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
) {
77 if (applicationName
!= null) {
78 setApplicationName(applicationName
);
81 if (applicationIconPath
!= null) {
82 setApplicationDockIcon(applicationIconPath
);
87 enablePreferencesMenu();
93 * @param listenerMethodName
96 * <br>Range: { {@code "handleAbout"}, {@code "handlePreferences"}, {@code "handleQuit"} }
97 * @param objectOrClass
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
) {
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() {
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
);
138 } catch (final Exception exception
) {
139 getLoggerForThisMethod().log(Level
.SEVERE
, null, exception
);
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
153 public static void setApplicationDockIcon(final String iconResourcePath
) {
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, ...).
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
181 public static final void setApplicationName(final String applicationName
) {
182 System
.setProperty("com.apple.mrj.application.apple.menu.about.name", applicationName
);
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
);
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);
229 public static final Class
<?
> getApplicationClass() {
231 return Class
.forName("com.apple.eawt.Application");
232 } catch (final ClassNotFoundException exception
) {