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