de.winterdrache.layout
Class MSBLayout.Group

java.lang.Object
  extended by de.winterdrache.layout.MSBLayout.Group
Enclosing class:
MSBLayout

public class MSBLayout.Group
extends Object

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.

Setting Constraints on all Group members

A Group can be used to set Constraints on all members at the same time. This is especially useful when using autobox strings to assign components to groups automatically.

Example: You want to set hfill=2 on all buttons of a button panel.

 JFrame myFrame = new JFrame("Example");
 MSBLayout layout = new MSBLayout("{['buttons']}", myFrame);

 layout.group("buttons").hfill(2);

 for (int i = 1; i <= 10; ++i)
   layout.add(new JButton("" + i));

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

Aligning edges and synchronizing sizes

Example 1: You have 2 hboxes, each with a label followed by a text field. You want the text fields to start at the same x coordinate.

Instead of

  Short label [______________]
  Much longer label [________]
 
you want
  Short label       [________]
  Much longer label [________]
 

You achieve this by assigning the 2 labels to the same Group. tieWidth() and tieMargins() are set by default for all Groups.

Example 2: You want all buttons of a dialog to have the same size.

Instead of

    [ OK ]  [ Cancel ]
 
you want
    [   OK   ]  [ Cancel ]
 
You achieve this by assigning the 2 buttons to the same Group. tieWidth() and tieMargins() are set by default for all Groups.

Alignment pitfalls

It is important to understand that methods like tieWidth() do not tie the actual sizes of the group members together. It is only the size hints preferred, minimum and maximum size that are tied together. As a consequence, putting 2 components into the same Group with tieWidth() set will not necessarily cause the 2 components to have the same size. If the use of a Group for alignment does not yield the expected result, check the issues described in the following sections.

Alignment trouble? Check hfill/vfill.

A box with hfill==0 will insist on its preferred width. This can counteract alignment attempts in several ways. The most obvious consequence of hfill==0 is that the respective box will not grow when the dialog window is enlarged. Assume you put a box with hfill==0 into a Group together with a box with hfill==2 and set tieWidth() on the Group. If you expect tieWidth() to force both boxes to be the same size, you are mistaken. When the dialog window is enlarged, the hfill==2 box will grow with it but the hfill==0 box will not.

Now you may say that all you care about is a dialog's natural size because you disable window resizing on it anyway. Even then you may discover that 2 boxes in the same Group with different hfill values do not have the same size. Take the following example:

    JFrame myFrame = new JFrame("Example");
    MSBLayout layout = new MSBLayout("{1,1,1}", myFrame);

    layout.group("test").tieWidth(); // redundant

    layout.add(new JLabel("Long label that determines the width of the containing vbox"));

    layout.add(new   JLabel("Short label")).groups("test");
    layout.add(new JTextField("Textfield")).groups("test").hfill(2);

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

The result will look like this:

   Long label that determines the width of the containing vbox
   Short label
   [Textfield_________________________________________________]
   

Even though the textfield and the short label are in a Group with tieWidth() and even though the dialog is displayed at its natural size, the textfield does not have the same size as the label. The reason is that the textfield has hfill==2 which means that it will grow larger even than its maximum size if there is space to fill. The tieWidth() does cause the textfield to have the same maximum size as the label, but the hfill==2 overrides it.

Take note that the default ConstraintsFactory has different default constraints for different component types. When you group different types of components for alignment purposes it is advisable to set hfill/vfill explictly to make sure all group members have the same value. You can use the Group's hfill(int) and vfill(int) methods for this.

Alignment trouble? Check minimum, preferred and maximum sizes.

Every Component has a minimum, maximum and preferred size. These sizes are hints to the LayoutManager. MSBLayout respects these hints whenever it can. When multiple components are put into a Group with tieWidth()/ tieHeight() set, all members of the Group will be considered to have the same size hints. Where size hints differ, the Group chooses the most restrictive hint.

Putting components into a Group for alignment can have several side effects related to the size hints that may be surprising. For instance a textfield may stop growing to fill space after being put into an alignment group, because its maximum size hint has been overridden by the more restrictive one from another Group member.

Alignment trouble? Check the box structure.

There are 2 common pitfalls concerning alignment and the box structure. When a box is nested in other boxes, this may interfere with alignment. For instance a surrounding box may have hfill==0 set. That will prevent it from growing larger than its preferred size. This in turn restricts any contained child boxes, even if they have hfill==2 set. As described further above when discussing alignment problems concerning hfill/vfill, this can cause alignment to break.

Another common issue where alignment will break due to issues with the box structure occurs when 2 members of a Group have a different context. When the neighbours and surrounding or contained boxes of box A have different properties than the neighbours and surrounding or contained boxes of box B, box A and B may end up having different sizes, even when in the same Group. As a general rule, whenever you have alignment or sizing issues that you don't understand, try to make the context of the concerned boxes as similar as possible.

Alignment trouble? Check the margins.

