summaryrefslogtreecommitdiffstats
path: root/documentation/layout/layout-settings.asciidoc
blob: 97edabd9b91b9728a3194cded4565afe926e229f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
---
title: Layout Formatting
order: 13
layout: page
---

[[layout.settings]]
= Layout Formatting

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 [parameter]#cellspacing# attribute in HTML.

Moreover, as many layout sizes are calculated dynamically in the Client-Side
Engine of Vaadin, some CSS settings can fail altogether.

[[layout.settings.size]]
== Layout Size

The size of a layout component can be specified with the
[methodname]#setWidth()# and [methodname]#setHeight()# methods defined in the
[classname]#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.
<<../components/components-features#components.features.sizeable,"Sizing
Components">> gives details on the interface.

[[figure.layout.settings.size.undefined]]
.[classname]#HorizontalLayout# with Undefined vs Defined size
image::img/layout_size_undefined_vs_defined.png[]

Many layout components take 100% width by default, while they 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
[methodname]#setWidth("100%");# or with the (most commonly used method)
[methodname]#setFullSize()# that sets 100% size in both directions. If you use a
percentage in a [classname]#HorizontalLayout#, [classname]#VerticalLayout#, or
[classname]#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 a contained component has, say, 100% size,
the component will try to fill the space given by the layout, while the layout
will 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
<<../advanced/advanced-debug#advanced.debug.hierarchy,"Inspecting
Component Hierarchy">>.

====



For example:


[source, java]
----
// 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%");
----

If you have a layout with undefined height, such as [classname]#VerticalLayout#,
in a [classname]#UI#, [classname]#Window#, or [classname]#Panel#, and put enough
content in it so that it extends outside the bottom of the view area, scrollbars
will appear. If you want your application to use all the browser view, nothing
more or less, you should use [methodname]#setFullSize()# for the root layout.


[source, java]
----
// Create the UI content
VerticalLayout content = new VerticalLayout();

// Use entire view area
content.setSizeFull();

setContent(content);
----


[[layout.settings.size.expanding]]
== Expanding Components

If you set a [classname]#HorizontalLayout# to a defined size horizontally or a
[classname]#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 one or more components to take
all the leftover space. You need to set such a component to 100% size and use
[methodname]#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.

[classname]#GridLayout# has corresponding method for both of its directions,
[methodname]#setRowExpandRatio()# and [methodname]#setColumnExpandRatio()#.

Expansion is covered in detail in the documentation of the layout components that
support it. See
<<layout-orderedlayout#layout.orderedlayout,"VerticalLayout
and HorizontalLayout">> and
<<layout-gridlayout#layout.gridlayout,"GridLayout">>
for details on components with relative sizes.


[[layout.settings.alignment]]
== Layout Cell Alignment

((("Alignment", id="term.alignment", range="startofrange")))


((("[methodname]#setComponentAlignment()#", id="term.setcomponentalignment", range="startofrange")))


When a component in a layout cell has size (width or height) smaller than the
size of the cell, it will by default be aligned in the top-left corner of the
cell. You can set the alignment with the [methodname]#setComponentAlignment()#
method. The method takes as its parameters the component contained in the cell
to be formatted, and the horizontal and vertical alignment. The component must
have been added to the layout before setting the alignment.

<<figure.layout.settings.alignment>> illustrates the alignment of components
within a [classname]#GridLayout#.

[[figure.layout.settings.alignment]]
.Cell Alignments
image::img/layout_alignment.png[]

Note that __a component with 100% relative size can not be aligned__, as it will
take the entire width or height of the cell, in which case alignment is
meaningless. This should especially be noted with the [classname]#Label#
component, which has 100% default width, and the text alignment __within__ the
component is separate, defined by the CSS [literal]#++text-align++# property.

The easiest way to set alignments is to use the constants defined in the
[classname]#Alignment# class. Let us look how the buttons in the top row of the
above [classname]#GridLayout# are aligned with constants:


[source, java]
----
// Create a grid layout
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 [classname]#Alignment# constants by their
respective locations:

.Alignment Constants

|===============
|[parameter]#TOP_LEFT#|[parameter]#TOP_CENTER#|[parameter]#TOP_RIGHT#
|[parameter]#MIDDLE_LEFT#|[parameter]#MIDDLE_CENTER#|[parameter]#MIDDLE_RIGHT#
|[parameter]#BOTTOM_LEFT#|[parameter]#BOTTOM_CENTER#|[parameter]#BOTTOM_RIGHT#

|===============



Another way to specify the alignments is to create an [classname]#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.


