source: AE/installer2/src/net/oni2/aeinstaller/gui/MainWin.java@ 637

Last change on this file since 637 was 637, checked in by alloc, 12 years ago

AEI2 0.94:

  • Added context menu item to open Depot page of mod in table
  • Added last-change column to table
File size: 21.0 KB
Line 
1package net.oni2.aeinstaller.gui;
2
3import java.awt.BorderLayout;
4import java.awt.Desktop;
5import java.awt.GridLayout;
6import java.awt.event.ActionEvent;
7import java.awt.event.ItemEvent;
8import java.awt.event.ItemListener;
9import java.io.File;
10import java.io.IOException;
11import java.net.URL;
12import java.util.Date;
13import java.util.HashMap;
14import java.util.HashSet;
15import java.util.ResourceBundle;
16import java.util.TreeMap;
17import java.util.TreeSet;
18import java.util.Vector;
19
20import javax.swing.AbstractAction;
21import javax.swing.Icon;
22import javax.swing.ImageIcon;
23import javax.swing.JButton;
24import javax.swing.JCheckBox;
25import javax.swing.JComboBox;
26import javax.swing.JFileChooser;
27import javax.swing.JFrame;
28import javax.swing.JLabel;
29import javax.swing.JMenu;
30import javax.swing.JMenuItem;
31import javax.swing.JOptionPane;
32import javax.swing.JPanel;
33import javax.swing.JRadioButton;
34import javax.swing.JSplitPane;
35import javax.swing.SwingUtilities;
36import javax.swing.ToolTipManager;
37import javax.swing.filechooser.FileFilter;
38
39import net.oni2.aeinstaller.AEInstaller2;
40import net.oni2.aeinstaller.backend.AppExecution;
41import net.oni2.aeinstaller.backend.Paths;
42import net.oni2.aeinstaller.backend.Settings;
43import net.oni2.aeinstaller.backend.Settings.Platform;
44import net.oni2.aeinstaller.backend.SizeFormatter;
45import net.oni2.aeinstaller.backend.depot.DepotManager;
46import net.oni2.aeinstaller.backend.mods.Mod;
47import net.oni2.aeinstaller.backend.mods.ModManager;
48import net.oni2.aeinstaller.backend.mods.Type;
49import net.oni2.aeinstaller.backend.mods.download.ModDownloader;
50import net.oni2.aeinstaller.backend.mods.download.ModDownloader.State;
51import net.oni2.aeinstaller.backend.mods.download.ModDownloaderListener;
52import net.oni2.aeinstaller.backend.oni.InstallProgressListener;
53import net.oni2.aeinstaller.backend.oni.Installer;
54import net.oni2.aeinstaller.backend.oni.OniSplit;
55import net.oni2.aeinstaller.gui.about.AboutDialog;
56import net.oni2.aeinstaller.gui.downloadwindow.Downloader;
57import net.oni2.aeinstaller.gui.modtable.DownloadSizeListener;
58import net.oni2.aeinstaller.gui.modtable.ModSelectionListener;
59import net.oni2.aeinstaller.gui.modtable.ModTable;
60import net.oni2.aeinstaller.gui.settings.SettingsDialog;
61import net.oni2.aeinstaller.gui.toolmanager.ToolManager;
62
63import org.javabuilders.BuildResult;
64import org.javabuilders.annotations.DoInBackground;
65import org.javabuilders.event.BackgroundEvent;
66import org.javabuilders.swing.SwingJavaBuilder;
67import org.simplericity.macify.eawt.ApplicationEvent;
68import org.simplericity.macify.eawt.ApplicationListener;
69
70/**
71 * @author Christian Illy
72 */
73public class MainWin extends JFrame implements ApplicationListener,
74 DownloadSizeListener, ModSelectionListener {
75 private static final long serialVersionUID = -4027395051382659650L;
76
77 private ResourceBundle bundle = ResourceBundle
78 .getBundle("net.oni2.aeinstaller.localization."
79 + getClass().getSimpleName());
80 @SuppressWarnings("unused")
81 private BuildResult result = SwingJavaBuilder.build(this, bundle);
82
83 private JMenu mainMenu;
84 private JMenu toolsMenu;
85 private TreeSet<JMenuItem> toolsMenuItems = new TreeSet<JMenuItem>();
86
87 private JSplitPane contents;
88
89 private JComboBox cmbModTypes;
90 private JRadioButton radAll;
91 private JRadioButton radOnline;
92 private JRadioButton radLocal;
93 private ModTable tblMods;
94 private JLabel lblDownloadSizeVal;
95
96 private JLabel lblSubmitterVal;
97 private JLabel lblCreatorVal;
98 private JLabel lblTypesVal;
99 private JLabel lblPlatformVal;
100 private JLabel lblPackageNumberVal;
101 private HTMLLinkLabel lblDescriptionVal;
102
103 private JButton btnInstall;
104
105 private TreeSet<Mod> execUpdates = null;
106
107 private enum EInstallResult {
108 DONE,
109 OFFLINE,
110 INCOMPATIBLE
111 };
112
113 private EInstallResult installDone = EInstallResult.DONE;
114
115 /**
116 * Constructor of main window.
117 */
118 public MainWin() {
119 this.setTitle(SwingJavaBuilder.getConfig().getResource("appname")
120 + " - v"
121 + SwingJavaBuilder.getConfig().getResource("appversion"));
122
123 setSize(getWidth()+150, getHeight());
124 contents.setDividerLocation(500);
125 contents.setResizeWeight(0.4);
126
127 if (Settings.getPlatform() == Platform.MACOS) {
128 mainMenu.setVisible(false);
129 }
130
131 ToolTipManager.sharedInstance().setInitialDelay(250);
132
133 getRootPane().setDefaultButton(btnInstall);
134 lblDownloadSizeVal.setText(SizeFormatter.format(0, 2));
135 radAll.setSelected(true);
136
137 tblMods.addModSelectionListener(this);
138 tblMods.addDownloadSizeListener(this);
139 }
140
141 private void initModTypeBox() {
142 cmbModTypes.removeAllItems();
143
144 TreeMap<String, Type> types = new TreeMap<String, Type>();
145 for (Type t : ModManager.getInstance().getTypesWithContent()) {
146 types.put(t.getName(), t);
147 }
148 cmbModTypes.addItem("-All-");
149 for (Type t : types.values()) {
150 cmbModTypes.addItem(t);
151 }
152 cmbModTypes.setSelectedIndex(0);
153 }
154
155 private void exit() {
156 dispose();
157 System.exit(0);
158 }
159
160 private void saveLocalData() {
161 Settings.getInstance().serializeToFile();
162 }
163
164 @DoInBackground(progressMessage = "updateDepot.title", cancelable = false, indeterminateProgress = false)
165 private void execDepotUpdate(final BackgroundEvent evt) {
166 if (!Settings.getInstance().isOfflineMode()) {
167 long start = new Date().getTime();
168
169 try {
170 DepotManager.getInstance().updateInformation(false);
171 } catch (Exception e) {
172 e.printStackTrace();
173 }
174
175 System.out.println("Took: " + (new Date().getTime() - start)
176 + " msec");
177 }
178
179 ModManager.getInstance().init();
180 tblMods.reloadData();
181 initModTypeBox();
182
183 tblMods.setVisible(true);
184 }
185
186 @SuppressWarnings("unused")
187 private void checkUpdates(Object evtSource) {
188 if ((evtSource != this)
189 || Settings.getInstance().get("notifyupdates", true)) {
190 if (Settings.getInstance().isOfflineMode()) {
191 if (evtSource != this) {
192 JOptionPane.showMessageDialog(this,
193 bundle.getString("offlineMode.text"),
194 bundle.getString("offlineMode.title"),
195 JOptionPane.WARNING_MESSAGE);
196 }
197 } else {
198 TreeSet<Mod> mods = ModManager.getInstance().getUpdatableMods();
199 TreeSet<Mod> tools = ModManager.getInstance()
200 .getUpdatableTools();
201 int size = 0;
202 JPanel panPackages = new JPanel(new GridLayout(0, 1));
203 execUpdates = new TreeSet<Mod>();
204 execUpdates.addAll(mods);
205 execUpdates.addAll(tools);
206 for (final Mod m : mods) {
207 size += m.getZipSize();
208 JCheckBox check = new JCheckBox("Mod: " + m.getName());
209 check.setSelected(true);
210 check.addItemListener(new ItemListener() {
211 @Override
212 public void itemStateChanged(ItemEvent e) {
213 if (e.getStateChange() == ItemEvent.SELECTED)
214 execUpdates.add(m);
215 else
216 execUpdates.remove(m);
217 }
218 });
219 panPackages.add(check);
220 }
221 for (final Mod m : tools) {
222 size += m.getZipSize();
223 JCheckBox check = new JCheckBox("Tool: " + m.getName());
224 check.setSelected(true);
225 panPackages.add(check);
226 }
227 if (size > 0) {
228 // Build info dialog content
229 JPanel packages = new JPanel(new BorderLayout(0, 7));
230 JLabel lblIntro = new JLabel("<html>"
231 + bundle.getString("updatesAvailable.text")
232 + "</html>");
233 JLabel lblSize = new JLabel("<html>"
234 + String.format(bundle
235 .getString("updatesAvailableSize.text"),
236 SizeFormatter.format(size, 3)) + "</html>");
237 packages.add(lblIntro, BorderLayout.NORTH);
238 packages.add(panPackages, BorderLayout.CENTER);
239 packages.add(lblSize, BorderLayout.SOUTH);
240
241 JPanel pan = new JPanel(new BorderLayout(0, 25));
242 pan.add(packages, BorderLayout.CENTER);
243 JCheckBox checkFutureUpdates = new JCheckBox(
244 bundle.getString("checkOnStartup.text"));
245 checkFutureUpdates.setSelected(Settings.getInstance().get(
246 "notifyupdates", true));
247 checkFutureUpdates.addItemListener(new ItemListener() {
248 @Override
249 public void itemStateChanged(ItemEvent evt) {
250 Settings.getInstance().put("notifyupdates",
251 evt.getStateChange() == ItemEvent.SELECTED);
252 }
253 });
254 pan.add(checkFutureUpdates, BorderLayout.SOUTH);
255
256 // Show dialog
257 int res = JOptionPane.showConfirmDialog(this, pan,
258 bundle.getString("updatesAvailable.title"),
259 JOptionPane.YES_NO_OPTION,
260 JOptionPane.QUESTION_MESSAGE);
261 if (res == JOptionPane.NO_OPTION) {
262 execUpdates = null;
263 }
264 }
265 }
266 }
267 }
268
269 @SuppressWarnings("unused")
270 private void doUpdate() {
271 if (execUpdates != null && execUpdates.size() > 0) {
272 Downloader dl = new Downloader(execUpdates);
273 try {
274 dl.setVisible(true);
275 if (dl.isFinished()) {
276 TreeSet<Integer> installed = Installer.getInstalledTools();
277 TreeSet<Mod> tools = new TreeSet<Mod>();
278 for (Mod m : execUpdates)
279 if (m.isTool()
280 && installed.contains(m.getPackageNumber()))
281 tools.add(m);
282 if (tools.size() > 0) {
283 Installer.installTools(tools);
284 }
285 }
286 } finally {
287 dl.dispose();
288 }
289 }
290 execUpdates = null;
291 }
292
293 @SuppressWarnings("unused")
294 private void focus() {
295 SwingUtilities.invokeLater(new Runnable() {
296
297 @Override
298 public void run() {
299 toFront();
300 repaint();
301 }
302 });
303
304 }
305
306 private void showSettings() {
307 new SettingsDialog().setVisible(true);
308 }
309
310 private void showAbout() {
311 new AboutDialog().setVisible(true);
312 }
313
314 private JFileChooser getConfigOpenSaveDialog(boolean save) {
315 JFileChooser fc = new JFileChooser();
316 fc.setCurrentDirectory(Paths.getEditionBasePath());
317 if (save)
318 fc.setDialogType(JFileChooser.SAVE_DIALOG);
319 else
320 fc.setDialogType(JFileChooser.OPEN_DIALOG);
321 fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
322 fc.setFileFilter(new FileFilter() {
323 @Override
324 public String getDescription() {
325 return "XML files";
326 }
327
328 @Override
329 public boolean accept(File arg0) {
330 return (arg0.isDirectory())
331 || (arg0.getName().toLowerCase().endsWith(".xml"));
332 }
333 });
334 fc.setMultiSelectionEnabled(false);
335 return fc;
336 }
337
338 @SuppressWarnings("unused")
339 private void loadConfig() {
340 JFileChooser fc = getConfigOpenSaveDialog(false);
341 int res = fc.showOpenDialog(this);
342 if (res == JFileChooser.APPROVE_OPTION) {
343 if (fc.getSelectedFile().exists())
344 tblMods.reloadSelection(fc.getSelectedFile());
345 }
346 }
347
348 @SuppressWarnings("unused")
349 private void saveConfig() {
350 JFileChooser fc = getConfigOpenSaveDialog(true);
351 int res = fc.showSaveDialog(this);
352 if (res == JFileChooser.APPROVE_OPTION) {
353 File f = fc.getSelectedFile();
354 if (!f.getName().endsWith(".xml"))
355 f = new File(f.getParentFile(), f.getName() + ".xml");
356 ModManager.getInstance().saveModSelection(f,
357 tblMods.getSelectedMods());
358 }
359 }
360
361 @DoInBackground(progressMessage = "initializingEdition.title", cancelable = false, indeterminateProgress = false)
362 private void reglobalize(final BackgroundEvent evt) {
363 Installer.initializeEdition(new InstallProgressListener() {
364 @Override
365 public void installProgressUpdate(int done, int total, String step) {
366 evt.setProgressEnd(total);
367 evt.setProgressValue(done);
368 evt.setProgressMessage(step);
369 }
370 });
371 }
372
373 @SuppressWarnings("unused")
374 private void tools() {
375 new ToolManager().setVisible(true);
376 }
377
378 @SuppressWarnings("unused")
379 private void refreshToolsMenu() {
380 for (JMenuItem i : toolsMenuItems) {
381 toolsMenu.remove(i);
382 }
383 toolsMenuItems.clear();
384 for (Mod m : ModManager.getInstance().getInstalledTools()) {
385 if (m.getExeFile() != null && m.getExeFile().exists()) {
386 JMenuItem item = new JMenuItem();
387 final Vector<String> params = new Vector<String>();
388 params.add(m.getExeFile().getPath());
389 final File wd = m.getWorkingDir();
390 Icon ico = null;
391 if (m.getIconFile() != null && m.getIconFile().exists()) {
392 ico = new ImageIcon(m.getIconFile().getPath());
393 } else {
394 URL icon = AEInstaller2.class
395 .getResource("images/transparent.png");
396 ico = new ImageIcon(icon);
397 }
398 item.setAction(new AbstractAction(m.getName(), ico) {
399 private static final long serialVersionUID = 1L;
400
401 @Override
402 public void actionPerformed(ActionEvent e) {
403 AppExecution.execute(params, wd);
404 }
405 });
406 toolsMenuItems.add(item);
407 toolsMenu.add(item);
408 }
409 }
410 }
411
412 private void revertSelection() {
413 tblMods.revertSelection();
414 }
415
416 @DoInBackground(progressMessage = "mandatoryFiles.title", cancelable = false, indeterminateProgress = false)
417 private void checkMandatoryFiles(final BackgroundEvent evt) {
418 if (!Settings.getInstance().isOfflineMode()) {
419 TreeSet<Mod> mand = new TreeSet<Mod>();
420 for (Mod m : ModManager.getInstance().getMandatoryTools()) {
421 if (m.isNewerAvailable()) {
422 mand.add(m);
423 }
424 }
425 for (Mod m : ModManager.getInstance().getMandatoryMods()) {
426 if (m.isNewerAvailable()) {
427 mand.add(m);
428 }
429 }
430 if (mand.size() > 0) {
431 ModDownloader m = new ModDownloader(mand,
432 new ModDownloaderListener() {
433 @Override
434 public void updateStatus(ModDownloader source,
435 State state, int filesDown, int filesTotal,
436 int bytesDown, int bytesTotal,
437 int duration, int remaining, int speed) {
438 evt.setProgressEnd(filesTotal);
439 evt.setProgressValue(filesDown);
440 }
441 });
442 while (!m.isFinished()) {
443 try {
444 Thread.sleep(10);
445 } catch (InterruptedException e) {
446 e.printStackTrace();
447 }
448 }
449 }
450 evt.setProgressMessage(bundle
451 .getString("mandatoryToolsInstall.title"));
452 Installer
453 .installTools(ModManager.getInstance().getMandatoryTools());
454 }
455 }
456
457 @DoInBackground(progressMessage = "installing.title", cancelable = false, indeterminateProgress = false)
458 private void install(final BackgroundEvent evt) {
459 TreeSet<Mod> mods = new TreeSet<Mod>();
460 mods.addAll(ModManager.getInstance().getMandatoryMods());
461 mods.addAll(tblMods.getSelectedMods());
462
463 boolean instReady = false;
464 installDone = EInstallResult.DONE;
465
466 while (!instReady) {
467 TreeSet<Mod> toDownload = new TreeSet<Mod>();
468 for (Mod m : mods) {
469 if (!m.isLocalAvailable())
470 toDownload.add(m);
471 }
472 if (Settings.getInstance().isOfflineMode()) {
473 installDone = EInstallResult.OFFLINE;
474 break;
475 }
476 if (toDownload.size() > 0) {
477 Downloader dl = new Downloader(toDownload);
478 try {
479 dl.setVisible(true);
480 if (!dl.isFinished())
481 break;
482 } finally {
483 dl.dispose();
484 }
485 }
486 HashMap<Mod, HashSet<Mod>> dependencies = ModManager.getInstance()
487 .checkDependencies(mods);
488 if (dependencies.size() > 0) {
489 System.out.println("Unmet dependencies: "
490 + dependencies.toString());
491 for (Mod m : dependencies.keySet()) {
492 for (Mod mDep : dependencies.get(m))
493 mods.add(mDep);
494 }
495 } else {
496 HashMap<Mod, HashSet<Mod>> conflicts = ModManager.getInstance()
497 .checkIncompabitilites(mods);
498 if (conflicts.size() > 0) {
499 installDone = EInstallResult.INCOMPATIBLE;
500 System.err.println("Incompatible mods: "
501 + conflicts.toString());
502 break;
503 } else {
504 instReady = true;
505 }
506 }
507 }
508
509 if (instReady) {
510 TreeSet<Mod> actuallyMods = new TreeSet<Mod>();
511 TreeSet<Mod> actuallyTools = new TreeSet<Mod>();
512
513 for (Mod m : mods) {
514 if (m.isTool())
515 actuallyTools.add(m);
516 else
517 actuallyMods.add(m);
518 }
519
520 if (actuallyTools.size() > 0) {
521 Installer.installTools(actuallyTools);
522 }
523
524 Installer.install(actuallyMods, new InstallProgressListener() {
525 @Override
526 public void installProgressUpdate(int done, int total,
527 String step) {
528 evt.setProgressEnd(total);
529 evt.setProgressValue(done);
530 evt.setProgressMessage(step);
531 }
532 });
533 installDone = EInstallResult.DONE;
534 }
535 }
536
537 @SuppressWarnings("unused")
538 private void installDone() {
539 ModManager.getInstance().updateInstalledMods();
540 revertSelection();
541 switch (installDone) {
542 case DONE:
543 JOptionPane.showMessageDialog(this,
544 bundle.getString("installDone.text"),
545 bundle.getString("installDone.title"),
546 JOptionPane.INFORMATION_MESSAGE);
547 break;
548 case OFFLINE:
549 JOptionPane.showMessageDialog(this,
550 bundle.getString("offlineMode.text"),
551 bundle.getString("offlineMode.title"),
552 JOptionPane.WARNING_MESSAGE);
553 break;
554 case INCOMPATIBLE:
555 break;
556 }
557 }
558
559 @Override
560 public void modSelectionChanged(ModTable source, Mod m) {
561 lblSubmitterVal.setText("");
562 lblCreatorVal.setText("");
563 lblDescriptionVal.setText("");
564 lblTypesVal.setText("");
565 lblPlatformVal.setText("");
566 lblPackageNumberVal.setText("");
567 if (m != null) {
568 lblSubmitterVal.setText(m.getName());
569 lblCreatorVal.setText(m.getCreator());
570 lblDescriptionVal.setText(m.getDescription());
571
572 String types = "";
573 for (Type t : m.getTypes()) {
574 if (types.length() > 0)
575 types += ", ";
576 types += t.getName();
577 }
578 lblTypesVal.setText(types);
579 lblPlatformVal.setText(m.getPlatform().toString());
580 lblPackageNumberVal.setText(m.getPackageNumberString());
581 }
582 }
583
584 private void updateTableFilter() {
585 Object o = cmbModTypes.getSelectedItem();
586 Type t = null;
587 if (o instanceof Type)
588 t = (Type) o;
589 int downloadState = 0;
590 if (radOnline.isSelected())
591 downloadState = 1;
592 if (radLocal.isSelected())
593 downloadState = 2;
594 tblMods.setFilter(t, downloadState);
595 }
596
597 @SuppressWarnings("unused")
598 private void modTypeSelection() {
599 updateTableFilter();
600 }
601
602 @SuppressWarnings("unused")
603 private void showTypeSelection() {
604 updateTableFilter();
605 }
606
607 @Override
608 public void downloadSizeChanged(int newSize) {
609 lblDownloadSizeVal.setText(SizeFormatter.format(newSize, 2));
610 }
611
612 @SuppressWarnings("unused")
613 private void checkInitialize() {
614 if (!Installer.isEditionInitialized()) {
615 if (!OniSplit.isOniSplitInstalled()) {
616 JOptionPane.showMessageDialog(this,
617 bundle.getString("noOniSplit.text"),
618 bundle.getString("noOniSplit.title"),
619 JOptionPane.ERROR_MESSAGE);
620 exit();
621 } else {
622 int res = JOptionPane
623 .showConfirmDialog(this,
624 bundle.getString("askInitialize.text"),
625 bundle.getString("askInitialize.title"),
626 JOptionPane.YES_NO_OPTION,
627 JOptionPane.QUESTION_MESSAGE);
628 if (res == JOptionPane.NO_OPTION) {
629 saveLocalData();
630 exit();
631 }
632 }
633 }
634 }
635
636 @DoInBackground(progressMessage = "initializingEdition.title", cancelable = false, indeterminateProgress = false)
637 private void initialize(final BackgroundEvent evt) {
638 if (!Installer.isEditionInitialized()) {
639 Installer.initializeEdition(new InstallProgressListener() {
640 @Override
641 public void installProgressUpdate(int done, int total,
642 String step) {
643 evt.setProgressEnd(total);
644 evt.setProgressValue(done);
645 evt.setProgressMessage(step);
646 }
647 });
648 }
649 }
650
651 private Vector<String> getBasicOniLaunchParams() {
652 Vector<String> params = new Vector<String>();
653 File exe = null;
654 switch (Settings.getPlatform()) {
655 case WIN:
656 exe = new File(Paths.getEditionBasePath(), "Oni.exe");
657 if (exe.exists())
658 params.add(exe.getPath());
659 break;
660 case MACOS:
661 exe = new File(Paths.getEditionBasePath(),
662 "Oni.app/Contents/MacOS/Oni");
663 if (exe.exists())
664 params.add(exe.getPath());
665 break;
666 case LINUX:
667 String wine = Settings.getWinePath();
668 exe = new File(Paths.getEditionBasePath(), "Oni.exe");
669 if (exe.exists()) {
670 if (wine != null) {
671 params.add(wine);
672 params.add(exe.getPath());
673 }
674 }
675 break;
676 default:
677 }
678 if (params.size() > 0) {
679 params.add("-debugfiles");
680 }
681 return params;
682 }
683
684 @SuppressWarnings("unused")
685 private void oniFull() {
686 Vector<String> params = getBasicOniLaunchParams();
687 if (params.size() > 0) {
688 AppExecution.execute(params, Paths.getEditionBasePath());
689 }
690 }
691
692 @SuppressWarnings("unused")
693 private void oniWin() {
694 Vector<String> params = getBasicOniLaunchParams();
695 if (params.size() > 0) {
696 params.add("-noswitch");
697 AppExecution.execute(params, Paths.getEditionBasePath());
698 }
699 }
700
701 @SuppressWarnings("unused")
702 private void openEditionFolder() {
703 try {
704 Desktop.getDesktop().open(Paths.getEditionBasePath());
705 } catch (IOException e) {
706 e.printStackTrace();
707 }
708 }
709
710 @Override
711 public void handleAbout(ApplicationEvent event) {
712 event.setHandled(true);
713 showAbout();
714 }
715
716 @Override
717 public void handleOpenApplication(ApplicationEvent event) {
718 }
719
720 @Override
721 public void handleOpenFile(ApplicationEvent event) {
722 }
723
724 @Override
725 public void handlePreferences(ApplicationEvent event) {
726 showSettings();
727 }
728
729 @Override
730 public void handlePrintFile(ApplicationEvent event) {
731 }
732
733 @Override
734 public void handleQuit(ApplicationEvent event) {
735 event.setHandled(true);
736 saveLocalData();
737 exit();
738 }
739
740 @Override
741 public void handleReOpenApplication(ApplicationEvent event) {
742 }
743
744}
Note: See TracBrowser for help on using the repository browser.