KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > swt > awt > SWT_AWT


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 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.swt.awt;
12
13 import java.lang.reflect.Constructor JavaDoc;
14 import java.lang.reflect.Field JavaDoc;
15 import java.lang.reflect.Method JavaDoc;
16
17 /* SWT Imports */
18 import org.eclipse.swt.*;
19 import org.eclipse.swt.graphics.Rectangle;
20 import org.eclipse.swt.widgets.Shell;
21 import org.eclipse.swt.widgets.Composite;
22 import org.eclipse.swt.widgets.Display;
23 import org.eclipse.swt.widgets.Listener;
24 import org.eclipse.swt.widgets.Event;
25 import org.eclipse.swt.internal.*;
26
27 /* AWT Imports */
28 import java.awt.EventQueue JavaDoc;
29 import java.awt.Canvas JavaDoc;
30 import java.awt.Frame JavaDoc;
31 import java.awt.Dimension JavaDoc;
32 import java.awt.Toolkit JavaDoc;
33 import java.awt.event.ComponentAdapter JavaDoc;
34 import java.awt.event.ComponentEvent JavaDoc;
35 import java.awt.event.WindowEvent JavaDoc;
36 import java.awt.event.FocusEvent JavaDoc;
37
38 /**
39  * This class provides a bridge between SWT and AWT, so that it
40  * is possible to embed AWT components in SWT and vice versa.
41  *
42  * @since 3.0
43  */

