123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452 |
- /* BoxLayout.java -- A layout for swing components.
- Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
- This file is part of GNU Classpath.
- GNU Classpath is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
- GNU Classpath is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with GNU Classpath; see the file COPYING. If not, write to the
- Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
- 02110-1301 USA.
- Linking this library statically or dynamically with other modules is
- making a combined work based on this library. Thus, the terms and
- conditions of the GNU General Public License cover the whole
- combination.
- As a special exception, the copyright holders of this library give you
- permission to link this library with independent modules to produce an
- executable, regardless of the license terms of these independent
- modules, and to copy and distribute the resulting executable under
- terms of your choice, provided that you also meet, for each linked
- independent module, the terms and conditions of the license of that
- module. An independent module is a module which is not derived from
- or based on this library. If you modify this library, you may extend
- this exception to your version of the library, but you are not
- obligated to do so. If you do not wish to do so, delete this
- exception statement from your version. */
- package javax.swing;
- import java.awt.AWTError;
- import java.awt.Component;
- import java.awt.ComponentOrientation;
- import java.awt.Container;
- import java.awt.Dimension;
- import java.awt.Insets;
- import java.awt.LayoutManager2;
- import java.io.Serializable;
- /**
- * A layout that stacks the children of a container in a Box, either
- * horizontally or vertically.
- *
- * @author Ronald Veldema (rveldema@cs.vu.nl)
- * @author Roman Kennke (roman@kennke.org)
- */
- public class BoxLayout implements LayoutManager2, Serializable
- {
- /**
- * Specifies that components are laid out left to right.
- */
- public static final int X_AXIS = 0;
- /**
- * Specifies that components are laid out top to bottom.
- */
- public static final int Y_AXIS = 1;
- /**
- * Specifies that components are laid out in the direction of a line of text.
- */
- public static final int LINE_AXIS = 2;
- /**
- * Sepcifies that components are laid out in the direction of the line flow.
- */
- public static final int PAGE_AXIS = 3;
- /*
- * Needed for serialization.
- */
- private static final long serialVersionUID = -2474455742719112368L;
- /*
- * The container given to the constructor.
- */
- private Container container;
- /**
- * Current type of component layouting. Defaults to X_AXIS.
- */
- private int way = X_AXIS;
- /**
- * 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;
- /**
- * Constructs a <code>BoxLayout</code> object.
- *
- * @param container The container that needs to be laid out.
- * @param way The orientation of the components.
- *
- * @exception AWTError If way has an invalid value.
- */
- public BoxLayout(Container container, int way)
- {
- if (way != X_AXIS && way != Y_AXIS && way != LINE_AXIS && way != PAGE_AXIS)
- throw new AWTError("Invalid axis");
- int width = 0;
- int height = 0;
- this.container = container;
- this.way = way;
- }
- /**
- * Adds a component to the layout. Not used in BoxLayout.
- *
- * @param name The name of the component to add.
- * @param component the component to add to the layout.
- */
- public void addLayoutComponent(String name, Component component)
- {
- // Nothing to do here.
- }
- /**
- * Removes a component from the layout. Not used in BoxLayout.
- *
- * @param component The component to remove from the layout.
- */
- public void removeLayoutComponent(Component component)
- {
- // Nothing to do here.
- }
- private boolean isHorizontalIn(Container parent)
- {
- ComponentOrientation orientation = parent.getComponentOrientation();
- return this.way == X_AXIS
- || (this.way == LINE_AXIS
- && orientation.isHorizontal())
- || (this.way == PAGE_AXIS
- && (!orientation.isHorizontal()));
- }
- /**
- * Returns the preferred size of the layout.
- *
- * @param parent The container that needs to be laid out.
- *
- * @return The dimension of the layout.
- */
- public Dimension preferredLayoutSize(Container parent)
- {
- synchronized (container.getTreeLock())
- {
- if (container != parent)
- throw new AWTError("BoxLayout can't be shared");
- checkTotalRequirements();
- Insets i = container.getInsets();
- return new Dimension(xTotal.preferred + i.left + i.right,
- yTotal.preferred + i.top + i.bottom);
- }
- }
- /**
- * Returns the minimum size of the layout.
- *
- * @param parent The container that needs to be laid out.
- *
- * @return The dimension of the layout.
- */
- public Dimension minimumLayoutSize(Container parent)
- {
- synchronized (container.getTreeLock())
- {
- if (container != parent)
- throw new AWTError("BoxLayout can't be shared");
- checkTotalRequirements();
- Insets i = container.getInsets();
- return new Dimension(xTotal.minimum + i.left + i.right,
- yTotal.minimum + i.top + i.bottom);
- }
- }
- /**
- * Lays out the specified container using this layout.
- *
- * @param parent The container that needs to be laid out.
- */
- public void layoutContainer(Container parent)
- {
- synchronized (container.getTreeLock())
- {
- if (container != parent)
- throw new AWTError("BoxLayout can't be shared");
- checkLayout();
- Component[] children = container.getComponents();
- Insets in = container.getInsets();
- for (int i = 0; i < children.length; i++)
- children[i].setBounds(offsetsX[i] + in.left, offsetsY[i] + in.top,
- spansX[i], spansY[i]);
- }
- }
- /**
- * Adds a component to the layout. Not used in BoxLayout
- *
- * @param child The component to add to the layout.
- * @param constraints The constraints for the component in the layout.
- */
- public void addLayoutComponent(Component child, Object constraints)
- {
- // Nothing to do here.
- }
- /**
- * Returns the alignment along the X axis for the container.
- *
- * @param parent The container that needs to be laid out.
- *
- * @return The alignment.
- */
- public float getLayoutAlignmentX(Container parent)
- {
- synchronized (container.getTreeLock())
- {
- if (container != parent)
- throw new AWTError("BoxLayout can't be shared");
- checkTotalRequirements();
- return xTotal.alignment;
- }
- }
- /**
- * Returns the alignment along the Y axis for the container.
- *
- * @param parent The container that needs to be laid out.
- *
- * @return The alignment.
- */
- public float getLayoutAlignmentY(Container parent)
- {
- synchronized (container.getTreeLock())
- {
- if (container != parent)
- throw new AWTError("BoxLayout can't be shared");
- checkTotalRequirements();
- return yTotal.alignment;
- }
- }
- /**
- * Invalidates the layout.
- *
- * @param parent The container that needs to be laid out.
- */
- public void invalidateLayout(Container parent)
- {
- if (container != parent)
- throw new AWTError("BoxLayout can't be shared");
- synchronized (container.getTreeLock())
- {
- xChildren = null;
- yChildren = null;
- xTotal = null;
- yTotal = null;
- offsetsX = null;
- offsetsY = null;
- spansX = null;
- spansY = null;
- }
- }
- /**
- * Returns the maximum size of the layout gived the components
- * in the given container.
- *
- * @param parent The container that needs to be laid out.
- *
- * @return The dimension of the layout.
- */
- public Dimension maximumLayoutSize(Container parent)
- {
- synchronized (container.getTreeLock())
- {
- if (container != parent)
- throw new AWTError("BoxLayout can't be shared");
- checkTotalRequirements();
- Insets i = container.getInsets();
- int xDim = xTotal.maximum + i.left + i.right;
- int yDim = yTotal.maximum + i.top + i.bottom;
- // Check for overflow
- if (xDim < xTotal.maximum)
- xDim = Integer.MAX_VALUE;
- if (yDim < yTotal.maximum)
- yDim = Integer.MAX_VALUE;
- return new Dimension(xDim, yDim);
- }
- }
- /**
- * 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();
- if (isHorizontalIn(container))
- {
- xTotal = SizeRequirements.getTiledSizeRequirements(xChildren);
- yTotal = SizeRequirements.getAlignedSizeRequirements(yChildren);
- }
- else
- {
- xTotal = SizeRequirements.getAlignedSizeRequirements(xChildren);
- yTotal = SizeRequirements.getTiledSizeRequirements(yChildren);
- }
- }
- }
- /**
- * 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 = container.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 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 = container.getComponents().length;
- offsetsX = new int[len];
- offsetsY = new int[len];
- spansX = new int[len];
- spansY = new int[len];
- Insets in = container.getInsets();
- int width = container.getWidth() - in.left - in.right;
- int height = container.getHeight() - in.top - in.bottom;
- if (isHorizontalIn(container))
- {
- SizeRequirements.calculateTiledPositions(width,
- xTotal, xChildren,
- offsetsX, spansX);
- SizeRequirements.calculateAlignedPositions(height,
- yTotal, yChildren,
- offsetsY, spansY);
- }
- else
- {
- SizeRequirements.calculateAlignedPositions(width,
- xTotal, xChildren,
- offsetsX, spansX);
- SizeRequirements.calculateTiledPositions(height,
- yTotal, yChildren,
- offsetsY, spansY);
- }
- }
- }
- }
|