Margins are treated separate from the size hints. Like the size hints Groups tie them together by default. This is normally what you want to achieve proper alignment. In some cases, however, this may cause unexpected effects, usually causing a box or a gap to be larger than desired. These problems occur mostly when using the default LayoutStyle because of its often inconsistent behaviour. When you suspect a margin problem, try untieMargins() on the affected Group or set explicit pixel margins on the Group's members. Using a custom LayoutStyle is also a good idea to achieve results consistent with your expectations.

Author:
Matthias S. Benkmann

Method Summary
 MSBLayout.Group halign(float align)
          If halign is not Float.NaN, it will be set on all current and all future members.
 MSBLayout.Group hfill(int hfill)
          If hfill >= 0, it will be set on all current and all future members.
 MSBLayout.Group hshrink(int weight)
          If hshrink > 0, it will be set on all current and all future members.
 MSBLayout.Group hweight(int weight)
          If hweight > 0, it will be set on all current and all future members.
 MSBLayout.Group tieHeight()
           (tieHeight() is on by default)All boxes belonging to this Group will have the same minimum, preferred and maximum height (multiplied by their respective vscale).
 MSBLayout.Group tieMargins()
           (tieMargins() is on by default)All boxes belonging to this Group will have the same margins.
 MSBLayout.Group tieMargins(boolean top, boolean left, boolean bottom, boolean right)
           All boxes belonging to this Group will have the same margins as specified by the top, left, bottom and right arguments.
 MSBLayout.Group tieWidth()
           (tieWidth() is on by default)All boxes belonging to this Group will have the same minimum, preferred and maximum width (multiplied by their respective hscale).
 MSBLayout.Group untieAll()
          Combines untieWidth(), untieHeight() and untieMargins(); useful when you need a group only for setting Constraints on all members.
 MSBLayout.Group untieHeight()
          Deactivates tieHeight().
 MSBLayout.Group untieMargins()
          Deactivates tieMargins() for top, bottom, left and right margin.
 MSBLayout.Group untieWidth()
          Deactivates tieWidth().
 MSBLayout.Group valign(float align)
          If valign is not Float.NaN, it will be set on all current and all future members.
 MSBLayout.Group vfill(int vfill)
          If vfill >= 0, it will be set on all current and all future members.
 MSBLayout.Group vshrink(int weight)
          If vshrink > 0, it will be set on all current and all future members.
 MSBLayout.Group vweight(int weight)
          If vweight > 0, it will be set on all current and all future members.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Method Detail

hfill

public MSBLayout.Group hfill(int hfill)
If hfill >= 0, it will be set on all current and all future members. Pass -1 to reset a previously set hfill value, meaning that future members will not get their hfill changed. Note that this is NOT an override value. It will be set now on every current member and whenever a new member is added to the group will be set on that new member. Changes to the constraints afterwards will take effect as usual.

Throws:
IllegalArgumentException - if the value passed is < -1 or > 2.
See Also:
MSBLayout.MutableConstraints.hfill(int)

vfill

public MSBLayout.Group vfill(int vfill)
If vfill >= 0, it will be set on all current and all future members. Pass -1 to reset a previously set vfill value, meaning that future members will not get their vfill changed. Note that this is NOT an override value. It will be set now on every current member and whenever a new member is added to the group will be set on that new member. Changes to the constraints afterwards will take effect as usual.

Throws:
IllegalArgumentException - if the value passed is < -1 or > 2.
See Also:
MSBLayout.MutableConstraints.vfill(int)

hweight

public MSBLayout.Group hweight(int weight)
If hweight > 0, it will be set on all current and all future members. Pass -1 to reset a previously set hweight value, meaning that future members will not get their hweight changed. Note that this is NOT an override value. It will be set now on every current member and whenever a new member is added to the group will be set on that new member. Changes to the constraints afterwards will take effect as usual.

Throws:
IllegalArgumentException - if the value passed is < -1, = 0 or > MSBLayout.MAX_WEIGHT_SHRINK.
See Also:
MSBLayout.MutableConstraints.hweight(int)

vweight

public MSBLayout.Group vweight(int weight)
If vweight > 0, it will be set on all current and all future members. Pass -1 to reset a previously set vweight value, meaning that future members will not get their vweight changed. Note that this is NOT an override value. It will be set now on every current member and whenever a new member is added to the group will be set on that new member. Changes to the constraints afterwards will take effect as usual.

Throws:
IllegalArgumentException - if the value passed is < -1, = 0 or > MSBLayout.MAX_WEIGHT_SHRINK.
See Also:
MSBLayout.MutableConstraints.vweight(int)

hshrink

public MSBLayout.Group hshrink(int weight)
If hshrink > 0, it will be set on all current and all future members. Pass -1 to reset a previously set hshrink value, meaning that future members will not get their hshrink changed. Note that this is NOT an override value. It will be set now on every current member and whenever a new member is added to the group will be set on that new member. Changes to the constraints afterwards will take effect as usual.

Throws:
IllegalArgumentException - if the value passed is < -1, = 0 or > MSBLayout.MAX_WEIGHT_SHRINK.
See Also:
MSBLayout.MutableConstraints.hshrink(int)

