< prev index next >

src/java.desktop/share/classes/javax/swing/JInternalFrame.java

Print this page




  38 
  39 import java.io.ObjectOutputStream;
  40 import java.io.IOException;
  41 import java.beans.PropertyChangeListener;
  42 import sun.awt.AppContext;
  43 import sun.swing.SwingUtilities2;
  44 
  45 
  46 /**
  47  * A lightweight object that provides many of the features of
  48  * a native frame, including dragging, closing, becoming an icon,
  49  * resizing, title display, and support for a menu bar.
  50  * For task-oriented documentation and examples of using internal frames,
  51  * see <a
  52  href="http://docs.oracle.com/javase/tutorial/uiswing/components/internalframe.html" target="_top">How to Use Internal Frames</a>,
  53  * a section in <em>The Java Tutorial</em>.
  54  *
  55  * <p>
  56  *
  57  * Generally,
  58  * you add <code>JInternalFrame</code>s to a <code>JDesktopPane</code>. The UI
  59  * delegates the look-and-feel-specific actions to the
  60  * <code>DesktopManager</code>
  61  * object maintained by the <code>JDesktopPane</code>.
  62  * <p>
  63  * The <code>JInternalFrame</code> content pane
  64  * is where you add child components.
  65  * As a convenience, the {@code add}, {@code remove}, and {@code setLayout}
  66  * methods of this class are overridden, so that they delegate calls
  67  * to the corresponding methods of the {@code ContentPane}.
  68  * For example, you can add a child component to an internal frame as follows:
  69  * <pre>
  70  *       internalFrame.add(child);
  71  * </pre>
  72  * And the child will be added to the contentPane.
  73  * The content pane is actually managed by an instance of
  74  * <code>JRootPane</code>,
  75  * which also manages a layout pane, glass pane, and
  76  * optional menu bar for the internal frame. Please see the
  77  * <code>JRootPane</code>
  78  * documentation for a complete description of these components.
  79  * Refer to {@link javax.swing.RootPaneContainer}
  80  * for details on adding, removing and setting the <code>LayoutManager</code>
  81  * of a <code>JInternalFrame</code>.
  82  * <p>
  83  * <strong>Warning:</strong> Swing is not thread safe. For more
  84  * information see <a
  85  * href="package-summary.html#threading">Swing's Threading
  86  * Policy</a>.
  87  * <p>
  88  * <strong>Warning:</strong>
  89  * Serialized objects of this class will not be compatible with
  90  * future Swing releases. The current serialization support is
  91  * appropriate for short term storage or RMI between applications running
  92  * the same version of Swing.  As of 1.4, support for long term storage
  93  * of all JavaBeans&trade;
  94  * has been added to the <code>java.beans</code> package.
  95  * Please see {@link java.beans.XMLEncoder}.
  96  *
  97  * @see InternalFrameEvent
  98  * @see JDesktopPane
  99  * @see DesktopManager
 100  * @see JInternalFrame.JDesktopIcon
 101  * @see JRootPane
 102  * @see javax.swing.RootPaneContainer
 103  *
 104  * @author David Kloba
 105  * @author Rich Schiavi
 106  * @since 1.2
 107  * @beaninfo
 108  *      attribute: isContainer true
 109  *      attribute: containerDelegate getContentPane
 110  *      description: A frame container which is contained within
 111  *                   another window.
 112  */
 113 @SuppressWarnings("serial") // Same-version serialization only
 114 public class JInternalFrame extends JComponent implements
 115         Accessible, WindowConstants,
 116         RootPaneContainer
 117 {
 118     /**
 119      * @see #getUIClassID
 120      * @see #readObject
 121      */
 122     private static final String uiClassID = "InternalFrameUI";
 123 
 124     /**
 125      * The <code>JRootPane</code> instance that manages the
 126      * content pane
 127      * and optional menu bar for this internal frame, as well as the
 128      * glass pane.
 129      *
 130      * @see JRootPane
 131      * @see RootPaneContainer
 132      */
 133     protected JRootPane rootPane;
 134 
 135     /**
 136      * If true then calls to <code>add</code> and <code>setLayout</code>
 137      * will be forwarded to the <code>contentPane</code>. This is initially
 138      * false, but is set to true when the <code>JInternalFrame</code> is
 139      * constructed.
 140      *
 141      * @see #isRootPaneCheckingEnabled
 142      * @see #setRootPaneCheckingEnabled
 143      * @see javax.swing.RootPaneContainer
 144      */
 145     protected boolean rootPaneCheckingEnabled = false;
 146 
 147     /** The frame can be closed. */
 148     protected boolean closable;
 149     /** The frame has been closed. */
 150     protected boolean isClosed;
 151     /** The frame can be expanded to the size of the desktop pane. */
 152     protected boolean maximizable;
 153     /**
 154      * The frame has been expanded to its maximum size.
 155      * @see #maximizable
 156      */
 157     protected boolean isMaximum;
 158     /**


 174     /** The icon shown in the top-left corner of this internal frame. */
 175     protected Icon frameIcon;
 176     /** The title displayed in this internal frame's title bar. */
 177     protected String  title;
 178     /**
 179      * The icon that is displayed when this internal frame is iconified.
 180      * @see #iconable
 181      */
 182     protected JDesktopIcon desktopIcon;
 183 
 184     private Cursor lastCursor;
 185 
 186     private boolean opened;
 187 
 188     private Rectangle normalBounds = null;
 189 
 190     private int defaultCloseOperation = DISPOSE_ON_CLOSE;
 191 
 192     /**
 193      * Contains the Component that focus is to go when
 194      * <code>restoreSubcomponentFocus</code> is invoked, that is,
 195      * <code>restoreSubcomponentFocus</code> sets this to the value returned
 196      * from <code>getMostRecentFocusOwner</code>.
 197      */
 198     private Component lastFocusOwner;
 199 
 200     /** Bound property name. */
 201     public static final String CONTENT_PANE_PROPERTY = "contentPane";
 202     /** Bound property name. */
 203     public static final String MENU_BAR_PROPERTY = "JMenuBar";
 204     /** Bound property name. */
 205     public static final String TITLE_PROPERTY = "title";
 206     /** Bound property name. */
 207     public static final String LAYERED_PANE_PROPERTY = "layeredPane";
 208     /** Bound property name. */
 209     public static final String ROOT_PANE_PROPERTY = "rootPane";
 210     /** Bound property name. */
 211     public static final String GLASS_PANE_PROPERTY = "glassPane";
 212     /** Bound property name. */
 213     public static final String FRAME_ICON_PROPERTY = "frameIcon";
 214 
 215     /**
 216      * Constrained property name indicated that this frame has


 248                 updateLastFocusOwner((Component)e.getNewValue());
 249             }
 250         }
 251     }
 252 
 253     private static void updateLastFocusOwner(Component component) {
 254         if (component != null) {
 255             Component parent = component;
 256             while (parent != null && !(parent instanceof Window)) {
 257                 if (parent instanceof JInternalFrame) {
 258                     // Update lastFocusOwner for parent.
 259                     ((JInternalFrame)parent).setLastFocusOwner(component);
 260                 }
 261                 parent = parent.getParent();
 262             }
 263         }
 264     }
 265 
 266     /**
 267      * Creates a non-resizable, non-closable, non-maximizable,
 268      * non-iconifiable <code>JInternalFrame</code> with no title.
 269      */
 270     public JInternalFrame() {
 271         this("", false, false, false, false);
 272     }
 273 
 274     /**
 275      * Creates a non-resizable, non-closable, non-maximizable,
 276      * non-iconifiable <code>JInternalFrame</code> with the specified title.
 277      * Note that passing in a <code>null</code> <code>title</code> results in
 278      * unspecified behavior and possibly an exception.
 279      *
 280      * @param title  the non-<code>null</code> <code>String</code>
 281      *     to display in the title bar
 282      */
 283     public JInternalFrame(String title) {
 284         this(title, false, false, false, false);
 285     }
 286 
 287     /**
 288      * Creates a non-closable, non-maximizable, non-iconifiable
 289      * <code>JInternalFrame</code> with the specified title
 290      * and resizability.
 291      *
 292      * @param title      the <code>String</code> to display in the title bar
 293      * @param resizable  if <code>true</code>, the internal frame can be resized
 294      */
 295     public JInternalFrame(String title, boolean resizable) {
 296         this(title, resizable, false, false, false);
 297     }
 298 
 299     /**
 300      * Creates a non-maximizable, non-iconifiable <code>JInternalFrame</code>
 301      * with the specified title, resizability, and
 302      * closability.
 303      *
 304      * @param title      the <code>String</code> to display in the title bar
 305      * @param resizable  if <code>true</code>, the internal frame can be resized
 306      * @param closable   if <code>true</code>, the internal frame can be closed
 307      */
 308     public JInternalFrame(String title, boolean resizable, boolean closable) {
 309         this(title, resizable, closable, false, false);
 310     }
 311 
 312     /**
 313      * Creates a non-iconifiable <code>JInternalFrame</code>
 314      * with the specified title,
 315      * resizability, closability, and maximizability.
 316      *
 317      * @param title       the <code>String</code> to display in the title bar
 318      * @param resizable   if <code>true</code>, the internal frame can be resized
 319      * @param closable    if <code>true</code>, the internal frame can be closed
 320      * @param maximizable if <code>true</code>, the internal frame can be maximized
 321      */
 322     public JInternalFrame(String title, boolean resizable, boolean closable,
 323                           boolean maximizable) {
 324         this(title, resizable, closable, maximizable, false);
 325     }
 326 
 327     /**
 328      * Creates a <code>JInternalFrame</code> with the specified title,
 329      * resizability, closability, maximizability, and iconifiability.
 330      * All <code>JInternalFrame</code> constructors use this one.
 331      *
 332      * @param title       the <code>String</code> to display in the title bar
 333      * @param resizable   if <code>true</code>, the internal frame can be resized
 334      * @param closable    if <code>true</code>, the internal frame can be closed
 335      * @param maximizable if <code>true</code>, the internal frame can be maximized
 336      * @param iconifiable if <code>true</code>, the internal frame can be iconified
 337      */
 338     public JInternalFrame(String title, boolean resizable, boolean closable,
 339                                 boolean maximizable, boolean iconifiable) {
 340 
 341         setRootPane(createRootPane());
 342         setLayout(new BorderLayout());
 343         this.title = title;
 344         this.resizable = resizable;
 345         this.closable = closable;
 346         this.maximizable = maximizable;
 347         isMaximum = false;
 348         this.iconable = iconifiable;
 349         isIcon = false;
 350         setVisible(false);
 351         setRootPaneCheckingEnabled(true);
 352         desktopIcon = new JDesktopIcon(this);
 353         updateUI();
 354         sun.awt.SunToolkit.checkAndSetPolicy(this);
 355         addPropertyChangeListenerIfNecessary();
 356     }
 357 
 358     /**
 359      * Called by the constructor to set up the <code>JRootPane</code>.
 360      * @return  a new <code>JRootPane</code>
 361      * @see JRootPane
 362      */
 363     protected JRootPane createRootPane() {
 364         return new JRootPane();
 365     }
 366 
 367     /**
 368      * Returns the look-and-feel object that renders this component.
 369      *
 370      * @return the <code>InternalFrameUI</code> object that renders
 371      *          this component
 372      */
 373     public InternalFrameUI getUI() {
 374         return (InternalFrameUI)ui;
 375     }
 376 
 377     /**
 378      * Sets the UI delegate for this <code>JInternalFrame</code>.
 379      * @param ui  the UI delegate
 380      * @beaninfo
 381      *        bound: true
 382      *       hidden: true
 383      *    attribute: visualUpdate true
 384      *  description: The UI object that implements the Component's LookAndFeel.
 385      */
 386     public void setUI(InternalFrameUI ui) {
 387         boolean checkingEnabled = isRootPaneCheckingEnabled();
 388         try {
 389             setRootPaneCheckingEnabled(false);
 390             super.setUI(ui);
 391         }
 392         finally {
 393             setRootPaneCheckingEnabled(checkingEnabled);
 394         }
 395     }
 396 
 397     /**
 398      * Notification from the <code>UIManager</code> that the look and feel
 399      * has changed.
 400      * Replaces the current UI object with the latest version from the
 401      * <code>UIManager</code>.
 402      *
 403      * @see JComponent#updateUI
 404      */
 405     public void updateUI() {
 406         setUI((InternalFrameUI)UIManager.getUI(this));
 407         invalidate();
 408         if (desktopIcon != null) {
 409             desktopIcon.updateUIWhenHidden();
 410         }
 411     }
 412 
 413     /* This method is called if <code>updateUI</code> was called
 414      * on the associated
 415      * JDesktopIcon.  It's necessary to avoid infinite recursion.
 416      */
 417     void updateUIWhenHidden() {
 418         setUI((InternalFrameUI)UIManager.getUI(this));
 419         invalidate();
 420         Component[] children = getComponents();
 421         if (children != null) {
 422             for (Component child : children) {
 423                 SwingUtilities.updateComponentTreeUI(child);
 424             }
 425         }
 426     }
 427 
 428 
 429     /**
 430      * Returns the name of the look-and-feel
 431      * class that renders this component.
 432      *
 433      * @return the string "InternalFrameUI"
 434      *
 435      * @see JComponent#getUIClassID
 436      * @see UIDefaults#getUI
 437      *
 438      * @beaninfo
 439      *     description: UIClassID
 440      */
 441     public String getUIClassID() {
 442         return uiClassID;
 443     }
 444 
 445     /**
 446      * Returns whether calls to <code>add</code> and
 447      * <code>setLayout</code> are forwarded to the <code>contentPane</code>.
 448      *
 449      * @return true if <code>add</code> and <code>setLayout</code>
 450      *         are forwarded; false otherwise
 451      *
 452      * @see #addImpl
 453      * @see #setLayout
 454      * @see #setRootPaneCheckingEnabled
 455      * @see javax.swing.RootPaneContainer
 456      */
 457     protected boolean isRootPaneCheckingEnabled() {
 458         return rootPaneCheckingEnabled;
 459     }
 460 
 461     /**
 462      * Sets whether calls to <code>add</code> and
 463      * <code>setLayout</code> are forwarded to the <code>contentPane</code>.
 464      *
 465      * @param enabled  true if <code>add</code> and <code>setLayout</code>
 466      *        are forwarded, false if they should operate directly on the
 467      *        <code>JInternalFrame</code>.
 468      *
 469      * @see #addImpl
 470      * @see #setLayout
 471      * @see #isRootPaneCheckingEnabled
 472      * @see javax.swing.RootPaneContainer
 473      * @beaninfo
 474      *      hidden: true
 475      * description: Whether the add and setLayout methods are forwarded
 476      */
 477     protected void setRootPaneCheckingEnabled(boolean enabled) {
 478         rootPaneCheckingEnabled = enabled;
 479     }
 480 
 481     /**
 482      * Adds the specified child <code>Component</code>.
 483      * This method is overridden to conditionally forward calls to the
 484      * <code>contentPane</code>.
 485      * By default, children are added to the <code>contentPane</code> instead
 486      * of the frame, refer to {@link javax.swing.RootPaneContainer} for
 487      * details.
 488      *
 489      * @param comp the component to be enhanced
 490      * @param constraints the constraints to be respected
 491      * @param index the index
 492      * @exception IllegalArgumentException if <code>index</code> is invalid
 493      * @exception IllegalArgumentException if adding the container's parent
 494      *                  to itself
 495      * @exception IllegalArgumentException if adding a window to a container
 496      *
 497      * @see #setRootPaneCheckingEnabled
 498      * @see javax.swing.RootPaneContainer
 499      */
 500     protected void addImpl(Component comp, Object constraints, int index) {
 501         if(isRootPaneCheckingEnabled()) {
 502             getContentPane().add(comp, constraints, index);
 503         }
 504         else {
 505             super.addImpl(comp, constraints, index);
 506         }
 507     }
 508 
 509     /**
 510      * Removes the specified component from the container. If
 511      * <code>comp</code> is not a child of the <code>JInternalFrame</code>
 512      * this will forward the call to the <code>contentPane</code>.
 513      *
 514      * @param comp the component to be removed
 515      * @throws NullPointerException if <code>comp</code> is null
 516      * @see #add
 517      * @see javax.swing.RootPaneContainer
 518      */
 519     public void remove(Component comp) {
 520         int oldCount = getComponentCount();
 521         super.remove(comp);
 522         if (oldCount == getComponentCount()) {
 523             getContentPane().remove(comp);
 524         }
 525     }
 526 
 527 
 528     /**
 529      * Ensures that, by default, the layout of this component cannot be set.
 530      * Overridden to conditionally forward the call to the
 531      * <code>contentPane</code>.
 532      * Refer to {@link javax.swing.RootPaneContainer} for
 533      * more information.
 534      *
 535      * @param manager the <code>LayoutManager</code>
 536      * @see #setRootPaneCheckingEnabled
 537      */
 538     public void setLayout(LayoutManager manager) {
 539         if(isRootPaneCheckingEnabled()) {
 540             getContentPane().setLayout(manager);
 541         }
 542         else {
 543             super.setLayout(manager);
 544         }
 545     }
 546 
 547 
 548 //////////////////////////////////////////////////////////////////////////
 549 /// Property Methods
 550 //////////////////////////////////////////////////////////////////////////
 551 
 552     /**
 553      * Returns the current <code>JMenuBar</code> for this
 554      * <code>JInternalFrame</code>, or <code>null</code>
 555      * if no menu bar has been set.
 556      * @return the current menu bar, or <code>null</code> if none has been set
 557      *
 558      * @deprecated As of Swing version 1.0.3,
 559      * replaced by <code>getJMenuBar()</code>.
 560      */
 561     @Deprecated
 562     public JMenuBar getMenuBar() {
 563       return getRootPane().getMenuBar();
 564     }
 565 
 566     /**
 567      * Returns the current <code>JMenuBar</code> for this
 568      * <code>JInternalFrame</code>, or <code>null</code>
 569      * if no menu bar has been set.
 570      *
 571      * @return  the <code>JMenuBar</code> used by this internal frame
 572      * @see #setJMenuBar
 573      */
 574     public JMenuBar getJMenuBar() {
 575         return getRootPane().getJMenuBar();
 576     }
 577 
 578     /**
 579      * Sets the <code>menuBar</code> property for this <code>JInternalFrame</code>.
 580      *
 581      * @param m  the <code>JMenuBar</code> to use in this internal frame
 582      * @see #getJMenuBar
 583      * @deprecated As of Swing version 1.0.3
 584      *  replaced by <code>setJMenuBar(JMenuBar m)</code>.
 585      */
 586     @Deprecated
 587     public void setMenuBar(JMenuBar m) {
 588         JMenuBar oldValue = getMenuBar();
 589         getRootPane().setJMenuBar(m);
 590         firePropertyChange(MENU_BAR_PROPERTY, oldValue, m);
 591     }
 592 
 593     /**
 594      * Sets the <code>menuBar</code> property for this <code>JInternalFrame</code>.
 595      *
 596      * @param m  the <code>JMenuBar</code> to use in this internal frame
 597      * @see #getJMenuBar
 598      * @beaninfo
 599      *     bound: true
 600      *     preferred: true
 601      *     description: The menu bar for accessing pulldown menus
 602      *                  from this internal frame.
 603      */
 604     public void setJMenuBar(JMenuBar m){
 605         JMenuBar oldValue = getMenuBar();
 606         getRootPane().setJMenuBar(m);
 607         firePropertyChange(MENU_BAR_PROPERTY, oldValue, m);
 608     }
 609 
 610     // implements javax.swing.RootPaneContainer
 611     /**
 612      * Returns the content pane for this internal frame.
 613      * @return the content pane
 614      */
 615     public Container getContentPane() {
 616         return getRootPane().getContentPane();
 617     }
 618 
 619 
 620     /**
 621      * Sets this <code>JInternalFrame</code>'s <code>contentPane</code>
 622      * property.
 623      *
 624      * @param c  the content pane for this internal frame
 625      *
 626      * @exception java.awt.IllegalComponentStateException (a runtime
 627      *           exception) if the content pane parameter is <code>null</code>
 628      * @see RootPaneContainer#getContentPane
 629      * @beaninfo
 630      *     bound: true
 631      *     hidden: true
 632      *     description: The client area of the internal frame where child
 633      *                  components are normally inserted.
 634      */
 635     public void setContentPane(Container c) {
 636         Container oldValue = getContentPane();
 637         getRootPane().setContentPane(c);
 638         firePropertyChange(CONTENT_PANE_PROPERTY, oldValue, c);
 639     }
 640 
 641     /**
 642      * Returns the layered pane for this internal frame.
 643      *
 644      * @return a <code>JLayeredPane</code> object
 645      * @see RootPaneContainer#setLayeredPane
 646      * @see RootPaneContainer#getLayeredPane
 647      */
 648     public JLayeredPane getLayeredPane() {
 649         return getRootPane().getLayeredPane();
 650     }
 651 
 652     /**
 653      * Sets this <code>JInternalFrame</code>'s
 654      * <code>layeredPane</code> property.
 655      *
 656      * @param layered the <code>JLayeredPane</code> for this internal frame
 657      *
 658      * @exception java.awt.IllegalComponentStateException (a runtime
 659      *           exception) if the layered pane parameter is <code>null</code>
 660      * @see RootPaneContainer#setLayeredPane
 661      * @beaninfo
 662      *     hidden: true
 663      *     bound: true
 664      *     description: The pane which holds the various desktop layers.
 665      */
 666     public void setLayeredPane(JLayeredPane layered) {
 667         JLayeredPane oldValue = getLayeredPane();
 668         getRootPane().setLayeredPane(layered);
 669         firePropertyChange(LAYERED_PANE_PROPERTY, oldValue, layered);
 670     }
 671 
 672     /**
 673      * Returns the glass pane for this internal frame.
 674      *
 675      * @return the glass pane
 676      * @see RootPaneContainer#setGlassPane
 677      */
 678     public Component getGlassPane() {
 679         return getRootPane().getGlassPane();
 680     }
 681 
 682     /**
 683      * Sets this <code>JInternalFrame</code>'s
 684      * <code>glassPane</code> property.
 685      *
 686      * @param glass the glass pane for this internal frame
 687      * @see RootPaneContainer#getGlassPane
 688      * @beaninfo
 689      *     bound: true
 690      *     hidden: true
 691      *     description: A transparent pane used for menu rendering.
 692      */
 693     public void setGlassPane(Component glass) {
 694         Component oldValue = getGlassPane();
 695         getRootPane().setGlassPane(glass);
 696         firePropertyChange(GLASS_PANE_PROPERTY, oldValue, glass);
 697     }
 698 
 699     /**
 700      * Returns the <code>rootPane</code> object for this internal frame.
 701      *
 702      * @return the <code>rootPane</code> property
 703      * @see RootPaneContainer#getRootPane
 704      */
 705     public JRootPane getRootPane() {
 706         return rootPane;
 707     }
 708 
 709 
 710     /**
 711      * Sets the <code>rootPane</code> property
 712      * for this <code>JInternalFrame</code>.
 713      * This method is called by the constructor.
 714      *
 715      * @param root  the new <code>JRootPane</code> object
 716      * @beaninfo
 717      *     bound: true
 718      *     hidden: true
 719      *     description: The root pane used by this internal frame.
 720      */
 721     protected void setRootPane(JRootPane root) {
 722         if(rootPane != null) {
 723             remove(rootPane);
 724         }
 725         JRootPane oldValue = getRootPane();
 726         rootPane = root;
 727         if(rootPane != null) {
 728             boolean checkingEnabled = isRootPaneCheckingEnabled();
 729             try {
 730                 setRootPaneCheckingEnabled(false);
 731                 add(rootPane, BorderLayout.CENTER);
 732             }
 733             finally {
 734                 setRootPaneCheckingEnabled(checkingEnabled);
 735             }
 736         }
 737         firePropertyChange(ROOT_PANE_PROPERTY, oldValue, root);
 738     }
 739 
 740     /**
 741      * Sets whether this <code>JInternalFrame</code> can be closed by
 742      * some user action.
 743      * @param b a boolean value, where <code>true</code> means this internal frame can be closed
 744      * @beaninfo
 745      *     preferred: true
 746      *           bound: true
 747      *     description: Indicates whether this internal frame can be closed.
 748      */
 749     public void setClosable(boolean b) {
 750         Boolean oldValue = closable ? Boolean.TRUE : Boolean.FALSE;
 751         Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
 752         closable = b;
 753         firePropertyChange("closable", oldValue, newValue);
 754     }
 755 
 756     /**
 757      * Returns whether this <code>JInternalFrame</code> can be closed by
 758      * some user action.
 759      * @return <code>true</code> if this internal frame can be closed
 760      */
 761     public boolean isClosable() {
 762         return closable;
 763     }
 764 
 765     /**
 766      * Returns whether this <code>JInternalFrame</code> is currently closed.
 767      * @return <code>true</code> if this internal frame is closed, <code>false</code> otherwise
 768      */
 769     public boolean isClosed() {
 770         return isClosed;
 771     }
 772 
 773     /**
 774      * Closes this internal frame if the argument is <code>true</code>.
 775      * Do not invoke this method with a <code>false</code> argument;
 776      * the result of invoking <code>setClosed(false)</code>
 777      * is unspecified.
 778      *
 779      * <p>
 780      *
 781      * If the internal frame is already closed,
 782      * this method does nothing and returns immediately.
 783      * Otherwise,
 784      * this method begins by firing
 785      * an <code>INTERNAL_FRAME_CLOSING</code> event.
 786      * Then this method sets the <code>closed</code> property to <code>true</code>
 787      * unless a listener vetoes the property change.
 788      * This method finishes by making the internal frame
 789      * invisible and unselected,
 790      * and then firing an <code>INTERNAL_FRAME_CLOSED</code> event.
 791      *
 792      * <p>
 793      *
 794      * <b>Note:</b>
 795      * To reuse an internal frame that has been closed,
 796      * you must add it to a container
 797      * (even if you never removed it from its previous container).
 798      * Typically, this container will be the <code>JDesktopPane</code>
 799      * that previously contained the internal frame.
 800      *
 801      * @param b must be <code>true</code>
 802      *
 803      * @exception PropertyVetoException when the attempt to set the
 804      *            property is vetoed by the <code>JInternalFrame</code>
 805      *
 806      * @see #isClosed()
 807      * @see #setDefaultCloseOperation
 808      * @see #dispose
 809      * @see javax.swing.event.InternalFrameEvent#INTERNAL_FRAME_CLOSING
 810      *
 811      * @beaninfo
 812      *           bound: true
 813      *     constrained: true
 814      *     description: Indicates whether this internal frame has been closed.
 815      */
 816     public void setClosed(boolean b) throws PropertyVetoException {
 817         if (isClosed == b) {
 818             return;
 819         }
 820 
 821         Boolean oldValue = isClosed ? Boolean.TRUE : Boolean.FALSE;
 822         Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
 823         if (b) {
 824           fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_CLOSING);
 825         }
 826         fireVetoableChange(IS_CLOSED_PROPERTY, oldValue, newValue);
 827         isClosed = b;
 828         if (isClosed) {
 829           setVisible(false);
 830         }
 831         firePropertyChange(IS_CLOSED_PROPERTY, oldValue, newValue);
 832         if (isClosed) {
 833           dispose();
 834         } else if (!opened) {
 835           /* this bogus -- we haven't defined what
 836              setClosed(false) means. */
 837           //        fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_OPENED);
 838           //            opened = true;
 839         }
 840     }
 841 
 842     /**
 843      * Sets whether the <code>JInternalFrame</code> can be resized by some
 844      * user action.
 845      *
 846      * @param b  a boolean, where <code>true</code> means this internal frame can be resized
 847      * @beaninfo
 848      *     preferred: true
 849      *           bound: true
 850      *     description: Determines whether this internal frame can be resized
 851      *                  by the user.
 852      */
 853     public void setResizable(boolean b) {
 854         Boolean oldValue = resizable ? Boolean.TRUE : Boolean.FALSE;
 855         Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
 856         resizable = b;
 857         firePropertyChange("resizable", oldValue, newValue);
 858     }
 859 
 860     /**
 861      * Returns whether the <code>JInternalFrame</code> can be resized
 862      * by some user action.
 863      *
 864      * @return <code>true</code> if this internal frame can be resized, <code>false</code> otherwise
 865      */
 866     public boolean isResizable() {
 867         // don't allow resizing when maximized.
 868         return isMaximum ? false : resizable;
 869     }
 870 
 871     /**
 872      * Sets the <code>iconable</code> property,
 873      * which must be <code>true</code>
 874      * for the user to be able to
 875      * make the <code>JInternalFrame</code> an icon.
 876      * Some look and feels might not implement iconification;
 877      * they will ignore this property.
 878      *
 879      * @param b  a boolean, where <code>true</code> means this internal frame can be iconified
 880      * @beaninfo
 881      *     preferred: true
 882                bound: true
 883      *     description: Determines whether this internal frame can be iconified.
 884      */
 885     public void setIconifiable(boolean b) {
 886         Boolean oldValue = iconable ? Boolean.TRUE : Boolean.FALSE;
 887         Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
 888         iconable = b;
 889         firePropertyChange("iconable", oldValue, newValue);
 890     }
 891 
 892     /**
 893      * Gets the <code>iconable</code> property,
 894      * which by default is <code>false</code>.
 895      *
 896      * @return the value of the <code>iconable</code> property.
 897      *
 898      * @see #setIconifiable
 899      */
 900     public boolean isIconifiable() {
 901         return iconable;
 902     }
 903 
 904     /**
 905      * Returns whether the <code>JInternalFrame</code> is currently iconified.
 906      *
 907      * @return <code>true</code> if this internal frame is iconified
 908      */
 909     public boolean isIcon() {
 910         return isIcon;
 911     }
 912 
 913     /**
 914      * Iconifies or de-iconifies this internal frame,
 915      * if the look and feel supports iconification.
 916      * If the internal frame's state changes to iconified,
 917      * this method fires an <code>INTERNAL_FRAME_ICONIFIED</code> event.
 918      * If the state changes to de-iconified,
 919      * an <code>INTERNAL_FRAME_DEICONIFIED</code> event is fired.
 920      *
 921      * @param b a boolean, where <code>true</code> means to iconify this internal frame and
 922      *          <code>false</code> means to de-iconify it
 923      * @exception PropertyVetoException when the attempt to set the
 924      *            property is vetoed by the <code>JInternalFrame</code>
 925      *
 926      * @see InternalFrameEvent#INTERNAL_FRAME_ICONIFIED
 927      * @see InternalFrameEvent#INTERNAL_FRAME_DEICONIFIED
 928      *
 929      * @beaninfo
 930      *           bound: true
 931      *     constrained: true
 932      *     description: The image displayed when this internal frame is minimized.
 933      */
 934     public void setIcon(boolean b) throws PropertyVetoException {
 935         if (isIcon == b) {
 936             return;
 937         }
 938 
 939         /* If an internal frame is being iconified before it has a
 940            parent, (e.g., client wants it to start iconic), create the
 941            parent if possible so that we can place the icon in its
 942            proper place on the desktop. I am not sure the call to
 943            validate() is necessary, since we are not going to display
 944            this frame yet */
 945         firePropertyChange("ancestor", null, getParent());
 946 
 947         Boolean oldValue = isIcon ? Boolean.TRUE : Boolean.FALSE;
 948         Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
 949         fireVetoableChange(IS_ICON_PROPERTY, oldValue, newValue);
 950         isIcon = b;
 951         firePropertyChange(IS_ICON_PROPERTY, oldValue, newValue);
 952         if (b)
 953           fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_ICONIFIED);
 954         else
 955           fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_DEICONIFIED);
 956     }
 957 
 958     /**
 959      * Sets the <code>maximizable</code> property,
 960      * which determines whether the <code>JInternalFrame</code>
 961      * can be maximized by
 962      * some user action.
 963      * Some look and feels might not support maximizing internal frames;
 964      * they will ignore this property.
 965      *
 966      * @param b <code>true</code> to specify that this internal frame should be maximizable; <code>false</code> to specify that it should not be
 967      * @beaninfo
 968      *         bound: true
 969      *     preferred: true
 970      *     description: Determines whether this internal frame can be maximized.
 971      */
 972     public void setMaximizable(boolean b) {
 973         Boolean oldValue = maximizable ? Boolean.TRUE : Boolean.FALSE;
 974         Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
 975         maximizable = b;
 976         firePropertyChange("maximizable", oldValue, newValue);
 977     }
 978 
 979     /**
 980      * Gets the value of the <code>maximizable</code> property.
 981      *
 982      * @return the value of the <code>maximizable</code> property
 983      * @see #setMaximizable
 984      */
 985     public boolean isMaximizable() {
 986         return maximizable;
 987     }
 988 
 989     /**
 990      * Returns whether the <code>JInternalFrame</code> is currently maximized.
 991      *
 992      * @return <code>true</code> if this internal frame is maximized, <code>false</code> otherwise
 993      */
 994     public boolean isMaximum() {
 995         return isMaximum;
 996     }
 997 
 998     /**
 999      * Maximizes and restores this internal frame.  A maximized frame is resized to
1000      * fully fit the <code>JDesktopPane</code> area associated with the
1001      * <code>JInternalFrame</code>.
1002      * A restored frame's size is set to the <code>JInternalFrame</code>'s
1003      * actual size.
1004      *
1005      * @param b  a boolean, where <code>true</code> maximizes this internal frame and <code>false</code>
1006      *           restores it
1007      * @exception PropertyVetoException when the attempt to set the
1008      *            property is vetoed by the <code>JInternalFrame</code>
1009      * @beaninfo
1010      *     bound: true
1011      *     constrained: true
1012      *     description: Indicates whether this internal frame is maximized.
1013      */
1014     public void setMaximum(boolean b) throws PropertyVetoException {
1015         if (isMaximum == b) {
1016             return;
1017         }
1018 
1019         Boolean oldValue = isMaximum ? Boolean.TRUE : Boolean.FALSE;
1020         Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
1021         fireVetoableChange(IS_MAXIMUM_PROPERTY, oldValue, newValue);
1022         /* setting isMaximum above the event firing means that
1023            property listeners that, for some reason, test it will
1024            get it wrong... See, for example, getNormalBounds() */
1025         isMaximum = b;
1026         firePropertyChange(IS_MAXIMUM_PROPERTY, oldValue, newValue);
1027     }
1028 
1029     /**
1030      * Returns the title of the <code>JInternalFrame</code>.
1031      *
1032      * @return a <code>String</code> containing this internal frame's title
1033      * @see #setTitle
1034      */
1035     public String getTitle() {
1036         return title;
1037     }
1038 
1039     /**
1040      * Sets the <code>JInternalFrame</code> title. <code>title</code>
1041      * may have a <code>null</code> value.
1042      * @see #getTitle
1043      *
1044      * @param title  the <code>String</code> to display in the title bar
1045      * @beaninfo
1046      *     preferred: true
1047      *     bound: true
1048      *     description: The text displayed in the title bar.
1049      */
1050     public void setTitle(String title) {
1051         String oldValue = this.title;
1052         this.title = title;
1053         firePropertyChange(TITLE_PROPERTY, oldValue, title);
1054     }
1055 
1056     /**
1057      * Selects or deselects the internal frame
1058      * if it's showing.
1059      * A <code>JInternalFrame</code> normally draws its title bar
1060      * differently if it is
1061      * the selected frame, which indicates to the user that this
1062      * internal frame has the focus.
1063      * When this method changes the state of the internal frame
1064      * from deselected to selected, it fires an
1065      * <code>InternalFrameEvent.INTERNAL_FRAME_ACTIVATED</code> event.
1066      * If the change is from selected to deselected,
1067      * an <code>InternalFrameEvent.INTERNAL_FRAME_DEACTIVATED</code> event
1068      * is fired.
1069      *
1070      * @param selected  a boolean, where <code>true</code> means this internal frame
1071      *                  should become selected (currently active)
1072      *                  and <code>false</code> means it should become deselected
1073      * @exception PropertyVetoException when the attempt to set the
1074      *            property is vetoed by the <code>JInternalFrame</code>
1075      *
1076      * @see #isShowing
1077      * @see InternalFrameEvent#INTERNAL_FRAME_ACTIVATED
1078      * @see InternalFrameEvent#INTERNAL_FRAME_DEACTIVATED
1079      *
1080      * @beaninfo
1081      *     constrained: true
1082      *           bound: true
1083      *     description: Indicates whether this internal frame is currently
1084      *                  the active frame.
1085      */
1086     public void setSelected(boolean selected) throws PropertyVetoException {
1087        // The InternalFrame may already be selected, but the focus
1088        // may be outside it, so restore the focus to the subcomponent
1089        // which previously had it. See Bug 4302764.
1090         if (selected && isSelected) {
1091             restoreSubcomponentFocus();
1092             return;
1093         }
1094         // The internal frame or the desktop icon must be showing to allow


1110            want focus, then it will get transfered there later.
1111 
1112            We test for parent.isShowing() above, because AWT throws a
1113            NPE if you try to request focus on a lightweight before its
1114            parent has been made visible */
1115 
1116         if (selected) {
1117             restoreSubcomponentFocus();
1118         }
1119 
1120         isSelected = selected;
1121         firePropertyChange(IS_SELECTED_PROPERTY, oldValue, newValue);
1122         if (isSelected)
1123           fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_ACTIVATED);
1124         else
1125           fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_DEACTIVATED);
1126         repaint();
1127     }
1128 
1129     /**
1130      * Returns whether the <code>JInternalFrame</code> is the
1131      * currently "selected" or active frame.
1132      *
1133      * @return <code>true</code> if this internal frame is currently selected (active)
1134      * @see #setSelected
1135      */
1136     public boolean isSelected() {
1137         return isSelected;
1138     }
1139 
1140     /**
1141      * Sets an image to be displayed in the titlebar of this internal frame (usually
1142      * in the top-left corner).
1143      * Some look and feels might not support displaying an icon in the titlebar.
1144      *
1145      * This image is not the <code>desktopIcon</code> object, which
1146      * is the image displayed in the <code>JDesktop</code> when
1147      * this internal frame is iconified.
1148      *
1149      * Passing <code>null</code> to this function is valid,
1150      * but the look and feel can choose the appropriate behavior
1151      * for that situation, such as displaying no icon
1152      * or a default icon for the look and feel.
1153      *
1154      * @param icon the <code>Icon</code> to display in the title bar
1155      * @see #getFrameIcon
1156      * @beaninfo
1157      *           bound: true
1158      *     description: The icon shown in the top-left corner of this internal frame.
1159      */
1160   public void setFrameIcon(Icon icon) {
1161         Icon oldIcon = frameIcon;
1162         frameIcon = icon;
1163         firePropertyChange(FRAME_ICON_PROPERTY, oldIcon, icon);
1164     }
1165 
1166     /**
1167      * Returns the image displayed in the title bar of this internal frame (usually
1168      * in the top-left corner).
1169      *
1170      * @return the <code>Icon</code> displayed in the title bar
1171      * @see #setFrameIcon
1172      */
1173     public Icon getFrameIcon()  {
1174         return frameIcon;
1175     }
1176 
1177     /**
1178       * Convenience method that moves this component to position 0 if its
1179       * parent is a <code>JLayeredPane</code>.
1180       */
1181     public void moveToFront() {
1182         if (isIcon()) {
1183             if (getDesktopIcon().getParent() instanceof JLayeredPane) {
1184                 ((JLayeredPane)getDesktopIcon().getParent()).
1185                     moveToFront(getDesktopIcon());
1186             }
1187         }
1188         else if (getParent() instanceof JLayeredPane) {
1189             ((JLayeredPane)getParent()).moveToFront(this);
1190         }
1191     }
1192 
1193     /**
1194       * Convenience method that moves this component to position -1 if its
1195       * parent is a <code>JLayeredPane</code>.
1196       */
1197     public void moveToBack() {
1198         if (isIcon()) {
1199             if (getDesktopIcon().getParent() instanceof JLayeredPane) {
1200                 ((JLayeredPane)getDesktopIcon().getParent()).
1201                     moveToBack(getDesktopIcon());
1202             }
1203         }
1204         else if (getParent() instanceof JLayeredPane) {
1205             ((JLayeredPane)getParent()).moveToBack(this);
1206         }
1207     }
1208 
1209     /**
1210      * Returns the last <code>Cursor</code> that was set by the
1211      * <code>setCursor</code> method that is not a resizable
1212      * <code>Cursor</code>.
1213      *
1214      * @return the last non-resizable <code>Cursor</code>
1215      * @since 1.6
1216      */
1217     public Cursor getLastCursor() {
1218         return lastCursor;
1219     }
1220 
1221     /**
1222      * {@inheritDoc}
1223      * @since 1.6
1224      */
1225     public void setCursor(Cursor cursor) {
1226         if (cursor == null) {
1227             lastCursor = null;
1228             super.setCursor(cursor);
1229             return;
1230         }
1231         int type = cursor.getType();
1232         if (!(type == Cursor.SW_RESIZE_CURSOR  ||
1233               type == Cursor.SE_RESIZE_CURSOR  ||
1234               type == Cursor.NW_RESIZE_CURSOR  ||
1235               type == Cursor.NE_RESIZE_CURSOR  ||
1236               type == Cursor.N_RESIZE_CURSOR   ||
1237               type == Cursor.S_RESIZE_CURSOR   ||
1238               type == Cursor.W_RESIZE_CURSOR   ||
1239               type == Cursor.E_RESIZE_CURSOR)) {
1240             lastCursor = cursor;
1241         }
1242         super.setCursor(cursor);
1243     }
1244 
1245     /**
1246      * Convenience method for setting the layer attribute of this component.
1247      *
1248      * @param layer  an <code>Integer</code> object specifying this
1249      *          frame's desktop layer
1250      * @throws NullPointerException if {@code layer} is {@code null}
1251      * @see JLayeredPane
1252      * @beaninfo
1253      *     expert: true
1254      *     description: Specifies what desktop layer is used.
1255      */
1256     public void setLayer(Integer layer) {
1257         if(getParent() != null && getParent() instanceof JLayeredPane) {
1258             // Normally we want to do this, as it causes the LayeredPane
1259             // to draw properly.
1260             JLayeredPane p = (JLayeredPane)getParent();
1261             p.setLayer(this, layer.intValue(), p.getPosition(this));
1262         } else {
1263              // Try to do the right thing
1264              JLayeredPane.putLayer(this, layer.intValue());
1265              if(getParent() != null)
1266                  getParent().repaint(getX(), getY(), getWidth(), getHeight());
1267         }
1268     }
1269 
1270     /**
1271      * Convenience method for setting the layer attribute of this component.
1272      * The method <code>setLayer(Integer)</code> should be used for
1273      * layer values predefined in <code>JLayeredPane</code>.
1274      * When using <code>setLayer(int)</code>, care must be taken not to
1275      * accidentally clash with those values.
1276      *
1277      * @param layer  an integer specifying this internal frame's desktop layer
1278      *
1279      * @since 1.3
1280      *
1281      * @see #setLayer(Integer)
1282      * @see JLayeredPane
1283      * @beaninfo
1284      *     expert: true
1285      *     description: Specifies what desktop layer is used.
1286      */
1287     public void setLayer(int layer) {
1288       this.setLayer(Integer.valueOf(layer));
1289     }
1290 
1291     /**
1292      * Convenience method for getting the layer attribute of this component.
1293      *
1294      * @return  an <code>Integer</code> object specifying this
1295      *          frame's desktop layer
1296      * @see JLayeredPane
1297       */
1298     public int getLayer() {
1299         return JLayeredPane.getLayer(this);
1300     }
1301 
1302     /**
1303       * Convenience method that searches the ancestor hierarchy for a
1304       * <code>JDesktop</code> instance. If <code>JInternalFrame</code>
1305       * finds none, the <code>desktopIcon</code> tree is searched.
1306       *
1307       * @return the <code>JDesktopPane</code> this internal frame belongs to,
1308       *         or <code>null</code> if none is found
1309       */
1310     public JDesktopPane getDesktopPane() {
1311         Container p;
1312 
1313         // Search upward for desktop
1314         p = getParent();
1315         while(p != null && !(p instanceof JDesktopPane))
1316             p = p.getParent();
1317 
1318         if(p == null) {
1319            // search its icon parent for desktop
1320            p = getDesktopIcon().getParent();
1321            while(p != null && !(p instanceof JDesktopPane))
1322                 p = p.getParent();
1323         }
1324 
1325         return (JDesktopPane)p;
1326     }
1327 
1328     /**
1329      * Sets the <code>JDesktopIcon</code> associated with this
1330      * <code>JInternalFrame</code>.
1331      *
1332      * @param d the <code>JDesktopIcon</code> to display on the desktop
1333      * @see #getDesktopIcon
1334      * @beaninfo
1335      *           bound: true
1336      *     description: The icon shown when this internal frame is minimized.
1337      */
1338     public void setDesktopIcon(JDesktopIcon d) {
1339         JDesktopIcon oldValue = getDesktopIcon();
1340         desktopIcon = d;
1341         firePropertyChange("desktopIcon", oldValue, d);
1342     }
1343 
1344     /**
1345      * Returns the <code>JDesktopIcon</code> used when this
1346      * <code>JInternalFrame</code> is iconified.
1347      *
1348      * @return the <code>JDesktopIcon</code> displayed on the desktop
1349      * @see #setDesktopIcon
1350      */
1351     public JDesktopIcon getDesktopIcon() {
1352         return desktopIcon;
1353     }
1354 
1355     /**
1356      * If the <code>JInternalFrame</code> is not in maximized state, returns
1357      * <code>getBounds()</code>; otherwise, returns the bounds that the
1358      * <code>JInternalFrame</code> would be restored to.
1359      *
1360      * @return a <code>Rectangle</code> containing the bounds of this
1361      *          frame when in the normal state
1362      * @since 1.3
1363      */
1364     public Rectangle getNormalBounds() {
1365 
1366       /* we used to test (!isMaximum) here, but since this
1367          method is used by the property listener for the
1368          IS_MAXIMUM_PROPERTY, it ended up getting the wrong
1369          answer... Since normalBounds get set to null when the
1370          frame is restored, this should work better */
1371 
1372       if (normalBounds != null) {
1373         return normalBounds;
1374       } else {
1375         return getBounds();
1376       }
1377     }
1378 
1379     /**
1380      * Sets the normal bounds for this internal frame, the bounds that
1381      * this internal frame would be restored to from its maximized state.
1382      * This method is intended for use only by desktop managers.
1383      *
1384      * @param r the bounds that this internal frame should be restored to
1385      * @since 1.3
1386      */
1387     public void setNormalBounds(Rectangle r) {
1388         normalBounds = r;
1389     }
1390 
1391     /**
1392      * If this <code>JInternalFrame</code> is active,
1393      * returns the child that has focus.
1394      * Otherwise, returns <code>null</code>.
1395      *
1396      * @return the component with focus, or <code>null</code> if no children have focus
1397      * @since 1.3
1398      */
1399     public Component getFocusOwner() {
1400         if (isSelected()) {
1401             return lastFocusOwner;
1402         }
1403         return null;
1404     }
1405 
1406     /**
1407      * Returns the child component of this <code>JInternalFrame</code>
1408      * that will receive the
1409      * focus when this <code>JInternalFrame</code> is selected.
1410      * If this <code>JInternalFrame</code> is
1411      * currently selected, this method returns the same component as
1412      * the <code>getFocusOwner</code> method.
1413      * If this <code>JInternalFrame</code> is not selected,
1414      * then the child component that most recently requested focus will be
1415      * returned. If no child component has ever requested focus, then this
1416      * <code>JInternalFrame</code>'s initial focusable component is returned.
1417      * If no such
1418      * child exists, then this <code>JInternalFrame</code>'s default component
1419      * to focus is returned.
1420      *
1421      * @return the child component that will receive focus when this
1422      *         <code>JInternalFrame</code> is selected
1423      * @see #getFocusOwner
1424      * @see #isSelected
1425      * @since 1.4
1426      */
1427     public Component getMostRecentFocusOwner() {
1428         if (isSelected()) {
1429             return getFocusOwner();
1430         }
1431 
1432         if (lastFocusOwner != null) {
1433             return lastFocusOwner;
1434         }
1435 
1436         FocusTraversalPolicy policy = getFocusTraversalPolicy();
1437         if (policy instanceof InternalFrameFocusTraversalPolicy) {
1438             return ((InternalFrameFocusTraversalPolicy)policy).
1439                 getInitialComponent(this);
1440         }
1441 
1442         Component toFocus = policy.getDefaultComponent(this);


1511      *
1512      * @param l the internal frame listener
1513      */
1514     public void addInternalFrameListener(InternalFrameListener l) {  // remind: sync ??
1515       listenerList.add(InternalFrameListener.class, l);
1516       // remind: needed?
1517       enableEvents(0);   // turn on the newEventsOnly flag in Component.
1518     }
1519 
1520     /**
1521      * Removes the specified internal frame listener so that it no longer
1522      * receives internal frame events from this internal frame.
1523      *
1524      * @param l the internal frame listener
1525      */
1526     public void removeInternalFrameListener(InternalFrameListener l) {  // remind: sync??
1527       listenerList.remove(InternalFrameListener.class, l);
1528     }
1529 
1530     /**
1531      * Returns an array of all the <code>InternalFrameListener</code>s added
1532      * to this <code>JInternalFrame</code> with
1533      * <code>addInternalFrameListener</code>.
1534      *
1535      * @return all of the <code>InternalFrameListener</code>s added or an empty
1536      *         array if no listeners have been added
1537      * @since 1.4
1538      *
1539      * @see #addInternalFrameListener
1540      */
1541     public InternalFrameListener[] getInternalFrameListeners() {
1542         return listenerList.getListeners(InternalFrameListener.class);
1543     }
1544 
1545     // remind: name ok? all one method ok? need to be synchronized?
1546     /**
1547      * Fires an internal frame event.
1548      *
1549      * @param id  the type of the event being fired; one of the following:
1550      * <ul>
1551      * <li><code>InternalFrameEvent.INTERNAL_FRAME_OPENED</code>
1552      * <li><code>InternalFrameEvent.INTERNAL_FRAME_CLOSING</code>
1553      * <li><code>InternalFrameEvent.INTERNAL_FRAME_CLOSED</code>
1554      * <li><code>InternalFrameEvent.INTERNAL_FRAME_ICONIFIED</code>
1555      * <li><code>InternalFrameEvent.INTERNAL_FRAME_DEICONIFIED</code>
1556      * <li><code>InternalFrameEvent.INTERNAL_FRAME_ACTIVATED</code>
1557      * <li><code>InternalFrameEvent.INTERNAL_FRAME_DEACTIVATED</code>
1558      * </ul>
1559      * If the event type is not one of the above, nothing happens.
1560      */
1561     protected void fireInternalFrameEvent(int id){
1562       Object[] listeners = listenerList.getListenerList();
1563       InternalFrameEvent e = null;
1564       for (int i = listeners.length -2; i >=0; i -= 2){
1565         if (listeners[i] == InternalFrameListener.class){
1566           if (e == null){
1567             e = new InternalFrameEvent(this, id);
1568             //      System.out.println("InternalFrameEvent: " + e.paramString());
1569           }
1570           switch(e.getID()) {
1571           case InternalFrameEvent.INTERNAL_FRAME_OPENED:
1572             ((InternalFrameListener)listeners[i+1]).internalFrameOpened(e);
1573             break;
1574           case InternalFrameEvent.INTERNAL_FRAME_CLOSING:
1575             ((InternalFrameListener)listeners[i+1]).internalFrameClosing(e);
1576             break;
1577           case InternalFrameEvent.INTERNAL_FRAME_CLOSED:


1586           case InternalFrameEvent.INTERNAL_FRAME_ACTIVATED:
1587             ((InternalFrameListener)listeners[i+1]).internalFrameActivated(e);
1588             break;
1589           case InternalFrameEvent.INTERNAL_FRAME_DEACTIVATED:
1590             ((InternalFrameListener)listeners[i+1]).internalFrameDeactivated(e);
1591             break;
1592           default:
1593             break;
1594           }
1595         }
1596       }
1597       /* we could do it off the event, but at the moment, that's not how
1598          I'm implementing it */
1599       //      if (id == InternalFrameEvent.INTERNAL_FRAME_CLOSING) {
1600       //          doDefaultCloseAction();
1601       //      }
1602     }
1603 
1604     /**
1605      * Fires an
1606      * <code>INTERNAL_FRAME_CLOSING</code> event
1607      * and then performs the action specified by
1608      * the internal frame's default close operation.
1609      * This method is typically invoked by the
1610      * look-and-feel-implemented action handler
1611      * for the internal frame's close button.
1612      *
1613      * @since 1.3
1614      * @see #setDefaultCloseOperation
1615      * @see javax.swing.event.InternalFrameEvent#INTERNAL_FRAME_CLOSING
1616      */
1617     public void doDefaultCloseAction() {
1618         fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_CLOSING);
1619         switch(defaultCloseOperation) {
1620           case DO_NOTHING_ON_CLOSE:
1621             break;
1622           case HIDE_ON_CLOSE:
1623             setVisible(false);
1624             if (isSelected())
1625                 try {
1626                     setSelected(false);


1634                 fireVetoableChange(IS_CLOSED_PROPERTY, Boolean.FALSE,
1635                                    Boolean.TRUE);
1636                 isClosed = true;
1637                 setVisible(false);
1638                 firePropertyChange(IS_CLOSED_PROPERTY, Boolean.FALSE,
1639                                    Boolean.TRUE);
1640                 dispose();
1641               } catch (PropertyVetoException pve) {}
1642               break;
1643           default:
1644               break;
1645         }
1646     }
1647 
1648     /**
1649      * Sets the operation that will happen by default when
1650      * the user initiates a "close" on this internal frame.
1651      * The possible choices are:
1652      * <br><br>
1653      * <dl>
1654      * <dt><code>DO_NOTHING_ON_CLOSE</code>
1655      * <dd> Do nothing.
1656      *      This requires the program to handle the operation
1657      *      in the <code>internalFrameClosing</code> method
1658      *      of a registered <code>InternalFrameListener</code> object.
1659      * <dt><code>HIDE_ON_CLOSE</code>
1660      * <dd> Automatically make the internal frame invisible.
1661      * <dt><code>DISPOSE_ON_CLOSE</code>
1662      * <dd> Automatically dispose of the internal frame.
1663      * </dl>
1664      * <p>
1665      * The default value is <code>DISPOSE_ON_CLOSE</code>.
1666      * Before performing the specified close operation,
1667      * the internal frame fires
1668      * an <code>INTERNAL_FRAME_CLOSING</code> event.
1669      *
1670      * @param operation one of the following constants defined in
1671      *                  <code>javax.swing.WindowConstants</code>
1672      *                  (an interface implemented by
1673      *                  <code>JInternalFrame</code>):
1674      *                  <code>DO_NOTHING_ON_CLOSE</code>,
1675      *                  <code>HIDE_ON_CLOSE</code>, or
1676      *                  <code>DISPOSE_ON_CLOSE</code>
1677      *
1678      * @see #addInternalFrameListener
1679      * @see #getDefaultCloseOperation
1680      * @see #setVisible
1681      * @see #dispose
1682      * @see InternalFrameEvent#INTERNAL_FRAME_CLOSING
1683      */
1684     public void setDefaultCloseOperation(int operation) {
1685         this.defaultCloseOperation = operation;
1686     }
1687 
1688    /**
1689     * Returns the default operation that occurs when the user
1690     * initiates a "close" on this internal frame.
1691     * @return the operation that will occur when the user closes the internal
1692     *         frame
1693     * @see #setDefaultCloseOperation
1694     */
1695     public int getDefaultCloseOperation() {
1696         return defaultCloseOperation;
1697     }
1698 
1699     /**
1700      * Causes subcomponents of this <code>JInternalFrame</code>
1701      * to be laid out at their preferred size.  Internal frames that are
1702      * iconized or maximized are first restored and then packed.  If the
1703      * internal frame is unable to be restored its state is not changed
1704      * and will not be packed.
1705      *
1706      * @see       java.awt.Window#pack
1707      */
1708     public void pack() {
1709         try {
1710             if (isIcon()) {
1711                 setIcon(false);
1712             } else if (isMaximum()) {
1713                 setMaximum(false);
1714             }
1715         } catch(PropertyVetoException e) {
1716             return;
1717         }
1718         setSize(getPreferredSize());
1719         validate();
1720     }
1721 
1722     /**
1723      * If the internal frame is not visible,
1724      * brings the internal frame to the front,
1725      * makes it visible,
1726      * and attempts to select it.
1727      * The first time the internal frame is made visible,
1728      * this method also fires an <code>INTERNAL_FRAME_OPENED</code> event.
1729      * This method does nothing if the internal frame is already visible.
1730      * Invoking this method
1731      * has the same result as invoking
1732      * <code>setVisible(true)</code>.
1733      *
1734      * @see #moveToFront
1735      * @see #setSelected
1736      * @see InternalFrameEvent#INTERNAL_FRAME_OPENED
1737      * @see #setVisible
1738      */
1739     @SuppressWarnings("deprecation")
1740     public void show() {
1741         // bug 4312922
1742         if (isVisible()) {
1743             //match the behavior of setVisible(true): do nothing
1744             return;
1745         }
1746 
1747         // bug 4149505
1748         if (!opened) {
1749           fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_OPENED);
1750           opened = true;
1751         }
1752 


