View Javadoc
1   package org.opentrafficsim.swing.gui;
2   
3   import java.awt.Dimension;
4   import java.awt.event.ActionEvent;
5   import java.awt.event.ActionListener;
6   import java.awt.event.FocusEvent;
7   import java.awt.event.FocusListener;
8   
9   import javax.swing.BoxLayout;
10  import javax.swing.JCheckBox;
11  import javax.swing.JComboBox;
12  import javax.swing.JLabel;
13  import javax.swing.JPanel;
14  import javax.swing.JTextField;
15  import javax.swing.event.DocumentEvent;
16  import javax.swing.event.DocumentListener;
17  
18  import org.opentrafficsim.base.Identifiable;
19  import org.opentrafficsim.core.gtu.Gtu;
20  import org.opentrafficsim.core.network.Link;
21  import org.opentrafficsim.core.network.Node;
22  import org.opentrafficsim.core.network.Network;
23  
24  import nl.tudelft.simulation.dsol.animation.Locatable;
25  
26  /**
27   * The OTS search panel.
28   * <p>
29   * Copyright (c) 2020-2023 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
30   * BSD-style license. See <a href="https://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
31   * </p>
32   * @author <a href="https://github.com/averbraeck">Alexander Verbraeck</a>
33   * @author <a href="https://tudelft.nl/staff/p.knoppers-1">Peter Knoppers</a>
34   */
35  public class OtsSearchPanel extends JPanel implements ActionListener, FocusListener, DocumentListener
36  {
37      /** ... */
38      private static final long serialVersionUID = 20200127L;
39  
40      /** The animation panel. */
41      private final OtsAnimationPanel otsAnimationPanel;
42  
43      /** The type-of-object-to-search-for selector. */
44      private final JComboBox<ObjectKind<?>> typeToSearch;
45  
46      /** Id of the object to search for. */
47      private final JTextField idTextField;
48  
49      /** Track object check box. */
50      private final JCheckBox trackObject;
51  
52      /**
53       * Construct a new OtsSearchPanel.
54       * @param otsAnimationPanel OtsAnimationPanel; the animation panel
55       */
56      public OtsSearchPanel(final OtsAnimationPanel otsAnimationPanel)
57      {
58          this.otsAnimationPanel = otsAnimationPanel;
59          this.setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
60          this.add(new JLabel("    ")); // insert some white space in the GUI
61          this.add(new JLabel(OtsControlPanel.loadIcon("/View.png")));
62          ObjectKind<?>[] objectKinds = new ObjectKind[] {new ObjectKind<Gtu>("GTU")
63          {
64              @Override
65              Gtu searchNetwork(final Network network, final String id)
66              {
67                  return network.getGTU(id);
68              }
69          }, new ObjectKind<Node>("Node")
70          {
71              @Override
72              Node searchNetwork(final Network network, final String id)
73              {
74                  return network.getNode(id);
75              }
76          }, new ObjectKind<Link>("Link")
77          {
78              @Override
79              Link searchNetwork(final Network network, final String id)
80              {
81                  return network.getLink(id);
82              }
83          }};
84          this.typeToSearch = new JComboBox<ObjectKind<?>>(objectKinds);
85          this.add(this.typeToSearch);
86  
87          /** Text field with appearance control. */
88          class AppearanceControlTextField extends JTextField implements AppearanceControl
89          {
90              /** */
91              private static final long serialVersionUID = 20180207L;
92  
93              /** {@inheritDoc} */
94              @Override
95              public boolean isForeground()
96              {
97                  return false;
98              }
99  
100             /** {@inheritDoc} */
101             @Override
102             public boolean isBackground()
103             {
104                 return false;
105             }
106 
107             /** {@inheritDoc} */
108             @Override
109             public String toString()
110             {
111                 return "AppearanceControlLabel []";
112             }
113         }
114 
115         this.idTextField = new AppearanceControlTextField();
116         this.idTextField.setPreferredSize(new Dimension(100, 0));
117         this.add(this.idTextField);
118         this.trackObject = new JCheckBox("track");
119         this.add(this.trackObject);
120         this.trackObject.setActionCommand("Tracking status changed");
121         this.idTextField.setActionCommand("Id changed");
122         this.typeToSearch.setActionCommand("Type changed");
123         this.trackObject.addActionListener(this);
124         this.idTextField.addActionListener(this);
125         this.typeToSearch.addActionListener(this);
126         this.idTextField.addFocusListener(this);
127         this.idTextField.getDocument().addDocumentListener(this);
128     }
129 
130     /**
131      * Update all values at once.
132      * @param objectKey String; key of the object type to search
133      * @param id String; id of object to search
134      * @param track boolean; if true; track continuously; if false; center on it, but do not track
135      */
136     public void selectAndTrackObject(final String objectKey, final String id, final boolean track)
137     {
138         for (int index = this.typeToSearch.getItemCount(); --index >= 0;)
139         {
140             if (this.typeToSearch.getItemAt(index).getKey().equals(objectKey))
141             {
142                 this.typeToSearch.setSelectedIndex(index);
143             }
144         }
145         this.trackObject.setSelected(track);
146         this.idTextField.setText(id);
147         actionPerformed(null);
148     }
149 
150     /** {@inheritDoc} */
151     @Override
152     public void actionPerformed(final ActionEvent e)
153     {
154         this.otsAnimationPanel.setAutoPan(this.idTextField.getText(), (ObjectKind<?>) this.typeToSearch.getSelectedItem(),
155                 this.trackObject.isSelected());
156     }
157 
158     /** {@inheritDoc} */
159     @Override
160     public final void focusGained(final FocusEvent e)
161     {
162         actionPerformed(null);
163     }
164 
165     /** {@inheritDoc} */
166     @Override
167     public final void focusLost(final FocusEvent e)
168     {
169         // Do nothing
170     }
171 
172     /** {@inheritDoc} */
173     @Override
174     public final void insertUpdate(final DocumentEvent e)
175     {
176         actionPerformed(null);
177     }
178 
179     /** {@inheritDoc} */
180     @Override
181     public final void removeUpdate(final DocumentEvent e)
182     {
183         actionPerformed(null);
184     }
185 
186     /** {@inheritDoc} */
187     @Override
188     public final void changedUpdate(final DocumentEvent e)
189     {
190         actionPerformed(null);
191     }
192 
193     /**
194      * Entries in the typeToSearch JComboBox of the OTS search panel.
195      * @param <T> Type of object identified by key
196      */
197     abstract static class ObjectKind<T extends Locatable & Identifiable>
198     {
199         /** The key of this ObjectKind. */
200         private final String key;
201 
202         /**
203          * Construct a new ObjectKind (entry in the combo box).
204          * @param key String; the key of the new ObjectKind
205          */
206         ObjectKind(final String key)
207         {
208             this.key = key;
209         }
210 
211         /**
212          * Retrieve the key.
213          * @return String; the key
214          */
215         public Object getKey()
216         {
217             return this.key;
218         }
219 
220         /**
221          * Lookup an object of type T in an OTS network.
222          * @param network Network; the OTS network
223          * @param id String; id of the object to return
224          * @return T; the object in the network of the correct type and matching id, or null if no matching object was found.
225          */
226         abstract T searchNetwork(Network network, String id);
227 
228         /**
229          * Produce the text that will appear in the combo box. This method should be overridden to implement localization.
230          */
231         @Override
232         public String toString()
233         {
234             return this.key;
235         }
236     }
237 }