JLayeredPanepublic class JLayeredPane extends JComponent implements AccessibleJLayeredPane adds depth to a JFC/Swing container,
allowing components to overlap each other when needed.
An Integer object specifies each component's depth in the
container, where higher-numbered components sit "on top" of other
components.
For task-oriented documentation and examples of using layered panes see
How to Use a Layered Pane,
a section in The Java Tutorial.
For convenience, JLayeredPane divides the depth-range
into several different layers. Putting a component into one of those
layers makes it easy to ensure that components overlap properly,
without having to worry about specifying numbers for specific depths:
- DEFAULT_LAYER
- The standard layer, where most components go. This the bottommost
layer.
- PALETTE_LAYER
- The palette layer sits over the default layer. Useful for floating
toolbars and palettes, so they can be positioned above other components.
- MODAL_LAYER
- The layer used for modal dialogs. They will appear on top of any
toolbars, palettes, or standard components in the container.
- POPUP_LAYER
- The popup layer displays above dialogs. That way, the popup windows
associated with combo boxes, tooltips, and other help text will appear
above the component, palette, or dialog that generated them.
- DRAG_LAYER
- When dragging a component, reassigning it to the drag layer ensures
that it is positioned over every other component in the container. When
finished dragging, it can be reassigned to its normal layer.
The JLayeredPane methods moveToFront(Component) ,
moveToBack(Component) and setPosition can be used
to reposition a component within its layer. The setLayer method
can also be used to change the component's current layer.
Details
JLayeredPane manages its list of children like
Container , but allows for the definition of a several
layers within itself. Children in the same layer are managed exactly
like the normal Container object,
with the added feature that when children components overlap, children
in higher layers display above the children in lower layers.
Each layer is a distinct integer number. The layer attribute can be set
on a Component by passing an Integer
object during the add call. For example:
layeredPane.add(child, JLayeredPane.DEFAULT_LAYER);
or
layeredPane.add(child, new Integer(10));
The layer attribute can also be set on a Component by calling
layeredPaneParent.setLayer(child, 10)
on the JLayeredPane that is the parent of component. The layer
should be set before adding the child to the parent.
Higher number layers display above lower number layers. So, using
numbers for the layers and letters for individual components, a
representative list order would look like this:
5a, 5b, 5c, 2a, 2b, 2c, 1a
where the leftmost components are closest to the top of the display.
A component can be moved to the top or bottom position within its
layer by calling moveToFront or moveToBack .
The position of a component within a layer can also be specified directly.
Valid positions range from 0 up to one less than the number of
components in that layer. A value of -1 indicates the bottommost
position. A value of 0 indicates the topmost position. Unlike layer
numbers, higher position values are lower in the display.
Note: This sequence (defined by java.awt.Container) is the reverse
of the layer numbering sequence. Usually though, you will use moveToFront ,
moveToBack , and setLayer .
Here are some examples using the method add(Component, layer, position):
Calling add(5x, 5, -1) results in:
5a, 5b, 5c, 5x, 2a, 2b, 2c, 1a
Calling add(5z, 5, 2) results in:
5a, 5b, 5z, 5c, 5x, 2a, 2b, 2c, 1a
Calling add(3a, 3, 7) results in:
5a, 5b, 5z, 5c, 5x, 3a, 2a, 2b, 2c, 1a
Using normal paint/event mechanics results in 1a appearing at the bottom
and 5a being above all other components.
Note: that these layers are simply a logical construct and LayoutManagers
will affect all child components of this container without regard for
layer settings.
Warning: Swing is not thread safe. For more
information see Swing's Threading
Policy.
Warning:
Serialized objects of this class will not be compatible with
future Swing releases. The current serialization support is
appropriate for short term storage or RMI between applications running
the same version of Swing. As of 1.4, support for long term storage
of all JavaBeansTM
has been added to the java.beans package.
Please see {@link java.beans.XMLEncoder}. |
Fields Summary |
---|
public static final Integer | DEFAULT_LAYERConvenience object defining the Default layer. Equivalent to new Integer(0). | public static final Integer | PALETTE_LAYERConvenience object defining the Palette layer. Equivalent to new Integer(100). | public static final Integer | MODAL_LAYERConvenience object defining the Modal layer. Equivalent to new Integer(200). | public static final Integer | POPUP_LAYERConvenience object defining the Popup layer. Equivalent to new Integer(300). | public static final Integer | DRAG_LAYERConvenience object defining the Drag layer. Equivalent to new Integer(400). | public static final Integer | FRAME_CONTENT_LAYERConvenience object defining the Frame Content layer.
This layer is normally only use to positon the contentPane and menuBar
components of JFrame.
Equivalent to new Integer(-30000). | public static final String | LAYER_PROPERTYBound property | private Hashtable | componentToLayer | private boolean | optimizedDrawingPossible |
Constructors Summary |
---|
public JLayeredPane()Create a new JLayeredPane
//////////////////////////////////////////////////////////////////////////////
//// Container Override methods
//////////////////////////////////////////////////////////////////////////////
setLayout(null);
|
Methods Summary |
---|
protected void | addImpl(java.awt.Component comp, java.lang.Object constraints, int index)
int layer = DEFAULT_LAYER.intValue();
int pos;
if(constraints instanceof Integer) {
layer = ((Integer)constraints).intValue();
setLayer(comp, layer);
} else
layer = getLayer(comp);
pos = insertIndexForLayer(layer, index);
super.addImpl(comp, constraints, pos);
comp.validate();
comp.repaint();
validateOptimizedDrawing();
| public javax.accessibility.AccessibleContext | getAccessibleContext()Gets the AccessibleContext associated with this JLayeredPane.
For layered panes, the AccessibleContext takes the form of an
AccessibleJLayeredPane.
A new AccessibleJLayeredPane instance is created if necessary.
if (accessibleContext == null) {
accessibleContext = new AccessibleJLayeredPane();
}
return accessibleContext;
| public int | getComponentCountInLayer(int layer)Returns the number of children currently in the specified layer.
int i, count, curLayer;
int layerCount = 0;
count = getComponentCount();
for(i = 0; i < count; i++) {
curLayer = getLayer(getComponent(i));
if(curLayer == layer) {
layerCount++;
/// Short circut the counting when we have them all
} else if(layerCount > 0 || curLayer < layer) {
break;
}
}
return layerCount;
| protected java.util.Hashtable | getComponentToLayer()Returns the hashtable that maps components to layers.
if(componentToLayer == null)
componentToLayer = new Hashtable<Component,Integer>(4);
return componentToLayer;
| public java.awt.Component[] | getComponentsInLayer(int layer)Returns an array of the components in the specified layer.
int i, count, curLayer;
int layerCount = 0;
Component[] results;
results = new Component[getComponentCountInLayer(layer)];
count = getComponentCount();
for(i = 0; i < count; i++) {
curLayer = getLayer(getComponent(i));
if(curLayer == layer) {
results[layerCount++] = getComponent(i);
/// Short circut the counting when we have them all
} else if(layerCount > 0 || curLayer < layer) {
break;
}
}
return results;
| public int | getIndexOf(java.awt.Component c)Returns the index of the specified Component.
This is the absolute index, ignoring layers.
Index numbers, like position numbers, have the topmost component
at index zero. Larger numbers are closer to the bottom.
int i, count;
count = getComponentCount();
for(i = 0; i < count; i++) {
if(c == getComponent(i))
return i;
}
return -1;
| public int | getLayer(java.awt.Component c)Returns the layer attribute for the specified Component.
Integer i;
if(c instanceof JComponent)
i = (Integer)((JComponent)c).getClientProperty(LAYER_PROPERTY);
else
i = (Integer)getComponentToLayer().get((Component)c);
if(i == null)
return DEFAULT_LAYER.intValue();
return i.intValue();
| public static int | getLayer(javax.swing.JComponent c)Gets the layer property for a JComponent, it
does not cause any side effects like setLayer(). (painting, add/remove, etc)
Normally you should use the instance method getLayer().
Integer i;
if((i = (Integer)c.getClientProperty(LAYER_PROPERTY)) != null)
return i.intValue();
return DEFAULT_LAYER.intValue();
| public static javax.swing.JLayeredPane | getLayeredPaneAbove(java.awt.Component c)Convenience method that returns the first JLayeredPane which
contains the specified component. Note that all JFrames have a
JLayeredPane at their root, so any component in a JFrame will
have a JLayeredPane parent.
if(c == null) return null;
Component parent = c.getParent();
while(parent != null && !(parent instanceof JLayeredPane))
parent = parent.getParent();
return (JLayeredPane)parent;
| protected java.lang.Integer | getObjectForLayer(int layer)Returns the Integer object associated with a specified layer.
Integer layerObj;
switch(layer) {
case 0:
layerObj = DEFAULT_LAYER;
break;
case 100:
layerObj = PALETTE_LAYER;
break;
case 200:
layerObj = MODAL_LAYER;
break;
case 300:
layerObj = POPUP_LAYER;
break;
case 400:
layerObj = DRAG_LAYER;
break;
default:
layerObj = new Integer(layer);
}
return layerObj;
| public int | getPosition(java.awt.Component c)Get the relative position of the component within its layer.
int i, count, startLayer, curLayer, startLocation, pos = 0;
count = getComponentCount();
startLocation = getIndexOf(c);
if(startLocation == -1)
return -1;
startLayer = getLayer(c);
for(i = startLocation - 1; i >= 0; i--) {
curLayer = getLayer(getComponent(i));
if(curLayer == startLayer)
pos++;
else
return pos;
}
return pos;
| public int | highestLayer()Returns the highest layer value from all current children.
Returns 0 if there are no children.
if(getComponentCount() > 0)
return getLayer(getComponent(0));
return 0;
| protected int | insertIndexForLayer(int layer, int position)Primitive method that determines the proper location to
insert a new child based on layer and position requests.
return insertIndexForLayer(null, layer, position);
| private int | insertIndexForLayer(java.awt.Component comp, int layer, int position)This method is an extended version of insertIndexForLayer()
to support setLayer which uses Container.setZOrder which does
not remove the component from the containment heirarchy though
we need to ignore it when calculating the insertion index.
int i, count, curLayer;
int layerStart = -1;
int layerEnd = -1;
int componentCount = getComponentCount();
ArrayList<Component> compList =
new ArrayList<Component>(componentCount);
for (int index = 0; index < componentCount; index++) {
if (getComponent(index) != comp) {
compList.add(getComponent(index));
}
}
count = compList.size();
for (i = 0; i < count; i++) {
curLayer = getLayer(compList.get(i));
if (layerStart == -1 && curLayer == layer) {
layerStart = i;
}
if (curLayer < layer) {
if (i == 0) {
// layer is greater than any current layer
// [ ASSERT(layer > highestLayer()) ]
layerStart = 0;
layerEnd = 0;
} else {
layerEnd = i;
}
break;
}
}
// layer requested is lower than any current layer
// [ ASSERT(layer < lowestLayer()) ]
// put it on the bottom of the stack
if (layerStart == -1 && layerEnd == -1)
return count;
// In the case of a single layer entry handle the degenerative cases
if (layerStart != -1 && layerEnd == -1)
layerEnd = count;
if (layerEnd != -1 && layerStart == -1)
layerStart = layerEnd;
// If we are adding to the bottom, return the last element
if (position == -1)
return layerEnd;
// Otherwise make sure the requested position falls in the
// proper range
if (position > -1 && layerStart + position <= layerEnd)
return layerStart + position;
// Otherwise return the end of the layer
return layerEnd;
| public boolean | isOptimizedDrawingEnabled()Returns false if components in the pane can overlap, which makes
optimized drawing impossible. Otherwise, returns true.
return optimizedDrawingPossible;
| public int | lowestLayer()Returns the lowest layer value from all current children.
Returns 0 if there are no children.
int count = getComponentCount();
if(count > 0)
return getLayer(getComponent(count-1));
return 0;
| public void | moveToBack(java.awt.Component c)Moves the component to the bottom of the components in its current layer
(position -1).
setPosition(c, -1);
| public void | moveToFront(java.awt.Component c)Moves the component to the top of the components in its current layer
(position 0).
setPosition(c, 0);
| public void | paint(java.awt.Graphics g)Paints this JLayeredPane within the specified graphics context.
if(isOpaque()) {
Rectangle r = g.getClipBounds();
Color c = getBackground();
if(c == null)
c = Color.lightGray;
g.setColor(c);
if (r != null) {
g.fillRect(r.x, r.y, r.width, r.height);
}
else {
g.fillRect(0, 0, getWidth(), getHeight());
}
}
super.paint(g);
| protected java.lang.String | paramString()Returns a string representation of this JLayeredPane. This method
is intended to be used only for debugging purposes, and the
content and format of the returned string may vary between
implementations. The returned string may be empty but may not
be null .
String optimizedDrawingPossibleString = (optimizedDrawingPossible ?
"true" : "false");
return super.paramString() +
",optimizedDrawingPossible=" + optimizedDrawingPossibleString;
| public static void | putLayer(javax.swing.JComponent c, int layer)Sets the layer property on a JComponent. This method does not cause
any side effects like setLayer() (painting, add/remove, etc).
Normally you should use the instance method setLayer(), in order to
get the desired side-effects (like repainting).
/// MAKE SURE THIS AND setLayer(Component c, int layer, int position) are SYNCED
Integer layerObj;
layerObj = new Integer(layer);
c.putClientProperty(LAYER_PROPERTY, layerObj);
| public void | remove(int index)Remove the indexed component from this pane.
This is the absolute index, ignoring layers.
Component c = getComponent(index);
super.remove(index);
if (c != null && !(c instanceof JComponent)) {
getComponentToLayer().remove(c);
}
validateOptimizedDrawing();
| public void | removeAll()Removes all the components from this container.
Component[] children = getComponents();
Hashtable cToL = getComponentToLayer();
for (int counter = children.length - 1; counter >= 0; counter--) {
Component c = children[counter];
if (c != null && !(c instanceof JComponent)) {
cToL.remove(c);
}
}
super.removeAll();
| public void | setLayer(java.awt.Component c, int layer)Sets the layer attribute on the specified component,
making it the bottommost component in that layer.
Should be called before adding to parent.
setLayer(c, layer, -1);
| public void | setLayer(java.awt.Component c, int layer, int position)Sets the layer attribute for the specified component and
also sets its position within that layer.
Integer layerObj;
layerObj = getObjectForLayer(layer);
if(layer == getLayer(c) && position == getPosition(c)) {
repaint(c.getBounds());
return;
}
/// MAKE SURE THIS AND putLayer(JComponent c, int layer) are SYNCED
if(c instanceof JComponent)
((JComponent)c).putClientProperty(LAYER_PROPERTY, layerObj);
else
getComponentToLayer().put((Component)c, layerObj);
if(c.getParent() == null || c.getParent() != this) {
repaint(c.getBounds());
return;
}
int index = insertIndexForLayer(c, layer, position);
setComponentZOrder(c, index);
repaint(c.getBounds());
| public void | setPosition(java.awt.Component c, int position)Moves the component to position within its current layer,
where 0 is the topmost position within the layer and -1 is the bottommost
position.
Note: Position numbering is defined by java.awt.Container, and
is the opposite of layer numbering. Lower position numbers are closer
to the top (0 is topmost), and higher position numbers are closer to
the bottom.
setLayer(c, getLayer(c), position);
| private void | validateOptimizedDrawing()
boolean layeredComponentFound = false;
synchronized(getTreeLock()) {
Integer layer = null;
for (Component c : getComponents()) {
layer = null;
if(c instanceof JInternalFrame || (c instanceof JComponent &&
(layer = (Integer)((JComponent)c).getClientProperty(
LAYER_PROPERTY)) != null)) {
if(layer != null && layer.equals(FRAME_CONTENT_LAYER))
continue;
layeredComponentFound = true;
break;
}
}
}
if(layeredComponentFound)
optimizedDrawingPossible = false;
else
optimizedDrawingPossible = true;
|
|