KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > ui > internal > handlers > WidgetMethodHandler


1 /*******************************************************************************
2  * Copyright (c) 2000, 2006 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.ui.internal.handlers;
12
13 import java.lang.reflect.InvocationTargetException JavaDoc;
14 import java.lang.reflect.Method JavaDoc;
15
16 import org.eclipse.core.commands.AbstractHandler;
17 import org.eclipse.core.commands.ExecutionEvent;
18 import org.eclipse.core.commands.ExecutionException;
19 import org.eclipse.core.runtime.IConfigurationElement;
20 import org.eclipse.core.runtime.IExecutableExtension;
21 import org.eclipse.swt.SWT;
22 import org.eclipse.swt.widgets.Composite;
23 import org.eclipse.swt.widgets.Control;
24 import org.eclipse.swt.widgets.Display;
25 import org.eclipse.ui.internal.ExceptionHandler;
26
27 /**
28  * Handles the cut command in both dialogs and windows. This handler is enabled
29  * if the focus control supports the "cut" method.
30  *
31  * @since 3.0
32  */

33 public class WidgetMethodHandler extends AbstractHandler implements
34         IExecutableExtension {
35
36     /**
37      * The parameters to pass to the method this handler invokes. This handler
38      * always passes no parameters.
39      */

40     protected static final Class JavaDoc[] NO_PARAMETERS = new Class JavaDoc[0];
41
42     /**
43      * The name of the method to be invoked by this handler. This value should
44      * never be <code>null</code>.
45      */

46     protected String JavaDoc methodName;
47
48     public Object JavaDoc execute(final ExecutionEvent event) throws ExecutionException {
49         final Method JavaDoc methodToExecute = getMethodToExecute();
50         if (methodToExecute != null) {
51             try {
52                 final Control focusControl = Display.getCurrent()
53                         .getFocusControl();
54                 if ((focusControl instanceof Composite)
55                         && ((((Composite) focusControl).getStyle() & SWT.EMBEDDED) != 0)) {
56                     /*
57                      * Okay. Have a seat. Relax a while. This is going to be a
58                      * bumpy ride. If it is an embedded widget, then it *might*
59                      * be a Swing widget. At the point where this handler is
60                      * executing, the key event is already bound to be
61                      * swallowed. If I don't do something, then the key will be
62                      * gone for good. So, I will try to forward the event to the
63                      * Swing widget. Unfortunately, we can't even count on the
64                      * Swing libraries existing, so I need to use reflection
65                      * everywhere. And, to top it off, I need to dispatch the
66                      * event on the Swing event queue, which means that it will
67                      * be carried out asynchronously to the SWT event queue.
68                      */

69                     try {
70                         final Object JavaDoc focusComponent = getFocusComponent();
71                         if (focusComponent != null) {
72                             Runnable JavaDoc methodRunnable = new Runnable JavaDoc() {
73                                 public void run() {
74                                     try {
75                                         methodToExecute.invoke(focusComponent,
76                                                 null);
77                                     } catch (final IllegalAccessException JavaDoc e) {
78                                         // The method is protected, so do
79
// nothing.
80
} catch (final InvocationTargetException JavaDoc e) {
81                                         /*
82                                          * I would like to log this exception --
83                                          * and possibly show a dialog to the
84                                          * user -- but I have to go back to the
85                                          * SWT event loop to do this. So, back
86                                          * we go....
87                                          */

88                                         focusControl.getDisplay().asyncExec(
89                                                 new Runnable JavaDoc() {
90                                                     public void run() {
91                                                         ExceptionHandler
92                                                                 .getInstance()
93                                                                 .handleException(
94                                                                         new ExecutionException(
95                                                                                 "An exception occurred while executing " //$NON-NLS-1$
96
+ methodToExecute
97                                                                                                 .getName(),
98                                                                                 e
99                                                                                         .getTargetException()));
100                                                     }
101                                                 });
102                                     }
103                                 }
104                             };
105
106                             swingInvokeLater(methodRunnable);
107                         }
108                     } catch (final ClassNotFoundException JavaDoc e) {
109                         // There is no Swing support, so do nothing.
110

111                     } catch (final NoSuchMethodException JavaDoc e) {
112                         // The API has changed, which seems amazingly unlikely.
113
throw new Error JavaDoc("Something is seriously wrong here"); //$NON-NLS-1$
114
}
115
116                 } else {
117
118                     methodToExecute.invoke(focusControl, null);
119                 }
120
121             } catch (IllegalAccessException JavaDoc e) {
122                 // The method is protected, so do nothing.
123

124             } catch (InvocationTargetException JavaDoc e) {
125                 throw new ExecutionException(
126                         "An exception occurred while executing " //$NON-NLS-1$
127
+ methodToExecute.getName(), e
128                                 .getTargetException());
129
130             }
131         }
132
133         return null;
134     }
135
136     /**
137      * Invoke a runnable on the swing EDT.
138      *
139      * @param methodRunnable
140      * @throws ClassNotFoundException
141      * @throws NoSuchMethodException
142      * @throws IllegalAccessException
143      * @throws InvocationTargetException
144      */

145     protected void swingInvokeLater(Runnable JavaDoc methodRunnable)
146             throws ClassNotFoundException JavaDoc, NoSuchMethodException JavaDoc,
147             IllegalAccessException JavaDoc, InvocationTargetException JavaDoc {
148         final Class JavaDoc swingUtilitiesClass = Class
149                 .forName("javax.swing.SwingUtilities"); //$NON-NLS-1$
150
final Method JavaDoc swingUtilitiesInvokeLaterMethod = swingUtilitiesClass
151                 .getMethod("invokeLater", //$NON-NLS-1$
152
new Class JavaDoc[] { Runnable JavaDoc.class });
153         swingUtilitiesInvokeLaterMethod.invoke(
154                 swingUtilitiesClass,
155                 new Object JavaDoc[] { methodRunnable });
156     }
157
158     /**
159      * Find the swing focus component, if it is available.
160      *
161      * @return Hopefully, the swing focus component, but it can return <code>null</code>.
162      * @throws ClassNotFoundException
163      * @throws NoSuchMethodException
164      * @throws IllegalAccessException
165      * @throws InvocationTargetException
166      */

167     protected Object JavaDoc getFocusComponent() throws ClassNotFoundException JavaDoc,
168             NoSuchMethodException JavaDoc, IllegalAccessException JavaDoc,
169             InvocationTargetException JavaDoc {
170         final Class JavaDoc focusManagerClass = Class
171                 .forName("javax.swing.FocusManager"); //$NON-NLS-1$
172
final Method JavaDoc focusManagerGetCurrentManagerMethod = focusManagerClass
173                 .getMethod("getCurrentManager", null); //$NON-NLS-1$
174
final Object JavaDoc focusManager = focusManagerGetCurrentManagerMethod
175                 .invoke(focusManagerClass, null);
176         final Method JavaDoc focusManagerGetFocusOwner = focusManagerClass
177                 .getMethod("getFocusOwner", null); //$NON-NLS-1$
178
final Object JavaDoc focusComponent = focusManagerGetFocusOwner
179                 .invoke(focusManager, null);
180         return focusComponent;
181     }
182
183     public final boolean isEnabled() {
184         return getMethodToExecute() != null;
185     }
186
187     /**
188      * Looks up the method on the focus control.
189      *
190      * @return The method on the focus control; <code>null</code> if none.
191      */

192     protected Method JavaDoc getMethodToExecute() {
193         final Control focusControl = Display.getCurrent().getFocusControl();
194         Method JavaDoc method = null;
195
196         if (focusControl != null) {
197             final Class JavaDoc clazz = focusControl.getClass();
198             try {
199                 method = clazz.getMethod(methodName, NO_PARAMETERS);
200             } catch (NoSuchMethodException JavaDoc e) {
201                 // Fall through...
202
}
203         }
204
205         if ((method == null)
206                 && (focusControl instanceof Composite)
207                 && ((((Composite) focusControl).getStyle() & SWT.EMBEDDED) != 0)) {
208             /*
209              * We couldn't find the appropriate method on the current focus
210              * control. It is possible that the current focus control is an
211              * embedded SWT composite, which could be containing some Swing
212              * components. If this is the case, then we should try to pass
213              * through to the underlying Swing component hierarchy. Insha'allah,
214              * this will work.
215              */

216             try {
217                 final Object JavaDoc focusComponent = getFocusComponent();
218                 if (focusComponent != null) {
219                     final Class JavaDoc clazz = focusComponent.getClass();
220
221                     try {
222                         method = clazz.getMethod(methodName, NO_PARAMETERS);
223                     } catch (NoSuchMethodException JavaDoc e) {
224                         // Do nothing.
225
}
226                 }
227             } catch (final ClassNotFoundException JavaDoc e) {
228                 // There is no Swing support, so do nothing.
229

230             } catch (final NoSuchMethodException JavaDoc e) {
231                 // The API has changed, which seems amazingly unlikely.
232
throw new Error JavaDoc("Something is seriously wrong here"); //$NON-NLS-1$
233
} catch (IllegalAccessException JavaDoc e) {
234                 // The API has changed, which seems amazingly unlikely.
235
throw new Error JavaDoc("Something is seriously wrong here"); //$NON-NLS-1$
236
} catch (InvocationTargetException JavaDoc e) {
237                 // The API has changed, which seems amazingly unlikely.
238
throw new Error JavaDoc("Something is seriously wrong here"); //$NON-NLS-1$
239
}
240         }
241
242         return method;
243     }
244
245     /*
246      * (non-Javadoc)
247      *
248      * @see org.eclipse.core.runtime.IExecutableExtension#setInitializationData(org.eclipse.core.runtime.IConfigurationElement,
249      * java.lang.String, java.lang.Object)
250      */

251     public void setInitializationData(IConfigurationElement config,
252             String JavaDoc propertyName, Object JavaDoc data) {
253         // The data is really just a string (i.e., the method name).
254
methodName = data.toString();
255     }
256 }
257
Popular Tags