[source, java]
----
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:

.Alignment Bitmasks

|===============
|Horizontal|[parameter]#Bits.ALIGNMENT_LEFT#
|[parameter]#Bits.ALIGNMENT_HORIZONTAL_CENTER#
|[parameter]#Bits.ALIGNMENT_RIGHT#
|Vertical|[parameter]#Bits.ALIGNMENT_TOP#
|[parameter]#Bits.ALIGNMENT_VERTICAL_CENTER#
|[parameter]#Bits.ALIGNMENT_BOTTOM#

|===============



You can determine the current alignment of a component with
[methodname]#getComponentAlignment()#, which returns an [classname]#Alignment#
object. The class provides a number of getter methods for decoding the
alignment, which you can also get as a bitmask value.

[[layout.settings.alignment.size]]
=== Size of Aligned Components

You can only align a component that is smaller than its containing cell in the
direction of alignment. If a component has 100% width, as some components have
by default, horizontal alignment does not have any effect. For example,
[classname]#VerticalLayout# is 100% wide by default and can not therefore be horizontally
aligned as such. The problem can sometimes be hard to notice, as the content inside a
[classname]#VerticalLayout# is left-aligned by default.

You usually need to set either a fixed size, undefined size, or less than a 100%
relative size for the component to be aligned - a size that is smaller than the
containing layout has.

If you set the size as undefined and the component itself contains components,
make sure that the contained components also have either undefined or fixed
size.


(((range="endofrange", startref="term.alignment")))
(((range="endofrange", startref="term.setcomponentalignment")))

[[layout.settings.spacing]]
== Layout Cell Spacing

The [classname]#VerticalLayout#, [classname]#HorizontalLayout#, and
[classname]#GridLayout# layouts offer a [methodname]#setSpacing()# method to
enable or disable spacing between the cells of the layout.

For example:


[source, java]
----
VerticalLayout layout = new VerticalLayout();
layout.setSpacing(false);
layout.addComponent(new Button("Component 1"));
layout.addComponent(new Button("Component 2"));
layout.addComponent(new Button("Component 3"));
----

The effect of spacing in [classname]#VerticalLayout# and
[classname]#HorizontalLayout# is illustrated in <<figure.layout.spacing>>.

[[figure.layout.spacing]]
.Layout Spacings
image::img/layout_spacing.png[]

The exact amount of spacing is defined in CSS. If the default is not suitable,
you can customize it in a custom theme.

In the Valo theme, you can specify the spacing with the
$v-layout-spacing-vertical and $v-layout-spacing-horizontal parameters, as
described in
<<../themes/themes-valo#themes.valo.variables,"Common
Settings">>. The spacing defaults to the $v-unit-size measure.

When adjusting spacing in other themes, you should note that it is implemented
in a bit different ways in different layouts. In the ordered layouts, it is done
with spacer elements, while in the [classname]#GridLayout# it has special
handling. Please see the sections on the individual components for more details.


[[layout.settings.margins]]
== Layout Margins

Most layout components (with the exception of [classname]#VerticalLayout#) do
not have any margin around them by default. The ordered layouts, as well as
[classname]#GridLayout#, support enabling or disabling a margin with
[methodname]#setMargin()#. This enables CSS classes for each margin in the
HTML element of the layout component.

In the Valo theme, the margin sizes default to $v-unit-size. You can customize
them with $v-layout-margin-top, right, bottom, and left. See
<<../themes/themes-valo#themes.valo.variables,"Common
Settings">> for a description of the parameters.

To customize the default margins in other themes, you can define each margin
with the [literal]#++padding++# property in CSS. You may want to have a custom
CSS class for the layout component to enable specific customization of the
margins, as is done in the following with the [literal]#++mymargins++# class:

[subs="normal"]
----

.**mymargins**.v-margin-left   {padding-left:   **10**px;}
.**mymargins**.v-margin-right  {padding-right:  **20**px;}
.**mymargins**.v-margin-top    {padding-top:    **40**px;}
.**mymargins**.v-margin-bottom {padding-bottom: **80**px;}
----
You can enable only specific margins by passing a [classname]#MarginInfo# to the
[methodname]#setMargin()#. The margins are specified in clockwise order for top,
right, bottom, and left margin. The following would enable the left and right
margins:


[source, java]
----
layout.setMargin(new MarginInfo(false, true, false, true));
----

The resulting margins are shown in <<figure.layout.margin>> below. The two ways
produce identical margins.

[[figure.layout.margin]]
.Layout Margins
image::img/layout_margin.png[]