Home » openjdk-7 » javax » swing » [javadoc | source]

    1   /*
    2    * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
    3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    4    *
    5    * This code is free software; you can redistribute it and/or modify it
    6    * under the terms of the GNU General Public License version 2 only, as
    7    * published by the Free Software Foundation.  Oracle designates this
    8    * particular file as subject to the "Classpath" exception as provided
    9    * by Oracle in the LICENSE file that accompanied this code.
   10    *
   11    * This code is distributed in the hope that it will be useful, but WITHOUT
   12    * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   13    * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   14    * version 2 for more details (a copy is included in the LICENSE file that
   15    * accompanied this code).
   16    *
   17    * You should have received a copy of the GNU General Public License version
   18    * 2 along with this work; if not, write to the Free Software Foundation,
   19    * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   20    *
   21    * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   22    * or visit www.oracle.com if you need additional information or have any
   23    * questions.
   24    */
   25   package javax.swing;
   26   
   27   import java.awt.Component;
   28   import java.util.ArrayList;
   29   import java.util.Hashtable;
   30   import java.awt.Color;
   31   import java.awt.Graphics;
   32   import java.awt.Rectangle;
   33   import sun.awt.SunToolkit;
   34   
   35   import javax.accessibility;
   36   
   37   /**
   38    * <code>JLayeredPane</code> adds depth to a JFC/Swing container,
   39    * allowing components to overlap each other when needed.
   40    * An <code>Integer</code> object specifies each component's depth in the
   41    * container, where higher-numbered components sit &quot;on top&quot; of other
   42    * components.
   43    * For task-oriented documentation and examples of using layered panes see
   44    * <a href="http://java.sun.com/docs/books/tutorial/uiswing/components/layeredpane.html">How to Use a Layered Pane</a>,
   45    * a section in <em>The Java Tutorial</em>.
   46    * <P>
   47    * <TABLE ALIGN="RIGHT" BORDER="0" SUMMARY="layout">
   48    * <TR>
   49    *   <TD ALIGN="CENTER">
   50    *     <P ALIGN="CENTER"><IMG SRC="doc-files/JLayeredPane-1.gif"
   51    *     alt="The following text describes this image."
   52    *     WIDTH="269" HEIGHT="264" ALIGN="BOTTOM" BORDER="0">
   53    *   </TD>
   54    * </TR>
   55    * </TABLE>
   56    * For convenience, <code>JLayeredPane</code> divides the depth-range
   57    * into several different layers. Putting a component into one of those
   58    * layers makes it easy to ensure that components overlap properly,
   59    * without having to worry about specifying numbers for specific depths:
   60    * <DL>
   61    *    <DT><FONT SIZE="2">DEFAULT_LAYER</FONT></DT>
   62    *         <DD>The standard layer, where most components go. This the bottommost
   63    *         layer.
   64    *    <DT><FONT SIZE="2">PALETTE_LAYER</FONT></DT>
   65    *         <DD>The palette layer sits over the default layer. Useful for floating
   66    *         toolbars and palettes, so they can be positioned above other components.
   67    *    <DT><FONT SIZE="2">MODAL_LAYER</FONT></DT>
   68    *         <DD>The layer used for modal dialogs. They will appear on top of any
   69    *         toolbars, palettes, or standard components in the container.
   70    *    <DT><FONT SIZE="2">POPUP_LAYER</FONT></DT>
   71    *         <DD>The popup layer displays above dialogs. That way, the popup windows
   72    *         associated with combo boxes, tooltips, and other help text will appear
   73    *         above the component, palette, or dialog that generated them.
   74    *    <DT><FONT SIZE="2">DRAG_LAYER</FONT></DT>
   75    *         <DD>When dragging a component, reassigning it to the drag layer ensures
   76    *         that it is positioned over every other component in the container. When
   77    *         finished dragging, it can be reassigned to its normal layer.
   78    * </DL>
   79    * The <code>JLayeredPane</code> methods <code>moveToFront(Component)</code>,
   80    * <code>moveToBack(Component)</code> and <code>setPosition</code> can be used
   81    * to reposition a component within its layer. The <code>setLayer</code> method
   82    * can also be used to change the component's current layer.
   83    *
   84    * <h2>Details</h2>
   85    * <code>JLayeredPane</code> manages its list of children like
   86    * <code>Container</code>, but allows for the definition of a several
   87    * layers within itself. Children in the same layer are managed exactly
   88    * like the normal <code>Container</code> object,
   89    * with the added feature that when children components overlap, children
   90    * in higher layers display above the children in lower layers.
   91    * <p>
   92    * Each layer is a distinct integer number. The layer attribute can be set
   93    * on a <code>Component</code> by passing an <code>Integer</code>
   94    * object during the add call.<br> For example:
   95    * <PRE>
   96    *     layeredPane.add(child, JLayeredPane.DEFAULT_LAYER);
   97    * or
   98    *     layeredPane.add(child, new Integer(10));
   99    * </PRE>
  100    * The layer attribute can also be set on a Component by calling<PRE>
  101    *     layeredPaneParent.setLayer(child, 10)</PRE>
  102    * on the <code>JLayeredPane</code> that is the parent of component. The layer
  103    * should be set <i>before</i> adding the child to the parent.
  104    * <p>
  105    * Higher number layers display above lower number layers. So, using
  106    * numbers for the layers and letters for individual components, a
  107    * representative list order would look like this:<PRE>
  108    *       5a, 5b, 5c, 2a, 2b, 2c, 1a </PRE>
  109    * where the leftmost components are closest to the top of the display.
  110    * <p>
  111    * A component can be moved to the top or bottom position within its
  112    * layer by calling <code>moveToFront</code> or <code>moveToBack</code>.
  113    * <p>
  114    * The position of a component within a layer can also be specified directly.
  115    * Valid positions range from 0 up to one less than the number of
  116    * components in that layer. A value of -1 indicates the bottommost
  117    * position. A value of 0 indicates the topmost position. Unlike layer
  118    * numbers, higher position values are <i>lower</i> in the display.
  119    * <blockquote>
  120    * <b>Note:</b> This sequence (defined by java.awt.Container) is the reverse
  121    * of the layer numbering sequence. Usually though, you will use <code>moveToFront</code>,
  122    * <code>moveToBack</code>, and <code>setLayer</code>.
  123    * </blockquote>
  124    * Here are some examples using the method add(Component, layer, position):
  125    * Calling add(5x, 5, -1) results in:<PRE>
  126    *       5a, 5b, 5c, 5x, 2a, 2b, 2c, 1a </PRE>
  127    *
  128    * Calling add(5z, 5, 2) results in:<PRE>
  129    *       5a, 5b, 5z, 5c, 5x, 2a, 2b, 2c, 1a </PRE>
  130    *
  131    * Calling add(3a, 3, 7) results in:<PRE>
  132    *       5a, 5b, 5z, 5c, 5x, 3a, 2a, 2b, 2c, 1a </PRE>
  133    *
  134    * Using normal paint/event mechanics results in 1a appearing at the bottom
  135    * and 5a being above all other components.
  136    * <p>
  137    * <b>Note:</b> that these layers are simply a logical construct and LayoutManagers
  138    * will affect all child components of this container without regard for
  139    * layer settings.
  140    * <p>
  141    * <strong>Warning:</strong> Swing is not thread safe. For more
  142    * information see <a
  143    * href="package-summary.html#threading">Swing's Threading
  144    * Policy</a>.
  145    * <p>
  146    * <strong>Warning:</strong>
  147    * Serialized objects of this class will not be compatible with
  148    * future Swing releases. The current serialization support is
  149    * appropriate for short term storage or RMI between applications running
  150    * the same version of Swing.  As of 1.4, support for long term storage
  151    * of all JavaBeans<sup><font size="-2">TM</font></sup>
  152    * has been added to the <code>java.beans</code> package.
  153    * Please see {@link java.beans.XMLEncoder}.
  154    *
  155    * @author David Kloba
  156    */
  157   public class JLayeredPane extends JComponent implements Accessible {
  158       /// Watch the values in getObjectForLayer()
  159       /** Convenience object defining the Default layer. Equivalent to new Integer(0).*/
  160       public final static Integer DEFAULT_LAYER = new Integer(0);
  161       /** Convenience object defining the Palette layer. Equivalent to new Integer(100).*/
  162       public final static Integer PALETTE_LAYER = new Integer(100);
  163       /** Convenience object defining the Modal layer. Equivalent to new Integer(200).*/
  164       public final static Integer MODAL_LAYER = new Integer(200);
  165       /** Convenience object defining the Popup layer. Equivalent to new Integer(300).*/
  166       public final static Integer POPUP_LAYER = new Integer(300);
  167       /** Convenience object defining the Drag layer. Equivalent to new Integer(400).*/
  168       public final static Integer DRAG_LAYER = new Integer(400);
  169       /** Convenience object defining the Frame Content layer.
  170         * This layer is normally only use to positon the contentPane and menuBar
  171         * components of JFrame.
  172         * Equivalent to new Integer(-30000).
  173         * @see JFrame
  174         */
  175       public final static Integer FRAME_CONTENT_LAYER = new Integer(-30000);
  176   
  177       /** Bound property */
  178       public final static String LAYER_PROPERTY = "layeredContainerLayer";
  179       // Hashtable to store layer values for non-JComponent components
  180       private Hashtable<Component,Integer> componentToLayer;
  181       private boolean optimizedDrawingPossible = true;
  182   
  183   
  184   //////////////////////////////////////////////////////////////////////////////
  185   //// Container Override methods
  186   //////////////////////////////////////////////////////////////////////////////
  187       /** Create a new JLayeredPane */
  188       public JLayeredPane() {
  189           setLayout(null);
  190       }
  191   
  192       private void validateOptimizedDrawing() {
  193           boolean layeredComponentFound = false;
  194           synchronized(getTreeLock()) {
  195               Integer layer;
  196   
  197               for (Component c : getComponents()) {
  198                   layer = null;
  199   
  200                   if(SunToolkit.isInstanceOf(c, "javax.swing.JInternalFrame") ||
  201                          (c instanceof JComponent &&
  202                           (layer = (Integer)((JComponent)c).
  203                                        getClientProperty(LAYER_PROPERTY)) != null))
  204                   {
  205                       if(layer != null && layer.equals(FRAME_CONTENT_LAYER))
  206                           continue;
  207                       layeredComponentFound = true;
  208                       break;
  209                   }
  210               }
  211           }
  212   
  213           if(layeredComponentFound)
  214               optimizedDrawingPossible = false;
  215           else
  216               optimizedDrawingPossible = true;
  217       }
  218   
  219       protected void addImpl(Component comp, Object constraints, int index) {
  220           int layer;
  221           int pos;
  222   
  223           if(constraints instanceof Integer) {
  224               layer = ((Integer)constraints).intValue();
  225               setLayer(comp, layer);
  226           } else
  227               layer = getLayer(comp);
  228   
  229           pos = insertIndexForLayer(layer, index);
  230           super.addImpl(comp, constraints, pos);
  231           comp.validate();
  232           comp.repaint();
  233           validateOptimizedDrawing();
  234       }
  235   
  236       /**
  237        * Remove the indexed component from this pane.
  238        * This is the absolute index, ignoring layers.
  239        *
  240        * @param index  an int specifying the component to remove
  241        * @see #getIndexOf
  242        */
  243       public void remove(int index) {
  244           Component c = getComponent(index);
  245           super.remove(index);
  246           if (c != null && !(c instanceof JComponent)) {
  247               getComponentToLayer().remove(c);
  248           }
  249           validateOptimizedDrawing();
  250       }
  251   
  252       /**
  253        * Removes all the components from this container.
  254        *
  255        * @since 1.5
  256        */
  257       public void removeAll() {
  258           Component[] children = getComponents();
  259           Hashtable cToL = getComponentToLayer();
  260           for (int counter = children.length - 1; counter >= 0; counter--) {
  261               Component c = children[counter];
  262               if (c != null && !(c instanceof JComponent)) {
  263                   cToL.remove(c);
  264               }
  265           }
  266           super.removeAll();
  267       }
  268   
  269       /**
  270        * Returns false if components in the pane can overlap, which makes
  271        * optimized drawing impossible. Otherwise, returns true.
  272        *
  273        * @return false if components can overlap, else true
  274        * @see JComponent#isOptimizedDrawingEnabled
  275        */
  276       public boolean isOptimizedDrawingEnabled() {
  277           return optimizedDrawingPossible;
  278       }
  279   
  280   
  281   //////////////////////////////////////////////////////////////////////////////
  282   //// New methods for managing layers
  283   //////////////////////////////////////////////////////////////////////////////
  284       /** Sets the layer property on a JComponent. This method does not cause
  285         * any side effects like setLayer() (painting, add/remove, etc).
  286         * Normally you should use the instance method setLayer(), in order to
  287         * get the desired side-effects (like repainting).
  288         *
  289         * @param c      the JComponent to move
  290         * @param layer  an int specifying the layer to move it to
  291         * @see #setLayer
  292         */
  293       public static void putLayer(JComponent c, int layer) {
  294           /// MAKE SURE THIS AND setLayer(Component c, int layer, int position)  are SYNCED
  295           Integer layerObj;
  296   
  297           layerObj = new Integer(layer);
  298           c.putClientProperty(LAYER_PROPERTY, layerObj);
  299       }
  300   
  301       /** Gets the layer property for a JComponent, it
  302         * does not cause any side effects like setLayer(). (painting, add/remove, etc)
  303         * Normally you should use the instance method getLayer().
  304         *
  305         * @param c  the JComponent to check
  306         * @return   an int specifying the component's layer
  307         */
  308       public static int getLayer(JComponent c) {
  309           Integer i;
  310           if((i = (Integer)c.getClientProperty(LAYER_PROPERTY)) != null)
  311               return i.intValue();
  312           return DEFAULT_LAYER.intValue();
  313       }
  314   
  315       /** Convenience method that returns the first JLayeredPane which
  316         * contains the specified component. Note that all JFrames have a
  317         * JLayeredPane at their root, so any component in a JFrame will
  318         * have a JLayeredPane parent.
  319         *
  320         * @param c the Component to check
  321         * @return the JLayeredPane that contains the component, or
  322         *         null if no JLayeredPane is found in the component
  323         *         hierarchy
  324         * @see JFrame
  325         * @see JRootPane
  326         */
  327       public static JLayeredPane getLayeredPaneAbove(Component c) {
  328           if(c == null) return null;
  329   
  330           Component parent = c.getParent();
  331           while(parent != null && !(parent instanceof JLayeredPane))
  332               parent = parent.getParent();
  333           return (JLayeredPane)parent;
  334       }
  335   
  336       /** Sets the layer attribute on the specified component,
  337         * making it the bottommost component in that layer.
  338         * Should be called before adding to parent.
  339         *
  340         * @param c     the Component to set the layer for
  341         * @param layer an int specifying the layer to set, where
  342         *              lower numbers are closer to the bottom
  343         */
  344       public void setLayer(Component c, int layer)  {
  345           setLayer(c, layer, -1);
  346       }
  347   
  348       /** Sets the layer attribute for the specified component and
  349         * also sets its position within that layer.
  350         *
  351         * @param c         the Component to set the layer for
  352         * @param layer     an int specifying the layer to set, where
  353         *                  lower numbers are closer to the bottom
  354         * @param position  an int specifying the position within the
  355         *                  layer, where 0 is the topmost position and -1
  356         *                  is the bottommost position
  357         */
  358       public void setLayer(Component c, int layer, int position)  {
  359           Integer layerObj;
  360           layerObj = getObjectForLayer(layer);
  361   
  362           if(layer == getLayer(c) && position == getPosition(c)) {
  363                   repaint(c.getBounds());
  364               return;
  365           }
  366   
  367           /// MAKE SURE THIS AND putLayer(JComponent c, int layer) are SYNCED
  368           if(c instanceof JComponent)
  369               ((JComponent)c).putClientProperty(LAYER_PROPERTY, layerObj);
  370           else
  371               getComponentToLayer().put(c, layerObj);
  372   
  373           if(c.getParent() == null || c.getParent() != this) {
  374               repaint(c.getBounds());
  375               return;
  376           }
  377   
  378           int index = insertIndexForLayer(c, layer, position);
  379   
  380           setComponentZOrder(c, index);
  381           repaint(c.getBounds());
  382       }
  383   
  384       /**
  385        * Returns the layer attribute for the specified Component.
  386        *
  387        * @param c  the Component to check
  388        * @return an int specifying the component's current layer
  389        */
  390       public int getLayer(Component c) {
  391           Integer i;
  392           if(c instanceof JComponent)
  393               i = (Integer)((JComponent)c).getClientProperty(LAYER_PROPERTY);
  394           else
  395               i = getComponentToLayer().get(c);
  396   
  397           if(i == null)
  398               return DEFAULT_LAYER.intValue();
  399           return i.intValue();
  400       }
  401   
  402       /**
  403        * Returns the index of the specified Component.
  404        * This is the absolute index, ignoring layers.
  405        * Index numbers, like position numbers, have the topmost component
  406        * at index zero. Larger numbers are closer to the bottom.
  407        *
  408        * @param c  the Component to check
  409        * @return an int specifying the component's index
  410        */
  411       public int getIndexOf(Component c) {
  412           int i, count;
  413   
  414           count = getComponentCount();
  415           for(i = 0; i < count; i++) {
  416               if(c == getComponent(i))
  417                   return i;
  418           }
  419           return -1;
  420       }
  421       /**
  422        * Moves the component to the top of the components in its current layer
  423        * (position 0).
  424        *
  425        * @param c the Component to move
  426        * @see #setPosition(Component, int)
  427        */
  428       public void moveToFront(Component c) {
  429           setPosition(c, 0);
  430       }
  431   
  432       /**
  433        * Moves the component to the bottom of the components in its current layer
  434        * (position -1).
  435        *
  436        * @param c the Component to move
  437        * @see #setPosition(Component, int)
  438        */
  439       public void moveToBack(Component c) {
  440           setPosition(c, -1);
  441       }
  442   
  443       /**
  444        * Moves the component to <code>position</code> within its current layer,
  445        * where 0 is the topmost position within the layer and -1 is the bottommost
  446        * position.
  447        * <p>
  448        * <b>Note:</b> Position numbering is defined by java.awt.Container, and
  449        * is the opposite of layer numbering. Lower position numbers are closer
  450        * to the top (0 is topmost), and higher position numbers are closer to
  451        * the bottom.
  452        *
  453        * @param c         the Component to move
  454        * @param position  an int in the range -1..N-1, where N is the number of
  455        *                  components in the component's current layer
  456        */
  457       public void setPosition(Component c, int position) {
  458           setLayer(c, getLayer(c), position);
  459       }
  460   
  461       /**
  462        * Get the relative position of the component within its layer.
  463        *
  464        * @param c  the Component to check
  465        * @return an int giving the component's position, where 0 is the
  466        *         topmost position and the highest index value = the count
  467        *         count of components at that layer, minus 1
  468        *
  469        * @see #getComponentCountInLayer
  470        */
  471       public int getPosition(Component c) {
  472           int i, startLayer, curLayer, startLocation, pos = 0;
  473   
  474           getComponentCount();
  475           startLocation = getIndexOf(c);
  476   
  477           if(startLocation == -1)
  478               return -1;
  479   
  480           startLayer = getLayer(c);
  481           for(i = startLocation - 1; i >= 0; i--) {
  482               curLayer = getLayer(getComponent(i));
  483               if(curLayer == startLayer)
  484                   pos++;
  485               else
  486                   return pos;
  487           }
  488           return pos;
  489       }
  490   
  491       /** Returns the highest layer value from all current children.
  492         * Returns 0 if there are no children.
  493         *
  494         * @return an int indicating the layer of the topmost component in the
  495         *         pane, or zero if there are no children
  496         */
  497       public int highestLayer() {
  498           if(getComponentCount() > 0)
  499               return getLayer(getComponent(0));
  500           return 0;
  501       }
  502   
  503       /** Returns the lowest layer value from all current children.
  504         * Returns 0 if there are no children.
  505         *
  506         * @return an int indicating the layer of the bottommost component in the
  507         *         pane, or zero if there are no children
  508         */
  509       public int lowestLayer() {
  510           int count = getComponentCount();
  511           if(count > 0)
  512               return getLayer(getComponent(count-1));
  513           return 0;
  514       }
  515   
  516       /**
  517        * Returns the number of children currently in the specified layer.
  518        *
  519        * @param layer  an int specifying the layer to check
  520        * @return an int specifying the number of components in that layer
  521        */
  522       public int getComponentCountInLayer(int layer) {
  523           int i, count, curLayer;
  524           int layerCount = 0;
  525   
  526           count = getComponentCount();
  527           for(i = 0; i < count; i++) {
  528               curLayer = getLayer(getComponent(i));
  529               if(curLayer == layer) {
  530                   layerCount++;
  531               /// Short circut the counting when we have them all
  532               } else if(layerCount > 0 || curLayer < layer) {
  533                   break;
  534               }
  535           }
  536   
  537           return layerCount;
  538       }
  539   
  540       /**
  541        * Returns an array of the components in the specified layer.
  542        *
  543        * @param layer  an int specifying the layer to check
  544        * @return an array of Components contained in that layer
  545        */
  546       public Component[] getComponentsInLayer(int layer) {
  547           int i, count, curLayer;
  548           int layerCount = 0;
  549           Component[] results;
  550   
  551           results = new Component[getComponentCountInLayer(layer)];
  552           count = getComponentCount();
  553           for(i = 0; i < count; i++) {
  554               curLayer = getLayer(getComponent(i));
  555               if(curLayer == layer) {
  556                   results[layerCount++] = getComponent(i);
  557               /// Short circut the counting when we have them all
  558               } else if(layerCount > 0 || curLayer < layer) {
  559                   break;
  560               }
  561           }
  562   
  563           return results;
  564       }
  565   
  566       /**
  567        * Paints this JLayeredPane within the specified graphics context.
  568        *
  569        * @param g  the Graphics context within which to paint
  570        */
  571       public void paint(Graphics g) {
  572           if(isOpaque()) {
  573               Rectangle r = g.getClipBounds();
  574               Color c = getBackground();
  575               if(c == null)
  576                   c = Color.lightGray;
  577               g.setColor(c);
  578               if (r != null) {
  579                   g.fillRect(r.x, r.y, r.width, r.height);
  580               }
  581               else {
  582                   g.fillRect(0, 0, getWidth(), getHeight());
  583               }
  584           }
  585           super.paint(g);
  586       }
  587   
  588   //////////////////////////////////////////////////////////////////////////////
  589   //// Implementation Details
  590   //////////////////////////////////////////////////////////////////////////////
  591   
  592       /**
  593        * Returns the hashtable that maps components to layers.
  594        *
  595        * @return the Hashtable used to map components to their layers
  596        */
  597       protected Hashtable<Component,Integer> getComponentToLayer() {
  598           if(componentToLayer == null)
  599               componentToLayer = new Hashtable<Component,Integer>(4);
  600           return componentToLayer;
  601       }
  602   
  603       /**
  604        * Returns the Integer object associated with a specified layer.
  605        *
  606        * @param layer an int specifying the layer
  607        * @return an Integer object for that layer
  608        */
  609       protected Integer getObjectForLayer(int layer) {
  610           Integer layerObj;
  611           switch(layer) {
  612           case 0:
  613               layerObj = DEFAULT_LAYER;
  614               break;
  615           case 100:
  616               layerObj = PALETTE_LAYER;
  617               break;
  618           case 200:
  619               layerObj = MODAL_LAYER;
  620               break;
  621           case 300:
  622               layerObj = POPUP_LAYER;
  623               break;
  624           case 400:
  625               layerObj = DRAG_LAYER;
  626               break;
  627           default:
  628               layerObj = new Integer(layer);
  629           }
  630           return layerObj;
  631       }
  632   
  633       /**
  634        * Primitive method that determines the proper location to
  635        * insert a new child based on layer and position requests.
  636        *
  637        * @param layer     an int specifying the layer
  638        * @param position  an int specifying the position within the layer
  639        * @return an int giving the (absolute) insertion-index
  640        *
  641        * @see #getIndexOf
  642        */
  643       protected int insertIndexForLayer(int layer, int position) {
  644           return insertIndexForLayer(null, layer, position);
  645       }
  646   
  647       /**
  648        * This method is an extended version of insertIndexForLayer()
  649        * to support setLayer which uses Container.setZOrder which does
  650        * not remove the component from the containment heirarchy though
  651        * we need to ignore it when calculating the insertion index.
  652        *
  653        * @param comp      component to ignore when determining index
  654        * @param layer     an int specifying the layer
  655        * @param position  an int specifying the position within the layer
  656        * @return an int giving the (absolute) insertion-index
  657        *
  658        * @see #getIndexOf
  659        */
  660       private int insertIndexForLayer(Component comp, int layer, int position) {
  661           int i, count, curLayer;
  662           int layerStart = -1;
  663           int layerEnd = -1;
  664           int componentCount = getComponentCount();
  665   
  666           ArrayList<Component> compList =
  667               new ArrayList<Component>(componentCount);
  668           for (int index = 0; index < componentCount; index++) {
  669               if (getComponent(index) != comp) {
  670                   compList.add(getComponent(index));
  671               }
  672           }
  673   
  674           count = compList.size();
  675           for (i = 0; i < count; i++) {
  676               curLayer = getLayer(compList.get(i));
  677               if (layerStart == -1 && curLayer == layer) {
  678                   layerStart = i;
  679               }
  680               if (curLayer < layer) {
  681                   if (i == 0) {
  682                       // layer is greater than any current layer
  683                       // [ ASSERT(layer > highestLayer()) ]
  684                       layerStart = 0;
  685                       layerEnd = 0;
  686                   } else {
  687                       layerEnd = i;
  688                   }
  689                   break;
  690               }
  691           }
  692   
  693           // layer requested is lower than any current layer
  694           // [ ASSERT(layer < lowestLayer()) ]
  695           // put it on the bottom of the stack
  696           if (layerStart == -1 && layerEnd == -1)
  697               return count;
  698   
  699           // In the case of a single layer entry handle the degenerative cases
  700           if (layerStart != -1 && layerEnd == -1)
  701               layerEnd = count;
  702   
  703           if (layerEnd != -1 && layerStart == -1)
  704               layerStart = layerEnd;
  705   
  706           // If we are adding to the bottom, return the last element
  707           if (position == -1)
  708               return layerEnd;
  709   
  710           // Otherwise make sure the requested position falls in the
  711           // proper range
  712           if (position > -1 && layerStart + position <= layerEnd)
  713               return layerStart + position;
  714   
  715           // Otherwise return the end of the layer
  716           return layerEnd;
  717       }
  718   
  719       /**
  720        * Returns a string representation of this JLayeredPane. This method
  721        * is intended to be used only for debugging purposes, and the
  722        * content and format of the returned string may vary between
  723        * implementations. The returned string may be empty but may not
  724        * be <code>null</code>.
  725        *
  726        * @return  a string representation of this JLayeredPane.
  727        */
  728       protected String paramString() {
  729           String optimizedDrawingPossibleString = (optimizedDrawingPossible ?
  730                                                    "true" : "false");
  731   
  732           return super.paramString() +
  733           ",optimizedDrawingPossible=" + optimizedDrawingPossibleString;
  734       }
  735   
  736   /////////////////
  737   // Accessibility support
  738   ////////////////
  739   
  740       /**
  741        * Gets the AccessibleContext associated with this JLayeredPane.
  742        * For layered panes, the AccessibleContext takes the form of an
  743        * AccessibleJLayeredPane.
  744        * A new AccessibleJLayeredPane instance is created if necessary.
  745        *
  746        * @return an AccessibleJLayeredPane that serves as the
  747        *         AccessibleContext of this JLayeredPane
  748        */
  749       public AccessibleContext getAccessibleContext() {
  750           if (accessibleContext == null) {
  751               accessibleContext = new AccessibleJLayeredPane();
  752           }
  753           return accessibleContext;
  754       }
  755   
  756       /**
  757        * This class implements accessibility support for the
  758        * <code>JLayeredPane</code> class.  It provides an implementation of the
  759        * Java Accessibility API appropriate to layered pane user-interface
  760        * elements.
  761        * <p>
  762        * <strong>Warning:</strong>
  763        * Serialized objects of this class will not be compatible with
  764        * future Swing releases. The current serialization support is
  765        * appropriate for short term storage or RMI between applications running
  766        * the same version of Swing.  As of 1.4, support for long term storage
  767        * of all JavaBeans<sup><font size="-2">TM</font></sup>
  768        * has been added to the <code>java.beans</code> package.
  769        * Please see {@link java.beans.XMLEncoder}.
  770        */
  771       protected class AccessibleJLayeredPane extends AccessibleJComponent {
  772   
  773           /**
  774            * Get the role of this object.
  775            *
  776            * @return an instance of AccessibleRole describing the role of the
  777            * object
  778            * @see AccessibleRole
  779            */
  780           public AccessibleRole getAccessibleRole() {
  781               return AccessibleRole.LAYERED_PANE;
  782           }
  783       }
  784   }

Home » openjdk-7 » javax » swing » [javadoc | source]