de.winterdrache.layout
Class MSBLayout

java.lang.Object
  extended by de.winterdrache.layout.MSBLayout
All Implemented Interfaces:
LayoutManager, LayoutManager2

public class MSBLayout
extends Object
implements LayoutManager2

MSBLayout is a LayoutManager that combines the nested-boxes approach of BoxLayout with flexible constraints as used by GridBagLayout, but surpasses both its spiritual parents in flexibility and ease of use. MSBLayout has been designed to meet the following goals:


API Reference

Follow this link to skip ahead to the API reference.

Download, Contact

Download releases from the SourceForge file release system.
For feedback, bug reports and questions, use the mailing list.
You can follow the latest development by tracking the Mercurial repository.
More can be found on the SourceForge project page.


Box Structure

MSBLayout organizes everything in boxes that can be nested to an arbitrary level. A horizontal box (hbox) arranges its contents (=child boxes) horizontally. A vertical box (vbox) arranges its contents vertically. A component box always contains exactly one Component and nothing else. The minimum information MSBLayout needs to do its job is the box structure, i.e. what boxes exist and how they should be nested. Constraints (see further below) can be used to fine tune the layout, but often the box structure is enough to get a good layout.

There multiple ways of specifying the box structure. The following illustration shows 3 code examples that produce the exact same dialog.

 // Example 1: autobox-String in constructor 
 JFrame myFrame = new JFrame("Example"); 
 MSBLayout layout = new MSBLayout("(2),(2),2,(3)"
                                  ,myFrame);
 
 myFrame.add(new JLabel("First Name")); 
 myFrame.add(new JTextField(20));
 
 myFrame.add(new JLabel("Last Name")); 
 myFrame.add(new JTextField(20));
 
 layout.glue();
 layout.separator();
 
 layout.glue(); 
 myFrame.add(new JButton("OK")); 
 myFrame.add(new JButton("Cancel"));
 
 myFrame.pack();
 myFrame.setVisible(true);
 
 // Example 2: hbox()/leavebox() pairs 
 JFrame myFrame = new JFrame("Example"); 
 MSBLayout layout = new MSBLayout(myFrame);
 
 layout.hbox();
 { 
   layout.add(new JLabel("First Name")); 
   layout.add(new JTextField(20));
 }
 layout.leavebox();
 
 layout.hbox();
 { 
   layout.add(new JLabel("Last Name")); 
   layout.add(new JTextField(20));
 }
 layout.leavebox();
 
 layout.glue();
 layout.separator();
 
 layout.hbox();
 { 
   layout.glue(); 
   layout.add(new JButton("OK")); 
   layout.add(new JButton("Cancel"));
 }
 layout.leavebox();
 
 myFrame.pack();
 myFrame.setVisible(true);
 
 // Example 3: autobox()/autostop() pairs 
 JFrame myFrame = new JFrame("Example"); 
 MSBLayout layout = new MSBLayout(myFrame);
 
 layout.autobox("(2)*");
 { 
   myFrame.add(new JLabel("First Name")); 
   myFrame.add(new JTextField(20));
 
   myFrame.add(new JLabel("Last Name")); 
   myFrame.add(new JTextField(20));
 
   // You can add more label/textfield pairs here
   // without changing the autobox string
    
 }
 layout.autostop();
 
 layout.glue();
 layout.separator();
 
 layout.autobox("(*)");
 { 
   layout.glue(); 
   layout.add(new JButton("OK")); 
   layout.add(new JButton("Cancel")); 
 }
 layout.autostop();
 
 myFrame.pack();
 myFrame.setVisible(true);
 

Notes:

Further reading on boxes:

For more information on inserting hboxes and vboxes explicitly, see hbox(), vbox() and leavebox().
For more information on autobox-Strings, see autobox(String), autobreak(), autostop() and MSBLayout(String)


Constraints

Every box in an MSBLayout is associated with an object of type MSBLayout.Constraints. These constraints control the sizing and placement behaviour of the box. The following list gives a short introduction of the most important (but not all) constraints.

halign/valign: The horizontal and vertical alignment of the box. Either -1 to justify the box with the edges of its container, or a floating point value between 0.0 (left-most/top-most) and 1.0 (right-most/bottom-most).
hfill/vfill: Whether the box is willing to grow horizontally/vertically to fill excess space. 0 means the box insists on its preferred size, 1 lets it grow up to its maximum size and 2 lets it grow unrestricted.
hweight/vweight: How fast the box will grow compared to its siblings in the same container.

There are several ways of setting/changing the constraints of a box. The following code example demonstrates some (but not all) of them.

  /*
   import de.winterdrache.layout.MSBLayout;
   import de.winterdrache.layout.MSBLayout.Constraints;
   import de.winterdrache.layout.MSBLayout.ConstraintsFactory;
   import de.winterdrache.layout.MSBLayout.ConstraintsImpl;
   import de.winterdrache.layout.MSBLayout.Gap;
  */

   JFrame myFrame = new JFrame("Example");
   MSBLayout layout = new MSBLayout(myFrame);
   Component component = ...;
   ConstraintsFactory myOwnConstraintsFactory = ...;
   
   // Setting constraints via chained manipulators on add() 
   layout.add(component).hfill(2).hweight(1000);
   
   // Setting constraints via chained manipulators after add()
   myFrame.add(component);
   layout.current().hfill(2).hweight(1000);
     
   // Passing a Constraints object to add()
   Constraints constraints = 
     new ConstraintsImpl(1, 0, -1.0f, -1.0f, new Insets(Gap.RELATED,Gap.RELATED,Gap.RELATED,Gap.RELATED), 
                         100, 100, new Dimension(0,0), 1.0f, 1.0f, 100, 100);
   myFrame.add(component,constraints);
   
   // Changing constraints of multiple boxes via a group
   layout.group("buttons").hfill(2).hweight(1000);
   
   // Changing the default constraints for a whole class of Components
   layout.modifyConstraintsFor(JButton.class).hfill(2).hweight(1000);
   
   // Changing the factory that provides the default constraints for a single MSBLayout instance
   layout.setConstraintsFactory(new ConstraintsFactory());
   layout.getConstraintsFactory().setConstraintsFor(JButton.class, constraints);
   
   // Replacing the global factory used by default by ALL instances of MSBLayout
   MSBLayout.setDefaultConstraintsFactory(myOwnConstraintsFactory);
 

Further reading on constraints:

For a detailed discussion of all available constraints, see MSBLayout.MutableConstraints and MSBLayout.Constraints.
For more information on ConstraintsFactorys, see MSBLayout.ConstraintsFactory.


Aligning edges and synchronizing sizes

In order to improve the aesthetics of a dialog it is often desirable to align the edges of components, so that e.g. 2 text fields in adjacent lines start and end at the same x coordinate. It's also sometimes an improvement to give some elements the same size even though their natural preferred sizes differ. The most common example for this are buttons. When several buttons are arranged in a group it's usually desirable for them all to have the same width, regardless of their labels.

MSBLayout serves both requirements via (alignment) groups. Every box can belong to one or more groups. A group can be configured to tie together the widths and/or heights of its members, meaning that all boxes from the same group will share the same minimum, preferred and maximum size. Because MSBLayout respects the size hints when building a layout, you can use groups to make sure that certain elements get the same size and stay at the same size when growing or shrinking the layout.

