[Aprog]
[aprog.git] / Aprog / src / net / sourceforge / aprog / af / MacOSXTools.java
blobdc531ebe19ed214144d117d2732fbc4bc52978ab
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 (MAC_OS_X) {
77 if (applicationName != null) {
78 setApplicationName(applicationName);
81 if (applicationIconPath != null) {
82 setApplicationDockIcon(applicationIconPath);
85 useScreenMenuBar();
86 enableAboutMenu();
87 enablePreferencesMenu();
91 /**
93 * @param listenerMethodName
94 * <br>Not null
95 * <br>Shared
96 * <br>Range: { {@code "handleAbout"}, {@code "handlePreferences"}, {@code "handleQuit"} }
97 * @param objectOrClass
98 * <br>Not null
99 * <br>Shared
100 * @param methodName
101 * <br>Not null
102 * <br>Shared
103 * @param arguments
104 * <br>Not null
105 * <br>Shared
106 * @return {@code true} if a listener was successfully created and registered
108 @SuppressWarnings("unchecked")
109 public static final boolean registerMacOSXApplicationListener(final String listenerMethodName,
110 final Object objectOrClass, final String methodName, final Object... arguments) {
111 try {
112 final Class<?> applicationClass = Class.forName("com.apple.eawt.Application");
113 final Class<?> listenerClass = Class.forName("com.apple.eawt.ApplicationListener");
114 final Class<?> eventClass = Class.forName("com.apple.eawt.ApplicationEvent");
115 final Object application = invoke(applicationClass, "getApplication");
117 invoke(application, "addApplicationListener", Proxy.newProxyInstance(
118 getCallerClass().getClassLoader(),
119 array(listenerClass),
120 new AbstractInvocationHandler() {
122 @Override
123 public final Object invoke(final Object proxy,
124 final Method method, final Object[] proxyMethodArguments) throws Throwable {
125 if (method.getName().equals(listenerMethodName) &&
126 proxyMethodArguments.length == 1 && null != cast(eventClass, proxyMethodArguments[0])) {
127 Tools.invoke(proxyMethodArguments[0], "setHandled", true);
129 return Tools.invoke(objectOrClass, methodName, arguments);
132 return this.defaultInvoke(proxy, method, proxyMethodArguments);
135 }));
137 return true;
138 } catch (final Exception exception) {
139 getLoggerForThisMethod().log(Level.SEVERE, null, exception);
141 return false;
146 * Sets the application dock icon that will be displayed in the Mac OS X Dock.
148 * <br>This must be invoked before loading any UI-related class (AWT, Swing, ...).
150 * @param iconResourcePath
151 * <br>Not null
153 public static void setApplicationDockIcon(final String iconResourcePath) {
154 try {
155 setApplicationDockIcon(ImageIO.read(getResourceAsStream(iconResourcePath)));
156 } catch (final IOException exception) {
157 exception.printStackTrace();
162 * Sets the application dock icon that will be displayed in the Mac OS X Dock.
164 * <br>This must be invoked before loading any UI-related class (AWT, Swing, ...).
166 * @param icon
167 * <br>Not null
169 public static void setApplicationDockIcon(final Image icon) {
170 invoke(invoke(getApplicationClass(), "getApplication"), "setDockIconImage", icon);
174 * Sets the application title that will be displayed in the Mac OS X Application Menu.
176 * <br>This must be invoked before loading any UI-related class (AWT, Swing, ...).
178 * @param applicationName
179 * <br>Not null
181 public static final void setApplicationName(final String applicationName) {
182 System.setProperty("com.apple.mrj.application.apple.menu.about.name", applicationName);
186 * @return
187 * <br>Maybe null
189 public static final String getApplicationName() {
190 return System.getProperty("com.apple.mrj.application.apple.menu.about.name");
194 * Calls {@code setUseScreenMenuBar(true)}.
196 public static final void useScreenMenuBar() {
197 setUseScreenMenuBar(true);
202 * @param useScreenMenuBar
203 * <br>Range: any boolean
205 public static final void setUseScreenMenuBar(final boolean useScreenMenuBar) {
206 System.setProperty("apple.laf.useScreenMenuBar", "" + useScreenMenuBar);
210 * @return
211 * <br>Range: any boolean
213 public static final boolean getUseScreenMenuBar() {
214 return "true".equals(System.getProperty("apple.laf.useScreenMenuBar"));
217 public static final void enableAboutMenu() {
218 invoke(invoke(getApplicationClass(), "getApplication"), "setEnabledAboutMenu", true);
221 public static final void enablePreferencesMenu() {
222 invoke(invoke(getApplicationClass(), "getApplication"), "setEnabledPreferencesMenu", true);
226 * @return
227 * <br>Maybe null
229 public static final Class<?> getApplicationClass() {
230 try {
231 return Class.forName("com.apple.eawt.Application");
232 } catch (final ClassNotFoundException exception) {
233 ignore(exception);
235 return null;