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™
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™
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™
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™
1999 * has been added to the <code>java.beans</code> package.
|