The SplitPanel chapter still uses a Tree in its example.
for (String caption: tabs) {
String basename = "img/planets/" + caption;
VerticalLayout tab = new VerticalLayout();
- tab.addComponent(new Embedded(null,
+ tab.addComponent(new Image(null,
new ThemeResource(basename + ".jpg")));
accordion.addTab(tab, caption,
new ThemeResource(basename + "_symbol.png"));
[[layout.csslayout.compatibility]]
== Browser Compatibility
-The stregth of the [classname]#CssLayout# is also its weakness. Much of the
-logic behind the other layout components is there to give nice default behaviour
-and to handle the differences in different browsers. Some browsers, no need to
-say which, are notoriously incompatible with the CSS standards, so they require
-a lot of custom CSS. You may need to make use of the browser-specific style
-classes in the root element of the application.
+The strength of the [classname]#CssLayout# is also its weakness. Much of the
+logic behind the other layout components is there to give nice default behavior
+and to handle the differences in different browsers. With [classname]#CssLayout#,
+you may need to make use of the browser-specific style classes in the root
+element of the application to write browser specific CSS rules.
// TODO: ... described in <<advanced.browserinfo>>
Some features in the other layouts are not even solvable in pure CSS, at least
in all browsers.
as Adobe Dreamweaver.
A template is a HTML file located under [filename]#layouts# folder under a theme
-folder under the [filename]#WebContent/VAADIN/themes/# folder, for example,
-[filename]#WebContent/VAADIN/themes/__themename/layouts/mylayout.html__#.
-(Notice that the root path [filename]#WebContent/VAADIN/themes/# for themes is
+folder under the [filename]#/VAADIN/themes/# folder, for example,
+[filename]#/VAADIN/themes/__themename/layouts/mylayout.html__#.
+(Notice that the root path [filename]#/VAADIN/themes/# for themes is
fixed.) A template can also be provided dynamically from an
[classname]#InputStream#, as explained below. A template includes
[literal]#++<div>++# elements with a [parameter]#location# attribute that
FormLayout form = new FormLayout();
TextField tf1 = new TextField("Name");
tf1.setIcon(FontAwesome.USER);
-tf1.setRequired(true);
-tf1.addValidator(new NullValidator("Must be given", false));
+tf1.setRequiredIndicatorVisible(true);
form.addComponent(tf1);
TextField tf2 = new TextField("Street address");
TextField tf3 = new TextField("Postal code");
tf3.setIcon(FontAwesome.ENVELOPE);
-tf3.addValidator(new IntegerRangeValidator("Doh!", 1, 99999));
form.addComponent(tf3);
+// normally comes from validation by Binder
+tf3.setComponentError(new UserError("Doh!"));
----
-The resulting layout will look as follows. The error message shows in a tooptip
+The resulting layout will look as follows. The error message shows in a tooltip
when you hover the mouse pointer over the error indicator.
[[figure.layout.formlayout]]
[source, java]
----
GridLayout grid = new GridLayout(3,2);
-ifdef::web[]
// Layout containing relatively sized components must have
// a defined size, here is fixed size.
grid.setWidth("600px");
label.setWidth(null); // Set width as undefined
grid.addComponent(label);
}
-endif::web[]
// Set different expansion ratios for the two columns
grid.setColumnExpandRatio(1, 1);
grid.setColumnExpandRatio(2, 5);
// Set the bottom row to expand
grid.setRowExpandRatio(1, 1);
-ifdef::web[]
// Align and size the labels.
for (int col=0; col<grid.getColumns(); col++) {
for (int row=0; row<grid.getRows(); row++) {
c.setHeight("100%");
}
}
-endif::web[]
----
[[figure.ui.gridlayout.sizing.expanding]]
vertical.addComponent(new TextField("Postal code"));
layout.addComponent(vertical);
----
-See the http://demo.vaadin.com/book-examples-vaadin7/book#layout.orderedlayout.basic[on-line example, window="_blank"].
In [classname]#VerticalLayout#, the captions of child components are placed above each component, so the layout would look as follows:
image::img/orderedlayout_horizontal.png[width=80%, scaledwidth=100%]
-ifdef::web[]
[[layout.orderedlayout.declarative]]
== Declarative Format
|===============
|Component|Element Name
-|[classname]#VerticalLayout#|[elementname]#v-verticallayout#
-|[classname]#HorizontalLayout#|[elementname]#v-horizontallayout#
-|[classname]#FormLayout#|[elementname]#v-formlayout#
+|[classname]#VerticalLayout#|[elementname]#v-vertical-layout#
+|[classname]#HorizontalLayout#|[elementname]#v-horizontal-layout#
+|[classname]#FormLayout#|[elementname]#v-form-layout#
|===============
The have the following declarative attributes:
</v-horizontal-layout>
</v-vertical-layout>
----
-endif::web[]
[[layout.orderedlayout.spacing]]
== Spacing in Ordered Layouts
The ordered layouts can have spacing between the horizontal or vertical cells.
-The spacing can be enabled with [methodname]#setSpacing(true)# or declaratively
-with the [literal]#++spacing++# attribute.
+Spacing is enabled by default, and can be disabled with [methodname]#setSpacing(false)# or declaratively
+with the [literal]#++spacing="false"++# attribute.
-The spacing as a default height or width, which can be customized in CSS. You
+The spacing has a default height or width, which can be customized in CSS. You
need to set the height or width for spacing elements with
[literal]#++v-spacing++# style. You also need to specify an enclosing rule
element in a CSS selector, such as [literal]#++v-verticallayout++# for a
image::img/horizontallayout_sizing.png[width=75%, scaledwidth=100%]
<<figure.layout.orderedlayout.size.summary>> gives a summary of the sizing
-options for a [classname]#HorizontalLayout#. The figure is broken down in the
-following subsections.
+options for a [classname]#HorizontalLayout# with spacing disabled.
+The figure is broken down in the following subsections.
[[layout.orderedlayout.sizing.undefined]]
=== Layout with Undefined Size
If a [classname]#VerticalLayout# has undefined height or
[classname]#HorizontalLayout# undefined width, the layout will shrink to fit the
-contained components so that there is no extra space between them.
+contained components so that there is no extra space between them (apart from
+optional spacing).
[source, java]
----
HorizontalLayout fittingLayout = new HorizontalLayout();
fittingLayout.setWidth(Sizeable.SIZE_UNDEFINED, 0); // Default
+fittingLayout.setSpacing(false); // Compact layout
fittingLayout.addComponent(new Button("Small"));
fittingLayout.addComponent(new Button("Medium-sized"));
fittingLayout.addComponent(new Button("Quite a big component"));
layout, removing the paradox. That size is then used for the relatively sized
components.
-ifdef::web[]
The technique can be used to define the width of a [classname]#VerticalLayout#
or the height of a [classname]#HorizontalLayout#.
butt.setWidth("100%");
vertical.addComponent(butt);
----
-See the http://demo.vaadin.com/book-examples-vaadin7/book#layout.orderedlayout.sizing.sizing-undefined-defining[on-line example, window="_blank"].
[[figure.layout.orderedlayout.sizing.undefined.defining]]
.Defining the Size with a Component
image::img/orderedlayout-sizing-undefined.png[width=50%, scaledwidth=75%]
-endif::web[]
[[layout.orderedlayout.defined-size]]
=== Layout with Defined Size
fixedLayout.setWidth("400px");
----
-Using percentual sizes for components contained in a layout requires answering
-the question, "Percentage of what?" There is no sensible default answer for this
-question in the current implementation of the layouts, so in practice, you may
-not define "100%" size alone.
-
[[layout.orderedlayout.expanding]]
=== Expanding Components
<vaadin-label>The Ultimate Cat Finder</vaadin-label>
<vaadin-horizontal-layout>
- <vaadin-tree caption="Possible Places"/>
+ <vaadin-radio-button-group caption="Possible Places"/>
<vaadin-panel/>
...
</vaadin-horizontal-layout>
(((range="endofrange", startref="term.layout.panel.scrolling.scrollbars")))
-ifdef::web[]
[[layout.panel.css]]
== CSS Style Rules
[literal]#++v-panel-deco++#, respectively. If the panel has no caption, the
caption element will have the style [literal]#++v-panel-nocaption++#.
-The built-in [literal]#++light++# style in the Reindeer and Runo themes has no
+The built-in [literal]#++borderless++# style in the Valo theme has no
borders or border decorations for the [classname]#Panel#. You can use the
-[parameter]#Reindeer.PANEL_LIGHT# and [parameter]#Runo.PANEL_LIGHT# constants to
-add the style to a panel. Other themes may also provide the light and other
-styles for [classname]#Panel# as well.
-
-endif::web[]
+[parameter]#ValoTheme.PANEL_BORDERLESS# constant to
+add the style to a panel.
\ No newline at end of file
[classname]#GridLayout# has corresponding method for both of its directions,
[methodname]#setRowExpandRatio()# and [methodname]#setColumnExpandRatio()#.
-Expansion is dealt in detail in the documentation of the layout components that
+Expansion is covered in detail in the documentation of the layout components that
support it. See
<<dummy/../../../framework/layout/layout-orderedlayout#layout.orderedlayout,"VerticalLayout
and HorizontalLayout">> and
=== 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 many components have
+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]#Label# is 100% wide by default and can not therefore be horizontally
-aligned as such. The problem can be hard to notice, as the text inside a
-[classname]#Label# is left-aligned.
+[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.
-For example, assuming that a [classname]#Label# has short content that is less
-wide than the containing [classname]#VerticalLayout#, you could center it as
-follows:
-
-
-[source, java]
-----
-VerticalLayout layout = new VerticalLayout(); // 100% default width
-Label label = new Label("Hello"); // 100% default width
-label.setSizeUndefined();
-layout.addComponent(label);
-layout.setComponentAlignment(label, Alignment.MIDDLE_CENTER);
-----
-
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. For example, if you set the size of a [classname]#Form# as undefined, its
-containing layout [classname]#FormLayout# has 100% default width, which you also
-need to set as undefined. But then, any components inside the
-[classname]#FormLayout# must have either undefined or fixed size.
+size.
(((range="endofrange", startref="term.alignment")))
The [classname]#VerticalLayout#, [classname]#HorizontalLayout#, and
[classname]#GridLayout# layouts offer a [methodname]#setSpacing()# method to
-enable spacing between the cells of the layout.
+enable or disable spacing between the cells of the layout.
For example:
[source, java]
----
VerticalLayout layout = new VerticalLayout();
-layout.setSpacing(true);
+layout.setSpacing(false);
layout.addComponent(new Button("Component 1"));
layout.addComponent(new Button("Component 2"));
layout.addComponent(new Button("Component 3"));
[[layout.settings.margins]]
== Layout Margins
-Most layout components do not have any margin around them by default. The
-ordered layouts, as well as [classname]#GridLayout#, support enabling a margin
-with [methodname]#setMargin()#. This enables CSS classes for each margin in the
+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
[methodname]#setSecondComponent()# methods, or with the regular
[methodname]#addComponent()# method.
+// TODO replace Tree with something else in the example code and screenshot
[source, java]
----
vsplit.addComponent(new Label("Here's the upper panel"));
vsplit.addComponent(new Label("Here's the lower panel"));
----
-See the http://demo.vaadin.com/book-examples-vaadin7/book#layout.splitpanel.basic[on-line example, window="_blank"].
The result is shown in <<figure.splitpanel.basic>>. Observe that the tree is cut
horizontally as it can not fit in the layout. If its height exceeds the height
// Set the position of the splitter as percentage
hsplit.setSplitPosition(75, Sizeable.UNITS_PERCENTAGE);
----
-See the http://demo.vaadin.com/book-examples-vaadin7/book#layout.splitpanel.splitposition[on-line example, window="_blank"].
Another version of the [methodname]#setSplitPosition()# method allows leaving
out the unit, using the same unit as previously. The method also has versions
// Lock the splitter
hsplit.setLocked(true);
----
-See the http://demo.vaadin.com/book-examples-vaadin7/book#layout.splitpanel.splitposition[on-line example, window="_blank"].
Setting the split position programmatically and locking the split bar is
illustrated in <<figure.component.splitpanel.splitposition>>.
// Create a sub-window and set the content
Window subWindow = new Window("Sub-window");
VerticalLayout subContent = new VerticalLayout();
- subContent.setMargin(true);
subWindow.setContent(subContent);
// Put some components in it
[guibutton]#OK# or [guibutton]#Cancel# button. You can also call
[methodname]#removeWindow()# for the current [classname]#UI#.
-ifdef::web[]
[[layout.sub-window.openclose.example]]
=== Sub-Window Management
super("Subs on Sale"); // Set window caption
center();
- // Some basic content for the window
- VerticalLayout content = new VerticalLayout();
- content.addComponent(new Label("Just say it's OK!"));
- content.setMargin(true);
- setContent(content);
-
// Disable the close button
setClosable(false);
- // Trivial logic for closing the sub-window
- Button ok = new Button("OK");
- ok.addClickListener(new ClickListener() {
- public void buttonClick(ClickEvent event) {
- close(); // Close the sub-window
- }
- });
- content.addComponent(ok);
+ setContent(new Button("Close me", event -> close()));
}
}
----
----
// Some UI logic to open the sub-window
final Button open = new Button("Open Sub-Window");
-open.addClickListener(new ClickListener() {
- public void buttonClick(ClickEvent event) {
- MySub sub = new MySub();
+open.addClickListener(event -> {
+ MySub sub = new MySub();
- // Add it to the root component
- UI.getCurrent().addWindow(sub);
- }
+ // Add it to the root component
+ UI.getCurrent().addWindow(sub);
});
----
-endif::web[]
-
[[layout.sub-window.position]]
== Window Positioning
// Create the first tab
VerticalLayout tab1 = new VerticalLayout();
-tab1.addComponent(new Embedded(null,
+tab1.addComponent(new Image(null,
new ThemeResource("img/planets/Mercury.jpg")));
tabsheet.addTab(tab1, "Mercury",
new ThemeResource("img/planets/Mercury_symbol.png"));
// This tab gets its caption from the component caption
VerticalLayout tab2 = new VerticalLayout();
-tab2.addComponent(new Embedded(null,
+tab2.addComponent(new Image(null,
new ThemeResource("img/planets/Venus.jpg")));
tab2.setCaption("Venus");
tabsheet.addTab(tab2).setIcon(
tab bar entirely. This can be useful in tabbed document interfaces (TDI) when
there is only one tab.
-ifdef::web[]
-[[figure.tabsheet.example2]]
-.A TabSheet with Hidden and Disabled Tabs
-image::img/tabsheet-example2.png[width=50%, scaledwidth=70%]
-endif::web[]
-
[[layout.tabsheet.events]]
== Tab Change Events
fired, so if you want to catch that, you need to add your listener before adding
any tabs.
-ifdef::web[]
[[layout.tabsheet.events.dynamic]]
=== Creating Tab Content Dynamically
new ThemeResource("img/planets/"+caption+"_symbol.png"));
----
-endif::web[]
-
[[layout.tabsheet.closing]]
== Enabling and Handling Closing Tabs
-ifdef::web[]
[[layout.tabsheet.css]]
== CSS Style Rules
The content area where the tab contents are shown can be styled with
[literal]#++v-tabsheet-content++#, and the surrounding decoration with
[literal]#++v-tabsheet-deco++#.
-
-endif::web[]