Edge alignment is done indirectly through size synchronization. The example dialog below has 2 lines, each with a label followed by a text field. Because each text field starts at the x coordinate at which the preceding label ends, if we synchronize the sizes of the 2 labels, the left edges of the text fields align automatically.

 JFrame myFrame = new JFrame("Example");
 MSBLayout layout = new MSBLayout("(1,1),(1,1)",myFrame);
 
 //Redundant! tieWidth() and tieHeight() are default for all groups.
 layout.group("label").tieWidth().tieHeight();
 
 layout.add(new JLabel("Short")).groups("label");
 layout.add(new JTextField(10));
 
 layout.add(new JLabel("A good deal longer")).groups("label");
 layout.add(new JTextField(10));
 
 layout.glue(); //eat space when growing window vertically
 
 myFrame.pack();
 myFrame.setVisible(true);
 

Notes:

Groups and autobox strings

Because groups play an important part in many layouts there is special support for them in autobox strings. The following is an extended version of the previous example. It adds a row of buttons and uses 2 groups, one for the labels and one for the buttons. The name of the labels group in this example is "", i.e. the empty string, which is a legal group name. The name of the buttons group is "buttons". The tieWidth() method calls are omitted because it is default behaviour for all groups.

 JFrame myFrame = new JFrame("Example");
 MSBLayout layout = new MSBLayout(
        "([1],1)([1],1),1,(['buttons' 2])",myFrame);
 
 layout.add(new JLabel("Short"));
 layout.add(new JTextField(20));
 
 layout.add(new JLabel("A good deal longer"));
 layout.add(new JTextField(20));
 
 layout.glue(0, 16, 16384); // some space to separate the form from the buttons
 
 layout.add(new JButton("Short"));
 layout.add(new JButton("A good deal longer"));
 
 myFrame.pack();
 myFrame.setVisible(true);
 

Further reading on groups:

For details on how groups behave and what you can do with them, see MSBLayout.Group.
For details on setting the groups of a box, see MutableConstraints.groups(String) and MutableConstraints.groups(String[]). For details on accessing the groups of an MSBLayout, see group(String).
For details on how to define groups via autobox strings, see autobox(String).


Gaps

If all elements of a user interface are simply lumped together with no gaps between them, the result is ugly and hard to use. For that reason MSBLayout inserts gaps by default and offers multiple ways to control if, where and how much space is inserted.

Fixed margins

The simplest way to get gaps between your components is to use margin constraints with fixed pixel values. You could set them once for all component classes at the global ConstraintsFactory and be done with it. For its simplicity this approach yields surprisingly good results. The following code example demonstrates some ways to set margin constraints.

   MSBLayout layout = ...;
   JLabel label = ...;
   JButton button = ...;

   // At least 4 pixels free space on each side of a button.
   // Note that 2 adjacent buttons will have a gap of 4+4=8 pixels between them.
   MSBLayout.getDefaultConstraintsFactory().modifyConstraintsFor(JButton.class).margin(4,4,4,4);

   // 4 pixels right of label plus 3 pixels left of button gives a 7 pixel gap between the two. 
   layout.add(label).right(4);
   layout.add(button).left(3);
 

Automatic margins and LayoutStyle

MSBLayout supports the LayoutStyle class to provide the sizes of gaps. Instead of a pixel value, you can set one of the constants provided by the Gap class on a margin. Such a margin will be sized automatically depending on its type and context. MSBLayout supports the following types of automatic gaps:

related: A gap between 2 components that are logically related.
unrelated: A gap between 2 components that are not logically related. Usually larger than a related gap.
container: A gap between a component and the edge of its Container.

The following example code demonstrates the use of automatic gaps and a LayoutStyle that sizes gaps based on the font size:

   LayoutStyle myStyle = new LayoutStyle() {
     private int unit;

     //anonymous constructor
     { unit = new JLabel("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz").getPreferredSize().width; }
     
     public int getContainerGap(JComponent component, int position, Container parent)
     { return unit/26; }

     public int getPreferredGap(JComponent component1, JComponent component2,
                                ComponentPlacement type, int position, Container parent)
     { switch (type) {
         case RELATED:
           return unit/52;
         case UNRELATED:
           return unit/26;
         case INDENT:
           return 0; // Note: MSBLayout does not use INDENT
         default:
           throw new IllegalArgumentException("Unknown ComponentPlacement");
       }
     }
   };
   
   // Change style globally for all layouts.
   LayoutStyle.setInstance(myStyle);
  JFrame myFrame = new JFrame("Example");
  MSBLayout layout = new MSBLayout("(2)*",myFrame);
   
  layout.add(new JLabel("Data 1"));
  layout.add(new JTextField(20));
   
  layout.add(new JLabel("Related data 2"));
  layout.add(new JTextField(20));
   
  layout.add(new JLabel("Unrelated data 3")).top(Gap.UNRELATED);
  layout.add(new JTextField(20));
   
  layout.glue(); // eat space when growing window vertically
   
  myFrame.pack();
  myFrame.setVisible(true);
 
 

Notes:

Glues

A glue is an invisible layout element whose only job is to take up space. You can control a glue's minimum, preferred and maximum sizes individually which makes them very flexible. Aside from providing fixed gaps, glues are especially useful for eating up extra space in container boxes. Glues are by default configured with large hweight and vweight values, so that they will usually get all the excess space in a container box. The following example code demonstrates how to use glues:

   JFrame myFrame = new JFrame("Example");
   MSBLayout layout = new MSBLayout(myFrame);
   
   layout.hbox();
   
   layout.add(new JButton("Left"));
   
   layout.glue(32); // A fixed size 32 pixel gap
   
   layout.add(new JButton("Left 2"));
   
   // Minimum size 0 but will gobble up all excess space.
   // The result is that when the window is grown horizontally, all the extra space 
   // ends up here, which means that the buttons "Left" and "Left 2" will always be
   // at the left edge of the window, whereas the button "Right" will always be
   // at the right edge.
   layout.glue();
   
   layout.add(new JButton("Right"));
   
   myFrame.pack();
   myFrame.setVisible(true);
 

Further reading on gaps:

For documentation on the margin constraint, see MutableConstraints.margin(int,int,int,int).
For a detailed discussion of automatic gaps, see MSBLayout.Gap.
For details on the use of glues, see glue() and glue(int, int, int, int, int, int).

Author:
Matthias S. Benkmann

Nested Class Summary
static interface MSBLayout.Constraints
           Every box in an MSBLayout is associated with a Constraints object that controls the sizing and placement behaviour of the box.
static class MSBLayout.ConstraintsFactory
           When a new box is added to an MSBLayout without an accompanying Constraints object, MSBLayout uses a ConstraintsFactory to provide the Constraints.
static class MSBLayout.ConstraintsImpl
          A straightforward implementation of the MutableConstraints interface.
static class MSBLayout.Gap
          The Gap class contains constants that can be used as margin constraints instead of fixed pixel values to get automatic context-dependent gaps.
 class MSBLayout.Group
          A Group's primary purpose is to force certain aspects (most importantly width and height) of several boxes to be the same; furthermore it allows you to change the constraints of all member boxes in a single statement.
static interface MSBLayout.MutableConstraints
          Extends the (read-only) Constraints interface with methods to modify the constraints.
 
Field Summary
static int MAX_WEIGHT_SHRINK
          Maximum value for the hweight, vweight, hshrink and vshrink constraints.
 
Constructor Summary
MSBLayout()
          Creates a new MSBLayout whose outer-most box is a vbox.
MSBLayout(Container containerToLayout)
          Creates a new MSBLayout whose outer-most box is a vbox and sets it as LayoutManager on a given Container.
