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 java.awt.Component;
042    import java.beans.PropertyVetoException;
043    
044    import javax.accessibility.Accessible;
045    import javax.accessibility.AccessibleContext;
046    import javax.accessibility.AccessibleRole;
047    import javax.swing.plaf.DesktopPaneUI;
048    
049    /**
050     * JDesktopPane is a container (usually for JInternalFrames) that simulates a
051     * desktop. Typically, the user will create JInternalFrames and place them in
052     * a JDesktopPane. The user can then interact with JInternalFrames like they
053     * usually would with JFrames. The actions (minimize, maximize, close, etc)
054     * are done by using a DesktopManager that is associated with the
055     * JDesktopPane.
056     */
057    public class JDesktopPane extends JLayeredPane implements Accessible
058    {
059      private static final long serialVersionUID = 766333777224038726L;
060    
061      /**
062       * This specifies that when dragged, a JInternalFrame should be completely
063       * visible.
064       *
065       * @specnote final since 1.5.0.
066       */
067      public static final int LIVE_DRAG_MODE = 0;
068    
069      /**
070       * This specifies that when dragged, a JInternalFrame should only be visible
071       * as an outline.
072       *
073       * @specnote final since 1.5.0.
074       */
075      public static final int OUTLINE_DRAG_MODE = 1;
076    
077      /** The selected frame in the JDesktopPane. */
078      private transient JInternalFrame selectedFrame;
079    
080      /** The JDesktopManager to use for acting on JInternalFrames. */
081      transient DesktopManager desktopManager;
082    
083      /** The drag mode used by the JDesktopPane. */
084      private transient int dragMode = LIVE_DRAG_MODE;
085    
086      /**
087       * Indicates if the dragMode property has been set by a client
088       * program or by the UI.
089       *
090       * @see #setUIProperty(String, Object)
091       * @see LookAndFeel#installProperty(JComponent, String, Object)
092       */
093      private boolean clientDragModeSet = false;
094    
095      /**
096       * Provides the accessibility features for the <code>JDesktopPane</code>
097       * component.
098       */
099      protected class AccessibleJDesktopPane extends AccessibleJComponent
100      {
101        private static final long serialVersionUID = 6079388927946077570L;
102    
103        /**
104         * Creates a new <code>AccessibleJDesktopPane</code> instance.
105         */
106        protected AccessibleJDesktopPane()
107        {
108          // Nothing to do here.
109        }
110    
111        /**
112         * Returns the accessible role for the <code>JSlider</code> component.
113         *
114         * @return {@link AccessibleRole#DESKTOP_PANE}.
115         */
116        public AccessibleRole getAccessibleRole()
117        {
118          return AccessibleRole.DESKTOP_PANE;
119        }
120      }
121    
122      /**
123       * Creates a new JDesktopPane object.
124       */
125      public JDesktopPane()
126      {
127        setLayout(null);
128        updateUI();
129      }
130    
131      /**
132       * This method returns the UI used with the JDesktopPane.
133       *
134       * @return The UI used with the JDesktopPane.
135       */
136      public DesktopPaneUI getUI()
137      {
138        return (DesktopPaneUI) ui;
139      }
140    
141      /**
142       * This method sets the UI used with the JDesktopPane.
143       *
144       * @param ui The UI to use with the JDesktopPane.
145       */
146      public void setUI(DesktopPaneUI ui)
147      {
148        super.setUI(ui);
149      }
150    
151      /**
152       * This method sets the drag mode to use with the JDesktopPane.
153       *
154       * @param mode The drag mode to use.
155       *
156       * @throws IllegalArgumentException If the drag mode given is not
157       *         LIVE_DRAG_MODE or OUTLINE_DRAG_MODE.
158       */
159      public void setDragMode(int mode)
160      {
161        if ((mode != LIVE_DRAG_MODE) && (mode != OUTLINE_DRAG_MODE))
162          throw new IllegalArgumentException("Drag mode not valid.");
163    
164        clientDragModeSet = true;
165    
166        // FIXME: Unsupported mode.
167        if (mode == OUTLINE_DRAG_MODE)
168          // throw new IllegalArgumentException("Outline drag modes are
169          // unsupported.");
170          mode = LIVE_DRAG_MODE;
171    
172        dragMode = mode;
173      }
174    
175      /**
176       * This method returns the drag mode used with the JDesktopPane.
177       *
178       * @return The drag mode used with the JDesktopPane.
179       */
180      public int getDragMode()
181      {
182        return dragMode;
183      }
184    
185      /**
186       * This method returns the DesktopManager used with the JDesktopPane.
187       *
188       * @return The DesktopManager to use with the JDesktopPane.
189       */
190      public DesktopManager getDesktopManager()
191      {
192        return desktopManager;
193      }
194    
195      /**
196       * This method sets the DesktopManager to use with the JDesktopPane.
197       *
198       * @param manager The DesktopManager to use with the JDesktopPane.
199       */
200      public void setDesktopManager(DesktopManager manager)
201      {
202        desktopManager = manager;
203      }
204    
205      /**
206       * This method restores the UI used with the JDesktopPane to the default.
207       */
208      public void updateUI()
209      {
210        setUI((DesktopPaneUI) UIManager.getUI(this));
211      }
212    
213      /**
214       * This method returns a String identifier that allows the UIManager to know
215       * which class will act as JDesktopPane's UI.
216       *
217       * @return A String identifier for the UI class to use.
218       */
219      public String getUIClassID()
220      {
221        return "DesktopPaneUI";
222      }
223    
224      /**
225       * This method returns all JInternalFrames that are in the JDesktopPane.
226       *
227       * @return All JInternalFrames that are in the JDesktopPane.
228       */
229      public JInternalFrame[] getAllFrames()
230      {
231        return getFramesFromComponents(getComponents());
232      }
233    
234      /**
235       * This method returns the currently selected frame in the JDesktopPane.
236       *
237       * @return The currently selected frame in the JDesktopPane.
238       */
239      public JInternalFrame getSelectedFrame()
240      {
241        return selectedFrame;
242      }
243    
244      /**
245       * This method sets the selected frame in the JDesktopPane.
246       *
247       * @param frame The selected frame in the JDesktopPane.
248       */
249      public void setSelectedFrame(JInternalFrame frame)
250      {
251        if (selectedFrame != null)
252          {
253            try
254              {
255                selectedFrame.setSelected(false);
256              }
257            catch (PropertyVetoException e)
258              {
259                // We do nothing when the attempt is vetoed.
260              }
261          }
262        selectedFrame = null;
263    
264        try
265          {
266            if (frame != null)
267              frame.setSelected(true);
268    
269            selectedFrame = frame;
270          }
271        catch (PropertyVetoException e)
272          {
273            // We do nothing when the attempt is vetoed.
274          }
275      }
276    
277      /**
278       * This method returns all the JInternalFrames in the given layer.
279       *
280       * @param layer The layer to grab frames in.
281       *
282       * @return All JInternalFrames in the given layer.
283       */
284      public JInternalFrame[] getAllFramesInLayer(int layer)
285      {
286        return getFramesFromComponents(getComponentsInLayer(layer));
287      }
288    
289      /**
290       * This method always returns true to indicate that it is not transparent.
291       *
292       * @return true.
293       */
294      public boolean isOpaque()
295      {
296        return true;
297      }
298    
299      /**
300       * Returns an implementation-dependent string describing the attributes of
301       * this <code>JDesktopPane</code>.
302       *
303       * @return A string describing the attributes of this <code>JDesktopPane</code>
304       *         (never <code>null</code>).
305       */
306      protected String paramString()
307      {
308        String superParamStr = super.paramString();
309        StringBuffer sb = new StringBuffer();
310        sb.append(",isOptimizedDrawingPossible=");
311        sb.append(isOptimizedDrawingEnabled());
312        sb.append(",desktopManager=");
313        if (desktopManager != null)
314          sb.append(desktopManager);
315        return superParamStr + sb.toString();
316      }
317    
318      /**
319       * This method returns all the JInternalFrames in the given Component array.
320       *
321       * @param components An array to search for JInternalFrames in.
322       *
323       * @return An array of JInternalFrames found in the Component array.
324       */
325      private static JInternalFrame[] getFramesFromComponents(Component[] components)
326      {
327        int count = 0;
328    
329        for (int i = 0; i < components.length; i++)
330            if (components[i] instanceof JInternalFrame)
331              count++;
332              
333        JInternalFrame[] value = new JInternalFrame[count];
334        for (int i = 0, j = 0; i < components.length && j != count; i++)
335          if (components[i] instanceof JInternalFrame)
336            value[j++] = (JInternalFrame) components[i];
337        return value;
338      }
339    
340      /**
341       * Returns the object that provides accessibility features for this
342       * <code>JDesktopPane</code> component.
343       *
344       * @return The accessible context (an instance of 
345       *     {@link AccessibleJDesktopPane}).
346       */
347      public AccessibleContext getAccessibleContext()
348      {
349        if (accessibleContext == null)
350          accessibleContext = new AccessibleJDesktopPane();
351    
352        return accessibleContext;
353      }
354    
355      /**
356       * Helper method for
357       * {@link LookAndFeel#installProperty(JComponent, String, Object)}.
358       * 
359       * @param propertyName the name of the property
360       * @param value the value of the property
361       *
362       * @throws IllegalArgumentException if the specified property cannot be set
363       *         by this method
364       * @throws ClassCastException if the property value does not match the
365       *         property type
366       * @throws NullPointerException if <code>c</code> or
367       *         <code>propertyValue</code> is <code>null</code>
368       */
369      void setUIProperty(String propertyName, Object value)
370      {
371        if (propertyName.equals("dragMode"))
372          {
373            if (! clientDragModeSet)
374              {
375                setDragMode(((Integer) value).intValue());
376                clientDragModeSet = false;
377              }
378          }
379        else
380          {
381            super.setUIProperty(propertyName, value);
382          }
383      }
384    }