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