001package apps.plaf.macosx;
002
003import java.awt.Desktop;
004import java.awt.desktop.*;
005import java.lang.reflect.InvocationTargetException;
006import java.lang.reflect.Method;
007
008/**
009 * Wrapper for Apple provided extensions to Java that allow Java apps to feel
010 * more "Mac-like" on Mac OS X for JDK 9.
011 * <p>
012 * <b>NOTE</b> All use of this class must be wrapped in a conditional test that
013 * ensures that JMRI is not running on Mac OS X or in Try-Catch blocks. The
014 * easiest test is:
015 * <pre><code>
016 * if (SystemType.isMacOSX()) {
017 *     ...
018 * }
019 * </code></pre> A Try-Catch block will need to catch
020 * {@link java.lang.NoClassDefFoundError} Failure to use one of these methods
021 * will result in crashes.
022  *
023 * @author Randall Wood     (c) 2016
024 * @author Daniel Bergqvist (c) 2021
025 * @see Application
026 */
027class Jdk9Application extends Application {
028
029    Jdk9Application() {
030    }
031
032    private void setHandler(String methodName, String handlerType, Object handler) {
033        try {
034            Class<?> parameterType = Class.forName(handlerType);
035            Class<?>[] parameterTypes = {parameterType};
036            Method method = java.awt.Desktop.class.getDeclaredMethod(methodName, parameterTypes);
037            Object[] parameters = {handler};
038            method.invoke(Desktop.getDesktop(), parameters);
039        } catch (NoClassDefFoundError | ClassNotFoundException | NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
040            log.debug("Exception calling {} with {}", methodName, handlerType, ex);
041        }
042    }
043
044    @Override
045    public void setAboutHandler(final AboutHandler handler) {
046        if (handler != null) {
047            java.awt.Desktop.getDesktop().setAboutHandler(handler::handleAbout);
048        } else {
049            this.setHandler("setAboutHandler", "java.awt.desktop.AboutHandler", null); // NOI18N
050        }
051    }
052
053    @Override
054    public void setPreferencesHandler(final PreferencesHandler handler) {
055        if (handler != null) {
056            java.awt.Desktop.getDesktop().setPreferencesHandler(handler::handlePreferences);
057        } else {
058            this.setHandler("setPreferencesHandler", "java.awt.desktop.PreferencesHandler", null); // NOI18N
059        }
060    }
061
062    @Override
063    public void setQuitHandler(final QuitHandler handler) {
064        if (handler != null) {
065            java.awt.Desktop.getDesktop().setQuitHandler(
066                    (QuitEvent qe, QuitResponse response) -> {
067                        if (handler.handleQuitRequest(qe)) {
068                            response.performQuit();
069                        } else {
070                            response.cancelQuit();
071                        }
072                    });
073        } else {
074            this.setHandler("setQuitHandler", "java.awt.desktop.QuitHandler", null); // NOI18N
075        }
076    }
077
078    private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(Jdk9Application.class);
079
080}