MSBLayout(Container containerToLayout, MSBLayout.ConstraintsFactory factory)
          Creates a new MSBLayout and installs it on the given Container; the outer-most box is a vbox; Constraints will be taken from the given factory.
MSBLayout(MSBLayout.ConstraintsFactory factory)
          Creates a new MSBLayout whose outer-most box is a vbox and that uses the given factory to provide default constraints for all boxes.
MSBLayout(String structure)
          Creates a new MSBLayout with the given hbox/vbox structure.
MSBLayout(String structure, Container containerToLayout)
          Creates a new MSBLayout with the given hbox/vbox structure and installs it as LayoutManager on the given Container.
MSBLayout(String structure, Container containerToLayout, MSBLayout.ConstraintsFactory factory)
          Creates a new MSBLayout with the given hbox/vbox structure and installs it as LayoutManager on the given Container; the given factory will be used to provide default Constraint for boxes.
MSBLayout(String structure, MSBLayout.ConstraintsFactory factory)
          Creates a new MSBLayout with the given hbox/vbox structure; the given factory will be used to provide default constraints for all boxes.
 
Method Summary
 MSBLayout.MutableConstraints add(Component compo)
          Adds compo to the Container this MSBLayout is LayoutManager for.
 MSBLayout.MutableConstraints add(Component compo, MSBLayout.Constraints constraints)
          Adds compo to the Container this MSBLayout is LayoutManager for using the provided Constraints rather than those from the ConstraintsFactory.
 void addLayoutComponent(Component comp, Object constraints)
          Called by the Container's add() methods; User code should not call it directly.
 void addLayoutComponent(String name, Component comp)
          Unsupported method obsoleted by addLayoutComponent(Component, Object).
 MSBLayout.MutableConstraints autobox(String structure)
          Configures this MSBLayout to automatically create hboxes and vboxes according to the given structure when components are added to the layout.
 MSBLayout autobreak()
          Similar to leavebox(), but if an autobox(String) is active, the repetition count of the box that is being left is immediately reduced to 0 and the box will not be repeated.
 MSBLayout autostop()
          Stops all autobox(String) processing if any is active.
 MSBLayout.MutableConstraints current()
          Returns a MutableConstraints reference through which you can set the behaviour of the most recently added box.
 MSBLayout.MutableConstraints currentbox()
          Returns a MutableConstraints reference through which you can set the behaviour of the parent box of current().
 MSBLayout.ConstraintsFactory getConstraintsFactory()
          Returns the ConstraintsFactory used by this MSBLayout.
 Container getContainer()
          If this MSBLayout knows its Container, it will be returned.
static MSBLayout.ConstraintsFactory getDefaultConstraintsFactory()
          Returns the static ConstraintsFactory that is used by MSBLayouts that have no individual factory set.
 float getLayoutAlignmentX(Container target)
          Returns 0.5f.
 float getLayoutAlignmentY(Container target)
          Returns 0.5f.
 LayoutStyle getLayoutStyle()
          Returns the LayoutStyle set via setLayoutStyle(LayoutStyle) or null if the global style from LayoutStyle.getInstance() is used.
 MSBLayout.MutableConstraints glue()
          Adds an empty box to the layout that will eat up excess space.
 MSBLayout.MutableConstraints glue(int length)
          Adds a spacer that has the given length as its minimum, preferred and maximum dimensions.
 MSBLayout.MutableConstraints glue(int min, int pref, int max)
          Adds a spacer with the given minimum, preferred and maximum dimensions.
 MSBLayout.MutableConstraints glue(int minWidth, int minHeight, int prefWidth, int prefHeight, int maxWidth, int maxHeight)
          Adds a spacer with the given dimensions to this layout.
 MSBLayout.Group group(String groupName)
          Returns the Group with name groupName.
 MSBLayout.MutableConstraints hbox()
          Inserts an hbox at the current insert location and sets the insert cursor inside this hbox.
 MSBLayout.MutableConstraints hbox(Border border)
          (Swing-only) Inserts an hbox with a border.
 MSBLayout.MutableConstraints hbox(Container background)
          Inserts an hbox with a background component that can be used to provide a border, background image or similar.
 MSBLayout.MutableConstraints hbox(Container background, MSBLayout.Constraints constraints)
          If background is non-null behaves like hbox(Container); if constraints is non-null behaves like hbox(Constraints); if both are non-null combines both; if both are null behaves like hbox().
 MSBLayout.MutableConstraints hbox(MSBLayout.Constraints constraints)
          Inserts an hbox at the current insert location and sets the insert cursor inside this hbox.
 MSBLayout.MutableConstraints hbox(String title)
          (Swing-only) A shortcut for hbox(new TitledBorder(title)).
 void invalidateLayout(Container target)
          Does nothing; particularly does not call recomputeMargins().
 void layoutContainer(Container parent)
          Computes and sets the sizes and positions of all components in the Container via Component.setBounds(java.awt.Rectangle).
 void leavebox()
          Places the insert cursor after the container box it is currently in, i.e. in the parent box of that box.
 Dimension maximumLayoutSize(Container parent)
          Calculates the maximum size for this layout.
 Dimension minimumLayoutSize(Container parent)
          Calculates the minimum size for this layout.
 MSBLayout.MutableConstraints modifyConstraintsFor(Class<?> cls)
          Allows access to the initial default Constraints used when a Component of the given class is added to the layout and no accompanying Constraints object is provided.
 Dimension preferredLayoutSize(Container parent)
          Calculates the preferred size for this layout.
 void recomputeMargins()
          Translates context-dependent margin gaps as specified by the Gap constants into actual pixel values.
 MSBLayout remove(Component comp)
          Removes comp from the Container this MSBLayout is LayoutManager for and sets the insert cursor to the old position of comp in the box hierarchy, so that adding a new component immediately after removing comp will result in replacing comp.
 void removeLayoutComponent(Component comp)
          If the Component comp is part of this layout, removes comp from it and sets the insert cursor to the old position of comp in the box hierarchy, so that adding a new component immediately after the removal will result in replacing comp.
 MSBLayout.MutableConstraints seek(Component comp)
          Find the given Component in the box hierarchy, place the insert cursor before it and make it available via current().
 MSBLayout.MutableConstraints separator()
          (Swing-only) Inserts a separator at the current insert cursor position.
 MSBLayout setConstraintsFactory(MSBLayout.ConstraintsFactory factory)
          Sets the provided factory as the new ConstraintsFactory for this MSBLayout.
 MSBLayout setContainer(Container containerToLayout)
          Tells this MSBLayout that containerToLayout is the Container for which the MSBLayout will be used.
static void setDefaultConstraintsFactory(MSBLayout.ConstraintsFactory factory)
          Sets the provided factory as the ConstraintsFactory to be used for MSBLayout's that don't have their own individually set.
 MSBLayout setLayoutStyle(LayoutStyle style)
          (Swing and AWT) Sets the LayoutStyle this MSBLayout instance should use for translating context-dependent margin values as specified by the Gap constants into actual pixel values.
 MSBLayout setSingleBoxJustifyBehaviour(float halign, float valign, int hfill, int vfill)
          Configures how to deal with the situation of a single box whose alignment is set to -1 (meaning "justify").
 boolean usesDefaultConstraintsFactory()
          Returns true if and only if this MSBLayout uses the default ConstraintsFactory.
 MSBLayout.MutableConstraints vbox()
          Inserts a vbox at the current insert location and sets the insert cursor inside this vbox.
 MSBLayout.MutableConstraints vbox(Border border)
          (Swing-only) Inserts a vbox with a border.
 MSBLayout.MutableConstraints vbox(Container background)
          Inserts a vbox with a background component that can be used to provide a border, background image or similar.
 MSBLayout.MutableConstraints vbox(Container background, MSBLayout.Constraints constraints)
          If background is non-null behaves like vbox(Container); if constraints is non-null behaves like vbox(Constraints); if both are non-null combines both; if both are null behaves like vbox().
 MSBLayout.MutableConstraints vbox(MSBLayout.Constraints constraints)
          Inserts a vbox at the current insert location and sets the insert cursor inside this vbox.
 MSBLayout.MutableConstraints vbox(String title)
          (Swing-only) A shortcut for vbox(new TitledBorder(title)).
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

