diff options
Diffstat (limited to 'libjava/classpath/javax/swing/OverlayLayout.java')
-rw-r--r-- | libjava/classpath/javax/swing/OverlayLayout.java | 507 |
1 files changed, 364 insertions, 143 deletions
diff --git a/libjava/classpath/javax/swing/OverlayLayout.java b/libjava/classpath/javax/swing/OverlayLayout.java index e8aef98a521..56b8c8bb67a 100644 --- a/libjava/classpath/javax/swing/OverlayLayout.java +++ b/libjava/classpath/javax/swing/OverlayLayout.java @@ -1,5 +1,5 @@ -/* OverlayLayout.java -- - Copyright (C) 2002, 2004 Free Software Foundation, Inc. +/* OverlayLayout.java -- A layout manager + Copyright (C) 2002, 2004, 2005 Free Software Foundation, Inc. This file is part of GNU Classpath. @@ -37,155 +37,376 @@ exception statement from your version. */ package javax.swing; +import java.awt.AWTError; import java.awt.Component; import java.awt.Container; import java.awt.Dimension; +import java.awt.Insets; import java.awt.LayoutManager2; import java.io.Serializable; /** - * OverlayLayout - * @author Andrew Selkirk - * @version 1.0 + * A layout manager that lays out the components of a container one over + * another. + * + * The components take as much space as is available in the container, but not + * more than specified by their maximum size. + * + * The overall layout is mainly affected by the components + * <code>alignmentX</code> and <code>alignmentY</code> properties. All + * components are aligned, so that their alignment points (for either + * direction) are placed in one line (the baseline for this direction). + * + * For example: An X alignment of 0.0 means that the component's alignment + * point is at it's left edge, an X alignment of 0.5 means that the alignment + * point is in the middle, an X alignment of 1.0 means, the aligment point is + * at the right edge. So if you have three components, the first with 0.0, the + * second with 0.5 and the third with 1.0, then they are laid out like this: + * + * <pre> + * +-------+ + * | 1 | + * +-------+ + * +-------+ + * | 2 | + * +-------+ + * +---------+ + * | 3 + + * +---------+ + * </pre> + * The above picture shows the X alignment between the components. An Y + * alignment like shown above cannot be achieved with this layout manager. The + * components are place on top of each other, with the X alignment shown above. + * + * @author Roman Kennke (kennke@aicas.com) + * @author Andrew Selkirk */ -public class OverlayLayout - implements LayoutManager2, Serializable +public class OverlayLayout implements LayoutManager2, Serializable { private static final long serialVersionUID = 18082829169631543L; - //------------------------------------------------------------- - // Variables -------------------------------------------------- - //------------------------------------------------------------- - - /** - * target - */ - private Container target; - - /** - * xChildren - */ - private SizeRequirements[] xChildren; - - /** - * yChildren - */ - private SizeRequirements[] yChildren; - - /** - * xTotal - */ - private SizeRequirements xTotal; - - /** - * yTotal - */ - private SizeRequirements yTotal; - - - //------------------------------------------------------------- - // Initialization --------------------------------------------- - //------------------------------------------------------------- - - /** - * Constructor OverlayLayout - * @param target TODO - */ - public OverlayLayout(Container target) { - // TODO - } // OverlayLayout() - - - //------------------------------------------------------------- - // Methods ---------------------------------------------------- - //------------------------------------------------------------- - - /** - * invalidateLayout - * @param target TODO - */ - public void invalidateLayout(Container target) { - // TODO - } // invalidateLayout() - - /** - * addLayoutComponent - * @param string TODO - * @param component TODO - */ - public void addLayoutComponent(String string, Component component) { - // TODO - } // addLayoutComponent() - - /** - * addLayoutComponent - * @param component TODO - * @param constraints TODO - */ - public void addLayoutComponent(Component component, Object constraints) { - // TODO - } // addLayoutComponent() - - /** - * removeLayoutComponent - * @param component TODO - */ - public void removeLayoutComponent(Component component) { - // TODO - } // removeLayoutComponent() - - /** - * preferredLayoutSize - * @param target TODO - * @returns Dimension - */ - public Dimension preferredLayoutSize(Container target) { - return null; // TODO - } // preferredLayoutSize() - - /** - * minimumLayoutSize - * @param target TODO - * @returns Dimension - */ - public Dimension minimumLayoutSize(Container target) { - return null; // TODO - } // minimumLayoutSize() - - /** - * maximumLayoutSize - * @param target TODO - * @returns Dimension - */ - public Dimension maximumLayoutSize(Container target) { - return null; // TODO - } // maximumLayoutSize() - - /** - * getLayoutAlignmentX - * @param target TODO - * @returns float - */ - public float getLayoutAlignmentX(Container target) { - return (float) 0.0; // TODO - } // getLayoutAlignmentX() - - /** - * getLayoutAlignmentY - * @param target TODO - * @returns float - */ - public float getLayoutAlignmentY(Container target) { - return (float) 0.0; // TODO - } // getLayoutAlignmentY() - - /** - * layoutContainer - * @param target TODO - */ - public void layoutContainer(Container target) { - // TODO - } // layoutContainer() - - -} // OverlayLayout + /** + * The container to be laid out. + */ + private Container target; + + /** + * The size requirements of the containers children for the X direction. + */ + private SizeRequirements[] xChildren; + + /** + * The size requirements of the containers children for the Y direction. + */ + private SizeRequirements[] yChildren; + + /** + * The size requirements of the container to be laid out for the X direction. + */ + private SizeRequirements xTotal; + + /** + * The size requirements of the container to be laid out for the Y direction. + */ + private SizeRequirements yTotal; + + /** + * The offsets of the child components in the X direction. + */ + private int[] offsetsX; + + /** + * The offsets of the child components in the Y direction. + */ + private int[] offsetsY; + + /** + * The spans of the child components in the X direction. + */ + private int[] spansX; + + /** + * The spans of the child components in the Y direction. + */ + private int[] spansY; + + /** + * Creates a new OverlayLayout for the specified container. + * + * @param target the container to be laid out + */ + public OverlayLayout(Container target) + { + this.target = target; + } + + /** + * Notifies the layout manager that the layout has become invalid. It throws + * away cached layout information and recomputes it the next time it is + * requested. + * + * @param target not used here + */ + public void invalidateLayout(Container target) + { + xChildren = null; + yChildren = null; + xTotal = null; + yTotal = null; + offsetsX = null; + offsetsY = null; + spansX = null; + spansY = null; + } + + /** + * This method is not used in this layout manager. + * + * @param string not used here + * @param component not used here + */ + public void addLayoutComponent(String string, Component component) + { + // Nothing to do here. + } + + /** + * This method is not used in this layout manager. + * + * @param component not used here + * @param constraints not used here + */ + public void addLayoutComponent(Component component, Object constraints) + { + // Nothing to do here. + } + + /** + * This method is not used in this layout manager. + * + * @param component not used here + */ + public void removeLayoutComponent(Component component) + { + // Nothing to do here. + } + + /** + * Returns the preferred size of the container that is laid out. This is + * computed by the children's preferred sizes, taking their alignments into + * account. + * + * @param target not used here + * + * @returns the preferred size of the container that is laid out + */ + public Dimension preferredLayoutSize(Container target) + { + if (target != this.target) + throw new AWTError("OverlayLayout can't be shared"); + + checkTotalRequirements(); + return new Dimension(xTotal.preferred, yTotal.preferred); + } + + /** + * Returns the minimum size of the container that is laid out. This is + * computed by the children's minimum sizes, taking their alignments into + * account. + * + * @param target not used here + * + * @returns the minimum size of the container that is laid out + */ + public Dimension minimumLayoutSize(Container target) + { + if (target != this.target) + throw new AWTError("OverlayLayout can't be shared"); + + checkTotalRequirements(); + return new Dimension(xTotal.minimum, yTotal.minimum); + } + + /** + * Returns the maximum size of the container that is laid out. This is + * computed by the children's maximum sizes, taking their alignments into + * account. + * + * @param target not used here + * + * @returns the maximum size of the container that is laid out + */ + public Dimension maximumLayoutSize(Container target) + { + if (target != this.target) + throw new AWTError("OverlayLayout can't be shared"); + + checkTotalRequirements(); + return new Dimension(xTotal.maximum, yTotal.maximum); + } + + /** + * Returns the X alignment of the container that is laid out. This is + * computed by the children's preferred sizes, taking their alignments into + * account. + * + * @param target not used here + * + * @returns the X alignment of the container that is laid out + */ + public float getLayoutAlignmentX(Container target) + { + if (target != this.target) + throw new AWTError("OverlayLayout can't be shared"); + + checkTotalRequirements(); + return xTotal.alignment; + } + + /** + * Returns the Y alignment of the container that is laid out. This is + * computed by the children's preferred sizes, taking their alignments into + * account. + * + * @param target not used here + * + * @returns the X alignment of the container that is laid out + */ + public float getLayoutAlignmentY(Container target) + { + if (target != this.target) + throw new AWTError("OverlayLayout can't be shared"); + + checkTotalRequirements(); + return yTotal.alignment; + } + + /** + * Lays out the container and it's children. + * + * The children are laid out one over another. + * + * The components take as much space as is available in the container, but + * not more than specified by their maximum size. + * + * The overall layout is mainly affected by the components + * <code>alignmentX</code> and <code>alignmentY</code> properties. All + * components are aligned, so that their alignment points (for either + * direction) are placed in one line (the baseline for this direction). + * + * For example: An X alignment of 0.0 means that the component's alignment + * point is at it's left edge, an X alignment of 0.5 means that the alignment + * point is in the middle, an X alignment of 1.0 means, the aligment point is + * at the right edge. So if you have three components, the first with 0.0, + * the second with 0.5 and the third with 1.0, then they are laid out like + * this: + * + * <pre> + * +-------+ + * | 1 | + * +-------+ + * +-------+ + * | 2 | + * +-------+ + * +---------+ + * | 3 + + * +---------+ + * </pre> + * The above picture shows the X alignment between the components. An Y + * alignment like shown above cannot be achieved with this layout manager. + * The components are place on top of each other, with the X alignment shown + * above. + * + * @param target not used here + */ + public void layoutContainer(Container target) + { + if (target != this.target) + throw new AWTError("OverlayLayout can't be shared"); + + checkLayout(); + Component[] children = target.getComponents(); + for (int i = 0; i < children.length; i++) + children[i].setBounds(offsetsX[i], offsetsY[i], spansX[i], spansY[i]); + } + + /** + * Makes sure that the xChildren and yChildren fields are correctly set up. + * A call to {@link #invalidateLayout(Container)} sets these fields to null, + * so they have to be set up again. + */ + private void checkRequirements() + { + if (xChildren == null || yChildren == null) + { + Component[] children = target.getComponents(); + xChildren = new SizeRequirements[children.length]; + yChildren = new SizeRequirements[children.length]; + for (int i = 0; i < children.length; i++) + { + if (! children[i].isVisible()) + { + xChildren[i] = new SizeRequirements(); + yChildren[i] = new SizeRequirements(); + } + else + { + xChildren[i] = + new SizeRequirements(children[i].getMinimumSize().width, + children[i].getPreferredSize().width, + children[i].getMaximumSize().width, + children[i].getAlignmentX()); + yChildren[i] = + new SizeRequirements(children[i].getMinimumSize().height, + children[i].getPreferredSize().height, + children[i].getMaximumSize().height, + children[i].getAlignmentY()); + } + } + } + } + + /** + * Makes sure that the xTotal and yTotal fields are set up correctly. A call + * to {@link #invalidateLayout} sets these fields to null and they have to be + * recomputed. + */ + private void checkTotalRequirements() + { + if (xTotal == null || yTotal == null) + { + checkRequirements(); + xTotal = SizeRequirements.getAlignedSizeRequirements(xChildren); + yTotal = SizeRequirements.getAlignedSizeRequirements(yChildren); + } + } + + /** + * Makes sure that the offsetsX, offsetsY, spansX and spansY fields are set + * up correctly. A call to {@link #invalidateLayout} sets these fields + * to null and they have to be recomputed. + */ + private void checkLayout() + { + if (offsetsX == null || offsetsY == null || spansX == null + || spansY == null) + { + checkRequirements(); + checkTotalRequirements(); + int len = target.getComponents().length; + offsetsX = new int[len]; + offsetsY = new int[len]; + spansX = new int[len]; + spansY = new int[len]; + + Insets in = target.getInsets(); + int width = target.getWidth() - in.left - in.right; + int height = target.getHeight() - in.top - in.bottom; + + SizeRequirements.calculateAlignedPositions(width, xTotal, + xChildren, offsetsX, spansX); + SizeRequirements.calculateAlignedPositions(height, yTotal, + yChildren, offsetsY, spansY); + } + } +} |