JLayeredPane.java: Implement.
authorGraydon Hoare <graydon@redhat.com>
Sat, 22 Nov 2003 00:03:35 +0000 (00:03 +0000)
committerGraydon Hoare <graydon@gcc.gnu.org>
Sat, 22 Nov 2003 00:03:35 +0000 (00:03 +0000)
2003-11-18  Graydon Hoare  <graydon@redhat.com>

* javax/swing/JLayeredPane.java: Implement.
* javax/swing/JFrame.java (getContentPane): Make public
* javax/swing/javax/swing/JRootPane.java (setContentPane):
Use JLayeredPane.FRAME_CONTENT_LAYER.

From-SVN: r73825

libjava/ChangeLog
libjava/javax/swing/JFrame.java
libjava/javax/swing/JLayeredPane.java
libjava/javax/swing/JRootPane.java

index 3abf280..79a8911 100644 (file)
@@ -1,3 +1,10 @@
+2003-11-18  Graydon Hoare  <graydon@redhat.com>
+
+       * javax/swing/JLayeredPane.java: Implement.
+       * javax/swing/JFrame.java (getContentPane): Make public
+       * javax/swing/javax/swing/JRootPane.java (setContentPane): 
+       Use JLayeredPane.FRAME_CONTENT_LAYER.
+
 2003-11-21  Mark Wielaard  <mark@klomp.org>
 
        * java/lang/Float.java (static): Removed.
index 9f4436f..cc93a87 100644 (file)
@@ -149,7 +149,7 @@ public class JFrame extends Frame
     JRootPane createRootPane()
     {   return new JRootPane();    }
 
-    Container getContentPane()
+    public Container getContentPane()
     {    return getRootPane().getContentPane();     }
 
     void setContentPane(Container contentPane)
index 6921780..68512a6 100644 (file)
@@ -39,22 +39,353 @@ exception statement from your version. */
 package javax.swing;
 
 import java.awt.Component;
+import java.util.*;
+import java.awt.Component;
 import javax.accessibility.Accessible;
 