MAX_WEIGHT_SHRINK

public static final int MAX_WEIGHT_SHRINK
Maximum value for the hweight, vweight, hshrink and vshrink constraints.

See Also:
Constant Field Values
Constructor Detail

MSBLayout

public MSBLayout()
Creates a new MSBLayout whose outer-most box is a vbox.


MSBLayout

public MSBLayout(MSBLayout.ConstraintsFactory factory)
Creates a new MSBLayout whose outer-most box is a vbox and that uses the given factory to provide default constraints for all boxes.

Parameters:
factory - if null, the default constraints factory will be used, otherwise the passed factory.
See Also:
setConstraintsFactory(de.winterdrache.layout.MSBLayout.ConstraintsFactory)

MSBLayout

public MSBLayout(Container containerToLayout)
Creates a new MSBLayout whose outer-most box is a vbox and sets it as LayoutManager on a given Container.

Parameters:
containerToLayout - Container.setLayout(LayoutManager) will be called to make this MSBLayout become containerToLayout's LayoutManager. Furthermore this MSBLayout will remember the Container which allows you to use those methods that require this knowledge. If containerToLayout implements RootPaneContainer, the MSBLayout will manage its content pane instead.

MSBLayout

public MSBLayout(Container containerToLayout,
                 MSBLayout.ConstraintsFactory factory)
Creates a new MSBLayout and installs it on the given Container; the outer-most box is a vbox; Constraints will be taken from the given factory.

Parameters:
containerToLayout - if non-null, then Container.setLayout(LayoutManager) will be called to make this MSBLayout become containerToLayout's LayoutManager. Furthermore this MSBLayout will remember the Container which allows you to use those methods that require this knowledge. If it implements RootPaneContainer, the MSBLayout will manage its content pane instead.
factory - if null, the default constraints factory will be used, otherwise the passed factory.

MSBLayout

public MSBLayout(String structure)
Creates a new MSBLayout with the given hbox/vbox structure.

Parameters:
structure - see autobox(String). If structure does not have an unrepeated outermost box, a vbox will be wrapped around the whole structure.

MSBLayout

public MSBLayout(String structure,
                 MSBLayout.ConstraintsFactory factory)
Creates a new MSBLayout with the given hbox/vbox structure; the given factory will be used to provide default constraints for all boxes.

Parameters:
factory - if null, the default constraints factory will be used, otherwise the passed factory.
structure - see autobox(String). If structure does not have an unrepeated outermost box, a vbox will be wrapped around the whole structure.
See Also:
setConstraintsFactory(de.winterdrache.layout.MSBLayout.ConstraintsFactory)

MSBLayout

public MSBLayout(String structure,
                 Container containerToLayout)
Creates a new MSBLayout with the given hbox/vbox structure and installs it as LayoutManager on the given Container.

Parameters:
containerToLayout - Container.setLayout(LayoutManager) will be called to make this MSBLayout become containerToLayout's LayoutManager. Furthermore this MSBLayout will remember the Container which allows you to use those methods that require this knowledge. If it implements RootPaneContainer, the MSBLayout will manage its content pane instead.
structure - see autobox(String). If structure does not have an unrepeated outermost box, a vbox will be wrapped around the whole structure.

MSBLayout

public MSBLayout(String structure,
                 Container containerToLayout,
                 MSBLayout.ConstraintsFactory factory)
Creates a new MSBLayout with the given hbox/vbox structure and installs it as LayoutManager on the given Container; the given factory will be used to provide default Constraint for boxes.

Parameters:
containerToLayout - if non-null, then Container.setLayout(LayoutManager) will be called to make this MSBLayout become containerToLayout's LayoutManager. Furthermore this MSBLayout will remember the Container which allows you to use those methods that require this knowledge. If it implements RootPaneContainer, the MSBLayout will manage its content pane instead.
factory - if null, the default constraints factory will be used, otherwise the passed factory.
structure - see autobox(String). If structure does not have an unrepeated outermost box, a vbox will be wrapped around the whole structure.
Method Detail

getDefaultConstraintsFactory

public static MSBLayout.ConstraintsFactory getDefaultConstraintsFactory()
Returns the static ConstraintsFactory that is used by MSBLayouts that have no individual factory set. When a box is added without specifying Constraints, a ConstraintsFactory is used to provide an initial set of constraints. As long as no ConstraintsFactory is set on an MSBLayout, this default factory is used.

See Also:
setDefaultConstraintsFactory(de.winterdrache.layout.MSBLayout.ConstraintsFactory), setConstraintsFactory(de.winterdrache.layout.MSBLayout.ConstraintsFactory), getConstraintsFactory()

setDefaultConstraintsFactory

public static void setDefaultConstraintsFactory(MSBLayout.ConstraintsFactory factory)
Sets the provided factory as the ConstraintsFactory to be used for MSBLayout's that don't have their own individually set.

See Also:
getDefaultConstraintsFactory(), setConstraintsFactory(de.winterdrache.layout.MSBLayout.ConstraintsFactory), getConstraintsFactory()

getConstraintsFactory

public MSBLayout.ConstraintsFactory getConstraintsFactory()
Returns the ConstraintsFactory used by this MSBLayout. The ConstraintsFactory is used to initialize the constraints when boxes are added to the layout without a Constraints argument. The returned object may be the static default factory or a factory set with setConstraintsFactory(ConstraintsFactory). Use usesDefaultConstraintsFactory() to disambiguate the 2 cases.

See Also:
getDefaultConstraintsFactory(), usesDefaultConstraintsFactory(), setConstraintsFactory(de.winterdrache.layout.MSBLayout.ConstraintsFactory), setDefaultConstraintsFactory(de.winterdrache.layout.MSBLayout.ConstraintsFactory)

usesDefaultConstraintsFactory

public boolean usesDefaultConstraintsFactory()
Returns true if and only if this MSBLayout uses the default ConstraintsFactory.

See Also:
getDefaultConstraintsFactory(), setConstraintsFactory(de.winterdrache.layout.MSBLayout.ConstraintsFactory)

setConstraintsFactory

public MSBLayout setConstraintsFactory(MSBLayout.ConstraintsFactory factory)
Sets the provided factory as the new ConstraintsFactory for this MSBLayout. The ConstraintsFactory is used to initialize the constraints when boxes are added to the layout without a Constraints argument. If you pass null the MSBLayout will switch to using the default constraints factory.

See Also:
getConstraintsFactory(), getDefaultConstraintsFactory(), setDefaultConstraintsFactory(de.winterdrache.layout.MSBLayout.ConstraintsFactory)

modifyConstraintsFor

