1 package org.opentrafficsim.swing.graphs;
2
3 import java.awt.BorderLayout;
4 import java.awt.Dimension;
5 import java.awt.event.ActionEvent;
6 import java.awt.event.ActionListener;
7 import java.awt.event.WindowAdapter;
8 import java.awt.event.WindowEvent;
9 import java.io.BufferedOutputStream;
10 import java.io.File;
11 import java.io.FileOutputStream;
12 import java.io.IOException;
13 import java.io.OutputStream;
14
15 import javax.swing.JFileChooser;
16 import javax.swing.JFrame;
17 import javax.swing.JLabel;
18 import javax.swing.JMenuItem;
19 import javax.swing.JPopupMenu;
20 import javax.swing.JTextField;
21 import javax.swing.SwingConstants;
22 import javax.swing.filechooser.FileNameExtensionFilter;
23
24 import org.jfree.chart.ChartMouseListener;
25 import org.jfree.chart.ChartPanel;
26 import org.jfree.chart.JFreeChart;
27 import org.jfree.chart.plot.XYPlot;
28 import org.opentrafficsim.draw.graphs.AbstractPlot;
29 import org.opentrafficsim.draw.graphs.JFileChooserWithSettings;
30 import org.opentrafficsim.draw.graphs.PointerHandler;
31
32
33
34
35
36
37
38
39
40
41
42
43 public class SwingPlot extends JFrame
44 {
45
46 private static final long serialVersionUID = 20190823L;
47
48
49 @SuppressWarnings("checkstyle:visibilitymodifier")
50 protected final AbstractPlot plot;
51
52
53 private JLabel statusLabel;
54
55
56 private JMenuItem detach;
57
58
59
60
61
62 public SwingPlot(final AbstractPlot plot)
63 {
64 this.plot = plot;
65
66 this.statusLabel = new JLabel(" ", SwingConstants.CENTER);
67 add(this.statusLabel, BorderLayout.SOUTH);
68 setChart(plot.getChart());
69 }
70
71
72
73
74
75 protected void setChart(final JFreeChart chart)
76 {
77
78
79 ChartPanel chartPanel = new ChartPanel(chart)
80 {
81
82 private static final long serialVersionUID = 20181006L;
83
84
85 @Override
86 public void restoreAutoDomainBounds()
87 {
88 super.restoreAutoDomainBounds();
89 if (chart.getPlot() instanceof XYPlot)
90 {
91 SwingPlot.this.plot.setAutoBoundDomain(chart.getXYPlot());
92 }
93 }
94
95
96 @Override
97 public void restoreAutoRangeBounds()
98 {
99 super.restoreAutoRangeBounds();
100 if (chart.getPlot() instanceof XYPlot)
101 {
102 SwingPlot.this.plot.setAutoBoundRange(chart.getXYPlot());
103 }
104 }
105
106
107 @Override
108 public void doSaveAs() throws IOException
109 {
110
111
112
113 JLabel fontSizeLabel = new JLabel("font size");
114 JTextField fontSize = new JTextField("32");
115 fontSize.setToolTipText("Font size of title (other fonts are scaled)");
116 fontSize.setPreferredSize(new Dimension(40, 20));
117 JTextField width = new JTextField("960");
118 width.setToolTipText("Width [pixels]");
119 width.setPreferredSize(new Dimension(40, 20));
120 JLabel x = new JLabel("x");
121 JTextField height = new JTextField("540");
122 height.setToolTipText("Height [pixels]");
123 height.setPreferredSize(new Dimension(40, 20));
124
125
126 JFileChooser fileChooser = new JFileChooserWithSettings(fontSizeLabel, fontSize, width, x, height);
127 fileChooser.setCurrentDirectory(getDefaultDirectoryForSaveAs());
128 FileNameExtensionFilter filter =
129 new FileNameExtensionFilter(localizationResources.getString("PNG_Image_Files"), "png");
130 fileChooser.addChoosableFileFilter(filter);
131 fileChooser.setFileFilter(filter);
132
133 int option = fileChooser.showSaveDialog(this);
134 if (option == JFileChooser.APPROVE_OPTION)
135 {
136 String filename = fileChooser.getSelectedFile().getPath();
137 if (isEnforceFileExtensions())
138 {
139 if (!filename.endsWith(".png"))
140 {
141 filename = filename + ".png";
142 }
143 }
144
145
146 double fs;
147 try
148 {
149 fs = Double.parseDouble(fontSize.getText());
150 }
151 catch (NumberFormatException exception)
152 {
153 fs = 16.0;
154 }
155 int w;
156 try
157 {
158 w = Integer.parseInt(width.getText());
159 }
160 catch (NumberFormatException exception)
161 {
162 w = getWidth();
163 }
164 int h;
165 try
166 {
167 h = Integer.parseInt(height.getText());
168 }
169 catch (NumberFormatException exception)
170 {
171 h = getHeight();
172 }
173 OutputStream out = new BufferedOutputStream(new FileOutputStream(new File(filename)));
174 out.write(SwingPlot.this.plot.encodeAsPng(w, h, fs));
175 out.close();
176 }
177 }
178 };
179 ChartMouseListener chartListener = getChartMouseListener();
180 if (chartListener != null)
181 {
182 chartPanel.addChartMouseListener(chartListener);
183 }
184
185
186 final PointerHandler ph = new PointerHandler()
187 {
188
189 @Override
190 public void updateHint(final double domainValue, final double rangeValue)
191 {
192 if (Double.isNaN(domainValue))
193 {
194 setStatusLabel(" ");
195 }
196 else
197 {
198 setStatusLabel(SwingPlot.this.plot.getStatusLabel(domainValue, rangeValue));
199 }
200 }
201 };
202 chartPanel.addMouseMotionListener(ph);
203 chartPanel.addMouseListener(ph);
204 add(chartPanel, BorderLayout.CENTER);
205 chartPanel.setMouseWheelEnabled(true);
206
207
208 JPopupMenu popupMenu = chartPanel.getPopupMenu();
209 popupMenu.add(new JPopupMenu.Separator());
210 this.detach = new JMenuItem("Show in detached window");
211 this.detach.addActionListener(new ActionListener()
212 {
213 @SuppressWarnings("synthetic-access")
214 @Override
215 public void actionPerformed(final ActionEvent e)
216 {
217 SwingPlot.this.detach.setEnabled(false);
218 JFrame window = new JFrame(getPlot().getCaption());
219 window.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
220 window.add(chartPanel, BorderLayout.CENTER);
221 window.add(SwingPlot.this.statusLabel, BorderLayout.SOUTH);
222 window.addWindowListener(new WindowAdapter()
223 {
224
225 @Override
226 public void windowClosing(@SuppressWarnings("hiding") final WindowEvent e)
227 {
228 add(chartPanel, BorderLayout.CENTER);
229 add(SwingPlot.this.statusLabel, BorderLayout.SOUTH);
230 SwingPlot.this.detach.setEnabled(true);
231 SwingPlot.this.getContentPane().validate();
232 SwingPlot.this.getContentPane().repaint();
233 }
234 });
235 window.pack();
236 window.setVisible(true);
237 SwingPlot.this.getContentPane().repaint();
238 }
239 });
240 popupMenu.add(this.detach);
241 addPopUpMenuItems(popupMenu);
242 }
243
244
245
246
247
248 protected final void setStatusLabel(final String label)
249 {
250 if (this.statusLabel != null)
251 {
252 this.statusLabel.setText(label);
253 }
254 }
255
256
257
258
259
260 protected void addPopUpMenuItems(final JPopupMenu popupMenu)
261 {
262
263 }
264
265
266
267
268
269 protected ChartMouseListener getChartMouseListener()
270 {
271 return null;
272 }
273
274
275
276
277
278 public AbstractPlot getPlot()
279 {
280 return this.plot;
281 }
282
283 }