From 8377c9c615938c6d69f186fcc62d46b45763d85d Mon Sep 17 00:00:00 2001 From: Maarten Billemont Date: Sun, 29 Jul 2018 00:08:09 -0400 Subject: [PATCH] JDK9 platform-independent way of managing application events. --- platform-independent/java/gui/build.gradle | 2 +- .../gui/{GUI.java => Main.java} | 45 +++----------- .../gui/platform/{macos => }/AppleGUI.java | 25 ++++---- .../masterpassword/gui/platform/BaseGUI.java | 58 ++++++++++++++++++ .../masterpassword/gui/platform/JDK9GUI.java | 60 +++++++++++++++++++ .../platform/{macos => }/package-info.java | 2 +- 6 files changed, 144 insertions(+), 48 deletions(-) rename platform-independent/java/gui/src/main/java/com/lyndir/masterpassword/gui/{GUI.java => Main.java} (73%) rename platform-independent/java/gui/src/main/java/com/lyndir/masterpassword/gui/platform/{macos => }/AppleGUI.java (67%) create mode 100644 platform-independent/java/gui/src/main/java/com/lyndir/masterpassword/gui/platform/BaseGUI.java create mode 100644 platform-independent/java/gui/src/main/java/com/lyndir/masterpassword/gui/platform/JDK9GUI.java rename platform-independent/java/gui/src/main/java/com/lyndir/masterpassword/gui/platform/{macos => }/package-info.java (94%) diff --git a/platform-independent/java/gui/build.gradle b/platform-independent/java/gui/build.gradle index 7cd5ad3a..8bfb918a 100644 --- a/platform-independent/java/gui/build.gradle +++ b/platform-independent/java/gui/build.gradle @@ -5,7 +5,7 @@ plugins { } description = 'Master Password GUI' -mainClassName = 'com.lyndir.masterpassword.gui.GUI' +mainClassName = 'com.lyndir.masterpassword.gui.Main' dependencies { implementation group: 'com.lyndir.lhunath.opal', name: 'opal-system', version: '1.7-p2' diff --git a/platform-independent/java/gui/src/main/java/com/lyndir/masterpassword/gui/GUI.java b/platform-independent/java/gui/src/main/java/com/lyndir/masterpassword/gui/Main.java similarity index 73% rename from platform-independent/java/gui/src/main/java/com/lyndir/masterpassword/gui/GUI.java rename to platform-independent/java/gui/src/main/java/com/lyndir/masterpassword/gui/Main.java index 65917500..9fa1fbd9 100644 --- a/platform-independent/java/gui/src/main/java/com/lyndir/masterpassword/gui/GUI.java +++ b/platform-independent/java/gui/src/main/java/com/lyndir/masterpassword/gui/Main.java @@ -23,14 +23,10 @@ import static com.lyndir.lhunath.opal.system.util.StringUtils.*; import com.google.common.base.Charsets; import com.google.common.io.ByteSource; import com.lyndir.lhunath.opal.system.logging.Logger; -import com.lyndir.lhunath.opal.system.util.TypeUtils; -import com.lyndir.masterpassword.gui.util.Res; -import com.lyndir.masterpassword.gui.view.MasterPasswordFrame; +import com.lyndir.masterpassword.gui.platform.BaseGUI; import java.io.IOException; import java.io.InputStream; -import java.lang.reflect.InvocationTargetException; import java.net.*; -import java.util.Optional; import javax.swing.*; @@ -39,20 +35,15 @@ import javax.swing.*; * * @author mbillemo */ -public class GUI { +public final class Main { @SuppressWarnings("UnusedDeclaration") - private static final Logger logger = Logger.get( GUI.class ); - - private final MasterPasswordFrame frame = new MasterPasswordFrame(); + private static final Logger logger = Logger.get( Main.class ); public static void main(final String... args) { // Thread.setDefaultUncaughtExceptionHandler( // (t, e) -> logger.bug( e, "Uncaught: %s", e.getLocalizedMessage() ) ); - if (Config.get().checkForUpdates()) - checkUpdate(); - // Try and set the system look & feel, if available. try { UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName() ); @@ -60,29 +51,17 @@ public class GUI { catch (final UnsupportedLookAndFeelException | ClassNotFoundException | InstantiationException | IllegalAccessException ignored) { } - create().open(); - } + // Check online to see if this version has been superseded. + if (Config.get().checkForUpdates()) + checkUpdate(); - private static GUI create() { - try { - // AppleGUI adds support for macOS features. - Optional> appleGUI = TypeUtils.loadClass( "com.lyndir.masterpassword.gui.platform.mac.AppleGUI" ); - if (appleGUI.isPresent()) - return appleGUI.get().getConstructor().newInstance(); - } - catch (@SuppressWarnings("ErrorNotRethrown") final LinkageError ignored) { - } - catch (final IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e) { - throw logger.bug( e ); - } - - // Use platform-independent GUI. - return new GUI(); + // Create a platform-specific GUI and open it. + BaseGUI.createPlatformGUI().open(); } private static void checkUpdate() { try { - String implementationVersion = GUI.class.getPackage().getImplementationVersion(); + String implementationVersion = Main.class.getPackage().getImplementationVersion(); String latestVersion = new ByteSource() { @Override public InputStream openStream() @@ -111,10 +90,4 @@ public class GUI { logger.wrn( e, "Couldn't check for version update." ); } } - - protected void open() { - Res.ui( () -> { - frame.setVisible( true ); - } ); - } } diff --git a/platform-independent/java/gui/src/main/java/com/lyndir/masterpassword/gui/platform/macos/AppleGUI.java b/platform-independent/java/gui/src/main/java/com/lyndir/masterpassword/gui/platform/AppleGUI.java similarity index 67% rename from platform-independent/java/gui/src/main/java/com/lyndir/masterpassword/gui/platform/macos/AppleGUI.java rename to platform-independent/java/gui/src/main/java/com/lyndir/masterpassword/gui/platform/AppleGUI.java index 2a7c109f..4a5731bf 100644 --- a/platform-independent/java/gui/src/main/java/com/lyndir/masterpassword/gui/platform/macos/AppleGUI.java +++ b/platform-independent/java/gui/src/main/java/com/lyndir/masterpassword/gui/platform/AppleGUI.java @@ -16,29 +16,34 @@ // LICENSE file. Alternatively, see . //============================================================================== -package com.lyndir.masterpassword.gui.platform.macos; +package com.lyndir.masterpassword.gui.platform; import com.apple.eawt.*; import com.google.common.base.Preconditions; -import com.lyndir.masterpassword.gui.GUI; +import com.lyndir.masterpassword.gui.view.MasterPasswordFrame; +import javax.swing.*; /** * @author lhunath, 2014-06-10 */ -public class AppleGUI extends GUI { +public class AppleGUI extends BaseGUI { - static Application application; - - static { - application = Preconditions.checkNotNull( Application.getApplication(), "Not an Apple Java application." ); - } + static Application application = Preconditions.checkNotNull( + Application.getApplication(), "Not an Apple Java application." ); public AppleGUI() { - application.addAppEventListener( new ApplicationListener() ); + application.addAppEventListener( new AppEventHandler() ); } - private class ApplicationListener implements AppForegroundListener, AppReOpenedListener { + @Override + protected MasterPasswordFrame createFrame() { + MasterPasswordFrame frame = super.createFrame(); + frame.setDefaultCloseOperation( WindowConstants.HIDE_ON_CLOSE ); + return frame; + } + + private class AppEventHandler implements AppForegroundListener, AppReOpenedListener { @Override public void appMovedToBackground(final AppEvent.AppForegroundEvent arg0) { diff --git a/platform-independent/java/gui/src/main/java/com/lyndir/masterpassword/gui/platform/BaseGUI.java b/platform-independent/java/gui/src/main/java/com/lyndir/masterpassword/gui/platform/BaseGUI.java new file mode 100644 index 00000000..f0750534 --- /dev/null +++ b/platform-independent/java/gui/src/main/java/com/lyndir/masterpassword/gui/platform/BaseGUI.java @@ -0,0 +1,58 @@ +package com.lyndir.masterpassword.gui.platform; + +import com.lyndir.lhunath.opal.system.logging.Logger; +import com.lyndir.lhunath.opal.system.util.TypeUtils; +import com.lyndir.masterpassword.gui.util.Res; +import com.lyndir.masterpassword.gui.view.MasterPasswordFrame; +import java.lang.reflect.InvocationTargetException; +import java.util.Optional; +import javax.annotation.Nullable; + + +/** + * @author lhunath, 2018-07-28 + */ +public class BaseGUI { + + private static final Logger logger = Logger.get( BaseGUI.class ); + + private final MasterPasswordFrame frame = createFrame(); + + public static BaseGUI createPlatformGUI() { + BaseGUI jdk9GUI = construct( "com.lyndir.masterpassword.gui.platform.JDK9GUI" ); + if (jdk9GUI != null) + return jdk9GUI; + + BaseGUI appleGUI = construct( "com.lyndir.masterpassword.gui.platform.AppleGUI" ); + if (appleGUI != null) + return appleGUI; + + // Use platform-independent GUI. + return new BaseGUI(); + } + + @Nullable + private static BaseGUI construct(final String typeName) { + try { + // AppleGUI adds support for macOS features. + Optional> gui = TypeUtils.loadClass( typeName ); + if (gui.isPresent()) + return gui.get().getConstructor().newInstance(); + } + catch (@SuppressWarnings("ErrorNotRethrown") final LinkageError ignored) { + } + catch (final IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e) { + throw logger.bug( e ); + } + + return null; + } + + protected MasterPasswordFrame createFrame() { + return new MasterPasswordFrame(); + } + + public void open() { + Res.ui( () -> frame.setVisible( true ) ); + } +} diff --git a/platform-independent/java/gui/src/main/java/com/lyndir/masterpassword/gui/platform/JDK9GUI.java b/platform-independent/java/gui/src/main/java/com/lyndir/masterpassword/gui/platform/JDK9GUI.java new file mode 100644 index 00000000..7970f32b --- /dev/null +++ b/platform-independent/java/gui/src/main/java/com/lyndir/masterpassword/gui/platform/JDK9GUI.java @@ -0,0 +1,60 @@ +//============================================================================== +// This file is part of Master Password. +// Copyright (c) 2011-2017, Maarten Billemont. +// +// Master Password is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Master Password is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You can find a copy of the GNU General Public License in the +// LICENSE file. Alternatively, see . +//============================================================================== + +package com.lyndir.masterpassword.gui.platform; + +import com.lyndir.masterpassword.gui.view.MasterPasswordFrame; +import java.awt.*; +import java.awt.desktop.*; +import javax.swing.*; + + +/** + * @author lhunath, 2014-06-10 + */ +@SuppressWarnings("Since15") +public class JDK9GUI extends BaseGUI { + + public JDK9GUI() { + Desktop.getDesktop().addAppEventListener( new AppEventHandler() ); + } + + @Override + protected MasterPasswordFrame createFrame() { + MasterPasswordFrame frame = super.createFrame(); + frame.setDefaultCloseOperation( WindowConstants.HIDE_ON_CLOSE ); + return frame; + } + + private class AppEventHandler implements AppForegroundListener, AppReopenedListener { + + @Override + public void appRaisedToForeground(final AppForegroundEvent e) { + open(); + } + + @Override + public void appMovedToBackground(final AppForegroundEvent e) { + } + + @Override + public void appReopened(final AppReopenedEvent e) { + open(); + } + } +} diff --git a/platform-independent/java/gui/src/main/java/com/lyndir/masterpassword/gui/platform/macos/package-info.java b/platform-independent/java/gui/src/main/java/com/lyndir/masterpassword/gui/platform/package-info.java similarity index 94% rename from platform-independent/java/gui/src/main/java/com/lyndir/masterpassword/gui/platform/macos/package-info.java rename to platform-independent/java/gui/src/main/java/com/lyndir/masterpassword/gui/platform/package-info.java index 1994f1f5..0168e33e 100644 --- a/platform-independent/java/gui/src/main/java/com/lyndir/masterpassword/gui/platform/macos/package-info.java +++ b/platform-independent/java/gui/src/main/java/com/lyndir/masterpassword/gui/platform/package-info.java @@ -20,6 +20,6 @@ * @author lhunath, 2018-04-26 */ @ParametersAreNonnullByDefault -package com.lyndir.masterpassword.gui.platform.macos; +package com.lyndir.masterpassword.gui.platform; import javax.annotation.ParametersAreNonnullByDefault;