While the formatting of layouts is mainly done with style sheets, just as with
other components, style sheets are not ideal or even possible to use in some
situations. For example, CSS does not allow defining the spacing of table
cells, which is done with the cellspacing
attribute in
HTML.
Moreover, as many layout sizes are calculated dynamically in the Client-Side Engine of IT Mill Toolkit, some CSS settings can fail altogether.
The size of a layout component can be specified with the
setWidth()
and
setHeight()
methods defined in the
Sizeable
interface, just like for any component. It
can also be undefined, in which case the layout shrinks to fit the
component(s) inside it. Section 4.18.1, “Sizing Components through Sizeable
interface”
gives details on the interface.
Many layout components take 100% width by default, while have the height undefined.
The sizes of components inside a layout can also be defined as a
percentage of the space available in the layout, for example with
setWidth("100%");
or with the (most commonly used
method) setFullSize()
that sets 100% size in both
directions. If you use a percentage in a
HorizontalLayout
,
VerticalLayout
, or
GridLayout
, you will also have to set the component
as expanding, as noted below.
Warning: A layout that contains components with percentual size must have a defined size! If a layout has undefined size and component has, say, 100% size, the component would fill the space given by the layout, while the layout would shrink to fit the space taken by the component, which is a paradox. This requirement holds for height and width separately. The debug mode allows detecting such invalid cases; see Section 9.1.1, “Debug Mode”.
For example:
// This takes 100% width but has undefined height. VerticalLayout layout = new VerticalLayout(); // A button that takes all the space available in the layout. Button button = new Button("100%x100% button"); button.setSizeFull(); layout.addComponent(button); // We must set the layout to a defined height vertically, in this // case 100% of its parent layout, which also must not have // undefined size. layout.setHeight("100%");
The default layout of Window
and
Panel
is VerticalLayout
with
undefined height. If you insert enough components in such a layout, it
will grow outside the bottom of the view area and scrollbars will appear
in the browser. If you want to have your application to use all the
browser view, nothing more or less, you should use
setFullSize()
for the root layout.
// Create the main window. Window main = new Window("Main Window"); setMainWindow(main); // Use full size. main.getLayout().setSizeFull();
If you set a HorizontalLayout
to a defined size
horizontally or a VerticalLayout
vertically,
and there is space left over from the contained components, the extra
space is distributed equally between the component cells. The
components are aligned within these cells, according to their
alignment setting, top left by default, as in the example below.
Often, you don't want such empty space, but want to have one or more
components to take all the leftover space. You need to set such a
component to 100% size and use
setExpandRatio()
. If there is just one
such expanding component in the layout, the ratio parameter is irrelevant.
If you set multiple components as expanding, the expand ratio dictates how large proportion of the available space (overall or excess depending on whether the components are sized as a percentage or not) each component takes. In the example below, the buttons have 1:2:3 ratio for the expansion.
GridLayout
has corresponding method for both of
its directions, setRowExpandRatio()
and
setColumnExpandRatio()
.
Expansion is dealt in detail in the documentation of the layout
components that support it. See Section 5.2.1, “VerticalLayout
and HorizontalLayout
” and Section 5.2.2, “GridLayout
” for details on components
with relative sizes.
You can set the alignment of the component inside a specific layout cell
with the setComponentAlignment()
method. The
method takes as its parameters the component contained in the cell to be
formatted, and the horizontal and vertical alignment.
Figure 5.9, “Cell Alignments” below illustrates the
alignment of components within a GridLayout
.
The easiest way to set alignments is to use the constants defined in the
Alignment
class. Let us look how the buttons in the
top row of the above GridLayout
are aligned with
constants:
// Create a grid layout final GridLayout grid = new GridLayout(3, 3); grid.setWidth(400, Sizeable.UNITS_PIXELS); grid.setHeight(200, Sizeable.UNITS_PIXELS); Button topleft = new Button("Top Left"); grid.addComponent(topleft, 0, 0); grid.setComponentAlignment(topleft, Alignment.TOP_LEFT); Button topcenter = new Button("Top Center"); grid.addComponent(topcenter, 1, 0); grid.setComponentAlignment(topcenter, Alignment.TOP_CENTER); Button topright = new Button("Top Right"); grid.addComponent(topright, 2, 0); grid.setComponentAlignment(topright, Alignment.TOP_RIGHT); ...
The following table lists all the alignment constants by their respective locations:
Table 5.1. Alignment Constants
Alignment.TOP_LEFT | Alignment.TOP_CENTER | Alignment.TOP_RIGHT |
Alignment.MIDDLE_LEFT | Alignment.MIDDLE_CENTER | Alignment.MIDDLE_RIGHT |
Alignment.BOTTOM_LEFT | Alignment.BOTTOM_CENTER | Alignment.BOTTOM_RIGHT |
Another way to specify the alignments is to create an
Alignment
object and specify the horizontal and
vertical alignment with separate constants. You can specify either of the
directions, in which case the other alignment direction is not modified,
or both with a bitmask operation between the two directions.
Button middleleft = new Button("Middle Left"); grid.addComponent(middleleft, 0, 1); grid.setComponentAlignment(middleleft, new Alignment(Bits.ALIGNMENT_VERTICAL_CENTER | Bits.ALIGNMENT_LEFT)); Button middlecenter = new Button("Middle Center"); grid.addComponent(middlecenter, 1, 1); grid.setComponentAlignment(middlecenter, new Alignment(Bits.ALIGNMENT_VERTICAL_CENTER | Bits.ALIGNMENT_HORIZONTAL_CENTER)); Button middleright = new Button("Middle Right"); grid.addComponent(middleright, 2, 1); grid.setComponentAlignment(middleright, new Alignment(Bits.ALIGNMENT_VERTICAL_CENTER | Bits.ALIGNMENT_RIGHT));
Obviously, you may combine only one vertical bitmask with one horizontal bitmask, though you may leave either one out. The following table lists the available alignment bitmask constants:
Table 5.2. Alignment Bitmasks
Horizontal | Bits.ALIGNMENT_LEFT |
Bits.ALIGNMENT_HORIZONTAL_CENTER | |
Bits.ALIGNMENT_RIGHT | |
Vertical | Bits.ALIGNMENT_TOP |
Bits.ALIGNMENT_VERTICAL_CENTER | |
Bits.ALIGNMENT_BOTTOM |
You can determine the current alignment of a component with
getComponentAlignment()
, which returns an
Alignment
object. The class provides a number of
getter methods for decoding the alignment, which you can also get as a
bitmask value.
The VerticalLayout
,
HorizontalLayout
, and
GridLayout
layouts offer a
setSpacing()
method for enabling space between
the cells in the layout. Enabling the spacing adds a spacing style for all
cells except the first.
To enable spacing, simply call setSpacing(true)
for the layout as follows:
HorizontalLayout layout2 = new HorizontalLayout(); layout2.addStyleName("spacingexample"); layout2.setSpacing(true); layout2.addComponent(new Button("Component 1")); layout2.addComponent(new Button("Component 2")); layout2.addComponent(new Button("Component 3")); VerticalLayout layout4 = new VerticalLayout(); layout4.addStyleName("spacingexample"); layout4.setSpacing(true); layout4.addComponent(new Button("Component 1")); layout4.addComponent(new Button("Component 2")); layout4.addComponent(new Button("Component 3"));
Enabling the spacing adds spacing style names to all the cells except the
first one (on left or top), thereby allowing setting of amount of spacing
between the cells. Spacing can be horizontal (for
HorizontalLayout
) or vertical (for
VerticalLayout
), or both for
GridLayout
. The name of the spacing style is the
base name of the component style name plus
"-spacing-on
" for horizontal and vertical spacing,
respectively, as shown in the following table:
Table 5.3. Spacing Style Names
VerticalLayout | i-orderedlayout-spacing-on |
HorizontalLayout | i-orderedlayout-spacing-on |
GridLayout | i-gridlayout-spacing-on |
Below we specify the exact amount of spacing for the code example given
above, for the elements with the "spacingexample
" style
name:
/* Set horizontal cell spacing in specific layout with "spacingexample" style. */ .i-orderedlayout-spacingexample .i-orderedlayout-spacing-on { padding-left: 30px; } /* Set vertical cell spacing in specific layout with "spacingexample" style. */ .i-orderedlayout-spacingexample .i-orderedlayout-spacing-on { margin-top: 30px; /* Set vertical and horizontal cell spacing in specific gridlayout with "spacingexample" style. */ .i-gridlayout-spacingexample .i-gridlayout-spacing-on { margin-top: 30px; margin-left: 50px; }
The resulting layouts will look as shown in Figure 5.10, “Layout Spacings” below, which also shows the layouts with no spacing.
Spacing is unrelated to "cell spacing" in HTML tables. While many
layout components are implemented with HTML tables in the browser,
this implementation is not guaranteed to stay the same and at least
Vertical
-/HorizontalLayout
could be implemented with <div>
elements as
well. In fact, as GWT compiles widgets separately for different
browsers, the implementation could even vary between browsers.
By default, layout components do not have any margin around them. You can add margin with CSS directly to the layout component. Below we set margins for a specific layout component:
layout1.addStyleName("marginexample1");
.i-orderedlayout-marginexample1 .i-orderedlayout-margin { padding-left: 200px; } .i-orderedlayout-marginexample1 .i-orderedlayout-margin { padding-right: 100px; } .i-orderedlayout-marginexample1 .i-orderedlayout-margin { padding-top: 50px; } .i-orderedlayout-marginexample1 .i-orderedlayout-margin { padding-bottom: 25px; }
In addition to pure CSS method, you can enable margin around the layout
with setMargin(true)
. The margin element has some
default margin widths, but you can adjust the widths in CSS if you need
to.
Let us consider the following example, where we enable the margin on all sides of the layout:
// Create a layout HorizontalLayout layout2 = new HorizontalLayout(); containinglayout.addComponent(new Label("Layout with margin on all sides:")); containinglayout.addComponent(layout2); // Set style name for the layout to allow styling it layout2.addStyleName("marginexample"); // Have margin on all sides around the layout layout2.setMargin(true); // Put something inside the layout layout2.addComponent(new Label("Cell 1")); layout2.addComponent(new Label("Cell 2")); layout2.addComponent(new Label("Cell 3"));
You can enable the margins only for specific sides. The margins are
specified for the setMargin()
method in clockwise
order for top, right, bottom, and left margin. The following would enable
the top and left margins:
layout2.setMargin(true, false, false, true);
You can specify the actual margin widths in the CSS if you are not satisfied with the default widths:
.i-orderedlayout-marginexample .i-orderedlayout-margin-left {padding-left: 200px;} .i-orderedlayout-marginexample .i-orderedlayout-margin-right {padding-right: 100px;} .i-orderedlayout-marginexample .i-orderedlayout-margin-top {padding-top: 50px; } .i-orderedlayout-marginexample .i-orderedlayout-margin-bottom {padding-bottom: 25px; }
The resulting margins are shown in Figure 5.11, “Layout Margins” below. The two ways produce identical margins.
The CSS style names for the margin widths for
setMargin()
consist of the specific layout
name plus -margin-left
and so on. Below, the style
rules are given for VerticalLayout
:
.i-orderedlayout-margin-left {padding-left: ___px;} .i-orderedlayout-margin-right {padding-right: ___px;} .i-orderedlayout-margin-top {padding-top: ___px;} .i-orderedlayout-margin-bottom {padding-bottom: ___px;}