View Javadoc
1   package org.opentrafficsim.swing.gui;
2   
3   import java.awt.BorderLayout;
4   import java.awt.Container;
5   import java.awt.FlowLayout;
6   import java.awt.event.ActionEvent;
7   import java.awt.event.ActionListener;
8   
9   import javax.swing.JComboBox;
10  import javax.swing.JLabel;
11  import javax.swing.JPanel;
12  import javax.swing.border.Border;
13  import javax.swing.border.LineBorder;
14  
15  import org.opentrafficsim.core.animation.gtu.colorer.GTUColorer;
16  import org.opentrafficsim.core.animation.gtu.colorer.SwitchableGTUColorer;
17  
18  /**
19   * Let the user select what the colors in the animation mean.
20   * <p>
21   * Copyright (c) 2013-2019 Delft University of Technology, PO Box 5, 2600 AA, Delft, the Netherlands. All rights reserved. <br>
22   * BSD-style license. See <a href="http://opentrafficsim.org/docs/license.html">OpenTrafficSim License</a>.
23   * <p>
24   * $LastChangedDate: 2018-10-11 22:54:04 +0200 (Thu, 11 Oct 2018) $, @version $Revision: 4696 $, by $Author: averbraeck $,
25   * initial version 27 mei 2015 <br>
26   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
27   */
28  public class ColorControlPanel extends JPanel implements ActionListener
29  {
30      /** */
31      private static final long serialVersionUID = 20150527L;
32  
33      /** The combo box that sets the coloring for the GTUs. */
34      private JComboBox<GTUColorer> comboBoxGTUColor;
35  
36      /** The panel that holds the legend for the currently selected GTUColorer. */
37      private final JPanel legendPanel;
38  
39      /** The GTUColorer that is currently active. */
40      private GTUColorer gtuColorer;
41  
42      /** The SwitchableGTUColorer that is controlled by this ColorControlPanel, if available. */
43      private final SwitchableGTUColorer switchableGTUColorer;
44  
45      /**
46       * Add a ColorControlPanel to an AnimationPanel. Initially the ColorControlPanel will have no items. Items are added with
47       * the <code>addItem</code> method. The first item added automatically becomes the active one.
48       * @param gtuColorer GTUColorer; the switchable GTU colorer that will be controlled by this ColorControlPanel
49       */
50      public ColorControlPanel(final GTUColorer gtuColorer)
51      {
52          this.setLayout(new FlowLayout(FlowLayout.LEFT));
53          this.legendPanel = new JPanel(new FlowLayout());
54  
55          if (gtuColorer instanceof SwitchableGTUColorer)
56          {
57              this.switchableGTUColorer = (SwitchableGTUColorer) gtuColorer;
58  
59              /**
60               * ComboBox for AppearanceControl.
61               * @param <T> generic type of the ComboBox
62               */
63              class AppearanceControlComboBox<T> extends JComboBox<T> implements AppearanceControl
64              {
65                  /** */
66                  private static final long serialVersionUID = 1L;
67  
68                  /** {@inheritDoc} */
69                  @Override
70                  public boolean isFont()
71                  {
72                      return true;
73                  }
74  
75                  /** {@inheritDoc} */
76                  @Override
77                  public String toString()
78                  {
79                      return "AppearanceControlComboBox []";
80                  }
81  
82              }
83              this.comboBoxGTUColor = new AppearanceControlComboBox<>();
84              this.add(this.comboBoxGTUColor);
85              this.comboBoxGTUColor.addActionListener(this);
86  
87              for (GTUColorer colorer : ((SwitchableGTUColorer) gtuColorer).getColorers())
88              {
89                  addItem(colorer);
90              }
91          }
92          else
93          {
94              this.gtuColorer = gtuColorer;
95              this.switchableGTUColorer = null;
96              rebuildLegend();
97          }
98  
99          this.add(this.legendPanel);
100     }
101 
102     /**
103      * Add one item to this ColorControlPanel. The <cite>getName</cite> method of the
104      * @param colorer GTUColorer; the GTUColorer that will be added
105      */
106     public final void addItem(final GTUColorer colorer)
107     {
108         this.comboBoxGTUColor.addItem(colorer);
109         // The first item added automatically becomes the current one and triggers a call to actionPerformed.
110     }
111 
112     /** {@inheritDoc} */
113     @Override
114     public final void actionPerformed(final ActionEvent e)
115     {
116         GTUColorer newColorer = (GTUColorer) this.comboBoxGTUColor.getSelectedItem();
117         if (null != newColorer)
118         {
119             this.gtuColorer = newColorer;
120             rebuildLegend();
121 
122             if (this.switchableGTUColorer != null)
123             {
124                 this.switchableGTUColorer.setGTUColorer(this.comboBoxGTUColor.getSelectedIndex());
125             }
126         }
127     }
128 
129     /**
130      * Build or rebuild the legend on the screen.
131      */
132     private void rebuildLegend()
133     {
134         this.legendPanel.removeAll();
135         for (GTUColorer.LegendEntry legendEntry : this.gtuColorer.getLegend())
136         {
137             JPanel panel = new JPanel(new BorderLayout());
138             /**
139              * ColorBox for AppearanceControl.
140              */
141             class ColorBox extends JLabel implements AppearanceControl
142             {
143                 /** */
144                 private static final long serialVersionUID = 20180206L;
145 
146                 /**
147                  * Constructor.
148                  */
149                 ColorBox()
150                 {
151                     super("     ");
152                 }
153 
154                 /** {@inheritDoc} */
155                 @Override
156                 public String toString()
157                 {
158                     return "ColorBox []";
159                 }
160 
161             }
162             ColorBox colorBox = new ColorBox();
163             colorBox.setOpaque(true); // By default, the label is transparent
164             colorBox.setBackground(legendEntry.getColor());
165             Border border = LineBorder.createBlackLineBorder();
166             colorBox.setBorder(border);
167             panel.add(colorBox, BorderLayout.LINE_START);
168             JLabel name = new JLabel(" " + legendEntry.getName().trim());
169             panel.add(name, BorderLayout.CENTER);
170             name.setOpaque(true);
171             name.setForeground(getForeground());
172             name.setBackground(getBackground());
173             panel.setToolTipText(legendEntry.getDescription());
174             this.legendPanel.add(panel);
175         }
176         this.legendPanel.revalidate();
177 
178         Container parentPanel = this.getParent();
179 
180         if (parentPanel != null)
181         {
182             parentPanel.repaint();
183         }
184     }
185 
186     /** {@inheritDoc} */
187     @Override
188     public final String toString()
189     {
190         return "ColorControlPanel [gtuColorer=" + this.gtuColorer + "]";
191     }
192 
193 }