import java.io.ObjectInputStream; import java.io.IOException; import java.awt.*; import java.awt.event.*; class VerticalFlowLayout implements LayoutManager, java.io.Serializable { /** * This value indicates that each row of components * should be left-justified. */ public static final int TOP = 0; /** * This value indicates that each row of components * should be centered. */ public static final int CENTER = 1; /** * This value indicates that each row of components * should be right-justified. */ public static final int BOTTOM = 2; /** * This value indicates that each row of components * should be justified to the leading edge of the container's * orientation, e.g. to the left in left-to-right orientations. * * @see java.awt.Component#getComponentOrientation * @see java.awt.ComponentOrientation * @since 1.2 * Package-private pending API change approval */ public static final int LEADING = 3; /** * This value indicates that each row of components * should be justified to the leading edge of the container's * orientation, e.g. to the right in left-to-right orientations. * * @see java.awt.Component#getComponentOrientation * @see java.awt.ComponentOrientation * @since 1.2 * Package-private pending API change approval */ public static final int TRAILING = 4; /** * align is the proprty that determines * how each row distributes empty space. * It can be one of the following three values : * TOP * BOTTOM * CENTER * * @serial * @see #getAlignment * @see #setAlignment */ int align; // This is for 1.1 serialization compatibilitys /** * newAlign is the property that determines * how each row distributes empty space for the Java 2 platform, v1.2 and greater. * It can be one of the following three values : * TOP * BOTTOM * CENTER * * @serial * @since 1.2 * @see #getAlignment * @see #setAlignment */ int newAlign; // This is the one we actually use /** * The flow layout manager allows a seperation of * components with gaps. The horizontal gap will * specify the space between components. * * @serial * @see getHgap * @see setHgap */ int hgap; /** * The flow layout manager allows a seperation of * components with gaps. The vertical gap will * specify the space between rows. * * @serial * @see getVgap * @see setVgap */ int vgap; /* * JDK 1.1 serialVersionUID */ private static final long serialVersionUID = -1262434865582285639L; /** * Constructs a new Flow Layout with a centered alignment and a * default 5-unit horizontal and vertical gap. */ public VerticalFlowLayout() { this(CENTER, 5, 5); } /** * Constructs a new Flow Layout with the specified alignment and a * default 5-unit horizontal and vertical gap. * The value of the alignment argument must be one of * FlowLayout.TOP, FlowLayout.BOTTOM, * or FlowLayout.CENTER. * @param align the alignment value */ public VerticalFlowLayout(int align) { this(align, 5, 5); } /** * Creates a new flow layout manager with the indicated alignment * and the indicated horizontal and vertical gaps. *

* The value of the alignment argument must be one of * FlowLayout.TOP, FlowLayout.BOTTOM, * or FlowLayout.CENTER. * @param align the alignment value. * @param hgap the horizontal gap between components. * @param vgap the vertical gap between components. */ public VerticalFlowLayout(int align, int hgap, int vgap) { this.hgap = hgap; this.vgap = vgap; setAlignment(align); } /** * Gets the alignment for this layout. * Possible values are FlowLayout.TOP, * FlowLayout.BOTTOM, or FlowLayout.CENTER. * @return the alignment value for this layout. * @see java.awt.FlowLayout#setAlignment * @since JDK1.1 */ public int getAlignment() { return newAlign; } /** * Sets the alignment for this layout. * Possible values are FlowLayout.TOP, * FlowLayout.BOTTOM, and FlowLayout.CENTER. * @param align the alignment value. * @see #getAlignment() * @since JDK1.1 */ public void setAlignment(int align) { this.newAlign = align; // this.align is used only for serialization compatibility, // so set it to a value compatible with the 1.1 version // of the class switch (align) { case LEADING: this.align = TOP; break; case TRAILING: this.align = BOTTOM; break; default: this.align = align; break; } } /** * Gets the horizontal gap between components. * @return the horizontal gap between components. * @see java.awt.FlowLayout#setHgap * @since JDK1.1 */ public int getHgap() { return hgap; } /** * Sets the horizontal gap between components. * @param hgap the horizontal gap between components * @see java.awt.FlowLayout#getHgap * @since JDK1.1 */ public void setHgap(int hgap) { this.hgap = hgap; } /** * Gets the vertical gap between components. * @return the vertical gap between components. * @see java.awt.FlowLayout#setVgap * @since JDK1.1 */ public int getVgap() { return vgap; } /** * Sets the vertical gap between components. * @param vgap the vertical gap between components * @see java.awt.FlowLayout#getVgap * @since JDK1.1 */ public void setVgap(int vgap) { this.vgap = vgap; } /** * Adds the specified component to the layout. Not used by this class. * @param name the name of the component * @param comp the component to be added */ public void addLayoutComponent(String name, Component comp) { } /** * Removes the specified component from the layout. Not used by * this class. * @param comp the component to remove * @see java.awt.Container#removeAll */ public void removeLayoutComponent(Component comp) { } /** * Returns the preferred dimensions for this layout given the components * in the specified target container. * @param target the component which needs to be laid out * @return the preferred dimensions to lay out the * subcomponents of the specified container. * @see Container * @see #minimumLayoutSize * @see java.awt.Container#getPreferredSize */ public Dimension preferredLayoutSize(Container target) { synchronized (target.getTreeLock()) { Dimension dim = new Dimension(0, 0); int nmembers = target.getComponentCount(); boolean firstVisibleComponent = true; for (int i = 0 ; i < nmembers ; i++) { Component m = target.getComponent(i); if (m.isVisible()) { Dimension d = m.getPreferredSize(); dim.width = Math.max(dim.width, d.width); if (firstVisibleComponent) { firstVisibleComponent = false; } else { dim.height += vgap; } dim.height += d.height; } } Insets insets = target.getInsets(); dim.width += insets.left + insets.right + hgap*2; dim.height += insets.top + insets.bottom + vgap*2; return dim; } } /** * Returns the minimum dimensions needed to layout the components * contained in the specified target container. * @param target the component which needs to be laid out * @return the minimum dimensions to lay out the * subcomponents of the specified container. * @see #preferredLayoutSize * @see java.awt.Container * @see java.awt.Container#doLayout */ public Dimension minimumLayoutSize(Container target) { synchronized (target.getTreeLock()) { Dimension dim = new Dimension(0, 0); int nmembers = target.getComponentCount(); for (int i = 0 ; i < nmembers ; i++) { Component m = target.getComponent(i); if (m.isVisible()) { Dimension d = m.getMinimumSize(); dim.width = Math.max(dim.width, d.width); if (i > 0) { dim.height += vgap; } dim.height += d.height; } } Insets insets = target.getInsets(); dim.width += insets.left + insets.right + hgap*2; dim.height += insets.top + insets.bottom + vgap*2; return dim; } } /** * Centers the elements in the specified row, if there is any slack. * @param target the component which needs to be moved * @param x the x coordinate * @param y the y coordinate * @param width the width dimensions * @param height the height dimensions * @param rowStart the beginning of the row * @param rowEnd the the ending of the row */ private void moveComponents(Container target, int x, int y, int width, int height, int rowStart, int rowEnd, boolean ltr) { synchronized (target.getTreeLock()) { switch (newAlign) { case TOP: y += ltr ? 0 : height; break; case CENTER: y += height / 2; break; case BOTTOM: y += ltr ? height : 0; break; case LEADING: break; case TRAILING: y += height; break; } for (int i = rowStart ; i < rowEnd ; i++) { Component m = target.getComponent(i); if (m.isVisible()) { if (ltr) { m.setLocation(x /*+ (width - m.getWidth())/2*/, y);// + (height - m.getHeight()) / 2); } else { m.setLocation(target.getWidth() - x - m.getWidth(), y + (height - m.getHeight()) / 2); //System.out.println("Hello kiddo"); } y += m.getHeight() + vgap; } } } } /** * Lays out the container. This method lets each component take * its preferred size by reshaping the components in the * target container in order to satisfy the constraints of * this FlowLayout object. * @param target the specified component being laid out. * @see Container * @see java.awt.Container#doLayout */ public void layoutContainer(Container target) { synchronized (target.getTreeLock()) { Insets insets = target.getInsets(); int maxHeight = target.getHeight() - (insets.top + insets.bottom + vgap*2); int nmembers = target.getComponentCount(); int x = insets.left+hgap , y = 0; int colw = 0, start = 0; boolean ltr = target.getComponentOrientation().isLeftToRight(); for (int i = 0 ; i < nmembers ; i++) { Component m = target.getComponent(i); if (m.isVisible()) { Dimension d = m.getPreferredSize(); m.setSize(d.width, d.height); if ((y == 0) || ((y + d.height) <= maxHeight)) { if (y > 0) { y += vgap; } y += d.height; colw = Math.max(colw, d.width); } else { moveComponents(target, x, insets.top + vgap, colw, maxHeight - y, start, i, ltr); y = d.height; x += hgap + colw; colw = d.width; start = i; } } } moveComponents(target, x, insets.top + vgap, colw, maxHeight - y, start, nmembers, ltr); } } // // the internal serial version which says which version was written // - 0 (default) for versions before the Java 2 platform, v1.2 // - 1 for version >= Java 2 platform v1.2, which includes "newAlign" field // private static final int currentSerialVersion = 1; /** * This represent the currentSerialVersion * which is bein used. It will be one of two values : * 0 versions before Java 2 platform v1.2.. * 1 versions after Java 2 platform v1.2.. * * @serial * @since 1.2 */ private int serialVersionOnStream = currentSerialVersion; /** * Read this object out of a serialization stream, handling * objects written by older versions of the class that didn't contain all * of the fields we use now.. */ private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { stream.defaultReadObject(); if (serialVersionOnStream < 1) { // "newAlign" field wasn't present, so use the old "align" field. setAlignment(this.align); } serialVersionOnStream = currentSerialVersion; } /** * Returns a string representation of this FlowLayout * object and its values. * @return a string representation of this layout. */ public String toString() { String str = ""; switch (align) { case TOP: str = ",align=left"; break; case CENTER: str = ",align=center"; break; case BOTTOM: str = ",align=right"; break; case LEADING: str = ",align=leading"; break; case TRAILING: str = ",align=trailing"; break; } return getClass().getName() + "[hgap=" + hgap + ",vgap=" + vgap + str + "]"; } }