1 /*
2 Copyright (C) 2000 - 2007 Grid Systems, S.A.
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License, version 2, as
6 published by the Free Software Foundation.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 */
17
18 /*
19 * Project: KernelConfigurator
20 * Created on 27-feb-2004
21 *
22 * Copyright (c)2003 Grid Systems
23 */
24 package com.gridsystems.config.tools.swing;
25
26 import java.awt.event.ActionEvent;
27 import java.lang.reflect.Method;
28 import java.util.ResourceBundle;
29
30 import javax.swing.AbstractAction;
31
32 import com.gridsystems.config.app.UI;
33
34 /**
35 * Action implementation that invokes a specified method of another class through
36 * reflection.
37 * <p>
38 * It allows the minimization of class creation for actions.
39 *
40 * @author <a href="mailto:rruiz@gridsystems.com">Rodrigo Ruiz Aguayo</a>
41 * @version 1.0
42 */
43 public class ReflectedAction extends AbstractAction {
44 /**
45 * The object instance that will execute the action.
46 */
47 private Object target;
48
49 /**
50 * The method to invoke to execute the action.
51 */
52 private Method method;
53
54 /**
55 * If <code>true</code> the action event will be passed as a parameter to the method.
56 */
57 private boolean sendEvent;
58
59 /**
60 * Name of the resource bundle from where this action label will be obtained.
61 */
62 private String bundleName;
63
64 /**
65 * Key in the resource bundle for the label text.
66 */
67 private String bundleKey;
68
69 /**
70 * Creates an action that will invoke the specified method name on the
71 * target object on ActionEvents.
72 * <p>
73 * It first searches for a method taking an ActionEvent instance as argument,
74 * and if not found, it will search for a method with no arguments.
75 * <p>
76 * The key parameter contains an string indicating from where to obtain this
77 * action name. Its syntax is one of:
78 *
79 * <ul>
80 * <li> <code>key</code> : searches the key through UI.getString()
81 * <li> <code>#key</code> : as the previous one
82 * <li> <code>bundleName#key</code> : searches key in a bundle with name
83 * "bundleName"
84 * </ul>
85 *
86 * @param target The object whose method will be invoked
87 * @param methodName The name of the method to invoke
88 * @param key The key for i18n of the action name.
89 */
90 public ReflectedAction(Object target, String methodName, String key) {
91 super();
92
93 // Gets the method to invoke
94 if (methodName != null) {
95 this.target = target;
96 Class c = target.getClass();
97 Class[] types = { ActionEvent.class };
98 method = getMethod(c, methodName, types);
99 if (method == null) {
100 method = getMethod(c, methodName, null);
101 }
102 if (method == null) {
103 throw new NoSuchMethodError(c.getName() + "." + methodName);
104 }
105 }
106
107 // Parses the bundle name / key pair for I18N
108 String text = null;
109 int pos = key.indexOf('#');
110 if (pos == -1) {
111 text = UI.getString(key + ".text");
112 } else if (pos == 0) {
113 text = UI.getString(key.substring(1) + ".text");
114 } else {
115 bundleName = key.substring(0, pos);
116 bundleKey = key.substring(pos + 1);
117 ResourceBundle bundle = ResourceBundle.getBundle(bundleName);
118 text = bundle.getString(bundleKey + ".text");
119 }
120
121 // Sets the label for this action
122 this.putValue(AbstractAction.NAME, text);
123 }
124
125 /**
126 * Gets a Method instance. It differs from Class.getMethod() in that if no
127 * method is found, it returns null instead of throwing an exception.
128 *
129 * @param c The class
130 * @param methodName The name of the method
131 * @param types The argument type list
132 * @return The Method instance, or null if not found
133 */
134 private Method getMethod(Class c, String methodName, Class[] types) {
135 try {
136 return c.getMethod(methodName, types);
137 } catch (Exception e) {
138 return null;
139 }
140 }
141
142 /**
143 * {@inheritDoc}
144 */
145 public void actionPerformed(ActionEvent event) {
146 if (method != null) {
147 Object[] args = (sendEvent) ? new Object[] { event } : null;
148 try {
149 method.invoke(target, args);
150 } catch (Exception e) {
151 e.printStackTrace();
152 }
153 }
154 }
155 }