KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jdesktop > swing > actions > BoundAction


1 /*
2  * $Id: BoundAction.java,v 1.1.1.1 2004/06/16 01:43:39 davidson1 Exp $
3  *
4  * Copyright 2004 Sun Microsystems, Inc., 4150 Network Circle,
5  * Santa Clara, California 95054, U.S.A. All rights reserved.
6  */

7
8 /**
9  * Copyright 2004 Sun Microsystems, Inc. All Rights Reserved.
10  *
11  * Redistribution and use in source and binary forms, with or
12  * without modification, are permitted provided that the following
13  * conditions are met:
14  *
15  * - Redistributions of source code must retain the above copyright
16  * notice, this list of conditions and the following disclaimer.
17  *
18  * - Redistribution in binary form must reproduce the above
19  * copyright notice, this list of conditions and the following
20  * disclaimer in the documentation and/or other materials
21  * provided with the distribution.
22  *
23  * Neither the name of Sun Microsystems, Inc. or the names of
24  * contributors may be used to endorse or promote products derived
25  * from this software without specific prior written permission.
26  *
27  * This software is provided "AS IS," without a warranty of any
28  * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
29  * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
30  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
31  * EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY
32  * DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT OF OR
33  * RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THIS SOFTWARE OR
34  * ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS LICENSORS BE LIABLE
35  * FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT,
36  * SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
37  * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF
38  * THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF SUN HAS
39  * BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
40  *
41  * You acknowledge that this software is not designed, licensed or
42  * intended for use in the design, construction, operation or
43  * maintenance of any nuclear facility.
44  *
45  */

46 package org.jdesktop.swing.actions;
47
48 import java.awt.event.ActionEvent JavaDoc;
49 import java.awt.event.ActionListener JavaDoc;
50 import java.awt.event.ItemEvent JavaDoc;
51 import java.awt.event.ItemListener JavaDoc;
52
53 import java.beans.EventHandler JavaDoc;
54 import java.beans.Statement JavaDoc;
55
56 import java.util.EventListener JavaDoc;
57 import java.util.Iterator JavaDoc;
58 import java.util.List JavaDoc;
59
60 import javax.swing.Action JavaDoc;
61 import javax.swing.Icon JavaDoc;
62
63 import javax.swing.event.EventListenerList JavaDoc;
64
65 /**
66  * A class that represents the many type of actions that this framework supports.
67  * <p>
68  * The command invocation of this action may be delegated to another action or item state
69  * listener. If there isn't an explicit binding then the command is forwarded to
70  * the TargetManager.
71  *
72  * @author Mark Davidson
73  */

