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