[Aprog]
[aprog.git] / Aprog / src / net / sourceforge / aprog / af / MacOSXTools.java
blob8621684d74c61390cba150f377d089c2abdb64e5
1 /*
2 * The MIT License
3 *
4 * Copyright 2010 Codist Monk.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
25 package net.sourceforge.aprog.af;
27 import static net.sourceforge.aprog.tools.Tools.array;
28 import static net.sourceforge.aprog.tools.Tools.cast;
29 import static net.sourceforge.aprog.tools.Tools.getCallerClass;
30 import static net.sourceforge.aprog.tools.Tools.getLoggerForThisMethod;
31 import static net.sourceforge.aprog.tools.Tools.getResourceAsStream;
32 import static net.sourceforge.aprog.tools.Tools.ignore;
33 import static net.sourceforge.aprog.tools.Tools.invoke;
35 import java.awt.Image;
36 import java.io.IOException;
37 import java.lang.reflect.Method;
38 import java.lang.reflect.Proxy;
39 import java.util.logging.Level;
41 import javax.imageio.ImageIO;
43 import net.sourceforge.aprog.tools.AbstractInvocationHandler;
44 import net.sourceforge.aprog.tools.IllegalInstantiationException;
45 import net.sourceforge.aprog.tools.Tools;
47 /**
49 * @author codistmonk (creation 2010-09-16)
51 public final class MacOSXTools {
53 /**
54 * @throws IllegalInstantiationException To prevent instantiation
56 private MacOSXTools() {
57 throw new IllegalInstantiationException();
60 public static final boolean MAC_OS_X = System.getProperty("os.name").equalsIgnoreCase("mac os x");
62 /**
63 * Sets up the GUI with:<ul>
64 * <li>{@link #setApplicationName(String)};
65 * <li>{@link #setApplicationDockIcon(String)};
66 * <li>{@link #useScreenMenuBar()};
67 * <li>{@link #enableAboutMenu()};
68 * <li>{@link #enablePreferencesMenu()}.
69 * </ul>
70 * @param applicationName
71 * <br>Maybe null
72 * @param applicationIconPath
73 * <br>Maybe null
75 public static final void setupUI(final String applicationName, final String applicationIconPath) {
76 if (applicationName != null) {
77 setApplicationName(applicationName);
80 if (applicationIconPath != null) {
81 setApplicationDockIcon(applicationIconPath);
84 useScreenMenuBar();
85 enableAboutMenu();
86 enablePreferencesMenu();
89 /**
91 * @param listenerMethodName
92 * <br>Not null
93 * <br>Shared
94 * <br>Range: { {@code "handleAbout"}, {@code "handlePreferences"}, {@code "handleQuit"} }
95 * @param objectOrClass
96 * <br>Not null
97 * <br>Shared
98 * @param methodName
99 * <br>Not null
100 * <br>Shared
101 * @param arguments
102 * <br>Not null
103 * <br>Shared
104 * @return {@code true} if a listener was successfully created and registered
106 @SuppressWarnings("unchecked")
107 public static final boolean registerMacOSXApplicationListener(final String listenerMethodName,
108 final Object objectOrClass, final String methodName, final Object... arguments) {
109 try {
110 final Class<?> applicationClass = Class.forName("com.apple.eawt.Application");
111 final Class<?> listenerClass = Class.forName("com.apple.eawt.ApplicationListener");
112 final Class<?> eventClass = Class.forName("com.apple.eawt.ApplicationEvent");
113 final Object application = invoke(applicationClass, "getApplication");
115 invoke(application, "addApplicationListener", Proxy.newProxyInstance(
116 getCallerClass().getClassLoader(),
117 array(listenerClass),
118 new AbstractInvocationHandler() {
120 @Override
121 public final Object invoke(final Object proxy,
122 final Method method, final Object[] proxyMethodArguments) throws Throwable {
123 if (method.getName().equals(listenerMethodName) &&
124 proxyMethodArguments.length == 1 && null != cast(eventClass, proxyMethodArguments[0])) {
125 Tools.invoke(proxyMethodArguments[0], "setHandled", true);
127 return Tools.invoke(objectOrClass, methodName, arguments);
130 return this.defaultInvoke(proxy, method, proxyMethodArguments);
133 }));
135 return true;
136 } catch (final Exception exception) {
137 getLoggerForThisMethod().log(Level.SEVERE, null, exception);
139 return false;
144 * Sets the application dock icon that will be displayed in the Mac OS X Dock.
146 * <br>This must be invoked before loading any UI-related class (AWT, Swing, ...).
148 * @param iconResourcePath
149 * <br>Not null
151 public static void setApplicationDockIcon(final String iconResourcePath) {
152 try {
153 setApplicationDockIcon(ImageIO.read(getResourceAsStream(iconResourcePath)));
154 } catch (final IOException exception) {
155 exception.printStackTrace();
160 * Sets the application dock icon that will be displayed in the Mac OS X Dock.
162 * <br>This must be invoked before loading any UI-related class (AWT, Swing, ...).
164 * @param icon
165 * <br>Not null
167 public static void setApplicationDockIcon(final Image icon) {
168 invoke(invoke(getApplicationClass(), "getApplication"), "setDockIconImage", icon);
172 * Sets the application title that will be displayed in the Mac OS X Application Menu.
174 * <br>This must be invoked before loading any UI-related class (AWT, Swing, ...).
176 * @param applicationName
177 * <br>Not null
179 public static final void setApplicationName(final String applicationName) {
180 System.setProperty("com.apple.mrj.application.apple.menu.about.name", applicationName);
184 * @return
185 * <br>Maybe null
187 public static final String getApplicationName() {
188 return System.getProperty("com.apple.mrj.application.apple.menu.about.name");
192 * Calls {@code setUseScreenMenuBar(true)}.
194 public static final void useScreenMenuBar() {
195 setUseScreenMenuBar(true);
200 * @param useScreenMenuBar
201 * <br>Range: any boolean
203 public static final void setUseScreenMenuBar(final boolean useScreenMenuBar) {
204 System.setProperty("apple.laf.useScreenMenuBar", "" + useScreenMenuBar);
208 * @return
209 * <br>Range: any boolean
211 public static final boolean getUseScreenMenuBar() {
212 return "true".equals(System.getProperty("apple.laf.useScreenMenuBar"));
215 public static final void enableAboutMenu() {
216 invoke(invoke(getApplicationClass(), "getApplication"), "setEnabledAboutMenu", true);
219 public static final void enablePreferencesMenu() {
220 invoke(invoke(getApplicationClass(), "getApplication"), "setEnabledPreferencesMenu", true);
224 * @return
225 * <br>Maybe null
227 public static final Class<?> getApplicationClass() {
228 try {
229 return Class.forName("com.apple.eawt.Application");
230 } catch (final ClassNotFoundException exception) {
231 ignore(exception);
233 return null;