/*  FlowLayoutCorrectMinimumSize.java of project jchart2d, 
 *  Copyright (c) 2006 - 2011 Achim Westermann, created on 08.10.2006 14:44:18.
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library 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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA*
 *  If you modify or optimize the code in a useful way please let me know.
 *  Achim.Westermann@gmx.de
 *
 */
package info.monitorenter.gui.chart.layouts;

import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Insets;

/**
 * A flow layout that claims the correct height of the component managed in case
 * the available width is known. The standard {@link java.awt.FlowLayout} does
 * not claim the correct size but chooses the maximum width of all components to
 * render which is worthless as the fact of flow breaks is not taken into
 * account.
 * 

* * This class is inspired by the sun class * {@link java.awt.FlowLayout} with modifications to the methods * {@link #preferredLayoutSize(Container)} and * {@link #minimumLayoutSize(Container)}. *

* * @author Achim Westermann * * @version $Revision: 1.13 $ */ public class FlowLayoutCorrectMinimumSize extends FlowLayout { /** Generated serialVersionUID. */ private static final long serialVersionUID = 5192358035459949687L; /** * Constructs a new FlowLayout with the specified alignment and * a default 5-unit horizontal and vertical gap. The value of the alignment * argument must be one of FlowLayout.LEFT, * FlowLayout.RIGHT, FlowLayout.CENTER, * FlowLayout.LEADING, or FlowLayout.TRAILING. * * @param align * the alignment value */ public FlowLayoutCorrectMinimumSize(final 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.LEFT, FlowLayout.RIGHT, * FlowLayout.CENTER, FlowLayout.LEADING, or * FlowLayout.TRAILING. * * @param align * the alignment value * @param hgap * the horizontal gap between components and between the components * and the borders of the Container * @param vgap * the vertical gap between components and between the components * and the borders of the Container */ public FlowLayoutCorrectMinimumSize(final int align, final int hgap, final int vgap) { super(align, hgap, vgap); } /** * Lays out the container. This method lets each visible component * take its preferred size by reshaping the components in the target container * in order to satisfy the alignment of this FlowLayout object. * * @param target * the specified component being laid out * @see Container * @see java.awt.Container#doLayout */ @Override public void layoutContainer(final Container target) { synchronized (target.getTreeLock()) { int hgap = this.getHgap(); int vgap = this.getVgap(); Insets insets = target.getInsets(); int maxwidth = target.getWidth() - (insets.left + insets.right + hgap * 2); int nmembers = target.getComponentCount(); int x = 0; int y = insets.top + vgap; int rowh = 0; int 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 ((x == 0) || ((x + d.width) <= maxwidth)) { if (x > 0) { x += hgap; } x += d.width; rowh = Math.max(rowh, d.height); } else { this.moveComponents(target, insets.left + hgap, y, maxwidth - x, rowh, start, i, ltr); x = d.width; y += vgap + rowh; rowh = d.height; start = i; } } } this.moveComponents(target, insets.left + hgap, y, maxwidth - x, rowh, start, nmembers, ltr); } } /** * Returns the minimum dimensions needed to layout the visible * components contained in the specified target container. * * @param target * the container that 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 */ @Override public Dimension minimumLayoutSize(final Container target) { synchronized (target.getTreeLock()) { int hgap = this.getHgap(); int vgap = this.getVgap(); Insets insets = target.getInsets(); int maxwidth = target.getWidth() - (insets.left + insets.right + hgap * 2); int nmembers = target.getComponentCount(); boolean firstVisibleComponent = true; int rowWidth = 0; int maxRowWidth = 0; int height = 0; for (int i = 0; i < nmembers; i++) { Component m = target.getComponent(i); if (m.isVisible()) { Dimension d = m.getMinimumSize(); if (firstVisibleComponent) { height = d.height; firstVisibleComponent = false; } if (rowWidth + hgap + d.width > maxwidth) { maxRowWidth = Math.max(rowWidth, maxRowWidth); height += (vgap + d.height); rowWidth = d.width; } else { rowWidth += (hgap + d.width); } } } Dimension dim = new Dimension(maxRowWidth, height); 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 * @param ltr * if true, left to right alignment is used. */ private void moveComponents(final Container target, final int x, final int y, final int width, final int height, final int rowStart, final int rowEnd, final boolean ltr) { synchronized (target.getTreeLock()) { int xMod = x; int hgap = this.getHgap(); switch (this.getAlignment()) { case LEFT: xMod += ltr ? 0 : width; break; case CENTER: xMod += width / 2; break; case RIGHT: xMod += ltr ? width : 0; break; case LEADING: break; case TRAILING: xMod += width; break; default: break; } for (int i = rowStart; i < rowEnd; i++) { Component m = target.getComponent(i); if (m.isVisible()) { if (ltr) { m.setLocation(xMod, y + (height - m.getHeight()) / 2); } else { m .setLocation(target.getWidth() - xMod - m.getWidth(), y + (height - m.getHeight()) / 2); } xMod += m.getWidth() + hgap; } } } } /** * Returns the preferred dimensions for this layout given the visible * components in the specified target container. * * @param target * the container that 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 */ @Override public Dimension preferredLayoutSize(final Container target) { synchronized (target.getTreeLock()) { int hgap = this.getHgap(); int vgap = this.getVgap(); Insets insets = target.getInsets(); int maxwidth = target.getWidth() - (insets.left + insets.right + hgap * 2); int nmembers = target.getComponentCount(); boolean firstVisibleComponent = true; int rowWidth = 0; int maxRowWidth = 0; int height = 0; for (int i = 0; i < nmembers; i++) { Component m = target.getComponent(i); if (m.isVisible()) { Dimension d = m.getPreferredSize(); if (firstVisibleComponent) { height = d.height; firstVisibleComponent = false; } if (rowWidth + hgap + d.width > maxwidth) { maxRowWidth = Math.max(rowWidth, maxRowWidth); height += (vgap + d.height); rowWidth = d.width; } else { rowWidth += (hgap + d.width); } } } Dimension dim = new Dimension(maxRowWidth, height); dim.width += insets.left + insets.right + hgap * 2; dim.height += insets.top + insets.bottom + vgap * 2; return dim; } } }

Ads help maintain this website.