package com.myjavaworld.jftp; import java.awt.Image; import java.awt.Toolkit; import java.awt.Window; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * Helper class for integrating with Mac OS X. The design intent here is to not * refer any Mac OS X specific classes, instead use reflection to use the Mac OS * X specific APIs. * * @author Sai Pullabhotla * */ public class OSXAdapter { /** * A reference to the Mac OS X Application - com.apple.eawt.Application */ private static Object macOSXApplication = null; /** * A reference to the JFTP application */ private static JFTPApplication jftpApplication = null; /** * A common event handler for various types of Mac OS X events */ private static MacOSXEventHandler eventHandler = null; /** * Handler for events generated by Mac OS X. * * @author Sai Pullabhotla * */ private static class MacOSXEventHandler implements InvocationHandler { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // System.out.println("Proxy is null: " + (proxy == null)); // We are only interested in handling the about, preferences and // quit events. if ("handleAbout".equals(method.getName())) { jftpApplication.showAboutDialog(); } else if ("handlePreferences".equals(method.getName())) { jftpApplication.showPreferencesDialog(); } else if ("handleQuitRequestWith".equals(method.getName())) { jftpApplication.quit(); } return null; } } /** * Initializes this Adapter for the given JFTPApplication. * * @param jftpApplication * a reference to the JFTPApplication */ public static void init(JFTPApplication jftpApplication) { OSXAdapter.jftpApplication = jftpApplication; createMacOSXApplication(); if (macOSXApplication == null) { return; } eventHandler = new MacOSXEventHandler(); handleDockIcon(); registerQuitHandler(); registerAboutHandler(); registerPreferencesHandler(); } /** * Registers a handler for handling About event. */ private static void registerAboutHandler() { registerHandler("com.apple.eawt.AboutHandler", "setAboutHandler"); } /** * Registers a handler for handling Quit event. */ private static void registerQuitHandler() { registerHandler("com.apple.eawt.QuitHandler", "setQuitHandler"); } /** * Registers a handler for handling Preferences event. */ private static void registerPreferencesHandler() { registerHandler("com.apple.eawt.PreferencesHandler", "setPreferencesHandler"); } /** * Registers a handler for a specific event. * * @param handlerClassName * the event handler interface name (e.g. * com.apple.eawt.AboutHandler). * @param registrationMethodName * the name of the method defined in the * com.apple.eawt.Application class for registering the above * event handler. */ private static void registerHandler(String handlerClassName, String registrationMethodName) { try { Class<?> handlerClass = Class.forName(handlerClassName); // Create a proxy for the given interface. We use our common class, // MacOSXEventHandler for handling all events. Object proxy = Proxy.newProxyInstance( handlerClass.getClassLoader(), new Class[] { handlerClass }, eventHandler); // Invoke the event handler registration method on the Application // object. Method method = macOSXApplication.getClass().getMethod( registrationMethodName, handlerClass); method.invoke(macOSXApplication, proxy); } catch (Throwable t) { System.err.println("Unable to register event handler: " + handlerClassName); t.printStackTrace(); } } /** * Utility method for enabling full-screen mode for the specified window. * * @param window * the reference to the window object */ public static void enableFullScreenMode(Window window) { if (macOSXApplication == null) { return; } try { Class<?> c = Class.forName("com.apple.eawt.FullScreenUtilities"); Method method = c.getMethod("setWindowCanFullScreen", new Class[] { Window.class, boolean.class }); method.invoke(null, window, true); } catch (Throwable t) { System.err.println("Unable to set fullscreen mode for window"); t.printStackTrace(); } } /** * Sets the dock icon for the application. */ private static void handleDockIcon() { try { Method method = macOSXApplication.getClass().getMethod( "setDockIconImage", Image.class); Image image = Toolkit.getDefaultToolkit().getImage( JFTP.class.getResource("jftp128.gif")); method.invoke(macOSXApplication, new Object[] { image }); } catch (Throwable t) { System.err.println("Unable to set the dock icon"); t.printStackTrace(); } } /** * Reflectively gets a reference to the Mac OS X Application object and * assigns it to the class variable for later use. */ private static void createMacOSXApplication() { String applicationClassName = "com.apple.eawt.Application"; try { Class<?> applicationClass = Class.forName(applicationClassName); Method method = applicationClass.getMethod("getApplication"); macOSXApplication = method.invoke(null); } catch (Throwable exp) { System.err.println("Unable to get a reference to: " + applicationClassName); exp.printStackTrace(); } } }