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

Print this page




   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package javax.swing;
  27 
  28 import java.awt.*;
  29 


  30 import java.beans.PropertyVetoException;
  31 import java.beans.PropertyChangeEvent;

  32 
  33 import javax.swing.event.InternalFrameEvent;
  34 import javax.swing.event.InternalFrameListener;
  35 import javax.swing.plaf.*;
  36 
  37 import javax.accessibility.*;
  38 
  39 import java.io.ObjectOutputStream;
  40 import java.io.IOException;
  41 import java.lang.StringBuilder;
  42 import java.beans.PropertyChangeListener;
  43 import sun.awt.AppContext;
  44 import sun.swing.SwingUtilities2;
  45 
  46 
  47 /**
  48  * A lightweight object that provides many of the features of
  49  * a native frame, including dragging, closing, becoming an icon,
  50  * resizing, title display, and support for a menu bar.
  51  * For task-oriented documentation and examples of using internal frames,
  52  * see <a
  53  href="http://docs.oracle.com/javase/tutorial/uiswing/components/internalframe.html" target="_top">How to Use Internal Frames</a>,
  54  * a section in <em>The Java Tutorial</em>.
  55  *
  56  * <p>
  57  *
  58  * Generally,
  59  * you add <code>JInternalFrame</code>s to a <code>JDesktopPane</code>. The UI
  60  * delegates the look-and-feel-specific actions to the
  61  * <code>DesktopManager</code>
  62  * object maintained by the <code>JDesktopPane</code>.
  63  * <p>
  64  * The <code>JInternalFrame</code> content pane
  65  * is where you add child components.
  66  * As a convenience, the {@code add}, {@code remove}, and {@code setLayout}


  88  * <p>
  89  * <strong>Warning:</strong>
  90  * Serialized objects of this class will not be compatible with
  91  * future Swing releases. The current serialization support is
  92  * appropriate for short term storage or RMI between applications running
  93  * the same version of Swing.  As of 1.4, support for long term storage
  94  * of all JavaBeans&trade;
  95  * has been added to the <code>java.beans</code> package.
  96  * Please see {@link java.beans.XMLEncoder}.
  97  *
  98  * @see InternalFrameEvent
  99  * @see JDesktopPane
 100  * @see DesktopManager
 101  * @see JInternalFrame.JDesktopIcon
 102  * @see JRootPane
 103  * @see javax.swing.RootPaneContainer
 104  *
 105  * @author David Kloba
 106  * @author Rich Schiavi
 107  * @since 1.2
 108  * @beaninfo
 109  *      attribute: isContainer true
 110  *      attribute: containerDelegate getContentPane
 111  *      description: A frame container which is contained within
 112  *                   another window.
 113  */


 114 @SuppressWarnings("serial") // Same-version serialization only
 115 public class JInternalFrame extends JComponent implements
 116         Accessible, WindowConstants,
 117         RootPaneContainer
 118 {
 119     /**
 120      * @see #getUIClassID
 121      * @see #readObject
 122      */
 123     private static final String uiClassID = "InternalFrameUI";
 124 
 125     /**
 126      * The <code>JRootPane</code> instance that manages the
 127      * content pane
 128      * and optional menu bar for this internal frame, as well as the
 129      * glass pane.
 130      *
 131      * @see JRootPane
 132      * @see RootPaneContainer
 133      */


 361      * @return  a new <code>JRootPane</code>
 362      * @see JRootPane
 363      */
 364     protected JRootPane createRootPane() {
 365         return new JRootPane();
 366     }
 367 
 368     /**
 369      * Returns the look-and-feel object that renders this component.
 370      *
 371      * @return the <code>InternalFrameUI</code> object that renders
 372      *          this component
 373      */
 374     public InternalFrameUI getUI() {
 375         return (InternalFrameUI)ui;
 376     }
 377 
 378     /**
 379      * Sets the UI delegate for this <code>JInternalFrame</code>.
 380      * @param ui  the UI delegate
 381      * @beaninfo
 382      *        bound: true
 383      *       hidden: true
 384      *    attribute: visualUpdate true
 385      *  description: The UI object that implements the Component's LookAndFeel.
 386      */


 387     public void setUI(InternalFrameUI ui) {
 388         boolean checkingEnabled = isRootPaneCheckingEnabled();
 389         try {
 390             setRootPaneCheckingEnabled(false);
 391             super.setUI(ui);
 392         }
 393         finally {
 394             setRootPaneCheckingEnabled(checkingEnabled);
 395         }
 396     }
 397 
 398     /**
 399      * Notification from the <code>UIManager</code> that the look and feel
 400      * has changed.
 401      * Replaces the current UI object with the latest version from the
 402      * <code>UIManager</code>.
 403      *
 404      * @see JComponent#updateUI
 405      */
 406     public void updateUI() {


 418     void updateUIWhenHidden() {
 419         setUI((InternalFrameUI)UIManager.getUI(this));
 420         invalidate();
 421         Component[] children = getComponents();
 422         if (children != null) {
 423             for (Component child : children) {
 424                 SwingUtilities.updateComponentTreeUI(child);
 425             }
 426         }
 427     }
 428 
 429 
 430     /**
 431      * Returns the name of the look-and-feel
 432      * class that renders this component.
 433      *
 434      * @return the string "InternalFrameUI"
 435      *
 436      * @see JComponent#getUIClassID
 437      * @see UIDefaults#getUI
 438      *
 439      * @beaninfo
 440      *     description: UIClassID
 441      */


 442     public String getUIClassID() {
 443         return uiClassID;
 444     }
 445 
 446     /**
 447      * Returns whether calls to <code>add</code> and
 448      * <code>setLayout</code> are forwarded to the <code>contentPane</code>.
 449      *
 450      * @return true if <code>add</code> and <code>setLayout</code>
 451      *         are forwarded; false otherwise
 452      *
 453      * @see #addImpl
 454      * @see #setLayout
 455      * @see #setRootPaneCheckingEnabled
 456      * @see javax.swing.RootPaneContainer
 457      */
 458     protected boolean isRootPaneCheckingEnabled() {
 459         return rootPaneCheckingEnabled;
 460     }
 461 
 462     /**
 463      * Sets whether calls to <code>add</code> and
 464      * <code>setLayout</code> are forwarded to the <code>contentPane</code>.
 465      *
 466      * @param enabled  true if <code>add</code> and <code>setLayout</code>
 467      *        are forwarded, false if they should operate directly on the
 468      *        <code>JInternalFrame</code>.
 469      *
 470      * @see #addImpl
 471      * @see #setLayout
 472      * @see #isRootPaneCheckingEnabled
 473      * @see javax.swing.RootPaneContainer
 474      * @beaninfo
 475      *      hidden: true
 476      * description: Whether the add and setLayout methods are forwarded
 477      */


 478     protected void setRootPaneCheckingEnabled(boolean enabled) {
 479         rootPaneCheckingEnabled = enabled;
 480     }
 481 
 482     /**
 483      * Adds the specified child <code>Component</code>.
 484      * This method is overridden to conditionally forward calls to the
 485      * <code>contentPane</code>.
 486      * By default, children are added to the <code>contentPane</code> instead
 487      * of the frame, refer to {@link javax.swing.RootPaneContainer} for
 488      * details.
 489      *
 490      * @param comp the component to be enhanced
 491      * @param constraints the constraints to be respected
 492      * @param index the index
 493      * @exception IllegalArgumentException if <code>index</code> is invalid
 494      * @exception IllegalArgumentException if adding the container's parent
 495      *                  to itself
 496      * @exception IllegalArgumentException if adding a window to a container
 497      *


 579     /**
 580      * Sets the <code>menuBar</code> property for this <code>JInternalFrame</code>.
 581      *
 582      * @param m  the <code>JMenuBar</code> to use in this internal frame
 583      * @see #getJMenuBar
 584      * @deprecated As of Swing version 1.0.3
 585      *  replaced by <code>setJMenuBar(JMenuBar m)</code>.
 586      */
 587     @Deprecated
 588     public void setMenuBar(JMenuBar m) {
 589         JMenuBar oldValue = getMenuBar();
 590         getRootPane().setJMenuBar(m);
 591         firePropertyChange(MENU_BAR_PROPERTY, oldValue, m);
 592     }
 593 
 594     /**
 595      * Sets the <code>menuBar</code> property for this <code>JInternalFrame</code>.
 596      *
 597      * @param m  the <code>JMenuBar</code> to use in this internal frame
 598      * @see #getJMenuBar
 599      * @beaninfo
 600      *     bound: true
 601      *     preferred: true
 602      *     description: The menu bar for accessing pulldown menus
 603      *                  from this internal frame.
 604      */


 605     public void setJMenuBar(JMenuBar m){
 606         JMenuBar oldValue = getMenuBar();
 607         getRootPane().setJMenuBar(m);
 608         firePropertyChange(MENU_BAR_PROPERTY, oldValue, m);
 609     }
 610 
 611     // implements javax.swing.RootPaneContainer
 612     /**
 613      * Returns the content pane for this internal frame.
 614      * @return the content pane
 615      */
 616     public Container getContentPane() {
 617         return getRootPane().getContentPane();
 618     }
 619 
 620 
 621     /**
 622      * Sets this <code>JInternalFrame</code>'s <code>contentPane</code>
 623      * property.
 624      *
 625      * @param c  the content pane for this internal frame
 626      *
 627      * @exception java.awt.IllegalComponentStateException (a runtime
 628      *           exception) if the content pane parameter is <code>null</code>
 629      * @see RootPaneContainer#getContentPane
 630      * @beaninfo
 631      *     bound: true
 632      *     hidden: true
 633      *     description: The client area of the internal frame where child
 634      *                  components are normally inserted.
 635      */


 636     public void setContentPane(Container c) {
 637         Container oldValue = getContentPane();
 638         getRootPane().setContentPane(c);
 639         firePropertyChange(CONTENT_PANE_PROPERTY, oldValue, c);
 640     }
 641 
 642     /**
 643      * Returns the layered pane for this internal frame.
 644      *
 645      * @return a <code>JLayeredPane</code> object
 646      * @see RootPaneContainer#setLayeredPane
 647      * @see RootPaneContainer#getLayeredPane
 648      */
 649     public JLayeredPane getLayeredPane() {
 650         return getRootPane().getLayeredPane();
 651     }
 652 
 653     /**
 654      * Sets this <code>JInternalFrame</code>'s
 655      * <code>layeredPane</code> property.
 656      *
 657      * @param layered the <code>JLayeredPane</code> for this internal frame
 658      *
 659      * @exception java.awt.IllegalComponentStateException (a runtime
 660      *           exception) if the layered pane parameter is <code>null</code>
 661      * @see RootPaneContainer#setLayeredPane
 662      * @beaninfo
 663      *     hidden: true
 664      *     bound: true
 665      *     description: The pane which holds the various desktop layers.
 666      */


 667     public void setLayeredPane(JLayeredPane layered) {
 668         JLayeredPane oldValue = getLayeredPane();
 669         getRootPane().setLayeredPane(layered);
 670         firePropertyChange(LAYERED_PANE_PROPERTY, oldValue, layered);
 671     }
 672 
 673     /**
 674      * Returns the glass pane for this internal frame.
 675      *
 676      * @return the glass pane
 677      * @see RootPaneContainer#setGlassPane
 678      */
 679     public Component getGlassPane() {
 680         return getRootPane().getGlassPane();
 681     }
 682 
 683     /**
 684      * Sets this <code>JInternalFrame</code>'s
 685      * <code>glassPane</code> property.
 686      *
 687      * @param glass the glass pane for this internal frame
 688      * @see RootPaneContainer#getGlassPane
 689      * @beaninfo
 690      *     bound: true
 691      *     hidden: true
 692      *     description: A transparent pane used for menu rendering.
 693      */


 694     public void setGlassPane(Component glass) {
 695         Component oldValue = getGlassPane();
 696         getRootPane().setGlassPane(glass);
 697         firePropertyChange(GLASS_PANE_PROPERTY, oldValue, glass);
 698     }
 699 
 700     /**
 701      * Returns the <code>rootPane</code> object for this internal frame.
 702      *
 703      * @return the <code>rootPane</code> property
 704      * @see RootPaneContainer#getRootPane
 705      */


 706     public JRootPane getRootPane() {
 707         return rootPane;
 708     }
 709 
 710 
 711     /**
 712      * Sets the <code>rootPane</code> property
 713      * for this <code>JInternalFrame</code>.
 714      * This method is called by the constructor.
 715      *
 716      * @param root  the new <code>JRootPane</code> object
 717      * @beaninfo
 718      *     bound: true
 719      *     hidden: true
 720      *     description: The root pane used by this internal frame.
 721      */
 722     protected void setRootPane(JRootPane root) {
 723         if(rootPane != null) {
 724             remove(rootPane);
 725         }
 726         JRootPane oldValue = getRootPane();
 727         rootPane = root;
 728         if(rootPane != null) {
 729             boolean checkingEnabled = isRootPaneCheckingEnabled();
 730             try {
 731                 setRootPaneCheckingEnabled(false);
 732                 add(rootPane, BorderLayout.CENTER);
 733             }
 734             finally {
 735                 setRootPaneCheckingEnabled(checkingEnabled);
 736             }
 737         }
 738         firePropertyChange(ROOT_PANE_PROPERTY, oldValue, root);
 739     }
 740 
 741     /**
 742      * Sets whether this <code>JInternalFrame</code> can be closed by
 743      * some user action.
 744      * @param b a boolean value, where <code>true</code> means this internal frame can be closed
 745      * @beaninfo
 746      *     preferred: true
 747      *           bound: true
 748      *     description: Indicates whether this internal frame can be closed.
 749      */


 750     public void setClosable(boolean b) {
 751         Boolean oldValue = closable ? Boolean.TRUE : Boolean.FALSE;
 752         Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
 753         closable = b;
 754         firePropertyChange("closable", oldValue, newValue);
 755     }
 756 
 757     /**
 758      * Returns whether this <code>JInternalFrame</code> can be closed by
 759      * some user action.
 760      * @return <code>true</code> if this internal frame can be closed
 761      */
 762     public boolean isClosable() {
 763         return closable;
 764     }
 765 
 766     /**
 767      * Returns whether this <code>JInternalFrame</code> is currently closed.
 768      * @return <code>true</code> if this internal frame is closed, <code>false</code> otherwise
 769      */


 791      * and then firing an <code>INTERNAL_FRAME_CLOSED</code> event.
 792      *
 793      * <p>
 794      *
 795      * <b>Note:</b>
 796      * To reuse an internal frame that has been closed,
 797      * you must add it to a container
 798      * (even if you never removed it from its previous container).
 799      * Typically, this container will be the <code>JDesktopPane</code>
 800      * that previously contained the internal frame.
 801      *
 802      * @param b must be <code>true</code>
 803      *
 804      * @exception PropertyVetoException when the attempt to set the
 805      *            property is vetoed by the <code>JInternalFrame</code>
 806      *
 807      * @see #isClosed()
 808      * @see #setDefaultCloseOperation
 809      * @see #dispose
 810      * @see javax.swing.event.InternalFrameEvent#INTERNAL_FRAME_CLOSING
 811      *
 812      * @beaninfo
 813      *           bound: true
 814      *     constrained: true
 815      *     description: Indicates whether this internal frame has been closed.
 816      */


 817     public void setClosed(boolean b) throws PropertyVetoException {
 818         if (isClosed == b) {
 819             return;
 820         }
 821 
 822         Boolean oldValue = isClosed ? Boolean.TRUE : Boolean.FALSE;
 823         Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
 824         if (b) {
 825           fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_CLOSING);
 826         }
 827         fireVetoableChange(IS_CLOSED_PROPERTY, oldValue, newValue);
 828         isClosed = b;
 829         if (isClosed) {
 830           setVisible(false);
 831         }
 832         firePropertyChange(IS_CLOSED_PROPERTY, oldValue, newValue);
 833         if (isClosed) {
 834           dispose();
 835         } else if (!opened) {
 836           /* this bogus -- we haven't defined what
 837              setClosed(false) means. */
 838           //        fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_OPENED);
 839           //            opened = true;
 840         }
 841     }
 842 
 843     /**
 844      * Sets whether the <code>JInternalFrame</code> can be resized by some
 845      * user action.
 846      *
 847      * @param b  a boolean, where <code>true</code> means this internal frame can be resized
 848      * @beaninfo
 849      *     preferred: true
 850      *           bound: true
 851      *     description: Determines whether this internal frame can be resized
 852      *                  by the user.
 853      */


 854     public void setResizable(boolean b) {
 855         Boolean oldValue = resizable ? Boolean.TRUE : Boolean.FALSE;
 856         Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
 857         resizable = b;
 858         firePropertyChange("resizable", oldValue, newValue);
 859     }
 860 
 861     /**
 862      * Returns whether the <code>JInternalFrame</code> can be resized
 863      * by some user action.
 864      *
 865      * @return <code>true</code> if this internal frame can be resized, <code>false</code> otherwise
 866      */
 867     public boolean isResizable() {
 868         // don't allow resizing when maximized.
 869         return isMaximum ? false : resizable;
 870     }
 871 
 872     /**
 873      * Sets the <code>iconable</code> property,
 874      * which must be <code>true</code>
 875      * for the user to be able to
 876      * make the <code>JInternalFrame</code> an icon.
 877      * Some look and feels might not implement iconification;
 878      * they will ignore this property.
 879      *
 880      * @param b  a boolean, where <code>true</code> means this internal frame can be iconified
 881      * @beaninfo
 882      *     preferred: true
 883                bound: true
 884      *     description: Determines whether this internal frame can be iconified.
 885      */


 886     public void setIconifiable(boolean b) {
 887         Boolean oldValue = iconable ? Boolean.TRUE : Boolean.FALSE;
 888         Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
 889         iconable = b;
 890         firePropertyChange("iconable", oldValue, newValue);
 891     }
 892 
 893     /**
 894      * Gets the <code>iconable</code> property,
 895      * which by default is <code>false</code>.
 896      *
 897      * @return the value of the <code>iconable</code> property.
 898      *
 899      * @see #setIconifiable
 900      */
 901     public boolean isIconifiable() {
 902         return iconable;
 903     }
 904 
 905     /**


 909      */
 910     public boolean isIcon() {
 911         return isIcon;
 912     }
 913 
 914     /**
 915      * Iconifies or de-iconifies this internal frame,
 916      * if the look and feel supports iconification.
 917      * If the internal frame's state changes to iconified,
 918      * this method fires an <code>INTERNAL_FRAME_ICONIFIED</code> event.
 919      * If the state changes to de-iconified,
 920      * an <code>INTERNAL_FRAME_DEICONIFIED</code> event is fired.
 921      *
 922      * @param b a boolean, where <code>true</code> means to iconify this internal frame and
 923      *          <code>false</code> means to de-iconify it
 924      * @exception PropertyVetoException when the attempt to set the
 925      *            property is vetoed by the <code>JInternalFrame</code>
 926      *
 927      * @see InternalFrameEvent#INTERNAL_FRAME_ICONIFIED
 928      * @see InternalFrameEvent#INTERNAL_FRAME_DEICONIFIED
 929      *
 930      * @beaninfo
 931      *           bound: true
 932      *     constrained: true
 933      *     description: The image displayed when this internal frame is minimized.
 934      */


 935     public void setIcon(boolean b) throws PropertyVetoException {
 936         if (isIcon == b) {
 937             return;
 938         }
 939 
 940         /* If an internal frame is being iconified before it has a
 941            parent, (e.g., client wants it to start iconic), create the
 942            parent if possible so that we can place the icon in its
 943            proper place on the desktop. I am not sure the call to
 944            validate() is necessary, since we are not going to display
 945            this frame yet */
 946         firePropertyChange("ancestor", null, getParent());
 947 
 948         Boolean oldValue = isIcon ? Boolean.TRUE : Boolean.FALSE;
 949         Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
 950         fireVetoableChange(IS_ICON_PROPERTY, oldValue, newValue);
 951         isIcon = b;
 952         firePropertyChange(IS_ICON_PROPERTY, oldValue, newValue);
 953         if (b)
 954           fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_ICONIFIED);
 955         else
 956           fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_DEICONIFIED);
 957     }
 958 
 959     /**
 960      * Sets the <code>maximizable</code> property,
 961      * which determines whether the <code>JInternalFrame</code>
 962      * can be maximized by
 963      * some user action.
 964      * Some look and feels might not support maximizing internal frames;
 965      * they will ignore this property.
 966      *
 967      * @param b <code>true</code> to specify that this internal frame should be maximizable; <code>false</code> to specify that it should not be
 968      * @beaninfo
 969      *         bound: true
 970      *     preferred: true
 971      *     description: Determines whether this internal frame can be maximized.
 972      */


 973     public void setMaximizable(boolean b) {
 974         Boolean oldValue = maximizable ? Boolean.TRUE : Boolean.FALSE;
 975         Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
 976         maximizable = b;
 977         firePropertyChange("maximizable", oldValue, newValue);
 978     }
 979 
 980     /**
 981      * Gets the value of the <code>maximizable</code> property.
 982      *
 983      * @return the value of the <code>maximizable</code> property
 984      * @see #setMaximizable
 985      */
 986     public boolean isMaximizable() {
 987         return maximizable;
 988     }
 989 
 990     /**
 991      * Returns whether the <code>JInternalFrame</code> is currently maximized.
 992      *
 993      * @return <code>true</code> if this internal frame is maximized, <code>false</code> otherwise
 994      */
 995     public boolean isMaximum() {
 996         return isMaximum;
 997     }
 998 
 999     /**
1000      * Maximizes and restores this internal frame.  A maximized frame is resized to
1001      * fully fit the <code>JDesktopPane</code> area associated with the
1002      * <code>JInternalFrame</code>.
1003      * A restored frame's size is set to the <code>JInternalFrame</code>'s
1004      * actual size.
1005      *
1006      * @param b  a boolean, where <code>true</code> maximizes this internal frame and <code>false</code>
1007      *           restores it
1008      * @exception PropertyVetoException when the attempt to set the
1009      *            property is vetoed by the <code>JInternalFrame</code>
1010      * @beaninfo
1011      *     bound: true
1012      *     constrained: true
1013      *     description: Indicates whether this internal frame is maximized.
1014      */


