mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			251 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			Java
		
	
	
	
			
		
		
	
	
			251 lines
		
	
	
		
			6.1 KiB
		
	
	
	
		
			Java
		
	
	
	
// GridLayout.java - Grid-based layout engine
 | 
						|
 | 
						|
/* Copyright (C) 2000  Free Software Foundation
 | 
						|
 | 
						|
   This file is part of libgcj.
 | 
						|
 | 
						|
This software is copyrighted work licensed under the terms of the
 | 
						|
Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
 | 
						|
details.  */
 | 
						|
 | 
						|
package java.awt;
 | 
						|
 | 
						|
import java.io.Serializable;
 | 
						|
 | 
						|
/** This class implements a flow-based layout.  Components are laid
 | 
						|
 * out in order from left to right.  When a component cannot be placed
 | 
						|
 * without horizontal clipping, a new row is started.  This class
 | 
						|
 * supports horizontal and vertical gaps.  These are used for spacing
 | 
						|
 * between components.
 | 
						|
 */
 | 
						|
public class FlowLayout implements LayoutManager, Serializable
 | 
						|
{
 | 
						|
  /** Constant that specifies left alignment.  */
 | 
						|
  public static final int LEFT = 0;
 | 
						|
  /** Constant that specifies center alignment.  */
 | 
						|
  public static final int CENTER = 1;
 | 
						|
  /** Constant that specifies right alignment.  */
 | 
						|
  public static final int RIGHT = 2;
 | 
						|
 | 
						|
  /** Add a new component to the layout.  This particular implementation
 | 
						|
   * does nothing.
 | 
						|
   */
 | 
						|
  public void addLayoutComponent (String name, Component comp)
 | 
						|
  {
 | 
						|
    // Nothing.
 | 
						|
  }
 | 
						|
 | 
						|
  /** Return the alignment.  */
 | 
						|
  public int getAlignment ()
 | 
						|
  {
 | 
						|
    return align;
 | 
						|
  }
 | 
						|
 | 
						|
  /** Return the horizontal gap.  */
 | 
						|
  public int getHgap ()
 | 
						|
  {
 | 
						|
    return hgap;
 | 
						|
  }
 | 
						|
 | 
						|
  /** Return the vertical gap.  */
 | 
						|
  public int getVgap ()
 | 
						|
  {
 | 
						|
    return vgap;
 | 
						|
  }
 | 
						|
 | 
						|
  /** Create a new FlowLayout with center alignment.
 | 
						|
   * Both gaps are set to 0.
 | 
						|
   */
 | 
						|
  public FlowLayout ()
 | 
						|
  {
 | 
						|
    this (CENTER, 0, 0);
 | 
						|
  }
 | 
						|
 | 
						|
  /** Create a new FlowLayout with the alignment.
 | 
						|
   * columns.  Both gaps are set to 0.
 | 
						|
   * @param align Alignment
 | 
						|
   */
 | 
						|
  public FlowLayout (int align)
 | 
						|
  {
 | 
						|
    this (align, 0, 0);
 | 
						|
  }
 | 
						|
 | 
						|
  /** Create a new FlowLayout with the specified alignment and gaps.
 | 
						|
   * @param align Alignment
 | 
						|
   * @param hgap The horizontal gap
 | 
						|
   * @param vgap The vertical gap
 | 
						|
   * @exception IllegalArgumentException If either gap is negative
 | 
						|
   */
 | 
						|
  public FlowLayout (int align, int hgap, int vgap)
 | 
						|
  {
 | 
						|
    if (hgap < 0)
 | 
						|
      throw new IllegalArgumentException ("horizontal gap must be nonnegative");
 | 
						|
    if (vgap < 0)
 | 
						|
      throw new IllegalArgumentException ("vertical gap must be nonnegative");
 | 
						|
    if (align != LEFT && align != RIGHT && align != CENTER)
 | 
						|
      throw new IllegalArgumentException ("invalid align: " + align);
 | 
						|
    this.align = align;
 | 
						|
    this.hgap = hgap;
 | 
						|
    this.vgap = vgap;
 | 
						|
  }
 | 
						|
 | 
						|
  /** Lay out the container's components based on current settings.
 | 
						|
   * @param parent The parent container
 | 
						|
   */
 | 
						|
  public void layoutContainer (Container parent)
 | 
						|
  {
 | 
						|
    int num = parent.getComponentCount ();
 | 
						|
    // This is more efficient than calling getComponents().
 | 
						|
    Component[] comps = parent.component;
 | 
						|
 | 
						|
    Dimension d = parent.getSize ();
 | 
						|
    Insets ins = parent.getInsets ();
 | 
						|
 | 
						|
    int y = ins.top + vgap;
 | 
						|
    int i = 0;
 | 
						|
    while (i < num)
 | 
						|
      {
 | 
						|
	// Find the components which go in the current row.
 | 
						|
	int new_w = ins.left + hgap + ins.right;
 | 
						|
	int new_h = 0;
 | 
						|
	int j;
 | 
						|
	for (j = i; j < num; ++j)
 | 
						|
	  {
 | 
						|
	    // FIXME: this is very inefficient.
 | 
						|
	    Dimension c = comps[i].getPreferredSize ();
 | 
						|
	    int next_w = new_w + hgap + c.width;
 | 
						|
	    if (next_w > d.width)
 | 
						|
	      {
 | 
						|
		// We must start a new row.
 | 
						|
		break;
 | 
						|
	      }
 | 
						|
	    new_w = next_w;
 | 
						|
	    new_h = Math.max (new_h, c.height);
 | 
						|
	  }
 | 
						|
	// We always need at least one item.
 | 
						|
	if (j == i)
 | 
						|
	  ++j;
 | 
						|
 | 
						|
	// Set the location of each component for this row.
 | 
						|
	int x;
 | 
						|
	if (align == LEFT)
 | 
						|
	  x = ins.left + hgap;
 | 
						|
	else if (align == CENTER)
 | 
						|
	  x = (d.width - new_w) / 2;
 | 
						|
	else
 | 
						|
	  x = d.width - new_w;
 | 
						|
	for (int k = i; i < j; ++k)
 | 
						|
	  {
 | 
						|
	    // FIXME: this is very inefficient.
 | 
						|
	    Dimension c = comps[i].getPreferredSize ();
 | 
						|
	    comps[i].setLocation (x, y);
 | 
						|
	    x += c.width + vgap;
 | 
						|
	  }
 | 
						|
 | 
						|
	// Advance to next row.
 | 
						|
	i = j;
 | 
						|
	y += new_h + vgap;
 | 
						|
      }
 | 
						|
  }
 | 
						|
 | 
						|
  /** Get the minimum layout size of the container.
 | 
						|
   * @param cont The parent container
 | 
						|
   */
 | 
						|
  public Dimension minimumLayoutSize (Container cont)
 | 
						|
  {
 | 
						|
    return getSize (cont, true);
 | 
						|
  }
 | 
						|
 | 
						|
  /** Get the preferred layout size of the container.
 | 
						|
   * @param cont The parent container
 | 
						|
   */
 | 
						|
  public Dimension preferredLayoutSize (Container cont)
 | 
						|
  {
 | 
						|
    return getSize (cont, false);
 | 
						|
  }
 | 
						|
 | 
						|
  /** Remove the indicated component from this layout manager.
 | 
						|
   * This particular implementation does nothing.
 | 
						|
   * @param comp The component to remove
 | 
						|
   */
 | 
						|
  public void removeLayoutComponent (Component comp)
 | 
						|
  {
 | 
						|
    // Nothing.
 | 
						|
  }
 | 
						|
 | 
						|
  /** Set the alignment.
 | 
						|
   * @param align The alignment
 | 
						|
   */
 | 
						|
  public void setAlignment (int align)
 | 
						|
  {
 | 
						|
    if (align != LEFT && align != RIGHT && align != CENTER)
 | 
						|
      throw new IllegalArgumentException ("invalid align: " + align);
 | 
						|
    this.align = align;
 | 
						|
  }
 | 
						|
 | 
						|
  /** Set the horizontal gap
 | 
						|
   * @param hgap The horizontal gap
 | 
						|
   */
 | 
						|
  public void setHgap (int hgap)
 | 
						|
  {
 | 
						|
    if (hgap < 0)
 | 
						|
      throw new IllegalArgumentException ("horizontal gap must be nonnegative");
 | 
						|
    this.hgap = hgap;
 | 
						|
  }
 | 
						|
 | 
						|
  /** Set the vertical gap.
 | 
						|
   * @param vgap The vertical gap
 | 
						|
   */
 | 
						|
  public void setVgap (int vgap)
 | 
						|
  {
 | 
						|
    if (vgap < 0)
 | 
						|
      throw new IllegalArgumentException ("vertical gap must be nonnegative");
 | 
						|
    this.vgap = vgap;
 | 
						|
  }
 | 
						|
 | 
						|
  /** Return String description of this object.  */
 | 
						|
  public String toString ()
 | 
						|
  {
 | 
						|
    return ("[" + getClass ().getName () + ",hgap=" + hgap + ",vgap=" + vgap
 | 
						|
	    + ",align=" + align + "]");
 | 
						|
  }
 | 
						|
 | 
						|
  // This method is used to compute the various sizes.
 | 
						|
  private Dimension getSize (Container parent, boolean is_min)
 | 
						|
  {
 | 
						|
    int w, h, num = parent.getComponentCount ();
 | 
						|
    // This is more efficient than calling getComponents().
 | 
						|
    Component[] comps = parent.component;
 | 
						|
 | 
						|
    w = 0;
 | 
						|
    h = 0;
 | 
						|
    for (int i = 0; i < num; ++i)
 | 
						|
      {
 | 
						|
	// FIXME: can we just directly read the fields in Component?
 | 
						|
	// Or will that not work with subclassing?
 | 
						|
	Dimension d;
 | 
						|
 | 
						|
	if (is_min)
 | 
						|
	  d = comps[i].getMinimumSize ();
 | 
						|
	else
 | 
						|
	  d = comps[i].getPreferredSize ();
 | 
						|
 | 
						|
	w += d.width;
 | 
						|
	h = Math.max (d.height, h);
 | 
						|
      }
 | 
						|
 | 
						|
    Insets ins = parent.getInsets ();
 | 
						|
 | 
						|
    w += (num + 1) * hgap + ins.left + ins.right;
 | 
						|
    h += 2 * vgap + ins.top + ins.bottom;
 | 
						|
 | 
						|
    return new Dimension (w, h);
 | 
						|
  }
 | 
						|
 | 
						|
  // Alignment.
 | 
						|
  private int align;
 | 
						|
  // The gaps.
 | 
						|
  private int hgap;
 | 
						|
  private int vgap;
 | 
						|
}
 |