001    /* JDesktopPane.java --
002       Copyright (C) 2002, 2004 Free Software Foundation, Inc.
003    
004    This file is part of GNU Classpath.
005    
006    GNU Classpath is free software; you can redistribute it and/or modify
007    it under the terms of the GNU General Public License as published by
008    the Free Software Foundation; either version 2, or (at your option)
009    any later version.
010    
011    GNU Classpath is distributed in the hope that it will be useful, but
012    WITHOUT ANY WARRANTY; without even the implied warranty of
013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014    General Public License for more details.
015    
016    You should have received a copy of the GNU General Public License
017    along with GNU Classpath; see the file COPYING.  If not, write to the
018    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
019    02110-1301 USA.
020    
021    Linking this library statically or dynamically with other modules is
022    making a combined work based on this library.  Thus, the terms and
023    conditions of the GNU General Public License cover the whole
024    combination.
025    
026    As a special exception, the copyright holders of this library give you
027    permission to link this library with independent modules to produce an
028    executable, regardless of the license terms of these independent
029    modules, and to copy and distribute the resulting executable under
030    terms of your choice, provided that you also meet, for each linked
031    independent module, the terms and conditions of the license of that
032    module.  An independent module is a module which is not derived from
033    or based on this library.  If you modify this library, you may extend
034    this exception to your version of the library, but you are not
035    obligated to do so.  If you do not wish to do so, delete this
036    exception statement from your version. */
037    
038    
039    package javax.swing;
040    
041    import gnu.java.lang.CPStringBuilder;
042    
043    import java.awt.Component;
044    import java.beans.PropertyVetoException;
045    
046    import javax.accessibility.Accessible;
047    import javax.accessibility.AccessibleContext;
048    import javax.accessibility.AccessibleRole;
049    import javax.swing.plaf.DesktopPaneUI;
050    
051    /**
052     * JDesktopPane is a container (usually for JInternalFrames) that simulates a
053     * desktop. Typically, the user will create JInternalFrames and place them in
054     * a JDesktopPane. The user can then interact with JInternalFrames like they
055     * usually would with JFrames. The actions (minimize, maximize, close, etc)
056     * are done by using a DesktopManager that is associated with the
057     * JDesktopPane.
058     */
059    public class JDesktopPane extends JLayeredPane implements Accessible
060    {
061      private static final long serialVersionUID = 766333777224038726L;
062    
063      /**
064       * This specifies that when dragged, a JInternalFrame should be completely
065       * visible.
066       *
067       * @specnote final since 1.5.0.
068       */
069      public static final int LIVE_DRAG_MODE = 0;
070    
071      /**
072       * This specifies that when dragged, a JInternalFrame should only be visible
073       * as an outline.
074       *
075       * @specnote final since 1.5.0.
076       */
077      public static final int OUTLINE_DRAG_MODE = 1;
078    
079      /** The selected frame in the JDesktopPane. */
080      private transient JInternalFrame selectedFrame;
081    
082      /** The JDesktopManager to use for acting on JInternalFrames. */
083      transient DesktopManager desktopManager;
084    
085      /** The drag mode used by the JDesktopPane. */
086      private transient int dragMode = LIVE_DRAG_MODE;
087    
088      /**
089       * Indicates if the dragMode property has been set by a client
090       * program or by the UI.
091       *
092       * @see #setUIProperty(String, Object)
093       * @see LookAndFeel#installProperty(JComponent, String, Object)
094       */
095      private boolean clientDragModeSet = false;
096    
097      /**
098       * Provides the accessibility features for the <code>JDesktopPane</code>
099       * component.
100       */
101      protected class AccessibleJDesktopPane extends AccessibleJComponent
102      {
103        private static final long serialVersionUID = 6079388927946077570L;
104    
105        /**
106         * Creates a new <code>AccessibleJDesktopPane</code> instance.
107         */
108        protected AccessibleJDesktopPane()
109        {
110          // Nothing to do here.
111        }
112    
113        /**
114         * Returns the accessible role for the <code>JSlider</code> component.
115         *
116         * @return {@link AccessibleRole#DESKTOP_PANE}.
117         */
118        public AccessibleRole getAccessibleRole()
119        {
120          return AccessibleRole.DESKTOP_PANE;
121        }
122      }
123    
124      /**
125       * Creates a new JDesktopPane object.
126       */
127      public JDesktopPane()
128      {
129        setLayout(null);
130        updateUI();
131      }
132    
133      /**
134       * This method returns the UI used with the JDesktopPane.
135       *
136       * @return The UI used with the JDesktopPane.
137       */
138      public DesktopPaneUI getUI()
139      {
140        return (DesktopPaneUI) ui;
141      }
142    
143      /**
144       * This method sets the UI used with the JDesktopPane.
145       *
146       * @param ui The UI to use with the JDesktopPane.
147       */
148      public void setUI(DesktopPaneUI ui)
149      {
150        super.setUI(ui);
151      }
152    
153      /**
154       * This method sets the drag mode to use with the JDesktopPane.
155       *
156       * @param mode The drag mode to use.
157       *
158       * @throws IllegalArgumentException If the drag mode given is not
159       *         LIVE_DRAG_MODE or OUTLINE_DRAG_MODE.
160       */
161      public void setDragMode(int mode)
162      {
163        if ((mode != LIVE_DRAG_MODE) && (mode != OUTLINE_DRAG_MODE))
164          throw new IllegalArgumentException("Drag mode not valid.");
165    
166        clientDragModeSet = true;
167    
168        // FIXME: Unsupported mode.
169        if (mode == OUTLINE_DRAG_MODE)
170          // throw new IllegalArgumentException("Outline drag modes are
171          // unsupported.");
172          mode = LIVE_DRAG_MODE;
173    
174        dragMode = mode;
175      }
176    
177      /**
178       * This method returns the drag mode used with the JDesktopPane.
179       *
180       * @return The drag mode used with the JDesktopPane.
181       */
182      public int getDragMode()
183      {
184        return dragMode;
185      }
186    
187      /**
188       * This method returns the DesktopManager used with the JDesktopPane.
189       *
190       * @return The DesktopManager to use with the JDesktopPane.
191       */
192      public DesktopManager getDesktopManager()
193      {
194        return desktopManager;
195      }
196    
197      /**
198       * This method sets the DesktopManager to use with the JDesktopPane.
199       *
200       * @param manager The DesktopManager to use with the JDesktopPane.
201       */
202      public void setDesktopManager(DesktopManager manager)
203      {
204        desktopManager = manager;
205      }
206    
207      /**
208       * This method restores the UI used with the JDesktopPane to the default.
209       */
210      public void updateUI()
211      {
212        setUI((DesktopPaneUI) UIManager.getUI(this));
213      }
214    
215      /**
216       * This method returns a String identifier that allows the UIManager to know
217       * which class will act as JDesktopPane's UI.
218       *
219       * @return A String identifier for the UI class to use.
220       */
221      public String getUIClassID()
222      {
223        return "DesktopPaneUI";
224      }
225    
226      /**
227       * This method returns all JInternalFrames that are in the JDesktopPane.
228       *
229       * @return All JInternalFrames that are in the JDesktopPane.
230       */
231      public JInternalFrame[] getAllFrames()
232      {
233        return getFramesFromComponents(getComponents());
234      }
235    
236      /**
237       * This method returns the currently selected frame in the JDesktopPane.
238       *
239       * @return The currently selected frame in the JDesktopPane.
240       */
241      public JInternalFrame getSelectedFrame()
242      {
243        return selectedFrame;
244      }
245    
246      /**
247       * This method sets the selected frame in the JDesktopPane.
248       *
249       * @param frame The selected frame in the JDesktopPane.
250       */
251      public void setSelectedFrame(JInternalFrame frame)
252      {
253        if (selectedFrame != null)
254          {
255            try
256              {
257                selectedFrame.setSelected(false);
258              }
259            catch (PropertyVetoException e)
260              {
261                // We do nothing when the attempt is vetoed.
262              }
263          }
264        selectedFrame = null;
265    
266        try
267          {
268            if (frame != null)
269              frame.setSelected(true);
270    
271            selectedFrame = frame;
272          }
273        catch (PropertyVetoException e)
274          {
275            // We do nothing when the attempt is vetoed.
276          }
277      }
278    
279      /**
280       * This method returns all the JInternalFrames in the given layer.
281       *
282       * @param layer The layer to grab frames in.
283       *
284       * @return All JInternalFrames in the given layer.
285       */
286      public JInternalFrame[] getAllFramesInLayer(int layer)
287      {
288        return getFramesFromComponents(getComponentsInLayer(layer));
289      }
290    
291      /**
292       * This method always returns true to indicate that it is not transparent.
293       *
294       * @return true.
295       */
296      public boolean isOpaque()
297      {
298        return true;
299      }
300    
301      /**
302       * Returns an implementation-dependent string describing the attributes of
303       * this <code>JDesktopPane</code>.
304       *
305       * @return A string describing the attributes of this <code>JDesktopPane</code>
306       *         (never <code>null</code>).
307       */
308      protected String paramString()
309      {
310        String superParamStr = super.paramString();
311        CPStringBuilder sb = new CPStringBuilder();
312        sb.append(",isOptimizedDrawingPossible=");
313        sb.append(isOptimizedDrawingEnabled());
314        sb.append(",desktopManager=");
315        if (desktopManager != null)
316          sb.append(desktopManager);
317        return superParamStr + sb.toString();
318      }
319    
320      /**
321       * This method returns all the JInternalFrames in the given Component array.
322       *
323       * @param components An array to search for JInternalFrames in.
324       *
325       * @return An array of JInternalFrames found in the Component array.
326       */
327      private static JInternalFrame[] getFramesFromComponents(Component[] components)
328      {
329        int count = 0;
330    
331        for (int i = 0; i < components.length; i++)
332            if (components[i] instanceof JInternalFrame)
333              count++;
334              
335        JInternalFrame[] value = new JInternalFrame[count];
336        for (int i = 0, j = 0; i < components.length && j != count; i++)
337          if (components[i] instanceof JInternalFrame)
338            value[j++] = (JInternalFrame) components[i];
339        return value;
340      }
341    
342      /**
343       * Returns the object that provides accessibility features for this
344       * <code>JDesktopPane</code> component.
345       *
346       * @return The accessible context (an instance of 
347       *     {@link AccessibleJDesktopPane}).
348       */
349      public AccessibleContext getAccessibleContext()
350      {
351        if (accessibleContext == null)
352          accessibleContext = new AccessibleJDesktopPane();
353    
354        return accessibleContext;
355      }
356    
357      /**
358       * Helper method for
359       * {@link LookAndFeel#installProperty(JComponent, String, Object)}.
360       * 
361       * @param propertyName the name of the property
362       * @param value the value of the property
363       *
364       * @throws IllegalArgumentException if the specified property cannot be set
365       *         by this method
366       * @throws ClassCastException if the property value does not match the
367       *         property type
368       * @throws NullPointerException if <code>c</code> or
369       *         <code>propertyValue</code> is <code>null</code>
370       */
371      void setUIProperty(String propertyName, Object value)
372      {
373        if (propertyName.equals("dragMode"))
374          {
375            if (! clientDragModeSet)
376              {
377                setDragMode(((Integer) value).intValue());
378                clientDragModeSet = false;
379              }
380          }
381        else
382          {
383            super.setUIProperty(propertyName, value);
384          }
385      }
386    }