74 public class BoundAction extends AbstractActionExt {
75
76     // Holds the listeners
77
private EventListenerList JavaDoc listeners;
78
79     public BoundAction() {
80     this("BoundAction");
81     }
82
83     public BoundAction(String JavaDoc name) {
84     super(name);
85     }
86
87     /**
88      * @param name display name of the action
89      * @param command the value of the action command key
90      */

91     public BoundAction(String JavaDoc name, String JavaDoc command) {
92     super(name, command);
93     }
94
95     public BoundAction(String JavaDoc name, Icon JavaDoc icon) {
96     super(name, icon);
97     }
98
99     /**
100      * @param name display name of the action
101      * @param command the value of the action command key
102      * @param icon icon to display
103      */

104     public BoundAction(String JavaDoc name, String JavaDoc command, Icon JavaDoc icon) {
105     super(name, command, icon);
106     }
107
108     /**
109      * The callback string will be called to register the action callback.
110      * Note the toggle property must be set if this is a state action before
111      * this method is called.
112      * For example,
113      * <pre>
114      * &lt;exec&gt;com.sun.foo.FubarHandler#handleBar&lt;/exec&gt;
115      * </pre>
116      * will register
117      * <pre>
118      * registerCallback(com.sun.foo.FubarHandler(), "handleBar");
119      * </pre>
120      */

121     public void setCallback(String JavaDoc callback) {
122     String JavaDoc[] elems = callback.split("#", 2);
123     if (elems.length == 2) {
124         try {
125         Class JavaDoc clz = Class.forName(elems[0]);
126
127         // May throw a security exception in an Applet
128
// context.
129
Object JavaDoc obj = clz.newInstance();
130
131         registerCallback(obj, elems[1]);
132         } catch (Exception JavaDoc ex) {
133         System.out.println("ERROR: setCallback(" + callback
134                    + ") - " + ex.getMessage());
135         }
136     }
137     }
138
139     /**
140      * Registers a callback method when the Action corresponding to
141      * the action id is invoked. When a Component that was constructed from the
142      * Action identified by the action id invokes actionPerformed then the method
143      * named will be invoked on the handler Object.
144      * <p>
145      * If the Action represented by the action id is a StateChangeAction, then
146      * the method passed should take an int as an argument. The value of
147      * getStateChange() on the ItemEvent object will be passed as the parameter.
148      *
149      * @param handler the object which will be perform the action
150      * @param method the name of the method on the handler which will be called.
151      */

152     public void registerCallback(Object JavaDoc handler, String JavaDoc method) {
153     if (isStateAction()) {
154         // Create a handler for toogle type actions.
155
addItemListener(new BooleanInvocationHandler(handler, method));
156     } else {
157         // Create a new ActionListener using the dynamic proxy api.
158
addActionListener((ActionListener JavaDoc)EventHandler.create(ActionListener JavaDoc.class,
159                                   handler, method));
160     }
161     }
162     
163     /**
164      * The callback for the toggle/state changed action that invokes a method
165      * with a boolean argument on a target.
166      *
167      * TODO: should reimplement this class as something that can be persistable.
168      */

169     private class BooleanInvocationHandler implements ItemListener JavaDoc {
170
171     private Statement JavaDoc falseStatement;
172     private Statement JavaDoc trueStatement;
173
174     public BooleanInvocationHandler(Object JavaDoc target, String JavaDoc methodName) {
175         // Create the true and false statements.
176
falseStatement = new Statement JavaDoc(target, methodName,
177                        new Object JavaDoc[] { Boolean.FALSE });
178         
179         trueStatement = new Statement JavaDoc(target, methodName,
180                       new Object JavaDoc[] { Boolean.TRUE });
181     }
182
183     public void itemStateChanged(ItemEvent JavaDoc evt) {
184         Statement JavaDoc statement = (evt.getStateChange() == ItemEvent.DESELECTED) ?
185         falseStatement : trueStatement;
186         
187         try {
188         statement.execute();
189         } catch (Exception JavaDoc ex) {
190         ex.printStackTrace();
191         }
192     }
193     }
194
195     // Listener registration...
196

197     private void addListener(Class JavaDoc clz, EventListener JavaDoc listener) {
198     if (listeners == null) {
199         listeners = new EventListenerList JavaDoc();
200     }
201     listeners.add(clz, listener);
202     }
203
204     private void removeListener(Class JavaDoc clz, EventListener JavaDoc listener) {
205     if (listeners != null) {
206         listeners.remove(clz, listener);
207     }
208     }
209
210     private EventListener JavaDoc[] getListeners(Class JavaDoc clz) {
211     if (listeners == null) {
212         return null;
213     }
214     return listeners.getListeners(clz);
215     }
216
217     /**
218      * Add an action listener which will be invoked when this action is invoked.
219      */

220     public void addActionListener(ActionListener JavaDoc listener) {
221     addListener(ActionListener JavaDoc.class, listener);
222     }
223
224     public void removeActionListener(ActionListener JavaDoc listener) {
225     removeListener(ActionListener JavaDoc.class, listener);
226     }
227
228     public ActionListener JavaDoc[] getActionListeners() {
229     return (ActionListener JavaDoc[])getListeners(ActionListener JavaDoc.class);
230     }
231
232     /**
233      * Add an item listener which will be invoked for toggle actions.
234      */

235     public void addItemListener(ItemListener JavaDoc listener) {
236     addListener(ItemListener JavaDoc.class, listener);
237     }
238
239     public void removeItemListener(ItemListener JavaDoc listener) {
240     removeListener(ItemListener JavaDoc.class, listener);
241     }
242
243     public ItemListener JavaDoc[] getItemListeners() {
244     return (ItemListener JavaDoc[])getListeners(ItemListener JavaDoc.class);
245     }
246
247     // Callbacks...
248

249     /**
250      * Callback for command actions.
251      */

252     public void actionPerformed(ActionEvent JavaDoc evt) {
253     ActionListener JavaDoc[] alist = getActionListeners();
254     if (alist != null) {
255         for (int i = 0 ; i < alist.length; i++) {
256         alist[i].actionPerformed(evt);
257         }
258     }
259     }
260
261     /**
262      * Callback for toggle actions.
263      */

264     public void itemStateChanged(ItemEvent JavaDoc evt) {
265         // Update all objects that share this item
266
boolean newValue;
267     boolean oldValue = isSelected();
268
269         if (evt.getStateChange() == ItemEvent.SELECTED) {
270         newValue = true;
271     } else {
272         newValue = false;
273     }
274
275     if (oldValue != newValue) {
276         setSelected(newValue);
277
278         // Forward the event to the delgate for handling.
279
ItemListener JavaDoc[] ilist = getItemListeners();
280         if (ilist != null) {
281         for (int i = 0; i < ilist.length; i++) {
282             ilist[i].itemStateChanged(evt);
283         }
284         }
285     }
286     }
287
288 }
289
Popular Tags