1015     public void setMaximum(boolean b) throws PropertyVetoException {
1016         if (isMaximum == b) {
1017             return;
1018         }
1019 
1020         Boolean oldValue = isMaximum ? Boolean.TRUE : Boolean.FALSE;
1021         Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
1022         fireVetoableChange(IS_MAXIMUM_PROPERTY, oldValue, newValue);
1023         /* setting isMaximum above the event firing means that
1024            property listeners that, for some reason, test it will
1025            get it wrong... See, for example, getNormalBounds() */
1026         isMaximum = b;
1027         firePropertyChange(IS_MAXIMUM_PROPERTY, oldValue, newValue);
1028     }
1029 
1030     /**
1031      * Returns the title of the <code>JInternalFrame</code>.
1032      *
1033      * @return a <code>String</code> containing this internal frame's title
1034      * @see #setTitle
1035      */
1036     public String getTitle() {
1037         return title;
1038     }
1039 
1040     /**
1041      * Sets the <code>JInternalFrame</code> title. <code>title</code>
1042      * may have a <code>null</code> value.
1043      * @see #getTitle
1044      *
1045      * @param title  the <code>String</code> to display in the title bar
1046      * @beaninfo
1047      *     preferred: true
1048      *     bound: true
1049      *     description: The text displayed in the title bar.
1050      */


