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

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