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