Stack Layout, uses an orientation to determine if the contents should be arranged horizontally or vertically. : Custom Layout « Swing « Java Tutorial

Java Tutorial
1. Language
2. Data Type
3. Operators
4. Statement Control
5. Class Definition
6. Development
7. Reflection
8. Regular Expressions
9. Collections
10. Thread
11. File
12. Generics
13. I18N
14. Swing
15. Swing Event
16. 2D Graphics
17. SWT
18. SWT 2D Graphics
19. Network
20. Database
21. Hibernate
22. JPA
23. JSP
24. JSTL
25. Servlet
26. Web Services SOA
27. EJB3
28. Spring
29. PDF
30. Email
31. J2ME
32. J2EE Application
33. XML
34. Design Pattern
35. Log
36. Security
37. Apache Common
38. Ant
39. JUnit
Java
Java Source Code / Java Documentation
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Tutorial » Swing » Custom Layout 
14. 97. 7. Stack Layout, uses an orientation to determine if the contents should be arranged horizontally or vertically.
/*
 *  StackLayout.java
 *  2005-07-15
 */


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

import javax.swing.JSeparator;
import javax.swing.JToolBar;
import javax.swing.SwingConstants;



/**
 * Similar to BoxLayout, uses an orientation to determine if the contents
 * should be arranged horizontally or vertically.  By default, Resizes each
 * item to equal width or height (depending on the orientation) based on the
 * maximum preferred width or height of all items.
 @author Christopher Bach
 */
public class StackLayout implements LayoutManager
{
  public static final int   HORIZONTAL = SwingConstants.HORIZONTAL;
  public static final int   VERTICAL = SwingConstants.VERTICAL;

  private int     ourOrientation = HORIZONTAL;
  private int     ourSpacing = 0;

  private boolean   ourDepthsMatched = true;
  private boolean   ourLengthsMatched = false;
  private boolean   ourFill = false;
  private boolean   ourDrop = false;

  private int     ourSqueezeFactor = 100;







  /**
   * Creates a new StackLayout with a horizontal orientation.
   */
  public StackLayout()
  {

  }



  /**
   * Creates a new StackLayout with the specified orientation.
   */
  public StackLayout(int orientation)
  {
    setOrientation(orientation);
  }



  /**
   * Creates a new StackLayout with the specified orientation and spacing.
   */
  public StackLayout(int orientation, int spacing)
  {
    setOrientation(orientation);
    setSpacing(spacing);
  }



  /**
   * Creates a new StackLayout matching the component lengths and
   * depths as indicated.
   */
  public StackLayout(boolean matchLengths, boolean matchDepths)
  {
    setMatchesComponentLengths(matchLengths);
    setMatchesComponentDepths(matchDepths);
  }



  /**
   * Creates a new StackLayout with the specified orientation
   * and spacing, matching the component lengths and depths
   * as indicated.
   */
  public StackLayout(int orientation, int spacing,
          boolean matchLengths, boolean matchDepths)
  {
    setOrientation(orientation);
    setSpacing(spacing);
    setMatchesComponentLengths(matchLengths);
    setMatchesComponentDepths(matchDepths);
  }















  /**
   * Sets this StackLayout's orientation, either
   * SwingConstants.HORIZONTAL or SwingConstants.VERTICAL.
   */
  public void setOrientation(int orientation)
  {
    if (orientation == HORIZONTAL || orientation == VERTICAL)
    {
      ourOrientation = orientation;
    }
  }



  /**
   * Returns this StackLayout's orientation, either
   * SwingConstants.HORIZONTAL or SwingConstants.VERTICAL.
   */
  public int getOrientation()
  {
    return ourOrientation;
  }



  /**
   * Sets the spacing between components that this StackLayout uses
   * when laying out the components.
   */
  public void setSpacing(int spacing)
  {
    ourSpacing = Math.max(0, spacing);
  }



  /**
   * Returns the spacing between components that this StackLayout uses
   * when laying out the components.
   */
  public int getSpacing()
  {
    return ourSpacing;
  }



  /**
   * Sets whether or not the last component in the stack
   * should be stretched to fill any remaining space within
   * the parent container.  The default value is false.
   */
  public void setFillsTrailingSpace(boolean shouldFill)
  {
    ourFill = shouldFill;
  }



  /**
   * Returns whether or not the last component in the stack
   * should be stretched to fill any remaining space within
   * the parent container.
   */
  public boolean fillsTrailingSpace()
  {
    return ourFill;
  }



