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 javax
.swing
.KeyStroke
.getKeyStroke
;
29 import static net
.sourceforge
.aprog
.af
.AFConstants
.Variables
.*;
30 import static net
.sourceforge
.aprog
.af
.MacOSXTools
.*;
31 import static net
.sourceforge
.aprog
.swing
.SwingTools
.*;
32 import static net
.sourceforge
.aprog
.i18n
.Messages
.*;
33 import static net
.sourceforge
.aprog
.tools
.Tools
.*;
35 import java
.awt
.Component
;
36 import java
.lang
.reflect
.Method
;
37 import java
.lang
.reflect
.Proxy
;
39 import javax
.swing
.JMenu
;
40 import javax
.swing
.JMenuItem
;
41 import javax
.swing
.JTabbedPane
;
42 import javax
.swing
.KeyStroke
;
43 import net
.sourceforge
.aprog
.context
.Context
;
45 import net
.sourceforge
.aprog
.swing
.SwingTools
;
46 import net
.sourceforge
.aprog
.tools
.AbstractInvocationHandler
;
47 import net
.sourceforge
.aprog
.tools
.IllegalInstantiationException
;
48 import net
.sourceforge
.aprog
.tools
.Tools
;
52 * @author codistmonk (creation 2010-09-22)
54 public final class AFTools
{
57 * @throws IllegalInstantiationException To prevent instantiation
60 throw new IllegalInstantiationException();
63 public static final String META
= MacOSXTools
.MAC_OS_X ?
"meta" : "control";
66 * Prepares the application to use the OS default look and feel.
67 * <br>On Mac OS X, sets up the use of the screen menu bar and the application name.
69 * @param applicationName
72 public static final void setupSystemLookAndFeel(final String applicationName
) {
75 setApplicationName(applicationName
);
78 useSystemLookAndFeel();
82 * Creates a new context with the folowing properties:<ul>
83 * <li>{@link AFConstants.Variables#APPLICATION_NAME} -> {@link AFConstants#APPLICATION_NAME}
84 * <li>{@link AFConstants.Variables#APPLICATION_VERSION} -> {@link AFConstants#APPLICATION_VERSION}
85 * <li>{@link AFConstants.Variables#APPLICATION_COPYRIGHT} -> {@link AFConstants#APPLICATION_COPYRIGHT}
86 * <li>{@link AFConstants.Variables#APPLICATION_ICON_PATH} -> {@link AFConstants#APPLICATION_ICON_PATH}
93 public static final Context
newContext() {
94 final Context result
= new Context();
96 result
.set(APPLICATION_NAME
, AFConstants
.APPLICATION_NAME
);
97 result
.set(APPLICATION_VERSION
, AFConstants
.APPLICATION_VERSION
);
98 result
.set(APPLICATION_COPYRIGHT
, AFConstants
.APPLICATION_COPYRIGHT
);
99 result
.set(APPLICATION_ICON_PATH
, AFConstants
.APPLICATION_ICON_PATH
);
105 * If {@code context} value for the key {@link AFConstants.Variables#ACTIONS_SHOW_ABOUT_DIALOG} is null,
106 * then associates a new {@link ShowAboutDialogAction} to the key.
107 * <br>On Mac OS X, if the use of the screen menu bar is enabled then registers a listener for the appropriate menu item.
112 * @return An autotranslated menu item or null if the screen menu bar is used on Mac OS X
116 public static final JMenuItem
newAboutItem(final Context context
) {
119 if (context
.get(ACTIONS_SHOW_ABOUT_DIALOG
) == null) {
120 new ShowAboutDialogAction(context
);
123 if (MAC_OS_X
&& getUseScreenMenuBar()) {
126 if (registerMacOSXApplicationListener("handleAbout",
127 AFTools
.class, "perform", context
, ACTIONS_SHOW_ABOUT_DIALOG
)) {
132 return item("About", context
, ACTIONS_SHOW_ABOUT_DIALOG
);
144 public static final JMenuItem
newPreferencesItem(final Context context
) {
147 if (context
.get(ACTIONS_SHOW_PREFERENCES_DIALOG
) == null) {
148 new ShowPreferencesDialogAction(context
);
151 if (MAC_OS_X
&& getUseScreenMenuBar()) {
152 enablePreferencesMenu();
154 if (registerMacOSXApplicationListener("handlePreferences",
155 AFTools
.class, "perform", context
, ACTIONS_SHOW_PREFERENCES_DIALOG
)) {
160 return item("Preferences...", getKeyStroke(META
+ " R"),
161 context
, ACTIONS_SHOW_PREFERENCES_DIALOG
);
173 public static final JMenuItem
newQuitItem(final Context context
) {
176 if (context
.get(ACTIONS_QUIT
) == null) {
177 new QuitAction(context
);
180 if (MAC_OS_X
&& getUseScreenMenuBar()) {
181 if (registerMacOSXApplicationListener("handleQuit",
182 AFTools
.class, "perform", context
, ACTIONS_QUIT
)) {
187 return item("Quit", getKeyStroke(META
+ " Q"),
188 context
, ACTIONS_QUIT
);
198 public static final void perform(final Context context
, final String actionKey
) {
199 ((AbstractAFAction
) context
.get(actionKey
)).perform();
208 * @return The index of {@code component} in {@code tabbedPane}, or {@code -1} if it cannot be found
209 * <br>Range: {@code [-1 .. tabbedPane.getTabCount() - 1]}
211 public static final int indexOf(final JTabbedPane tabbedPane
, final Component component
) {
214 for (int i
= 0; i
< tabbedPane
.getTabCount(); ++i
) {
215 if (component
== tabbedPane
.getComponentAt(i
)) {
224 * Creates a localized menu from the elements in {@code items}.
225 * <br>Uses {@link net.sourceforge.aprog.i18n.Messages#translate(java.lang.Object, java.lang.Object[])}
226 * and {@link SwingTools#menu(java.lang.String, javax.swing.JMenuItem[])}.
228 * @param translationKey
237 public static final JMenu
menu(final String translationKey
, final JMenuItem
... items
) {
240 return translate(SwingTools
.menu(translationKey
, items
));
245 * @param translationKey
254 * @return An autotranslated menu item
258 public static final JMenuItem
item(final String translationKey
, final Context context
,
259 final String actionKey
) {
262 return translate(new JMenuItem(new AFSwingAction(context
, actionKey
)
263 .setName(translationKey
)));
268 * @param translationKey
284 public static final JMenuItem
item(final String translationKey
, final KeyStroke shortcut
,
285 final Context context
, final String actionKey
) {
288 return translate(new JMenuItem(new AFSwingAction(context
, actionKey
)
289 .setName(translationKey
)
290 .setShortcut(shortcut
)));
295 * @param <L> The listener type
296 * @param listenerClass
298 * @param listenerMethodName
300 * @param objectOrClass
310 @SuppressWarnings("unchecked")
311 public static final <L
> L
newListener(final Class
<L
> listenerClass
, final String listenerMethodName
,
312 final Object objectOrClass
, final String methodName
, final Object
... arguments
) {
313 return (L
) Proxy
.newProxyInstance(getCallerClass().getClassLoader(), array(listenerClass
),
314 new ListenerInvocationHandler(listenerMethodName
, objectOrClass
, methodName
, arguments
));
319 * @author codistmonk (creation 2010-07-03)
321 public static final class ListenerInvocationHandler
extends AbstractInvocationHandler
{
323 private final String listenerMethodName
;
325 private final Object objectOrClass
;
327 private final String methodName
;
329 private final Object
[] arguments
;
333 * @param listenerMethodName
336 * @param objectOrClass
346 public ListenerInvocationHandler(final String listenerMethodName
,
347 final Object objectOrClass
, final String methodName
, final Object
... arguments
) {
348 this.listenerMethodName
= listenerMethodName
;
349 this.objectOrClass
= objectOrClass
;
350 this.methodName
= methodName
;
351 this.arguments
= arguments
;
355 public final Object
invoke(final Object proxy
,
356 final Method method
, final Object
[] arguments
) throws Throwable
{
357 if (method
.getName().equals(this.listenerMethodName
)) {
358 return Tools
.invoke(this.objectOrClass
, this.methodName
, this.arguments
);
361 return this.defaultInvoke(proxy
, method
, arguments
);