vshrink

public MSBLayout.Group vshrink(int weight)
If vshrink > 0, it will be set on all current and all future members. Pass -1 to reset a previously set vshrink value, meaning that future members will not get their vshrink changed. Note that this is NOT an override value. It will be set now on every current member and whenever a new member is added to the group will be set on that new member. Changes to the constraints afterwards will take effect as usual.

Throws:
IllegalArgumentException - if the value passed is < -1, = 0 or > MSBLayout.MAX_WEIGHT_SHRINK.
See Also:
MSBLayout.MutableConstraints.vshrink(int)

halign

public MSBLayout.Group halign(float align)
If halign is not Float.NaN, it will be set on all current and all future members. Pass Float.NaN to reset a previously set halign value, meaning that future members will not get their halign changed. Note that this is NOT an override value. It will be set now on every current member and whenever a new member is added to the group will be set on that new member. Changes to the constraints afterwards will take effect as usual.

See Also:
MSBLayout.MutableConstraints.halign(float)

valign

public MSBLayout.Group valign(float align)
If valign is not Float.NaN, it will be set on all current and all future members. Pass Float.NaN to reset a previously set valign value, meaning that future members will not get their valign changed. Note that this is NOT an override value. It will be set now on every current member and whenever a new member is added to the group will be set on that new member. Changes to the constraints afterwards will take effect as usual.

See Also:
MSBLayout.MutableConstraints.valign(float)

tieWidth

public MSBLayout.Group tieWidth()

(tieWidth() is on by default)All boxes belonging to this Group will have the same minimum, preferred and maximum width (multiplied by their respective hscale). This does not necessarily mean they will all have the same actual width, because the actual width depends on the Constraints of the individual boxes and other factors.

NOTE: The widths considered by the Group include padding but exclude margin. If you want margins to be the same, use tieMargins(). This applies only to the margins set directly on the members of the Group. I.e. If the Group contains hboxes and/or vboxes, the margins set on these boxes will not be considered. However the margins of the child boxes contained within will not be ignored. You can make use of this fact to have the margin of a component box be considered by the Group, by wrapping it in an h/vbox and putting that into the Group.

Returns:
this
See Also:
tieMargins(), MSBLayout.Constraints.hscale()

untieWidth

public MSBLayout.Group untieWidth()
Deactivates tieWidth(). NOTE: tieWidth() is on by default.

Returns:
this
See Also:
tieWidth()

tieHeight

public MSBLayout.Group tieHeight()

(tieHeight() is on by default)All boxes belonging to this Group will have the same minimum, preferred and maximum height (multiplied by their respective vscale). This does not necessarily mean they will all have the same actual height, because the actual height depends on the Constraints of the individual boxes and other factors.

NOTE: The heights considered by the Group include padding but exclude margin. If you want margins to be the same, use tieMargins(). This applies only to the margins set directly on the members of the Group. I.e. If the Group contains hboxes and/or vboxes, the margins set on these boxes will not be considered. However the margins of the child boxes contained within will not be ignored. You can make use of this fact to have the margin of a component box be considered by the Group, by wrapping it in an h/vbox and putting that into the Group.

Returns:
this
See Also:
tieMargins(), MSBLayout.Constraints.vscale()

untieHeight

public MSBLayout.Group untieHeight()
Deactivates tieHeight(). NOTE: tieHeight() is on by default.

Returns:
this
See Also:
tieHeight()

tieMargins

public MSBLayout.Group tieMargins()

(tieMargins() is on by default)All boxes belonging to this Group will have the same margins. If you want fine-grained control over which margins will be unified, use tieMargins(boolean, boolean, boolean, boolean).

NOTE: Context-dependent gaps between a Container's edge and a Component are treated separately from other gaps. This means for instance that all left margins that touch the container's left edge and are specified by a Gap constant will be the same among all members of the group, but they may be different from other left margins that are either not set to a Gap constant or do not touch the container's edge.

See Also:
tieMargins(boolean, boolean, boolean, boolean)

tieMargins

public MSBLayout.Group tieMargins(boolean top,
                                  boolean left,
                                  boolean bottom,
                                  boolean right)

All boxes belonging to this Group will have the same margins as specified by the top, left, bottom and right arguments. A value of true for one of the arguments means that the respective margin will be the same among all members of the Group. A value of false means that the respective margins will be left at their individual values.

NOTE: Context-dependent gaps between a Container's edge and a Component are treated separately from other gaps. This means for instance that all left margins that touch the container's left edge and are specified by a Gap constant will be the same among all members of the group, but they may be different from other left margins that are either not set to a Gap constant or do not touch the container's edge.

See Also:
tieMargins()

untieMargins

public MSBLayout.Group untieMargins()
Deactivates tieMargins() for top, bottom, left and right margin.

Returns:
this
See Also:
tieMargins()

untieAll

public MSBLayout.Group untieAll()
Combines untieWidth(), untieHeight() and untieMargins(); useful when you need a group only for setting Constraints on all members.



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