home *** CD-ROM | disk | FTP | other *** search
/ Chip 1998 November / Chip_1998-11_cd.bin / tema / Cafe / jfc.bin / JInternalFrame.java < prev    next >
Text File  |  1998-02-26  |  53KB  |  1,639 lines

  1. /* @(#)JInternalFrame.java    1.54 98/02/05
  2.  * 
  3.  * Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
  4.  * 
  5.  * This software is the confidential and proprietary information of Sun
  6.  * Microsystems, Inc. ("Confidential Information").  You shall not
  7.  * disclose such Confidential Information and shall use it only in
  8.  * accordance with the terms of the license agreement you entered into
  9.  * with Sun.
  10.  * 
  11.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
  12.  * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  13.  * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
  14.  * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
  15.  * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
  16.  * THIS SOFTWARE OR ITS DERIVATIVES.
  17.  * 
  18.  */
  19.  
  20. package com.sun.java.swing;
  21.  
  22. import java.awt.*;
  23. import java.awt.event.*;
  24. import java.beans.PropertyVetoException;
  25. import java.beans.PropertyChangeEvent;
  26. import com.sun.java.swing.border.Border;
  27. import com.sun.java.swing.event.InternalFrameEvent;
  28. import com.sun.java.swing.event.InternalFrameListener;
  29. import com.sun.java.swing.plaf.*;
  30.  
  31. import com.sun.java.accessibility.*;
  32.  
  33.  
  34. /** A lightweight object that provides many of the features of
  35.  * a native frame, including dragging, closing, becoming an icon,
  36.  * resizing, title display, and support for a menu bar. Generally,
  37.  * you will create an instance and add it to a JDesktopPane.
  38.  * <p>
  39.  * The JInternalFrame has a 'contentPane' that is used to describe the
  40.  * area of the component where normal child components should be placed.
  41.  * So, if you wanted build a JInternalFrame that had a number of buttons
  42.  * arranged through a BorderLayout object, you might do something like:
  43.  * <PRE>
  44.  *    JComponent c = frame.getContentPane();
  45.  *    c.setLayoutManager(new BorderLayout());
  46.  *    c.add(new JButton(), BorderLayout.NORTH);
  47.  *    c.add(new JButton(), BorderLayout.CENTER);
  48.  * <PRE>
  49.  *
  50.  * <p>
  51.  * Please see the JRootPane documentation for a complete description of
  52.  * the contentPane(), glassPane(), and layeredPane() components.
  53.  * <p>
  54.  * Warning: serialized objects of this class will not be compatible with
  55.  * future swing releases.  The current serialization support is appropriate 
  56.  * for short term storage or RMI between Swing1.0 applications.  It will
  57.  * not be possible to load serialized Swing1.0 objects with future releases
  58.  * of Swing.  The JDK1.2 release of Swing will be the compatibility
  59.  * baseline for the serialized form of Swing objects.
  60.  *
  61.  * @see JDesktopPane
  62.  * @see JDesktopIcon
  63.  * @see DesktopManager
  64.  * @see JRootPane
  65.  *
  66.  * @version 1.54 02/05/98
  67.  * @author David Kloba
  68.  * @beaninfo
  69.  *      attribute: isContainer true
  70.  *      attribute: containerDelegate getContentPane
  71.  *      description: A frame container which is contained within 
  72.  *                   another window.
  73.  */
  74. public class JInternalFrame extends JComponent implements 
  75.         Accessible, MouseListener, MouseMotionListener, WindowConstants, 
  76.         RootPaneContainer, ComponentListener
  77. {
  78.     /**
  79.      * @see #getRootPane
  80.      * @see #setRootPane
  81.      */
  82.     protected JRootPane rootPane;
  83.  
  84.     /**
  85.      * @see #isRootPaneCheckingEnabled
  86.      * @see #setRootPaneCheckingEnabled
  87.      */
  88.     protected boolean rootPaneCheckingEnabled = false;
  89.  
  90.     protected boolean closable;
  91.     protected boolean isClosed;
  92.     protected boolean maximizable;
  93.     protected boolean isMaximum;   
  94.     protected boolean iconable;
  95.     protected boolean isIcon;   
  96.     protected boolean resizable;
  97.     protected boolean isSelected;
  98.     protected Icon frameIcon;
  99.     protected String  title;
  100.     protected JDesktopIcon desktopIcon;
  101.  
  102.     transient InternalFrameListener internalFrameListener;
  103.     private boolean opened;
  104.  
  105.     private int defaultCloseOperation = HIDE_ON_CLOSE;
  106.  
  107.     /** Bound property name. */
  108.     public final static String CONTENT_PANE_PROPERTY = "contentPane";
  109.     /** Bound property name. */
  110.     public final static String MENU_BAR_PROPERTY = "menuBar";
  111.     /** Bound property name. */
  112.     public final static String TITLE_PROPERTY = "title";
  113.     /** Bound property name. */
  114.     public final static String LAYERED_PANE_PROPERTY = "layeredPane";
  115.     /** Bound property name. */
  116.     public final static String ROOT_PANE_PROPERTY = "rootPane";
  117.     /** Bound property name. */
  118.     public final static String GLASS_PANE_PROPERTY = "glassPane";
  119.  
  120.     /** Constrained property name indicated that this frame has selected status. */
  121.     public final static String IS_SELECTED_PROPERTY = "isSelected";
  122.     /** Constrained property name indicating that the frame is closed. */
  123.     public final static String IS_CLOSED_PROPERTY = "isClosed";
  124.     /** Constrained property name indicating that the frame is maximized. */
  125.     public final static String IS_MAXIMUM_PROPERTY = "isMaximum";
  126.     /** Constrained property name indicating that the frame is iconified. */
  127.     public final static String IS_ICON_PROPERTY = "isIcon";
  128.  
  129.     /** Creates a JInternalFrame with no title, and all boolean setting false.*/
  130.     public JInternalFrame() {
  131.         this("", false, false, false, false);
  132.     }
  133.  
  134.     /** Creates a JInternalFrame with <b>title</b>, and all boolean setting false.*/
  135.     public JInternalFrame(String title) {
  136.         this(title, false, false, false, false);
  137.     }
  138.  
  139.     public JInternalFrame(String title, boolean resizable) {
  140.         this(title, resizable, false, false, false);
  141.     }
  142.  
  143.     public JInternalFrame(String title, boolean resizable, boolean closable) {
  144.         this(title, resizable, closable, false, false);
  145.     }
  146.  
  147.     public JInternalFrame(String title, boolean resizable, boolean closable,
  148.                           boolean maximizable) {
  149.         this(title, resizable, closable, maximizable, false);
  150.     }
  151.  
  152.     /** Primitive creation method that sets the appropriate values. 
  153.       */
  154.     public JInternalFrame(String title, boolean resizable, boolean closable, 
  155.                                 boolean maximizable, boolean iconifiable) {
  156.     
  157.     setRootPane(createRootPane());
  158.     setLayout(new BorderLayout());
  159.         this.title = title;
  160.         this.resizable = resizable;
  161.         this.closable = closable;
  162.         this.maximizable = maximizable;
  163.     isMaximum = false;
  164.         this.iconable = iconifiable;                         
  165.     isIcon = false;
  166.     updateUI();
  167.     setRootPaneCheckingEnabled(true);
  168.         desktopIcon = new JDesktopIcon(this);
  169.         if (isVisible()) {
  170.             postInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_OPENED);
  171.             opened = true;
  172.         }
  173.     }
  174.  
  175.     protected JRootPane createRootPane() {
  176.     return new JRootPane();
  177.     }
  178.  
  179.     public InternalFrameUI getUI() {
  180.         return (InternalFrameUI)ui;
  181.     }
  182.  
  183.     /**
  184.      * Sets the UI delegate for this JInternalFrame.
  185.      * @beaninfo
  186.      *     expert: true
  187.      *     description: The InternalFrameUI implementation that 
  188.      *                  defines the labels look and feel.
  189.      */
  190.     public void setUI(InternalFrameUI ui) {
  191.     boolean checkingEnabled = isRootPaneCheckingEnabled();
  192.     try {
  193.         setRootPaneCheckingEnabled(false);
  194.         super.setUI(ui);
  195.     }
  196.     finally {
  197.             setRootPaneCheckingEnabled(checkingEnabled);
  198.     }
  199.     }
  200.  
  201.     public void updateUI() {
  202.         setUI((InternalFrameUI)UIManager.getUI(this));
  203.     invalidate();
  204.         if (desktopIcon != null) {
  205.             desktopIcon.updateUIWhenHidden();
  206.         }
  207.     }
  208.  
  209.     /* This method is called if updateUI was called on the associated
  210.      * JDesktopIcon.  It's necessary to avoid infinite recursion.
  211.      */
  212.     void updateUIWhenHidden() {
  213.         setUI((InternalFrameUI)UIManager.getUI(this));
  214.     invalidate();
  215.         Component[] children = getComponents();
  216.     if (children != null) {
  217.         for(int i = 0; i < children.length; i++) {
  218.         SwingUtilities.updateComponentTreeUI(children[i]);
  219.         }
  220.     }
  221.     }
  222.  
  223.  
  224.     /**
  225.      * @return "InternalFrameUI"
  226.      * @see JComponent#getUIClassID
  227.      * @see UIDefaults#getUI
  228.      * @beaninfo
  229.      *     description: UIClassID
  230.      */
  231.     public String getUIClassID() {
  232.     return "InternalFrameUI";
  233.     }
  234.  
  235.  
  236.  
  237.     /**
  238.      * @return true if add and setLayout should be checked
  239.      * @see #addImpl
  240.      * @see #setLayout
  241.      * @see #setRootPaneCheckingEnabled
  242.      */
  243.     protected boolean isRootPaneCheckingEnabled() {
  244.     return rootPaneCheckingEnabled;
  245.     }
  246.  
  247.  
  248.     /**
  249.      * If true then calls to add() and setLayout() will cause an exception
  250.      * to be thrown.  
  251.      *
  252.      * @see #addImpl
  253.      * @see #setLayout
  254.      * @see #isRootPaneCheckingEnabled
  255.      */
  256.     protected void setRootPaneCheckingEnabled(boolean enabled) {
  257.     rootPaneCheckingEnabled = enabled;
  258.     }
  259.  
  260.  
  261.     /**
  262.      * Create an runtime exception with a message like:
  263.      * <pre>
  264.      * "Do not use JFrame.add() use JFrame.getContentPane().add() instead"
  265.      * </pre>
  266.      */
  267.     private Error createRootPaneException(String op) {
  268.     String type = getClass().getName();
  269.     return new Error(
  270.             "Do not use " + type + "." + op + "() use " 
  271.                           + type + ".getContentPane()." + op + "() instead");
  272.     }
  273.  
  274.  
  275.     /**
  276.      * By default, children may not be added directly to a this component,
  277.      * they must be added to its contentPane instead.  For example:
  278.      * <pre>
  279.      * thisComponent.getContentPane().add(child)
  280.      * </pre>
  281.      * An attempt to add to directly to this component will cause an
  282.      * runtime exception to be thrown.  Subclasses can disable this
  283.      * behavior.
  284.      * 
  285.      * @see #setRootPaneCheckingEnabled
  286.      * @exception Error if called with rootPaneChecking true
  287.      */
  288.     protected void addImpl(Component comp, Object constraints, int index) 
  289.     {
  290.         if(isRootPaneCheckingEnabled()) {
  291.         throw createRootPaneException("add");
  292.     }
  293.     else {
  294.         super.addImpl(comp, constraints, index);
  295.     }
  296.     }
  297.  
  298.  
  299.     /**
  300.      * By default the layout of this component may not be set,
  301.      * the layout of its contentPane should be set instead.  
  302.      * For example:
  303.      * <pre>
  304.      * thiComponent.getContentPane().setLayout(new BorderLayout())
  305.      * </pre>
  306.      * An attempt to set the layout of this component will cause an
  307.      * runtime exception to be thrown.  Subclasses can disable this
  308.      * behavior.
  309.      * 
  310.      * @see #setRootPaneCheckingEnabled
  311.      * @exception Error if called with rootPaneChecking true
  312.      */
  313.     public void setLayout(LayoutManager manager) {
  314.         if(isRootPaneCheckingEnabled()) {
  315.         throw createRootPaneException("setLayout");
  316.     }
  317.     else {
  318.         super.setLayout(manager);
  319.     }
  320.     }
  321.  
  322.  
  323. //////////////////////////////////////////////////////////////////////////
  324. /// Property Methods
  325. //////////////////////////////////////////////////////////////////////////
  326.  
  327.     /**
  328.      * Returns the current JMenuBar for this JInternalFrame, or null
  329.      * if no menu bar has been set.
  330.      * @see setMenuBar
  331.      */
  332.     public JMenuBar getMenuBar() {
  333.         return getRootPane().getMenuBar();
  334.     }
  335.  
  336.     /**
  337.      * Sets the JMenuBar for this JInternalFrame.
  338.      * @see getMenuBar
  339.      * @beaninfo
  340.      *     preferred: true
  341.      *     description: The menubar for accessing pulldown menus 
  342.      *                  from this frame.
  343.      */
  344.     public void setMenuBar(JMenuBar m) {
  345.     JMenuBar oldValue = getMenuBar();
  346.         getRootPane().setMenuBar(m);
  347.     firePropertyChange(MENU_BAR_PROPERTY, oldValue, m);    
  348.     }
  349.  
  350.  
  351.     /**
  352.      * @see RootPaneContainer#getContentPane
  353.      */
  354.     public Container getContentPane() {
  355.         return getRootPane().getContentPane();
  356.     }
  357.  
  358.  
  359.     /**
  360.      * Sets this JInternalFrame's content pane.
  361.      * @see RootPaneContainer#getContentPane
  362.      * @beaninfo
  363.      *     bound: true
  364.      *     hidden: true
  365.      *     description: The client area of the frame where child 
  366.      *                  components are normally inserted.
  367.      */
  368.     public void setContentPane(Container c) {
  369.     Container oldValue = getContentPane();
  370.         getRootPane().setContentPane(c);
  371.     firePropertyChange(CONTENT_PANE_PROPERTY, oldValue, c);
  372.     }
  373.  
  374.  
  375.     /**
  376.      * @see RootPaneContainer#setLayeredPane
  377.      */
  378.     public JLayeredPane getLayeredPane() { 
  379.     return getRootPane().getLayeredPane(); 
  380.     }
  381.  
  382.  
  383.     /**
  384.      * @see RootPaneContainer#setLayeredPane
  385.      * @beaninfo
  386.      *     hidden: true
  387.      *     bound: true
  388.      *     description: The pane which holds the various desktop layers.
  389.      */
  390.     public void setLayeredPane(JLayeredPane layered) {
  391.     JLayeredPane oldValue = getLayeredPane();
  392.     getRootPane().setLayeredPane(layered);
  393.     firePropertyChange(LAYERED_PANE_PROPERTY, oldValue, layered);    
  394.     }
  395.  
  396.  
  397.     /**
  398.      * @see RootPaneContainer#setGlassPane
  399.      */
  400.     public Component getGlassPane() { 
  401.     return getRootPane().getGlassPane(); 
  402.     }
  403.  
  404.  
  405.     /**
  406.      * @see RootPaneContainer#getGlassPane
  407.      * @beaninfo
  408.      *     hidden: true
  409.      *     description: A transparent pane used for menu rendering.
  410.      */
  411.     public void setGlassPane(Component glass) {
  412.     Component oldValue = getGlassPane();
  413.     getRootPane().setGlassPane(glass);
  414.     firePropertyChange(GLASS_PANE_PROPERTY, oldValue, glass);    
  415.     }
  416.  
  417.  
  418.     /**
  419.      * @see RootPaneContainer#getRootPane
  420.      */
  421.     public JRootPane getRootPane() { 
  422.     return rootPane; 
  423.     }
  424.  
  425.  
  426.     /**
  427.      * Set the rootPane property.  This method is called by the constructor.
  428.      * @beaninfo
  429.      *     hidden: true
  430.      *     beaninfo: The rootPane used by this frame.
  431.      */
  432.     protected void setRootPane(JRootPane root) {
  433.     if(rootPane != null) {
  434.         remove(rootPane);
  435.     }
  436.     JRootPane oldValue = getRootPane();
  437.     rootPane = root;
  438.     if(rootPane != null) {
  439.         boolean checkingEnabled = isRootPaneCheckingEnabled();
  440.         try {
  441.         setRootPaneCheckingEnabled(false);
  442.         add(rootPane, BorderLayout.CENTER);
  443.         }
  444.         finally {
  445.         setRootPaneCheckingEnabled(checkingEnabled);
  446.         }
  447.         }
  448.     firePropertyChange(ROOT_PANE_PROPERTY, oldValue, root);    
  449.     }
  450.  
  451.  
  452.     /**
  453.      * Set the visible state of the object.
  454.      *
  455.      * @param b if true, shows this object; otherwise, hides it 
  456.      */
  457.     public void setVisible(boolean b) {
  458.         super.setVisible(b);
  459.         // If first time shown, generate InternalFrameOpened event
  460.         if (!opened) {
  461.             postInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_OPENED);
  462.             opened = true;
  463.         }
  464.     }
  465.  
  466.     /** 
  467.      * Set that this JInternalFrame can be closed by some user action. 
  468.      * @beaninfo
  469.      *     preferred: true
  470.      *     description: Indicates whether this frame can be closed.
  471.      */
  472.     public void setClosable(boolean b) {
  473.         closable = b;
  474.     }
  475.  
  476.     /** 
  477.      * Returns whether this JInternalFrame be closed by some user action. 
  478.      */
  479.     public boolean isClosable() {
  480.         return closable;
  481.     }
  482.  
  483.     public boolean isClosed() {
  484.     return isClosed;
  485.     }
  486.  
  487.     /** Calling this method with true, will cause the frame to close.
  488.      *
  489.      * @exception PropertyVetoException when the attempt to set the 
  490.      *            property is vetoed by the receiver.
  491.      * @beaninfo
  492.      *     constrained: true
  493.      *     description: Indicates that the frame has been closed.
  494.      */
  495.     public void setClosed(boolean b) throws PropertyVetoException {
  496.         if (isClosed == b) {
  497.             return;
  498.         }
  499.  
  500.     Boolean oldValue = isClosed ? Boolean.TRUE : Boolean.FALSE; 
  501.     Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
  502.     fireVetoableChange(IS_CLOSED_PROPERTY, oldValue, newValue);
  503.     isClosed = b;
  504.         if (isClosed) {
  505.             /* Dispatch a closed event to any listeners.  We can't post
  506.              * an event since firing IS_CLOSED_PROPERTY causes this
  507.              * frame to be removed from its parent, which causes any
  508.              * of its events on the EventQueue to get purged.
  509.              */
  510.             synchronized (this) {
  511.                 if (internalFrameListener != null) {
  512.                     InternalFrameEvent e = new InternalFrameEvent(
  513.                         this, InternalFrameEvent.INTERNAL_FRAME_CLOSED);
  514.                     dispatchEvent(e);
  515.                 }
  516.             }
  517.             opened = false;
  518.         } else if (!opened) {
  519.             postInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_OPENED);
  520.             opened = true;
  521.         }
  522.     firePropertyChange(IS_CLOSED_PROPERTY, oldValue, newValue);
  523.     }
  524.  
  525.     /** 
  526.      * Set that the JInternalFrame resizable by some user action. 
  527.      * @beaninfo
  528.      *     preferred: true
  529.      *     description: Determines whether the frame can be resized 
  530.      *                  by the user.
  531.      */
  532.     public void setResizable(boolean b) {
  533.         resizable = b;
  534.     }
  535.  
  536.     public boolean isResizable() {
  537.         // don't allow resizing when maximized.
  538.         return isMaximum ? false : resizable; 
  539.     }
  540.  
  541.     /** 
  542.      * Set that the JInternalFrame can be made an icon by some user action. 
  543.      * @beaninfo:
  544.      *     preferred: true
  545.      *     bound: false
  546.      *     description: Determines whether this frame can be iconified.
  547.      */
  548.     public void setIconifiable(boolean b) {
  549.         iconable = b;
  550.     }
  551.  
  552.     public boolean isIconifiable() {
  553.         return iconable; 
  554.     }
  555.  
  556.     public boolean isIcon() {
  557.     return isIcon;
  558.     }
  559.  
  560.     /** 
  561.      * Setting this property to true will iconify the frame, false will 
  562.      * deiconify. 
  563.      *
  564.      * @exception PropertyVetoException when the attempt to set the 
  565.      *            property is vetoed by the receiver.
  566.      * @beaninfo
  567.      *     constrained: true
  568.      *     description: The image displayed when this frame is minimized.
  569.      */
  570.     public void setIcon(boolean b) throws PropertyVetoException {
  571.         if (isIcon == b) {
  572.             return;
  573.         }
  574.  
  575.     Boolean oldValue = isIcon ? Boolean.TRUE : Boolean.FALSE; 
  576.     Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
  577.     fireVetoableChange(IS_ICON_PROPERTY, oldValue, newValue);
  578.     isIcon = b;
  579.     firePropertyChange(IS_ICON_PROPERTY, oldValue, newValue);
  580.         postInternalFrameEvent(
  581.             b ? InternalFrameEvent.INTERNAL_FRAME_ICONIFIED :
  582.                 InternalFrameEvent.INTERNAL_FRAME_DEICONIFIED);
  583.     }
  584.  
  585.     /** 
  586.      * Set that the JInternalFrame can be maximized by some user action. 
  587.      * @beaninfo
  588.      *     preferred: true
  589.      *     description: Determines whether this frame can be maximized.
  590.      */
  591.     public void setMaximizable(boolean b) {
  592.         maximizable = b;
  593.     }
  594.  
  595.     public boolean isMaximizable() {
  596.         return maximizable; 
  597.     }
  598.  
  599.     public boolean isMaximum() {
  600.     return isMaximum;
  601.     }
  602.  
  603.     /**
  604.      * Setting this property to true will maximize the frame, 
  605.      * false will minimize.
  606.      *
  607.      * @exception PropertyVetoException when the attempt to set the 
  608.      *            property is vetoed by the receiver.
  609.      * @beaninfo
  610.      *     constrained: true
  611.      *     description: Indicates whether the frame is maximized.
  612.      */
  613.     public void setMaximum(boolean b) throws PropertyVetoException {
  614.         if (isMaximum == b) {
  615.             return;
  616.         }
  617.  
  618.     Boolean oldValue = isMaximum ? Boolean.TRUE : Boolean.FALSE;
  619.     Boolean newValue = b ? Boolean.TRUE : Boolean.FALSE;
  620.     fireVetoableChange(IS_MAXIMUM_PROPERTY, oldValue, newValue);
  621.     isMaximum = b;
  622.         if (b) {
  623.             getDesktopPane().addComponentListener(this);
  624.         } else {
  625.             JDesktopPane pane = getDesktopPane();
  626.             if (pane != null) {
  627.                 pane.removeComponentListener(this);
  628.             }
  629.         }
  630.     firePropertyChange(IS_MAXIMUM_PROPERTY, oldValue, newValue);
  631.     }
  632.  
  633.     /**
  634.      * Returns the current JInternalFrame title.
  635.      * @see setTitle
  636.      */
  637.     public String getTitle() {
  638.         return title;
  639.     }
  640.  
  641.     /** 
  642.      * Sets the JInternalFrame title. 
  643.      * @see getTitle
  644.      * @beaninfo:
  645.      *     preferred: true
  646.      *     bound: true
  647.      *     description: The text displayed in the title bar.
  648.      */
  649.     public void setTitle(String title) {
  650.     String oldValue = this.title;
  651.         this.title = title;
  652.     firePropertyChange(TITLE_PROPERTY, oldValue, title);
  653.     }
  654.  
  655.     /**
  656.      * A JInternalFrame normally draws it's title bar differently if it is the 
  657.      * selected frame. This normally indicates that this internalFrame has 
  658.      * focus for the user.
  659.      *
  660.      * @exception PropertyVetoException when the attempt to set the 
  661.      *            property is vetoed by the receiver.
  662.      * @beaninfo
  663.      *     constrained: true
  664.      *     description: Indicates whether this frame is currently 
  665.      *                  the active frame.
  666.      */
  667.     public void setSelected(boolean selected) throws PropertyVetoException {
  668.         if (isSelected == selected) {
  669.             return;
  670.         }
  671.  
  672.     Boolean oldValue = isSelected ? Boolean.TRUE : Boolean.FALSE;
  673.     Boolean newValue = selected ? Boolean.TRUE : Boolean.FALSE;
  674.     fireVetoableChange(IS_SELECTED_PROPERTY, oldValue, newValue);
  675.         isSelected = selected;
  676.  
  677.         Component glassPane = getGlassPane();
  678.         if (isSelected) {
  679.             // Turn off mouse event forwarding (see below).
  680.             glassPane.removeMouseListener(this);
  681.             glassPane.removeMouseMotionListener(this);
  682.             glassPane.setVisible(false);
  683.         } else {
  684.             // Forward mouse events on to UI, so it can activate this frame.
  685.             glassPane.addMouseListener(this);
  686.             glassPane.addMouseMotionListener(this);
  687.             glassPane.setVisible(true);
  688.         }
  689.  
  690.     firePropertyChange(IS_SELECTED_PROPERTY, oldValue, newValue);
  691.         postInternalFrameEvent(
  692.             isSelected ? InternalFrameEvent.INTERNAL_FRAME_ACTIVATED :
  693.                          InternalFrameEvent.INTERNAL_FRAME_DEACTIVATED);
  694.         repaint();
  695.     }
  696.  
  697.     public boolean isSelected() {
  698.         return isSelected;
  699.     } 
  700.  
  701.     /** 
  702.      * Sets an image to be displayed in the titlebar of the frame.
  703.      * Do not confuse this with the desktopIcon object, which describes
  704.      * what is displayed in the JDesktop when the frame is iconified.
  705.      * @beaninfo
  706.      *     description: The icon shown in the top-left corner of the frame.
  707.      */
  708.     public void setFrameIcon(Icon icon)    {
  709.     frameIcon = icon;
  710.     }
  711.  
  712.     public Icon getFrameIcon()    {
  713.     return frameIcon;
  714.     }
  715.  
  716.     /**
  717.      * Get the background color of this object.
  718.      *
  719.      * @return the background color, if supported, of the object; 
  720.      * otherwise, null
  721.      */
  722.     public Color getBackground() {
  723.         return getContentPane().getBackground();
  724.     }
  725.  
  726.     /**
  727.      * Set the background color of this object.
  728.      * (For transparency, see <code>isOpaque</code>.)
  729.      *
  730.      * @param c the new Color for the background
  731.      * @see #isOpaque
  732.      */
  733.     public void setBackground(Color c) {
  734.         getContentPane().setBackground(c);
  735.     }
  736.  
  737.     /**
  738.      * Get the foreground color of this object.
  739.      *
  740.      * @return the foreground color, if supported, of the object; 
  741.      * otherwise, null
  742.      */
  743.     public Color getForeground() {
  744.         return getContentPane().getForeground();
  745.     }
  746.  
  747.     /**
  748.      * Set the foreground color of this object.
  749.      *
  750.      * @param c the new Color for the foreground
  751.      */
  752.     public void setForeground(Color c) {
  753.         getContentPane().setForeground(c);
  754.     }
  755.  
  756.     /** Convenience method that moves this component to position 0 if it's 
  757.       * parent is a JLayeredPane.
  758.       */
  759.     public void moveToFront() {
  760.         if(getParent() != null && getParent() instanceof JLayeredPane) {
  761.             JLayeredPane l =  (JLayeredPane)getParent();
  762.             l.moveToFront(this);
  763.         }
  764.     }
  765.  
  766.     /** Convenience method that moves this component to position -1 if it's 
  767.       * parent is a JLayeredPane.
  768.       */
  769.     public void moveToBack() {
  770.         if(getParent() != null && getParent() instanceof JLayeredPane) {
  771.             JLayeredPane l =  (JLayeredPane)getParent();
  772.             l.moveToBack(this);
  773.         }
  774.     }
  775.  
  776.     /** 
  777.      * Convenience method for setting the layer attribute of this component.
  778.      * @beaninfo
  779.      *     expert: true
  780.      *     description: Specifies what desktop layer is used.
  781.      */
  782.     public void setLayer(Integer layer) {
  783.         if(getParent() != null && getParent() instanceof JLayeredPane) {
  784.         // Normally we want to do this, as it causes the LayeredPane
  785.         // to draw properly.
  786.         JLayeredPane p = (JLayeredPane)getParent();
  787.         p.setLayer(this, layer.intValue(), p.getPosition(this));
  788.     } else {
  789.          // Try to do the right thing
  790.          JLayeredPane.putLayer(this, layer.intValue());
  791.          if(getParent() != null)
  792.         getParent().repaint(_bounds.x, _bounds.y, 
  793.                                     _bounds.width, _bounds.height);
  794.     }
  795.     }
  796.  
  797.     /** Convenience method for getting the layer attribute of this component.
  798.       */
  799.     public int getLayer() {
  800.     return JLayeredPane.getLayer(this);
  801.     }
  802.  
  803.     /** Convenience method that searchs the anscestor heirarchy for a JDesktop
  804.       * instance. If JInternalFrame finds none, the desktopIcon tree is 
  805.       * searched.
  806.       */
  807.     public JDesktopPane getDesktopPane() { 
  808.     Container p;
  809.  
  810.     // Search upward for desktop
  811.         p = getParent();
  812.     while(p != null && !(p instanceof JDesktopPane))
  813.         p = p.getParent();
  814.     
  815.     if(p == null) {
  816.        // search it's icon parent for desktop
  817.        p = getDesktopIcon().getParent();
  818.        while(p != null && !(p instanceof JDesktopPane))
  819.         p = p.getParent();
  820.     }
  821.  
  822.     return (JDesktopPane)p; 
  823.     }
  824.  
  825.     /**
  826.      * Sets the JDesktopIcon associated with this JInternalFrame.
  827.      * @see getDesktopIcon
  828.      * @beaninfo
  829.      *     description: The icon shown when this frame is minimized.
  830.      */
  831.     public void setDesktopIcon(JDesktopIcon d) { desktopIcon = d; }
  832.  
  833.     /** 
  834.      * Returns the JDesktopIcon used when this JInternalFrame is iconified.
  835.      * @see setDesktopIcon
  836.      */
  837.     public JDesktopIcon getDesktopIcon() { 
  838.     return desktopIcon; 
  839.     }
  840.  
  841.  
  842.     /*
  843.      * Creates a new EventDispatchThread to dispatch events from. This
  844.      * method will return when stopModal is invoked.
  845.      */
  846.     synchronized void startModal() {
  847.     try {
  848.         // can't use instanceof EventDispatchThread because the class isn't public
  849.         if (Thread.currentThread().getClass().getName().endsWith("EventDispatchThread")) {
  850.         EventQueue theQueue = getToolkit().getSystemEventQueue();
  851.         while (isVisible()) {
  852.             // This is essentially the body of EventDispatchThread
  853.             AWTEvent event = theQueue.getNextEvent();
  854.             Object src = event.getSource();
  855.             // can't call theQueue.dispatchEvent, so I pasted it's body here
  856.             /*if (event instanceof ActiveEvent) {
  857.               ((ActiveEvent) event).dispatch();
  858.               } else */ if (src instanceof Component) {
  859.               ((Component) src).dispatchEvent(event);
  860.               } else if (src instanceof MenuComponent) {
  861.               ((MenuComponent) src).dispatchEvent(event);
  862.               } else {
  863.               System.err.println("unable to dispatch event: " + event);
  864.               }
  865.         }
  866.         } else
  867.         while (isVisible())
  868.             wait();
  869.     } catch(InterruptedException e){}
  870.     }
  871.   
  872.     /*
  873.      * Stops the event dispatching loop created in a previous call to
  874.      * start.
  875.      */
  876.     synchronized void stopModal() {
  877.     notifyAll();
  878.     }
  879.   
  880.     /**
  881.      * Moves and resizes this component.  Unlike other components,
  882.      * this implementation also forces re-layout, so that frame
  883.      * decorations such as the title bar are always redisplayed.
  884.      */
  885.     public void reshape(int x, int y, int width, int height) {
  886.         super.reshape(x, y, width, height);
  887.         validate();
  888.         repaint();
  889.     }
  890.  
  891. ///////////////////////////
  892. // Frame/Window equivalents
  893. ///////////////////////////
  894.  
  895.     /**
  896.      * Adds the specified internal frame listener to receive internal frame events from
  897.      * this internal frame.
  898.      * @param l the internal frame listener
  899.      */ 
  900.     public synchronized void addInternalFrameListener(InternalFrameListener l) {
  901.         internalFrameListener = MyEventMulticaster.add(
  902.             internalFrameListener, l);
  903.         enableEvents(0);   // turn on the newEventsOnly flag in Component.
  904.     }
  905.  
  906.     /**
  907.      * Removes the specified internal frame listener so that it no longer
  908.      * receives internal frame events from this internal frame.
  909.      * @param l the internal frame listener
  910.      */ 
  911.     public synchronized void removeInternalFrameListener(InternalFrameListener l) {
  912.         internalFrameListener = MyEventMulticaster.remove(
  913.             internalFrameListener, l);
  914.     }
  915.  
  916.     private synchronized void postInternalFrameEvent(int id) {
  917.         if (internalFrameListener != null) {
  918.             InternalFrameEvent e = new InternalFrameEvent(this, id);
  919.             /* Try posting event, but don't bother if there's a 
  920.              * SecurityManager since in most environments it will
  921.              * display a harmless stacktrace when creating the
  922.              * SecurityException which developers find scary. 
  923.              */
  924.             if (JInternalFrame.class.getClassLoader() == null) {
  925.                 try {
  926.                     Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(e);
  927.                     return;
  928.                 } catch (SecurityException se) {
  929.                     // Use dispatchEvent instead.
  930.                 }
  931.             }
  932.             dispatchEvent(e);
  933.         }
  934.     }
  935.  
  936.     private void doDefaultCloseAction() {
  937.         switch(defaultCloseOperation) {
  938.           case HIDE_ON_CLOSE:
  939.               try {
  940.                   setClosed(true);
  941.               } catch (PropertyVetoException pve) {}
  942.               break;
  943.           case DISPOSE_ON_CLOSE:
  944.               try {
  945.                   setClosed(true);
  946.                   dispose();  // only executes if close wasn't vetoed.
  947.               } catch (PropertyVetoException pve) {}
  948.               break;
  949.           case DO_NOTHING_ON_CLOSE:
  950.           default: 
  951.               break;
  952.         }
  953.     }
  954.  
  955.     /**
  956.      * Processes events on this internal frame. If the event has a
  957.      * InternalFrameEvent id, it notifies its internalFrameListener, else it 
  958.      * invokes its superclass's processEvent.
  959.      * @param e the event
  960.      */
  961.     protected void processEvent(AWTEvent e) {
  962.         synchronized (this) { 
  963.             if (internalFrameListener != null) {
  964.                 switch(e.getID()) {
  965.                   case InternalFrameEvent.INTERNAL_FRAME_OPENED:
  966.                       internalFrameListener.internalFrameOpened(
  967.                           (InternalFrameEvent)e);
  968.                       return;
  969.                   case InternalFrameEvent.INTERNAL_FRAME_CLOSING:
  970.                       internalFrameListener.internalFrameClosing(
  971.                           (InternalFrameEvent)e);
  972.                       doDefaultCloseAction();
  973.                       return;
  974.                   case InternalFrameEvent.INTERNAL_FRAME_CLOSED:
  975.                       internalFrameListener.internalFrameClosed(
  976.                           (InternalFrameEvent)e);
  977.                       return;
  978.                   case InternalFrameEvent.INTERNAL_FRAME_ICONIFIED:
  979.                       internalFrameListener.internalFrameIconified(
  980.                           (InternalFrameEvent)e);
  981.                       return;
  982.                   case InternalFrameEvent.INTERNAL_FRAME_DEICONIFIED:
  983.                       internalFrameListener.internalFrameDeiconified(
  984.                           (InternalFrameEvent)e);
  985.                       return;
  986.                   case InternalFrameEvent.INTERNAL_FRAME_ACTIVATED:
  987.                       internalFrameListener.internalFrameActivated(
  988.                           (InternalFrameEvent)e);
  989.                       return;
  990.                   case InternalFrameEvent.INTERNAL_FRAME_DEACTIVATED:
  991.                       internalFrameListener.internalFrameDeactivated(
  992.                           (InternalFrameEvent)e);
  993.                       return;
  994.                   default:
  995.                       break;
  996.                 }
  997.             } else if (e.getID() == InternalFrameEvent.INTERNAL_FRAME_CLOSING) {
  998.                 doDefaultCloseAction();
  999.             }
  1000.         }
  1001.         super.processEvent(e);
  1002.     }
  1003.  
  1004.     /**
  1005.      * Sets the operation which will happen by default when
  1006.      * the user initiates a "close" on this window.
  1007.      * The possible choices are:
  1008.      * <p>
  1009.      * <ul>
  1010.      * <li>DO_NOTHING_ON_CLOSE - do not do anything - require the
  1011.      * program to handle the operation in the windowClosing
  1012.      * method of a registered InternalFrameListener object.
  1013.      * <li>HIDE_ON_CLOSE - automatically hide the window after
  1014.      * invoking any registered InternalFrameListener objects
  1015.      * <li>DISPOSE_ON_CLOSE - automatically hide and dispose the 
  1016.      * window after invoking any registered InternalFrameListener objects
  1017.      * </ul>
  1018.      * <p>
  1019.      * The value is set to HIDE_ON_CLOSE by default.
  1020.      * @see #addInternalFrameListener
  1021.      * @see #getDefaultCloseOperation
  1022.      */
  1023.     public void setDefaultCloseOperation(int operation) {
  1024.         this.defaultCloseOperation = operation;
  1025.     }
  1026.  
  1027.    /**
  1028.     * Returns the default operation which occurs when the user
  1029.     * initiates a "close" on this window.
  1030.     * @see #setDefaultCloseOperation
  1031.     */
  1032.     public int getDefaultCloseOperation() {
  1033.         return defaultCloseOperation;
  1034.     }
  1035.  
  1036.     /**
  1037.      * Causes subcomponents of this JInternalFrame to be laid out at their
  1038.      * preferred size.
  1039.      * @see       java.awt.Window#pack
  1040.      */
  1041.     public void pack() {
  1042.     Container parent = getParent();
  1043.     if (parent != null && parent.getPeer() == null) {
  1044.         parent.addNotify();
  1045.         addNotify();
  1046.     }
  1047.     setSize(getPreferredSize());
  1048.     validate();
  1049.     }
  1050.  
  1051.     /**
  1052.      * Shows this internal frame, and brings it to the front.
  1053.      * <p>
  1054.      * If this window is not yet visible, <code>show</code> 
  1055.      * makes it visible. If this window is already visible, 
  1056.      * then this method brings it to the front. 
  1057.      * @see       java.awt.Window#show
  1058.      * @see       java.awt.Window#toFront
  1059.      * @see       java.awt.Component#setVisible
  1060.      */
  1061.     public void show() {
  1062.         pack();
  1063.         if (!isVisible()) {
  1064.             setVisible(true);
  1065.         }
  1066.         if (!isSelected()) {
  1067.             try {
  1068.                 setSelected(true);
  1069.             } catch (PropertyVetoException pve) {}
  1070.         }
  1071.     }
  1072.  
  1073.     /**
  1074.      * Disposes of this internal frame.
  1075.      */
  1076.     public void dispose() {
  1077.         if (isVisible()) {
  1078.             setVisible(false);
  1079.         }
  1080.         if (isSelected()) {
  1081.             try {
  1082.                 setSelected(false);
  1083.             } catch (PropertyVetoException pve) {}
  1084.         }
  1085.         if (!isClosed) {
  1086.             postInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_CLOSED);
  1087.         }
  1088.     }
  1089.  
  1090.     /**
  1091.      * Brings this internal frame to the front.
  1092.      * @see       java.awt.Window#toFront
  1093.      * @see       #moveToFront
  1094.      */
  1095.     public void toFront() {
  1096.         moveToFront();
  1097.     }
  1098.  
  1099.     /**
  1100.      * Sends this internal frame to the back.
  1101.      * Places this internal frame  at the bottom of the stacking order
  1102.      * and makes the corresponding adjustment to other visible windows.
  1103.      * @see       java.awt.Window#toBack
  1104.      * @see       #moveToBack
  1105.      */
  1106.     public void toBack() {
  1107.         moveToBack();
  1108.     }
  1109.  
  1110.     /**
  1111.      * Gets the warning string that is displayed with this window. 
  1112.      * Since an internal frame is always secure (since it's fully
  1113.      * contained within a window which might need a warning string)
  1114.      * this method always returns null.
  1115.      * @return    null.
  1116.      * @see       java.awt.Window#getWarningString
  1117.      */
  1118.     public final String getWarningString() {
  1119.     return null;
  1120.     }
  1121.  
  1122.  
  1123. /////////////////
  1124. // Mouse support
  1125. ////////////////
  1126.  
  1127.     /*
  1128.      * When inactive, mouse events are forwarded as appropriate either to 
  1129.      * the UI to activate the frame or to the underlying child component.
  1130.      *
  1131.      * In keeping with the MDI messaging model (which JInternalFrame
  1132.      * emulates), only the mousePressed event is forwarded to the UI
  1133.      * to activate the frame.  The mouseEntered, mouseMoved, and 
  1134.      * MouseExited events are forwarded to the underlying child
  1135.      * component, using methods derived from those in Container.
  1136.      * The other mouse events are purposely ignored, since they have
  1137.      * no meaning to either the frame or its children when the frame
  1138.      * is inactive.
  1139.      */
  1140.     public void mousePressed(MouseEvent e) {
  1141.         ((MouseListener)ui).mousePressed(e);
  1142.     }
  1143.     public void mouseEntered(MouseEvent e) {
  1144.         forwardMouseEvent(e);
  1145.     }
  1146.     public void mouseMoved(MouseEvent e) {
  1147.         forwardMouseEvent(e);
  1148.     }
  1149.     public void mouseExited(MouseEvent e) {
  1150.         forwardMouseEvent(e);
  1151.     }
  1152.     public void mouseClicked(MouseEvent e) {
  1153.     }
  1154.     public void mouseReleased(MouseEvent e) {
  1155.     }
  1156.     public void mouseDragged(MouseEvent e) {
  1157.     }
  1158.  
  1159.     /* 
  1160.      * Forward a mouse event to the current mouse target, setting it
  1161.      * if necessary.
  1162.      */
  1163.     private void forwardMouseEvent(MouseEvent e) {
  1164.         Component target = findComponentAt(getContentPane(), 
  1165.                                            e.getX(), e.getY());
  1166.         if (target != mouseEventTarget) {
  1167.             setMouseTarget(target, e);
  1168.         }
  1169.         retargetMouseEvent(e.getID(), e);
  1170.     }
  1171.  
  1172.     private Component mouseEventTarget = null;
  1173.  
  1174.     /*
  1175.      * Find the lightweight child component which corresponds to the
  1176.      * specified location.  This is similar to the new 1.2 API in
  1177.      * Container, but we need to run on 1.1.  The other changes are
  1178.      * due to Container.findComponentAt's use of package-private data.
  1179.      */
  1180.     private static Component findComponentAt(Container c, int x, int y) {
  1181.     if (!c.contains(x, y)) {
  1182.         return c;
  1183.     }
  1184.         int ncomponents = c.getComponentCount();
  1185.         Component component[] = c.getComponents();
  1186.         for (int i = 0 ; i < ncomponents ; i++) {
  1187.             Component comp = component[i];
  1188.             Point loc = comp.getLocation();
  1189.         if ((comp != null) && (comp.contains(x - loc.x, y - loc.y)) &&
  1190.         (comp.getPeer() instanceof java.awt.peer.LightweightPeer) &&
  1191.         (comp.isVisible() == true)) {
  1192.         // found a component that intersects the point, see if there
  1193.         // is a deeper possibility.
  1194.         if (comp instanceof Container) {
  1195.             Container child = (Container) comp;
  1196.                     Point childLoc = child.getLocation();
  1197.             Component deeper = findComponentAt(child,
  1198.                         x - childLoc.x, y - childLoc.y);
  1199.             if (deeper != null) {
  1200.             return deeper;
  1201.             }
  1202.         } else {
  1203.                     return comp;
  1204.                 }
  1205.         }
  1206.         }
  1207.     return c;
  1208.     }
  1209.  
  1210.     /*
  1211.      * Set the child component to which events are forwarded, and
  1212.      * synthesize the appropriate mouseEntered and mouseExited events.
  1213.      */
  1214.     private void setMouseTarget(Component target, MouseEvent e) {
  1215.     if (mouseEventTarget != null) {
  1216.         retargetMouseEvent(MouseEvent.MOUSE_EXITED, e);
  1217.     }
  1218.     mouseEventTarget = target;
  1219.     if (mouseEventTarget != null) {
  1220.         retargetMouseEvent(MouseEvent.MOUSE_ENTERED, e);
  1221.     }
  1222.     }
  1223.  
  1224.     /* 
  1225.      * Dispatch an event clone, retargeted for the current mouse target.
  1226.      */
  1227.     void retargetMouseEvent(int id, MouseEvent e) {
  1228.         MouseEvent retargeted = new MouseEvent(mouseEventTarget, 
  1229.                                                id, 
  1230.                                                e.getWhen(), 
  1231.                                                e.getModifiers(),
  1232.                                                e.getX(), 
  1233.                                                e.getY(), 
  1234.                                                e.getClickCount(), 
  1235.                                                e.isPopupTrigger());
  1236.         mouseEventTarget.dispatchEvent(retargeted);
  1237.     }
  1238.  
  1239.     /**
  1240.      * Invoked when a maximized JInternalFrame's parent's size changes.
  1241.      */
  1242.     public void componentResized(ComponentEvent e) {
  1243.         Dimension d = ((Component)e.getSource()).getSize();
  1244.         setBounds(0, 0, d.width, d.height);
  1245.         validate();
  1246.     }
  1247.  
  1248.     /* Unused */
  1249.     public void componentMoved(ComponentEvent e) {}
  1250.     public void componentShown(ComponentEvent e) {}
  1251.     public void componentHidden(ComponentEvent e) {}
  1252.  
  1253. /////////////////
  1254. // Accessibility support
  1255. ////////////////
  1256.  
  1257.     /**
  1258.      * Get the AccessibleContext associated with this JComponent
  1259.      *
  1260.      * @return the AccessibleContext of this JComponent
  1261.      */
  1262.     public AccessibleContext getAccessibleContext() {
  1263.     if (accessibleContext == null) {
  1264.         accessibleContext = new AccessibleJInternalFrame();
  1265.     }
  1266.     return accessibleContext;
  1267.     }
  1268.  
  1269.     /**
  1270.      * The class used to obtain the accessible role for this object.
  1271.      * <p>
  1272.      * Warning: serialized objects of this class will not be compatible with
  1273.      * future swing releases.  The current serialization support is appropriate
  1274.      * for short term storage or RMI between Swing1.0 applications.  It will
  1275.      * not be possible to load serialized Swing1.0 objects with future releases
  1276.      * of Swing.  The JDK1.2 release of Swing will be the compatibility
  1277.      * baseline for the serialized form of Swing objects.
  1278.      */
  1279.     protected class AccessibleJInternalFrame extends AccessibleJComponent 
  1280.         implements AccessibleValue {
  1281.  
  1282.         /**
  1283.          * Get the accessible name of this object.  This should almost never
  1284.          * return java.awt.Component.getName(), as that generally isn't
  1285.          * a localized name, and doesn't have meaning for the user.  If the
  1286.          * object is fundamentally a text object (e.g. a menu item), the
  1287.          * accessible name should be the text of the object (e.g. "save").
  1288.          * If the object has a tooltip, the tooltip text may also be an
  1289.          * appropriate String to return.
  1290.          *
  1291.          * @return the localized name of the object -- can be null if this 
  1292.          * object does not have a name
  1293.          * @see #setAccessibleName
  1294.          */
  1295.         public String getAccessibleName() {
  1296.             if (accessibleName != null) {
  1297.                 return accessibleName;
  1298.             } else {
  1299.                 return getTitle();
  1300.             }
  1301.         }
  1302.  
  1303.     /**
  1304.      * Get the role of this object.
  1305.      *
  1306.      * @return an instance of AccessibleRole describing the role of the 
  1307.      * object
  1308.      * @see AccessibleRole
  1309.      */
  1310.     public AccessibleRole getAccessibleRole() {
  1311.         return AccessibleRole.INTERNAL_FRAME;
  1312.     }
  1313.  
  1314.         /**
  1315.          * Get the AccessibleValue associated with this object if one
  1316.          * exists.  Otherwise return null.
  1317.          */
  1318.         public AccessibleValue getAccessibleValue() {
  1319.         return this;
  1320.         }
  1321.  
  1322.  
  1323.     //
  1324.     // AccessibleValue methods
  1325.     //
  1326.  
  1327.     /**
  1328.      * Get the value of this object as a Number.
  1329.      *
  1330.      * @return value of the object -- can be null if this object does not
  1331.      * have a value
  1332.      */
  1333.     public Number getCurrentAccessibleValue() {
  1334.         return new Integer(getLayer());
  1335.     }
  1336.  
  1337.     /**
  1338.      * Set the value of this object as a Number.
  1339.      *
  1340.      * @return True if the value was set.
  1341.      */
  1342.     public boolean setCurrentAccessibleValue(Number n) {
  1343.         if (n instanceof Integer) {
  1344.         setLayer((Integer) n);
  1345.         return true;
  1346.         } else {
  1347.         return false;
  1348.         }
  1349.     }
  1350.  
  1351.     /**
  1352.      * Get the minimum value of this object as a Number.
  1353.      *
  1354.      * @return Minimum value of the object; null if this object does not
  1355.      * have a minimum value
  1356.      */
  1357.     public Number getMinimumAccessibleValue() {
  1358.         return new Integer(Integer.MIN_VALUE);
  1359.     }
  1360.  
  1361.     /**
  1362.      * Get the maximum value of this object as a Number.
  1363.      *
  1364.      * @return Maximum value of the object; null if this object does not
  1365.      * have a maximum value
  1366.      */
  1367.     public Number getMaximumAccessibleValue() {
  1368.         return new Integer(Integer.MAX_VALUE);
  1369.     }
  1370.  
  1371.     } // AccessibleJInternalFrame
  1372.  
  1373.     private static class MyEventMulticaster extends AWTEventMulticaster 
  1374.             implements InternalFrameListener {
  1375.         public MyEventMulticaster(InternalFrameListener a,
  1376.                                   InternalFrameListener b) {
  1377.             super(a, b);
  1378.         }
  1379.  
  1380.         public static InternalFrameListener add(InternalFrameListener a, 
  1381.                                                 InternalFrameListener b) {
  1382.             return (InternalFrameListener)addInternal(a, b);
  1383.         }
  1384.  
  1385.         public static InternalFrameListener remove(InternalFrameListener l, 
  1386.                                                    InternalFrameListener oldl){
  1387.             return (InternalFrameListener) removeInternal(l, oldl);
  1388.         }
  1389.  
  1390.         public void internalFrameOpened(InternalFrameEvent e) {
  1391.             ((InternalFrameListener)a).internalFrameOpened(e);
  1392.             ((InternalFrameListener)b).internalFrameOpened(e);
  1393.         }
  1394.  
  1395.         public void internalFrameClosing(InternalFrameEvent e) {
  1396.             ((InternalFrameListener)a).internalFrameClosing(e);
  1397.             ((InternalFrameListener)b).internalFrameClosing(e);
  1398.         }
  1399.  
  1400.         public void internalFrameClosed(InternalFrameEvent e) {
  1401.             ((InternalFrameListener)a).internalFrameClosed(e);
  1402.             ((InternalFrameListener)b).internalFrameClosed(e);
  1403.         }
  1404.  
  1405.         public void internalFrameIconified(InternalFrameEvent e) {
  1406.             ((InternalFrameListener)a).internalFrameIconified(e);
  1407.             ((InternalFrameListener)b).internalFrameIconified(e);
  1408.         }
  1409.  
  1410.         public void internalFrameDeiconified(InternalFrameEvent e) {
  1411.             ((InternalFrameListener)a).internalFrameDeiconified(e);
  1412.             ((InternalFrameListener)b).internalFrameDeiconified(e);
  1413.         }
  1414.  
  1415.         public void internalFrameActivated(InternalFrameEvent e) {
  1416.             ((InternalFrameListener)a).internalFrameActivated(e);
  1417.             ((InternalFrameListener)b).internalFrameActivated(e);
  1418.         }
  1419.  
  1420.         public void internalFrameDeactivated(InternalFrameEvent e) {
  1421.             ((InternalFrameListener)a).internalFrameDeactivated(e);
  1422.             ((InternalFrameListener)b).internalFrameDeactivated(e);
  1423.         }
  1424.     }
  1425.  
  1426.     /**
  1427.      * This component represents an iconified version of a JInternalFrame.
  1428.      * This API should NOT BE USED by Swing applications, as it will go
  1429.      * away in future versions of Swing as its functionality is moved into
  1430.      * JInternalFrame.  This class is public only so that UI objects can
  1431.      * display a desktop icon.  If an application wants to display a
  1432.      * desktop icon, it should create a JInternalFrame instance and
  1433.      * iconify it.
  1434.      * <p>
  1435.      * Warning: serialized objects of this class will not be compatible with
  1436.      * future swing releases.  The current serialization support is appropriate 
  1437.      * for short term storage or RMI between Swing1.0 applications.  It will
  1438.      * not be possible to load serialized Swing1.0 objects with future releases
  1439.      * of Swing.  The JDK1.2 release of Swing will be the compatibility
  1440.      * baseline for the serialized form of Swing objects.
  1441.      *
  1442.      * @author David Kloba
  1443.      */
  1444.     static public class JDesktopIcon extends JComponent implements Accessible
  1445.     {
  1446.         JInternalFrame internalFrame;
  1447.  
  1448.         public JDesktopIcon(JInternalFrame f) {
  1449.             setInternalFrame(f);
  1450.             updateUI();
  1451.         }
  1452.  
  1453.         public DesktopIconUI getUI() {
  1454.             return (DesktopIconUI)ui;
  1455.         }
  1456.  
  1457.         public void setUI(DesktopIconUI ui) {
  1458.             super.setUI(ui);
  1459.         }
  1460.  
  1461.         /** 
  1462.          * Returns the JInternalFrame that this DesktopIcon is 
  1463.          * associated with. 
  1464.          */
  1465.         public JInternalFrame getInternalFrame() {
  1466.             return internalFrame;
  1467.         }
  1468.  
  1469.         public void setInternalFrame(JInternalFrame f) {
  1470.             internalFrame = f;
  1471.         }
  1472.  
  1473.         /** Convience method to ask the appropriate JInternalFrame
  1474.          * for the Desktop object.
  1475.          */
  1476.         public JDesktopPane getDesktopPane() {
  1477.             if(getInternalFrame() != null)
  1478.                 return getInternalFrame().getDesktopPane();
  1479.             return null;
  1480.         }
  1481.  
  1482.         /**
  1483.          * Called to replace the UI with the latest version from the
  1484.          * default UIFactory.
  1485.          */
  1486.         public void updateUI() {
  1487.             boolean hadUI = (ui != null);
  1488.             setUI((DesktopIconUI)UIManager.getUI(this));
  1489.             invalidate();
  1490.  
  1491.             Dimension r = getPreferredSize();
  1492.             setSize(r.width, r.height);
  1493.             
  1494.             if (internalFrame != null) {
  1495.                 SwingUtilities.updateComponentTreeUI(internalFrame);
  1496.             }
  1497.         }
  1498.  
  1499.         /* This method is called if updateUI was called on the associated
  1500.          * JInternalFrame.  It's necessary to avoid infinite recursion.
  1501.          */
  1502.         void updateUIWhenHidden() {
  1503.             /* Update this UI and any associated internal frame */
  1504.             setUI((DesktopIconUI)UIManager.getUI(this));
  1505.             invalidate();
  1506.             Component[] children = getComponents();
  1507.             if (children != null) {
  1508.                 for(int i = 0; i < children.length; i++) {
  1509.                     SwingUtilities.updateComponentTreeUI(children[i]);
  1510.                 }
  1511.             }
  1512.         }
  1513.  
  1514.         /**
  1515.          * @return "DesktopIconUI"
  1516.          * @see JComponent#getUIClassID
  1517.          * @see UIDefaults#getUI
  1518.          */
  1519.         public String getUIClassID() {
  1520.             return "DesktopIconUI";
  1521.         }
  1522.  
  1523.        /////////////////
  1524.        // Accessibility support
  1525.        ////////////////
  1526.  
  1527.         /**
  1528.          * Get the AccessibleContext associated with this JComponent
  1529.          *
  1530.          * @return the AccessibleContext of this JComponent
  1531.          */
  1532.         public AccessibleContext getAccessibleContext() {
  1533.             if (accessibleContext == null) {
  1534.                 accessibleContext = new AccessibleJDesktopIcon();
  1535.             }
  1536.             return accessibleContext;
  1537.         }
  1538.  
  1539.         /**
  1540.          * The class used to obtain the accessible role for this object.
  1541.          * <p>
  1542.          * Warning: serialized objects of this class will not be compatible with
  1543.          * future swing releases.  The current serialization support is appropriate
  1544.          * for short term storage or RMI between Swing1.0 applications.  It will
  1545.          * not be possible to load serialized Swing1.0 objects with future releases
  1546.          * of Swing.  The JDK1.2 release of Swing will be the compatibility
  1547.          * baseline for the serialized form of Swing objects.
  1548.          */
  1549.         protected class AccessibleJDesktopIcon extends AccessibleJComponent 
  1550.             implements AccessibleValue {
  1551.  
  1552.             /**
  1553.              * Get the role of this object.
  1554.              *
  1555.              * @return an instance of AccessibleRole describing the role of the 
  1556.              * object
  1557.              * @see AccessibleRole
  1558.              */
  1559.             public AccessibleRole getAccessibleRole() {
  1560.                 return AccessibleRole.DESKTOP_ICON;
  1561.             }
  1562.  
  1563.             /**
  1564.              * Get the AccessibleValue associated with this object if one
  1565.              * exists.  Otherwise return null.
  1566.              */
  1567.             public AccessibleValue getAccessibleValue() {
  1568.                 return this;
  1569.             }
  1570.  
  1571.            //
  1572.         // AccessibleValue methods
  1573.         //
  1574.  
  1575.             /**
  1576.              * Get the value of this object as a Number.
  1577.              *
  1578.              * @return value of the object -- can be null if this object does not
  1579.              * have a value
  1580.              */
  1581.             public Number getCurrentAccessibleValue() {
  1582.                 AccessibleContext a = JDesktopIcon.this.getInternalFrame().getAccessibleContext();
  1583.                 AccessibleValue v = a.getAccessibleValue();
  1584.                 if (v != null) {
  1585.                     return v.getCurrentAccessibleValue();
  1586.                 } else {
  1587.                     return null;
  1588.                 }
  1589.             }
  1590.  
  1591.         /**
  1592.              * Set the value of this object as a Number.
  1593.              *
  1594.              * @return True if the value was set.
  1595.              */
  1596.         public boolean setCurrentAccessibleValue(Number n) {
  1597.                 AccessibleContext a = JDesktopIcon.this.getInternalFrame().getAccessibleContext();
  1598.                 AccessibleValue v = a.getAccessibleValue();
  1599.                 if (v != null) {
  1600.                     return v.setCurrentAccessibleValue(n);
  1601.                 } else {
  1602.                     return false;
  1603.                 }
  1604.             }
  1605.  
  1606.         /**
  1607.              * Get the minimum value of this object as a Number.
  1608.              *
  1609.              * @return Minimum value of the object; null if this object does not
  1610.              * have a minimum value
  1611.              */
  1612.             public Number getMinimumAccessibleValue() {
  1613.                 AccessibleContext a = JDesktopIcon.this.getInternalFrame().getAccessibleContext();
  1614.                 if (a instanceof AccessibleValue) {
  1615.                     return ((AccessibleValue)a).getMinimumAccessibleValue();
  1616.                 } else {
  1617.                     return null;
  1618.                 }
  1619.             }
  1620.  
  1621.         /**
  1622.              * Get the maximum value of this object as a Number.
  1623.              *
  1624.              * @return Maximum value of the object; null if this object does not
  1625.              * have a maximum value
  1626.              */
  1627.         public Number getMaximumAccessibleValue() {
  1628.                 AccessibleContext a = JDesktopIcon.this.getInternalFrame().getAccessibleContext();
  1629.                 if (a instanceof AccessibleValue) {
  1630.                     return ((AccessibleValue)a).getMaximumAccessibleValue();
  1631.                 } else {
  1632.                     return null;
  1633.                 }
  1634.             }
  1635.  
  1636.         } // AccessibleJDesktopIcon
  1637.     }
  1638. }
  1639.