+
+/**
+ * The "Layered Pane" is a container which divides its children into 6 (or
+ * more) disjoint sets. the pre-defined sets are:
+ *
+ *  "Frame Content", "Default", "Palette", "Modal", "Popup", and "Drag".
+ *
+ * A child is in exactly one of these layers at any time, though there may
+ * be other layers if someone creates them.
+ *
+ * The purpose of this class is to translate this view of "layers" into a
+ * contiguous array of components: the one held in our ancestor,
+ * java.awt.Container.
+ *
+ * There is a precise set of words we will use to refer to numbers within
+ * this class:
+ * 
+ * Internal Component Index: an offset into the "component" array held in
+ * our ancestor, java.awt.Container, from [0 .. component.length). The
+ * drawing rule with internal indices is that 0 is drawn first.
+ *
+ * External Component Index: an offset into the "logical drawing order" of
+ * this container. If I is the internal index of a component, the external
+ * index E = component.length - I. The rule with external indices is that 0
+ * is drawn last.
+ *
+ * Layer Number: a general int specifying a layer within this component.
+ * Negative numbers are drawn first, then layer 0, then positive numbered
+ * layers, in ascending order.
+ *
+ * Position: an offset into a layer's "logical drawing order". Layer
+ * position 0 is drawn last. Layer position -1 is a synonym for the first
+ * layer position (the logical "bottom").
+ */
+
 public class JLayeredPane extends JComponent implements Accessible
 {
+
+    public static String LAYER_PROPERTY = "LAYER_PROPERTY";
+
+    public static Integer FRAME_CONTENT_LAYER = new Integer (-30000);
+
+    public static Integer DEFAULT_LAYER = new Integer (0);
+    public static Integer PALETTE_LAYER = new Integer (100);
+    public static Integer MODAL_LAYER   = new Integer (200);
+    public static Integer POPUP_LAYER   = new Integer (300);
+    public static Integer DRAG_LAYER    = new Integer (400);
+
+    TreeMap layers;               // Layer Number (Integer) -> Layer Size (Integer)
+    Hashtable componentToLayer;   // Component -> Layer Number (Integer)
+
+    protected Integer getLayer (Component c)
+    {
+       if (! componentToLayer.containsKey (c))
+           throw new IllegalArgumentException ();
+       return (Integer) componentToLayer.get (c);
+    }
+
+    // this returns a half-open range [bottom, top), which is the range of
+    // internal component indices this layer number corresponds to.  note
+    // that top is *not* included in the range of component indices in this
+    // layer: a layer with 0 elements in it has ret[0] == ret[1].
+
+    protected int[] layerToRange (Integer layer)
+    {
+       int[] ret = new int[2]; 
+       Iterator i = layers.entrySet ().iterator ();
+       while (i.hasNext())
+           {
+               Map.Entry pair = (Map.Entry) i.next();
+               Integer layerNum = (Integer) pair.getKey ();
+               Integer layerSz = (Integer) pair.getValue ();
+               if (layerNum == layer)
+                   {
+                       ret[1] = ret[0] + layerSz.intValue ();
+                       return ret;
+                   }
+               else
+                   {
+                       ret[0] += layerSz.intValue ();
+                   }
+           }
+       // should have found the layer during iteration
+       throw new IllegalArgumentException ();
+    }
+
+    protected void incrLayer(Integer layer)
+    {
+       int sz = 1;
+       if (layers.containsKey (layer))
+           sz += ((Integer)(layers.get (layer))).intValue ();
+       layers.put (layer, new Integer(sz));
+    }
+
+    protected void decrLayer(Integer layer)
+    {
+       int sz = 0;
+       if (layers.containsKey (layer))
+           sz = ((Integer)(layers.get (layer))).intValue () - 1;
+       layers.put (layer, new Integer(sz));
+    }
+
     JLayeredPane()
     {
+       layers = new TreeMap ();
+       layers.put (FRAME_CONTENT_LAYER, new Integer (0));
+       layers.put (DEFAULT_LAYER, new Integer (0));
+       layers.put (PALETTE_LAYER, new Integer (0));
+       layers.put (MODAL_LAYER, new Integer (0));
+       layers.put (POPUP_LAYER, new Integer (0));
+       layers.put (DRAG_LAYER, new Integer (0));       
+
+       componentToLayer = new Hashtable ();
+    }
+
+    public int highestLayer()
+    {
+       if (layers.size() == 0)
+           return 0;
+       return ((Integer)(layers.lastKey ())).intValue ();
+    }
+    
+    public int lowestLayer()
+    {
+       if (layers.size() == 0)
+           return 0;
+       return ((Integer)(layers.firstKey ())).intValue ();
+    }
+
+    public void moveToFront(Component c)
+    {
+       setPosition (c, 0);
     }
 
+    public void moveToBack(Component c)
+    {
+       setPosition (c, -1);
+    }
     
-    protected void addImpl(Component comp, Object constraints, int index) 
-    {        
-        super.addImpl(comp, constraints, index);
+    public int getPosition(Component c)
+    {
+       Integer layer = getLayer (c);
+       int[] range = layerToRange (layer);
+       int top = (range[1] - 1);
+       Component[] comps = getComponents ();
+       for (int i = range[0]; i < range[1]; ++i)
+           {
+               if (comps[i] == c)
+                   return top - i;
+           }
+       // should have found it
+       throw new IllegalArgumentException ();
+    }
+
+    public void setPosition(Component c, int position)
+    {
+       Integer layer = getLayer (c);
+       int[] range = layerToRange (layer);
+       if (range[0] == range[1])
+           throw new IllegalArgumentException ();
+
+       int top = (range[1] - 1);
+       if (position == -1)
+           position = top - range[0];
+       int targ = top - position;
+       int curr = -1;
+
+       Component[] comps = getComponents();
+       for (int i = range[0]; i < range[1]; ++i)
+           {
+               if (comps[i] == c)
+                   {
+                       curr = i;
+                       break;
+                   }
+           }
+       if (curr == -1)
+           // should have found it
+           throw new IllegalArgumentException ();
+
+       // System.err.println("set component position to " + position + " in layer " + layer);
+
+       Component tmp = comps[curr];
+       super.remove (curr);
+       super.add (tmp, targ);
+       super.validate ();
+    }
+    
+
+
+    public Component[] getComponentsInLayer(int layer)
+    {
+       int[] range = layerToRange (getObjectForLayer (layer));
+       if (range[0] == range[1])
+           return new Component[0];
+       else
+           {
+               Component[] comps = getComponents ();
+               int sz = (range[1] - 1) - range[0];
+               Component[] nc = new Component[sz];
+               for (int i = 0; i < sz; ++i)
+                   nc[i] = comps[range[0] + i];
+               return nc;
+           }
+    }
+
+    public int getComponentCountInLayer(int layer)
+    {
+       int[] range = layerToRange (getObjectForLayer (layer));
+       if (range[0] == range[1])
+           return 0;
+       else
+           return ((range[1] - 1) - range[0]);
+    }
+
+    protected Hashtable getComponentToLayer()
+    {
+       return componentToLayer;
+    }
+
+    protected int getInternalIndexOf(Component c) 
+    {
+       Integer layer = getLayer (c);
+       int[] range = layerToRange (layer);
+       Component[] comps = getComponents();
+       for (int i = range[0]; i < range[1]; ++i)
+           {
+               if (comps[i] == c)
+                   return i;
+           }
+       // should have found the component during iteration
+       throw new IllegalArgumentException ();
+    }
+
+
+    public int getIndexOf(Component c) 
+    {
+       // returns the *external* index of the component.
+       int top = getComponentCount() - 1;
+       return top - getIndexOf (c);
+    }    
+
+
+    protected Integer getObjectForLayer(int layer)
+    {
+       switch (layer)
+           {
+           case -30000:
+               return FRAME_CONTENT_LAYER;
+
+           case 0:
+               return DEFAULT_LAYER;
+
+           case 100:
+               return PALETTE_LAYER;
+
+           case 200:
+               return MODAL_LAYER;
+
+           case 300:
+               return POPUP_LAYER;
+
+           case 400:
+               return DRAG_LAYER;
+
+           default:
+               break;
+           }
+
+       return new Integer(layer);
+    }
+    
+    protected int insertIndexForLayer(int layer, int position)
+    {
+       int[] range = layerToRange (getObjectForLayer (layer));
+       if (range[0] == range[1])
+           return range[0];
        
-        comp.validate();
-        comp.repaint();
+       int bottom = range[0];
+       int top = range[1] - 1;
+       
+       if (position == -1 || position > (top - bottom))
+           return bottom;
+       else
+           return top - position;
     }
     
-  
+    public void remove (int index)
+    {
+       Component c = getComponent (index);
+       Integer layer = getLayer (c);
+       decrLayer (layer);
+       componentToLayer.remove (c);
+       super.remove (index);
+    }
+       
+    public void remove (Component comp)
+    {
+       Integer layer = getLayer (comp);
+       decrLayer (layer);
+       componentToLayer.remove (comp);
+       super.remove (comp);
+    }
+
+    public void removeAll ()
+    {
+       componentToLayer.clear ();
+       layers.clear ();
+       super.removeAll ();
+    }
+
+    public void setLayer(Component c, int layer)
+    {
+       componentToLayer.put (c, getObjectForLayer (layer));
+    }
+
+    public void setLayer(Component c,
+                        int layer,
+                        int position)
+    {
+       componentToLayer.put (c, getObjectForLayer (layer));
+       setPosition(c, position);
+        repaint();
+    }
+
+    protected void addImpl(Component comp, Object layerConstraint, int index) 
+    {          
+       Integer layer;
+       if (layerConstraint != null && layerConstraint instanceof Integer)
+               layer = (Integer) layerConstraint;
+       else if (componentToLayer.containsKey (comp))
+           layer = (Integer) componentToLayer.remove (comp);
+       else
+           layer = DEFAULT_LAYER;
+
+       int newIdx = insertIndexForLayer(layer.intValue (), -1);
+       componentToLayer.put (comp, layer);
+       incrLayer (layer);
+
+       // System.err.println("adding component to layer " + layer);
+       
+        super.addImpl(comp, null, newIdx);     
+        validate();
+        repaint();
+    }     
 }
index f0121b8..ccab07c 100644 (file)
@@ -119,7 +119,7 @@ public class JRootPane extends JComponent
     public void setContentPane(Container p)
     {
        contentPane = p;    
-       getLayeredPane().add(contentPane, 0);
+       getLayeredPane().add(contentPane, JLayeredPane.FRAME_CONTENT_LAYER);
     }
 
     protected void addImpl(Component comp,