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 private ChartPanel chartPanel;
60
61
62
63
64
65 public SwingPlot(final AbstractPlot plot)
66 {
67 this.plot = plot;
68
69 this.statusLabel = new JLabel(" ", SwingConstants.CENTER);
70 add(this.statusLabel, BorderLayout.SOUTH);
71 setChart(plot.getChart());
72 }
73
74
75
76
77
78 protected void setChart(final JFreeChart chart)
79 {
80
81
82 this.chartPanel = new ChartPanel(chart)
83 {
84
85 private static final long serialVersionUID = 20181006L;
86
87 @Override
88 public void restoreAutoDomainBounds()
89 {
90 super.restoreAutoDomainBounds();
91 if (chart.getPlot() instanceof XYPlot)
92 {
93 SwingPlot.this.plot.setAutoBoundDomain(chart.getXYPlot());
94 }
95 }
96
97 @Override
98 public void restoreAutoRangeBounds()
99 {
100 super.restoreAutoRangeBounds();
101 if (chart.getPlot() instanceof XYPlot)
102 {
103 SwingPlot.this.plot.setAutoBoundRange(chart.getXYPlot());
104 }
105 }
106
107
108 @Override
109 public void doSaveAs() throws IOException
110 {
111
112
113
114 JLabel fontSizeLabel = new JLabel("font size");
115 JTextField fontSize = new JTextField("32");
116 fontSize.setToolTipText("Font size of title (other fonts are scaled)");
117 fontSize.setPreferredSize(new Dimension(40, 20));
118 JTextField width = new JTextField("960");
119 width.setToolTipText("Width [pixels]");
120 width.setPreferredSize(new Dimension(40, 20));
121 JLabel x = new JLabel("x");
122 JTextField height = new JTextField("540");
123 height.setToolTipText("Height [pixels]");
124 height.setPreferredSize(new Dimension(40, 20));
125
126
127 JFileChooser fileChooser = new JFileChooserWithSettings(fontSizeLabel, fontSize, width, x, height);
128 fileChooser.setCurrentDirectory(getDefaultDirectoryForSaveAs());
129 FileNameExtensionFilter filter =
130 new FileNameExtensionFilter(localizationResources.getString("PNG_Image_Files"), "png");
131 fileChooser.addChoosableFileFilter(filter);
132 fileChooser.setFileFilter(filter);
133
134 int option = fileChooser.showSaveDialog(this);
135 if (option == JFileChooser.APPROVE_OPTION)
136 {
137 String filename = fileChooser.getSelectedFile().getPath();
138 if (isEnforceFileExtensions())
139 {
140 if (!filename.endsWith(".png"))
141 {
142 filename = filename + ".png";
143 }
144 }
145
146
147 double fs;
148 try
149 {
150 fs = Double.parseDouble(fontSize.getText());
151 }
152 catch (NumberFormatException exception)
153 {
154 fs = 16.0;
155 }
156 int w;
157 try
158 {
159 w = Integer.parseInt(width.getText());
160 }
161 catch (NumberFormatException exception)
162 {
163 w = getWidth();
164 }
165 int h;
166 try
167 {
168 h = Integer.parseInt(height.getText());
169 }
170 catch (NumberFormatException exception)
171 {
172 h = getHeight();
173 }
174 OutputStream out = new BufferedOutputStream(new FileOutputStream(new File(filename)));
175 out.write(SwingPlot.this.plot.encodeAsPng(w, h, fs));
176 out.close();
177 }
178 }
179 };
180 ChartMouseListener chartListener = getChartMouseListener();
181 if (chartListener != null)
182 {
183 this.chartPanel.addChartMouseListener(chartListener);
184 }
185
186
187 final PointerHandler ph = new PointerHandler()
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 this.chartPanel.addMouseMotionListener(ph);
203 this.chartPanel.addMouseListener(ph);
204 add(this.chartPanel, BorderLayout.CENTER);
205 this.chartPanel.setMouseWheelEnabled(true);
206
207
208 JPopupMenu popupMenu = this.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(SwingPlot.this.chartPanel, BorderLayout.CENTER);
221 window.add(SwingPlot.this.statusLabel, BorderLayout.SOUTH);
222 window.addWindowListener(new WindowAdapter()
223 {
224 @Override
225 public void windowClosing(@SuppressWarnings("hiding") final WindowEvent e)
226 {
227 add(SwingPlot.this.chartPanel, BorderLayout.CENTER);
228 add(SwingPlot.this.statusLabel, BorderLayout.SOUTH);
229 SwingPlot.this.detach.setEnabled(true);
230 SwingPlot.this.getContentPane().validate();
231 SwingPlot.this.getContentPane().repaint();
232 }
233 });
234 window.pack();
235 window.setVisible(true);
236 SwingPlot.this.getContentPane().repaint();
237 }
238 });
239 popupMenu.add(this.detach);
240 addPopUpMenuItems(popupMenu);
241 }
242
243
244
245
246
247 protected final void setStatusLabel(final String label)
248 {
249 if (this.statusLabel != null)
250 {
251 this.statusLabel.setText(label);
252 }
253 }
254
255
256
257
258
259 protected void addPopUpMenuItems(final JPopupMenu popupMenu)
260 {
261
262 }
263
264
265
266
267
268 protected ChartMouseListener getChartMouseListener()
269 {
270 return null;
271 }
272
273
274
275
276
277 public AbstractPlot getPlot()
278 {
279 return this.plot;
280 }
281
282
283
284
285
286 public ChartPanel getChartPanel()
287 {
288 return this.chartPanel;
289 }
290
291 }