  /**
   * Sets whether or not components in the stack that do not
   * fit in the parent container should be left out of the layout.
   * The default value is false;
   */
  public void setDropsPartialComponents(boolean shouldDrop)
  {
    ourDrop = shouldDrop;
  }



  /**
   * Returns whether or not components in the stack that do not
   * fit in the parent container should be left out of the layout.
   */
  public boolean dropsPartialComponents()
  {
    return ourDrop;
  }



  /**
   * Sets whether or not all components in the stack will be sized
   * to the same height (when in a horizontal orientation) or width
   * (when in a vertical orientation).  The default value is true.
   */
  public void setMatchesComponentDepths(boolean match)
  {
    ourDepthsMatched = match;
  }



  /**
   * Returns whether or not all components in the stack will be sized
   * to the same height (when in a horizontal orientation) or width
   * (when in a vertical orientation).
   */
  public boolean matchesComponentDepths()
  {
    return ourDepthsMatched;
  }



  /**
   * Sets whether or not all components in the stack will be sized
   * to the same width (when in a horizontal orientation) or height
   * (when in a vertical orientation).  The default value is false.
   */
  public void setMatchesComponentLengths(boolean match)
  {
    ourLengthsMatched = match;
  }



  /**
   * Returns whether or not all components in the stack will be sized
   * to the same width (when in a horizontal orientation) or height
   * (when in a vertical orientation).
   */
  public boolean matchesComponentLengths()
  {
    return ourLengthsMatched;
  }



