fixes for host gcc 4.6.1
[zpugcc/jano.git] / toolchain / gcc / libjava / javax / swing / JLayeredPane.java
blobe82089b25d395b1e5e214eddbf099f074fe50b24
1 /* JLayeredPane.java --
2 Copyright (C) 2002, 2004 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
38 package javax.swing;
40 import java.awt.Component;
41 import java.util.Hashtable;
42 import java.util.Iterator;
43 import java.util.Map;
44 import java.util.TreeMap;
45 import javax.accessibility.Accessible;
47 /**
48 * <p>The "Layered Pane" is a container which divides its children into 6 (or
49 * more) disjoint sets. the pre-defined sets are:</p>
51 * <ul>
52 * <li>"Frame Content"</li>
53 * <li>"Default"</li>
54 * <li>"Palette"</li>
55 * <li>"Modal"</li>
56 * <li>"Popup"</li>
57 * <li>"Drag"</li>
58 * </ul>
60 * <p>A child is in exactly one of these layers at any time, though there may
61 * be other layers if someone creates them.</p>
63 * <p>The purpose of this class is to translate this view of "layers" into a
64 * contiguous array of components: the one held in our ancestor,
65 * {@link java.awt.Container}.</p>
67 * <p>There is a precise set of words we will use to refer to numbers within
68 * this class:</p>
70 * <dl>
71 * <dt>Component Index:</dt>
72 * <dd>An offset into the <code>component</code> array held in our ancestor,
73 * {@link java.awt.Container}, from <code>[0 .. component.length)</code>. The drawing
74 * rule with indices is that 0 is drawn last.</dd>
76 * <dt>Layer Number:</dt>
77 * <dd>A general <code>int</code> specifying a layer within this component. Negative
78 * numbers are drawn first, then layer 0, then positive numbered layers, in
79 * ascending order.</dd>
81 * <dt>Position:</dt>
82 * <dd>An offset into a layer's "logical drawing order". Layer position 0
83 * is drawn last. Layer position -1 is a synonym for the first layer
84 * position (the logical "bottom").</dd>
86 * <p><b>Note:</b> the layer numbering order is the <em>reverse</em> of the
87 * component indexing and position order</p>
89 * @author Graydon Hoare <graydon@redhat.com>
92 public class JLayeredPane extends JComponent implements Accessible
95 public static String LAYER_PROPERTY = "LAYER_PROPERTY";
97 public static Integer FRAME_CONTENT_LAYER = new Integer (-30000);
99 public static Integer DEFAULT_LAYER = new Integer (0);
100 public static Integer PALETTE_LAYER = new Integer (100);
101 public static Integer MODAL_LAYER = new Integer (200);
102 public static Integer POPUP_LAYER = new Integer (300);
103 public static Integer DRAG_LAYER = new Integer (400);
105 TreeMap layers; // Layer Number (Integer) -> Layer Size (Integer)
106 Hashtable componentToLayer; // Component -> Layer Number (Integer)
108 JLayeredPane()
110 layers = new TreeMap ();
111 componentToLayer = new Hashtable ();
115 /**
116 * Looks up the layer a child component is currently assigned to.
118 * @param c the component to look up.
119 * @return the layer the component is currently assigned to, in this container.
120 * @throws IllegalArgumentException if the component is not a child of this container.
123 protected Integer getLayer (Component c)
125 if (! componentToLayer.containsKey (c))
126 throw new IllegalArgumentException ();
127 return (Integer) componentToLayer.get (c);
131 * <p>Returns a pair of ints representing a half-open interval
132 * <code>[top, bottom)</code>, which is the range of component indices
133 * the provided layer number corresponds to.</p>
135 * <p>Note that "bottom" is <em>not</em> included in the interval of
136 * component indices in this layer: a layer with 0 elements in it has
137 * <code>ret[0] == ret[1]</code>.</p>
139 * @param layer the layer to look up.
140 * @return the half-open range of indices this layer spans.
141 * @throws IllegalArgumentException if layer does not refer to an active layer
142 * in this container.
145 protected int[] layerToRange (Integer layer)
147 int[] ret = new int[2];
148 ret[1] = getComponents ().length;
149 Iterator i = layers.entrySet ().iterator ();
150 while (i.hasNext())
152 Map.Entry pair = (Map.Entry) i.next();
153 Integer layerNum = (Integer) pair.getKey ();
154 Integer layerSz = (Integer) pair.getValue ();
155 if (layerNum == layer)
157 ret[0] = ret[1] - layerSz.intValue ();
158 return ret;
160 else
162 ret[1] -= layerSz.intValue ();
165 // should have found the layer during iteration
166 throw new IllegalArgumentException ();
170 * Increments the recorded size of a given layer.
172 * @param layer the layer number to increment.
173 * @see #incrLayer()
176 protected void incrLayer(Integer layer)
178 int sz = 1;
179 if (layers.containsKey (layer))
180 sz += ((Integer)(layers.get (layer))).intValue ();
181 layers.put (layer, new Integer(sz));
185 * Decrements the recorded size of a given layer.
187 * @param layer the layer number to decrement.
188 * @see #decrLayer()
191 protected void decrLayer(Integer layer)
193 int sz = 0;
194 if (layers.containsKey (layer))
195 sz = ((Integer)(layers.get (layer))).intValue () - 1;
196 layers.put (layer, new Integer(sz));
200 * Return the greatest layer number currently in use, in this container.
201 * This number may legally be positive <em>or</em> negative.
203 * @return the least layer number.
204 * @see #lowestLayer()
207 public int highestLayer()
209 if (layers.size() == 0)
210 return 0;
211 return ((Integer)(layers.lastKey ())).intValue ();
215 * Return the least layer number currently in use, in this container.
216 * This number may legally be positive <em>or</em> negative.
218 * @return the least layer number.
219 * @see #highestLayer()
222 public int lowestLayer()
224 if (layers.size() == 0)
225 return 0;
226 return ((Integer)(layers.firstKey ())).intValue ();
230 * Moves a component to the "front" of its layer. The "front" is a
231 * synonym for position 0, which is also the last position drawn in each
232 * layer, so is usually the component which occludes the most other
233 * components in its layer.
235 * @param c the component to move to the front of its layer.
236 * @throws IllegalArgumentException if the component is not a child of
237 * this container.
238 * @see #moveToBack()
241 public void moveToFront(Component c)
243 setPosition (c, 0);
247 * <p>Moves a component to the "back" of its layer. The "back" is a
248 * synonym for position N-1 (also known as position -1), where N is the
249 * size of the layer.</p>
251 * <p>The "back" of a layer is the first position drawn, so the component at
252 * the "back" is usually the component which is occluded by the most
253 * other components in its layer.</p>
255 * @param c the component to move to the back of its layer.
256 * @throws IllegalArgumentException if the component is not a child of
257 * this container.
258 * @see #moveToFront()
261 public void moveToBack(Component c)
263 setPosition (c, -1);
267 * Return the position of a component within its layer. Positions are assigned
268 * from the "front" (position 0) to the "back" (position N-1), and drawn from
269 * the back towards the front.
271 * @param c the component to get the position of.
272 * @throws IllegalArgumentException if the component is not a child of
273 * this container.
274 * @see #setPosition()
277 public int getPosition(Component c)
279 Integer layer = getLayer (c);
280 int[] range = layerToRange (layer);
281 int top = range[0];
282 int bot = range[1];
283 Component[] comps = getComponents ();
284 for (int i = top; i < bot; ++i)
286 if (comps[i] == c)
287 return i - top;
289 // should have found it
290 throw new IllegalArgumentException ();
294 * Change the position of a component within its layer. Positions are assigned
295 * from the "front" (position 0) to the "back" (position N-1), and drawn from
296 * the back towards the front.
298 * @param c the component to change the position of.
299 * @param position the position to assign the component to.
300 * @throws IllegalArgumentException if the component is not a child of
301 * this container.
302 * @see #getPosition()
305 public void setPosition(Component c, int position)
307 Integer layer = getLayer (c);
308 int[] range = layerToRange (layer);
309 if (range[0] == range[1])
310 throw new IllegalArgumentException ();
312 int top = range[0];
313 int bot = range[1];
314 if (position == -1)
315 position = (bot - top) - 1;
316 int targ = top + position;
317 int curr = -1;
319 Component[] comps = getComponents();
320 for (int i = top; i < bot; ++i)
322 if (comps[i] == c)
324 curr = i;
325 break;
328 if (curr == -1)
329 // should have found it
330 throw new IllegalArgumentException ();
332 super.swapComponents (curr, targ);
333 validate();
334 repaint();
338 * Return an array of all components within a layer of this
339 * container. Components are ordered front-to-back, with the "front"
340 * element (which draws last) at position 0 of the returned array.
342 * @param layer the layer to return components from.
343 * @return the components in the layer.
346 public Component[] getComponentsInLayer(int layer)
348 int[] range = layerToRange (getObjectForLayer (layer));
349 if (range[0] == range[1])
350 return new Component[0];
351 else
353 Component[] comps = getComponents ();
354 int sz = range[1] - range[0];
355 Component[] nc = new Component[sz];
356 for (int i = 0; i < sz; ++i)
357 nc[i] = comps[range[0] + i];
358 return nc;
363 * Return the number of components within a layer of this
364 * container.
366 * @param layer the layer count components in.
367 * @return the number of components in the layer.
370 public int getComponentCountInLayer(int layer)
372 int[] range = layerToRange (getObjectForLayer (layer));
373 if (range[0] == range[1])
374 return 0;
375 else
376 return (range[1] - range[0]);
380 * Return a hashtable mapping child components of this container to
381 * Integer objects representing the component's layer assignments.
384 protected Hashtable getComponentToLayer()
386 return componentToLayer;
390 * Return the index of a component within the underlying (contiguous)
391 * array of children. This is a "raw" number which does not represent the
392 * child's position in a layer, but rather its position in the logical
393 * drawing order of all children of the container.
395 * @param c the component to look up.
396 * @return the external index of the component.
397 * @throws IllegalArgumentException if the component is not a child of
398 * this container.
401 public int getIndexOf(Component c)
403 Integer layer = getLayer (c);
404 int[] range = layerToRange (layer);
405 Component[] comps = getComponents();
406 for (int i = range[0]; i < range[1]; ++i)
408 if (comps[i] == c)
409 return i;
411 // should have found the component during iteration
412 throw new IllegalArgumentException ();
416 * Return an Integer object which holds the same int value as the
417 * parameter. This is strictly an optimization to minimize the number of
418 * identical Integer objects which we allocate.
420 * @param layer the layer number as an int.
421 * @return the layer number as an Integer, possibly shared.
424 protected Integer getObjectForLayer(int layer)
426 switch (layer)
428 case -30000:
429 return FRAME_CONTENT_LAYER;
431 case 0:
432 return DEFAULT_LAYER;
434 case 100:
435 return PALETTE_LAYER;
437 case 200:
438 return MODAL_LAYER;
440 case 300:
441 return POPUP_LAYER;
443 case 400:
444 return DRAG_LAYER;
446 default:
447 break;
450 return new Integer(layer);
454 * Computes an index at which to request the superclass {@link
455 * java.awt.Container} inserts a component, given an abstract layer and
456 * position number.
458 * @param layer the layer in which to insert a component.
459 * @param position the position in the layer at which to insert a component.
460 * @return the index at which to insert the component.
463 protected int insertIndexForLayer(int layer, int position)
466 Integer lobj = getObjectForLayer (layer);
467 if (! layers.containsKey(lobj))
468 layers.put (lobj, new Integer (0));
469 int[] range = layerToRange (lobj);
470 if (range[0] == range[1])
471 return range[0];
473 int top = range[0];
474 int bot = range[1];
476 if (position == -1 || position > (bot - top))
477 return bot;
478 else
479 return top + position;
483 * Removes a child from this container. The child is specified by
484 * index. After removal, the child no longer occupies a layer.
486 * @param index the index of the child component to remove.
489 public void remove (int index)
491 Component c = getComponent (index);
492 Integer layer = getLayer (c);
493 decrLayer (layer);
494 componentToLayer.remove (c);
495 super.remove (index);
499 * Removes a child from this container. The child is specified directly.
500 * After removal, the child no longer occupies a layer.
502 * @param comp the child to remove.
505 public void remove (Component comp)
507 remove (getIndexOf (comp));
511 * <p>Set the layer property for a component, within this container. The
512 * component will be implicitly mapped to the bottom-most position in the
513 * layer, but only if added <em>after</em> calling this method.</p>
515 * <p>Read that carefully: this method should be called <em>before</em> the
516 * component is added to the container.</p>
518 * @param c the component to set the layer property for.
519 * @param layer the layer number to assign to the component.
522 public void setLayer(Component c, int layer)
524 componentToLayer.put (c, getObjectForLayer (layer));
528 * Set the layer and position of a component, within this container.
530 * @param c the child component to set the layer property for.
531 * @param layer the layer number to assign to the component.
532 * @param position the position number to assign to the component.
535 public void setLayer(Component c,
536 int layer,
537 int position)
539 componentToLayer.put (c, getObjectForLayer (layer));
540 setPosition(c, position);
541 validate();
542 repaint();
546 * Overrides the default implementation from {@link java.awt.Container}
547 * such that <code>layerConstraint</code> is interpreted as an {@link
548 * Integer}, specifying the layer to which the component will be added
549 * (at the bottom position).
551 * @param comp the component to add.
552 * @param layerConstraint an integer specifying the layer to add the component to.
553 * @param index an ignored parameter, for compatibility.
556 protected void addImpl(Component comp, Object layerConstraint, int index)
558 Integer layer;
559 if (layerConstraint != null && layerConstraint instanceof Integer)
560 layer = (Integer) layerConstraint;
561 else if (componentToLayer.containsKey (comp))
562 layer = (Integer) componentToLayer.remove (comp);
563 else
564 layer = DEFAULT_LAYER;
566 int newIdx = insertIndexForLayer(layer.intValue (), -1);
568 componentToLayer.put (comp, layer);
569 incrLayer (layer);
571 super.addImpl(comp, null, newIdx);
572 validate();
573 repaint();