001 package org.LiveGraph.gui.gs;
002
003 import static org.LiveGraph.settings.GraphSettings.HGridType.HGrid_None;
004 import static org.LiveGraph.settings.GraphSettings.HGridType.HGrid_Simple;
005 import static org.LiveGraph.settings.GraphSettings.VGridType.VGrid_DSNumAligned;
006 import static org.LiveGraph.settings.GraphSettings.VGridType.VGrid_None;
007 import static org.LiveGraph.settings.GraphSettings.VGridType.VGrid_XAUnitAligned;
008 import static org.LiveGraph.settings.GraphSettings.XAxisType.XAxis_DSNum;
009 import static org.LiveGraph.settings.GraphSettings.XAxisType.XAxis_DataValLogToSetBase;
010 import static org.LiveGraph.settings.GraphSettings.XAxisType.XAxis_DataValScaleBySetVal;
011 import static org.LiveGraph.settings.GraphSettings.XAxisType.XAxis_DataValSecsToSetPower;
012 import static org.LiveGraph.settings.GraphSettings.XAxisType.XAxis_DataValSimple;
013 import static org.LiveGraph.settings.GraphSettings.XAxisType.XAxis_DataValTrans0to1;
014
015 import java.awt.Color;
016 import java.awt.ComponentOrientation;
017 import java.awt.Dimension;
018 import java.awt.FlowLayout;
019 import java.awt.GridBagConstraints;
020 import java.awt.GridBagLayout;
021 import java.awt.Insets;
022 import java.awt.event.ActionEvent;
023 import java.awt.event.ActionListener;
024
025 import javax.swing.BorderFactory;
026 import javax.swing.Box;
027 import javax.swing.ButtonGroup;
028 import javax.swing.JButton;
029 import javax.swing.JColorChooser;
030 import javax.swing.JComboBox;
031 import javax.swing.JLabel;
032 import javax.swing.JPanel;
033 import javax.swing.JRadioButton;
034 import javax.swing.JSeparator;
035 import javax.swing.JTextField;
036 import javax.swing.SwingConstants;
037 import javax.swing.border.EtchedBorder;
038
039 import org.LiveGraph.LiveGraph;
040 import org.LiveGraph.dataCache.CacheEvent;
041 import org.LiveGraph.dataCache.DataCache;
042 import org.LiveGraph.events.Event;
043 import org.LiveGraph.events.EventType;
044 import org.LiveGraph.gui.LiveGraphSettingsPanel;
045 import org.LiveGraph.gui.RealNumFieldValueChangeAdaptor;
046 import org.LiveGraph.gui.Tools;
047 import org.LiveGraph.settings.GraphSettings;
048 import org.LiveGraph.settings.SettingsEvent;
049
050 import com.softnetConsult.utils.collections.ReadOnlyIterator;
051 import com.softnetConsult.utils.exceptions.UnexpectedSwitchCase;
052 import com.softnetConsult.utils.string.StringTools;
053 import com.softnetConsult.utils.swing.DisEnablingPanel;
054 import com.softnetConsult.utils.swing.ResizablePopupComboBox;
055 import com.softnetConsult.utils.swing.SwingTools;
056
057
058 /**
059 * The graph settings panel of the application. This is the only component contained in
060 * the content pane of the application's graph settings window. API users may request
061 * {@link org.LiveGraph.gui.GUIManager} to create additional instances of a
062 * {@code GraphSettingsPanel} if they wish to integrate the LiveGraph GUI into their application.
063 *
064 * <p>
065 * <strong>LiveGraph</strong>
066 * (<a href="http://www.live-graph.org" target="_blank">http://www.live-graph.org</a>).
067 * </p>
068 * <p>Copyright (c) 2007-2008 by G. Paperin.</p>
069 * <p>File: GraphSettingsPanel.java</p>
070 * <p style="font-size:smaller;">Redistribution and use in source and binary forms, with or
071 * without modification, are permitted provided that the following terms and conditions are met:
072 * </p>
073 * <p style="font-size:smaller;">1. Redistributions of source code must retain the above
074 * acknowledgement of the LiveGraph project and its web-site, the above copyright notice,
075 * this list of conditions and the following disclaimer.<br />
076 * 2. Redistributions in binary form must reproduce the above acknowledgement of the
077 * LiveGraph project and its web-site, the above copyright notice, this list of conditions
078 * and the following disclaimer in the documentation and/or other materials provided with
079 * the distribution.<br />
080 * 3. All advertising materials mentioning features or use of this software or any derived
081 * software must display the following acknowledgement:<br />
082 * <em>This product includes software developed by the LiveGraph project and its
083 * contributors.<br />(http://www.live-graph.org)</em><br />
084 * 4. All advertising materials distributed in form of HTML pages or any other technology
085 * permitting active hyper-links that mention features or use of this software or any
086 * derived software must display the acknowledgment specified in condition 3 of this
087 * agreement, and in addition, include a visible and working hyper-link to the LiveGraph
088 * homepage (http://www.live-graph.org).
089 * </p>
090 * <p style="font-size:smaller;">THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY
091 * OF ANY KIND, EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
092 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
093 * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
094 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
095 * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
096 * </p>
097 *
098 * @author Greg Paperin (<a href="http://www.paperin.org" target="_blank">http://www.paperin.org</a>)
099 * @version {@value org.LiveGraph.LiveGraph#version}
100 *
101 */
102 public class GraphSettingsPanel extends LiveGraphSettingsPanel {
103
104 private static final String[] xAxisTypeLabels = new String[] {
105 "Dataset numbers ",
106 "Data series ",
107 "Data series transformed into [0..1] ",
108 "Data series scaled by the specified value ",
109 "Logarithm of a data series to the specified base ",
110 "Data series as seconds * 10^(specified power) "};
111
112 private static final String[] xAxisParameterLabels = new String[] {
113 "Parameter:",
114 "Parameter:",
115 "Parameter:",
116 "Factor:",
117 "Base:",
118 "Power:"};
119
120 private JTextField minYField = null, maxYField = null, minXField = null, maxXField = null;
121 private JLabel minYLabelExpl = null, maxYLabelExpl = null, minXLabelExpl = null, maxXLabelExpl = null;
122 private JLabel minYLabelAuto = null, maxYLabelAuto = null, minXLabelAuto = null, maxXLabelAuto = null;
123 private JRadioButton minYValButton = null, minYAutoButton = null, maxYValButton = null, maxYAutoButton = null;
124 private JRadioButton minXValButton = null, minXAutoButton = null, maxXValButton = null, maxXAutoButton = null;
125
126 private JTextField vGridSizeField = null, hGridSizeField = null;
127 private JRadioButton vGridNoneButton = null, vGridDSNumAlignedButton = null, vGridXAUnitAlignedButton = null;
128 private JRadioButton hGridNoneButton = null, hGridSimpleButton = null;
129 private JButton vGridColourButton = null;
130 private JButton hGridColourButton = null;
131 private DisEnablingPanel hGridDetsPanel = null, vGridDetsPanel = null;
132
133 private JComboBox xAxisTypeCombo = null;
134 private JLabel xAxisSeriesLabel = null;
135 private JComboBox xAxisSeriesCombo = null;
136 private JLabel xAxisParameterLabel = null;
137 private JTextField xAxisParameterField = null;
138 private int preferredXAxisSeriesIndex = 0;
139
140 private boolean updatingSeriesLabels = false;
141
142
143 /**
144 * This is the default constructor.
145 */
146 public GraphSettingsPanel() {
147 super();
148 initialize();
149 }
150
151 /**
152 * This method initializes the panel.
153 */
154 private void initialize() {
155
156 // General settings:
157
158 Dimension panelDim = new Dimension(470, 400);
159 this.setPreferredSize(panelDim);
160 this.setSize(panelDim);
161 final JPanel thisPanel = this;
162 thisPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
163 thisPanel.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
164 GraphSettings gSettings = LiveGraph.application().getGraphSettings();
165 if (null == gSettings)
166 gSettings = new GraphSettings();
167
168 // Layout:
169
170 //AbstractButton button = null;
171 JLabel label = null;
172 ButtonGroup bGroup = null;
173 Dimension dim = null;
174 RealNumFieldValueChangeAdaptor fvalAdpt = null;
175 double defVal = Double.NaN;
176
177 // Viewport settings:
178 JPanel viewportPanel = new JPanel(new GridBagLayout());
179 thisPanel.add(viewportPanel);
180 viewportPanel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
181 viewportPanel.add(new JLabel("Viewport:"), Tools.createGridBagConstraints(0, 0, 5, 1));
182 /*
183 viewportPanel.add(new Box.Filler((dim = new Dimension(1, 1)), dim, dim),
184 new GridBagConstraints(0, 5, 6, 1, 1, 1,
185 GridBagConstraints.WEST,
186 GridBagConstraints.BOTH,
187 new Insets(0, 0, 0, 0),
188 0, 0));
189 */
190
191 viewportPanel.add(new JSeparator(SwingConstants.VERTICAL),
192 new GridBagConstraints(5, 1, 1, 2, 0, 1,
193 GridBagConstraints.NORTHWEST,
194 GridBagConstraints.BOTH,
195 new Insets(5, 5, 5, 5),
196 0, 0));
197
198
199 // Min Y:
200 viewportPanel.add((minYLabelExpl = new JLabel("Min Y:")), Tools.createGridBagConstraints(0, 1, 1, 1));
201 minYLabelExpl.setFont(SwingTools.getPlainFont(minYLabelExpl));
202 bGroup = new ButtonGroup();
203
204 minYValButton = new JRadioButton("", !Double.isNaN(gSettings.getMinY()));
205 viewportPanel.add(minYValButton, Tools.createGridBagConstraints(1, 1, 1, 1));
206 bGroup.add(minYValButton);
207 defVal = Double.isNaN(gSettings.getMinY()) ? 0. : gSettings.getMinY();
208 minYField = new JTextField(StringTools.toString(defVal), 6);
209 viewportPanel.add(minYField, Tools.createGridBagConstraints(2, 1, 1, 1));
210 minYField.addFocusListener(fvalAdpt = new RealNumFieldValueChangeAdaptor(defVal) {
211 @Override public double valueChanged(JTextField field, double newValue) {
212 GraphSettings gs = LiveGraph.application().getGraphSettings();
213 gs.setMinY(field.isEnabled() ? newValue : Double.NaN);
214 newValue = Double.isNaN(gs.getMinY()) ? 0. : gs.getMinY();
215 return newValue;
216 }
217 });
218 minYField.addKeyListener(fvalAdpt);
219
220 minYLabelAuto = new JLabel("auto");
221 minYLabelAuto.setFont(SwingTools.getPlainFont(minYLabelAuto));
222 viewportPanel.add(minYLabelAuto, Tools.createGridBagConstraints(4, 1, 1, 1));
223
224 minYValButton.addActionListener(new ActionListener() {
225 public void actionPerformed(ActionEvent e) {
226 GraphSettings gs = LiveGraph.application().getGraphSettings();
227 gs.setMinY(StringTools.parseDouble(minYField.getText()));
228 minYValButton.setSelected(!Double.isNaN(gs.getMinY()));
229 minYAutoButton.setSelected(Double.isNaN(gs.getMinY()));
230 }
231 });
232
233 minYAutoButton = new JRadioButton("", Double.isNaN(gSettings.getMinY()));
234 viewportPanel.add(minYAutoButton, Tools.createGridBagConstraints(3, 1, 1, 1));
235 bGroup.add(minYAutoButton);
236 minYAutoButton.addActionListener(new ActionListener() {
237 public void actionPerformed(ActionEvent e) {
238 GraphSettings gs = LiveGraph.application().getGraphSettings();
239 gs.setMinY(Double.NaN);
240 minYValButton.setSelected(!Double.isNaN(gs.getMinY()));
241 minYAutoButton.setSelected(Double.isNaN(gs.getMinY()));
242 }
243 });
244 minYField.setEnabled(!Double.isNaN(gSettings.getMinY()));
245
246 // Max Y:
247 viewportPanel.add((maxYLabelExpl = new JLabel("Max Y:")), Tools.createGridBagConstraints(6, 1, 1, 1));
248 maxYLabelExpl.setFont(SwingTools.getPlainFont(maxYLabelExpl));
249 bGroup = new ButtonGroup();
250
251 maxYValButton = new JRadioButton("", !Double.isNaN(gSettings.getMaxY()));
252 viewportPanel.add(maxYValButton, Tools.createGridBagConstraints(7, 1, 1, 1));
253 bGroup.add(maxYValButton);
254 defVal = Double.isNaN(gSettings.getMaxY()) ? 100. : gSettings.getMaxY();
255 maxYField = new JTextField(StringTools.toString(defVal), 6);
256 viewportPanel.add(maxYField, Tools.createGridBagConstraints(8, 1, 1, 1));
257 maxYField.addFocusListener(fvalAdpt = new RealNumFieldValueChangeAdaptor(defVal) {
258 @Override public double valueChanged(JTextField field, double newValue) {
259 GraphSettings gs = LiveGraph.application().getGraphSettings();
260 gs.setMaxY(field.isEnabled() ? newValue : Double.NaN);
261 newValue = Double.isNaN(gs.getMaxY()) ? 0. : gs.getMaxY();
262 return newValue;
263 }
264 });
265 maxYField.addKeyListener(fvalAdpt);
266
267 maxYLabelAuto = new JLabel("auto");
268 maxYLabelAuto.setFont(SwingTools.getPlainFont(label));
269 viewportPanel.add(maxYLabelAuto, Tools.createGridBagConstraints(10, 1, 1, 1));
270 maxYValButton.addActionListener(new ActionListener() {
271 public void actionPerformed(ActionEvent e) {
272 GraphSettings gs = LiveGraph.application().getGraphSettings();
273 gs.setMaxY(StringTools.parseDouble(maxYField.getText()));
274 maxYValButton.setSelected(!Double.isNaN(gs.getMaxY()));
275 maxYAutoButton.setSelected(Double.isNaN(gs.getMaxY()));
276 }
277 });
278
279 maxYAutoButton = new JRadioButton("", Double.isNaN(gSettings.getMaxY()));
280 viewportPanel.add(maxYAutoButton, Tools.createGridBagConstraints(9, 1, 1, 1));
281 bGroup.add(maxYAutoButton);
282 maxYAutoButton.addActionListener(new ActionListener() {
283 public void actionPerformed(ActionEvent e) {
284 GraphSettings gs = LiveGraph.application().getGraphSettings();
285 gs.setMaxY(Double.NaN);
286 maxYValButton.setSelected(!Double.isNaN(gs.getMaxY()));
287 maxYAutoButton.setSelected(Double.isNaN(gs.getMaxY()));
288 }
289 });
290 maxYField.setEnabled(false);
291
292 // Min X:
293 viewportPanel.add((minXLabelExpl = new JLabel("Min X:")), Tools.createGridBagConstraints(0, 2, 1, 1));
294 minXLabelExpl.setFont(SwingTools.getPlainFont(minXLabelExpl));
295 bGroup = new ButtonGroup();
296
297 minXValButton = new JRadioButton("", !Double.isNaN(gSettings.getMinX()));
298 viewportPanel.add(minXValButton, Tools.createGridBagConstraints(1, 2, 1, 1));
299 bGroup.add(minXValButton);
300 defVal = Double.isNaN(gSettings.getMinX()) ? -1. : gSettings.getMinX();
301 minXField = new JTextField(StringTools.toString(defVal), 6);
302 viewportPanel.add(minXField, Tools.createGridBagConstraints(2, 2, 1, 1));
303 minXField.addFocusListener(fvalAdpt = new RealNumFieldValueChangeAdaptor(defVal) {
304 @Override public double valueChanged(JTextField field, double newValue) {
305 GraphSettings gs = LiveGraph.application().getGraphSettings();
306 gs.setMinX(field.isEnabled() ? newValue : Double.NaN);
307 newValue = Double.isNaN(gs.getMinX()) ? 0. : gs.getMinX();
308 return newValue;
309 }
310 });
311 minXField.addKeyListener(fvalAdpt);
312
313 minXLabelAuto = new JLabel("auto");
314 minXLabelAuto.setFont(SwingTools.getPlainFont(minXLabelAuto));
315 viewportPanel.add(minXLabelAuto, Tools.createGridBagConstraints(4, 2, 1, 1));
316 minXValButton.addActionListener(new ActionListener() {
317 public void actionPerformed(ActionEvent e) {
318 GraphSettings gs = LiveGraph.application().getGraphSettings();
319 gs.setMinX(StringTools.parseDouble(minXField.getText()));
320 minXValButton.setSelected(!Double.isNaN(gs.getMinX()));
321 minXAutoButton.setSelected(Double.isNaN(gs.getMinX()));
322 }
323 });
324
325 minXAutoButton = new JRadioButton("", Double.isNaN(gSettings.getMinX()));
326 viewportPanel.add(minXAutoButton, Tools.createGridBagConstraints(3, 2, 1, 1));
327 bGroup.add(minXAutoButton);
328 minXAutoButton.addActionListener(new ActionListener() {
329 public void actionPerformed(ActionEvent e) {
330 GraphSettings gs = LiveGraph.application().getGraphSettings();
331 gs.setMinX(Double.NaN);
332 minXValButton.setSelected(!Double.isNaN(gs.getMinX()));
333 minXAutoButton.setSelected(Double.isNaN(gs.getMinX()));
334 }
335 });
336 minXField.setEnabled(false);
337
338 // Max X:
339 viewportPanel.add((maxXLabelExpl = new JLabel("Max X:")), Tools.createGridBagConstraints(6, 2, 1, 1));
340 maxXLabelExpl.setFont(SwingTools.getPlainFont(maxXLabelExpl));
341 bGroup = new ButtonGroup();
342
343 maxXValButton = new JRadioButton("", !Double.isNaN(gSettings.getMaxX()));
344 viewportPanel.add(maxXValButton, Tools.createGridBagConstraints(7, 2, 1, 1));
345 bGroup.add(maxXValButton);
346 defVal = Double.isNaN(gSettings.getMaxX()) ? 10000. : gSettings.getMaxX();
347 maxXField = new JTextField(StringTools.toString(defVal), 6);
348 viewportPanel.add(maxXField, Tools.createGridBagConstraints(8, 2, 1, 1));
349 maxXField.addFocusListener(fvalAdpt = new RealNumFieldValueChangeAdaptor(defVal) {
350 @Override public double valueChanged(JTextField field, double newValue) {
351 GraphSettings gs = LiveGraph.application().getGraphSettings();
352 gs.setMaxX(field.isEnabled() ? newValue : Double.NaN);
353 newValue = Double.isNaN(gs.getMaxX()) ? 0. : gs.getMaxX();
354 return newValue;
355 }
356 });
357 maxXField.addKeyListener(fvalAdpt);
358
359 maxXLabelAuto = new JLabel("auto");
360 maxXLabelAuto.setFont(SwingTools.getPlainFont(maxXLabelAuto));
361 viewportPanel.add(maxXLabelAuto, Tools.createGridBagConstraints(10, 2, 1, 1));
362 maxXValButton.addActionListener(new ActionListener() {
363 public void actionPerformed(ActionEvent e) {
364 GraphSettings gs = LiveGraph.application().getGraphSettings();
365 gs.setMaxX(StringTools.parseDouble(maxXField.getText()));
366 maxXValButton.setSelected(!Double.isNaN(gs.getMaxX()));
367 maxXAutoButton.setSelected(Double.isNaN(gs.getMaxX()));
368 }
369 });
370
371 maxXAutoButton = new JRadioButton("", Double.isNaN(gSettings.getMaxX()));
372 viewportPanel.add(maxXAutoButton, Tools.createGridBagConstraints(9, 2, 1, 1));
373 bGroup.add(maxXAutoButton);
374 maxXAutoButton.addActionListener(new ActionListener() {
375 public void actionPerformed(ActionEvent e) {
376 GraphSettings gs = LiveGraph.application().getGraphSettings();
377 gs.setMaxX(Double.NaN);
378 maxXValButton.setSelected(!Double.isNaN(gs.getMaxX()));
379 maxXAutoButton.setSelected(Double.isNaN(gs.getMaxX()));
380 }
381 });
382 maxXField.setEnabled(false);
383
384 // Grid settings:
385 JPanel gridPanel = new JPanel(new GridBagLayout());
386 thisPanel.add(gridPanel);
387 gridPanel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
388
389 gridPanel.add(new JSeparator(SwingConstants.VERTICAL),
390 new GridBagConstraints(3, 1, 1, 4, 0, 1,
391 GridBagConstraints.NORTHWEST,
392 GridBagConstraints.BOTH,
393 new Insets(5, 10, 5, 10),
394 0, 0));
395
396 // Vertical grid:
397 gridPanel.add(new JLabel("Vertical grid:"), Tools.createGridBagConstraints(0, 0, 3, 1));
398 bGroup = new ButtonGroup();
399
400 vGridDetsPanel = new DisEnablingPanel(new GridBagLayout());
401 gridPanel.add(vGridDetsPanel, Tools.createGridBagConstraints(1, 4, 1, 1));
402
403 vGridNoneButton = new JRadioButton("Do not display a grid",
404 gSettings.getVGridType() == VGrid_None);
405 vGridNoneButton.setFont(SwingTools.getPlainFont(vGridNoneButton));
406 gridPanel.add(vGridNoneButton, Tools.createGridBagConstraints(0, 1, 3, 1));
407 bGroup.add(vGridNoneButton);
408 vGridNoneButton.addActionListener(new ActionListener() {
409 public void actionPerformed(ActionEvent e) {
410 GraphSettings gs = LiveGraph.application().getGraphSettings();
411 gs.setVGridType(VGrid_None);
412 vGridNoneButton.setSelected(VGrid_None == gs.getVGridType());
413 vGridDSNumAlignedButton.setSelected(VGrid_DSNumAligned == gs.getVGridType());
414 vGridXAUnitAlignedButton.setSelected(VGrid_XAUnitAligned == gs.getVGridType());
415 vGridDetsPanel.setEnabled(VGrid_None != gs.getVGridType());
416 }
417 });
418
419 vGridDSNumAlignedButton = new JRadioButton("Grid aligned on dataset indices",
420 gSettings.getVGridType() == VGrid_DSNumAligned);
421 vGridDSNumAlignedButton.setFont(SwingTools.getPlainFont(vGridDSNumAlignedButton));
422 gridPanel.add(vGridDSNumAlignedButton, Tools.createGridBagConstraints(0, 2, 3, 1));
423 bGroup.add(vGridDSNumAlignedButton);
424 vGridDSNumAlignedButton.addActionListener(new ActionListener() {
425 public void actionPerformed(ActionEvent e) {
426 GraphSettings gs = LiveGraph.application().getGraphSettings();
427 gs.setVGridType(VGrid_DSNumAligned);
428 vGridNoneButton.setSelected(VGrid_None == gs.getVGridType());
429 vGridDSNumAlignedButton.setSelected(VGrid_DSNumAligned == gs.getVGridType());
430 vGridXAUnitAlignedButton.setSelected(VGrid_XAUnitAligned == gs.getVGridType());
431 vGridDetsPanel.setEnabled(VGrid_None != gs.getVGridType());
432 }
433 });
434
435 vGridXAUnitAlignedButton = new JRadioButton("Grid aligned on X-axis units",
436 gSettings.getVGridType() == VGrid_XAUnitAligned);
437 vGridXAUnitAlignedButton.setFont(SwingTools.getPlainFont(vGridXAUnitAlignedButton));
438 gridPanel.add(vGridXAUnitAlignedButton, Tools.createGridBagConstraints(0, 3, 3, 1));
439 bGroup.add(vGridXAUnitAlignedButton);
440 vGridXAUnitAlignedButton.addActionListener(new ActionListener() {
441 public void actionPerformed(ActionEvent e) {
442 GraphSettings gs = LiveGraph.application().getGraphSettings();
443 gs.setVGridType(VGrid_XAUnitAligned);
444 vGridNoneButton.setSelected(VGrid_None == gs.getVGridType());
445 vGridDSNumAlignedButton.setSelected(VGrid_DSNumAligned == gs.getVGridType());
446 vGridXAUnitAlignedButton.setSelected(VGrid_XAUnitAligned == gs.getVGridType());
447 vGridDetsPanel.setEnabled(VGrid_None != gs.getVGridType());
448 }
449 });
450
451 dim = new Dimension(20, 10);
452 gridPanel.add(new Box.Filler(dim, dim, dim), Tools.createGridBagConstraints(0, 4, 1, 1));
453
454 label = new JLabel("Grid size:");
455 label.setFont(SwingTools.getPlainFont(label));
456 vGridDetsPanel.add(label, Tools.createGridBagConstraints(0, 0, 1, 1));
457
458 vGridSizeField = new JTextField(StringTools.toString(gSettings.getVGridSize()), 4);
459 vGridDetsPanel.add(vGridSizeField, Tools.createGridBagConstraints(1, 0, 1, 1));
460 vGridSizeField.addFocusListener(fvalAdpt = new RealNumFieldValueChangeAdaptor(gSettings.getVGridSize()) {
461 @Override public double valueChanged(JTextField field, double newValue) {
462 GraphSettings gs = LiveGraph.application().getGraphSettings();
463 gs.setVGridSize(newValue);
464 return gs.getVGridSize();
465 }
466 });
467 vGridSizeField.addKeyListener(fvalAdpt);
468
469 label = new JLabel("Grid colour:");
470 label.setFont(SwingTools.getPlainFont(label));
471 vGridDetsPanel.add(label, Tools.createGridBagConstraints(0, 1, 1, 1));
472
473 vGridColourButton = new JButton();
474 vGridColourButton.setBackground(gSettings.getVGridColour());
475 dim = new Dimension(35, 15);
476 vGridColourButton.setSize(dim);
477 vGridColourButton.setPreferredSize(dim);
478 vGridDetsPanel.add(vGridColourButton, Tools.createGridBagConstraints(1, 1, 1, 1));
479 vGridColourButton.addActionListener(new ActionListener() {
480 public void actionPerformed(ActionEvent e) {
481 Color nc = JColorChooser.showDialog(thisPanel, "Choose a colour for the vertical grid:",
482 LiveGraph.application().getGraphSettings().getHGridColour());
483 if (null == nc) return;
484 GraphSettings gs = LiveGraph.application().getGraphSettings();
485 gs.setVGridColour(nc);
486 vGridColourButton.setBackground(gs.getVGridColour());
487 }
488 });
489 vGridDetsPanel.setEnabled(false);
490
491 // Horizontal grid:
492 gridPanel.add(new JLabel("Horizontal grid:"), Tools.createGridBagConstraints(4, 0, 3, 1));
493 bGroup = new ButtonGroup();
494
495 hGridDetsPanel = new DisEnablingPanel(new GridBagLayout());
496 gridPanel.add(hGridDetsPanel, Tools.createGridBagConstraints(5, 4, 1, 1));
497
498 hGridNoneButton = new JRadioButton("Do not display a grid",
499 gSettings.getHGridType() == HGrid_None);
500 hGridNoneButton.setFont(SwingTools.getPlainFont(hGridNoneButton));
501 gridPanel.add(hGridNoneButton, Tools.createGridBagConstraints(4, 1, 3, 1));
502 bGroup.add(hGridNoneButton);
503 hGridNoneButton.addActionListener(new ActionListener() {
504 public void actionPerformed(ActionEvent e) {
505 GraphSettings gs = LiveGraph.application().getGraphSettings();
506 gs.setHGridType(HGrid_None);
507 hGridNoneButton.setSelected(HGrid_None == gs.getHGridType());
508 hGridSimpleButton.setSelected(HGrid_Simple == gs.getHGridType());
509 hGridDetsPanel.setEnabled(HGrid_None != gs.getHGridType());
510 }
511 });
512
513 hGridSimpleButton = new JRadioButton("Display a horizontal grid",
514 gSettings.getHGridType() == HGrid_Simple);
515 hGridSimpleButton.setFont(SwingTools.getPlainFont(hGridSimpleButton));
516 gridPanel.add(hGridSimpleButton, Tools.createGridBagConstraints(4, 2, 3, 1));
517 bGroup.add(hGridSimpleButton);
518 hGridSimpleButton.addActionListener(new ActionListener() {
519 public void actionPerformed(ActionEvent e) {
520 GraphSettings gs = LiveGraph.application().getGraphSettings();
521 gs.setHGridType(HGrid_Simple);
522 hGridNoneButton.setSelected(HGrid_None == gs.getHGridType());
523 hGridSimpleButton.setSelected(HGrid_Simple == gs.getHGridType());
524 hGridDetsPanel.setEnabled(HGrid_None != gs.getHGridType());
525 }
526 });
527
528 dim = new Dimension(20, 10);
529 gridPanel.add(new Box.Filler(dim, dim, dim), Tools.createGridBagConstraints(0, 4, 1, 1));
530
531 label = new JLabel("Grid size:");
532 label.setFont(SwingTools.getPlainFont(label));
533 hGridDetsPanel.add(label, Tools.createGridBagConstraints(0, 0, 1, 1));
534
535 hGridSizeField = new JTextField(StringTools.toString(gSettings.getHGridSize()), 4);
536 hGridDetsPanel.add(hGridSizeField, Tools.createGridBagConstraints(1, 0, 1, 1));
537 hGridSizeField.addFocusListener(fvalAdpt = new RealNumFieldValueChangeAdaptor(gSettings.getHGridSize()) {
538 @Override public double valueChanged(JTextField field, double newValue) {
539 GraphSettings gs = LiveGraph.application().getGraphSettings();
540 gs.setHGridSize(newValue);
541 return gs.getHGridSize();
542 }
543 });
544 hGridSizeField.addKeyListener(fvalAdpt);
545
546 label = new JLabel("Grid colour:");
547 label.setFont(SwingTools.getPlainFont(label));
548 hGridDetsPanel.add(label, Tools.createGridBagConstraints(0, 1, 1, 1));
549
550 hGridColourButton = new JButton();
551 hGridColourButton.setBackground(gSettings.getHGridColour());
552 dim = new Dimension(35, 15);
553 hGridColourButton.setSize(dim);
554 hGridColourButton.setPreferredSize(dim);
555 hGridDetsPanel.add(hGridColourButton, Tools.createGridBagConstraints(1, 1, 1, 1));
556 hGridColourButton.addActionListener(new ActionListener() {
557 public void actionPerformed(ActionEvent e) {
558 Color nc = JColorChooser.showDialog(thisPanel, "Choose a colour for the horizontal grid:",
559 LiveGraph.application().getGraphSettings().getHGridColour());
560 if (null == nc) return;
561 GraphSettings gs = LiveGraph.application().getGraphSettings();
562 gs.setHGridColour(nc);
563 vGridColourButton.setBackground(gs.getHGridColour());
564 }
565 });
566 hGridDetsPanel.setEnabled(false);
567
568 // X axis settings:
569 JPanel xAxisPanel = new JPanel(new GridBagLayout());
570 thisPanel.add(xAxisPanel);
571 xAxisPanel.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
572
573 xAxisPanel.add(new JLabel("X axis:"), Tools.createGridBagConstraints(0, 0, 1, 1));
574
575 label = new JLabel("Type:");
576 xAxisPanel.add(label, Tools.createGridBagConstraints(0, 1, 1, 1));
577 label.setFont(SwingTools.getPlainFont(label));
578 label.setPreferredSize(new Dimension(100, label.getPreferredSize().height));
579 label.setMinimumSize(new Dimension(100, label.getMinimumSize().height));
580
581 xAxisTypeCombo = new ResizablePopupComboBox(xAxisTypeLabels);
582 switch(gSettings.getXAxisType()) {
583 case XAxis_DSNum: xAxisTypeCombo.setSelectedIndex(0); break;
584 case XAxis_DataValSimple: xAxisTypeCombo.setSelectedIndex(1); break;
585 case XAxis_DataValTrans0to1: xAxisTypeCombo.setSelectedIndex(2); break;
586 case XAxis_DataValScaleBySetVal: xAxisTypeCombo.setSelectedIndex(3); break;
587 case XAxis_DataValLogToSetBase: xAxisTypeCombo.setSelectedIndex(4); break;
588 case XAxis_DataValSecsToSetPower: xAxisTypeCombo.setSelectedIndex(5); break;
589 default: throw new UnexpectedSwitchCase(gSettings.getXAxisType());
590 }
591 xAxisPanel.add(xAxisTypeCombo, Tools.createGridBagConstraints(1, 1, 1, 1));
592 xAxisTypeCombo.setFont(SwingTools.getPlainFont(xAxisTypeCombo));
593 dim = new Dimension(panelDim.width - 150, xAxisTypeCombo.getPreferredSize().height);
594 xAxisTypeCombo.setPreferredSize(dim);
595 xAxisTypeCombo.setMinimumSize(dim);
596 xAxisTypeCombo.setMaximumSize(dim);
597 xAxisTypeCombo.addActionListener(new ActionListener() {
598 public void actionPerformed(ActionEvent e) {
599 int sel = xAxisTypeCombo.getSelectedIndex();
600 if (0 > sel)
601 return;
602 GraphSettings gs = LiveGraph.application().getGraphSettings();
603 switch(sel) {
604 case 0: gs.setXAxisType(XAxis_DSNum); break;
605 case 1: gs.setXAxisType(XAxis_DataValSimple); break;
606 case 2: gs.setXAxisType(XAxis_DataValTrans0to1); break;
607 case 3: gs.setXAxisType(XAxis_DataValScaleBySetVal); break;
608 case 4: gs.setXAxisType(XAxis_DataValLogToSetBase); break;
609 case 5: gs.setXAxisType(XAxis_DataValSecsToSetPower); break;
610 default: throw new UnexpectedSwitchCase(sel);
611 }
612 xAxisTypeSet(gs.getXAxisType());
613 }
614 });
615
616 xAxisSeriesLabel = new JLabel("Series:");
617 xAxisPanel.add(xAxisSeriesLabel, Tools.createGridBagConstraints(0, 2, 1, 1));
618 xAxisSeriesLabel.setFont(SwingTools.getPlainFont(xAxisSeriesLabel));
619 xAxisSeriesLabel.setEnabled(false);
620 xAxisSeriesLabel.setPreferredSize(new Dimension(100, xAxisSeriesLabel.getPreferredSize().height));
621 xAxisSeriesLabel.setMinimumSize(new Dimension(100, xAxisSeriesLabel.getMinimumSize().height));
622
623 xAxisSeriesCombo = new ResizablePopupComboBox(new String[] {});
624 preferredXAxisSeriesIndex = gSettings.getXAxisSeriesIndex();
625 xAxisPanel.add(xAxisSeriesCombo, Tools.createGridBagConstraints(1, 2, 1, 1));
626 dim = new Dimension(panelDim.width - 150, xAxisSeriesCombo.getPreferredSize().height);
627 xAxisSeriesCombo.setPreferredSize(dim);
628 xAxisSeriesCombo.setMinimumSize(dim);
629 xAxisSeriesCombo.setMaximumSize(dim);
630 updatingSeriesLabels = false;
631 xAxisSeriesCombo.addActionListener(new ActionListener() {
632 public void actionPerformed(ActionEvent e) {
633 if (updatingSeriesLabels || 0 > xAxisSeriesCombo.getSelectedIndex())
634 return;
635 GraphSettings gs = LiveGraph.application().getGraphSettings();
636 gs.setXAxisSeriesIndex(xAxisSeriesCombo.getSelectedIndex());
637
638 preferredXAxisSeriesIndex = Math.max(0, gs.getXAxisSeriesIndex());
639 xAxisSeriesCombo.setSelectedIndex(Math.min(xAxisSeriesCombo.getItemCount() - 1,
640 preferredXAxisSeriesIndex));
641 }
642 });
643
644 xAxisParameterLabel = new JLabel("Parameter:");
645 xAxisPanel.add(xAxisParameterLabel, Tools.createGridBagConstraints(0, 3, 1, 1));
646 xAxisParameterLabel.setFont(SwingTools.getPlainFont(xAxisParameterLabel));
647 xAxisParameterLabel.setEnabled(false);
648 xAxisParameterLabel.setPreferredSize(new Dimension(100, xAxisParameterLabel.getPreferredSize().height));
649 xAxisParameterLabel.setMinimumSize(new Dimension(100, xAxisParameterLabel.getMinimumSize().height));
650
651
652 xAxisParameterField = new JTextField(StringTools.toString(gSettings.getXAxisParamValue()));
653 xAxisPanel.add(xAxisParameterField, Tools.createGridBagConstraints(1, 3, 1, 1));
654 dim = new Dimension(panelDim.width - 150, xAxisParameterField.getPreferredSize().height);
655 xAxisParameterField.setPreferredSize(dim);
656 xAxisParameterField.setMinimumSize(dim);
657 xAxisParameterField.setMaximumSize(dim);
658 xAxisParameterField.addFocusListener(fvalAdpt = new RealNumFieldValueChangeAdaptor(gSettings.getXAxisParamValue()) {
659 @Override public double valueChanged(JTextField field, double newValue) {
660 GraphSettings gs = LiveGraph.application().getGraphSettings();
661 gs.setXAxisParamValue(newValue);
662 return gs.getXAxisParamValue();
663 }
664 });
665 xAxisParameterField.addKeyListener(fvalAdpt);
666
667
668 // Set all panes to the same width:
669 viewportPanel.setPreferredSize(new Dimension(panelDim.width - 20, viewportPanel.getPreferredSize().height));
670 gridPanel.setPreferredSize(new Dimension(panelDim.width - 20, gridPanel.getPreferredSize().height));
671 xAxisPanel.setPreferredSize(new Dimension(panelDim.width - 20, xAxisPanel.getPreferredSize().height));
672
673 } // private void initialize()
674
675 /**
676 * Updates the series selection drop down box with the specified series labels.
677 * @param labels Series labels.
678 */
679 public void setSeriesLabels(ReadOnlyIterator<String> labels) {
680
681 updatingSeriesLabels = true;
682
683 xAxisSeriesCombo.removeAllItems();
684
685 if (null == labels) {
686 updatingSeriesLabels = false;
687 return;
688 }
689
690 while (labels.hasNext()) {
691 xAxisSeriesCombo.addItem(labels.next());
692 }
693
694 if (preferredXAxisSeriesIndex < xAxisSeriesCombo.getItemCount())
695 xAxisSeriesCombo.setSelectedIndex(preferredXAxisSeriesIndex);
696 else
697 xAxisSeriesCombo.setSelectedIndex(xAxisSeriesCombo.getItemCount() - 1);
698
699 updatingSeriesLabels = false;
700 }
701
702 private void xAxisTypeSet(GraphSettings.XAxisType xAxisType) {
703 switch (xAxisType) {
704 case XAxis_DSNum: xAxisTypeCombo.setSelectedIndex(0);
705 xAxisSeriesLabel.setEnabled(false);
706 xAxisSeriesCombo.setEnabled(false);
707 xAxisParameterLabel.setText(xAxisParameterLabels[0]);
708 xAxisParameterLabel.setEnabled(false);
709 xAxisParameterField.setEnabled(false);
710 break;
711 case XAxis_DataValSimple: xAxisTypeCombo.setSelectedIndex(1);
712 xAxisSeriesLabel.setEnabled(true);
713 xAxisSeriesCombo.setEnabled(true);
714 xAxisParameterLabel.setText(xAxisParameterLabels[1]);
715 xAxisParameterLabel.setEnabled(false);
716 xAxisParameterField.setEnabled(false);
717 break;
718 case XAxis_DataValTrans0to1: xAxisTypeCombo.setSelectedIndex(2);
719 xAxisSeriesLabel.setEnabled(true);
720 xAxisSeriesCombo.setEnabled(true);
721 xAxisParameterLabel.setText(xAxisParameterLabels[2]);
722 xAxisParameterLabel.setEnabled(false);
723 xAxisParameterField.setEnabled(false);
724 break;
725 case XAxis_DataValScaleBySetVal: xAxisTypeCombo.setSelectedIndex(3);
726 xAxisSeriesLabel.setEnabled(true);
727 xAxisSeriesCombo.setEnabled(true);
728 xAxisParameterLabel.setText(xAxisParameterLabels[3]);
729 xAxisParameterLabel.setEnabled(true);
730 xAxisParameterField.setEnabled(true);
731 break;
732 case XAxis_DataValLogToSetBase: xAxisTypeCombo.setSelectedIndex(4);
733 xAxisSeriesLabel.setEnabled(true);
734 xAxisSeriesCombo.setEnabled(true);
735 xAxisParameterLabel.setText(xAxisParameterLabels[4]);
736 xAxisParameterLabel.setEnabled(true);
737 xAxisParameterField.setEnabled(true);
738 break;
739 case XAxis_DataValSecsToSetPower: xAxisTypeCombo.setSelectedIndex(5);
740 xAxisSeriesLabel.setEnabled(true);
741 xAxisSeriesCombo.setEnabled(true);
742 xAxisParameterLabel.setText(xAxisParameterLabels[5]);
743 xAxisParameterLabel.setEnabled(true);
744 xAxisParameterField.setEnabled(true);
745 break;
746 default: throw new UnexpectedSwitchCase(xAxisType);
747 }
748 }
749
750 /**
751 * Processes events.
752 *
753 * @param event Event to process.
754 */
755 @Override
756 public void eventRaised(Event<? extends EventType> event) {
757
758 super.eventRaised(event);
759
760 if (event.getDomain() == CacheEvent.class) {
761 processCacheEvent(event.cast(CacheEvent.class));
762 return;
763 }
764 }
765
766
767 /**
768 * Updates the series labels when the cache is updated.
769 *
770 * @param event The cache event.
771 */
772 private void processCacheEvent(Event<CacheEvent> event) {
773
774 if (CacheEvent.CACHE_UpdatedLabels == event.getType()) {
775 DataCache cache = (DataCache) event.getProducer();
776 synchronized (cache) {
777 setSeriesLabels(cache.iterateDataSeriesLabels());
778 }
779 }
780 }
781
782 /**
783 * Updates the display of the graph settings when they have been changed.
784 *
785 * @param event Describes the change event.
786 */
787 @Override
788 protected void processSettingsEvent(Event<SettingsEvent> event) {
789
790 final GraphSettings settings = LiveGraph.application().getGraphSettings();
791 final boolean loadEvent = (SettingsEvent.GS_Load == event.getType());
792
793 if (SettingsEvent.GS_MinY == event.getType() || loadEvent) {
794 if (Double.isNaN(settings.getMinY())) {
795 minYAutoButton.setSelected(true);
796 minYValButton.setSelected(false);
797 minYField.setEnabled(false);
798 } else {
799 minYAutoButton.setSelected(false);
800 minYValButton.setSelected(true);
801 minYField.setEnabled(true);
802 minYField.setText(StringTools.toString(settings.getMinY()));
803 }
804 }
805
806 if (SettingsEvent.GS_MaxY == event.getType() || loadEvent) {
807 if (Double.isNaN(settings.getMaxY())) {
808 maxYAutoButton.setSelected(true);
809 maxYValButton.setSelected(false);
810 maxYField.setEnabled(false);
811 } else {
812 maxYAutoButton.setSelected(false);
813 maxYValButton.setSelected(true);
814 maxYField.setEnabled(true);
815 maxYField.setText(StringTools.toString(settings.getMaxY()));
816 }
817 }
818
819 if (SettingsEvent.GS_MinX == event.getType() || loadEvent) {
820 if (Double.isNaN(settings.getMinX())) {
821 minXAutoButton.setSelected(true);
822 minXValButton.setSelected(false);
823 minXField.setEnabled(false);
824 } else {
825 minXAutoButton.setSelected(false);
826 minXValButton.setSelected(true);
827 minXField.setEnabled(true);
828 minXField.setText(StringTools.toString(settings.getMinX()));
829 }
830 }
831
832 if (SettingsEvent.GS_MaxX == event.getType() || loadEvent) {
833 if (Double.isNaN(settings.getMaxX())) {
834 maxXAutoButton.setSelected(true);
835 maxXValButton.setSelected(false);
836 maxXField.setEnabled(false);
837 } else {
838 maxXAutoButton.setSelected(false);
839 maxXValButton.setSelected(true);
840 maxXField.setEnabled(true);
841 maxXField.setText(StringTools.toString(settings.getMaxX()));
842 }
843 }
844
845 if (SettingsEvent.GS_VGridType == event.getType() || loadEvent) {
846 switch (settings.getVGridType()) {
847 case VGrid_None: vGridDetsPanel.setEnabled(false);
848 vGridNoneButton.setSelected(true);
849 break;
850 case VGrid_DSNumAligned: vGridDetsPanel.setEnabled(true);
851 vGridDSNumAlignedButton.setSelected(true);
852 break;
853 case VGrid_XAUnitAligned: vGridDetsPanel.setEnabled(true);
854 vGridXAUnitAlignedButton.setSelected(true);
855 break;
856 default: throw new UnexpectedSwitchCase(settings.getVGridType());
857 }
858 }
859
860 if (SettingsEvent.GS_VGridSize == event.getType() || loadEvent) {
861 vGridSizeField.setText(StringTools.toString(settings.getVGridSize()));
862 }
863
864 if (SettingsEvent.GS_VGridColour == event.getType() || loadEvent) {
865 vGridColourButton.setBackground(settings.getVGridColour());
866 }
867
868 if (SettingsEvent.GS_HGridType == event.getType() || loadEvent) {
869 switch (settings.getHGridType()) {
870 case HGrid_None: hGridDetsPanel.setEnabled(false);
871 hGridNoneButton.setSelected(true);
872 break;
873 case HGrid_Simple: hGridDetsPanel.setEnabled(true);
874 hGridSimpleButton.setSelected(true);
875 break;
876 default: throw new UnexpectedSwitchCase(settings.getHGridType());
877 }
878 }
879
880 if (SettingsEvent.GS_HGridSize == event.getType() || loadEvent) {
881 hGridSizeField.setText(StringTools.toString(settings.getHGridSize()));
882 }
883
884 if (SettingsEvent.GS_HGridColour == event.getType() || loadEvent) {
885 hGridColourButton.setBackground(settings.getHGridColour());
886 }
887
888 if (SettingsEvent.GS_XAxisType == event.getType() || loadEvent) {
889 xAxisTypeSet(settings.getXAxisType());
890 }
891
892 if (SettingsEvent.GS_XAxisSeriesIndex == event.getType() || loadEvent) {
893 preferredXAxisSeriesIndex = Math.max(0, settings.getXAxisSeriesIndex());
894 xAxisSeriesCombo.setSelectedIndex(Math.min(xAxisSeriesCombo.getItemCount() - 1,
895 preferredXAxisSeriesIndex));
896 }
897
898 if (SettingsEvent.GS_XAxisParamValue == event.getType() || loadEvent) {
899 xAxisParameterField.setText(StringTools.toString(settings.getXAxisParamValue()));
900 }
901 } // protected void processSettingsEvent
902
903 } // public class GraphSettingsPanel