public MSBLayout.MutableConstraints modifyConstraintsFor(Class<?> cls)
Allows access to the initial default Constraints used when a Component of the given class is added to the layout and no accompanying Constraints object is provided. If this MSBLayout doesn't have its own ConstraintsFactory yet (i.e. setConstraintsFactory(ConstraintsFactory) hasn't been called), a new ConstraintsFactory is created as a copy of getDefaultConstraintsFactory(). Then getConstraintsFactory(). modifyConstraintsFor(cls) is called.


setContainer

public MSBLayout setContainer(Container containerToLayout)
                       throws NullPointerException,
                              IllegalStateException
Tells this MSBLayout that containerToLayout is the Container for which the MSBLayout will be used. Container.setLayout(LayoutManager) will be called with this MSBLayout as argument so that it will be used to layout the container. After calling this method, you can call MSBLayout methods that require knowledge of the Container.

Parameters:
containerToLayout - the Container this MSBLayout should manage. If it implements RootPaneContainer, the MSBLayout will manage its content pane instead.
Returns:
this MSBLayout.
Throws:
IllegalStateException - if this MSBLayout is already being used to layout a Container different from containerToLayout. An instance of MSBLayout can only be used for a single Container.
NullPointerException - if containerToLayout is null.

getContainer

public Container getContainer()
If this MSBLayout knows its Container, it will be returned. Otherwise an IllegalStateException will be thrown. You can use setContainer(Container) to tell the MSBLayout about its Container. Calling Container.add(Component) on the Container (after setting this MSBLayout as its LayoutManager) will also let the MSBLayout know its Container.

Throws:
IllegalStateException - if this MSBLayout doesn't know its Container yet.

setSingleBoxJustifyBehaviour

public MSBLayout setSingleBoxJustifyBehaviour(float halign,
                                              float valign,
                                              int hfill,
                                              int vfill)
Configures how to deal with the situation of a single box whose alignment is set to -1 (meaning "justify"). When a container box has only a single child box along a given axis and that box specifies its alignment as "justify", there are several ways to interpret this. This method allows you to specify the behaviour of a box in such a situation. The arguments passed to this method will override the corresponding Constraints for a box in this situation. halign and valign must be >= 0.0 but for hfill and vfill you can pass -1 which will cause the respective constraint to not be overridden. The default values are 0.0 for halign and valign and "no override" for hfill and vfill. Note that this method changes the behaviour of layoutContainer(Container) rather than setting constraints. Therefore it will always affect all components that are part of the layout.

Returns:
this MSBLayout for easy chaining of method invocations.
See Also:
MSBLayout.MutableConstraints.halign(float), MSBLayout.MutableConstraints.valign(float), MSBLayout.MutableConstraints.hfill(int), MSBLayout.MutableConstraints.vfill(int)

setLayoutStyle

public MSBLayout setLayoutStyle(LayoutStyle style)
(Swing and AWT) Sets the LayoutStyle this MSBLayout instance should use for translating context-dependent margin values as specified by the Gap constants into actual pixel values. A null value (which is the default) tells MSBLayout to use the style returned by LayoutStyle.getInstance().

NOTE: Although LayoutStyle's methods require JComponents, MSBLayout uses it for plain AWT Components, too. Whenever a plain Component is involved in a gap computation it will be replaced (for purposes of calling LayoutStyle's methods) by a dummy JComponent. While this does not allow controlling the gaps based on the types of the components (e.g. Button or Checkbox), it still retains the ability to distinguish between related, unrelated and container gaps. It also means that you don't need to provide your own LayoutStyle. You will get a reasonable default spacing from the Swing LAF even when working with plain AWT.


getLayoutStyle

public LayoutStyle getLayoutStyle()
Returns the LayoutStyle set via setLayoutStyle(LayoutStyle) or null if the global style from LayoutStyle.getInstance() is used.


group

public MSBLayout.Group group(String groupName)
Returns the Group with name groupName. If it has not been used so far it is created.


hbox

public MSBLayout.MutableConstraints hbox()
Inserts an hbox at the current insert location and sets the insert cursor inside this hbox.

Returns:
MutableConstraints that allows you to modify the box's constraints.
See Also:
hbox(Constraints), hbox(Container, Constraints), vbox(), leavebox(), autobox(String)

hbox

public MSBLayout.MutableConstraints hbox(MSBLayout.Constraints constraints)
Inserts an hbox at the current insert location and sets the insert cursor inside this hbox.

Parameters:
constraints - the initial Constraints for the new box. Copied, not stored as reference. May be null. In that case the factory returned by getConstraintsFactory() is used.
Returns:
MutableConstraints that allows you to modify the box's constraints.
See Also:
hbox(), hbox(Container, Constraints), vbox(Constraints), leavebox(), autobox(String)

hbox

public MSBLayout.MutableConstraints hbox(Container background)
Inserts an hbox with a background component that can be used to provide a border, background image or similar. Inserts an hbox at the current insert location and sets the insert cursor inside this hbox. The hbox behaves like other hboxes with respect to arranging its child boxes and the hbox's size will be determined by the contained child boxes. With respect to its surroundings however the box behaves like a component box for the Component background which is added to the container managed by this layout. In its margin Gap.DEFER is translated to Gap.WEAK_UNRELATED.

NOTE: You can only use this method if this MSBLayout knows its Container. You can either pass this Container to MSBLayout's constructor or use setContainer(Container). Calling Container.add(Component) on the Container (after setting this MSBLayout as its LayoutManager) will also let the MSBLayout know its Container.

ATTENTION: Components added to the new box will NOT be placed inside the Container background, even if you add them via MSBLayout's add(Component). Despite this fact, background will be passed to LayoutStyle.getContainerGap(JComponent, int, Container) as parent. This is expressly permitted by the LayoutStyle interface and you should keep it in mind when writing your own LayoutStyle.

Parameters:
background - will be added to the Container managed by this layout as a special component (Do not add it yourself!). It will always be placed and sized so that its contents occupy the same space as the hbox inserted by this method. If background has Insets set on it (usually a Border), these will be treated specially. The margin set via Constraints on the new hbox will be outside of the insets, but the contents of the hbox will be inside of the insets. Effectively this creates an hbox with a Border.

Regardless of whether background has insets or not, when context-dependent Gaps are used by child boxes of the new box, the edges of the new box will be considered container edges and background will be passed as parent container to LayoutStyle.getContainerGap(JComponent, int, Container).
Throws:
IllegalStateException - if this MSBLayout doesn't know its Container.
See Also:
hbox(), hbox(Constraints), vbox(Container), leavebox(), autobox(String)

hbox

public MSBLayout.MutableConstraints hbox(Border border)
(Swing-only) Inserts an hbox with a border. This creates a JComponent, gives it the provided border and then calls hbox(Container).

NOTE: You can only use this method if this MSBLayout knows its Container. You can either pass this Container to MSBLayout's constructor or use setContainer(Container). Calling Container.add(Component) on the Container (after setting this MSBLayout as its LayoutManager) will also let the MSBLayout know its Container.

Throws:
IllegalStateException - if this MSBLayout doesn't know its Container.
See Also:
hbox(Container)

hbox

public MSBLayout.MutableConstraints hbox(String title)
(Swing-only) A shortcut for hbox(new TitledBorder(title)).


hbox

public MSBLayout.MutableConstraints hbox(Container background,
                                         MSBLayout.Constraints constraints)
If background is non-null behaves like hbox(Container); if constraints is non-null behaves like hbox(Constraints); if both are non-null combines both; if both are null behaves like hbox().


vbox

