diff options
author | Roman Kennke <roman@kennke.org> | 2005-06-29 09:28:42 +0000 |
---|---|---|
committer | Roman Kennke <roman@kennke.org> | 2005-06-29 09:28:42 +0000 |
commit | 88f5e6dab577049e03e73cb857ed7df97cbd9c88 (patch) | |
tree | 6239c3e2690025f4628704fe8e92f4405368aeac | |
parent | 6719b3eeb6afd2b9350901fcff4e55f41090aa0e (diff) | |
download | classpath-88f5e6dab577049e03e73cb857ed7df97cbd9c88.tar.gz |
2005-06-29 Roman Kennke <roman@kennke.org>
* gnu/java/awt/AWTUtilities.java
(VisibleComponentList): Added List implementation that iterates over
the child components of a Container and only returns Components
that are actually visible.
(getVisibleChildren): Now returns a List instead of an array. This
list is cached. This greatly decreases allocations in
LayoutManagers.
* javax/swing/BoxLayout.java:
Updated to use the new AWTUtilities.getVisibleChildren() method.
-rw-r--r-- | ChangeLog | 12 | ||||
-rw-r--r-- | gnu/java/awt/AWTUtilities.java | 266 | ||||
-rw-r--r-- | javax/swing/BoxLayout.java | 37 |
3 files changed, 290 insertions, 25 deletions
@@ -1,3 +1,15 @@ +2005-06-29 Roman Kennke <roman@kennke.org> + + * gnu/java/awt/AWTUtilities.java + (VisibleComponentList): Added List implementation that iterates over + the child components of a Container and only returns Components + that are actually visible. + (getVisibleChildren): Now returns a List instead of an array. This + list is cached. This greatly decreases allocations in + LayoutManagers. + * javax/swing/BoxLayout.java: + Updated to use the new AWTUtilities.getVisibleChildren() method. + 2005-06-29 David Gilbert <david.gilbert@object-refinery.com> * javax/swing/package.html: added package description, diff --git a/gnu/java/awt/AWTUtilities.java b/gnu/java/awt/AWTUtilities.java index 83263b466..8ec5288fe 100644 --- a/gnu/java/awt/AWTUtilities.java +++ b/gnu/java/awt/AWTUtilities.java @@ -39,7 +39,11 @@ package gnu.java.awt; import java.awt.Component; import java.awt.Container; -import java.util.Vector; +import java.util.AbstractSequentialList; +import java.util.List; +import java.util.ListIterator; +import java.util.NoSuchElementException; +import java.util.WeakHashMap; /** * This class provides utility methods that are commonly used in AWT @@ -49,6 +53,248 @@ public class AWTUtilities { /** + * This List implementation wraps the Component[] returned by + * {@link Container#getComponents()} and iterates over the visible Components + * in that array. This class is used in {@link #getVisibleChildren}. + */ + static class VisibleComponentList extends AbstractSequentialList + { + /** + * The ListIterator for this List. + */ + class VisibleComponentIterator implements ListIterator + { + /** The current index in the Component[]. */ + int index; + + /** The index in the List of visible Components. */ + int listIndex; + + /** + * Creates a new VisibleComponentIterator that starts at the specified + * <code>listIndex</code>. The array of Components is searched from + * the beginning to find the matching array index. + * + * @param listIndex the index from where to begin iterating + */ + VisibleComponentIterator(int listIndex) + { + this.listIndex = listIndex; + int visibleComponentsFound = 0; + for (index = 0; visibleComponentsFound != listIndex; index++) + { + if (components[index].isVisible()) + visibleComponentsFound++; + } + } + + /** + * Returns <code>true</code> if there are more visible components in the + * array, <code>false</code> otherwise. + * + * @return <code>true</code> if there are more visible components in the + * array, <code>false</code> otherwise + */ + public boolean hasNext() + { + boolean hasNext = false; + for (int i = index; i < components.length; i++) + { + if (components[i].isVisible()) + { + hasNext = true; + break; + } + } + return hasNext; + } + + /** + * Returns the next visible <code>Component</code> in the List. + * + * @return the next visible <code>Component</code> in the List + * + * @throws if there is no next element + */ + public Object next() + { + Object o = null; + for (; index < components.length; index++) + { + if (components[index].isVisible()) + { + o = components[index]; + break; + } + } + if (o != null) + { + index++; + listIndex++; + return o; + } + else + throw new NoSuchElementException(); + } + + /** + * Returns <code>true</code> if there are more visible components in the + * array in the reverse direction, <code>false</code> otherwise. + * + * @return <code>true</code> if there are more visible components in the + * array in the reverse direction, <code>false</code> otherwise + */ + public boolean hasPrevious() + { + boolean hasPrevious = false; + for (int i = index - 1; i >= 0; i--) + { + if (components[i].isVisible()) + { + hasPrevious = true; + break; + } + } + return hasPrevious; + } + + /** + * Returns the previous visible <code>Component</code> in the List. + * + * @return the previous visible <code>Component</code> in the List + * + * @throws NoSuchElementException if there is no previous element + */ + public Object previous() + { + Object o = null; + for (index--; index >= 0; index--) + { + if (components[index].isVisible()) + { + o = components[index]; + break; + } + } + if (o != null) + { + listIndex--; + return o; + } + else + throw new NoSuchElementException(); + } + + /** + * Returns the index of the next element in the List. + * + * @return the index of the next element in the List + */ + public int nextIndex() + { + return listIndex + 1; + } + + /** + * Returns the index of the previous element in the List. + * + * @return the index of the previous element in the List + */ + public int previousIndex() + { + return listIndex - 1; + } + + /** + * This operation is not supported because the List is immutable. + * + * @throws UnsupportedOperationException because the List is immutable + */ + public void remove() + { + throw new UnsupportedOperationException + ("VisibleComponentList is immutable"); + } + + /** + * This operation is not supported because the List is immutable. + * + * @param o not used here + * + * @throws UnsupportedOperationException because the List is immutable + */ + public void set(Object o) + { + throw new UnsupportedOperationException + ("VisibleComponentList is immutable"); + } + + /** + * This operation is not supported because the List is immutable. + * + * @param o not used here + * + * @throws UnsupportedOperationException because the List is immutable + */ + public void add(Object o) + { + throw new UnsupportedOperationException + ("VisibleComponentList is immutable"); + } + } + + /** + * The components over which we iterate. Only the visible components + * are returned by this List. + */ + Component[] components; + + /** + * Creates a new instance of VisibleComponentList that wraps the specified + * <code>Component[]</code>. + * + * @param c the <code>Component[]</code> to be wrapped. + */ + VisibleComponentList(Component[] c) + { + components = c; + } + + /** + * Returns a {@link ListIterator} for iterating over this List. + * + * @return a {@link ListIterator} for iterating over this List + */ + public ListIterator listIterator(int index) + { + return new VisibleComponentIterator(index); + } + + /** + * Returns the number of visible components in the wrapped Component[]. + * + * @return the number of visible components + */ + public int size() + { + int visibleComponents = 0; + for (int i = 0; i < components.length; i++) + if (components[i].isVisible()) + visibleComponents++; + return visibleComponents; + } + } + + /** + * The cache for our List instances. We try to hold one instance of + * VisibleComponentList for each Component[] that is requested. Note + * that we use a WeakHashMap for caching, so that the cache itself + * does not keep the array or the List from beeing garbage collected + * if no other objects hold references to it. + */ + static WeakHashMap visibleChildrenCache = new WeakHashMap(); + + /** * Returns the visible children of a {@link Container}. This method is * commonly needed in LayoutManagers, because they only have to layout * the visible children of a Container. @@ -57,13 +303,19 @@ public class AWTUtilities * * @return the visible children of <code>c</code> */ - public static Component[] getVisibleChildren(Container c) + public static List getVisibleChildren(Container c) { Component[] children = c.getComponents(); - Vector visible = new Vector(); - for (int i = 0; i < children.length; i++) - if (children[i].isVisible()) - visible.add(children[i]); - return (Component[]) visible.toArray(new Container[visible.size()]); + Object o = visibleChildrenCache.get(children); + VisibleComponentList visibleChildren = null; + if (o == null) + { + visibleChildren = new VisibleComponentList(children); + visibleChildrenCache.put(children, visibleChildren); + } + else + visibleChildren = (VisibleComponentList) o; + + return visibleChildren; } } diff --git a/javax/swing/BoxLayout.java b/javax/swing/BoxLayout.java index bd543bec1..78742bb8e 100644 --- a/javax/swing/BoxLayout.java +++ b/javax/swing/BoxLayout.java @@ -47,6 +47,7 @@ import java.awt.LayoutManager2; import java.io.Serializable; import java.util.Collection; import java.util.Iterator; +import java.util.List; import java.util.Vector; import gnu.java.awt.AWTUtilities; @@ -404,16 +405,16 @@ public class BoxLayout implements LayoutManager2, Serializable int x = 0; int y = 0; - Component[] children = AWTUtilities.getVisibleChildren(parent); + List children = AWTUtilities.getVisibleChildren(parent); if (isHorizontalIn(parent)) { x = insets.left + insets.right; // sum up preferred widths of components, find maximum of preferred // heights - for (int index = 0; index < children.length; index++) + for (Iterator i = children.iterator(); i.hasNext();) { - Component comp = children[index]; + Component comp = (Component) i.next(); Dimension sz = comp.getPreferredSize(); x += sz.width; y = Math.max(y, sz.height); @@ -425,9 +426,9 @@ public class BoxLayout implements LayoutManager2, Serializable y = insets.top + insets.bottom; // sum up preferred heights of components, find maximum of // preferred widths - for (int index = 0; index < children.length; index++) + for (Iterator i = children.iterator(); i.hasNext();) { - Component comp = children[index]; + Component comp = (Component) i.next(); Dimension sz = comp.getPreferredSize(); y += sz.height; x = Math.max(x, sz.width); @@ -454,15 +455,15 @@ public class BoxLayout implements LayoutManager2, Serializable int x = insets.left + insets.right; int y = insets.bottom + insets.top; - Component[] children = AWTUtilities.getVisibleChildren(parent); + List children = AWTUtilities.getVisibleChildren(parent); if (isHorizontalIn(parent)) { // sum up preferred widths of components, find maximum of preferred // heights - for (int index = 0; index < children.length; index++) + for (Iterator i = children.iterator(); i.hasNext();) { - Component comp = children[index]; + Component comp = (Component) i.next(); Dimension sz = comp.getMinimumSize(); x += sz.width; y = Math.max(y, sz.height); @@ -472,9 +473,9 @@ public class BoxLayout implements LayoutManager2, Serializable { // sum up preferred heights of components, find maximum of // preferred widths - for (int index = 0; index < children.length; index++) + for (Iterator i = children.iterator(); i.hasNext();) { - Component comp = children[index]; + Component comp = (Component) i.next(); Dimension sz = comp.getMinimumSize(); y += sz.height; x = Math.max(x, sz.width); @@ -565,16 +566,16 @@ public class BoxLayout implements LayoutManager2, Serializable int x = insets.left + insets.right; int y = insets.top + insets.bottom; - Component[] children = AWTUtilities.getVisibleChildren(parent); + List children = AWTUtilities.getVisibleChildren(parent); if (isHorizontalIn(parent)) { // sum up preferred widths of components, find maximum of preferred // heights - for (int index = 0; index < children.length; index++) + for (Iterator i = children.iterator(); i.hasNext();) { - Component comp = children[index]; + Component comp = (Component) i.next(); Dimension sz = comp.getMaximumSize(); x += sz.width; // Check for overflow. @@ -587,9 +588,9 @@ public class BoxLayout implements LayoutManager2, Serializable { // sum up preferred heights of components, find maximum of // preferred widths - for (int index = 0; index < children.length; index++) + for (Iterator i = children.iterator(); i.hasNext();) { - Component comp = children[index]; + Component comp = (Component) i.next(); Dimension sz = comp.getMaximumSize(); y += sz.height; // Check for overflow @@ -624,12 +625,12 @@ public class BoxLayout implements LayoutManager2, Serializable // Set all components to their preferredSizes and sum up the allocated // space. Create SizeReqs for each component and store them in // sizeReqs. Find the maximum size in the crossing direction. - Component[] children = AWTUtilities.getVisibleChildren(parent); + List children = AWTUtilities.getVisibleChildren(parent); Vector sizeReqs = new Vector(); int allocated = 0; - for (int i = 0; i < children.length; i++) + for (Iterator i = children.iterator(); i.hasNext();) { - Component c = children[i]; + Component c = (Component) i.next(); SizeReq sizeReq = new SizeReq(c, layoutDir); int preferred = layoutDir.size(c.getPreferredSize()); sizeReq.size = preferred; |