View Javadoc
1   package org.opentrafficsim.swing.graphs;
2   
3   import java.awt.event.ActionEvent;
4   import java.awt.event.ActionListener;
5   import java.util.LinkedHashMap;
6   import java.util.Map;
7   
8   import javax.swing.ButtonGroup;
9   import javax.swing.JCheckBoxMenuItem;
10  import javax.swing.JMenu;
11  import javax.swing.JPopupMenu;
12  import javax.swing.JRadioButtonMenuItem;
13  
14  import org.opentrafficsim.draw.graphs.AbstractContourPlot;
15  import org.opentrafficsim.draw.graphs.AbstractSpaceTimePlot;
16  import org.opentrafficsim.draw.graphs.ContourDataSource.Dimension;
17  
18  /**
19   * Embed a ContourPlot in a Swing JPanel.
20   * <P>
21   * @author <a href="http://www.tbm.tudelft.nl/averbraeck">Alexander Verbraeck</a>
22   * @author <a href="http://www.tudelft.nl/pknoppers">Peter Knoppers</a>
23   * @author <a href="http://www.transport.citg.tudelft.nl">Wouter Schakel</a>
24   */
25  public class SwingContourPlot extends SwingSpaceTimePlot
26  {
27  
28      /**  */
29      private static final long serialVersionUID = 20190823L;
30  
31      /** Map to set time granularity. */
32      private Map<JRadioButtonMenuItem, Double> timeGranularityButtons;
33  
34      /** Map to set space granularity. */
35      private Map<JRadioButtonMenuItem, Double> spaceGranularityButtons;
36  
37      /** Check box for smoothing. */
38      private JCheckBoxMenuItem smoothCheckBox;
39  
40      /** Check box for interpolation. */
41      private JCheckBoxMenuItem interpolateCheckBox;
42  
43      /**
44       * Create a new SwingContourPlot with embedded plot.
45       * @param plot AbstractSpaceTimePlot; the plot to embed
46       */
47      public SwingContourPlot(final AbstractSpaceTimePlot plot)
48      {
49          super(plot);
50      }
51  
52      /** {@inheritDoc} */
53      @Override
54      protected void addPopUpMenuItems(final JPopupMenu popupMenu)
55      {
56          timeGranularityButtons = new LinkedHashMap<>();
57          spaceGranularityButtons = new LinkedHashMap<>();
58          super.addPopUpMenuItems(popupMenu);
59          JMenu spaceGranularityMenu = buildMenu("Distance granularity", "%.0f m", 1000, "%.0f km", "setSpaceGranularity",
60                  getPlot().getDataPool().getGranularities(Dimension.DISTANCE),
61                  getPlot().getDataPool().getGranularity(Dimension.DISTANCE), this.spaceGranularityButtons);
62          popupMenu.insert(spaceGranularityMenu, 0);
63          JMenu timeGranularityMenu = buildMenu("Time granularity", "%.0f s", 60.0, "%.0f min", "setTimeGranularity",
64                  getPlot().getDataPool().getGranularities(Dimension.TIME),
65                  getPlot().getDataPool().getGranularity(Dimension.TIME), this.timeGranularityButtons);
66          popupMenu.insert(timeGranularityMenu, 1);
67          this.smoothCheckBox = new JCheckBoxMenuItem("Adaptive smoothing method", false);
68          this.smoothCheckBox.addActionListener(new ActionListener()
69          {
70              /** {@inheritDoc} */
71              @Override
72              public void actionPerformed(final ActionEvent e)
73              {
74                  getPlot().getDataPool().setSmooth(((JCheckBoxMenuItem) e.getSource()).isSelected());
75                  getPlot().notifyPlotChange();
76              }
77          });
78          popupMenu.insert(this.smoothCheckBox, 2);
79          this.interpolateCheckBox = new JCheckBoxMenuItem("Bilinear interpolation", true);
80          this.interpolateCheckBox.addActionListener(new ActionListener()
81          {
82              /** {@inheritDoc} */
83              @Override
84              public void actionPerformed(final ActionEvent e)
85              {
86                  boolean interpolate = ((JCheckBoxMenuItem) e.getSource()).isSelected();
87                  getPlot().getBlockRenderer().setInterpolate(interpolate);
88                  getPlot().getDataPool().setInterpolate(interpolate);
89                  getPlot().notifyPlotChange();
90              }
91          });
92          popupMenu.insert(this.interpolateCheckBox, 3);
93      }
94  
95      /**
96       * Create a JMenu to let the user set the granularity.
97       * @param menuName String; caption for the new JMenu
98       * @param format1 String; format string for the values in the items under the new JMenu, below formatValue
99       * @param formatValue double; format value
100      * @param format2 String; format string for the values in the items under the new JMenu, above and equal to formatValue
101      * @param command String; prefix for the actionCommand of the items under the new JMenu
102      * @param values double[]; array of values to be formatted using the format strings to yield the items under the new JMenu
103      * @param initialValue double; the currently selected value (used to put the bullet on the correct item)
104      * @param granularityButtons Map&lt;JRadioButtonMenuItem, Double&gt;; map in to which buttons should be added
105      * @return JMenu with JRadioMenuItems for the values and a bullet on the currentValue item
106      */
107     private JMenu buildMenu(final String menuName, final String format1, final double formatValue, final String format2,
108             final String command, final double[] values, final double initialValue,
109             final Map<JRadioButtonMenuItem, Double> granularityButtons)
110     {
111         JMenu result = new JMenu(menuName);
112         ButtonGroup group = new ButtonGroup();
113         for (double value : values)
114         {
115             JRadioButtonMenuItem item = new JRadioButtonMenuItem(
116                     String.format(value < formatValue ? format1 : format2, value < formatValue ? value : value / formatValue));
117             granularityButtons.put(item, value);
118             item.setSelected(value == initialValue);
119             item.setActionCommand(command);
120             item.addActionListener(new ActionListener()
121             {
122                 /** {@inheritDoc} */
123                 @Override
124                 public void actionPerformed(final ActionEvent actionEvent)
125                 {
126                     if (command.equalsIgnoreCase("setSpaceGranularity"))
127                     {
128                         double granularity = spaceGranularityButtons.get(actionEvent.getSource());
129                         getPlot().getDataPool().setGranularity(Dimension.DISTANCE, granularity);
130                     }
131                     else if (command.equalsIgnoreCase("setTimeGranularity"))
132                     {
133                         double granularity = timeGranularityButtons.get(actionEvent.getSource());
134                         getPlot().getDataPool().setGranularity(Dimension.TIME, granularity);
135                     }
136                     else
137                     {
138                         throw new RuntimeException("Unknown ActionEvent");
139                     }
140                 }
141             });
142             result.add(item);
143             group.add(item);
144         }
145         return result;
146     }
147 
148     /** {@inheritDoc} */
149     @Override
150     public AbstractContourPlot<?> getPlot()
151     {
152         return (AbstractContourPlot<?>) super.getPlot();
153     }
154 
155     /**
156      * Sets the correct space granularity radio button to selected. This is done from a {@code DataPool} to keep multiple plots
157      * consistent.
158      * @param granularity double; space granularity
159      */
160     protected final void setSpaceGranularityRadioButton(final double granularity)
161     {
162         getPlot().setSpaceGranularity(granularity);
163         for (JRadioButtonMenuItem button : this.spaceGranularityButtons.keySet())
164         {
165             button.setSelected(this.spaceGranularityButtons.get(button) == granularity);
166         }
167     }
168 
169     /**
170      * Sets the correct time granularity radio button to selected. This is done from a {@code DataPool} to keep multiple plots
171      * consistent.
172      * @param granularity double; time granularity
173      */
174     protected final void setTimeGranularityRadioButton(final double granularity)
175     {
176         getPlot().setTimeGranularity(granularity);
177         for (JRadioButtonMenuItem button : this.timeGranularityButtons.keySet())
178         {
179             button.setSelected(this.timeGranularityButtons.get(button) == granularity);
180         }
181     }
182 
183     /**
184      * Sets the check box for smooth rendering. This is done from a {@code DataPool} to keep multiple plots consistent.
185      * @param smooth boolean; selected or not
186      */
187     protected final void setSmoothing(final boolean smooth)
188     {
189         this.smoothCheckBox.setSelected(smooth);
190     }
191 
192     /**
193      * Sets the check box for interpolated rendering and block renderer setting. This is done from a {@code DataPool} to keep
194      * multiple plots consistent.
195      * @param interpolate boolean; selected or not
196      */
197     protected final void setInterpolation(final boolean interpolate)
198     {
199         getPlot().setInterpolation(interpolate);
200         this.interpolateCheckBox.setSelected(interpolate);
201     }
202 
203 }