1764         if (!isSelected()) {
1765             try {
1766                 setSelected(true);
1767             } catch (PropertyVetoException pve) {}
1768         }
1769     }
1770 
1771     @SuppressWarnings("deprecation")
1772     public void hide() {
1773         if (isIcon()) {
1774             getDesktopIcon().setVisible(false);
1775         }
1776         super.hide();
1777     }
1778 
1779     /**
1780      * Makes this internal frame
1781      * invisible, unselected, and closed.
1782      * If the frame is not already closed,
1783      * this method fires an
1784      * <code>INTERNAL_FRAME_CLOSED</code> event.
1785      * The results of invoking this method are similar to
1786      * <code>setClosed(true)</code>,
1787      * but <code>dispose</code> always succeeds in closing
1788      * the internal frame and does not fire
1789      * an <code>INTERNAL_FRAME_CLOSING</code> event.
1790      *
1791      * @see javax.swing.event.InternalFrameEvent#INTERNAL_FRAME_CLOSED
1792      * @see #setVisible
1793      * @see #setSelected
1794      * @see #setClosed
1795      */
1796     public void dispose() {
1797         if (isVisible()) {
1798             setVisible(false);
1799         }
1800         if (isSelected()) {
1801             try {
1802                 setSelected(false);
1803             } catch (PropertyVetoException pve) {}
1804         }
1805         if (!isClosed) {
1806           firePropertyChange(IS_CLOSED_PROPERTY, Boolean.FALSE, Boolean.TRUE);
1807           isClosed = true;
1808         }
1809         fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_CLOSED);


