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

Print this page




  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.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>.


  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      */


 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() {


 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      *


 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      */


 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     /**


 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
1095         // selection.  We may deselect even if neither is showing.
1096         if ((isSelected == selected) || (selected &&
1097             (isIcon ? !desktopIcon.isShowing() : !isShowing()))) {
1098             return;
1099         }
1100 
1101         Boolean oldValue = isSelected ? Boolean.TRUE : Boolean.FALSE;
1102         Boolean newValue = selected ? Boolean.TRUE : Boolean.FALSE;
1103         fireVetoableChange(IS_SELECTED_PROPERTY, oldValue, newValue);
1104 
1105         /* We don't want to leave focus in the previously selected


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>.


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


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);
1443         if (toFocus != null) {
1444             return toFocus;
1445         }
1446         return getContentPane();


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      */


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 {


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.




  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.*;

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


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





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


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





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


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



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



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


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





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





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




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




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




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




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


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





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





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




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


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





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




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




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




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






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


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



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


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



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



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



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


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


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


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