blob: b9b5b2506b9115ef58712cfd623ffd14c8129134 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25package javax.swing;
26
27import java.awt.*;
28import java.awt.event.*;
29import java.applet.Applet;
30import java.beans.PropertyChangeListener;
31import java.util.Locale;
32import java.util.Vector;
33import java.io.Serializable;
34import javax.accessibility.*;
35
36/**
37 * An extended version of <code>java.applet.Applet</code> that adds support for
38 * the JFC/Swing component architecture.
39 * You can find task-oriented documentation about using <code>JApplet</code>
40 * in <em>The Java Tutorial</em>,
41 * in the section
42 * <a
43 href="http://java.sun.com/docs/books/tutorial/uiswing/components/applet.html">How to Make Applets</a>.
44 * <p>
45 * The <code>JApplet</code> class is slightly incompatible with
46 * <code>java.applet.Applet</code>. <code>JApplet</code> contains a
47 * <code>JRootPane</code> as its only child. The <code>contentPane</code>
48 * should be the parent of any children of the <code>JApplet</code>.
49 * As a convenience <code>add</code> and its variants, <code>remove</code> and
50 * <code>setLayout</code> have been overridden to forward to the
51 * <code>contentPane</code> as necessary. This means you can write:
52 * <pre>
53 * applet.add(child);
54 * </pre>
55 *
56 * And the child will be added to the <code>contentPane</code>.
57 * The <code>contentPane</code> will always be non-<code>null</code>.
58 * Attempting to set it to <code>null</code> will cause the
59 * <code>JApplet</code> to throw an exception. The default
60 * <code>contentPane</code> will have a <code>BorderLayout</code>
61 * manager set on it.
62 * Refer to {@link javax.swing.RootPaneContainer}
63 * for details on adding, removing and setting the <code>LayoutManager</code>
64 * of a <code>JApplet</code>.
65 * <p>
66 * Please see the <code>JRootPane</code> documentation for a
67 * complete description of the <code>contentPane</code>, <code>glassPane</code>,
68 * and <code>layeredPane</code> properties.
69 * <p>
70 * <strong>Warning:</strong> Swing is not thread safe. For more
71 * information see <a
72 * href="package-summary.html#threading">Swing's Threading
73 * Policy</a>.
74 * <p>
75 * <strong>Warning:</strong>
76 * Serialized objects of this class will not be compatible with
77 * future Swing releases. The current serialization support is
78 * appropriate for short term storage or RMI between applications running
79 * the same version of Swing. As of 1.4, support for long term storage
80 * of all JavaBeans<sup><font size="-2">TM</font></sup>
81 * has been added to the <code>java.beans</code> package.
82 * Please see {@link java.beans.XMLEncoder}.
83 *
84 * @see javax.swing.RootPaneContainer
85 * @beaninfo
86 * attribute: isContainer true
87 * attribute: containerDelegate getContentPane
88 * description: Swing's Applet subclass.
89 *
90 * @author Arnaud Weber
91 */
92public class JApplet extends Applet implements Accessible,
93 RootPaneContainer,
94 TransferHandler.HasGetTransferHandler
95{
96 /**
97 * @see #getRootPane
98 * @see #setRootPane
99 */
100 protected JRootPane rootPane;
101
102 /**
103 * If true then calls to <code>add</code> and <code>setLayout</code>
104 * will be forwarded to the <code>contentPane</code>. This is initially
105 * false, but is set to true when the <code>JApplet</code> is constructed.
106 *
107 * @see #isRootPaneCheckingEnabled
108 * @see #setRootPaneCheckingEnabled
109 * @see javax.swing.RootPaneContainer
110 */
111 protected boolean rootPaneCheckingEnabled = false;
112
113 /**
114 * The <code>TransferHandler</code> for this applet.
115 */
116 private TransferHandler transferHandler;
117
118 /**
119 * Creates a swing applet instance.
120 * <p>
121 * This constructor sets the component's locale property to the value
122 * returned by <code>JComponent.getDefaultLocale</code>.
123 *
124 * @exception HeadlessException if GraphicsEnvironment.isHeadless()
125 * returns true.
126 * @see java.awt.GraphicsEnvironment#isHeadless
127 * @see JComponent#getDefaultLocale
128 */
129 public JApplet() throws HeadlessException {
130 super();
131 // Check the timerQ and restart if necessary.
132 TimerQueue q = TimerQueue.sharedInstance();
133 if(q != null) {
134 synchronized(q) {
135 if(!q.running)
136 q.start();
137 }
138 }
139
140 /* Workaround for bug 4155072. The shared double buffer image
141 * may hang on to a reference to this applet; unfortunately
142 * Image.getGraphics() will continue to call JApplet.getForeground()
143 * and getBackground() even after this applet has been destroyed.
144 * So we ensure that these properties are non-null here.
145 */
146 setForeground(Color.black);
147 setBackground(Color.white);
148
149 setLocale( JComponent.getDefaultLocale() );
150 setLayout(new BorderLayout());
151 setRootPane(createRootPane());
152 setRootPaneCheckingEnabled(true);
153
154 setFocusTraversalPolicyProvider(true);
155 sun.awt.SunToolkit.checkAndSetPolicy(this, true);
156
157 enableEvents(AWTEvent.KEY_EVENT_MASK);
158 }
159
160
161 /** Called by the constructor methods to create the default rootPane. */
162 protected JRootPane createRootPane() {
163 JRootPane rp = new JRootPane();
164 // NOTE: this uses setOpaque vs LookAndFeel.installProperty as there
165 // is NO reason for the RootPane not to be opaque. For painting to
166 // work the contentPane must be opaque, therefor the RootPane can
167 // also be opaque.
168 rp.setOpaque(true);
169 return rp;
170 }
171
172 /**
173 * Sets the {@code transferHandler} property, which is a mechanism to
174 * support transfer of data into this component. Use {@code null}
175 * if the component does not support data transfer operations.
176 * <p>
177 * If the system property {@code suppressSwingDropSupport} is {@code false}
178 * (the default) and the current drop target on this component is either
179 * {@code null} or not a user-set drop target, this method will change the
180 * drop target as follows: If {@code newHandler} is {@code null} it will
181 * clear the drop target. If not {@code null} it will install a new
182 * {@code DropTarget}.
183 * <p>
184 * Note: When used with {@code JApplet}, {@code TransferHandler} only
185 * provides data import capability, as the data export related methods
186 * are currently typed to {@code JComponent}.
187 * <p>
188 * Please see
189 * <a href="http://java.sun.com/docs/books/tutorial/uiswing/misc/dnd.html">
190 * How to Use Drag and Drop and Data Transfer</a>, a section in
191 * <em>The Java Tutorial</em>, for more information.
192 *
193 * @param newHandler the new {@code TransferHandler}
194 *
195 * @see TransferHandler
196 * @see #getTransferHandler
197 * @see java.awt.Component#setDropTarget
198 * @since 1.6
199 *
200 * @beaninfo
201 * bound: true
202 * hidden: true
203 * description: Mechanism for transfer of data into the component
204 */
205 public void setTransferHandler(TransferHandler newHandler) {
206 TransferHandler oldHandler = transferHandler;
207 transferHandler = newHandler;
208 SwingUtilities.installSwingDropTargetAsNecessary(this, transferHandler);
209 firePropertyChange("transferHandler", oldHandler, newHandler);
210 }
211
212 /**
213 * Gets the <code>transferHandler</code> property.
214 *
215 * @return the value of the <code>transferHandler</code> property
216 *
217 * @see TransferHandler
218 * @see #setTransferHandler
219 * @since 1.6
220 */
221 public TransferHandler getTransferHandler() {
222 return transferHandler;
223 }
224
225 /**
226 * Just calls <code>paint(g)</code>. This method was overridden to
227 * prevent an unnecessary call to clear the background.
228 */
229 public void update(Graphics g) {
230 paint(g);
231 }
232
233 /**
234 * Sets the menubar for this applet.
235 * @param menuBar the menubar being placed in the applet
236 *
237 * @see #getJMenuBar
238 *
239 * @beaninfo
240 * hidden: true
241 * description: The menubar for accessing pulldown menus from this applet.
242 */
243 public void setJMenuBar(JMenuBar menuBar) {
244 getRootPane().setMenuBar(menuBar);
245 }
246
247 /**
248 * Returns the menubar set on this applet.
249 *
250 * @see #setJMenuBar
251 */
252 public JMenuBar getJMenuBar() {
253 return getRootPane().getMenuBar();
254 }
255
256
257 /**
258 * Returns whether calls to <code>add</code> and
259 * <code>setLayout</code> are forwarded to the <code>contentPane</code>.
260 *
261 * @return true if <code>add</code> and <code>setLayout</code>
262 * are fowarded; false otherwise
263 *
264 * @see #addImpl
265 * @see #setLayout
266 * @see #setRootPaneCheckingEnabled
267 * @see javax.swing.RootPaneContainer
268 */
269 protected boolean isRootPaneCheckingEnabled() {
270 return rootPaneCheckingEnabled;
271 }
272
273
274 /**
275 * Sets whether calls to <code>add</code> and
276 * <code>setLayout</code> are forwarded to the <code>contentPane</code>.
277 *
278 * @param enabled true if <code>add</code> and <code>setLayout</code>
279 * are forwarded, false if they should operate directly on the
280 * <code>JApplet</code>.
281 *
282 * @see #addImpl
283 * @see #setLayout
284 * @see #isRootPaneCheckingEnabled
285 * @see javax.swing.RootPaneContainer
286 * @beaninfo
287 * hidden: true
288 * description: Whether the add and setLayout methods are forwarded
289 */
290 protected void setRootPaneCheckingEnabled(boolean enabled) {
291 rootPaneCheckingEnabled = enabled;
292 }
293
294
295 /**
296 * Adds the specified child <code>Component</code>.
297 * This method is overridden to conditionally forward calls to the
298 * <code>contentPane</code>.
299 * By default, children are added to the <code>contentPane</code> instead
300 * of the frame, refer to {@link javax.swing.RootPaneContainer} for
301 * details.
302 *
303 * @param comp the component to be enhanced
304 * @param constraints the constraints to be respected
305 * @param index the index
306 * @exception IllegalArgumentException if <code>index</code> is invalid
307 * @exception IllegalArgumentException if adding the container's parent
308 * to itself
309 * @exception IllegalArgumentException if adding a window to a container
310 *
311 * @see #setRootPaneCheckingEnabled
312 * @see javax.swing.RootPaneContainer
313 */
314 protected void addImpl(Component comp, Object constraints, int index)
315 {
316 if(isRootPaneCheckingEnabled()) {
317 getContentPane().add(comp, constraints, index);
318 }
319 else {
320 super.addImpl(comp, constraints, index);
321 }
322 }
323
324 /**
325 * Removes the specified component from the container. If
326 * <code>comp</code> is not the <code>rootPane</code>, this will forward
327 * the call to the <code>contentPane</code>. This will do nothing if
328 * <code>comp</code> is not a child of the <code>JFrame</code> or
329 * <code>contentPane</code>.
330 *
331 * @param comp the component to be removed
332 * @throws NullPointerException if <code>comp</code> is null
333 * @see #add
334 * @see javax.swing.RootPaneContainer
335 */
336 public void remove(Component comp) {
337 if (comp == rootPane) {
338 super.remove(comp);
339 } else {
340 getContentPane().remove(comp);
341 }
342 }
343
344
345 /**
346 * Sets the <code>LayoutManager</code>.
347 * Overridden to conditionally forward the call to the
348 * <code>contentPane</code>.
349 * Refer to {@link javax.swing.RootPaneContainer} for
350 * more information.
351 *
352 * @param manager the <code>LayoutManager</code>
353 * @see #setRootPaneCheckingEnabled
354 * @see javax.swing.RootPaneContainer
355 */
356 public void setLayout(LayoutManager manager) {
357 if(isRootPaneCheckingEnabled()) {
358 getContentPane().setLayout(manager);
359 }
360 else {
361 super.setLayout(manager);
362 }
363 }
364
365
366 /**
367 * Returns the rootPane object for this applet.
368 *
369 * @see #setRootPane
370 * @see RootPaneContainer#getRootPane
371 */
372 public JRootPane getRootPane() {
373 return rootPane;
374 }
375
376
377 /**
378 * Sets the rootPane property. This method is called by the constructor.
379 * @param root the rootPane object for this applet
380 *
381 * @see #getRootPane
382 *
383 * @beaninfo
384 * hidden: true
385 * description: the RootPane object for this applet.
386 */
387 protected void setRootPane(JRootPane root) {
388 if(rootPane != null) {
389 remove(rootPane);
390 }
391 rootPane = root;
392 if(rootPane != null) {
393 boolean checkingEnabled = isRootPaneCheckingEnabled();
394 try {
395 setRootPaneCheckingEnabled(false);
396 add(rootPane, BorderLayout.CENTER);
397 }
398 finally {
399 setRootPaneCheckingEnabled(checkingEnabled);
400 }
401 }
402 }
403
404
405 /**
406 * Returns the contentPane object for this applet.
407 *
408 * @see #setContentPane
409 * @see RootPaneContainer#getContentPane
410 */
411 public Container getContentPane() {
412 return getRootPane().getContentPane();
413 }
414
415 /**
416 * Sets the contentPane property. This method is called by the constructor.
417 * @param contentPane the contentPane object for this applet
418 *
419 * @exception java.awt.IllegalComponentStateException (a runtime
420 * exception) if the content pane parameter is null
421 * @see #getContentPane
422 * @see RootPaneContainer#setContentPane
423 *
424 * @beaninfo
425 * hidden: true
426 * description: The client area of the applet where child
427 * components are normally inserted.
428 */
429 public void setContentPane(Container contentPane) {
430 getRootPane().setContentPane(contentPane);
431 }
432
433 /**
434 * Returns the layeredPane object for this applet.
435 *
436 * @exception java.awt.IllegalComponentStateException (a runtime
437 * exception) if the layered pane parameter is null
438 * @see #setLayeredPane
439 * @see RootPaneContainer#getLayeredPane
440 */
441 public JLayeredPane getLayeredPane() {
442 return getRootPane().getLayeredPane();
443 }
444
445 /**
446 * Sets the layeredPane property. This method is called by the constructor.
447 * @param layeredPane the layeredPane object for this applet
448 *
449 * @see #getLayeredPane
450 * @see RootPaneContainer#setLayeredPane
451 *
452 * @beaninfo
453 * hidden: true
454 * description: The pane which holds the various applet layers.
455 */
456 public void setLayeredPane(JLayeredPane layeredPane) {
457 getRootPane().setLayeredPane(layeredPane);
458 }
459
460 /**
461 * Returns the glassPane object for this applet.
462 *
463 * @see #setGlassPane
464 * @see RootPaneContainer#getGlassPane
465 */
466 public Component getGlassPane() {
467 return getRootPane().getGlassPane();
468 }
469
470 /**
471 * Sets the glassPane property.
472 * This method is called by the constructor.
473 * @param glassPane the glassPane object for this applet
474 *
475 * @see #getGlassPane
476 * @see RootPaneContainer#setGlassPane
477 *
478 * @beaninfo
479 * hidden: true
480 * description: A transparent pane used for menu rendering.
481 */
482 public void setGlassPane(Component glassPane) {
483 getRootPane().setGlassPane(glassPane);
484 }
485
486 /**
487 * {@inheritDoc}
488 *
489 * @since 1.6
490 */
491 public Graphics getGraphics() {
492 JComponent.getGraphicsInvoked(this);
493 return super.getGraphics();
494 }
495
496 /**
497 * Repaints the specified rectangle of this component within
498 * <code>time</code> milliseconds. Refer to <code>RepaintManager</code>
499 * for details on how the repaint is handled.
500 *
501 * @param time maximum time in milliseconds before update
502 * @param x the <i>x</i> coordinate
503 * @param y the <i>y</i> coordinate
504 * @param width the width
505 * @param height the height
506 * @see RepaintManager
507 * @since 1.6
508 */
509 public void repaint(long time, int x, int y, int width, int height) {
510 if (RepaintManager.HANDLE_TOP_LEVEL_PAINT) {
511 RepaintManager.currentManager(this).addDirtyRegion(
512 this, x, y, width, height);
513 }
514 else {
515 super.repaint(time, x, y, width, height);
516 }
517 }
518
519 /**
520 * Returns a string representation of this JApplet. This method
521 * is intended to be used only for debugging purposes, and the
522 * content and format of the returned string may vary between
523 * implementations. The returned string may be empty but may not
524 * be <code>null</code>.
525 *
526 * @return a string representation of this JApplet.
527 */
528 protected String paramString() {
529 String rootPaneString = (rootPane != null ?
530 rootPane.toString() : "");
531 String rootPaneCheckingEnabledString = (rootPaneCheckingEnabled ?
532 "true" : "false");
533
534 return super.paramString() +
535 ",rootPane=" + rootPaneString +
536 ",rootPaneCheckingEnabled=" + rootPaneCheckingEnabledString;
537 }
538
539
540
541/////////////////
542// Accessibility support
543////////////////
544
545 protected AccessibleContext accessibleContext = null;
546
547 /**
548 * Gets the AccessibleContext associated with this JApplet.
549 * For JApplets, the AccessibleContext takes the form of an
550 * AccessibleJApplet.
551 * A new AccessibleJApplet instance is created if necessary.
552 *
553 * @return an AccessibleJApplet that serves as the
554 * AccessibleContext of this JApplet
555 */
556 public AccessibleContext getAccessibleContext() {
557 if (accessibleContext == null) {
558 accessibleContext = new AccessibleJApplet();
559 }
560 return accessibleContext;
561 }
562
563 /**
564 * This class implements accessibility support for the
565 * <code>JApplet</code> class.
566 */
567 protected class AccessibleJApplet extends AccessibleApplet {
568 // everything moved to new parent, AccessibleApplet
569 }
570}