001 package org.LiveGraph.gui; 002 003 import java.awt.event.ActionEvent; 004 import java.awt.event.ActionListener; 005 import java.io.File; 006 import java.io.FileNotFoundException; 007 008 import javax.swing.Box; 009 import javax.swing.JCheckBoxMenuItem; 010 import javax.swing.JFileChooser; 011 import javax.swing.JMenu; 012 import javax.swing.JMenuBar; 013 import javax.swing.JMenuItem; 014 import javax.swing.JOptionPane; 015 import javax.swing.filechooser.FileFilter; 016 017 import org.LiveGraph.LiveGraph; 018 import org.LiveGraph.events.Event; 019 import org.LiveGraph.events.EventListener; 020 import org.LiveGraph.events.EventManager; 021 import org.LiveGraph.events.EventType; 022 import org.LiveGraph.settings.DataFileSettings; 023 import org.LiveGraph.settings.DataSeriesSettings; 024 import org.LiveGraph.settings.GraphSettings; 025 026 027 /** 028 * Provides a LiveGraph application menu bar. 029 * 030 * <p> 031 * <strong>LiveGraph</strong> 032 * (<a href="http://www.live-graph.org" target="_blank">http://www.live-graph.org</a>). 033 * </p> 034 * <p>Copyright (c) 2007-2008 by G. Paperin.</p> 035 * <p>File: MainMenuBar.java</p> 036 * <p style="font-size:smaller;">Redistribution and use in source and binary forms, with or 037 * without modification, are permitted provided that the following terms and conditions are met: 038 * </p> 039 * <p style="font-size:smaller;">1. Redistributions of source code must retain the above 040 * acknowledgement of the LiveGraph project and its web-site, the above copyright notice, 041 * this list of conditions and the following disclaimer.<br /> 042 * 2. Redistributions in binary form must reproduce the above acknowledgement of the 043 * LiveGraph project and its web-site, the above copyright notice, this list of conditions 044 * and the following disclaimer in the documentation and/or other materials provided with 045 * the distribution.<br /> 046 * 3. All advertising materials mentioning features or use of this software or any derived 047 * software must display the following acknowledgement:<br /> 048 * <em>This product includes software developed by the LiveGraph project and its 049 * contributors.<br />(http://www.live-graph.org)</em><br /> 050 * 4. All advertising materials distributed in form of HTML pages or any other technology 051 * permitting active hyper-links that mention features or use of this software or any 052 * derived software must display the acknowledgment specified in condition 3 of this 053 * agreement, and in addition, include a visible and working hyper-link to the LiveGraph 054 * homepage (http://www.live-graph.org). 055 * </p> 056 * <p style="font-size:smaller;">THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY 057 * OF ANY KIND, EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 058 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 059 * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 060 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 061 * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 062 * </p> 063 * 064 * @author Greg Paperin (<a href="http://www.paperin.org" target="_blank">http://www.paperin.org</a>) 065 * @version {@value org.LiveGraph.LiveGraph#version} 066 * 067 */ 068 /*package*/ class MainMenuBar extends JMenuBar implements EventListener { 069 070 private JFileChooser dataFileSettingsFileDlg = null; 071 private JFileChooser graphSettingsFileDlg = null; 072 private JFileChooser seriesSettingsFileDlg = null; 073 074 private JCheckBoxMenuItem dataFileSettingsDisplayMenuItem = null; 075 private JCheckBoxMenuItem graphSettingsDisplayMenuItem = null; 076 private JCheckBoxMenuItem seriesSettingsDisplayMenuItem = null; 077 private JCheckBoxMenuItem messsagesDisplayMenuItem = null; 078 079 public MainMenuBar() { 080 init(); 081 } 082 083 private void init() { 084 085 // File Dialogs: 086 087 try { 088 dataFileSettingsFileDlg = new JFileChooser(""); 089 dataFileSettingsFileDlg.setFileFilter(new FileFilter() { 090 @Override public boolean accept(File f) { 091 if (null == f) return false; 092 if (f.isDirectory()) return true; 093 int p = f.getName().lastIndexOf("."); 094 return p < 0 095 ? false 096 : f.getName().substring(p).equalsIgnoreCase(DataFileSettings.preferredFileExtension); 097 } 098 @Override public String getDescription() { 099 return "LiveGraph data file settings (*" + DataFileSettings.preferredFileExtension + ")"; 100 } 101 }); 102 try { 103 dataFileSettingsFileDlg.setCurrentDirectory(new File(System.getProperty("user.dir"))); 104 } catch(SecurityException e) { 105 dataFileSettingsFileDlg.setCurrentDirectory(new File(System.getProperty("user.home"))); 106 } 107 } catch(SecurityException e) { 108 dataFileSettingsFileDlg = null; 109 } 110 111 112 try { 113 graphSettingsFileDlg = new JFileChooser(""); 114 graphSettingsFileDlg.setFileFilter(new FileFilter() { 115 @Override public boolean accept(File f) { 116 if (null == f) return false; 117 if (f.isDirectory()) return true; 118 int p = f.getName().lastIndexOf("."); 119 return p < 0 120 ? false 121 : f.getName().substring(p).equalsIgnoreCase(GraphSettings.preferredFileExtension); 122 } 123 @Override public String getDescription() { 124 return "LiveGraph graph settings (*" + GraphSettings.preferredFileExtension + ")"; 125 } 126 }); 127 try { 128 graphSettingsFileDlg.setCurrentDirectory(new File(System.getProperty("user.dir"))); 129 } catch(SecurityException e) { 130 graphSettingsFileDlg.setCurrentDirectory(new File(System.getProperty("user.home"))); 131 } 132 } catch(SecurityException e) { 133 graphSettingsFileDlg = null; 134 } 135 136 137 try { 138 seriesSettingsFileDlg = new JFileChooser(); 139 seriesSettingsFileDlg.setFileFilter(new FileFilter() { 140 @Override public boolean accept(File f) { 141 if (null == f) return false; 142 if (f.isDirectory()) return true; 143 int p = f.getName().lastIndexOf("."); 144 return p < 0 145 ? false 146 : f.getName().substring(p).equalsIgnoreCase(DataSeriesSettings.preferredFileExtension); 147 } 148 @Override public String getDescription() { 149 return "LiveGraph data series settings (*" + DataSeriesSettings.preferredFileExtension + ")"; 150 } 151 }); 152 try { 153 seriesSettingsFileDlg.setCurrentDirectory(new File(System.getProperty("user.dir"))); 154 } catch(SecurityException e) { 155 seriesSettingsFileDlg.setCurrentDirectory(new File(System.getProperty("user.home"))); 156 } 157 } catch(SecurityException e) { 158 seriesSettingsFileDlg = null; 159 } 160 161 162 // Temp variables: 163 JMenu menu = null; 164 JMenuItem mItem = null; 165 166 167 // Data file setings menu: 168 169 menu = new JMenu("Data file"); 170 171 mItem = new JMenuItem("Load data file settings..."); 172 mItem.addActionListener(new ActionListener() { 173 public void actionPerformed(ActionEvent e) { loadDataFileSettings(); } 174 }); 175 menu.add(mItem); 176 mItem.setEnabled(null != dataFileSettingsFileDlg); 177 178 mItem = new JMenuItem("Save data file settings..."); 179 mItem.addActionListener(new ActionListener() { 180 public void actionPerformed(ActionEvent e) { saveDataFileSettings(); } 181 }); 182 menu.add(mItem); 183 mItem.setEnabled(null != dataFileSettingsFileDlg); 184 menu.addSeparator(); 185 186 dataFileSettingsDisplayMenuItem = new JCheckBoxMenuItem("Display data file settings"); 187 dataFileSettingsDisplayMenuItem.addActionListener(new ActionListener() { 188 public void actionPerformed(ActionEvent e) { 189 visibilityDataFileSettings(); 190 } 191 }); 192 menu.add(dataFileSettingsDisplayMenuItem); 193 this.add(menu); 194 195 196 // Graph setings menu: 197 198 menu = new JMenu("Graph settings"); 199 200 mItem = new JMenuItem("Load graph settings..."); 201 mItem.addActionListener(new ActionListener() { 202 public void actionPerformed(ActionEvent e) { loadGraphSettings(); } 203 }); 204 menu.add(mItem); 205 mItem.setEnabled(null != graphSettingsFileDlg); 206 207 mItem = new JMenuItem("Save graph settings..."); 208 mItem.addActionListener(new ActionListener() { 209 public void actionPerformed(ActionEvent e) { saveGraphSettings(); } 210 }); 211 menu.add(mItem); 212 mItem.setEnabled(null != graphSettingsFileDlg); 213 menu.addSeparator(); 214 215 graphSettingsDisplayMenuItem = new JCheckBoxMenuItem("Display graph settings"); 216 graphSettingsDisplayMenuItem.addActionListener(new ActionListener() { 217 public void actionPerformed(ActionEvent e) { visibilityGraphSettings(); } 218 }); 219 menu.add(graphSettingsDisplayMenuItem); 220 this.add(menu); 221 222 223 // Data series settings menu: 224 225 menu = new JMenu("Data series"); 226 227 mItem = new JMenuItem("Load data series settings..."); 228 mItem.addActionListener(new ActionListener() { 229 public void actionPerformed(ActionEvent e) { loadDataSeriesSettings(); } 230 }); 231 menu.add(mItem); 232 mItem.setEnabled(null != seriesSettingsFileDlg); 233 234 mItem = new JMenuItem("Save data series settings..."); 235 mItem.addActionListener(new ActionListener() { 236 public void actionPerformed(ActionEvent e) { saveDataSeriesSettings(); } 237 }); 238 menu.add(mItem); 239 mItem.setEnabled(null != seriesSettingsFileDlg); 240 menu.addSeparator(); 241 242 seriesSettingsDisplayMenuItem = new JCheckBoxMenuItem("Display data series settings"); 243 seriesSettingsDisplayMenuItem.addActionListener(new ActionListener() { 244 public void actionPerformed(ActionEvent e) { visibilityDataSeriesSettings(); } 245 }); 246 menu.add(seriesSettingsDisplayMenuItem); 247 this.add(menu); 248 249 250 // Messages menu: 251 252 menu = new JMenu("Messages"); 253 254 messsagesDisplayMenuItem = new JCheckBoxMenuItem("Display message window"); 255 messsagesDisplayMenuItem.addActionListener(new ActionListener() { 256 public void actionPerformed(ActionEvent e) { visibilityMessageWindow(); } 257 }); 258 menu.add(messsagesDisplayMenuItem); 259 this.add(menu); 260 261 262 // Plot menu: 263 264 menu = new JMenu("Plot"); 265 mItem = new JMenuItem("Export graph to image..."); 266 mItem.addActionListener(new ActionListener() { 267 public void actionPerformed(ActionEvent e) { exportPlot(); } 268 }); 269 menu.add(mItem); 270 this.add(menu); 271 272 this.add(Box.createHorizontalGlue()); 273 274 275 // Help menu: 276 277 menu = new JMenu("Help"); 278 mItem = new JMenuItem("Support..."); 279 mItem.addActionListener(new ActionListener() { 280 public void actionPerformed(ActionEvent e) { showSupportInfo(); } 281 }); 282 menu.add(mItem); 283 284 mItem = new JMenuItem("Software update..."); 285 mItem.addActionListener(new ActionListener() { 286 public void actionPerformed(ActionEvent e) { displayUpdateDialog(); } 287 }); 288 menu.add(mItem); 289 mItem.setEnabled(LiveGraph.application().standalone()); 290 291 mItem = new JMenuItem("Info..."); 292 mItem.addActionListener(new ActionListener() { 293 public void actionPerformed(ActionEvent e) { showProgramInfo(); } 294 }); 295 menu.add(mItem); 296 this.add(menu); 297 } 298 299 300 private void loadDataFileSettings() { 301 302 if (JFileChooser.APPROVE_OPTION != dataFileSettingsFileDlg.showOpenDialog(this.getParent())) 303 return; 304 305 File selFile = dataFileSettingsFileDlg.getSelectedFile(); 306 if (!selFile.exists()) 307 return; 308 309 if (!LiveGraph.application().getDataFileSettings().load(selFile.getAbsolutePath(), false)) 310 LiveGraph.application().guiManager().logErrorLn("Error while loading data file settings from " + selFile.getName() + "."); 311 312 } 313 314 private void saveDataFileSettings() { 315 316 if (JFileChooser.APPROVE_OPTION != dataFileSettingsFileDlg.showSaveDialog(this.getParent())) 317 return; 318 319 File selFile = dataFileSettingsFileDlg.getSelectedFile(); 320 if (!selFile.getParentFile().exists()) 321 return; 322 323 if (!selFile.getName().contains(".")) 324 selFile = new File(selFile.getAbsolutePath() + DataFileSettings.preferredFileExtension); 325 326 if (!LiveGraph.application().getDataFileSettings().save(selFile.getAbsolutePath())) 327 LiveGraph.application().guiManager().logErrorLn("Error while saving data file settings to " + selFile.getName() + "."); 328 } 329 330 private void visibilityDataFileSettings() { 331 LiveGraph.application().guiManager().setDisplayDataFileSettingsWindows(dataFileSettingsDisplayMenuItem.getState()); 332 // For testing - remove later: 333 //LiveGraph.application().guiManager().createDataFileSettingsWindow(); 334 //LiveGraph.application().guiManager().setDisplayDataFileSettingsWindows(true); 335 } 336 337 private void loadGraphSettings() { 338 339 if (JFileChooser.APPROVE_OPTION != graphSettingsFileDlg.showOpenDialog(this.getParent())) 340 return; 341 342 File selFile = graphSettingsFileDlg.getSelectedFile(); 343 if (!selFile.exists()) 344 return; 345 346 if (!LiveGraph.application().getGraphSettings().load(selFile.getAbsolutePath())) 347 LiveGraph.application().guiManager().logErrorLn("Error while loading graph settings from " + selFile.getName() + "."); 348 349 } 350 351 private void saveGraphSettings() { 352 353 if (JFileChooser.APPROVE_OPTION != graphSettingsFileDlg.showSaveDialog(this.getParent())) 354 return; 355 356 File selFile = graphSettingsFileDlg.getSelectedFile(); 357 if (!selFile.getParentFile().exists()) 358 return; 359 360 if (!selFile.getName().contains(".")) 361 selFile = new File(selFile.getAbsolutePath() + GraphSettings.preferredFileExtension); 362 363 if (!LiveGraph.application().getGraphSettings().save(selFile.getAbsolutePath())) 364 LiveGraph.application().guiManager().logErrorLn("Error while saving graph settings to " + selFile.getName() + "."); 365 } 366 367 private void visibilityGraphSettings() { 368 LiveGraph.application().guiManager().setDisplayGraphSettingsWindows(graphSettingsDisplayMenuItem.getState()); 369 // For testing - remove later: 370 //LiveGraph.application().guiManager().createGraphSettingsWindow(); 371 //LiveGraph.application().guiManager().setDisplayGraphSettingsWindows(true); 372 } 373 374 private void loadDataSeriesSettings() { 375 376 if (JFileChooser.APPROVE_OPTION != seriesSettingsFileDlg.showOpenDialog(this.getParent())) 377 return; 378 379 File selFile = seriesSettingsFileDlg.getSelectedFile(); 380 if (!selFile.exists()) 381 return; 382 383 if (!LiveGraph.application().getDataSeriesSettings().load(selFile.getAbsolutePath())) 384 LiveGraph.application().guiManager().logErrorLn("Error while loading data series settings from " + selFile.getName() + "."); 385 } 386 387 private void saveDataSeriesSettings() { 388 389 if (JFileChooser.APPROVE_OPTION != seriesSettingsFileDlg.showSaveDialog(this.getParent())) 390 return; 391 392 File selFile = seriesSettingsFileDlg.getSelectedFile(); 393 if (!selFile.getParentFile().exists()) 394 return; 395 396 if (!selFile.getName().contains(".")) 397 selFile = new File(selFile.getAbsolutePath() + DataSeriesSettings.preferredFileExtension); 398 399 if (!LiveGraph.application().getDataSeriesSettings().save(selFile.getAbsolutePath())) 400 LiveGraph.application().guiManager().logErrorLn("Error while saving data series settings to " + selFile.getName() + "."); 401 } 402 403 private void visibilityDataSeriesSettings() { 404 LiveGraph.application().guiManager().setDisplaySeriesSettingsWindows(seriesSettingsDisplayMenuItem.getState()); 405 // For testing - remove later: 406 //LiveGraph.application().guiManager().createSeriesSettingsWindow(); 407 //LiveGraph.application().guiManager().setDisplaySeriesSettingsWindows(true); 408 } 409 410 private void visibilityMessageWindow() { 411 LiveGraph.application().guiManager().setDisplayMessageWindows(messsagesDisplayMenuItem.getState()); 412 } 413 414 private void exportPlot() { 415 LiveGraph.application().getGraphExporter().exportGraph(); 416 } 417 418 private void showSupportInfo() { 419 JOptionPane.showMessageDialog(this.getParent(), 420 "For help using LiveGraph " + LiveGraph.version + " please refer to the user manual at:\n" + 421 "http://www.live-graph.org/userManual.html\n\n" + 422 "In addition you can visit our support forums at:\n" + 423 "http://sourceforge.net/forum/?group_id=191061\n\n" + 424 "For further information browse the LiveGraph website at:\n" + 425 "http://www.live-graph.org\n ", 426 "Help", 427 JOptionPane.INFORMATION_MESSAGE); 428 } 429 430 private void displayUpdateDialog() { 431 LiveGraph.application().upgradeManager().upgradeOptionsDialog(); 432 } 433 434 private void showProgramInfo() { 435 JOptionPane.showMessageDialog(this.getParent(), 436 "LiveGraph\nVersion " + LiveGraph.version + "\n" + 437 "http://www.live-graph.org\n\n" + 438 "Developed by Greg Paperin\n(http://www.paperin.org)\n" + 439 "at Monash University\n ", 440 "LiveGraph " + LiveGraph.version + " credits", 441 JOptionPane.INFORMATION_MESSAGE); 442 } 443 444 445 /** 446 * Permits to register as listener with the main LiveGraph event manager and 447 * only with the main LiveGraph event manager. 448 * 449 * @param manager The {@code EventManager} for the registering attempt. 450 * @return {@code (LiveGraph.application().eventManager() == manager)}. 451 * @see EventListener#permissionRegisterWithEventManager(EventManager) 452 */ 453 public boolean permissionRegisterWithEventManager(EventManager manager) { 454 return LiveGraph.application().eventManager() == manager; 455 } 456 457 /** 458 * Does not permit any unregistering. 459 * 460 * @param manager The {@code EventManager} for the registering attempt. 461 * @return {@code false}. 462 * @see EventListener#permissionUnregisterWithEventManager(EventManager) 463 */ 464 public boolean permissionUnregisterWithEventManager(EventManager manager) { 465 return false; 466 } 467 468 /** 469 * Does nothing. 470 * 471 * @param manager The {@code EventManager} with which this {@code EventListener} is now registered. 472 * @see EventListener#completedRegisterWithEventManager(EventManager) 473 */ 474 public void completedRegisterWithEventManager(EventManager manager) { } 475 476 /** 477 * Does nothing. 478 * 479 * @param manager The {@code EventManager} with which this {@code EventListener} is now unregistered. 480 * @see EventListener#completedUnregisterWithEventManager(EventManager) 481 */ 482 public void completedUnregisterWithEventManager(EventManager manager) { } 483 484 /** 485 * Does nothing. 486 * 487 * @param event An event in which this {@code EventListener} may be interested. 488 * @return {@code false}. 489 * @see EventListener#checkEventInterest(Event) 490 */ 491 public boolean checkEventInterest(Event<? extends EventType> event) { 492 return false; 493 } 494 495 /** 496 * Does nothing. 497 * 498 * @param event The event to be validated. 499 * @param soFar Whether {@code event} has been successfuly validated by whichever {@code EventListener}s 500 * (if any) were invoked to validate {@code event} before this {@code EventListener}. 501 * @return {@code true}. 502 * @see EventListener#checkEventValid(Event, boolean) 503 */ 504 public boolean checkEventValid(Event<? extends EventType> event, boolean soFar) { 505 return true; 506 } 507 508 509 /** 510 * Processes events. 511 * 512 * @param event Event to process. 513 * @throws FileNotFoundException If could not read new data file. 514 */ 515 public void eventRaised(Event<? extends EventType> event) throws FileNotFoundException { 516 517 if (event.getDomain() == GUIEvent.class) { 518 processGUIEvent(event.cast(GUIEvent.class)); 519 return; 520 } 521 } 522 523 /** 524 * Updates local view on GUI events. 525 * 526 * @param event The GUI event. 527 */ 528 private void processGUIEvent(Event<GUIEvent> event) { 529 530 switch(event.getType()) { 531 532 case GUI_DataFileSettingsDisplayStateChanged: 533 dataFileSettingsDisplayMenuItem.setState(event.getInfoBoolean()); 534 break; 535 536 case GUI_GraphSettingsDisplayStateChanged: 537 graphSettingsDisplayMenuItem.setState(event.getInfoBoolean()); 538 break; 539 540 case GUI_DataSeriesSettingsDisplayStateChanged: 541 seriesSettingsDisplayMenuItem.setState(event.getInfoBoolean()); 542 break; 543 544 case GUI_MessagesDisplayStateChanged: 545 messsagesDisplayMenuItem.setState(event.getInfoBoolean()); 546 break; 547 548 default: 549 break; 550 551 } 552 } // private void processGUIEvent(Event<GUIEvent> event) 553 554 } // public class MainMenuBar