summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoman Kennke <roman@kennke.org>2005-06-29 09:28:42 +0000
committerRoman Kennke <roman@kennke.org>2005-06-29 09:28:42 +0000
commit88f5e6dab577049e03e73cb857ed7df97cbd9c88 (patch)
tree6239c3e2690025f4628704fe8e92f4405368aeac
parent6719b3eeb6afd2b9350901fcff4e55f41090aa0e (diff)
downloadclasspath-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--ChangeLog12
-rw-r--r--gnu/java/awt/AWTUtilities.java266
-rw-r--r--javax/swing/BoxLayout.java37
3 files changed, 290 insertions, 25 deletions
diff --git a/ChangeLog b/ChangeLog
index a71abb5c1..0ea9ba4f7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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;