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

Java
1. 2D Graphics GUI
2. 3D
3. Advanced Graphics
4. Ant
5. Apache Common
6. Chart
7. Class
8. Collections Data Structure
9. Data Type
10. Database SQL JDBC
11. Design Pattern
12. Development Class
13. EJB3
14. Email
15. Event
16. File Input Output
17. Game
18. Generics
19. GWT
20. Hibernate
21. I18N
22. J2EE
23. J2ME
24. JDK 6
25. JNDI LDAP
26. JPA
27. JSP
28. JSTL
29. Language Basics
30. Network Protocol
31. PDF RTF
32. Reflection
33. Regular Expressions
34. Scripting
35. Security
36. Servlets
37. Spring
38. Swing Components
39. Swing JFC
40. SWT JFace Eclipse
41. Threads
42. Tiny Application
43. Velocity
44. Web Services SOA
45. XML
Java Tutorial
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 » Swing JFC » Customized LayoutScreenshots 
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;
  }


}

   
    
  
Related examples in the same category
1. Custom layout: EdgeLayout
2. Customized layout managerCustomized layout manager
3. ColumnLayoutColumnLayout
4. Applet GUI demo of TreeLayout layout manager
5. Relative Layout Manager for Java J2SE
6. Basically two (or more) columns of different, but constant, widths
7. GraphPaperLayoutGraphPaperLayout
8. Table Layout
9. Table Layout implements LayoutManager2
10. Table layout manager
11. Flex Layout
12. Square Layout
13. Center Layout
14. Wrapper Layout
15. Tile Layout
16. Custom Layout DemoCustom Layout Demo
17. X Y Layout
18. DividerLayout is layout that divides two components with the column of actions
19. A simple layoutmanager to overlay all components of a parent.
20. A layout manager that displays a single component in the center of its container.
21. A layout manager that spaces components over six columns in seven different formats.
22. Compents are laid out in a circle.
23. Special simple layout used in TabbedContainer
24. Place components at exact locations (x, y, width, height) and then determine how they behave when the window containing them (their parent) is resized
25. Specialised layout manager for a grid of components.
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.