View Javadoc

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 }