  /**
   * Sets the percentage of a component's preferred size that it
   * may be squeezed in order to attempt to fit all components
   * into the layout.  The squeeze factor will only be applied
   * when this layout is set to match component lengths.
   *
   * For example, if the parent container is 100 pixels wide
   * and holds two buttons, the largest having a preferred
   * width of 80 pixels, a squeeze factor of 50 will allow each
   * button to be sized to as small as 40 pixels wide (50 percent
   * of the preferred width.
   *
   * The default value is 100.
   */
  public void setSqueezeFactor(int factor)
  {
    if (factor < 0ourSqueezeFactor = 0;
    else if (factor > 100ourSqueezeFactor = 100;
    else ourSqueezeFactor = factor;
  }



  /**
   * Returns the percentage of a component's preferred size that it
   * may be squeezed in order to attempt to fit all components
   * into the layout.
   */
  public int getSqueezeFactor()
  {
    return ourSqueezeFactor;
  }




















  ////// LayoutManager implementation //////


  /**
   * Adds the specified component with the specified name to this layout.
   */
  public void addLayoutComponent(String name, Component comp)
  {

  }


  /**
   * Removes the specified component from this layout.
   */
  public void removeLayoutComponent(Component comp)
  {

  }



  /**
   * Returns the preferred size for this layout to arrange the
   * indicated parent's children.
   */
  public Dimension preferredLayoutSize(Container parent)
  {
    if (parent instanceof JToolBar)
    {
      setOrientation( ((JToolBar)parent).getOrientation() );
    }

    return preferredLayoutSize(parent, ourOrientation);
  }


  /**
   * Returns the preferred size for this layout to arrange the
   * indicated parent's children at the specified orientation.
   */
  // public, because it's useful - not one of the LayoutManager methods
  public Dimension preferredLayoutSize(Container parent, int orientation)
  {
    synchronized (parent.getTreeLock())
    {
      Component[] comps = parent.getComponents();
      Dimension total = new Dimension(00);

      int depth = calculatePreferredDepth(comps, orientation);

      int length = ourLengthsMatched ?
        calculateAdjustedLength(comps, orientation, ourSpacing)
          : calculatePreferredLength(comps, orientation, ourSpacing) );


      total.width = (orientation == HORIZONTAL ? length : depth);
      total.height = (orientation == HORIZONTAL ? depth : length);


      Insets in = parent.getInsets();
      total.width += in.left + in.right;
      total.height += in.top + in.bottom;

      return total;
    }
    }




  /**
   * Returns the minimum size for this layout to arrange the
   * indicated parent's children at the specified orientation.
   */
    public Dimension minimumLayoutSize(Container parent)
    {
    synchronized (parent.getTreeLock())
    {
      if (parent instanceof JToolBar)
      {
        setOrientation( ((JToolBar)parent).getOrientation() );
      }

      Component[] comps = parent.getComponents();
      Dimension total = new Dimension(00);

      int depth = calculatePreferredDepth(comps, ourOrientation);
      int length = calculateMinimumLength(comps, ourOrientation, ourSpacing);

      total.width = (ourOrientation == HORIZONTAL ? length : depth);
      total.height = (ourOrientation == HORIZONTAL ? depth : length);

      Insets in = parent.getInsets();
      total.width += in.left + in.right;
      total.height += in.top + in.bottom;

      return total;
    }
    }




  /**
   * Lays out the child components within the indicated parent container.
   */
    public void layoutContainer(Container parent)
    {
    synchronized (parent.getTreeLock())
    {
      if (parent instanceof JToolBar)
      {
        setOrientation( ((JToolBar)parent).getOrientation() );
      }

      layoutComponents(parent);

    }
  }





  private void layoutComponents(Container parent)
  {
    Component[] components = parent.getComponents();
    Insets in = parent.getInsets();

    int maxHeight = parent.getHeight() - in.top - in.bottom;
    int maxWidth = parent.getWidth() - in.left - in.right;
    boolean horiz = (ourOrientation == HORIZONTAL);


    int totalDepth = calculatePreferredDepth(components, ourOrientation);
    totalDepth = Math.maxtotalDepth, (horiz ? maxHeight : maxWidth) );

    int prefLength = ourLengthsMatched ?
              calculateAdjustedLength(components, ourOrientation, ourSpacing)
              : calculatePreferredLength(components, ourOrientation, ourSpacing) );
    int totalLength = Math.minprefLength, (horiz ? maxWidth : maxHeight) );

    int a = (horiz ? in.left : in.top);
    int b = (horiz ? in.top : in.left);
    int l = 0, d = 0, sum = 0;
    int matchedLength = 0;
    Dimension prefsize = null;

    if (ourLengthsMatched)
    {
      matchedLength = horiz ? getMaxPrefWidth(components)
                    : getMaxPrefHeight(components) );

      if (prefLength > totalLength && ourSqueezeFactor < 100)
      {
        int minLength = calculateMinimumLength(components,
                      ourOrientation, ourSpacing);

        if (minLength >= totalLength)
        {
          matchedLength = (matchedLength * ourSqueezeFactor100;
        }

        else
        {
          int numSeparators = countSeparators(components);
          int numComponents = components.length - numSeparators;
          int diff = (prefLength - totalLength/ numComponents;
          if ((prefLength - totalLength% numComponents > 0diff++;
          matchedLength -= diff;
        }
      }
    }



    for (int i=0; i < components.length; i++)
    {
      prefsize = components[i].getPreferredSize();
      if (!ourLengthsMatchedl = (horiz ? prefsize.width : prefsize.height);
      else l = matchedLength;

      if (components[iinstanceof JSeparator)
      {
        // l = Math.min(prefsize.width, prefsize.height);
        l = (horiz ? prefsize.width : prefsize.height);
        d = totalDepth;
        sum += l;
        if (ourDrop && sum > totalLengthl = 0;
      }

      else
      {
        sum += l;
        if (ourDrop && sum > totalLengthl = 0;

        else if (ourFill && !ourLengthsMatched && i == components.length - 1)
        {
          l = Math.maxl, (horiz ? maxWidth : maxHeight) );
        }

        if (ourDepthsMatchedd = totalDepth;
        else d = (horiz ? prefsize.height : prefsize.width);
      }


      if (horizcomponents[i].setBounds(a, b + (totalDepth - d2, l, d);
      else components[i].setBounds(b + (totalDepth - d2, a, d, l);

      a += l + ourSpacing;
      sum += ourSpacing;
    }

  }




















  /**
   * Returns the largest preferred width of the provided components.
   */
  private int getMaxPrefWidth(Component[] components)
  {
    int maxWidth = 0;
    int componentWidth = 0;
    Dimension d = null;

    for (int i=0; i < components.length; i++)
    {
      d = components[i].getPreferredSize();
      componentWidth = d.width;

      if (components[iinstanceof JSeparator)
      {
        componentWidth = Math.min(d.width, d.height);
      }

      maxWidth = Math.max(maxWidth, componentWidth);
    }

    return maxWidth;
  }



  /**
   * Returns the largest preferred height of the provided components.
   */
  private int getMaxPrefHeight(Component[] components)
  {
    int maxHeight = 0;
    int componentHeight = 0;
    Dimension d = null;

    for (int i=0; i < components.length; i++)
    {
      d = components[i].getPreferredSize();
      componentHeight = d.height;

      if (components[iinstanceof JSeparator)
      {
        componentHeight = Math.min(d.width, d.height);
      }

      else maxHeight = Math.max(maxHeight, componentHeight);
    }

    return maxHeight;
  }

















  /**
   * Calculates the preferred "length" of this layout for the provided
   * components based on the largest component preferred size.
   */
  private int calculateAdjustedLength(Component[] components,
                    int orientation, int spacing)
  {
    int total = 0;
    int componentLength = orientation == HORIZONTAL ?
        getMaxPrefWidth(components: getMaxPrefHeight(components) );


    for (int i=0; i < components.length; i++)
    {
      if (components[iinstanceof JSeparator)
      {
        Dimension d = components[i].getPreferredSize();
        // total += Math.min(d.width, d.height);
        total += (orientation == HORIZONTAL ? d.width : d.height);
      }

      else total += componentLength;
    }


    int gaps = Math.max(0, spacing * (components.length - 1));
    total += gaps;


    return total;
  }




  /**
   * Calculates the minimum "length" of this layout for the provided
   * components, taking the squeeze factor into account when necessary.
   */
  private int calculateMinimumLength(Component[] components,
                    int orientation, int spacing)
  {
    if (!ourLengthsMatched)  return calculatePreferredLength(
                      components, orientation, spacing );

    if (ourSqueezeFactor == 100)  return calculateAdjustedLength(
                      components, orientation, spacing);

    int total = 0;
    int componentLength = orientation == HORIZONTAL ?
        getMaxPrefWidth(components: getMaxPrefHeight(components) );

    componentLength = (componentLength * ourSqueezeFactor100;


    for (int i=0; i < components.length; i++)
    {
      if (components[iinstanceof JSeparator)
      {
        Dimension d = components[i].getPreferredSize();
        // total += Math.min(d.width, d.height);
        total += (orientation == HORIZONTAL ? d.width : d.height);
      }

      else total += componentLength;
    }


    int gaps = Math.max(0, spacing * (components.length - 1));
    total += gaps;


    return total;
  }




  /**
   * Calculates the preferred "length" of this layout for the provided
   * components.
   */
  private int calculatePreferredLength(Component[] components,
                    int orientation, int spacing)
  {
    int total = 0;
    Dimension d = null;


    for (int i=0; i < components.length; i++)
    {
      d = components[i].getPreferredSize();

//      if (components[i] instanceof JSeparator)
//      {
//        total += Math.min(d.width, d.height);
//      }
//
//      else
        total += (orientation == HORIZONTAL ? d.width : d.height);
    }


    int gaps = Math.max(0, spacing * (components.length - 1));
    total += gaps;


    return total;
  }




  /**
   * Returns the preferred "depth" of this layout for the provided
   * components.
   */
  private int calculatePreferredDepth(Component[] components, int orientation)
  {
    if (orientation == HORIZONTALreturn getMaxPrefHeight(components);
    else if (orientation == VERTICALreturn getMaxPrefWidth(components);
    else return 0;
  }



  private int countSeparators(Component[] components)
  {
    int count = 0;

    for (int i=0; i < components.length; i++)
    {
      if (components[iinstanceof JSeparatorcount++;
    }

    return count;
  }


}
14. 97. Custom Layout
14. 97. 1. Custom Layout: DiagonalLayoutCustom Layout: DiagonalLayout
14. 97. 2. GraphPaperLayout implements LayoutManager2
14. 97. 3. Circle Layout
14. 97. 4. This LayoutManager arranges the components into a column. Components are always given their preferred size
14. 97. 5. Compents are laid out in a circle.
14. 97. 6. Specialised layout manager for a grid of components.
14. 97. 7. Stack Layout, uses an orientation to determine if the contents should be arranged horizontally or vertically.
14. 97. 8. A layout manager that displays a single component in the center of its container.
14. 97. 9. A simple layoutmanager to overlay all components of a parent.
14. 97. 10. A layout manager that lays out components along a central axis
14. 97. 11. Wrapper Layout
14. 97. 12. Center Layout
14. 97. 13. DividerLayout is layout that divides two components with the column of actions
14. 97. 14. X Y Layout
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.