4 * Copyright 2010 Codist Monk.
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
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
;
49 * @author codistmonk (creation 2010-09-16)
51 public final class MacOSXTools
{
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");
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()}.
70 * @param applicationName
72 * @param applicationIconPath
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
);
86 enablePreferencesMenu();
91 * @param listenerMethodName
94 * <br>Range: { {@code "handleAbout"}, {@code "handlePreferences"}, {@code "handleQuit"} }
95 * @param objectOrClass
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
) {
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() {
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
);
136 } catch (final Exception exception
) {
137 getLoggerForThisMethod().log(Level
.SEVERE
, null, exception
);
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
151 public static void setApplicationDockIcon(final String iconResourcePath
) {
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, ...).
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
179 public static final void setApplicationName(final String applicationName
) {
180 System
.setProperty("com.apple.mrj.application.apple.menu.about.name", applicationName
);
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
);
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);
227 public static final Class
<?
> getApplicationClass() {
229 return Class
.forName("com.apple.eawt.Application");
230 } catch (final ClassNotFoundException exception
) {