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