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 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
219 pack();
220
221 this.setVisible(true);
222 }
223
224
225
226
227
228
229 public static void main(final String[] args) {
230 java.awt.EventQueue.invokeLater(new Runnable() {
231
232 @Override
233 public void run() {
234 Locale currentLocale = Locale.getDefault();
235 labels = ResourceBundle.getBundle(this.getClass().getPackage().getName() + ".Labels", currentLocale);
236
237 final String lookAndFeel;
238 final String systemLookAndFeel = UIManager.getSystemLookAndFeelClassName();
239 if ("com.apple.laf.AquaLookAndFeel".equals(systemLookAndFeel)) {
240 System.setProperty("apple.laf.useScreenMenuBar", "true");
241 lookAndFeel = systemLookAndFeel;
242 } else {
243 lookAndFeel = "javax.swing.plaf.metal.MetalLookAndFeel";
244 }
245
246 try {
247 UIManager.setLookAndFeel(lookAndFeel);
248 } catch (UnsupportedLookAndFeelException e) {
249 e.printStackTrace();
250 System.out.println(labels.getString("LookAndFeelExceptionMessageOne"));
251 } catch (ClassNotFoundException e) {
252 e.printStackTrace();
253 System.out.println(labels.getString("LookAndFeelExceptionMessageTwo"));
254 } catch (InstantiationException e) {
255 e.printStackTrace();
256 System.out.println(labels.getString("LookAndFeelExceptionMessageThree"));
257 } catch (IllegalAccessException e) {
258 e.printStackTrace();
259 System.out.println(labels.getString("LookAndFeelExceptionMessageFour"));
260 }
261
262 mainAppRef = new OpenLogViewer();
263 }
264 });
265 }
266
267 public void openFile() {
268 final JFileChooser fileChooser = new JFileChooser();
269 final String lastFingFile = getApplicationWideProperty(NAME_OF_LAST_FILE_KEY);
270
271 if (lastFingFile != null) {
272 fileChooser.setSelectedFile(new File(lastFingFile));
273 } else {
274 final String lastFingDir = getApplicationWideProperty(NAME_OF_LAST_DIR_KEY);
275 if (lastFingDir != null) {
276 fileChooser.setCurrentDirectory(new File(lastFingDir));
277 }
278 }
279
280 fileChooser.addChoosableFileFilter(new FreeEMSFileFilter());
281 fileChooser.addChoosableFileFilter(new FreeEMSBinFileFilter());
282 fileChooser.addChoosableFileFilter(new FreeEMSLAFileFilter());
283 fileChooser.addChoosableFileFilter(new CSVFileFilter());
284 fileChooser.addChoosableFileFilter(new LogFileFilter());
285 fileChooser.addChoosableFileFilter(new MSTypeFileFilter());
286
287 final String chooserClass = getApplicationWideProperty(NAME_OF_LAST_CHOOSER_CLASS);
288
289 if (chooserClass != null) {
290 try {
291 final FileFilter[] existingFilters = fileChooser.getChoosableFileFilters();
292 boolean alreadyHasSavedFilter = false;
293 for (int i = 0; i < existingFilters.length; i++) {
294 final String thisFilter = existingFilters[i].getClass().getCanonicalName();
295 if (thisFilter.equals(chooserClass)) {
296 alreadyHasSavedFilter = true;
297 fileChooser.setFileFilter(existingFilters[i]);
298 }
299 }
300
301
302 if (!alreadyHasSavedFilter) {
303 final FileFilter savedFilter = (FileFilter) Class.forName(chooserClass).newInstance();
304 fileChooser.setFileFilter(savedFilter);
305 }
306 } catch (ClassNotFoundException c) {
307 removeApplicationWideProperty(NAME_OF_LAST_CHOOSER_CLASS);
308 System.out.println("Class not found! chooserClass removed from props!");
309 } catch (InstantiationException i) {
310 removeApplicationWideProperty(NAME_OF_LAST_CHOOSER_CLASS);
311 System.out.println("Could not instantiate class! chooserClass removed from props!");
312 } catch (IllegalAccessException l) {
313 removeApplicationWideProperty(NAME_OF_LAST_CHOOSER_CLASS);
314 System.out.println("Could not access class! chooserClass removed from props!");
315 }
316 }
317
318 final int acceptValue = fileChooser.showOpenDialog(OpenLogViewer.getInstance());
319 if (acceptValue == JFileChooser.APPROVE_OPTION) {
320 if (decoderInUse != null) {
321
322 final GenericLog logInUse = decoderInUse.getDecodedLog();
323 if (logInUse != null) {
324 logInUse.clearOut();
325 }
326 decoderInUse = null;
327 setLog(null);
328 }
329
330 final File openFile = fileChooser.getSelectedFile();
331 if ("bin".equals(Utilities.getExtension(openFile)) || "la".equals(Utilities.getExtension(openFile)) || (fileChooser.getFileFilter() instanceof FreeEMSFileFilter)) {
332 decoderInUse = new FreeEMSBin(openFile);
333 } else {
334 decoderInUse = new CSVTypeLog(openFile);
335 }
336
337 if (openFile != null) {
338 OpenLogViewer.getInstance().setTitle(APPLICATION_NAME + " - " + openFile.getName());
339 saveApplicationWideProperty(NAME_OF_LAST_DIR_KEY, openFile.getParent());
340 saveApplicationWideProperty(NAME_OF_LAST_FILE_KEY, openFile.getPath());
341 saveApplicationWideProperty(NAME_OF_LAST_CHOOSER_CLASS, fileChooser.getFileFilter().getClass().getCanonicalName());
342 }
343 }
344 }
345
346 private String getApplicationWideProperty(final String key) {
347 try {
348 final Properties AppWide = new Properties();
349 final File AppWideFile = openAppWideProps(AppWide);
350 if (AppWideFile != null) {
351 return AppWide.getProperty(key);
352 } else {
353 throw new IllegalArgumentException("Problem getting property, got null instead of file!");
354 }
355 } catch (IOException e) {
356 e.printStackTrace();
357 throw new RuntimeException("IO issue: " + e.getMessage(), e);
358 }
359 }
360
361 private void saveApplicationWideProperty(final String key, final String value) {
362 try {
363 final Properties AppWide = new Properties();
364 final File AppWideFile = openAppWideProps(AppWide);
365 if (AppWideFile != null) {
366 AppWide.setProperty(key, value);
367 AppWide.store(new FileOutputStream(AppWideFile), "saved");
368 } else {
369 throw new IllegalArgumentException("Problem saving property, got null instead of file!");
370 }
371 } catch (IOException e) {
372 e.printStackTrace();
373 throw new RuntimeException("Another IO issue: " + e.getMessage(), e);
374 }
375 }
376
377 private void removeApplicationWideProperty(final String key) {
378 try {
379 final Properties AppWide = new Properties();
380 final File AppWideFile = openAppWideProps(AppWide);
381 if (AppWideFile != null) {
382 AppWide.remove(key);
383 AppWide.store(new FileOutputStream(AppWideFile), "removed");
384 } else {
385 throw new IllegalArgumentException("Problem removing property, got null instead of file!");
386 }
387 } catch (IOException e) {
388 e.printStackTrace();
389 throw new RuntimeException("YAIO issue: " + e.getMessage(), e);
390 }
391 }
392
393 private File openAppWideProps(final Properties AppWide) throws IOException {
394 File AppWideFile;
395 AppWideFile = new File(System.getProperty("user.home"));
396
397 if (!AppWideFile.exists() || !AppWideFile.canRead() || !AppWideFile.canWrite()) {
398 System.out.println("Either you dont have a home director, or it isnt read/writeable... fix it!");
399 } else {
400 AppWideFile = new File(AppWideFile, SETTINGS_DIRECTORY);
401 }
402
403 if (!AppWideFile.exists()) {
404 try {
405 if (AppWideFile.mkdir()) {
406 AppWideFile = new File(AppWideFile, PROPERTIES_FILENAME);
407 if (AppWideFile.createNewFile()) {
408 AppWide.load(new FileInputStream(AppWideFile));
409 }
410 } else {
411 throw new RuntimeException("Failed to create directory, no code to handle this at this time.");
412
413 }
414 } catch (IOException IOE) {
415 System.out.print(IOE.getMessage());
416 }
417 } else {
418 AppWideFile = new File(AppWideFile, PROPERTIES_FILENAME);
419 if (!AppWideFile.createNewFile()) {
420 AppWide.load(new FileInputStream(AppWideFile));
421 }
422 }
423 return AppWideFile;
424 }
425
426 public void enterFullScreen() {
427 if (!fullscreen ) {
428 final GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
429 final GraphicsDevice[] gs = ge.getScreenDevices();
430 final GraphicsDevice gd = gs[0];
431
432 if (gd.isFullScreenSupported()) {
433 try {
434 setJMenuBar(null);
435 removeNotify();
436 setUndecorated(true);
437 addNotify();
438 setResizable(false);
439 gd.setFullScreenWindow(this);
440 validate();
441 fullscreen = true;
442 } catch(Exception e) {
443 e.printStackTrace();
444 System.out.println(labels.getObject(FAILED_TO_GO_FULLSCREEN_MESSAGE_KEY));
445 }
446 } else {
447 System.out.println(labels.getObject(CANT_GO_FULLSCREEN_MESSAGE_KEY));
448 }
449 }
450 }
451
452 public void exitFullScreen() {
453 if (fullscreen) {
454 GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
455 GraphicsDevice[] gs = ge.getScreenDevices();
456
457 gs[0].setFullScreenWindow(null);
458 removeNotify();
459 setUndecorated(false);
460 addNotify();
461 setJMenuBar(menuBar);
462 setResizable(true);
463 pack();
464 fullscreen = false;
465 }
466 }
467
468 public void toggleFullScreen(){
469 if(fullscreen){
470 exitFullScreen();
471 } else {
472 enterFullScreen();
473 }
474 }
475
476 public void setLog(final GenericLog genericLog) {
477 graphingPanel.setLog(genericLog);
478 }
479
480
481
482
483
484 public static OpenLogViewer getInstance() {
485 return mainAppRef;
486 }
487
488 public EntireGraphingPanel getEntireGraphingPanel() {
489 return graphingPanel;
490 }
491
492 public MultiGraphLayeredPane getMultiGraphLayeredPane() {
493 return graphingPanel.getMultiGraphLayeredPane();
494 }
495
496 public OptionFrameV2 getOptionFrame() {
497 return optionFrame;
498 }
499
500 public PropertiesPane getPropertyPane() {
501 return prefFrame;
502 }
503
504 public List<SingleProperty> getProperties() {
505 return properties;
506 }
507 }