1819      * @see       #moveToFront
1820      */
1821     public void toFront() {
1822         moveToFront();
1823     }
1824 
1825     /**
1826      * Sends this internal frame to the back.
1827      * Places this internal frame at the bottom of the stacking order
1828      * and makes the corresponding adjustment to other visible
1829      * internal frames.
1830      *
1831      * @see       java.awt.Window#toBack
1832      * @see       #moveToBack
1833      */
1834     public void toBack() {
1835         moveToBack();
1836     }
1837 
1838     /**
1839      * Does nothing because <code>JInternalFrame</code>s must always be roots of a focus
1840      * traversal cycle.
1841      *
1842      * @param focusCycleRoot this value is ignored
1843      * @see #isFocusCycleRoot
1844      * @see java.awt.Container#setFocusTraversalPolicy
1845      * @see java.awt.Container#getFocusTraversalPolicy
1846      * @since 1.4
1847      */
1848     public final void setFocusCycleRoot(boolean focusCycleRoot) {
1849     }
1850 
1851     /**
1852      * Always returns <code>true</code> because all <code>JInternalFrame</code>s must be
1853      * roots of a focus traversal cycle.
1854      *
1855      * @return <code>true</code>
1856      * @see #setFocusCycleRoot
1857      * @see java.awt.Container#setFocusTraversalPolicy
1858      * @see java.awt.Container#getFocusTraversalPolicy
1859      * @since 1.4
1860      */
1861     public final boolean isFocusCycleRoot() {
1862         return true;
1863     }
1864 
1865     /**
1866      * Always returns <code>null</code> because <code>JInternalFrame</code>s
1867      * must always be roots of a focus
1868      * traversal cycle.
1869      *
1870      * @return <code>null</code>
1871      * @see java.awt.Container#isFocusCycleRoot()
1872      * @since 1.4
1873      */
1874     public final Container getFocusCycleRootAncestor() {
1875         return null;
1876     }
1877 
1878     /**
1879      * Gets the warning string that is displayed with this internal frame.
1880      * Since an internal frame is always secure (since it's fully
1881      * contained within a window that might need a warning string)
1882      * this method always returns <code>null</code>.
1883      * @return    <code>null</code>
1884      * @see       java.awt.Window#getWarningString
1885      */
1886     public final String getWarningString() {
1887         return null;
1888     }
1889 
1890     /**
1891      * See <code>readObject</code> and <code>writeObject</code>
1892      * in <code>JComponent</code> for more
1893      * information about serialization in Swing.
1894      */
1895     private void writeObject(ObjectOutputStream s) throws IOException {
1896         s.defaultWriteObject();
1897         if (getUIClassID().equals(uiClassID)) {
1898             byte count = JComponent.getWriteObjCounter(this);
1899             JComponent.setWriteObjCounter(this, --count);
1900             if (count == 0 && ui != null) {
1901                 boolean old = isRootPaneCheckingEnabled();
1902                 try {
1903                     setRootPaneCheckingEnabled(false);
1904                     ui.installUI(this);
1905                 } finally {
1906                     setRootPaneCheckingEnabled(old);
1907                 }
1908             }
1909         }
1910     }
1911 
1912     /* Called from the JComponent's EnableSerializationFocusListener to
1913      * do any Swing-specific pre-serialization configuration.
1914      */
1915     void compWriteObjectNotify() {
1916       // need to disable rootpane checking for InternalFrame: 4172083
1917       boolean old = isRootPaneCheckingEnabled();
1918       try {
1919         setRootPaneCheckingEnabled(false);
1920         super.compWriteObjectNotify();
1921       }
1922       finally {
1923         setRootPaneCheckingEnabled(old);
1924       }
1925     }
1926 
1927     /**
1928      * Returns a string representation of this <code>JInternalFrame</code>.
1929      * This method
1930      * is intended to be used only for debugging purposes, and the
1931      * content and format of the returned string may vary between
1932      * implementations. The returned string may be empty but may not
1933      * be <code>null</code>.
1934      *
1935      * @return  a string representation of this <code>JInternalFrame</code>
1936      */
1937     protected String paramString() {
1938         String rootPaneString = (rootPane != null ?
1939                                  rootPane.toString() : "");
1940         String rootPaneCheckingEnabledString = (rootPaneCheckingEnabled ?
1941                                                 "true" : "false");
1942         String closableString = (closable ? "true" : "false");
1943         String isClosedString = (isClosed ? "true" : "false");
1944         String maximizableString = (maximizable ? "true" : "false");
1945         String isMaximumString = (isMaximum ? "true" : "false");
1946         String iconableString = (iconable ? "true" : "false");
1947         String isIconString = (isIcon ? "true" : "false");
1948         String resizableString = (resizable ? "true" : "false");
1949         String isSelectedString = (isSelected ? "true" : "false");
1950         String frameIconString = (frameIcon != null ?
1951                                   frameIcon.toString() : "");
1952         String titleString = (title != null ?
1953                               title : "");
1954         String desktopIconString = (desktopIcon != null ?
1955                                     desktopIcon.toString() : "");


1989     /**
1990      * Overridden to allow optimized painting when the
1991      * internal frame is being dragged.
1992      */
1993     protected void paintComponent(Graphics g) {
1994       if (isDragging) {
1995         //         System.out.println("ouch");
1996          danger = true;
1997       }
1998 
1999       super.paintComponent(g);
2000    }
2001 
2002     // ======= end optimized frame dragging defence code ==============
2003 
2004 /////////////////
2005 // Accessibility support
2006 ////////////////
2007 
2008     /**
2009      * Gets the <code>AccessibleContext</code> associated with this
2010      * <code>JInternalFrame</code>.
2011      * For internal frames, the <code>AccessibleContext</code>
2012      * takes the form of an
2013      * <code>AccessibleJInternalFrame</code> object.
2014      * A new <code>AccessibleJInternalFrame</code> instance is created if necessary.
2015      *
2016      * @return an <code>AccessibleJInternalFrame</code> that serves as the
2017      *         <code>AccessibleContext</code> of this
2018      *         <code>JInternalFrame</code>
2019      * @see AccessibleJInternalFrame
2020      */
2021     public AccessibleContext getAccessibleContext() {
2022         if (accessibleContext == null) {
2023             accessibleContext = new AccessibleJInternalFrame();
2024         }
2025         return accessibleContext;
2026     }
2027 
2028     /**
2029      * This class implements accessibility support for the
2030      * <code>JInternalFrame</code> class.  It provides an implementation of the
2031      * Java Accessibility API appropriate to internal frame user-interface
2032      * elements.
2033      * <p>
2034      * <strong>Warning:</strong>
2035      * Serialized objects of this class will not be compatible with
2036      * future Swing releases. The current serialization support is
2037      * appropriate for short term storage or RMI between applications running
2038      * the same version of Swing.  As of 1.4, support for long term storage
2039      * of all JavaBeans&trade;
2040      * has been added to the <code>java.beans</code> package.
2041      * Please see {@link java.beans.XMLEncoder}.
2042      */
2043     @SuppressWarnings("serial") // Same-version serialization only
2044     protected class AccessibleJInternalFrame extends AccessibleJComponent
2045         implements AccessibleValue {
2046 
2047         /**
2048          * Get the accessible name of this object.
2049          *
2050          * @return the localized name of the object -- can be <code>null</code> if this
2051          * object does not have a name
2052          * @see #setAccessibleName
2053          */
2054         public String getAccessibleName() {
2055             String name = accessibleName;
2056 
2057             if (name == null) {
2058                 name = (String)getClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY);
2059             }
2060             if (name == null) {
2061                 name = getTitle();
2062             }
2063             return name;
2064         }
2065 
2066         /**
2067          * Get the role of this object.
2068          *
2069          * @return an instance of AccessibleRole describing the role of the
2070          * object
2071          * @see AccessibleRole
2072          */
2073         public AccessibleRole getAccessibleRole() {
2074             return AccessibleRole.INTERNAL_FRAME;
2075         }
2076 
2077         /**
2078          * Gets the AccessibleValue associated with this object.  In the
2079          * implementation of the Java Accessibility API for this class,
2080          * returns this object, which is responsible for implementing the
2081          * <code>AccessibleValue</code> interface on behalf of itself.
2082          *
2083          * @return this object
2084          */
2085         public AccessibleValue getAccessibleValue() {
2086             return this;
2087         }
2088 
2089 
2090         //
2091         // AccessibleValue methods
2092         //
2093 
2094         /**
2095          * Get the value of this object as a Number.
2096          *
2097          * @return value of the object -- can be <code>null</code> if this object does not
2098          * have a value
2099          */
2100         public Number getCurrentAccessibleValue() {
2101             return Integer.valueOf(getLayer());
2102         }
2103 
2104         /**
2105          * Set the value of this object as a Number.
2106          *
2107          * @return <code>true</code> if the value was set
2108          */
2109         public boolean setCurrentAccessibleValue(Number n) {
2110             // TIGER - 4422535
2111             if (n == null) {
2112                 return false;
2113             }
2114             setLayer(Integer.valueOf(n.intValue()));
2115             return true;
2116         }
2117 
2118         /**
2119          * Get the minimum value of this object as a Number.
2120          *
2121          * @return Minimum value of the object; <code>null</code> if this object does not
2122          * have a minimum value
2123          */
2124         public Number getMinimumAccessibleValue() {
2125             return Integer.MIN_VALUE;
2126         }
2127 
2128         /**
2129          * Get the maximum value of this object as a Number.
2130          *
2131          * @return Maximum value of the object; <code>null</code> if this object does not
2132          * have a maximum value
2133          */
2134         public Number getMaximumAccessibleValue() {
2135             return Integer.MAX_VALUE;
2136         }
2137 
2138     } // AccessibleJInternalFrame
2139 
2140     /**
2141      * This component represents an iconified version of a
2142      * <code>JInternalFrame</code>.
2143      * This API should NOT BE USED by Swing applications, as it will go
2144      * away in future versions of Swing as its functionality is moved into
2145      * <code>JInternalFrame</code>.  This class is public only so that
2146      * UI objects can display a desktop icon.  If an application
2147      * wants to display a desktop icon, it should create a
2148      * <code>JInternalFrame</code> instance and iconify it.
2149      * <p>
2150      * <strong>Warning:</strong>
2151      * Serialized objects of this class will not be compatible with
2152      * future Swing releases. The current serialization support is
2153      * appropriate for short term storage or RMI between applications running
2154      * the same version of Swing.  As of 1.4, support for long term storage
2155      * of all JavaBeans&trade;
2156      * has been added to the <code>java.beans</code> package.
2157      * Please see {@link java.beans.XMLEncoder}.
2158      *
2159      * @author David Kloba
2160      */
2161     @SuppressWarnings("serial") // Same-version serialization only
2162     public static class JDesktopIcon extends JComponent implements Accessible
2163     {
2164         JInternalFrame internalFrame;
2165 
2166         /**
2167          * Creates an icon for an internal frame.
2168          *
2169          * @param f  the <code>JInternalFrame</code>
2170          *              for which the icon is created
2171          */
2172         public JDesktopIcon(JInternalFrame f) {
2173             setVisible(false);
2174             setInternalFrame(f);
2175             updateUI();
2176         }
2177 
2178         /**
2179          * Returns the look-and-feel object that renders this component.
2180          *
2181          * @return the <code>DesktopIconUI</code> object that renders
2182          *              this component
2183          */
2184         public DesktopIconUI getUI() {
2185             return (DesktopIconUI)ui;
2186         }
2187 
2188         /**
2189          * Sets the look-and-feel object that renders this component.
2190          *
2191          * @param ui  the <code>DesktopIconUI</code> look-and-feel object
2192          * @see UIDefaults#getUI
2193          */
2194         public void setUI(DesktopIconUI ui) {
2195             super.setUI(ui);
2196         }
2197 
2198         /**
2199          * Returns the <code>JInternalFrame</code> that this
2200          * <code>DesktopIcon</code> is associated with.
2201          *
2202          * @return the <code>JInternalFrame</code> with which this icon
2203          *              is associated
2204          */
2205         public JInternalFrame getInternalFrame() {
2206             return internalFrame;
2207         }
2208 
2209         /**
2210          * Sets the <code>JInternalFrame</code> with which this
2211          * <code>DesktopIcon</code> is associated.
2212          *
2213          * @param f  the <code>JInternalFrame</code> with which this icon
2214          *              is associated
2215          */
2216         public void setInternalFrame(JInternalFrame f) {
2217             internalFrame = f;
2218         }
2219 
2220         /**
2221          * Convenience method to ask the icon for the <code>Desktop</code>
2222          * object it belongs to.
2223          *
2224          * @return the <code>JDesktopPane</code> that contains this
2225          *           icon's internal frame, or <code>null</code> if none found
2226          */
2227         public JDesktopPane getDesktopPane() {
2228             if(getInternalFrame() != null)
2229                 return getInternalFrame().getDesktopPane();
2230             return null;
2231         }
2232 
2233         /**
2234          * Notification from the <code>UIManager</code> that the look and feel
2235          * has changed.
2236          * Replaces the current UI object with the latest version from the
2237          * <code>UIManager</code>.
2238          *
2239          * @see JComponent#updateUI
2240          */
2241         public void updateUI() {
2242             boolean hadUI = (ui != null);
2243             setUI((DesktopIconUI)UIManager.getUI(this));
2244             invalidate();
2245 
2246             Dimension r = getPreferredSize();
2247             setSize(r.width, r.height);
2248 
2249 
2250             if (internalFrame != null && internalFrame.getUI() != null) {  // don't do this if UI not created yet
2251                 SwingUtilities.updateComponentTreeUI(internalFrame);
2252             }
2253         }
2254 
2255         /* This method is called if updateUI was called on the associated
2256          * JInternalFrame.  It's necessary to avoid infinite recursion.
2257          */


2301        ////////////////
2302 
2303         /**
2304          * Gets the AccessibleContext associated with this JDesktopIcon.
2305          * For desktop icons, the AccessibleContext takes the form of an
2306          * AccessibleJDesktopIcon.
2307          * A new AccessibleJDesktopIcon instance is created if necessary.
2308          *
2309          * @return an AccessibleJDesktopIcon that serves as the
2310          *         AccessibleContext of this JDesktopIcon
2311          */
2312         public AccessibleContext getAccessibleContext() {
2313             if (accessibleContext == null) {
2314                 accessibleContext = new AccessibleJDesktopIcon();
2315             }
2316             return accessibleContext;
2317         }
2318 
2319         /**
2320          * This class implements accessibility support for the
2321          * <code>JInternalFrame.JDesktopIcon</code> class.  It provides an
2322          * implementation of the Java Accessibility API appropriate to
2323          * desktop icon user-interface elements.
2324          * <p>
2325          * <strong>Warning:</strong>
2326          * Serialized objects of this class will not be compatible with
2327          * future Swing releases. The current serialization support is
2328          * appropriate for short term storage or RMI between applications running
2329          * the same version of Swing.  As of 1.4, support for long term storage
2330          * of all JavaBeans&trade;
2331          * has been added to the <code>java.beans</code> package.
2332          * Please see {@link java.beans.XMLEncoder}.
2333          */
2334         @SuppressWarnings("serial") // Same-version serialization only
2335         protected class AccessibleJDesktopIcon extends AccessibleJComponent
2336             implements AccessibleValue {
2337 
2338             /**
2339              * Gets the role of this object.
2340              *
2341              * @return an instance of AccessibleRole describing the role of the
2342              * object
2343              * @see AccessibleRole
2344              */
2345             public AccessibleRole getAccessibleRole() {
2346                 return AccessibleRole.DESKTOP_ICON;
2347             }
2348 
2349             /**
2350              * Gets the AccessibleValue associated with this object.  In the
2351              * implementation of the Java Accessibility API for this class,
2352              * returns this object, which is responsible for implementing the
2353              * <code>AccessibleValue</code> interface on behalf of itself.
2354              *
2355              * @return this object
2356              */
2357             public AccessibleValue getAccessibleValue() {
2358                 return this;
2359             }
2360 
2361             //
2362             // AccessibleValue methods
2363             //
2364 
2365             /**
2366              * Gets the value of this object as a <code>Number</code>.
2367              *
2368              * @return value of the object -- can be <code>null</code> if this object does not
2369              * have a value
2370              */
2371             public Number getCurrentAccessibleValue() {
2372                 AccessibleContext a = JDesktopIcon.this.getInternalFrame().getAccessibleContext();
2373                 AccessibleValue v = a.getAccessibleValue();
2374                 if (v != null) {
2375                     return v.getCurrentAccessibleValue();
2376                 } else {
2377                     return null;
2378                 }
2379             }
2380 
2381             /**
2382              * Sets the value of this object as a <code>Number</code>.
2383              *
2384              * @return <code>true</code> if the value was set
2385              */
2386             public boolean setCurrentAccessibleValue(Number n) {
2387                 // TIGER - 4422535
2388                 if (n == null) {
2389                     return false;
2390                 }
2391                 AccessibleContext a = JDesktopIcon.this.getInternalFrame().getAccessibleContext();
2392                 AccessibleValue v = a.getAccessibleValue();
2393                 if (v != null) {
2394                     return v.setCurrentAccessibleValue(n);
2395                 } else {
2396                     return false;
2397                 }
2398             }
2399 
2400             /**
2401              * Gets the minimum value of this object as a <code>Number</code>.
2402              *
2403              * @return minimum value of the object; <code>null</code> if this object does not
2404              * have a minimum value
2405              */
2406             public Number getMinimumAccessibleValue() {
2407                 AccessibleContext a = JDesktopIcon.this.getInternalFrame().getAccessibleContext();
2408                 if (a instanceof AccessibleValue) {
2409                     return ((AccessibleValue)a).getMinimumAccessibleValue();
2410                 } else {
2411                     return null;
2412                 }
2413             }
2414 
2415             /**
2416              * Gets the maximum value of this object as a <code>Number</code>.
2417              *
2418              * @return maximum value of the object; <code>null</code> if this object does not
2419              * have a maximum value
2420              */
2421             public Number getMaximumAccessibleValue() {
2422                 AccessibleContext a = JDesktopIcon.this.getInternalFrame().getAccessibleContext();
2423                 if (a instanceof AccessibleValue) {
2424                     return ((AccessibleValue)a).getMaximumAccessibleValue();
2425                 } else {
2426                     return null;
2427                 }
2428             }
2429 
2430         } // AccessibleJDesktopIcon
2431     }
2432 }


  38 
  39 import java.io.ObjectOutputStream;
  40 import java.io.IOException;
  41 import java.beans.PropertyChangeListener;
  42 import sun.awt.AppContext;
  43 import sun.swing.SwingUtilities2;
  44 
  45 
  46 /**
  47  * A lightweight object that provides many of the features of
  48  * a native frame, including dragging, closing, becoming an icon,
  49  * resizing, title display, and support for a menu bar.
  50  * For task-oriented documentation and examples of using internal frames,
  51  * see <a
  52  href="http://docs.oracle.com/javase/tutorial/uiswing/components/internalframe.html" target="_top">How to Use Internal Frames</a>,
  53  * a section in <em>The Java Tutorial</em>.
  54  *
  55  * <p>
  56  *
  57  * Generally,
  58  * you add {@code JInternalFrame}s to a {@code JDesktopPane}. The UI
  59  * delegates the look-and-feel-specific actions to the
  60  * {@code DesktopManager}
  61  * object maintained by the {@code JDesktopPane}.
  62  * <p>
  63  * The {@code JInternalFrame} content pane
  64  * is where you add child components.
  65  * As a convenience, the {@code add}, {@code remove}, and {@code setLayout}
  66  * methods of this class are overridden, so that they delegate calls
  67  * to the corresponding methods of the {@code ContentPane}.
  68  * For example, you can add a child component to an internal frame as follows:
  69  * <pre>
  70  *       internalFrame.add(child);
  71  * </pre>
  72  * And the child will be added to the contentPane.
  73  * The content pane is actually managed by an instance of
  74  * {@code JRootPane},
  75  * which also manages a layout pane, glass pane, and
  76  * optional menu bar for the internal frame. Please see the
  77  * {@code JRootPane}
  78  * documentation for a complete description of these components.
  79  * Refer to {@link javax.swing.RootPaneContainer}
  80  * for details on adding, removing and setting the {@code LayoutManager}
  81  * of a {@code JInternalFrame}.
  82  * <p>
  83  * <strong>Warning:</strong> Swing is not thread safe. For more
  84  * information see <a
  85  * href="package-summary.html#threading">Swing's Threading
  86  * Policy</a>.
  87  * <p>
  88  * <strong>Warning:</strong>
  89  * Serialized objects of this class will not be compatible with
  90  * future Swing releases. The current serialization support is
  91  * appropriate for short term storage or RMI between applications running
  92  * the same version of Swing.  As of 1.4, support for long term storage
  93  * of all JavaBeans&trade;
  94  * has been added to the {@code java.beans} package.
  95  * Please see {@link java.beans.XMLEncoder}.
  96  *
  97  * @see InternalFrameEvent
  98  * @see JDesktopPane
  99  * @see DesktopManager
 100  * @see JInternalFrame.JDesktopIcon
 101  * @see JRootPane
 102  * @see javax.swing.RootPaneContainer
 103  *
 104  * @author David Kloba
 105  * @author Rich Schiavi
 106  * @since 1.2
 107  * @beaninfo
 108  *      attribute: isContainer true
 109  *      attribute: containerDelegate getContentPane
 110  *      description: A frame container which is contained within
 111  *                   another window.
 112  */
 113 @SuppressWarnings("serial") // Same-version serialization only
 114 public class JInternalFrame extends JComponent implements
 115         Accessible, WindowConstants,
 116         RootPaneContainer
 117 {
 118     /**
 119      * @see #getUIClassID
 120      * @see #readObject
 121      */
 122     private static final String uiClassID = "InternalFrameUI";
 123 
 124     /**
 125      * The {@code JRootPane} instance that manages the
 126      * content pane
 127      * and optional menu bar for this internal frame, as well as the
 128      * glass pane.
 129      *
 130      * @see JRootPane
 131      * @see RootPaneContainer
 132      */
 133     protected JRootPane rootPane;
 134 
 135     /**
 136      * If true then calls to {@code add} and {@code setLayout}
 137      * will be forwarded to the {@code contentPane}. This is initially
 138      * false, but is set to true when the {@code JInternalFrame} is
 139      * constructed.
 140      *
 141      * @see #isRootPaneCheckingEnabled
 142      * @see #setRootPaneCheckingEnabled
 143      * @see javax.swing.RootPaneContainer
 144      */
 145     protected boolean rootPaneCheckingEnabled = false;
 146 
 147     /** The frame can be closed. */
 148     protected boolean closable;
 149     /** The frame has been closed. */
 150     protected boolean isClosed;
 151     /** The frame can be expanded to the size of the desktop pane. */
 152     protected boolean maximizable;
 153     /**
 154      * The frame has been expanded to its maximum size.
 155      * @see #maximizable
 156      */
 157     protected boolean isMaximum;
 158     /**


 174     /** The icon shown in the top-left corner of this internal frame. */
 175     protected Icon frameIcon;
 176     /** The title displayed in this internal frame's title bar. */
 177     protected String  title;
 178     /**
 179      * The icon that is displayed when this internal frame is iconified.
 180      * @see #iconable
 181      */
 182     protected JDesktopIcon desktopIcon;
 183 
 184     private Cursor lastCursor;
 185 
 186     private boolean opened;
 187 
 188     private Rectangle normalBounds = null;
 189 
 190     private int defaultCloseOperation = DISPOSE_ON_CLOSE;
 191 
 192     /**
 193      * Contains the Component that focus is to go when
 194      * {@code restoreSubcomponentFocus} is invoked, that is,
 195      * {@code restoreSubcomponentFocus} sets this to the value returned
 196      * from {@code getMostRecentFocusOwner}.
 197      */
 198     private Component lastFocusOwner;
 199 
 200     /** Bound property name. */
 201     public static final String CONTENT_PANE_PROPERTY = "contentPane";
 202     /** Bound property name. */
 203     public static final String MENU_BAR_PROPERTY = "JMenuBar";
 204     /** Bound property name. */
 205     public static final String TITLE_PROPERTY = "title";
 206     /** Bound property name. */
 207     public static final String LAYERED_PANE_PROPERTY = "layeredPane";
 208     /** Bound property name. */
 209     public static final String ROOT_PANE_PROPERTY = "rootPane";
 210     /** Bound property name. */
 211     public static final String GLASS_PANE_PROPERTY = "glassPane";
 212     /** Bound property name. */
 213     public static final String FRAME_ICON_PROPERTY = "frameIcon";
 214 
 215     /**
 216      * Constrained property name indicated that this frame has


 248                 updateLastFocusOwner((Component)e.getNewValue());
 249             }
 250         }
 251     }
 252 
 253     private static void updateLastFocusOwner(Component component) {
 254         if (component != null) {
 255             Component parent = component;
 256             while (parent != null && !(parent instanceof Window)) {
 257                 if (parent instanceof JInternalFrame) {
 258                     // Update lastFocusOwner for parent.
 259                     ((JInternalFrame)parent).setLastFocusOwner(component);
 260                 }
 261                 parent = parent.getParent();
 262             }
 263         }
 264     }
 265 
 266     /**
 267      * Creates a non-resizable, non-closable, non-maximizable,
 268      * non-iconifiable {@code JInternalFrame} with no title.
 269      */
 270     public JInternalFrame() {
 271         this("", false, false, false, false);
 272     }
 273 
 274     /**
 275      * Creates a non-resizable, non-closable, non-maximizable,
 276      * non-iconifiable {@code JInternalFrame} with the specified title.
 277      * Note that passing in a {@code null title} results in
 278      * unspecified behavior and possibly an exception.
 279      *
 280      * @param title  the non-{@code null String}
 281      *     to display in the title bar
 282      */
 283     public JInternalFrame(String title) {
 284         this(title, false, false, false, false);
 285     }
 286 
 287     /**
 288      * Creates a non-closable, non-maximizable, non-iconifiable
 289      * {@code JInternalFrame} with the specified title
 290      * and resizability.
 291      *
 292      * @param title      the {@code String} to display in the title bar
 293      * @param resizable  if {@code true}, the internal frame can be resized
 294      */
 295     public JInternalFrame(String title, boolean resizable) {
 296         this(title, resizable, false, false, false);
 297     }
 298 
 299     /**
 300      * Creates a non-maximizable, non-iconifiable {@code JInternalFrame}
 301      * with the specified title, resizability, and
 302      * closability.
 303      *
 304      * @param title      the {@code String} to display in the title bar
 305      * @param resizable  if {@code true}, the internal frame can be resized
 306      * @param closable   if {@code true}, the internal frame can be closed
 307      */
 308     public JInternalFrame(String title, boolean resizable, boolean closable) {
 309         this(title, resizable, closable, false, false);
 310     }
 311 
 312     /**
 313      * Creates a non-iconifiable {@code JInternalFrame}
 314      * with the specified title,
 315      * resizability, closability, and maximizability.
 316      *
 317      * @param title       the {@code String} to display in the title bar
 318      * @param resizable   if {@code true}, the internal frame can be resized
 319      * @param closable    if {@code true}, the internal frame can be closed
 320      * @param maximizable if {@code true}, the internal frame can be maximized
 321      */
 322     public JInternalFrame(String title, boolean resizable, boolean closable,
 323                           boolean maximizable) {
 324         this(title, resizable, closable, maximizable, false);
 325     }
 326 
 327     /**
 328      * Creates a {@code JInternalFrame} with the specified title,
 329      * resizability, closability, maximizability, and iconifiability.
 330      * All {@code JInternalFrame} constructors use this one.
 331      *
 332      * @param title       the {@code String} to display in the title bar
 333      * @param resizable   if {@code true}, the internal frame can be resized
 334      * @param closable    if {@code true}, the internal frame can be closed
 335      * @param maximizable if {@code true}, the internal frame can be maximized
 336      * @param iconifiable if {@code true}, the internal frame can be iconified
 337      */
 338     public JInternalFrame(String title, boolean resizable, boolean closable,
 339                                 boolean maximizable, boolean iconifiable) {
 340 
 341         setRootPane(createRootPane());
 342         setLayout(new BorderLayout());
 343         this.title = title;
 344         this.resizable = resizable;
 345         this.closable = closable;
 346         this.maximizable = maximizable;
 347         isMaximum = false;
 348         this.iconable = iconifiable;
 349         isIcon = false;
 350         setVisible(false);
 351         setRootPaneCheckingEnabled(true);
 352         desktopIcon = new JDesktopIcon(this);
 353         updateUI();
 354         sun.awt.SunToolkit.checkAndSetPolicy(this);
 355         addPropertyChangeListenerIfNecessary();
 356     }
 357 
 358     /**
 359      * Called by the constructor to set up the {@code JRootPane}.
 360      * @return  a new {@code JRootPane}
 361      * @see JRootPane
 362      */
 363     protected JRootPane createRootPane() {
 364         return new JRootPane();
 365     }
 366 
 367     /**
 368      * Returns the look-and-feel object that renders this component.
 369      *
 370      * @return the {@code InternalFrameUI} object that renders
 371      *          this component
 372      */
 373     public InternalFrameUI getUI() {
 374         return (InternalFrameUI)ui;
 375     }
 376 
 377     /**
 378      * Sets the UI delegate for this {@code JInternalFrame}.
 379      * @param ui  the UI delegate
 380      * @beaninfo
 381      *        bound: true
 382      *       hidden: true
 383      *    attribute: visualUpdate true
 384      *  description: The UI object that implements the Component's LookAndFeel.
 385      */
 386     public void setUI(InternalFrameUI ui) {
 387         boolean checkingEnabled = isRootPaneCheckingEnabled();
 388         try {
 389             setRootPaneCheckingEnabled(false);
 390             super.setUI(ui);
 391         }
 392         finally {
 393             setRootPaneCheckingEnabled(checkingEnabled);
 394         }
 395     }
 396 
 397     /**
 398      * Notification from the {@code UIManager} that the look and feel
 399      * has changed.
 400      * Replaces the current UI object with the latest version from the
 401      * {@code UIManager}.
 402      *
 403      * @see JComponent#updateUI
 404      */
 405     public void updateUI() {
 406         setUI((InternalFrameUI)UIManager.getUI(this));
 407         invalidate();
 408         if (desktopIcon != null) {
 409             desktopIcon.updateUIWhenHidden();
 410         }
 411     }
 412 
 413     /* This method is called if {@code updateUI} was called
 414      * on the associated
 415      * JDesktopIcon.  It's necessary to avoid infinite recursion.
 416      */
 417     void updateUIWhenHidden() {
 418         setUI((InternalFrameUI)UIManager.getUI(this));
 419         invalidate();
 420         Component[] children = getComponents();
 421         if (children != null) {
 422             for (Component child : children) {
 423                 SwingUtilities.updateComponentTreeUI(child);
 424             }
 425         }
 426     }
 427 
 428 
 429     /**
 430      * Returns the name of the look-and-feel
 431      * class that renders this component.
 432      *
 433      * @return the string "InternalFrameUI"
 434      *
 435      * @see JComponent#getUIClassID
 436      * @see UIDefaults#getUI
 437      *
 438      * @beaninfo
 439      *     description: UIClassID
 440      */
 441     public String getUIClassID() {
 442         return uiClassID;
 443     }
 444 
 445     /**
 446      * Returns whether calls to {@code add} and
 447      * {@code setLayout} are forwarded to the {@code contentPane}.
 448      *
 449      * @return true if {@code add} and {@code setLayout}
 450      *         are forwarded; false otherwise
 451      *
 452      * @see #addImpl
 453      * @see #setLayout
 454      * @see #setRootPaneCheckingEnabled
 455      * @see javax.swing.RootPaneContainer
 456      */
 457     protected boolean isRootPaneCheckingEnabled() {
 458         return rootPaneCheckingEnabled;
 459     }
 460 
 461     /**
 462      * Sets whether calls to {@code add} and
 463      * {@code setLayout} are forwarded to the {@code contentPane}.
 464      *
 465      * @param enabled  true if {@code add} and {@code setLayout}
 466      *        are forwarded, false if they should operate directly on the
 467      *        {@code JInternalFrame}.
 468      *
 469      * @see #addImpl
 470      * @see #setLayout
 471      * @see #isRootPaneCheckingEnabled
 472      * @see javax.swing.RootPaneContainer
 473      * @beaninfo
 474      *      hidden: true
 475      * description: Whether the add and setLayout methods are forwarded
 476      */
 477     protected void setRootPaneCheckingEnabled(boolean enabled) {
 478         rootPaneCheckingEnabled = enabled;
 479     }
 480 
 481     /**
 482      * Adds the specified child {@code Component}.
 483      * This method is overridden to conditionally forward calls to the
 484      * {@code contentPane}.
 485      * By default, children are added to the {@code contentPane} instead
 486      * of the frame, refer to {@link javax.swing.RootPaneContainer} for
 487      * details.
 488      *
 489      * @param comp the component to be enhanced
 490      * @param constraints the constraints to be respected
 491      * @param index the index
 492      * @exception IllegalArgumentException if {@code index} is invalid
 493      * @exception IllegalArgumentException if adding the container's parent
 494      *                  to itself
 495      * @exception IllegalArgumentException if adding a window to a container
 496      *
 497      * @see #setRootPaneCheckingEnabled
 498      * @see javax.swing.RootPaneContainer
 499      */
 500     protected void addImpl(Component comp, Object constraints, int index) {
 501         if(isRootPaneCheckingEnabled()) {
 502             getContentPane().add(comp, constraints, index);
 503         }
 504         else {
 505             super.addImpl(comp, constraints, index);
 506         }
 507     }
 508 
 509     /**
 510      * Removes the specified component from the container. If
 511      * {@code comp} is not a child of the {@code JInternalFrame}
 512      * this will forward the call to the {@code contentPane}.
 513      *
 514      * @param comp the component to be removed
 515      * @throws NullPointerException if {@code comp} is null
 516      * @see #add
 517      * @see javax.swing.RootPaneContainer
 518      */
 519     public void remove(Component comp) {
 520         int oldCount = getComponentCount();
 521         super.remove(comp);
 522         if (oldCount == getComponentCount()) {
 523             getContentPane().remove(comp);
 524         }
 525     }
 526 
 527 
 528     /**
 529      * Ensures that, by default, the layout of this component cannot be set.
 530      * Overridden to conditionally forward the call to the
 531      * {@code contentPane}.
 532      * Refer to {@link javax.swing.RootPaneContainer} for
 533      * more information.
 534      *
 535      * @param manager the {@code LayoutManager}
 536      * @see #setRootPaneCheckingEnabled
 537      */
 538     public void setLayout(LayoutManager manager) {
 539         if(isRootPaneCheckingEnabled()) {
 540             getContentPane().setLayout(manager);
 541         }
 542         else {
 543             super.setLayout(manager);
 544         }
 545     }
 546 
 547 
 548 //////////////////////////////////////////////////////////////////////////
 549 /// Property Methods
 550 //////////////////////////////////////////////////////////////////////////
 551 
 552     /**
 553      * Returns the current {@code JMenuBar} for this
 554      * {@code JInternalFrame}, or {@code null}
 555      * if no menu bar has been set.
 556      * @return the current menu bar, or {@code null} if none has been set
 557      *
 558      * @deprecated As of Swing version 1.0.3,
 559      * replaced by {@code getJMenuBar()}.
 560      */
 561     @Deprecated
 562     public JMenuBar getMenuBar() {
 563       return getRootPane().getMenuBar();
 564     }
 565 
 566     /**
 567      * Returns the current {@code JMenuBar} for this
 568      * {@code JInternalFrame}, or {@code null}
 569      * if no menu bar has been set.
 570      *
 571      * @return  the {@code JMenuBar} used by this internal frame
 572      * @see #setJMenuBar
 573      */
 574     public JMenuBar getJMenuBar() {
 575         return getRootPane().getJMenuBar();
 576     }
 577 
 578     /**
 579      * Sets the {@code menuBar} property for this {@code JInternalFrame}.
 580      *
 581      * @param m  the {@code JMenuBar} to use in this internal frame
 582      * @see #getJMenuBar
 583      * @deprecated As of Swing version 1.0.3
 584      *  replaced by {@code setJMenuBar(JMenuBar m)}.
 585      */
 586     @Deprecated
 587     public void setMenuBar(JMenuBar m) {
 588         JMenuBar oldValue = getMenuBar();
 589         getRootPane().setJMenuBar(m);
 590         firePropertyChange(MENU_BAR_PROPERTY, oldValue, m);
 591     }
 592 
 593     /**
 594      * Sets the {@code menuBar} property for this {@code JInternalFrame}.
 595      *
 596      * @param m  the {@code JMenuBar} to use in this internal frame
 597      * @see #getJMenuBar
 598      * @beaninfo
 599      *     bound: true
 600      *     preferred: true
 601      *     description: The menu bar for accessing pulldown menus
 602      *                  from this internal frame.
 603      */
 604     public void setJMenuBar(JMenuBar m){
 605         JMenuBar oldValue = getMenuBar();
 606         getRootPane().setJMenuBar(m);
 607         firePropertyChange(MENU_BAR_PROPERTY, oldValue, m);
 608     }
 609 
 610     // implements javax.swing.RootPaneContainer
 611     /**
 612      * Returns the content pane for this internal frame.
 613      * @return the content pane
 614      */
 615     public Container getContentPane() {
 616         return getRootPane().getContentPane();
 617     }
 618 
 619 
 620     /**
 621      * Sets this {@code JInternalFrame}'s {@code contentPane}
 622      * property.
 623      *
 624      * @param c  the content pane for this internal frame
 625      *
 626      * @exception java.awt.IllegalComponentStateException (a runtime
 627      *           exception) if the content pane parameter is {@code null}
 628      * @see RootPaneContainer#getContentPane
 629      * @beaninfo
 630      *     bound: true
 631      *     hidden: true
 632      *     description: The client area of the internal frame where child
 633      *                  components are normally inserted.
 634      */
 635     public void setContentPane(Container c) {
 636         Container oldValue = getContentPane();
 637         getRootPane().setContentPane(c);
 638         firePropertyChange(CONTENT_PANE_PROPERTY, oldValue, c);
 639     }
 640 
 641     /**
 642      * Returns the layered pane for this internal frame.
 643      *
 644      * @return a {@code JLayeredPane} object
 645      * @see RootPaneContainer#setLayeredPane
 646      * @see RootPaneContainer#getLayeredPane
 647      */
 648     public JLayeredPane getLayeredPane() {
 649         return getRootPane().getLayeredPane();
 650     }
 651 
 652     /**
 653      * Sets this {@code JInternalFrame}'s
 654      * {@code layeredPane} property.
 655      *
 656      * @param layered the {@code JLayeredPane} for this internal frame
 657      *
 658      * @exception java.awt.IllegalComponentStateException (a runtime
 659      *           exception) if the layered pane parameter is {@code null}
 660      * @see RootPaneContainer#setLayeredPane
 661      * @beaninfo
 662      *     hidden: true
 663      *     bound: true
 664      *     description: The pane which holds the various desktop layers.
 665      */
 666     public void setLayeredPane(JLayeredPane layered) {
 667         JLayeredPane oldValue = getLayeredPane();
 668         getRootPane().setLayeredPane(layered);
 669         firePropertyChange(LAYERED_PANE_PROPERTY, oldValue, layered);
 670     }
 671 
 672     /**
 673      * Returns the glass pane for this internal frame.
 674      *
 675      * @return the glass pane
 676      * @see RootPaneContainer#setGlassPane
 677      */
 678     public Component getGlassPane() {
 679         return getRootPane().getGlassPane();
 680     }
 681 
 682     /**
 683      * Sets this {@code JInternalFrame}'s
 684      * {@code glassPane} property.
 685      *
 686      * @param glass the glass pane for this internal frame
 687      * @see RootPaneContainer#getGlassPane
 688      * @beaninfo
 689      *     bound: true
 690      *     hidden: true
 691      *     description: A transparent pane used for menu rendering.
 692      */
 693     public void setGlassPane(Component glass) {
 694         Component oldValue = getGlassPane();
 695         getRootPane().setGlassPane(glass);
 696         firePropertyChange(GLASS_PANE_PROPERTY, oldValue, glass);
 697     }
 698 
 699     /**
 700      * Returns the {@code rootPane} object for this internal frame.
 701      *
 702      * @return the {@code rootPane} property
 703      * @see RootPaneContainer#getRootPane
 704      */
 705     public JRootPane getRootPane() {
 706         return rootPane;
 707     }
 708 
 709 
 710     /**
 711      * Sets the {@code rootPane} property
 712      * for this {@code JInternalFrame}.
 713      * This method is called by the constructor.
 714      *
 715      * @param root  the new {@code JRootPane} object
 716      * @beaninfo
 717      *     bound: true
 718      *     hidden: true
 719      *     description: The root pane used by this internal frame.
 720      */
 721     protected void setRootPane(JRootPane root) {
 722         if(rootPane != null) {
 723             remove(rootPane);
 724         }
 725         JRootPane oldValue = getRootPane();
 726         rootPane = root;
 727         if(rootPane != null) {
 728             boolean checkingEnabled = isRootPaneCheckingEnabled();
 729             try {
 730                 setRootPaneCheckingEnabled(false);
 731                 add(rootPane, BorderLayout.CENTER);
 732             }
 733             finally {
 734                 setRootPaneCheckingEnabled(checkingEnabled);
 735             }
 736         }
 737         firePropertyChange(ROOT_PANE_PROPERTY, oldValue, root);
 738     }
 739 
 740     /**
 741      * Sets whether this {@code JInternalFrame} can be closed by
 742      * some user action.
 743      * @param b a boolean value, where {@code true} means this internal frame can be closed
 744      * @beaninfo
 745      *     preferred: true
 746      *           bound: true
 747      *     description: Indicates whether this internal frame can be closed.
 748      */
 749     public void setClosable(boolean b) {
 750         Boolean oldValue = closable ? Boolean.TRUE : Boolean.FALSE;
 751         Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
 752         closable = b;
 753         firePropertyChange("closable", oldValue, newValue);
 754     }
 755 
 756     /**
 757      * Returns whether this {@code JInternalFrame} can be closed by
 758      * some user action.
 759      * @return {@code true} if this internal frame can be closed
 760      */
 761     public boolean isClosable() {
 762         return closable;
 763     }
 764 
 765     /**
 766      * Returns whether this {@code JInternalFrame} is currently closed.
 767      * @return {@code true} if this internal frame is closed, {@code false} otherwise
 768      */
 769     public boolean isClosed() {
 770         return isClosed;
 771     }
 772 
 773     /**
 774      * Closes this internal frame if the argument is {@code true}.
 775      * Do not invoke this method with a {@code false} argument;
 776      * the result of invoking {@code setClosed(false)}
 777      * is unspecified.
 778      *
 779      * <p>
 780      *
 781      * If the internal frame is already closed,
 782      * this method does nothing and returns immediately.
 783      * Otherwise,
 784      * this method begins by firing
 785      * an {@code INTERNAL_FRAME_CLOSING} event.
 786      * Then this method sets the {@code closed} property to {@code true}
 787      * unless a listener vetoes the property change.
 788      * This method finishes by making the internal frame
 789      * invisible and unselected,
 790      * and then firing an {@code INTERNAL_FRAME_CLOSED} event.
 791      *
 792      * <p>
 793      *
 794      * <b>Note:</b>
 795      * To reuse an internal frame that has been closed,
 796      * you must add it to a container
 797      * (even if you never removed it from its previous container).
 798      * Typically, this container will be the {@code JDesktopPane}
 799      * that previously contained the internal frame.
 800      *
 801      * @param b must be {@code true}
 802      *
 803      * @exception PropertyVetoException when the attempt to set the
 804      *            property is vetoed by the {@code JInternalFrame}
 805      *
 806      * @see #isClosed()
 807      * @see #setDefaultCloseOperation
 808      * @see #dispose
 809      * @see javax.swing.event.InternalFrameEvent#INTERNAL_FRAME_CLOSING
 810      *
 811      * @beaninfo
 812      *           bound: true
 813      *     constrained: true
 814      *     description: Indicates whether this internal frame has been closed.
 815      */
 816     public void setClosed(boolean b) throws PropertyVetoException {
 817         if (isClosed == b) {
 818             return;
 819         }
 820 
 821         Boolean oldValue = isClosed ? Boolean.TRUE : Boolean.FALSE;
 822         Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
 823         if (b) {
 824           fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_CLOSING);
 825         }
 826         fireVetoableChange(IS_CLOSED_PROPERTY, oldValue, newValue);
 827         isClosed = b;
 828         if (isClosed) {
 829           setVisible(false);
 830         }
 831         firePropertyChange(IS_CLOSED_PROPERTY, oldValue, newValue);
 832         if (isClosed) {
 833           dispose();
 834         } else if (!opened) {
 835           /* this bogus -- we haven't defined what
 836              setClosed(false) means. */
 837           //        fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_OPENED);
 838           //            opened = true;
 839         }
 840     }
 841 
 842     /**
 843      * Sets whether the {@code JInternalFrame} can be resized by some
 844      * user action.
 845      *
 846      * @param b  a boolean, where {@code true} means this internal frame can be resized
 847      * @beaninfo
 848      *     preferred: true
 849      *           bound: true
 850      *     description: Determines whether this internal frame can be resized
 851      *                  by the user.
 852      */
 853     public void setResizable(boolean b) {
 854         Boolean oldValue = resizable ? Boolean.TRUE : Boolean.FALSE;
 855         Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
 856         resizable = b;
 857         firePropertyChange("resizable", oldValue, newValue);
 858     }
 859 
 860     /**
 861      * Returns whether the {@code JInternalFrame} can be resized
 862      * by some user action.
 863      *
 864      * @return {@code true} if this internal frame can be resized, {@code false} otherwise
 865      */
 866     public boolean isResizable() {
 867         // don't allow resizing when maximized.
 868         return isMaximum ? false : resizable;
 869     }
 870 
 871     /**
 872      * Sets the {@code iconable} property,
 873      * which must be {@code true}
 874      * for the user to be able to
 875      * make the {@code JInternalFrame} an icon.
 876      * Some look and feels might not implement iconification;
 877      * they will ignore this property.
 878      *
 879      * @param b  a boolean, where {@code true} means this internal frame can be iconified
 880      * @beaninfo
 881      *     preferred: true
 882                bound: true
 883      *     description: Determines whether this internal frame can be iconified.
 884      */
 885     public void setIconifiable(boolean b) {
 886         Boolean oldValue = iconable ? Boolean.TRUE : Boolean.FALSE;
 887         Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
 888         iconable = b;
 889         firePropertyChange("iconable", oldValue, newValue);
 890     }
 891 
 892     /**
 893      * Gets the {@code iconable} property,
 894      * which by default is {@code false}.
 895      *
 896      * @return the value of the {@code iconable} property.
 897      *
 898      * @see #setIconifiable
 899      */
 900     public boolean isIconifiable() {
 901         return iconable;
 902     }
 903 
 904     /**
 905      * Returns whether the {@code JInternalFrame} is currently iconified.
 906      *
 907      * @return {@code true} if this internal frame is iconified
 908      */
 909     public boolean isIcon() {
 910         return isIcon;
 911     }
 912 
 913     /**
 914      * Iconifies or de-iconifies this internal frame,
 915      * if the look and feel supports iconification.
 916      * If the internal frame's state changes to iconified,
 917      * this method fires an {@code INTERNAL_FRAME_ICONIFIED} event.
 918      * If the state changes to de-iconified,
 919      * an {@code INTERNAL_FRAME_DEICONIFIED} event is fired.
 920      *
 921      * @param b a boolean, where {@code true} means to iconify this internal frame and
 922      *          {@code false} means to de-iconify it
 923      * @exception PropertyVetoException when the attempt to set the
 924      *            property is vetoed by the {@code JInternalFrame}
 925      *
 926      * @see InternalFrameEvent#INTERNAL_FRAME_ICONIFIED
 927      * @see InternalFrameEvent#INTERNAL_FRAME_DEICONIFIED
 928      *
 929      * @beaninfo
 930      *           bound: true
 931      *     constrained: true
 932      *     description: The image displayed when this internal frame is minimized.
 933      */
 934     public void setIcon(boolean b) throws PropertyVetoException {
 935         if (isIcon == b) {
 936             return;
 937         }
 938 
 939         /* If an internal frame is being iconified before it has a
 940            parent, (e.g., client wants it to start iconic), create the
 941            parent if possible so that we can place the icon in its
 942            proper place on the desktop. I am not sure the call to
 943            validate() is necessary, since we are not going to display
 944            this frame yet */
 945         firePropertyChange("ancestor", null, getParent());
 946 
 947         Boolean oldValue = isIcon ? Boolean.TRUE : Boolean.FALSE;
 948         Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
 949         fireVetoableChange(IS_ICON_PROPERTY, oldValue, newValue);
 950         isIcon = b;
 951         firePropertyChange(IS_ICON_PROPERTY, oldValue, newValue);
 952         if (b)
 953           fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_ICONIFIED);
 954         else
 955           fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_DEICONIFIED);
 956     }
 957 
 958     /**
 959      * Sets the {@code maximizable} property,
 960      * which determines whether the {@code JInternalFrame}
 961      * can be maximized by
 962      * some user action.
 963      * Some look and feels might not support maximizing internal frames;
 964      * they will ignore this property.
 965      *
 966      * @param b {@code true} to specify that this internal frame should be maximizable; {@code false} to specify that it should not be
 967      * @beaninfo
 968      *         bound: true
 969      *     preferred: true
 970      *     description: Determines whether this internal frame can be maximized.
 971      */
 972     public void setMaximizable(boolean b) {
 973         Boolean oldValue = maximizable ? Boolean.TRUE : Boolean.FALSE;
 974         Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
 975         maximizable = b;
 976         firePropertyChange("maximizable", oldValue, newValue);
 977     }
 978 
 979     /**
 980      * Gets the value of the {@code maximizable} property.
 981      *
 982      * @return the value of the {@code maximizable} property
 983      * @see #setMaximizable
 984      */
 985     public boolean isMaximizable() {
 986         return maximizable;
 987     }
 988 
 989     /**
 990      * Returns whether the {@code JInternalFrame} is currently maximized.
 991      *
 992      * @return {@code true} if this internal frame is maximized, {@code false} otherwise
 993      */
 994     public boolean isMaximum() {
 995         return isMaximum;
 996     }
 997 
 998     /**
 999      * Maximizes and restores this internal frame.  A maximized frame is resized to
1000      * fully fit the {@code JDesktopPane} area associated with the
1001      * {@code JInternalFrame}.
1002      * A restored frame's size is set to the {@code JInternalFrame}'s
1003      * actual size.
1004      *
1005      * @param b  a boolean, where {@code true} maximizes this internal frame and {@code false}
1006      *           restores it
1007      * @exception PropertyVetoException when the attempt to set the
1008      *            property is vetoed by the {@code JInternalFrame}
1009      * @beaninfo
1010      *     bound: true
1011      *     constrained: true
1012      *     description: Indicates whether this internal frame is maximized.
1013      */
1014     public void setMaximum(boolean b) throws PropertyVetoException {
1015         if (isMaximum == b) {
1016             return;
1017         }
1018 
1019         Boolean oldValue = isMaximum ? Boolean.TRUE : Boolean.FALSE;
1020         Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
1021         fireVetoableChange(IS_MAXIMUM_PROPERTY, oldValue, newValue);
1022         /* setting isMaximum above the event firing means that
1023            property listeners that, for some reason, test it will
1024            get it wrong... See, for example, getNormalBounds() */
1025         isMaximum = b;
1026         firePropertyChange(IS_MAXIMUM_PROPERTY, oldValue, newValue);
1027     }
1028 
1029     /**
1030      * Returns the title of the {@code JInternalFrame}.
1031      *
1032      * @return a {@code String} containing this internal frame's title
1033      * @see #setTitle
1034      */
1035     public String getTitle() {
1036         return title;
1037     }
1038 
1039     /**
1040      * Sets the {@code JInternalFrame} title. {@code title}
1041      * may have a {@code null} value.
1042      * @see #getTitle
1043      *
1044      * @param title  the {@code String} to display in the title bar
1045      * @beaninfo
1046      *     preferred: true
1047      *     bound: true
1048      *     description: The text displayed in the title bar.
1049      */
1050     public void setTitle(String title) {
1051         String oldValue = this.title;
1052         this.title = title;
1053         firePropertyChange(TITLE_PROPERTY, oldValue, title);
1054     }
1055 
1056     /**
1057      * Selects or deselects the internal frame
1058      * if it's showing.
1059      * A {@code JInternalFrame} normally draws its title bar
1060      * differently if it is
1061      * the selected frame, which indicates to the user that this
1062      * internal frame has the focus.
1063      * When this method changes the state of the internal frame
1064      * from deselected to selected, it fires an
1065      * {@code InternalFrameEvent.INTERNAL_FRAME_ACTIVATED} event.
1066      * If the change is from selected to deselected,
1067      * an {@code InternalFrameEvent.INTERNAL_FRAME_DEACTIVATED} event
1068      * is fired.
1069      *
1070      * @param selected  a boolean, where {@code true} means this internal frame
1071      *                  should become selected (currently active)
1072      *                  and {@code false} means it should become deselected
1073      * @exception PropertyVetoException when the attempt to set the
1074      *            property is vetoed by the {@code JInternalFrame}
1075      *
1076      * @see #isShowing
1077      * @see InternalFrameEvent#INTERNAL_FRAME_ACTIVATED
1078      * @see InternalFrameEvent#INTERNAL_FRAME_DEACTIVATED
1079      *
1080      * @beaninfo
1081      *     constrained: true
1082      *           bound: true
1083      *     description: Indicates whether this internal frame is currently
1084      *                  the active frame.
1085      */
1086     public void setSelected(boolean selected) throws PropertyVetoException {
1087        // The InternalFrame may already be selected, but the focus
1088        // may be outside it, so restore the focus to the subcomponent
1089        // which previously had it. See Bug 4302764.
1090         if (selected && isSelected) {
1091             restoreSubcomponentFocus();
1092             return;
1093         }
1094         // The internal frame or the desktop icon must be showing to allow


1110            want focus, then it will get transfered there later.
1111 
1112            We test for parent.isShowing() above, because AWT throws a
1113            NPE if you try to request focus on a lightweight before its
1114            parent has been made visible */
1115 
1116         if (selected) {
1117             restoreSubcomponentFocus();
1118         }
1119 
1120         isSelected = selected;
1121         firePropertyChange(IS_SELECTED_PROPERTY, oldValue, newValue);
1122         if (isSelected)
1123           fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_ACTIVATED);
1124         else
1125           fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_DEACTIVATED);
1126         repaint();
1127     }
1128 
1129     /**
1130      * Returns whether the {@code JInternalFrame} is the
1131      * currently "selected" or active frame.
1132      *
1133      * @return {@code true} if this internal frame is currently selected (active)
1134      * @see #setSelected
1135      */
1136     public boolean isSelected() {
1137         return isSelected;
1138     }
1139 
1140     /**
1141      * Sets an image to be displayed in the titlebar of this internal frame (usually
1142      * in the top-left corner).
1143      * Some look and feels might not support displaying an icon in the titlebar.
1144      *
1145      * This image is not the {@code desktopIcon} object, which
1146      * is the image displayed in the {@code JDesktop} when
1147      * this internal frame is iconified.
1148      *
1149      * Passing {@code null} to this function is valid,
1150      * but the look and feel can choose the appropriate behavior
1151      * for that situation, such as displaying no icon
1152      * or a default icon for the look and feel.
1153      *
1154      * @param icon the {@code Icon} to display in the title bar
1155      * @see #getFrameIcon
1156      * @beaninfo
1157      *           bound: true
1158      *     description: The icon shown in the top-left corner of this internal frame.
1159      */
1160   public void setFrameIcon(Icon icon) {
1161         Icon oldIcon = frameIcon;
1162         frameIcon = icon;
1163         firePropertyChange(FRAME_ICON_PROPERTY, oldIcon, icon);
1164     }
1165 
1166     /**
1167      * Returns the image displayed in the title bar of this internal frame (usually
1168      * in the top-left corner).
1169      *
1170      * @return the {@code Icon} displayed in the title bar
1171      * @see #setFrameIcon
1172      */
1173     public Icon getFrameIcon()  {
1174         return frameIcon;
1175     }
1176 
1177     /**
1178       * Convenience method that moves this component to position 0 if its
1179       * parent is a {@code JLayeredPane}.
1180       */
1181     public void moveToFront() {
1182         if (isIcon()) {
1183             if (getDesktopIcon().getParent() instanceof JLayeredPane) {
1184                 ((JLayeredPane)getDesktopIcon().getParent()).
1185                     moveToFront(getDesktopIcon());
1186             }
1187         }
1188         else if (getParent() instanceof JLayeredPane) {
1189             ((JLayeredPane)getParent()).moveToFront(this);
1190         }
1191     }
1192 
1193     /**
1194       * Convenience method that moves this component to position -1 if its
1195       * parent is a {@code JLayeredPane}.
1196       */
1197     public void moveToBack() {
1198         if (isIcon()) {
1199             if (getDesktopIcon().getParent() instanceof JLayeredPane) {
1200                 ((JLayeredPane)getDesktopIcon().getParent()).
1201                     moveToBack(getDesktopIcon());
1202             }
1203         }
1204         else if (getParent() instanceof JLayeredPane) {
1205             ((JLayeredPane)getParent()).moveToBack(this);
1206         }
1207     }
1208 
1209     /**
1210      * Returns the last {@code Cursor} that was set by the
1211      * {@code setCursor} method that is not a resizable
1212      * {@code Cursor}.
1213      *
1214      * @return the last non-resizable {@code Cursor}
1215      * @since 1.6
1216      */
1217     public Cursor getLastCursor() {
1218         return lastCursor;
1219     }
1220 
1221     /**
1222      * {@inheritDoc}
1223      * @since 1.6
1224      */
1225     public void setCursor(Cursor cursor) {
1226         if (cursor == null) {
1227             lastCursor = null;
1228             super.setCursor(cursor);
1229             return;
1230         }
1231         int type = cursor.getType();
1232         if (!(type == Cursor.SW_RESIZE_CURSOR  ||
1233               type == Cursor.SE_RESIZE_CURSOR  ||
1234               type == Cursor.NW_RESIZE_CURSOR  ||
1235               type == Cursor.NE_RESIZE_CURSOR  ||
1236               type == Cursor.N_RESIZE_CURSOR   ||
1237               type == Cursor.S_RESIZE_CURSOR   ||
1238               type == Cursor.W_RESIZE_CURSOR   ||
1239               type == Cursor.E_RESIZE_CURSOR)) {
1240             lastCursor = cursor;
1241         }
1242         super.setCursor(cursor);
1243     }
1244 
1245     /**
1246      * Convenience method for setting the layer attribute of this component.
1247      *
1248      * @param layer  an {@code Integer} object specifying this
1249      *          frame's desktop layer
1250      * @throws NullPointerException if {@code layer} is {@code null}
1251      * @see JLayeredPane
1252      * @beaninfo
1253      *     expert: true
1254      *     description: Specifies what desktop layer is used.
1255      */
1256     public void setLayer(Integer layer) {
1257         if(getParent() != null && getParent() instanceof JLayeredPane) {
1258             // Normally we want to do this, as it causes the LayeredPane
1259             // to draw properly.
1260             JLayeredPane p = (JLayeredPane)getParent();
1261             p.setLayer(this, layer.intValue(), p.getPosition(this));
1262         } else {
1263              // Try to do the right thing
1264              JLayeredPane.putLayer(this, layer.intValue());
1265              if(getParent() != null)
1266                  getParent().repaint(getX(), getY(), getWidth(), getHeight());
1267         }
1268     }
1269 
1270     /**
1271      * Convenience method for setting the layer attribute of this component.
1272      * The method {@code setLayer(Integer)} should be used for
1273      * layer values predefined in {@code JLayeredPane}.
1274      * When using {@code setLayer(int)}, care must be taken not to
1275      * accidentally clash with those values.
1276      *
1277      * @param layer  an integer specifying this internal frame's desktop layer
1278      *
1279      * @since 1.3
1280      *
1281      * @see #setLayer(Integer)
1282      * @see JLayeredPane
1283      * @beaninfo
1284      *     expert: true
1285      *     description: Specifies what desktop layer is used.
1286      */
1287     public void setLayer(int layer) {
1288       this.setLayer(Integer.valueOf(layer));
1289     }
1290 
1291     /**
1292      * Convenience method for getting the layer attribute of this component.
1293      *
1294      * @return  an {@code Integer} object specifying this
1295      *          frame's desktop layer
1296      * @see JLayeredPane
1297       */
1298     public int getLayer() {
1299         return JLayeredPane.getLayer(this);
1300     }
1301 
1302     /**
1303       * Convenience method that searches the ancestor hierarchy for a
1304       * {@code JDesktop} instance. If {@code JInternalFrame}
1305       * finds none, the {@code desktopIcon} tree is searched.
1306       *
1307       * @return the {@code JDesktopPane} this internal frame belongs to,
1308       *         or {@code null} if none is found
1309       */
1310     public JDesktopPane getDesktopPane() {
1311         Container p;
1312 
1313         // Search upward for desktop
1314         p = getParent();
1315         while(p != null && !(p instanceof JDesktopPane))
1316             p = p.getParent();
1317 
1318         if(p == null) {
1319            // search its icon parent for desktop
1320            p = getDesktopIcon().getParent();
1321            while(p != null && !(p instanceof JDesktopPane))
1322                 p = p.getParent();
1323         }
1324 
1325         return (JDesktopPane)p;
1326     }
1327 
1328     /**
1329      * Sets the {@code JDesktopIcon} associated with this
1330      * {@code JInternalFrame}.
1331      *
1332      * @param d the {@code JDesktopIcon} to display on the desktop
1333      * @see #getDesktopIcon
1334      * @beaninfo
1335      *           bound: true
1336      *     description: The icon shown when this internal frame is minimized.
1337      */
1338     public void setDesktopIcon(JDesktopIcon d) {
1339         JDesktopIcon oldValue = getDesktopIcon();
1340         desktopIcon = d;
1341         firePropertyChange("desktopIcon", oldValue, d);
1342     }
1343 
1344     /**
1345      * Returns the {@code JDesktopIcon} used when this
1346      * {@code JInternalFrame} is iconified.
1347      *
1348      * @return the {@code JDesktopIcon} displayed on the desktop
1349      * @see #setDesktopIcon
1350      */
1351     public JDesktopIcon getDesktopIcon() {
1352         return desktopIcon;
1353     }
1354 
1355     /**
1356      * If the {@code JInternalFrame} is not in maximized state, returns
1357      * {@code getBounds()}; otherwise, returns the bounds that the
1358      * {@code JInternalFrame} would be restored to.
1359      *
1360      * @return a {@code Rectangle} containing the bounds of this
1361      *          frame when in the normal state
1362      * @since 1.3
1363      */
1364     public Rectangle getNormalBounds() {
1365 
1366       /* we used to test (!isMaximum) here, but since this
1367          method is used by the property listener for the
1368          IS_MAXIMUM_PROPERTY, it ended up getting the wrong
1369          answer... Since normalBounds get set to null when the
1370          frame is restored, this should work better */
1371 
1372       if (normalBounds != null) {
1373         return normalBounds;
1374       } else {
1375         return getBounds();
1376       }
1377     }
1378 
1379     /**
1380      * Sets the normal bounds for this internal frame, the bounds that
1381      * this internal frame would be restored to from its maximized state.
1382      * This method is intended for use only by desktop managers.
1383      *
1384      * @param r the bounds that this internal frame should be restored to
1385      * @since 1.3
1386      */
1387     public void setNormalBounds(Rectangle r) {
1388         normalBounds = r;
1389     }
1390 
1391     /**
1392      * If this {@code JInternalFrame} is active,
1393      * returns the child that has focus.
1394      * Otherwise, returns {@code null}.
1395      *
1396      * @return the component with focus, or {@code null} if no children have focus
1397      * @since 1.3
1398      */
1399     public Component getFocusOwner() {
1400         if (isSelected()) {
1401             return lastFocusOwner;
1402         }
1403         return null;
1404     }
1405 
1406     /**
1407      * Returns the child component of this {@code JInternalFrame}
1408      * that will receive the
1409      * focus when this {@code JInternalFrame} is selected.
1410      * If this {@code JInternalFrame} is
1411      * currently selected, this method returns the same component as
1412      * the {@code getFocusOwner} method.
1413      * If this {@code JInternalFrame} is not selected,
1414      * then the child component that most recently requested focus will be
1415      * returned. If no child component has ever requested focus, then this
1416      * {@code JInternalFrame}'s initial focusable component is returned.
1417      * If no such
1418      * child exists, then this {@code JInternalFrame}'s default component
1419      * to focus is returned.
1420      *
1421      * @return the child component that will receive focus when this
1422      *         {@code JInternalFrame} is selected
1423      * @see #getFocusOwner
1424      * @see #isSelected
1425      * @since 1.4
1426      */
1427     public Component getMostRecentFocusOwner() {
1428         if (isSelected()) {
1429             return getFocusOwner();
1430         }
1431 
1432         if (lastFocusOwner != null) {
1433             return lastFocusOwner;
1434         }
1435 
1436         FocusTraversalPolicy policy = getFocusTraversalPolicy();
1437         if (policy instanceof InternalFrameFocusTraversalPolicy) {
1438             return ((InternalFrameFocusTraversalPolicy)policy).
1439                 getInitialComponent(this);
1440         }
1441 
1442         Component toFocus = policy.getDefaultComponent(this);


1511      *
1512      * @param l the internal frame listener
1513      */
1514     public void addInternalFrameListener(InternalFrameListener l) {  // remind: sync ??
1515       listenerList.add(InternalFrameListener.class, l);
1516       // remind: needed?
1517       enableEvents(0);   // turn on the newEventsOnly flag in Component.
1518     }
1519 
1520     /**
1521      * Removes the specified internal frame listener so that it no longer
1522      * receives internal frame events from this internal frame.
1523      *
1524      * @param l the internal frame listener
1525      */
1526     public void removeInternalFrameListener(InternalFrameListener l) {  // remind: sync??
1527       listenerList.remove(InternalFrameListener.class, l);
1528     }
1529 
1530     /**
1531      * Returns an array of all the {@code InternalFrameListener}s added
1532      * to this {@code JInternalFrame} with
1533      * {@code addInternalFrameListener}.
1534      *
1535      * @return all of the {@code InternalFrameListener}s added or an empty
1536      *         array if no listeners have been added
1537      * @since 1.4
1538      *
1539      * @see #addInternalFrameListener
1540      */
1541     public InternalFrameListener[] getInternalFrameListeners() {
1542         return listenerList.getListeners(InternalFrameListener.class);
1543     }
1544 
1545     // remind: name ok? all one method ok? need to be synchronized?
1546     /**
1547      * Fires an internal frame event.
1548      *
1549      * @param id  the type of the event being fired; one of the following:
1550      * <ul>
1551      * <li>{@code InternalFrameEvent.INTERNAL_FRAME_OPENED}
1552      * <li>{@code InternalFrameEvent.INTERNAL_FRAME_CLOSING}
1553      * <li>{@code InternalFrameEvent.INTERNAL_FRAME_CLOSED}
1554      * <li>{@code InternalFrameEvent.INTERNAL_FRAME_ICONIFIED}
1555      * <li>{@code InternalFrameEvent.INTERNAL_FRAME_DEICONIFIED}
1556      * <li>{@code InternalFrameEvent.INTERNAL_FRAME_ACTIVATED}
1557      * <li>{@code InternalFrameEvent.INTERNAL_FRAME_DEACTIVATED}
1558      * </ul>
1559      * If the event type is not one of the above, nothing happens.
1560      */
1561     protected void fireInternalFrameEvent(int id){
1562       Object[] listeners = listenerList.getListenerList();
1563       InternalFrameEvent e = null;
1564       for (int i = listeners.length -2; i >=0; i -= 2){
1565         if (listeners[i] == InternalFrameListener.class){
1566           if (e == null){
1567             e = new InternalFrameEvent(this, id);
1568             //      System.out.println("InternalFrameEvent: " + e.paramString());
1569           }
1570           switch(e.getID()) {
1571           case InternalFrameEvent.INTERNAL_FRAME_OPENED:
1572             ((InternalFrameListener)listeners[i+1]).internalFrameOpened(e);
1573             break;
1574           case InternalFrameEvent.INTERNAL_FRAME_CLOSING:
1575             ((InternalFrameListener)listeners[i+1]).internalFrameClosing(e);
1576             break;
1577           case InternalFrameEvent.INTERNAL_FRAME_CLOSED:


1586           case InternalFrameEvent.INTERNAL_FRAME_ACTIVATED:
1587             ((InternalFrameListener)listeners[i+1]).internalFrameActivated(e);
1588             break;
1589           case InternalFrameEvent.INTERNAL_FRAME_DEACTIVATED:
1590             ((InternalFrameListener)listeners[i+1]).internalFrameDeactivated(e);
1591             break;
1592           default:
1593             break;
1594           }
1595         }
1596       }
1597       /* we could do it off the event, but at the moment, that's not how
1598          I'm implementing it */
1599       //      if (id == InternalFrameEvent.INTERNAL_FRAME_CLOSING) {
1600       //          doDefaultCloseAction();
1601       //      }
1602     }
1603 
1604     /**
1605      * Fires an
1606      * {@code INTERNAL_FRAME_CLOSING} event
1607      * and then performs the action specified by
1608      * the internal frame's default close operation.
1609      * This method is typically invoked by the
1610      * look-and-feel-implemented action handler
1611      * for the internal frame's close button.
1612      *
1613      * @since 1.3
1614      * @see #setDefaultCloseOperation
1615      * @see javax.swing.event.InternalFrameEvent#INTERNAL_FRAME_CLOSING
1616      */
1617     public void doDefaultCloseAction() {
1618         fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_CLOSING);
1619         switch(defaultCloseOperation) {
1620           case DO_NOTHING_ON_CLOSE:
1621             break;
1622           case HIDE_ON_CLOSE:
1623             setVisible(false);
1624             if (isSelected())
1625                 try {
1626                     setSelected(false);


1634                 fireVetoableChange(IS_CLOSED_PROPERTY, Boolean.FALSE,
1635                                    Boolean.TRUE);
1636                 isClosed = true;
1637                 setVisible(false);
1638                 firePropertyChange(IS_CLOSED_PROPERTY, Boolean.FALSE,
1639                                    Boolean.TRUE);
1640                 dispose();
1641               } catch (PropertyVetoException pve) {}
1642               break;
1643           default:
1644               break;
1645         }
1646     }
1647 
1648     /**
1649      * Sets the operation that will happen by default when
1650      * the user initiates a "close" on this internal frame.
1651      * The possible choices are:
1652      * <br><br>
1653      * <dl>
1654      * <dt>{@code DO_NOTHING_ON_CLOSE}
1655      * <dd> Do nothing.
1656      *      This requires the program to handle the operation
1657      *      in the {@code internalFrameClosing} method
1658      *      of a registered {@code InternalFrameListener} object.
1659      * <dt>{@code HIDE_ON_CLOSE}
1660      * <dd> Automatically make the internal frame invisible.
1661      * <dt>{@code DISPOSE_ON_CLOSE}
1662      * <dd> Automatically dispose of the internal frame.
1663      * </dl>
1664      * <p>
1665      * The default value is {@code DISPOSE_ON_CLOSE}.
1666      * Before performing the specified close operation,
1667      * the internal frame fires
1668      * an {@code INTERNAL_FRAME_CLOSING} event.
1669      *
1670      * @param operation one of the following constants defined in
1671      *                  {@code javax.swing.WindowConstants}
1672      *                  (an interface implemented by
1673      *                  {@code JInternalFrame}):
1674      *                  {@code DO_NOTHING_ON_CLOSE},
1675      *                  {@code HIDE_ON_CLOSE}, or
1676      *                  {@code DISPOSE_ON_CLOSE}
1677      *
1678      * @see #addInternalFrameListener
1679      * @see #getDefaultCloseOperation
1680      * @see #setVisible
1681      * @see #dispose
1682      * @see InternalFrameEvent#INTERNAL_FRAME_CLOSING
1683      */
1684     public void setDefaultCloseOperation(int operation) {
1685         this.defaultCloseOperation = operation;
1686     }
1687 
1688    /**
1689     * Returns the default operation that occurs when the user
1690     * initiates a "close" on this internal frame.
1691     * @return the operation that will occur when the user closes the internal
1692     *         frame
1693     * @see #setDefaultCloseOperation
1694     */
1695     public int getDefaultCloseOperation() {
1696         return defaultCloseOperation;
1697     }
1698 
1699     /**
1700      * Causes subcomponents of this {@code JInternalFrame}
1701      * to be laid out at their preferred size.  Internal frames that are
1702      * iconized or maximized are first restored and then packed.  If the
1703      * internal frame is unable to be restored its state is not changed
1704      * and will not be packed.
1705      *
1706      * @see       java.awt.Window#pack
1707      */
1708     public void pack() {
1709         try {
1710             if (isIcon()) {
1711                 setIcon(false);
1712             } else if (isMaximum()) {
1713                 setMaximum(false);
1714             }
1715         } catch(PropertyVetoException e) {
1716             return;
1717         }
1718         setSize(getPreferredSize());
1719         validate();
1720     }
1721 
1722     /**
1723      * If the internal frame is not visible,
1724      * brings the internal frame to the front,
1725      * makes it visible,
1726      * and attempts to select it.
1727      * The first time the internal frame is made visible,
1728      * this method also fires an {@code INTERNAL_FRAME_OPENED} event.
1729      * This method does nothing if the internal frame is already visible.
1730      * Invoking this method
1731      * has the same result as invoking
1732      * {@code setVisible(true)}.
1733      *
1734      * @see #moveToFront
1735      * @see #setSelected
1736      * @see InternalFrameEvent#INTERNAL_FRAME_OPENED
1737      * @see #setVisible
1738      */
1739     @SuppressWarnings("deprecation")
1740     public void show() {
1741         // bug 4312922
1742         if (isVisible()) {
1743             //match the behavior of setVisible(true): do nothing
1744             return;
1745         }
1746 
1747         // bug 4149505
1748         if (!opened) {
1749           fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_OPENED);
1750           opened = true;
1751         }
1752 