44 public class SWT_AWT {
45
46     /**
47      * The name of the embedded Frame class. The default class name
48      * for the platform will be used if <code>null</code>.
49      */

50     public static String JavaDoc embeddedFrameClass;
51
52     /**
53      * Key for looking up the embedded frame for a Composite using
54      * getData().
55      */

56     static String JavaDoc EMBEDDED_FRAME_KEY = "org.eclipse.swt.awt.SWT_AWT.embeddedFrame";
57
58     static boolean loaded, swingInitialized;
59
60 static native final int getAWTHandle (Canvas JavaDoc canvas);
61
62 static synchronized void loadLibrary () {
63     if (loaded) return;
64     loaded = true;
65     Toolkit.getDefaultToolkit();
66     /*
67     * Note that the jawt library is loaded explicitly
68     * because it cannot be found by the library loader.
69     * All exceptions are caught because the library may
70     * have been loaded already.
71     */

72     try {
73         System.loadLibrary("jawt");
74     } catch (Throwable JavaDoc e) {}
75     Library.loadLibrary("swt-awt");
76 }
77
78 static synchronized void initializeSwing() {
79     if (swingInitialized) return;
80     swingInitialized = true;
81     try {
82         /* Initialize the default focus traversal policy */
83         Class JavaDoc[] emptyClass = new Class JavaDoc[0];
84         Object JavaDoc[] emptyObject = new Object JavaDoc[0];
85         Class JavaDoc clazz = Class.forName("javax.swing.UIManager");
86         Method JavaDoc method = clazz.getMethod("getDefaults", emptyClass);
87         if (method != null) method.invoke(clazz, emptyObject);
88     } catch (Throwable JavaDoc e) {}
89 }
90
91 /**
92  * Returns a <code>java.awt.Frame</code> which is the embedded frame
93  * associated with the specified composite.
94  *
95  * @param parent the parent <code>Composite</code> of the <code>java.awt.Frame</code>
96  * @return a <code>java.awt.Frame</code> the embedded frame or <code>null</code>.
97  *
98  * @exception IllegalArgumentException <ul>
99  * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
100  * </ul>
101  *
102  * @since 3.2
103  */

104 public static Frame JavaDoc getFrame (Composite parent) {
105     if (parent == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
106     if ((parent.getStyle () & SWT.EMBEDDED) == 0) return null;
107     return (Frame JavaDoc)parent.getData(EMBEDDED_FRAME_KEY);
108 }
109
110 /**
111  * Creates a new <code>java.awt.Frame</code>. This frame is the root for
112  * the AWT components that will be embedded within the composite. In order
113  * for the embedding to succeed, the composite must have been created
114  * with the SWT.EMBEDDED style.
115  * <p>
116  * IMPORTANT: As of JDK1.5, the embedded frame does not receive mouse events.
117  * When a lightweight component is added as a child of the embedded frame,
118  * the cursor does not change. In order to work around both these problems, it is
119  * strongly recommended that a heavyweight component such as <code>java.awt.Panel</code>
120  * be added to the frame as the root of all components.
121  * </p>
122  *
123  * @param parent the parent <code>Composite</code> of the new <code>java.awt.Frame</code>
124  * @return a <code>java.awt.Frame</code> to be the parent of the embedded AWT components
125  *
126  * @exception IllegalArgumentException <ul>
127  * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
128  * <li>ERROR_INVALID_ARGUMENT - if the parent Composite does not have the SWT.EMBEDDED style</li>
129  * </ul>
130  *
131  * @since 3.0
132  */

133 public static Frame JavaDoc new_Frame (final Composite parent) {
134     if (parent == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
135     if ((parent.getStyle () & SWT.EMBEDDED) == 0) {
136         SWT.error (SWT.ERROR_INVALID_ARGUMENT);
137     }
138     int handle = parent.handle;
139     /*
140      * Some JREs have implemented the embedded frame constructor to take an integer
141      * and other JREs take a long. To handle this binary incompatibility, use
142      * reflection to create the embedded frame.
143      */

144     Class JavaDoc clazz = null;
145     try {
146         String JavaDoc className = embeddedFrameClass != null ? embeddedFrameClass : "sun.awt.windows.WEmbeddedFrame";
147         clazz = Class.forName(className);
148     } catch (Throwable JavaDoc e) {
149         SWT.error (SWT.ERROR_NOT_IMPLEMENTED, e);
150     }
151     Constructor JavaDoc constructor = null;
152     try {
153         constructor = clazz.getConstructor (new Class JavaDoc [] {int.class});
154     } catch (Throwable JavaDoc e1) {
155         try {
156             constructor = clazz.getConstructor (new Class JavaDoc [] {long.class});
157         } catch (Throwable JavaDoc e2) {
158             SWT.error (SWT.ERROR_NOT_IMPLEMENTED, e2);
159         }
160     }
161     initializeSwing ();
162     Object JavaDoc value = null;
163     try {
164         value = constructor.newInstance (new Object JavaDoc [] {new Integer JavaDoc (handle)});
165     } catch (Throwable JavaDoc e) {
166         SWT.error (SWT.ERROR_NOT_IMPLEMENTED, e);
167     }
168     final Frame JavaDoc frame = (Frame JavaDoc) value;
169     /*
170      * This is necessary to make lightweight components
171      * directly added to the frame receive mouse events
172      * properly.
173      */

174     frame.addNotify();
175
176     parent.setData(EMBEDDED_FRAME_KEY, frame);
177     
178     /* Forward the iconify and deiconify events */
179     final Listener shellListener = new Listener () {
180         public void handleEvent (Event e) {
181             switch (e.type) {
182                 case SWT.Deiconify:
183                     EventQueue.invokeLater(new Runnable JavaDoc () {
184                         public void run () {
185                             frame.dispatchEvent (new WindowEvent JavaDoc (frame, WindowEvent.WINDOW_DEICONIFIED));
186                         }
187                     });
188                     break;
189                 case SWT.Iconify:
190                     EventQueue.invokeLater(new Runnable JavaDoc () {
191                         public void run () {
192                             frame.dispatchEvent (new WindowEvent JavaDoc (frame, WindowEvent.WINDOW_ICONIFIED));
193                         }
194                     });
195                     break;
196             }
197         }
198     };
199     Shell shell = parent.getShell ();
200     shell.addListener (SWT.Deiconify, shellListener);
201     shell.addListener (SWT.Iconify, shellListener);
202     
203     /*
204     * Generate the appropriate events to activate and deactivate
205     * the embedded frame. This is needed in order to make keyboard
206     * focus work properly for lightweights.
207     */

208     Listener listener = new Listener () {
209         public void handleEvent (Event e) {
210             switch (e.type) {
211                 case SWT.Dispose:
212                     Shell shell = parent.getShell ();
213                     shell.removeListener (SWT.Deiconify, shellListener);
214                     shell.removeListener (SWT.Iconify, shellListener);
215                     parent.setVisible(false);
216                     EventQueue.invokeLater(new Runnable JavaDoc () {
217                         public void run () {
218                             frame.dispose ();
219                         }
220                     });
221                     break;
222                 case SWT.Activate:
223                     EventQueue.invokeLater(new Runnable JavaDoc () {
224                         public void run () {
225                             if (Library.JAVA_VERSION < Library.JAVA_VERSION(1, 4, 0)) {
226                                 frame.dispatchEvent (new WindowEvent JavaDoc (frame, WindowEvent.WINDOW_ACTIVATED));
227                                 frame.dispatchEvent (new FocusEvent JavaDoc (frame, FocusEvent.FOCUS_GAINED));
228                             } else {
229                                 frame.dispatchEvent (new WindowEvent JavaDoc (frame, WindowEvent.WINDOW_ACTIVATED));
230                                 frame.dispatchEvent (new WindowEvent JavaDoc (frame, 207 /*WindowEvent.WINDOW_GAINED_FOCUS*/));
231                             }
232                         }
233                     });
234                     break;
235                 case SWT.Deactivate:
236                     EventQueue.invokeLater(new Runnable JavaDoc () {
237                         public void run () {
238                             if (Library.JAVA_VERSION < Library.JAVA_VERSION(1, 4, 0)) {
239                                 frame.dispatchEvent (new WindowEvent JavaDoc (frame, WindowEvent.WINDOW_DEACTIVATED));
240                                 frame.dispatchEvent (new FocusEvent JavaDoc (frame, FocusEvent.FOCUS_LOST));
241                             } else {
242                                 frame.dispatchEvent (new WindowEvent JavaDoc (frame, 208 /*WindowEvent.WINDOW_LOST_FOCUS*/));
243                                 frame.dispatchEvent (new WindowEvent JavaDoc (frame, WindowEvent.WINDOW_DEACTIVATED));
244                             }
245                         }
246                     });
247                     break;
248             }
249         }
250     };
251     parent.addListener (SWT.Activate, listener);
252     parent.addListener (SWT.Deactivate, listener);
253     parent.addListener (SWT.Dispose, listener);
254     
255     parent.getDisplay().asyncExec(new Runnable JavaDoc() {
256         public void run () {
257             if (parent.isDisposed()) return;
258             final Rectangle clientArea = parent.getClientArea();
259             EventQueue.invokeLater(new Runnable JavaDoc () {
260                 public void run () {
261                     frame.setSize (clientArea.width, clientArea.height);
262                     frame.validate ();
263                 }
264             });
265         }
266     });
267     /*
268     * TEMPORARY CODE
269     *
270     * For some reason, the graphics configuration of the embedded
271     * frame is not initialized properly. This causes an exception
272     * when the depth of the screen is changed.
273     */

274     EventQueue.invokeLater(new Runnable JavaDoc () {
275         public void run () {
276             try {
277                 Class JavaDoc clazz = Class.forName("sun.awt.windows.WComponentPeer");
278                 Field JavaDoc field = clazz.getDeclaredField("winGraphicsConfig");
279                 field.setAccessible(true);
280                 field.set(frame.getPeer(), frame.getGraphicsConfiguration());
281             } catch (Throwable JavaDoc e) {}
282         }
283     });
284     return frame;
285 }
286
287 /**
288  * Creates a new <code>Shell</code>. This Shell is the root for
289  * the SWT widgets that will be embedded within the AWT canvas.
290  *
291  * @param display the display for the new Shell
292  * @param parent the parent <code>java.awt.Canvas</code> of the new Shell
293  * @return a <code>Shell</code> to be the parent of the embedded SWT widgets
294  *
295  * @exception IllegalArgumentException <ul>
296  * <li>ERROR_NULL_ARGUMENT - if the display is null</li>
297  * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
298  * <li>ERROR_INVALID_ARGUMENT - if the parent's peer is not created</li>
299  * </ul>
300  *
301  * @since 3.0
302  */

303 public static Shell new_Shell (final Display display, final Canvas JavaDoc parent) {
304     if (display == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
305     if (parent == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
306     int handle = 0;
307     try {
308         loadLibrary ();
309         handle = getAWTHandle (parent);
310     } catch (Throwable JavaDoc e) {
311         SWT.error (SWT.ERROR_NOT_IMPLEMENTED, e);
312     }
313     if (handle == 0) SWT.error (SWT.ERROR_INVALID_ARGUMENT, null, " [peer not created]");
314
315     final Shell shell = Shell.win32_new (display, handle);
316     parent.addComponentListener(new ComponentAdapter JavaDoc () {
317         public void componentResized (ComponentEvent JavaDoc e) {
318             display.syncExec (new Runnable JavaDoc () {
319                 public void run () {
320                     Dimension JavaDoc dim = parent.getSize ();
321                     shell.setSize (dim.width, dim.height);
322                 }
323             });
324         }
325     });
326     shell.setVisible (true);
327     return shell;
328 }
329 }
330
Popular Tags