1051     public void setTitle(String title) {
1052         String oldValue = this.title;
1053         this.title = title;
1054         firePropertyChange(TITLE_PROPERTY, oldValue, title);
1055     }
1056 
1057     /**
1058      * Selects or deselects the internal frame
1059      * if it's showing.
1060      * A <code>JInternalFrame</code> normally draws its title bar
1061      * differently if it is
1062      * the selected frame, which indicates to the user that this
1063      * internal frame has the focus.
1064      * When this method changes the state of the internal frame
1065      * from deselected to selected, it fires an
1066      * <code>InternalFrameEvent.INTERNAL_FRAME_ACTIVATED</code> event.
1067      * If the change is from selected to deselected,
1068      * an <code>InternalFrameEvent.INTERNAL_FRAME_DEACTIVATED</code> event
1069      * is fired.
1070      *
1071      * @param selected  a boolean, where <code>true</code> means this internal frame
1072      *                  should become selected (currently active)
1073      *                  and <code>false</code> means it should become deselected
1074      * @exception PropertyVetoException when the attempt to set the
1075      *            property is vetoed by the <code>JInternalFrame</code>
1076      *
1077      * @see #isShowing
1078      * @see InternalFrameEvent#INTERNAL_FRAME_ACTIVATED
1079      * @see InternalFrameEvent#INTERNAL_FRAME_DEACTIVATED
1080      *
1081      * @beaninfo
1082      *     constrained: true
1083      *           bound: true
1084      *     description: Indicates whether this internal frame is currently
1085      *                  the active frame.
1086      */