1764         if (!isSelected()) {
1765             try {
1766                 setSelected(true);
1767             } catch (PropertyVetoException pve) {}
1768         }
1769     }
1770 
1771     @SuppressWarnings("deprecation")
1772     public void hide() {
1773         if (isIcon()) {
1774             getDesktopIcon().setVisible(false);
1775         }
1776         super.hide();
1777     }
1778 
1779     /**
1780      * Makes this internal frame
1781      * invisible, unselected, and closed.
1782      * If the frame is not already closed,
1783      * this method fires an
1784      * {@code INTERNAL_FRAME_CLOSED} event.
1785      * The results of invoking this method are similar to
1786      * {@code setClosed(true)},
1787      * but {@code dispose} always succeeds in closing
1788      * the internal frame and does not fire
1789      * an {@code INTERNAL_FRAME_CLOSING} event.
1790      *
1791      * @see javax.swing.event.InternalFrameEvent#INTERNAL_FRAME_CLOSED
1792      * @see #setVisible
1793      * @see #setSelected
1794      * @see #setClosed
1795      */
1796     public void dispose() {
1797         if (isVisible()) {
1798             setVisible(false);
1799         }
1800         if (isSelected()) {
1801             try {
1802                 setSelected(false);
1803             } catch (PropertyVetoException pve) {}
1804         }
1805         if (!isClosed) {
1806           firePropertyChange(IS_CLOSED_PROPERTY, Boolean.FALSE, Boolean.TRUE);
1807           isClosed = true;
1808         }
1809         fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_CLOSED);


