1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 package org.diyefi.openlogviewer;
30
31 import java.awt.BorderLayout;
32 import java.awt.Dimension;
33 import java.awt.GraphicsDevice;
34 import java.awt.GraphicsEnvironment;
35 import java.awt.Toolkit;
36 import java.awt.event.ActionEvent;
37 import java.awt.event.ActionListener;
38 import java.awt.event.WindowEvent;
39 import java.io.File;
40 import java.io.IOException;
41 import java.io.FileInputStream;
42 import java.io.FileOutputStream;
43 import java.util.List;
44 import java.util.ArrayList;
45 import java.util.Locale;
46 import java.util.Properties;
47 import java.util.ResourceBundle;
48
49 import javax.swing.JFileChooser;
50 import javax.swing.JFrame;
51 import javax.swing.JMenu;
52 import javax.swing.JMenuBar;
53 import javax.swing.JMenuItem;
54 import javax.swing.JPanel;
55 import javax.swing.UIManager;
56 import javax.swing.UnsupportedLookAndFeelException;
57 import javax.swing.WindowConstants;
58 import javax.swing.filechooser.FileFilter;
59
60 import org.diyefi.openlogviewer.decoder.AbstractDecoder;
61 import org.diyefi.openlogviewer.decoder.CSVTypeLog;
62 import org.diyefi.openlogviewer.decoder.FreeEMSBin;
63 import org.diyefi.openlogviewer.filefilters.CSVFileFilter;
64 import org.diyefi.openlogviewer.filefilters.FreeEMSBinFileFilter;
65 import org.diyefi.openlogviewer.filefilters.FreeEMSLAFileFilter;
66 import org.diyefi.openlogviewer.filefilters.LogFileFilter;
67 import org.diyefi.openlogviewer.filefilters.MSTypeFileFilter;
68 import org.diyefi.openlogviewer.filefilters.FreeEMSFileFilter;
69 import org.diyefi.openlogviewer.genericlog.GenericLog;
70 import org.diyefi.openlogviewer.graphing.EntireGraphingPanel;
71 import org.diyefi.openlogviewer.graphing.MultiGraphLayeredPane;
72 import org.diyefi.openlogviewer.optionpanel.OptionFrameV2;
73 import org.diyefi.openlogviewer.propertypanel.PropertiesPane;
74 import org.diyefi.openlogviewer.propertypanel.SingleProperty;
75 import org.diyefi.openlogviewer.utils.Utilities;
76
77 public final class OpenLogViewer extends JFrame {
78 public static final String NEWLINE = System.getProperty("line.separator");
79
80 private static final long serialVersionUID = 1L;
81
82 private static final String APPLICATION_NAME = OpenLogViewer.class.getSimpleName();
83 private static final String SETTINGS_DIRECTORY = "." + APPLICATION_NAME;
84
85 private static final String FILE_MENU_KEY = "FileMenuName";
86 private static final String FILE_MENU_ITEM_OPEN_KEY = "FileMenuItemOpenName";
87 private static final String FILE_MENU_ITEM_QUIT_KEY = "FileMenuItemQuitName";
88
89 private static final String VIEW_MENU_KEY = "ViewMenuName";
90 private static final String VIEW_MENU_ITEM_FULL_SCREEN_KEY = "ViewMenuItemFullScreenName";
91 private static final String VIEW_MENU_ITEM_SCALE_AND_COLOR_KEY = "ViewMenuItemScaleAndColorName";
92 private static final String VIEW_MENU_ITEM_FIELDS_AND_DIVISIONS_KEY = "ViewMenuItemFieldsAndDivisionsName";
93
94 private static final String FAILED_TO_GO_FULLSCREEN_MESSAGE_KEY = "FailedToGoFullScreenMessage";
95 private static final String CANT_GO_FULLSCREEN_MESSAGE_KEY = "CantGoFullScreenMessage";
96
97
98 private static final String PROPERTIES_FILENAME = "OLVAllProperties.olv";
99
100 private static final String NAME_OF_LAST_FILE_KEY = "lastFingFile";
101 private static final String NAME_OF_LAST_DIR_KEY = "lastFingDir";
102 private static final String NAME_OF_LAST_CHOOSER_CLASS = "chooserClass";
103
104
105 private static OpenLogViewer mainAppRef;
106 private static ResourceBundle labels;
107
108 private JPanel mainPanel;
109 private EntireGraphingPanel graphingPanel;
110 private PlayBarPanel playBar;
111 private OptionFrameV2 optionFrame;
112 private PropertiesPane prefFrame;
113
114 private List<SingleProperty> properties;
115 private AbstractDecoder decoderInUse;
116 private JMenuBar menuBar;
117 private boolean fullscreen;
118
119 public OpenLogViewer() {
120 prefFrame = new PropertiesPane(labels.getString(VIEW_MENU_ITEM_SCALE_AND_COLOR_KEY));
121 properties = new ArrayList<SingleProperty>();
122 prefFrame.setProperties(properties);
123
124 playBar = new PlayBarPanel();
125 optionFrame = new OptionFrameV2();
126 graphingPanel = new EntireGraphingPanel();
127 graphingPanel.setPreferredSize(new Dimension(600, 420));
128
129 this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
130 this.setTitle(APPLICATION_NAME);
131 this.setLayout(new BorderLayout());
132 this.setFocusable(true);
133
134 mainPanel = new JPanel();
135 mainPanel.setName("mainPanel");
136 mainPanel.setLayout(new BorderLayout());
137 mainPanel.add(graphingPanel, BorderLayout.CENTER);
138 mainPanel.add(playBar, BorderLayout.SOUTH);
139 this.add(mainPanel, BorderLayout.CENTER);
140
141 final JMenuItem openFileMenuItem = new JMenuItem(labels.getString(FILE_MENU_ITEM_OPEN_KEY));
142 openFileMenuItem.setName(FILE_MENU_ITEM_OPEN_KEY);
143 openFileMenuItem.addActionListener(new ActionListener() {
144 @Override
145 public void actionPerformed(final ActionEvent e) {
146 openFile();
147 }
148 });
149
150 final JMenuItem quitFileMenuItem = new JMenuItem(labels.getString(FILE_MENU_ITEM_QUIT_KEY));
151 quitFileMenuItem.setName(FILE_MENU_ITEM_QUIT_KEY);
152 quitFileMenuItem.addActionListener(new ActionListener() {
153 @Override
154 public void actionPerformed(final ActionEvent e) {
155 final WindowEvent wev = new WindowEvent(OpenLogViewer.getInstance(), WindowEvent.WINDOW_CLOSING);
156 Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(wev);
157 }
158 });
159
160 final JMenuItem fullScreenViewMenuItem = new JMenuItem(labels.getString(VIEW_MENU_ITEM_FULL_SCREEN_KEY));
161 fullScreenViewMenuItem.setName(VIEW_MENU_ITEM_FULL_SCREEN_KEY);
162 fullScreenViewMenuItem.addActionListener(new ActionListener() {
163 @Override
164 public void actionPerformed(final ActionEvent e) {
165 enterFullScreen();
166 }
167 });
168
169 final JMenuItem scaleAndColorViewMenuItem = new JMenuItem(labels.getString(VIEW_MENU_ITEM_SCALE_AND_COLOR_KEY));
170 scaleAndColorViewMenuItem.setName(VIEW_MENU_ITEM_SCALE_AND_COLOR_KEY);
171 scaleAndColorViewMenuItem.addActionListener(new ActionListener() {
172 @Override
173 public void actionPerformed(final ActionEvent e) {
174 prefFrame.setVisible(true);
175 prefFrame.setAlwaysOnTop(true);
176 prefFrame.setAlwaysOnTop(false);
177 }
178 });
179
180 final JMenuItem fieldsAndDivisionsViewMenuItem = new JMenuItem(labels.getString(VIEW_MENU_ITEM_FIELDS_AND_DIVISIONS_KEY));
181 fieldsAndDivisionsViewMenuItem.setName(VIEW_MENU_ITEM_FIELDS_AND_DIVISIONS_KEY);
182 fieldsAndDivisionsViewMenuItem.addActionListener(new ActionListener() {
183 @Override
184 public void actionPerformed(final ActionEvent e) {
185 optionFrame.setVisible(true);
186 optionFrame.setAlwaysOnTop(true);
187 optionFrame.setAlwaysOnTop(false);
188 }
189 });
190
191
192
193
194
195
196
197
198
199
200 final JMenu fileMenu = new JMenu(labels.getString(FILE_MENU_KEY));
201 fileMenu.setName(FILE_MENU_KEY);
202 fileMenu.add(openFileMenuItem);
203 fileMenu.add(quitFileMenuItem);
204
205 final JMenu viewMenu = new JMenu(labels.getString(VIEW_MENU_KEY));
206 viewMenu.setName(VIEW_MENU_KEY);
207 viewMenu.add(fullScreenViewMenuItem);
208 viewMenu.add(scaleAndColorViewMenuItem);
209 viewMenu.add(fieldsAndDivisionsViewMenuItem);
210
211 menuBar = new JMenuBar();
212 menuBar.setName("menuBar");
213 menuBar.add(fileMenu);
214 menuBar.add(viewMenu);
215 setJMenuBar(menuBar);
216
217 this.addKeyListener(graphingPanel);
218 this.addComponentListener(graphingPanel);
219
220 pack();
221
222 this.setVisible(true);
223 }
224
225
226
227
228
229
230 public static void main(final String[] args) {
231 java.awt.EventQueue.invokeLater(new Runnable() {
232
233 @Override
234 public void run() {
235 final Locale currentLocale = Locale.getDefault();
236 labels = ResourceBundle.getBundle(this.getClass().getPackage().getName() + ".Labels", currentLocale);
237
238 final String lookAndFeel;
239 final String systemLookAndFeel = UIManager.getSystemLookAndFeelClassName();
240 if ("com.apple.laf.AquaLookAndFeel".equals(systemLookAndFeel)) {
241 System.setProperty("apple.laf.useScreenMenuBar", "true");
242 }
243 lookAndFeel = systemLookAndFeel;
244
245 try {
246 UIManager.setLookAndFeel(lookAndFeel);
247 } catch (UnsupportedLookAndFeelException e) {
248 e.printStackTrace();
249 System.out.println(labels.getString("LookAndFeelExceptionMessageOne"));
250 } catch (ClassNotFoundException e) {
251 e.printStackTrace();
252 System.out.println(labels.getString("LookAndFeelExceptionMessageTwo"));
253 } catch (InstantiationException e) {
254 e.printStackTrace();
255 System.out.println(labels.getString("LookAndFeelExceptionMessageThree"));
256 } catch (IllegalAccessException e) {
257 e.printStackTrace();
258 System.out.println(labels.getString("LookAndFeelExceptionMessageFour"));
259 }
260
261 mainAppRef = new OpenLogViewer();
262 }
263 });
264 }
265
266 public void openFile() {
267 final JFileChooser fileChooser = new JFileChooser();
268 final String lastFingFile = getApplicationWideProperty(NAME_OF_LAST_FILE_KEY);
269
270 if (lastFingFile != null) {
271 fileChooser.setSelectedFile(new File(lastFingFile));
272 } else {
273 final String lastFingDir = getApplicationWideProperty(NAME_OF_LAST_DIR_KEY);
274 if (lastFingDir != null) {
275 fileChooser.setCurrentDirectory(new File(lastFingDir));
276 }
277 }
278
279 fileChooser.addChoosableFileFilter(new FreeEMSFileFilter());
280 fileChooser.addChoosableFileFilter(new FreeEMSBinFileFilter());
281 fileChooser.addChoosableFileFilter(new FreeEMSLAFileFilter());
282 fileChooser.addChoosableFileFilter(new CSVFileFilter());
283 fileChooser.addChoosableFileFilter(new LogFileFilter());
284 fileChooser.addChoosableFileFilter(new MSTypeFileFilter());
285
286 final String chooserClass = getApplicationWideProperty(NAME_OF_LAST_CHOOSER_CLASS);
287
288 if (chooserClass != null) {
289 try {
290 final FileFilter[] existingFilters = fileChooser.getChoosableFileFilters();
291 boolean alreadyHasSavedFilter = false;
292 for (int i = 0; i < existingFilters.length; i++) {
293 final String thisFilter = existingFilters[i].getClass().getCanonicalName();
294 if (thisFilter.equals(chooserClass)) {
295 alreadyHasSavedFilter = true;
296 fileChooser.setFileFilter(existingFilters[i]);
297 }
298 }
299
300
301 if (!alreadyHasSavedFilter) {
302 final FileFilter savedFilter = (FileFilter) Class.forName(chooserClass).newInstance();
303 fileChooser.setFileFilter(savedFilter);
304 }
305 } catch (ClassNotFoundException c) {
306 removeApplicationWideProperty(NAME_OF_LAST_CHOOSER_CLASS);
307 System.out.println("Class not found! chooserClass removed from props!");
308 } catch (InstantiationException i) {
309 removeApplicationWideProperty(NAME_OF_LAST_CHOOSER_CLASS);
310 System.out.println("Could not instantiate class! chooserClass removed from props!");
311 } catch (IllegalAccessException l) {
312 removeApplicationWideProperty(NAME_OF_LAST_CHOOSER_CLASS);
313 System.out.println("Could not access class! chooserClass removed from props!");
314 }
315 }
316
317 final int acceptValue = fileChooser.showOpenDialog(OpenLogViewer.getInstance());
318 if (acceptValue == JFileChooser.APPROVE_OPTION) {
319 if (decoderInUse != null) {
320
321 final GenericLog logInUse = decoderInUse.getDecodedLog();
322 if (logInUse != null) {
323 logInUse.clearOut();
324 }
325 decoderInUse = null;
326 setLog(null);
327 }
328
329 final File openFile = fileChooser.getSelectedFile();
330 if ("bin".equals(Utilities.getExtension(openFile)) || "la".equals(Utilities.getExtension(openFile)) || (fileChooser.getFileFilter() instanceof FreeEMSFileFilter)) {
331 decoderInUse = new FreeEMSBin(openFile);
332 } else {
333 decoderInUse = new CSVTypeLog(openFile);
334 }
335
336 if (openFile != null) {
337 OpenLogViewer.getInstance().setTitle(APPLICATION_NAME + " - " + openFile.getName());
338 saveApplicationWideProperty(NAME_OF_LAST_DIR_KEY, openFile.getParent());
339 saveApplicationWideProperty(NAME_OF_LAST_FILE_KEY, openFile.getPath());
340 saveApplicationWideProperty(NAME_OF_LAST_CHOOSER_CLASS, fileChooser.getFileFilter().getClass().getCanonicalName());
341 }
342 }
343 }
344
345 private String getApplicationWideProperty(final String key) {
346 try {
347 final Properties AppWide = new Properties();
348 final File AppWideFile = openAppWideProps(AppWide);
349 if (AppWideFile != null) {
350 return AppWide.getProperty(key);
351 } else {
352 throw new IllegalArgumentException("Problem getting property, got null instead of file!");
353 }
354 } catch (IOException e) {
355 e.printStackTrace();
356 throw new RuntimeException("IO issue: " + e.getMessage(), e);
357 }
358 }
359
360 private void saveApplicationWideProperty(final String key, final String value) {
361 try {
362 final Properties AppWide = new Properties();
363 final File AppWideFile = openAppWideProps(AppWide);
364 if (AppWideFile != null) {
365 AppWide.setProperty(key, value);
366 AppWide.store(new FileOutputStream(AppWideFile), "saved");
367 } else {
368 throw new IllegalArgumentException("Problem saving property, got null instead of file!");
369 }
370 } catch (IOException e) {
371 e.printStackTrace();
372 throw new RuntimeException("Another IO issue: " + e.getMessage(), e);
373 }
374 }
375
376 private void removeApplicationWideProperty(final String key) {
377 try {
378 final Properties AppWide = new Properties();
379 final File AppWideFile = openAppWideProps(AppWide);
380 if (AppWideFile != null) {
381 AppWide.remove(key);
382 AppWide.store(new FileOutputStream(AppWideFile), "removed");
383 } else {
384 throw new IllegalArgumentException("Problem removing property, got null instead of file!");
385 }
386 } catch (IOException e) {
387 e.printStackTrace();
388 throw new RuntimeException("YAIO issue: " + e.getMessage(), e);
389 }
390 }
391
392 private File openAppWideProps(final Properties AppWide) throws IOException {
393 File AppWideFile;
394 AppWideFile = new File(System.getProperty("user.home"));
395
396 if (!AppWideFile.exists() || !AppWideFile.canRead() || !AppWideFile.canWrite()) {
397 System.out.println("Either you dont have a home director, or it isnt read/writeable... fix it!");
398 } else {
399 AppWideFile = new File(AppWideFile, SETTINGS_DIRECTORY);
400 }
401
402 if (!AppWideFile.exists()) {
403 try {
404 if (AppWideFile.mkdir()) {
405 AppWideFile = new File(AppWideFile, PROPERTIES_FILENAME);
406 if (AppWideFile.createNewFile()) {
407 AppWide.load(new FileInputStream(AppWideFile));
408 }
409 } else {
410 throw new RuntimeException("Failed to create directory, no code to handle this at this time.");
411
412 }
413 } catch (IOException IOE) {
414 System.out.print(IOE.getMessage());
415 }
416 } else {
417 AppWideFile = new File(AppWideFile, PROPERTIES_FILENAME);
418 if (!AppWideFile.createNewFile()) {
419 AppWide.load(new FileInputStream(AppWideFile));
420 }
421 }
422 return AppWideFile;
423 }
424
425 public void enterFullScreen() {
426 if (!fullscreen) {
427 final GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
428 final GraphicsDevice[] gs = ge.getScreenDevices();
429 final GraphicsDevice gd = gs[0];
430
431 if (gd.isFullScreenSupported()) {
432 try {
433 setJMenuBar(null);
434 removeNotify();
435 setUndecorated(true);
436 addNotify();
437 setResizable(false);
438 gd.setFullScreenWindow(this);
439 validate();
440 fullscreen = true;
441 } catch (Exception e) {
442 e.printStackTrace();
443 System.out.println(labels.getObject(FAILED_TO_GO_FULLSCREEN_MESSAGE_KEY));
444 }
445 } else {
446 System.out.println(labels.getObject(CANT_GO_FULLSCREEN_MESSAGE_KEY));
447 }
448 }
449 }
450
451 public void exitFullScreen() {
452 if (fullscreen) {
453 final GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
454 final GraphicsDevice[] gs = ge.getScreenDevices();
455
456 gs[0].setFullScreenWindow(null);
457 removeNotify();
458 setUndecorated(false);
459 addNotify();
460 setJMenuBar(menuBar);
461 setResizable(true);
462 pack();
463 fullscreen = false;
464 }
465 }
466
467 public void toggleFullScreen() {
468 if (fullscreen) {
469 exitFullScreen();
470 } else {
471 enterFullScreen();
472 }
473 }
474
475 public void setLog(final GenericLog genericLog) {
476 graphingPanel.setLog(genericLog);
477 }
478
479
480
481
482
483 public static OpenLogViewer getInstance() {
484 return mainAppRef;
485 }
486
487 public EntireGraphingPanel getEntireGraphingPanel() {
488 return graphingPanel;
489 }
490
491 public MultiGraphLayeredPane getMultiGraphLayeredPane() {
492 return graphingPanel.getMultiGraphLayeredPane();
493 }
494
495 public OptionFrameV2 getOptionFrame() {
496 return optionFrame;
497 }
498
499 public PropertiesPane getPropertyPane() {
500 return prefFrame;
501 }
502
503 public List<SingleProperty> getProperties() {
504 return properties;
505 }
506 }