1087     public void setSelected(boolean selected) throws PropertyVetoException {
1088        // The InternalFrame may already be selected, but the focus
1089        // may be outside it, so restore the focus to the subcomponent
1090        // which previously had it. See Bug 4302764.
1091         if (selected && isSelected) {
1092             restoreSubcomponentFocus();
1093             return;
1094         }
1095         // The internal frame or the desktop icon must be showing to allow
1096         // selection.  We may deselect even if neither is showing.
1097         if ((isSelected == selected) || (selected &&
1098             (isIcon ? !desktopIcon.isShowing() : !isShowing()))) {
1099             return;
1100         }
1101 
1102         Boolean oldValue = isSelected ? Boolean.TRUE : Boolean.FALSE;
1103         Boolean newValue = selected ? Boolean.TRUE : Boolean.FALSE;
1104         fireVetoableChange(IS_SELECTED_PROPERTY, oldValue, newValue);
1105 
1106         /* We don't want to leave focus in the previously selected


1136      */
1137     public boolean isSelected() {
1138         return isSelected;
1139     }
1140 
1141     /**
1142      * Sets an image to be displayed in the titlebar of this internal frame (usually
1143      * in the top-left corner).
1144      * This image is not the <code>desktopIcon</code> object, which
1145      * is the image displayed in the <code>JDesktop</code> when
1146      * this internal frame is iconified.
1147      *
1148      * Passing <code>null</code> to this function is valid,
1149      * but the look and feel
1150      * can choose the
1151      * appropriate behavior 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>.


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      * @see JLayeredPane
1251      * @beaninfo
1252      *     expert: true
1253      *     description: Specifies what desktop layer is used.
1254      */


1255     public void setLayer(Integer layer) {
1256         if(getParent() != null && getParent() instanceof JLayeredPane) {
1257             // Normally we want to do this, as it causes the LayeredPane
1258             // to draw properly.
1259             JLayeredPane p = (JLayeredPane)getParent();
1260             p.setLayer(this, layer.intValue(), p.getPosition(this));
1261         } else {
1262              // Try to do the right thing
1263              JLayeredPane.putLayer(this, layer.intValue());
1264              if(getParent() != null)
1265                  getParent().repaint(getX(), getY(), getWidth(), getHeight());
1266         }
1267     }
1268 
1269     /**
1270      * Convenience method for setting the layer attribute of this component.
1271      * The method <code>setLayer(Integer)</code> should be used for
1272      * layer values predefined in <code>JLayeredPane</code>.
1273      * When using <code>setLayer(int)</code>, care must be taken not to
1274      * accidentally clash with those values.
1275      *
1276      * @param layer  an integer specifying this internal frame's desktop layer
1277      *
1278      * @since 1.3
1279      *
1280      * @see #setLayer(Integer)
1281      * @see JLayeredPane
1282      * @beaninfo
1283      *     expert: true
1284      *     description: Specifies what desktop layer is used.
1285      */


1286     public void setLayer(int layer) {
1287       this.setLayer(Integer.valueOf(layer));
1288     }
1289 
1290     /**
1291      * Convenience method for getting the layer attribute of this component.
1292      *
1293      * @return  an <code>Integer</code> object specifying this
1294      *          frame's desktop layer
1295      * @see JLayeredPane
1296       */
1297     public int getLayer() {
1298         return JLayeredPane.getLayer(this);
1299     }
1300 
1301     /**
1302       * Convenience method that searches the ancestor hierarchy for a
1303       * <code>JDesktop</code> instance. If <code>JInternalFrame</code>
1304       * finds none, the <code>desktopIcon</code> tree is searched.
1305       *
1306       * @return the <code>JDesktopPane</code> this internal frame belongs to,
1307       *         or <code>null</code> if none is found
1308       */

1309     public JDesktopPane getDesktopPane() {
1310         Container p;
1311 
1312         // Search upward for desktop
1313         p = getParent();
1314         while(p != null && !(p instanceof JDesktopPane))
1315             p = p.getParent();
1316 
1317         if(p == null) {
1318            // search its icon parent for desktop
1319            p = getDesktopIcon().getParent();
1320            while(p != null && !(p instanceof JDesktopPane))
1321                 p = p.getParent();
1322         }
1323 
1324         return (JDesktopPane)p;
1325     }
1326 
1327     /**
1328      * Sets the <code>JDesktopIcon</code> associated with this
1329      * <code>JInternalFrame</code>.
1330      *
1331      * @param d the <code>JDesktopIcon</code> to display on the desktop
1332      * @see #getDesktopIcon
1333      * @beaninfo
1334      *           bound: true
1335      *     description: The icon shown when this internal frame is minimized.
1336      */


1337     public void setDesktopIcon(JDesktopIcon d) {
1338         JDesktopIcon oldValue = getDesktopIcon();
1339         desktopIcon = d;
1340         firePropertyChange("desktopIcon", oldValue, d);
1341     }
1342 
1343     /**
1344      * Returns the <code>JDesktopIcon</code> used when this
1345      * <code>JInternalFrame</code> is iconified.
1346      *
1347      * @return the <code>JDesktopIcon</code> displayed on the desktop
1348      * @see #setDesktopIcon
1349      */
1350     public JDesktopIcon getDesktopIcon() {
1351         return desktopIcon;
1352     }
1353 
1354     /**
1355      * If the <code>JInternalFrame</code> is not in maximized state, returns
1356      * <code>getBounds()</code>; otherwise, returns the bounds that the


1406      * Returns the child component of this <code>JInternalFrame</code>
1407      * that will receive the
1408      * focus when this <code>JInternalFrame</code> is selected.
1409      * If this <code>JInternalFrame</code> is
1410      * currently selected, this method returns the same component as
1411      * the <code>getFocusOwner</code> method.
1412      * If this <code>JInternalFrame</code> is not selected,
1413      * then the child component that most recently requested focus will be
1414      * returned. If no child component has ever requested focus, then this
1415      * <code>JInternalFrame</code>'s initial focusable component is returned.
1416      * If no such
1417      * child exists, then this <code>JInternalFrame</code>'s default component
1418      * to focus is returned.
1419      *
1420      * @return the child component that will receive focus when this
1421      *         <code>JInternalFrame</code> is selected
1422      * @see #getFocusOwner
1423      * @see #isSelected
1424      * @since 1.4
1425      */

1426     public Component getMostRecentFocusOwner() {
1427         if (isSelected()) {
1428             return getFocusOwner();
1429         }
1430 
1431         if (lastFocusOwner != null) {
1432             return lastFocusOwner;
1433         }
1434 
1435         FocusTraversalPolicy policy = getFocusTraversalPolicy();
1436         if (policy instanceof InternalFrameFocusTraversalPolicy) {
1437             return ((InternalFrameFocusTraversalPolicy)policy).
1438                 getInitialComponent(this);
1439         }
1440 
1441         Component toFocus = policy.getDefaultComponent(this);
1442         if (toFocus != null) {
1443             return toFocus;
1444         }
1445         return getContentPane();


1519      * Removes the specified internal frame listener so that it no longer
1520      * receives internal frame events from this internal frame.
1521      *
1522      * @param l the internal frame listener
1523      */
1524     public void removeInternalFrameListener(InternalFrameListener l) {  // remind: sync??
1525       listenerList.remove(InternalFrameListener.class, l);
1526     }
1527 
1528     /**
1529      * Returns an array of all the <code>InternalFrameListener</code>s added
1530      * to this <code>JInternalFrame</code> with
1531      * <code>addInternalFrameListener</code>.
1532      *
1533      * @return all of the <code>InternalFrameListener</code>s added or an empty
1534      *         array if no listeners have been added
1535      * @since 1.4
1536      *
1537      * @see #addInternalFrameListener
1538      */

1539     public InternalFrameListener[] getInternalFrameListeners() {
1540         return listenerList.getListeners(InternalFrameListener.class);
1541     }
1542 
1543     // remind: name ok? all one method ok? need to be synchronized?
1544     /**
1545      * Fires an internal frame event.
1546      *
1547      * @param id  the type of the event being fired; one of the following:
1548      * <ul>
1549      * <li><code>InternalFrameEvent.INTERNAL_FRAME_OPENED</code>
1550      * <li><code>InternalFrameEvent.INTERNAL_FRAME_CLOSING</code>
1551      * <li><code>InternalFrameEvent.INTERNAL_FRAME_CLOSED</code>
1552      * <li><code>InternalFrameEvent.INTERNAL_FRAME_ICONIFIED</code>
1553      * <li><code>InternalFrameEvent.INTERNAL_FRAME_DEICONIFIED</code>
1554      * <li><code>InternalFrameEvent.INTERNAL_FRAME_ACTIVATED</code>
1555      * <li><code>InternalFrameEvent.INTERNAL_FRAME_DEACTIVATED</code>
1556      * </ul>
1557      * If the event type is not one of the above, nothing happens.
1558      */


1850      *
1851      * @return <code>true</code>
1852      * @see #setFocusCycleRoot
1853      * @see java.awt.Container#setFocusTraversalPolicy
1854      * @see java.awt.Container#getFocusTraversalPolicy
1855      * @since 1.4
1856      */
1857     public final boolean isFocusCycleRoot() {
1858         return true;
1859     }
1860 
1861     /**
1862      * Always returns <code>null</code> because <code>JInternalFrame</code>s
1863      * must always be roots of a focus
1864      * traversal cycle.
1865      *
1866      * @return <code>null</code>
1867      * @see java.awt.Container#isFocusCycleRoot()
1868      * @since 1.4
1869      */

1870     public final Container getFocusCycleRootAncestor() {
1871         return null;
1872     }
1873 
1874     /**
1875      * Gets the warning string that is displayed with this internal frame.
1876      * Since an internal frame is always secure (since it's fully
1877      * contained within a window that might need a warning string)
1878      * this method always returns <code>null</code>.
1879      * @return    <code>null</code>
1880      * @see       java.awt.Window#getWarningString
1881      */

1882     public final String getWarningString() {
1883         return null;
1884     }
1885 
1886     /**
1887      * See <code>readObject</code> and <code>writeObject</code>
1888      * in <code>JComponent</code> for more
1889      * information about serialization in Swing.
1890      */
1891     private void writeObject(ObjectOutputStream s) throws IOException {
1892         s.defaultWriteObject();
1893         if (getUIClassID().equals(uiClassID)) {
1894             byte count = JComponent.getWriteObjCounter(this);
1895             JComponent.setWriteObjCounter(this, --count);
1896             if (count == 0 && ui != null) {
1897                 boolean old = isRootPaneCheckingEnabled();
1898                 try {
1899                     setRootPaneCheckingEnabled(false);
1900                     ui.installUI(this);
1901                 } finally {


1997 
1998     // ======= end optimized frame dragging defence code ==============
1999 
2000 /////////////////
2001 // Accessibility support
2002 ////////////////
2003 
2004     /**
2005      * Gets the <code>AccessibleContext</code> associated with this
2006      * <code>JInternalFrame</code>.
2007      * For internal frames, the <code>AccessibleContext</code>
2008      * takes the form of an
2009      * <code>AccessibleJInternalFrame</code> object.
2010      * A new <code>AccessibleJInternalFrame</code> instance is created if necessary.
2011      *
2012      * @return an <code>AccessibleJInternalFrame</code> that serves as the
2013      *         <code>AccessibleContext</code> of this
2014      *         <code>JInternalFrame</code>
2015      * @see AccessibleJInternalFrame
2016      */

2017     public AccessibleContext getAccessibleContext() {
2018         if (accessibleContext == null) {
2019             accessibleContext = new AccessibleJInternalFrame();
2020         }
2021         return accessibleContext;
2022     }
2023 
2024     /**
2025      * This class implements accessibility support for the
2026      * <code>JInternalFrame</code> class.  It provides an implementation of the
2027      * Java Accessibility API appropriate to internal frame user-interface
2028      * elements.
2029      * <p>
2030      * <strong>Warning:</strong>
2031      * Serialized objects of this class will not be compatible with
2032      * future Swing releases. The current serialization support is
2033      * appropriate for short term storage or RMI between applications running
2034      * the same version of Swing.  As of 1.4, support for long term storage
2035      * of all JavaBeans&trade;
2036      * has been added to the <code>java.beans</code> package.




   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */

  25 package javax.swing;
  26 
  27 import java.awt.*;
  28 
  29 import java.beans.JavaBean;
  30 import java.beans.BeanProperty;
  31 import java.beans.PropertyVetoException;
  32 import java.beans.PropertyChangeEvent;
  33 import java.beans.PropertyChangeListener;
  34 
  35 import javax.swing.event.InternalFrameEvent;
  36 import javax.swing.event.InternalFrameListener;
  37 import javax.swing.plaf.*;
  38 
  39 import javax.accessibility.*;
  40 
  41 import java.io.ObjectOutputStream;
  42 import java.io.IOException;
  43 import java.lang.StringBuilder;
  44 
  45 import sun.awt.AppContext;
  46 import sun.swing.SwingUtilities2;
  47 

  48 /**
  49  * A lightweight object that provides many of the features of
  50  * a native frame, including dragging, closing, becoming an icon,
  51  * resizing, title display, and support for a menu bar.
  52  * For task-oriented documentation and examples of using internal frames,
  53  * see <a
  54  href="http://docs.oracle.com/javase/tutorial/uiswing/components/internalframe.html" target="_top">How to Use Internal Frames</a>,
  55  * a section in <em>The Java Tutorial</em>.
  56  *
  57  * <p>
  58  *
  59  * Generally,
  60  * you add <code>JInternalFrame</code>s to a <code>JDesktopPane</code>. The UI
  61  * delegates the look-and-feel-specific actions to the
  62  * <code>DesktopManager</code>
  63  * object maintained by the <code>JDesktopPane</code>.
  64  * <p>
  65  * The <code>JInternalFrame</code> content pane
  66  * is where you add child components.
  67  * As a convenience, the {@code add}, {@code remove}, and {@code setLayout}


  89  * <p>
  90  * <strong>Warning:</strong>
  91  * Serialized objects of this class will not be compatible with
  92  * future Swing releases. The current serialization support is
  93  * appropriate for short term storage or RMI between applications running
  94  * the same version of Swing.  As of 1.4, support for long term storage
  95  * of all JavaBeans&trade;
  96  * has been added to the <code>java.beans</code> package.
  97  * Please see {@link java.beans.XMLEncoder}.
  98  *
  99  * @see InternalFrameEvent
 100  * @see JDesktopPane
 101  * @see DesktopManager
 102  * @see JInternalFrame.JDesktopIcon
 103  * @see JRootPane
 104  * @see javax.swing.RootPaneContainer
 105  *
 106  * @author David Kloba
 107  * @author Rich Schiavi
 108  * @since 1.2





 109  */
 110 @JavaBean(defaultProperty = "JMenuBar", description = "A frame container which is contained within another window.")
 111 @SwingContainer(delegate = "getContentPane")
 112 @SuppressWarnings("serial") // Same-version serialization only
 113 public class JInternalFrame extends JComponent implements
 114         Accessible, WindowConstants,
 115         RootPaneContainer
 116 {
 117     /**
 118      * @see #getUIClassID
 119      * @see #readObject
 120      */
 121     private static final String uiClassID = "InternalFrameUI";
 122 
 123     /**
 124      * The <code>JRootPane</code> instance that manages the
 125      * content pane
 126      * and optional menu bar for this internal frame, as well as the
 127      * glass pane.
 128      *
 129      * @see JRootPane
 130      * @see RootPaneContainer
 131      */


 359      * @return  a new <code>JRootPane</code>
 360      * @see JRootPane
 361      */
 362     protected JRootPane createRootPane() {
 363         return new JRootPane();
 364     }
 365 
 366     /**
 367      * Returns the look-and-feel object that renders this component.
 368      *
 369      * @return the <code>InternalFrameUI</code> object that renders
 370      *          this component
 371      */
 372     public InternalFrameUI getUI() {
 373         return (InternalFrameUI)ui;
 374     }
 375 
 376     /**
 377      * Sets the UI delegate for this <code>JInternalFrame</code>.
 378      * @param ui  the UI delegate





 379      */
 380     @BeanProperty(hidden = true, visualUpdate = true, description
 381             = "The UI object that implements the Component's LookAndFeel.")
 382     public void setUI(InternalFrameUI ui) {
 383         boolean checkingEnabled = isRootPaneCheckingEnabled();
 384         try {
 385             setRootPaneCheckingEnabled(false);
 386             super.setUI(ui);
 387         }
 388         finally {
 389             setRootPaneCheckingEnabled(checkingEnabled);
 390         }
 391     }
 392 
 393     /**
 394      * Notification from the <code>UIManager</code> that the look and feel
 395      * has changed.
 396      * Replaces the current UI object with the latest version from the
 397      * <code>UIManager</code>.
 398      *
 399      * @see JComponent#updateUI
 400      */
 401     public void updateUI() {


 413     void updateUIWhenHidden() {
 414         setUI((InternalFrameUI)UIManager.getUI(this));
 415         invalidate();
 416         Component[] children = getComponents();
 417         if (children != null) {
 418             for (Component child : children) {
 419                 SwingUtilities.updateComponentTreeUI(child);
 420             }
 421         }
 422     }
 423 
 424 
 425     /**
 426      * Returns the name of the look-and-feel
 427      * class that renders this component.
 428      *
 429      * @return the string "InternalFrameUI"
 430      *
 431      * @see JComponent#getUIClassID
 432      * @see UIDefaults#getUI



 433      */
 434     @BeanProperty(bound = false, description
 435             = "UIClassID")
 436     public String getUIClassID() {
 437         return uiClassID;
 438     }
 439 
 440     /**
 441      * Returns whether calls to <code>add</code> and
 442      * <code>setLayout</code> are forwarded to the <code>contentPane</code>.
 443      *
 444      * @return true if <code>add</code> and <code>setLayout</code>
 445      *         are forwarded; false otherwise
 446      *
 447      * @see #addImpl
 448      * @see #setLayout
 449      * @see #setRootPaneCheckingEnabled
 450      * @see javax.swing.RootPaneContainer
 451      */
 452     protected boolean isRootPaneCheckingEnabled() {
 453         return rootPaneCheckingEnabled;
 454     }
 455 
 456     /**
 457      * Sets whether calls to <code>add</code> and
 458      * <code>setLayout</code> are forwarded to the <code>contentPane</code>.
 459      *
 460      * @param enabled  true if <code>add</code> and <code>setLayout</code>
 461      *        are forwarded, false if they should operate directly on the
 462      *        <code>JInternalFrame</code>.
 463      *
 464      * @see #addImpl
 465      * @see #setLayout
 466      * @see #isRootPaneCheckingEnabled
 467      * @see javax.swing.RootPaneContainer



 468      */
 469     @BeanProperty(hidden = true, description
 470             = "Whether the add and setLayout methods are forwarded")
 471     protected void setRootPaneCheckingEnabled(boolean enabled) {
 472         rootPaneCheckingEnabled = enabled;
 473     }
 474 
 475     /**
 476      * Adds the specified child <code>Component</code>.
 477      * This method is overridden to conditionally forward calls to the
 478      * <code>contentPane</code>.
 479      * By default, children are added to the <code>contentPane</code> instead
 480      * of the frame, refer to {@link javax.swing.RootPaneContainer} for
 481      * details.
 482      *
 483      * @param comp the component to be enhanced
 484      * @param constraints the constraints to be respected
 485      * @param index the index
 486      * @exception IllegalArgumentException if <code>index</code> is invalid
 487      * @exception IllegalArgumentException if adding the container's parent
 488      *                  to itself
 489      * @exception IllegalArgumentException if adding a window to a container
 490      *


 572     /**
 573      * Sets the <code>menuBar</code> property for this <code>JInternalFrame</code>.
 574      *
 575      * @param m  the <code>JMenuBar</code> to use in this internal frame
 576      * @see #getJMenuBar
 577      * @deprecated As of Swing version 1.0.3
 578      *  replaced by <code>setJMenuBar(JMenuBar m)</code>.
 579      */
 580     @Deprecated
 581     public void setMenuBar(JMenuBar m) {
 582         JMenuBar oldValue = getMenuBar();
 583         getRootPane().setJMenuBar(m);
 584         firePropertyChange(MENU_BAR_PROPERTY, oldValue, m);
 585     }
 586 
 587     /**
 588      * Sets the <code>menuBar</code> property for this <code>JInternalFrame</code>.
 589      *
 590      * @param m  the <code>JMenuBar</code> to use in this internal frame
 591      * @see #getJMenuBar





 592      */
 593     @BeanProperty(preferred = true, description
 594             = "The menu bar for accessing pulldown menus from this internal frame.")
 595     public void setJMenuBar(JMenuBar m){
 596         JMenuBar oldValue = getMenuBar();
 597         getRootPane().setJMenuBar(m);
 598         firePropertyChange(MENU_BAR_PROPERTY, oldValue, m);
 599     }
 600 
 601     // implements javax.swing.RootPaneContainer
 602     /**
 603      * Returns the content pane for this internal frame.
 604      * @return the content pane
 605      */
 606     public Container getContentPane() {
 607         return getRootPane().getContentPane();
 608     }
 609 
 610 
 611     /**
 612      * Sets this <code>JInternalFrame</code>'s <code>contentPane</code>
 613      * property.
 614      *
 615      * @param c  the content pane for this internal frame
 616      *
 617      * @exception java.awt.IllegalComponentStateException (a runtime
 618      *           exception) if the content pane parameter is <code>null</code>
 619      * @see RootPaneContainer#getContentPane





 620      */
 621     @BeanProperty(hidden = true, description
 622             = "The client area of the internal frame where child components are normally inserted.")
 623     public void setContentPane(Container c) {
 624         Container oldValue = getContentPane();
 625         getRootPane().setContentPane(c);
 626         firePropertyChange(CONTENT_PANE_PROPERTY, oldValue, c);
 627     }
 628 
 629     /**
 630      * Returns the layered pane for this internal frame.
 631      *
 632      * @return a <code>JLayeredPane</code> object
 633      * @see RootPaneContainer#setLayeredPane
 634      * @see RootPaneContainer#getLayeredPane
 635      */
 636     public JLayeredPane getLayeredPane() {
 637         return getRootPane().getLayeredPane();
 638     }
 639 
 640     /**
 641      * Sets this <code>JInternalFrame</code>'s
 642      * <code>layeredPane</code> property.
 643      *
 644      * @param layered the <code>JLayeredPane</code> for this internal frame
 645      *
 646      * @exception java.awt.IllegalComponentStateException (a runtime
 647      *           exception) if the layered pane parameter is <code>null</code>
 648      * @see RootPaneContainer#setLayeredPane




 649      */
 650     @BeanProperty(hidden = true, description
 651             = "The pane which holds the various desktop layers.")
 652     public void setLayeredPane(JLayeredPane layered) {
 653         JLayeredPane oldValue = getLayeredPane();
 654         getRootPane().setLayeredPane(layered);
 655         firePropertyChange(LAYERED_PANE_PROPERTY, oldValue, layered);
 656     }
 657 
 658     /**
 659      * Returns the glass pane for this internal frame.
 660      *
 661      * @return the glass pane
 662      * @see RootPaneContainer#setGlassPane
 663      */
 664     public Component getGlassPane() {
 665         return getRootPane().getGlassPane();
 666     }
 667 
 668     /**
 669      * Sets this <code>JInternalFrame</code>'s
 670      * <code>glassPane</code> property.
 671      *
 672      * @param glass the glass pane for this internal frame
 673      * @see RootPaneContainer#getGlassPane




 674      */
 675     @BeanProperty(hidden = true, description
 676             = "A transparent pane used for menu rendering.")
 677     public void setGlassPane(Component glass) {
 678         Component oldValue = getGlassPane();
 679         getRootPane().setGlassPane(glass);
 680         firePropertyChange(GLASS_PANE_PROPERTY, oldValue, glass);
 681     }
 682 
 683     /**
 684      * Returns the <code>rootPane</code> object for this internal frame.
 685      *
 686      * @return the <code>rootPane</code> property
 687      * @see RootPaneContainer#getRootPane
 688      */
 689     @BeanProperty(hidden = true, description
 690             = "The root pane used by this internal frame.")
 691     public JRootPane getRootPane() {
 692         return rootPane;
 693     }
 694 
 695 
 696     /**
 697      * Sets the <code>rootPane</code> property
 698      * for this <code>JInternalFrame</code>.
 699      * This method is called by the constructor.
 700      *
 701      * @param root  the new <code>JRootPane</code> object




 702      */
 703     protected void setRootPane(JRootPane root) {
 704         if(rootPane != null) {
 705             remove(rootPane);
 706         }
 707         JRootPane oldValue = getRootPane();
 708         rootPane = root;
 709         if(rootPane != null) {
 710             boolean checkingEnabled = isRootPaneCheckingEnabled();
 711             try {
 712                 setRootPaneCheckingEnabled(false);
 713                 add(rootPane, BorderLayout.CENTER);
 714             }
 715             finally {
 716                 setRootPaneCheckingEnabled(checkingEnabled);
 717             }
 718         }
 719         firePropertyChange(ROOT_PANE_PROPERTY, oldValue, root);
 720     }
 721 
 722     /**
 723      * Sets whether this <code>JInternalFrame</code> can be closed by
 724      * some user action.
 725      * @param b a boolean value, where <code>true</code> means this internal frame can be closed




 726      */
 727     @BeanProperty(preferred = true, description
 728             = "Indicates whether this internal frame can be closed.")
 729     public void setClosable(boolean b) {
 730         Boolean oldValue = closable ? Boolean.TRUE : Boolean.FALSE;
 731         Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
 732         closable = b;
 733         firePropertyChange("closable", oldValue, newValue);
 734     }
 735 
 736     /**
 737      * Returns whether this <code>JInternalFrame</code> can be closed by
 738      * some user action.
 739      * @return <code>true</code> if this internal frame can be closed
 740      */
 741     public boolean isClosable() {
 742         return closable;
 743     }
 744 
 745     /**
 746      * Returns whether this <code>JInternalFrame</code> is currently closed.
 747      * @return <code>true</code> if this internal frame is closed, <code>false</code> otherwise
 748      */


 770      * and then firing an <code>INTERNAL_FRAME_CLOSED</code> event.
 771      *
 772      * <p>
 773      *
 774      * <b>Note:</b>
 775      * To reuse an internal frame that has been closed,
 776      * you must add it to a container
 777      * (even if you never removed it from its previous container).
 778      * Typically, this container will be the <code>JDesktopPane</code>
 779      * that previously contained the internal frame.
 780      *
 781      * @param b must be <code>true</code>
 782      *
 783      * @exception PropertyVetoException when the attempt to set the
 784      *            property is vetoed by the <code>JInternalFrame</code>
 785      *
 786      * @see #isClosed()
 787      * @see #setDefaultCloseOperation
 788      * @see #dispose
 789      * @see javax.swing.event.InternalFrameEvent#INTERNAL_FRAME_CLOSING





 790      */
 791     @BeanProperty(description
 792             = "Indicates whether this internal frame has been closed.")
 793     public void setClosed(boolean b) throws PropertyVetoException {
 794         if (isClosed == b) {
 795             return;
 796         }
 797 
 798         Boolean oldValue = isClosed ? Boolean.TRUE : Boolean.FALSE;
 799         Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
 800         if (b) {
 801           fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_CLOSING);
 802         }
 803         fireVetoableChange(IS_CLOSED_PROPERTY, oldValue, newValue);
 804         isClosed = b;
 805         if (isClosed) {
 806           setVisible(false);
 807         }
 808         firePropertyChange(IS_CLOSED_PROPERTY, oldValue, newValue);
 809         if (isClosed) {
 810           dispose();
 811         } else if (!opened) {
 812           /* this bogus -- we haven't defined what
 813              setClosed(false) means. */
 814           //        fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_OPENED);
 815           //            opened = true;
 816         }
 817     }
 818 
 819     /**
 820      * Sets whether the <code>JInternalFrame</code> can be resized by some
 821      * user action.
 822      *
 823      * @param b  a boolean, where <code>true</code> means this internal frame can be resized





 824      */
 825     @BeanProperty(preferred = true, description
 826             = "Determines whether this internal frame can be resized by the user.")
 827     public void setResizable(boolean b) {
 828         Boolean oldValue = resizable ? Boolean.TRUE : Boolean.FALSE;
 829         Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
 830         resizable = b;
 831         firePropertyChange("resizable", oldValue, newValue);
 832     }
 833 
 834     /**
 835      * Returns whether the <code>JInternalFrame</code> can be resized
 836      * by some user action.
 837      *
 838      * @return <code>true</code> if this internal frame can be resized, <code>false</code> otherwise
 839      */
 840     public boolean isResizable() {
 841         // don't allow resizing when maximized.
 842         return isMaximum ? false : resizable;
 843     }
 844 
 845     /**
 846      * Sets the <code>iconable</code> property,
 847      * which must be <code>true</code>
 848      * for the user to be able to
 849      * make the <code>JInternalFrame</code> an icon.
 850      * Some look and feels might not implement iconification;
 851      * they will ignore this property.
 852      *
 853      * @param b  a boolean, where <code>true</code> means this internal frame can be iconified




 854      */
 855     @BeanProperty(preferred = true, description
 856             = "Determines whether this internal frame can be iconified.")
 857     public void setIconifiable(boolean b) {
 858         Boolean oldValue = iconable ? Boolean.TRUE : Boolean.FALSE;
 859         Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
 860         iconable = b;
 861         firePropertyChange("iconable", oldValue, newValue);
 862     }
 863 
 864     /**
 865      * Gets the <code>iconable</code> property,
 866      * which by default is <code>false</code>.
 867      *
 868      * @return the value of the <code>iconable</code> property.
 869      *
 870      * @see #setIconifiable
 871      */
 872     public boolean isIconifiable() {
 873         return iconable;
 874     }
 875 
 876     /**


 880      */
 881     public boolean isIcon() {
 882         return isIcon;
 883     }
 884 
 885     /**
 886      * Iconifies or de-iconifies this internal frame,
 887      * if the look and feel supports iconification.
 888      * If the internal frame's state changes to iconified,
 889      * this method fires an <code>INTERNAL_FRAME_ICONIFIED</code> event.
 890      * If the state changes to de-iconified,
 891      * an <code>INTERNAL_FRAME_DEICONIFIED</code> event is fired.
 892      *
 893      * @param b a boolean, where <code>true</code> means to iconify this internal frame and
 894      *          <code>false</code> means to de-iconify it
 895      * @exception PropertyVetoException when the attempt to set the
 896      *            property is vetoed by the <code>JInternalFrame</code>
 897      *
 898      * @see InternalFrameEvent#INTERNAL_FRAME_ICONIFIED
 899      * @see InternalFrameEvent#INTERNAL_FRAME_DEICONIFIED





 900      */
 901     @BeanProperty(description
 902             = "The image displayed when this internal frame is minimized.")
 903     public void setIcon(boolean b) throws PropertyVetoException {
 904         if (isIcon == b) {
 905             return;
 906         }
 907 
 908         /* If an internal frame is being iconified before it has a
 909            parent, (e.g., client wants it to start iconic), create the
 910            parent if possible so that we can place the icon in its
 911            proper place on the desktop. I am not sure the call to
 912            validate() is necessary, since we are not going to display
 913            this frame yet */
 914         firePropertyChange("ancestor", null, getParent());
 915 
 916         Boolean oldValue = isIcon ? Boolean.TRUE : Boolean.FALSE;
 917         Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
 918         fireVetoableChange(IS_ICON_PROPERTY, oldValue, newValue);
 919         isIcon = b;
 920         firePropertyChange(IS_ICON_PROPERTY, oldValue, newValue);
 921         if (b)
 922           fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_ICONIFIED);
 923         else
 924           fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_DEICONIFIED);
 925     }
 926 
 927     /**
 928      * Sets the <code>maximizable</code> property,
 929      * which determines whether the <code>JInternalFrame</code>
 930      * can be maximized by
 931      * some user action.
 932      * Some look and feels might not support maximizing internal frames;
 933      * they will ignore this property.
 934      *
 935      * @param b <code>true</code> to specify that this internal frame should be maximizable; <code>false</code> to specify that it should not be




 936      */
 937     @BeanProperty(preferred = true, description
 938             = "Determines whether this internal frame can be maximized.")
 939     public void setMaximizable(boolean b) {
 940         Boolean oldValue = maximizable ? Boolean.TRUE : Boolean.FALSE;
 941         Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
 942         maximizable = b;
 943         firePropertyChange("maximizable", oldValue, newValue);
 944     }
 945 
 946     /**
 947      * Gets the value of the <code>maximizable</code> property.
 948      *
 949      * @return the value of the <code>maximizable</code> property
 950      * @see #setMaximizable
 951      */
 952     public boolean isMaximizable() {
 953         return maximizable;
 954     }
 955 
 956     /**
 957      * Returns whether the <code>JInternalFrame</code> is currently maximized.
 958      *
 959      * @return <code>true</code> if this internal frame is maximized, <code>false</code> otherwise
 960      */
 961     public boolean isMaximum() {
 962         return isMaximum;
 963     }
 964 
 965     /**
 966      * Maximizes and restores this internal frame.  A maximized frame is resized to
 967      * fully fit the <code>JDesktopPane</code> area associated with the
 968      * <code>JInternalFrame</code>.
 969      * A restored frame's size is set to the <code>JInternalFrame</code>'s
 970      * actual size.
 971      *
 972      * @param b  a boolean, where <code>true</code> maximizes this internal frame and <code>false</code>
 973      *           restores it
 974      * @exception PropertyVetoException when the attempt to set the
 975      *            property is vetoed by the <code>JInternalFrame</code>




 976      */
 977     @BeanProperty(description
 978             = "Indicates whether this internal frame is maximized.")
 979     public void setMaximum(boolean b) throws PropertyVetoException {
 980         if (isMaximum == b) {
 981             return;
 982         }
 983 
 984         Boolean oldValue = isMaximum ? Boolean.TRUE : Boolean.FALSE;
 985         Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
 986         fireVetoableChange(IS_MAXIMUM_PROPERTY, oldValue, newValue);
 987         /* setting isMaximum above the event firing means that
 988            property listeners that, for some reason, test it will
 989            get it wrong... See, for example, getNormalBounds() */
 990         isMaximum = b;
 991         firePropertyChange(IS_MAXIMUM_PROPERTY, oldValue, newValue);
 992     }
 993 
 994     /**
 995      * Returns the title of the <code>JInternalFrame</code>.
 996      *
 997      * @return a <code>String</code> containing this internal frame's title
 998      * @see #setTitle
 999      */
1000     public String getTitle() {
1001         return title;
1002     }
1003 
1004     /**
1005      * Sets the <code>JInternalFrame</code> title. <code>title</code>
1006      * may have a <code>null</code> value.
1007      * @see #getTitle
1008      *
1009      * @param title  the <code>String</code> to display in the title bar




1010      */
1011     @BeanProperty(preferred = true, description
1012             = "The text displayed in the title bar.")
1013     public void setTitle(String title) {
1014         String oldValue = this.title;
1015         this.title = title;
1016         firePropertyChange(TITLE_PROPERTY, oldValue, title);
1017     }
1018 
1019     /**
1020      * Selects or deselects the internal frame
1021      * if it's showing.
1022      * A <code>JInternalFrame</code> normally draws its title bar
1023      * differently if it is
1024      * the selected frame, which indicates to the user that this
1025      * internal frame has the focus.
1026      * When this method changes the state of the internal frame
1027      * from deselected to selected, it fires an
1028      * <code>InternalFrameEvent.INTERNAL_FRAME_ACTIVATED</code> event.
1029      * If the change is from selected to deselected,
1030      * an <code>InternalFrameEvent.INTERNAL_FRAME_DEACTIVATED</code> event
1031      * is fired.
1032      *
1033      * @param selected  a boolean, where <code>true</code> means this internal frame
1034      *                  should become selected (currently active)
1035      *                  and <code>false</code> means it should become deselected
1036      * @exception PropertyVetoException when the attempt to set the
1037      *            property is vetoed by the <code>JInternalFrame</code>
1038      *
1039      * @see #isShowing
1040      * @see InternalFrameEvent#INTERNAL_FRAME_ACTIVATED
1041      * @see InternalFrameEvent#INTERNAL_FRAME_DEACTIVATED






1042      */
1043     @BeanProperty(description
1044             = "Indicates whether this internal frame is currently the active frame.")
1045     public void setSelected(boolean selected) throws PropertyVetoException {
1046        // The InternalFrame may already be selected, but the focus
1047        // may be outside it, so restore the focus to the subcomponent
1048        // which previously had it. See Bug 4302764.
1049         if (selected && isSelected) {
1050             restoreSubcomponentFocus();
1051             return;
1052         }
1053         // The internal frame or the desktop icon must be showing to allow
1054         // selection.  We may deselect even if neither is showing.
1055         if ((isSelected == selected) || (selected &&
1056             (isIcon ? !desktopIcon.isShowing() : !isShowing()))) {
1057             return;
1058         }
1059 
1060         Boolean oldValue = isSelected ? Boolean.TRUE : Boolean.FALSE;
1061         Boolean newValue = selected ? Boolean.TRUE : Boolean.FALSE;
1062         fireVetoableChange(IS_SELECTED_PROPERTY, oldValue, newValue);
1063 
1064         /* We don't want to leave focus in the previously selected


1094      */
1095     public boolean isSelected() {
1096         return isSelected;
1097     }
1098 
1099     /**
1100      * Sets an image to be displayed in the titlebar of this internal frame (usually
1101      * in the top-left corner).
1102      * This image is not the <code>desktopIcon</code> object, which
1103      * is the image displayed in the <code>JDesktop</code> when
1104      * this internal frame is iconified.
1105      *
1106      * Passing <code>null</code> to this function is valid,
1107      * but the look and feel
1108      * can choose the
1109      * appropriate behavior for that situation, such as displaying no icon
1110      * or a default icon for the look and feel.
1111      *
1112      * @param icon the <code>Icon</code> to display in the title bar
1113      * @see #getFrameIcon



1114      */
1115     @BeanProperty(description
1116             = "The icon shown in the top-left corner of this internal frame.")
1117   public void setFrameIcon(Icon icon) {
1118         Icon oldIcon = frameIcon;
1119         frameIcon = icon;
1120         firePropertyChange(FRAME_ICON_PROPERTY, oldIcon, icon);
1121     }
1122 
1123     /**
1124      * Returns the image displayed in the title bar of this internal frame (usually
1125      * in the top-left corner).
1126      *
1127      * @return the <code>Icon</code> displayed in the title bar
1128      * @see #setFrameIcon
1129      */
1130     public Icon getFrameIcon()  {
1131         return frameIcon;
1132     }
1133 
1134     /**
1135       * Convenience method that moves this component to position 0 if its
1136       * parent is a <code>JLayeredPane</code>.


1154     public void moveToBack() {
1155         if (isIcon()) {
1156             if (getDesktopIcon().getParent() instanceof JLayeredPane) {
1157                 ((JLayeredPane)getDesktopIcon().getParent()).
1158                     moveToBack(getDesktopIcon());
1159             }
1160         }
1161         else if (getParent() instanceof JLayeredPane) {
1162             ((JLayeredPane)getParent()).moveToBack(this);
1163         }
1164     }
1165 
1166     /**
1167      * Returns the last <code>Cursor</code> that was set by the
1168      * <code>setCursor</code> method that is not a resizable
1169      * <code>Cursor</code>.
1170      *
1171      * @return the last non-resizable <code>Cursor</code>
1172      * @since 1.6
1173      */
1174     @BeanProperty(bound = false)
1175     public Cursor getLastCursor() {
1176         return lastCursor;
1177     }
1178 
1179     /**
1180      * {@inheritDoc}
1181      * @since 1.6
1182      */
1183     public void setCursor(Cursor cursor) {
1184         if (cursor == null) {
1185             lastCursor = null;
1186             super.setCursor(cursor);
1187             return;
1188         }
1189         int type = cursor.getType();
1190         if (!(type == Cursor.SW_RESIZE_CURSOR  ||
1191               type == Cursor.SE_RESIZE_CURSOR  ||
1192               type == Cursor.NW_RESIZE_CURSOR  ||
1193               type == Cursor.NE_RESIZE_CURSOR  ||
1194               type == Cursor.N_RESIZE_CURSOR   ||
1195               type == Cursor.S_RESIZE_CURSOR   ||
1196               type == Cursor.W_RESIZE_CURSOR   ||
1197               type == Cursor.E_RESIZE_CURSOR)) {
1198             lastCursor = cursor;
1199         }
1200         super.setCursor(cursor);
1201     }
1202 
1203     /**
1204      * Convenience method for setting the layer attribute of this component.
1205      *
1206      * @param layer  an <code>Integer</code> object specifying this
1207      *          frame's desktop layer
1208      * @see JLayeredPane



1209      */
1210     @BeanProperty(bound = false, expert = true, description
1211             = "Specifies what desktop layer is used.")
1212     public void setLayer(Integer layer) {
1213         if(getParent() != null && getParent() instanceof JLayeredPane) {
1214             // Normally we want to do this, as it causes the LayeredPane
1215             // to draw properly.
1216             JLayeredPane p = (JLayeredPane)getParent();
1217             p.setLayer(this, layer.intValue(), p.getPosition(this));
1218         } else {
1219              // Try to do the right thing
1220              JLayeredPane.putLayer(this, layer.intValue());
1221              if(getParent() != null)
1222                  getParent().repaint(getX(), getY(), getWidth(), getHeight());
1223         }
1224     }
1225 
1226     /**
1227      * Convenience method for setting the layer attribute of this component.
1228      * The method <code>setLayer(Integer)</code> should be used for
1229      * layer values predefined in <code>JLayeredPane</code>.
1230      * When using <code>setLayer(int)</code>, care must be taken not to
1231      * accidentally clash with those values.
1232      *
1233      * @param layer  an integer specifying this internal frame's desktop layer
1234      *
1235      * @since 1.3
1236      *
1237      * @see #setLayer(Integer)
1238      * @see JLayeredPane



1239      */
1240     @BeanProperty(bound = false, expert = true, description
1241             = "Specifies what desktop layer is used.")
1242     public void setLayer(int layer) {
1243       this.setLayer(Integer.valueOf(layer));
1244     }
1245 
1246     /**
1247      * Convenience method for getting the layer attribute of this component.
1248      *
1249      * @return  an <code>Integer</code> object specifying this
1250      *          frame's desktop layer
1251      * @see JLayeredPane
1252       */
1253     public int getLayer() {
1254         return JLayeredPane.getLayer(this);
1255     }
1256 
1257     /**
1258       * Convenience method that searches the ancestor hierarchy for a
1259       * <code>JDesktop</code> instance. If <code>JInternalFrame</code>
1260       * finds none, the <code>desktopIcon</code> tree is searched.
1261       *
1262       * @return the <code>JDesktopPane</code> this internal frame belongs to,
1263       *         or <code>null</code> if none is found
1264       */
1265     @BeanProperty(bound = false)
1266     public JDesktopPane getDesktopPane() {
1267         Container p;
1268 
1269         // Search upward for desktop
1270         p = getParent();
1271         while(p != null && !(p instanceof JDesktopPane))
1272             p = p.getParent();
1273 
1274         if(p == null) {
1275            // search its icon parent for desktop
1276            p = getDesktopIcon().getParent();
1277            while(p != null && !(p instanceof JDesktopPane))
1278                 p = p.getParent();
1279         }
1280 
1281         return (JDesktopPane)p;
1282     }
1283 
1284     /**
1285      * Sets the <code>JDesktopIcon</code> associated with this
1286      * <code>JInternalFrame</code>.
1287      *
1288      * @param d the <code>JDesktopIcon</code> to display on the desktop
1289      * @see #getDesktopIcon



1290      */
1291     @BeanProperty(description
1292             = "The icon shown when this internal frame is minimized.")
1293     public void setDesktopIcon(JDesktopIcon d) {
1294         JDesktopIcon oldValue = getDesktopIcon();
1295         desktopIcon = d;
1296         firePropertyChange("desktopIcon", oldValue, d);
1297     }
1298 
1299     /**
1300      * Returns the <code>JDesktopIcon</code> used when this
1301      * <code>JInternalFrame</code> is iconified.
1302      *
1303      * @return the <code>JDesktopIcon</code> displayed on the desktop
1304      * @see #setDesktopIcon
1305      */
1306     public JDesktopIcon getDesktopIcon() {
1307         return desktopIcon;
1308     }
1309 
1310     /**
1311      * If the <code>JInternalFrame</code> is not in maximized state, returns
1312      * <code>getBounds()</code>; otherwise, returns the bounds that the


1362      * Returns the child component of this <code>JInternalFrame</code>
1363      * that will receive the
1364      * focus when this <code>JInternalFrame</code> is selected.
1365      * If this <code>JInternalFrame</code> is
1366      * currently selected, this method returns the same component as
1367      * the <code>getFocusOwner</code> method.
1368      * If this <code>JInternalFrame</code> is not selected,
1369      * then the child component that most recently requested focus will be
1370      * returned. If no child component has ever requested focus, then this
1371      * <code>JInternalFrame</code>'s initial focusable component is returned.
1372      * If no such
1373      * child exists, then this <code>JInternalFrame</code>'s default component
1374      * to focus is returned.
1375      *
1376      * @return the child component that will receive focus when this
1377      *         <code>JInternalFrame</code> is selected
1378      * @see #getFocusOwner
1379      * @see #isSelected
1380      * @since 1.4
1381      */
1382     @BeanProperty(bound = false)
1383     public Component getMostRecentFocusOwner() {
1384         if (isSelected()) {
1385             return getFocusOwner();
1386         }
1387 
1388         if (lastFocusOwner != null) {
1389             return lastFocusOwner;
1390         }
1391 
1392         FocusTraversalPolicy policy = getFocusTraversalPolicy();
1393         if (policy instanceof InternalFrameFocusTraversalPolicy) {
1394             return ((InternalFrameFocusTraversalPolicy)policy).
1395                 getInitialComponent(this);
1396         }
1397 
1398         Component toFocus = policy.getDefaultComponent(this);
1399         if (toFocus != null) {
1400             return toFocus;
1401         }
1402         return getContentPane();


1476      * Removes the specified internal frame listener so that it no longer
1477      * receives internal frame events from this internal frame.
1478      *
1479      * @param l the internal frame listener
1480      */
1481     public void removeInternalFrameListener(InternalFrameListener l) {  // remind: sync??
1482       listenerList.remove(InternalFrameListener.class, l);
1483     }
1484 
1485     /**
1486      * Returns an array of all the <code>InternalFrameListener</code>s added
1487      * to this <code>JInternalFrame</code> with
1488      * <code>addInternalFrameListener</code>.
1489      *
1490      * @return all of the <code>InternalFrameListener</code>s added or an empty
1491      *         array if no listeners have been added
1492      * @since 1.4
1493      *
1494      * @see #addInternalFrameListener
1495      */
1496     @BeanProperty(bound = false)
1497     public InternalFrameListener[] getInternalFrameListeners() {
1498         return listenerList.getListeners(InternalFrameListener.class);
1499     }
1500 
1501     // remind: name ok? all one method ok? need to be synchronized?
1502     /**
1503      * Fires an internal frame event.
1504      *
1505      * @param id  the type of the event being fired; one of the following:
1506      * <ul>
1507      * <li><code>InternalFrameEvent.INTERNAL_FRAME_OPENED</code>
1508      * <li><code>InternalFrameEvent.INTERNAL_FRAME_CLOSING</code>
1509      * <li><code>InternalFrameEvent.INTERNAL_FRAME_CLOSED</code>
1510      * <li><code>InternalFrameEvent.INTERNAL_FRAME_ICONIFIED</code>
1511      * <li><code>InternalFrameEvent.INTERNAL_FRAME_DEICONIFIED</code>
1512      * <li><code>InternalFrameEvent.INTERNAL_FRAME_ACTIVATED</code>
1513      * <li><code>InternalFrameEvent.INTERNAL_FRAME_DEACTIVATED</code>
1514      * </ul>
1515      * If the event type is not one of the above, nothing happens.
1516      */


1808      *
1809      * @return <code>true</code>
1810      * @see #setFocusCycleRoot
1811      * @see java.awt.Container#setFocusTraversalPolicy
1812      * @see java.awt.Container#getFocusTraversalPolicy
1813      * @since 1.4
1814      */
1815     public final boolean isFocusCycleRoot() {
1816         return true;
1817     }
1818 
1819     /**
1820      * Always returns <code>null</code> because <code>JInternalFrame</code>s
1821      * must always be roots of a focus
1822      * traversal cycle.
1823      *
1824      * @return <code>null</code>
1825      * @see java.awt.Container#isFocusCycleRoot()
1826      * @since 1.4
1827      */
1828     @BeanProperty(bound = false)
1829     public final Container getFocusCycleRootAncestor() {
1830         return null;
1831     }
1832 
1833     /**
1834      * Gets the warning string that is displayed with this internal frame.
1835      * Since an internal frame is always secure (since it's fully
1836      * contained within a window that might need a warning string)
1837      * this method always returns <code>null</code>.
1838      * @return    <code>null</code>
1839      * @see       java.awt.Window#getWarningString
1840      */
1841     @BeanProperty(bound = false)
1842     public final String getWarningString() {
1843         return null;
1844     }
1845 
1846     /**
1847      * See <code>readObject</code> and <code>writeObject</code>
1848      * in <code>JComponent</code> for more
1849      * information about serialization in Swing.
1850      */
1851     private void writeObject(ObjectOutputStream s) throws IOException {
1852         s.defaultWriteObject();
1853         if (getUIClassID().equals(uiClassID)) {
1854             byte count = JComponent.getWriteObjCounter(this);
1855             JComponent.setWriteObjCounter(this, --count);
1856             if (count == 0 && ui != null) {
1857                 boolean old = isRootPaneCheckingEnabled();
1858                 try {
1859                     setRootPaneCheckingEnabled(false);
1860                     ui.installUI(this);
1861                 } finally {


1957 
1958     // ======= end optimized frame dragging defence code ==============
1959 
1960 /////////////////
1961 // Accessibility support
1962 ////////////////
1963 
1964     /**
1965      * Gets the <code>AccessibleContext</code> associated with this
1966      * <code>JInternalFrame</code>.
1967      * For internal frames, the <code>AccessibleContext</code>
1968      * takes the form of an
1969      * <code>AccessibleJInternalFrame</code> object.
1970      * A new <code>AccessibleJInternalFrame</code> instance is created if necessary.
1971      *
1972      * @return an <code>AccessibleJInternalFrame</code> that serves as the
1973      *         <code>AccessibleContext</code> of this
1974      *         <code>JInternalFrame</code>
1975      * @see AccessibleJInternalFrame
1976      */
1977     @BeanProperty(bound = false)
1978     public AccessibleContext getAccessibleContext() {
1979         if (accessibleContext == null) {
1980             accessibleContext = new AccessibleJInternalFrame();
1981         }
1982         return accessibleContext;
1983     }
1984 
1985     /**
1986      * This class implements accessibility support for the
1987      * <code>JInternalFrame</code> class.  It provides an implementation of the
1988      * Java Accessibility API appropriate to internal frame user-interface
1989      * elements.
1990      * <p>
1991      * <strong>Warning:</strong>
1992      * Serialized objects of this class will not be compatible with
1993      * future Swing releases. The current serialization support is
1994      * appropriate for short term storage or RMI between applications running
1995      * the same version of Swing.  As of 1.4, support for long term storage
1996      * of all JavaBeans&trade;
1997      * has been added to the <code>java.beans</code> package.