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