1819      * @see       #moveToFront
1820      */
1821     public void toFront() {
1822         moveToFront();
1823     }
1824 
1825     /**
1826      * Sends this internal frame to the back.
1827      * Places this internal frame at the bottom of the stacking order
1828      * and makes the corresponding adjustment to other visible
1829      * internal frames.
1830      *
1831      * @see       java.awt.Window#toBack
1832      * @see       #moveToBack
1833      */
1834     public void toBack() {
1835         moveToBack();
1836     }
1837 
1838     /**
1839      * Does nothing because {@code JInternalFrame}s must always be roots of a focus
1840      * traversal cycle.
1841      *
1842      * @param focusCycleRoot this value is ignored
1843      * @see #isFocusCycleRoot
1844      * @see java.awt.Container#setFocusTraversalPolicy
1845      * @see java.awt.Container#getFocusTraversalPolicy
1846      * @since 1.4
1847      */
1848     public final void setFocusCycleRoot(boolean focusCycleRoot) {
1849     }
1850 
1851     /**
1852      * Always returns {@code true} because all {@code JInternalFrame}s must be
1853      * roots of a focus traversal cycle.
1854      *
1855      * @return {@code true}
1856      * @see #setFocusCycleRoot
1857      * @see java.awt.Container#setFocusTraversalPolicy
1858      * @see java.awt.Container#getFocusTraversalPolicy
1859      * @since 1.4
1860      */
1861     public final boolean isFocusCycleRoot() {
1862         return true;
1863     }
1864 
1865     /**
1866      * Always returns {@code null} because {@code JInternalFrame}s
1867      * must always be roots of a focus
1868      * traversal cycle.
1869      *
1870      * @return {@code null}
1871      * @see java.awt.Container#isFocusCycleRoot()
1872      * @since 1.4
1873      */
1874     public final Container getFocusCycleRootAncestor() {
1875         return null;
1876     }
1877 
1878     /**
1879      * Gets the warning string that is displayed with this internal frame.
1880      * Since an internal frame is always secure (since it's fully
1881      * contained within a window that might need a warning string)
1882      * this method always returns {@code null}.
1883      * @return    {@code null}
1884      * @see       java.awt.Window#getWarningString
1885      */
1886     public final String getWarningString() {
1887         return null;
1888     }
1889 
1890     /**
1891      * See {@code readObject} and {@code writeObject}
1892      * in {@code JComponent} for more
1893      * information about serialization in Swing.
1894      */
1895     private void writeObject(ObjectOutputStream s) throws IOException {
1896         s.defaultWriteObject();
1897         if (getUIClassID().equals(uiClassID)) {
1898             byte count = JComponent.getWriteObjCounter(this);
1899             JComponent.setWriteObjCounter(this, --count);
1900             if (count == 0 && ui != null) {
1901                 boolean old = isRootPaneCheckingEnabled();
1902                 try {
1903                     setRootPaneCheckingEnabled(false);
1904                     ui.installUI(this);
1905                 } finally {
1906                     setRootPaneCheckingEnabled(old);
1907                 }
1908             }
1909         }
1910     }
1911 
1912     /* Called from the JComponent's EnableSerializationFocusListener to
1913      * do any Swing-specific pre-serialization configuration.
1914      */
1915     void compWriteObjectNotify() {
1916       // need to disable rootpane checking for InternalFrame: 4172083
1917       boolean old = isRootPaneCheckingEnabled();
1918       try {
1919         setRootPaneCheckingEnabled(false);
1920         super.compWriteObjectNotify();
1921       }
1922       finally {
1923         setRootPaneCheckingEnabled(old);
1924       }
1925     }
1926 
1927     /**
1928      * Returns a string representation of this {@code JInternalFrame}.
1929      * This method
1930      * is intended to be used only for debugging purposes, and the
1931      * content and format of the returned string may vary between
1932      * implementations. The returned string may be empty but may not
1933      * be {@code null}.
1934      *
1935      * @return  a string representation of this {@code JInternalFrame}
1936      */
1937     protected String paramString() {
1938         String rootPaneString = (rootPane != null ?
1939                                  rootPane.toString() : "");
1940         String rootPaneCheckingEnabledString = (rootPaneCheckingEnabled ?
1941                                                 "true" : "false");
1942         String closableString = (closable ? "true" : "false");
1943         String isClosedString = (isClosed ? "true" : "false");
1944         String maximizableString = (maximizable ? "true" : "false");
1945         String isMaximumString = (isMaximum ? "true" : "false");
1946         String iconableString = (iconable ? "true" : "false");
1947         String isIconString = (isIcon ? "true" : "false");
1948         String resizableString = (resizable ? "true" : "false");
1949         String isSelectedString = (isSelected ? "true" : "false");
1950         String frameIconString = (frameIcon != null ?
1951                                   frameIcon.toString() : "");
1952         String titleString = (title != null ?
1953                               title : "");
1954         String desktopIconString = (desktopIcon != null ?
1955                                     desktopIcon.toString() : "");


1989     /**
1990      * Overridden to allow optimized painting when the
1991      * internal frame is being dragged.
1992      */
1993     protected void paintComponent(Graphics g) {
1994       if (isDragging) {
1995         //         System.out.println("ouch");
1996          danger = true;
1997       }
1998 
1999       super.paintComponent(g);
2000    }
2001 
2002     // ======= end optimized frame dragging defence code ==============
2003 
2004 /////////////////
2005 // Accessibility support
2006 ////////////////
2007 
2008     /**
2009      * Gets the {@code AccessibleContext} associated with this
2010      * {@code JInternalFrame}.
2011      * For internal frames, the {@code AccessibleContext}
2012      * takes the form of an
2013      * {@code AccessibleJInternalFrame} object.
2014      * A new {@code AccessibleJInternalFrame} instance is created if necessary.
2015      *
2016      * @return an {@code AccessibleJInternalFrame} that serves as the
2017      *         {@code AccessibleContext} of this
2018      *         {@code JInternalFrame}
2019      * @see AccessibleJInternalFrame
2020      */
2021     public AccessibleContext getAccessibleContext() {
2022         if (accessibleContext == null) {
2023             accessibleContext = new AccessibleJInternalFrame();
2024         }
2025         return accessibleContext;
2026     }
2027 
2028     /**
2029      * This class implements accessibility support for the
2030      * {@code JInternalFrame} class.  It provides an implementation of the
2031      * Java Accessibility API appropriate to internal frame user-interface
2032      * elements.
2033      * <p>
2034      * <strong>Warning:</strong>
2035      * Serialized objects of this class will not be compatible with
2036      * future Swing releases. The current serialization support is
2037      * appropriate for short term storage or RMI between applications running
2038      * the same version of Swing.  As of 1.4, support for long term storage
2039      * of all JavaBeans&trade;
2040      * has been added to the {@code java.beans} package.
2041      * Please see {@link java.beans.XMLEncoder}.
2042      */
2043     @SuppressWarnings("serial") // Same-version serialization only
2044     protected class AccessibleJInternalFrame extends AccessibleJComponent
2045         implements AccessibleValue {
2046 
2047         /**
2048          * Get the accessible name of this object.
2049          *
2050          * @return the localized name of the object -- can be {@code null} if this
2051          * object does not have a name
2052          * @see #setAccessibleName
2053          */
2054         public String getAccessibleName() {
2055             String name = accessibleName;
2056 
2057             if (name == null) {
2058                 name = (String)getClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY);
2059             }
2060             if (name == null) {
2061                 name = getTitle();
2062             }
2063             return name;
2064         }
2065 
2066         /**
2067          * Get the role of this object.
2068          *
2069          * @return an instance of AccessibleRole describing the role of the
2070          * object
2071          * @see AccessibleRole
2072          */
2073         public AccessibleRole getAccessibleRole() {
2074             return AccessibleRole.INTERNAL_FRAME;
2075         }
2076 
2077         /**
2078          * Gets the AccessibleValue associated with this object.  In the
2079          * implementation of the Java Accessibility API for this class,
2080          * returns this object, which is responsible for implementing the
2081          * {@code AccessibleValue} interface on behalf of itself.
2082          *
2083          * @return this object
2084          */
2085         public AccessibleValue getAccessibleValue() {
2086             return this;
2087         }
2088 
2089 
2090         //
2091         // AccessibleValue methods
2092         //
2093 
2094         /**
2095          * Get the value of this object as a Number.
2096          *
2097          * @return value of the object -- can be {@code null} if this object does not
2098          * have a value
2099          */
2100         public Number getCurrentAccessibleValue() {
2101             return Integer.valueOf(getLayer());
2102         }
2103 
2104         /**
2105          * Set the value of this object as a Number.
2106          *
2107          * @return {@code true} if the value was set
2108          */
2109         public boolean setCurrentAccessibleValue(Number n) {
2110             // TIGER - 4422535
2111             if (n == null) {
2112                 return false;
2113             }
2114             setLayer(Integer.valueOf(n.intValue()));
2115             return true;
2116         }
2117 
2118         /**
2119          * Get the minimum value of this object as a Number.
2120          *
2121          * @return Minimum value of the object; {@code null} if this object does not
2122          * have a minimum value
2123          */
2124         public Number getMinimumAccessibleValue() {
2125             return Integer.MIN_VALUE;
2126         }
2127 
2128         /**
2129          * Get the maximum value of this object as a Number.
2130          *
2131          * @return Maximum value of the object; {@code null} if this object does not
2132          * have a maximum value
2133          */
2134         public Number getMaximumAccessibleValue() {
2135             return Integer.MAX_VALUE;
2136         }
2137 
2138     } // AccessibleJInternalFrame
2139 
2140     /**
2141      * This component represents an iconified version of a
2142      * {@code JInternalFrame}.
2143      * This API should NOT BE USED by Swing applications, as it will go
2144      * away in future versions of Swing as its functionality is moved into
2145      * {@code JInternalFrame}.  This class is public only so that
2146      * UI objects can display a desktop icon.  If an application
2147      * wants to display a desktop icon, it should create a
2148      * {@code JInternalFrame} instance and iconify it.
2149      * <p>
2150      * <strong>Warning:</strong>
2151      * Serialized objects of this class will not be compatible with
2152      * future Swing releases. The current serialization support is
2153      * appropriate for short term storage or RMI between applications running
2154      * the same version of Swing.  As of 1.4, support for long term storage
2155      * of all JavaBeans&trade;
2156      * has been added to the {@code java.beans} package.
2157      * Please see {@link java.beans.XMLEncoder}.
2158      *
2159      * @author David Kloba
2160      */
2161     @SuppressWarnings("serial") // Same-version serialization only
2162     public static class JDesktopIcon extends JComponent implements Accessible
2163     {
2164         JInternalFrame internalFrame;
2165 
2166         /**
2167          * Creates an icon for an internal frame.
2168          *
2169          * @param f  the {@code JInternalFrame}
2170          *              for which the icon is created
2171          */
2172         public JDesktopIcon(JInternalFrame f) {
2173             setVisible(false);
2174             setInternalFrame(f);
2175             updateUI();
2176         }
2177 
2178         /**
2179          * Returns the look-and-feel object that renders this component.
2180          *
2181          * @return the {@code DesktopIconUI} object that renders
2182          *              this component
2183          */
2184         public DesktopIconUI getUI() {
2185             return (DesktopIconUI)ui;
2186         }
2187 
2188         /**
2189          * Sets the look-and-feel object that renders this component.
2190          *
2191          * @param ui  the {@code DesktopIconUI} look-and-feel object
2192          * @see UIDefaults#getUI
2193          */
2194         public void setUI(DesktopIconUI ui) {
2195             super.setUI(ui);
2196         }
2197 
2198         /**
2199          * Returns the {@code JInternalFrame} that this
2200          * {@code DesktopIcon} is associated with.
2201          *
2202          * @return the {@code JInternalFrame} with which this icon
2203          *              is associated
2204          */
2205         public JInternalFrame getInternalFrame() {
2206             return internalFrame;
2207         }
2208 
2209         /**
2210          * Sets the {@code JInternalFrame} with which this
2211          * {@code DesktopIcon} is associated.
2212          *
2213          * @param f  the {@code JInternalFrame} with which this icon
2214          *              is associated
2215          */
2216         public void setInternalFrame(JInternalFrame f) {
2217             internalFrame = f;
2218         }
2219 
2220         /**
2221          * Convenience method to ask the icon for the {@code Desktop}
2222          * object it belongs to.
2223          *
2224          * @return the {@code JDesktopPane} that contains this
2225          *           icon's internal frame, or {@code null} if none found
2226          */
2227         public JDesktopPane getDesktopPane() {
2228             if(getInternalFrame() != null)
2229                 return getInternalFrame().getDesktopPane();
2230             return null;
2231         }
2232 
2233         /**
2234          * Notification from the {@code UIManager} that the look and feel
2235          * has changed.
2236          * Replaces the current UI object with the latest version from the
2237          * {@code UIManager}.
2238          *
2239          * @see JComponent#updateUI
2240          */
2241         public void updateUI() {
2242             boolean hadUI = (ui != null);
2243             setUI((DesktopIconUI)UIManager.getUI(this));
2244             invalidate();
2245 
2246             Dimension r = getPreferredSize();
2247             setSize(r.width, r.height);
2248 
2249 
2250             if (internalFrame != null && internalFrame.getUI() != null) {  // don't do this if UI not created yet
2251                 SwingUtilities.updateComponentTreeUI(internalFrame);
2252             }
2253         }
2254 
2255         /* This method is called if updateUI was called on the associated
2256          * JInternalFrame.  It's necessary to avoid infinite recursion.
2257          */


2301        ////////////////
2302 
2303         /**
2304          * Gets the AccessibleContext associated with this JDesktopIcon.
2305          * For desktop icons, the AccessibleContext takes the form of an
2306          * AccessibleJDesktopIcon.
2307          * A new AccessibleJDesktopIcon instance is created if necessary.
2308          *
2309          * @return an AccessibleJDesktopIcon that serves as the
2310          *         AccessibleContext of this JDesktopIcon
2311          */
2312         public AccessibleContext getAccessibleContext() {
2313             if (accessibleContext == null) {
2314                 accessibleContext = new AccessibleJDesktopIcon();
2315             }
2316             return accessibleContext;
2317         }
2318 
2319         /**
2320          * This class implements accessibility support for the
2321          * {@code JInternalFrame.JDesktopIcon} class.  It provides an
2322          * implementation of the Java Accessibility API appropriate to
2323          * desktop icon user-interface elements.
2324          * <p>
2325          * <strong>Warning:</strong>
2326          * Serialized objects of this class will not be compatible with
2327          * future Swing releases. The current serialization support is
2328          * appropriate for short term storage or RMI between applications running
2329          * the same version of Swing.  As of 1.4, support for long term storage
2330          * of all JavaBeans&trade;
2331          * has been added to the {@code java.beans} package.
2332          * Please see {@link java.beans.XMLEncoder}.
2333          */
2334         @SuppressWarnings("serial") // Same-version serialization only
2335         protected class AccessibleJDesktopIcon extends AccessibleJComponent
2336             implements AccessibleValue {
2337 
2338             /**
2339              * Gets the role of this object.
2340              *
2341              * @return an instance of AccessibleRole describing the role of the
2342              * object
2343              * @see AccessibleRole
2344              */
2345             public AccessibleRole getAccessibleRole() {
2346                 return AccessibleRole.DESKTOP_ICON;
2347             }
2348 
2349             /**
2350              * Gets the AccessibleValue associated with this object.  In the
2351              * implementation of the Java Accessibility API for this class,
2352              * returns this object, which is responsible for implementing the
2353              * {@code AccessibleValue} interface on behalf of itself.
2354              *
2355              * @return this object
2356              */
2357             public AccessibleValue getAccessibleValue() {
2358                 return this;
2359             }
2360 
2361             //
2362             // AccessibleValue methods
2363             //
2364 
2365             /**
2366              * Gets the value of this object as a {@code Number}.
2367              *
2368              * @return value of the object -- can be {@code null} if this object does not
2369              * have a value
2370              */
2371             public Number getCurrentAccessibleValue() {
2372                 AccessibleContext a = JDesktopIcon.this.getInternalFrame().getAccessibleContext();
2373                 AccessibleValue v = a.getAccessibleValue();
2374                 if (v != null) {
2375                     return v.getCurrentAccessibleValue();
2376                 } else {
2377                     return null;
2378                 }
2379             }
2380 
2381             /**
2382              * Sets the value of this object as a {@code Number}.
2383              *
2384              * @return {@code true} if the value was set
2385              */
2386             public boolean setCurrentAccessibleValue(Number n) {
2387                 // TIGER - 4422535
2388                 if (n == null) {
2389                     return false;
2390                 }
2391                 AccessibleContext a = JDesktopIcon.this.getInternalFrame().getAccessibleContext();
2392                 AccessibleValue v = a.getAccessibleValue();
2393                 if (v != null) {
2394                     return v.setCurrentAccessibleValue(n);
2395                 } else {
2396                     return false;
2397                 }
2398             }
2399 
2400             /**
2401              * Gets the minimum value of this object as a {@code Number}.
2402              *
2403              * @return minimum value of the object; {@code null} if this object does not
2404              * have a minimum value
2405              */
2406             public Number getMinimumAccessibleValue() {
2407                 AccessibleContext a = JDesktopIcon.this.getInternalFrame().getAccessibleContext();
2408                 if (a instanceof AccessibleValue) {
2409                     return ((AccessibleValue)a).getMinimumAccessibleValue();
2410                 } else {
2411                     return null;
2412                 }
2413             }
2414 
2415             /**
2416              * Gets the maximum value of this object as a {@code Number}.
2417              *
2418              * @return maximum value of the object; {@code null} if this object does not
2419              * have a maximum value
2420              */
2421             public Number getMaximumAccessibleValue() {
2422                 AccessibleContext a = JDesktopIcon.this.getInternalFrame().getAccessibleContext();
2423                 if (a instanceof AccessibleValue) {
2424                     return ((AccessibleValue)a).getMaximumAccessibleValue();
2425                 } else {
2426                     return null;
2427                 }
2428             }
2429 
2430         } // AccessibleJDesktopIcon
2431     }
2432 }
< prev index next >