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