public MSBLayout.MutableConstraints vbox()
Inserts a vbox at the current insert location and sets the insert cursor inside this vbox.

Returns:
MutableConstraints that allows you to modify the box's constraints.
See Also:
vbox(MSBLayout.Constraints), vbox(Container), hbox(), leavebox(), autobox(String)

vbox

public MSBLayout.MutableConstraints vbox(MSBLayout.Constraints constraints)
Inserts a vbox at the current insert location and sets the insert cursor inside this vbox.

Parameters:
constraints - the initial Constraints for the new box. Copied, not stored as reference. May be null. In that case the factory returned by getConstraintsFactory() is used.
Returns:
MutableConstraints that allows you to modify the box's constraints.
See Also:
vbox(), vbox(Container), leavebox(), hbox(Constraints), autobox(String)

vbox

public MSBLayout.MutableConstraints vbox(Container background)
Inserts a vbox with a background component that can be used to provide a border, background image or similar. Inserts a vbox at the current insert location and sets the insert cursor inside this vbox. The vbox behaves like other vboxes with respect to arranging its child boxes and the vbox's size will be determined by the contained child boxes. With respect to its surroundings however the box behaves like a component box for the Component background which is added to the container managed by this layout. In its margin Gap.DEFER is translated to Gap.WEAK_UNRELATED.

NOTE: You can only use this method if this MSBLayout knows its Container. You can either pass this Container to MSBLayout's constructor or use setContainer(Container). Calling Container.add(Component) on the Container (after setting this MSBLayout as its LayoutManager) will also let the MSBLayout know its Container.

ATTENTION: Components added to the new box will NOT be placed inside the Container background, even if you add them via MSBLayout's add(Component). Despite this fact, background will be passed to LayoutStyle.getContainerGap(JComponent, int, Container) as parent. This is expressly permitted by the LayoutStyle interface and you should keep it in mind when writing your own LayoutStyle.

Parameters:
background - will be added to the Container managed by this layout as a special component (Do not add it yourself!). It will always be placed and sized so that its contents occupy the same space as the vbox inserted by this method. If background has Insets set on it (usually a Border), these will be treated specially. The margin set via Constraints on the new vbox will be outside of the insets, but the contents of the vbox will be inside of the insets. Effectively this creates an vbox with a Border.

Regardless of whether background has insets or not, when context-dependent Gaps are used by child boxes of the new box, the edges of the new box will be considered container edges and background will be passed as parent container to LayoutStyle.getContainerGap(JComponent, int, Container).
Throws:
IllegalStateException - if this MSBLayout doesn't know its Container.
See Also:
vbox(), vbox(Constraints), hbox(Container), leavebox(), autobox(String)

vbox

public MSBLayout.MutableConstraints vbox(Border border)
(Swing-only) Inserts a vbox with a border. This creates a JComponent, gives it the provided border and then calls vbox(Container).

NOTE: You can only use this method if this MSBLayout knows its Container. You can either pass this Container to MSBLayout's constructor or use setContainer(Container). Calling Container.add(Component) on the Container (after setting this MSBLayout as its LayoutManager) will also let the MSBLayout know its Container.

Throws:
IllegalStateException - if this MSBLayout doesn't know its Container.
See Also:
vbox(Container)

vbox

public MSBLayout.MutableConstraints vbox(String title)
(Swing-only) A shortcut for vbox(new TitledBorder(title)).


vbox

public MSBLayout.MutableConstraints vbox(Container background,
                                         MSBLayout.Constraints constraints)
If background is non-null behaves like vbox(Container); if constraints is non-null behaves like vbox(Constraints); if both are non-null combines both; if both are null behaves like vbox().


autobox

public MSBLayout.MutableConstraints autobox(String structure)
Configures this MSBLayout to automatically create hboxes and vboxes according to the given structure when components are added to the layout.

