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://tudelft.nl/staff/p.knoppers-1">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 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 String; key of the object type to search
110      * @param id String; id of object to search
111      * @param track boolean; 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     /** {@inheritDoc} */
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     /** {@inheritDoc} */
136     @Override
137     public final void focusGained(final FocusEvent e)
138     {
139         actionPerformed(null);
140     }
141 
142     /** {@inheritDoc} */
143     @Override
144     public final void focusLost(final FocusEvent e)
145     {
146         // Do nothing
147     }
148 
149     /** {@inheritDoc} */
150     @Override
151     public final void insertUpdate(final DocumentEvent e)
152     {
153         actionPerformed(null);
154     }
155 
156     /** {@inheritDoc} */
157     @Override
158     public final void removeUpdate(final DocumentEvent e)
159     {
160         actionPerformed(null);
161     }
162 
163     /** {@inheritDoc} */
164     @Override
165     public final void changedUpdate(final DocumentEvent e)
166     {
167         actionPerformed(null);
168     }
169 
170     /**
171      * Entries in the typeToSearch JComboBox of the OTS search panel.
172      * @param <T> Type of object identified by key
173      */
174     abstract static class ObjectKind<T extends Locatable & Identifiable>
175     {
176         /** The key of this ObjectKind. */
177         private final String key;
178 
179         /**
180          * Construct a new ObjectKind (entry in the combo box).
181          * @param key String; the key of the new ObjectKind
182          */
183         ObjectKind(final String key)
184         {
185             this.key = key;
186         }
187 
188         /**
189          * Retrieve the key.
190          * @return String; the key
191          */
192         public Object getKey()
193         {
194             return this.key;
195         }
196 
197         /**
198          * Lookup an object of type T in an OTS network.
199          * @param network Network; the OTS network
200          * @param id String; id of the object to return
201          * @return T; the object in the network of the correct type and matching id, or null if no matching object was found.
202          */
203         abstract T searchNetwork(Network network, String id);
204 
205         /**
206          * Produce the text that will appear in the combo box. This method should be overridden to implement localization.
207          */
208         @Override
209         public String toString()
210         {
211             return this.key;
212         }
213     }
214 }