Parameters:
structure - specifies the hbox/vbox structure that should be constructed around the components added after the call to autobox(). The following syntax elements are understood:
n
n components
*
an arbitrary number of components (currently a maximum of 8191)
{...}
A vbox around .... If ... is empty, it is assumed to be *
{'title'...}
(Swing-only) A vbox with a TitledBorder with the given title. If ... is empty, it is assumed to be *
{...}n
The same as repeating {...} n-times. n may be any positive integer or * (=infinity, currently limited to 8191). There must be no space between } and n
(...)
An hbox around .... If ... is empty, it is assumed to be *
('title'...)
(Swing-only) An hbox with a TitledBorder with the given title. If ... is empty, it is assumed to be *
(...)n
The same as repeating (...) n-times. n may be any positive integer or * (=infinity, currently limited to 8191). There must be no space between ) and n
[...]
Put the boxes and components specified in the top level of ... into the group named "" (= the empty string). The top level of ... are those components and boxes that are not nested in other boxes specified in ... If ... is empty, it is assumed to be *
['name'...]
Put the boxes and components specified in the top level of ... into the group called "name". The top level of ... are those components and boxes that are not nested in other boxes specified in ... There must be no space between [ and ". If ... is empty, it is assumed to be *
spaces and commas
You may use spaces and commas to make the expression more readable and to separate consecutive component counts.

Example:
 JFrame myFrame = new JFrame("Example");
 MSBLayout layout = new MSBLayout(myFrame);

 // This is a nice trick to remember: You put each label into its own hbox,
 // put these hboxes into a group (here: group "") set to tieWidth() (on by default)
 // and set the labels' halign to 1.0 (right-align). The result is that the labels'
 // right edges and the text fields' left edges neatly align.
 // Very readable and nice-looking.
 layout.autobox("([( 1 )],(1))*");

 // The container gaps above the first label and below the last label are included
 // in the first and last hbox's height. If we kept the default tieHeight(), the middle
 // hbox's height would become larger than it should be.
 layout.group("").untieHeight();

 layout.add(new JLabel("First name")).halign(1.0f);
 layout.add(new JTextField(10));
 layout.add(new JLabel("Middle initial")).halign(1.0f);
 layout.add(new JTextField(1)).hfill(0);
 layout.add(new JLabel("Last name")).halign(1.0f);
 layout.add(new JTextField(10));

 myFrame.pack();
 myFrame.setVisible(true);
 
will result in the following layout:
                First name [_____________]
            Middle initial [_]
                 Last name [_____________]
          
Returns:
If the autobox structure specifies an all-encompassing outer box with repeat count 1 that is not inside any groups, that box will be entered right away and its MutableConstraints returned. Otherwise, null is returned.
See Also:
hbox(), vbox(), MSBLayout(String), autobreak(), autostop(), leavebox()

autobreak

public MSBLayout autobreak()
Similar to leavebox(), but if an autobox(String) is active, the repetition count of the box that is being left is immediately reduced to 0 and the box will not be repeated. The typical application of this method is to break out of infinite loops in the box structure. Infinite repetition counts (i.e. "*") are typically used when the number of elements is not known in advance. Note that autobreak() always works at the hbox/vbox level like leavebox() not at the component level. So in the structure "(* {4})" you cannot use autobreak() to break out of the component repeat "*" to continue with the vbox {4}. In the case of "(* {4})" autobreak() while at the "*" loop would leave the outermost hbox, thereby skipping over the "{4}".

Example:

  JFrame myFrame = new JFrame("Example");
  MSBLayout layout = new MSBLayout(myFrame);

  layout.autobox("([1],1)* ()");

  layout.add(new JLabel("Label"));
  layout.add(new JTextField());

  // ... add any number of label/text field pairs

  layout.autobreak(); // terminate * loop

  // Now add buttons to the button panel at the bottom of the layout
  layout.add(new JButton("Button"));
  layout.add(new JButton("Button"));
  layout.add(new JButton("Button"));

  myFrame.pack();
  myFrame.setVisible(true);
 

See Also:
autobox(String), leavebox(), autostop()

autostop

public MSBLayout autostop()
Stops all autobox(String) processing if any is active. This will leave all boxes entered by any active autobox processing (but not boxes entered by manual calls to e.g. hbox().

See Also:
autobox(String), autobreak(), leavebox()

leavebox

public void leavebox()
Places the insert cursor after the container box it is currently in, i.e. in the parent box of that box. This call is usually used in a pair with hbox() or vbox() but it could just as well be used after a seek(Component). If an autobox(String) is active and the insert cursor is currently in a box that has a non-0 repeat count in the autobox structure, then the repeat count will be decremented by 1 and if a non-0 count remains, further boxes will be generated.

Example:

  JFrame myFrame = new JFrame("Example");
  MSBLayout layout = new MSBLayout(myFrame);

  layout.autobox("(1,{1})5");
  layout.add(new JButton("Button"));// auto-creates an hbox to put the button in
  layout.leavebox();                  // hbox repetition count goes from 5 to 4
  layout.add(new JButton("Button"));// auto-creates an hbox to put the button in
  layout.add(new JTextField(20));   // auto-creates a vbox to put the text field in
  layout.leavebox();                  // Has NO EFFECT, because it leaves the vbox which is done anyway

  myFrame.pack();
  myFrame.setVisible(true);
 

Throws:
IllegalStateException - if the insert cursor is in the outermost box of the box hierarchy.
See Also:
hbox(), vbox(), autobox(String), autobreak(), autostop()

separator

public MSBLayout.MutableConstraints separator()
(Swing-only) Inserts a separator at the current insert cursor position. The separator will be horizontal when added to a vbox and vertical when added to an hbox. The default Constraints will be modified as follows:

Unlike a glue() a separator is a real component (a JSeparator) that is added to the Container.

NOTE: You can only use this method if this MSBLayout knows its Container. You can either pass this Container to MSBLayout's constructor or use setContainer(Container). Calling Container.add(Component) on the Container (after setting this MSBLayout as its LayoutManager) will also let the MSBLayout know its Container.

Returns:
MSBLayout.MutableConstraints object that can be used to change the separator's constraints.
Throws:
IllegalStateException - if this MSBLayout doesn't know its Container.
See Also:
glue(), add(Component)

glue

public MSBLayout.MutableConstraints glue()
Adds an empty box to the layout that will eat up excess space. A glue's default hfill and vfill constraints are set to the maximum possible, so that excess space will preferably be given to the glue. The typical application for glues is to keep a components aligned with the container's edges even when the window is grown larger than its preferred size.

Example:

  JFrame myFrame = new JFrame("Example");
  MSBLayout layout = new MSBLayout("(2),(2), 1 ,()", myFrame);
 
  layout.add(new JLabel("Label"));
  layout.add(new JTextField(20));
  layout.add(new JLabel("Label"));
  layout.add(new JTextField(20));
 
  layout.glue();
 
  layout.add(new JButton("Button"));
  layout.add(new JButton("Button"));
  layout.add(new JButton("Button"));
 
  myFrame.pack();
  myFrame.setVisible(true);
 
will create the following layout
 ---------------------------------
 | Label [_____________________] |
 | Label [_____________________] |
 | [Button]  [Button]  [Button]  |
 ---------------------------------
 
When you enlarge the window vertically, the glue will get all the excess space, leading to the following result.
 ---------------------------------
 | Label [_____________________] |
 | Label [_____________________] |
 |                               |
 |                               |
 |                               |
 | [Button]  [Button]  [Button]  |
 ---------------------------------
 

The buttons will stay at the bottom edge of the window and the input fields at the top edge. The same result could be achieved by setting the valign-values of the hboxes properly, but that would be more complicated.

Notes:

Returns:
MutableConstraints object that can be used to change the glue's constraints.
See Also:
separator(), glue(), glue(int,int,int), glue(int, int, int, int, int, int)

glue

public MSBLayout.MutableConstraints glue(int length)
Adds a spacer that has the given length as its minimum, preferred and maximum dimensions. If the insert cursor is inside an hbox

If the insert cursor is inside a vbox

The spacer is a virtual component that exists only in the layout and has no actual Component in the Container.

See glue() for more information the usage of glues.

Returns:
a MutableConstraints reference that you can use to change the behaviour of the spacer.
See Also:
separator(), glue(), glue(int,int,int), glue(int, int, int, int, int, int)

glue

public MSBLayout.MutableConstraints glue(int min,
                                         int pref,
                                         int max)
Adds a spacer with the given minimum, preferred and maximum dimensions. If the insert cursor is inside an hbox

If the insert cursor is inside a vbox

The spacer is a virtual component that exists only in the layout and has no actual Component in the Container.

See glue() for more information the usage of glues.

Returns:
a MutableConstraints reference that you can use to change the behaviour of the spacer.
See Also:
separator(), glue(), glue(int), glue(int, int, int, int, int, int)

glue

public MSBLayout.MutableConstraints glue(int minWidth,
                                         int minHeight,
                                         int prefWidth,
                                         int prefHeight,
                                         int maxWidth,
                                         int maxHeight)
Adds a spacer with the given dimensions to this layout. The spacer will exist only in the layout without an actual Component in the Container.

See glue() for more information the usage of glues.

Returns:
MutableConstraints object that can be used to change the glue's constraints.
See Also:
separator(), glue(), glue(int), glue(int, int, int)

add

public MSBLayout.MutableConstraints add(Component compo)
Adds compo to the Container this MSBLayout is LayoutManager for.

Note: You can only use this method if this MSBLayout knows its Container. You can either pass this Container to MSBLayout's constructor or use setContainer(Container). Calling Container.add(Component) on the Container (after setting this MSBLayout as its LayoutManager) will also let the MSBLayout know its Container.

Returns:
a MutableConstraints reference that you can use to change the behaviour of compo's box.
Throws:
IllegalStateException - if this MSBLayout doesn't know its Container.
See Also:
add(Component, de.winterdrache.layout.MSBLayout.Constraints)

add

public MSBLayout.MutableConstraints add(Component compo,
                                        MSBLayout.Constraints constraints)
Adds compo to the Container this MSBLayout is LayoutManager for using the provided Constraints rather than those from the ConstraintsFactory.

Note: You can only use this method if this MSBLayout knows its Container. You can either pass this Container to MSBLayout's constructor or use setContainer(Container). Calling Container.add(Component) on the Container (after setting this MSBLayout as its LayoutManager) will also let the MSBLayout know its Container.

Parameters:
constraints - the initial Constraints to initilize the new box with. Copied, not included by reference. If null, the appropriate ConstraintsFactory is used to obtain initial constraints.
Returns:
a MutableConstraints reference that you can use to change the behaviour of compo's box.
Throws:
IllegalStateException - if this MSBLayout doesn't know its Container.
See Also:
add(Component)

current

public MSBLayout.MutableConstraints current()
Returns a MutableConstraints reference through which you can set the behaviour of the most recently added box. This could either be a component box created when adding a Component to the Container or an hbox or vbox added via the respective methods.

Note: current() and currentbox() are definitely the worst-named methods of the MSBLayout API, because both names basically mean the same. I apologize for the inconvenience but I have been unable to come up with names that are both concise and distinctive. Take care not to confuse the 2 methods.


currentbox

public MSBLayout.MutableConstraints currentbox()
Returns a MutableConstraints reference through which you can set the behaviour of the parent box of current(). If the layout is still empty, the outermost container box is returned (i.e. in that case current() and currentbox() return the same box). This method is most useful in combination with autobox(String), because it allows you to access the automatically created boxes for which you could otherwise not set the Constraints.

Example:

   JFrame myFrame = new JFrame("Example");
   MSBLayout layout = new MSBLayout("(2)(2)", myFrame);

   layout.add(new JLabel("Dog's name"));
   layout.add(new JTextField(20));
   layout.currentbox().vfill(0); // modifies the 1st hbox

   layout.add(new JLabel("Cat's name"));
   layout.add(new JTextField(20));
   layout.currentbox().vfill(0); // modifies the 2nd hbox

   myFrame.pack();
   myFrame.setVisible(true);
 
Note: current() and currentbox() are definitely the worst-named methods of the MSBLayout API, because both names basically mean the same. I apologize for the inconvenience but I have been unable to come up with names that are both concise and distinctive. Take care not to confuse the 2 methods.

See Also:
current(), autobox(String)

seek

public MSBLayout.MutableConstraints seek(Component comp)
Find the given Component in the box hierarchy, place the insert cursor before it and make it available via current(). Will place the insert cursor immediately before comp in the box hierarchy so that the next Component that is added to the layout will be inserted before comp. Also makes current() return the MutableConstraints associated with comp. If you seek for the background component of a box added e.g. by hbox(Container), this will seek to the container box that has the background component set (unless it is the outer-most box).

Returns:
the MutableConstraints associated with comp. This allows you to easily access the constraints for a component added earlier.
Throws:
NoSuchElementException - if comp is not part of this layout. This Exception will also be thrown if the outer-most box has a background component and you seek for that.

addLayoutComponent

public void addLayoutComponent(Component comp,
                               Object constraints)
Called by the Container's add() methods; User code should not call it directly. Adds comp to this layout at the current insert cursor position and advances the cursor by one.

Specified by:
addLayoutComponent in interface LayoutManager2
Throws:
ClassCastException - if constraints are not an instance of MSBLayout.Constraints.
See Also:
LayoutManager.addLayoutComponent(java.lang.String, java.awt.Component)

addLayoutComponent

public void addLayoutComponent(String name,
                               Component comp)
Unsupported method obsoleted by addLayoutComponent(Component, Object).

Specified by:
addLayoutComponent in interface LayoutManager

remove

public MSBLayout remove(Component comp)
Removes comp from the Container this MSBLayout is LayoutManager for and sets the insert cursor to the old position of comp in the box hierarchy, so that adding a new component immediately after removing comp will result in replacing comp. The replacement will not inherit any of the removed component's constraints, however.

Note: You can only use this method if this MSBLayout knows its Container. You can either pass this Container to MSBLayout's constructor or use setContainer(Container). Calling Container.add(Component) on the Container (after setting this MSBLayout as its LayoutManager) will also let the MSBLayout know its Container.

Returns:
a reference to this MSBLayout for easy chaining of method calls.
Throws:
IllegalStateException - if this MSBLayout doesn't know its Container.

removeLayoutComponent

public void removeLayoutComponent(Component comp)
If the Component comp is part of this layout, removes comp from it and sets the insert cursor to the old position of comp in the box hierarchy, so that adding a new component immediately after the removal will result in replacing comp. The replacement will not inherit any of the removed component's constraints, however.

ATTENTION! This method is called by the Container's remove() methods. User code should not call it directly. Either use Container.remove(Component) or MSBLayout.remove(Component).

Specified by:
removeLayoutComponent in interface LayoutManager
See Also:
Container.remove(Component), remove(Component), LayoutManager.removeLayoutComponent(java.awt.Component)

layoutContainer

public void layoutContainer(Container parent)
Computes and sets the sizes and positions of all components in the Container via Component.setBounds(java.awt.Rectangle). Although this method is meant to be called from Swing internal code rather than from application code, it can be useful to call it directly. If you're running into the problem that you've changed something on a dialog that's already visible (e.g. a component's preferred size) and your dialog won't update properly, instead of trying random permutations of invalidate(), revalidate(), validate() and repaint(), a simple call to layoutContainer() (possibly preceded by recomputeMargins()) may do the trick. It does exactly what is said in the first sentence and will use the current values of components' minimum/preferred/maximum sizes. Calling layoutContainer() differs from calling pack() in that it will fit the layout into the current window dimensions whereas pack() will change the window dimensions to the preferred size.

ATTENTION! MSBLayout only works on a single Container. It is a requirement that

this == parent.getLayout()

Specified by:
layoutContainer in interface LayoutManager

minimumLayoutSize

public Dimension minimumLayoutSize(Container parent)
Calculates the minimum size for this layout.

ATTENTION! MSBLayout only works on a single Container. It is a requirement that

this == parent.getLayout()

Specified by:
minimumLayoutSize in interface LayoutManager
See Also:
LayoutManager.minimumLayoutSize(java.awt.Container)

preferredLayoutSize

public Dimension preferredLayoutSize(Container parent)
Calculates the preferred size for this layout.

ATTENTION! MSBLayout only works on a single Container. It is a requirement that

this == parent.getLayout()

Specified by:
preferredLayoutSize in interface LayoutManager
See Also:
LayoutManager.minimumLayoutSize(java.awt.Container)

maximumLayoutSize

public Dimension maximumLayoutSize(Container parent)
Calculates the maximum size for this layout.

ATTENTION! MSBLayout only works on a single Container. It is a requirement that

this == parent.getLayout()

Specified by:
maximumLayoutSize in interface LayoutManager2
See Also:
LayoutManager.minimumLayoutSize(java.awt.Container)

getLayoutAlignmentX

public float getLayoutAlignmentX(Container target)
Returns 0.5f.

Specified by:
getLayoutAlignmentX in interface LayoutManager2

getLayoutAlignmentY

public float getLayoutAlignmentY(Container target)
Returns 0.5f.

Specified by:
getLayoutAlignmentY in interface LayoutManager2

invalidateLayout

public void invalidateLayout(Container target)
Does nothing; particularly does not call recomputeMargins(). This is a conscious decision to avoid unnecessary calls to the margin recomputation code. invalidateLayout() is meant for the purpose of LayoutManagers that cache size data between calls to layoutContainer(Container) (which MSBLayout doesn't do). The situations that call for invalidateLayout() usually either don't require a margin recomputation or will trigger one anyway (because a new element is added).

Specified by:
invalidateLayout in interface LayoutManager2
See Also:
recomputeMargins()

recomputeMargins

public void recomputeMargins()
Translates context-dependent margin gaps as specified by the Gap constants into actual pixel values. Normally, MSBLayout recomputes the margins only when elements are removed from or added to the layout, or when a box's margin constraint changes. If other factors change (such as the LayoutStyle) that change the interpretation of context-dependent gaps, you have to call this method manually if you want the gaps to be updated.

NOTE: This method will not cause the Container to be re-layouted. Unless there is something else to trigger a re-layout, you will usually need to call layoutContainer(Container) or Window.pack() for the changes to take effect.

See Also:
invalidateLayout(Container)


Copyright © 2010 Matthias S. Benkmann. See LICENSE file for licensing details.
Hosted on Get MSBLayout at SourceForge.net. Fast, secure and Free Open Source software downloads