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
|
---
title: TabSheet
order: 9
layout: page
---
[[layout.tabsheet]]
= [classname]#TabSheet#
ifdef::web[]
[.sampler]
image:{live-demo-image}[alt="Live Demo", link="http://demo.vaadin.com/sampler/#ui/structure/tab-sheet"]
endif::web[]
The [classname]#TabSheet# is a multicomponent container that allows switching
between the components with "tabs". The tabs are organized as a tab bar at the
top of the tab sheet. Clicking on a tab opens its contained component in the
main display area of the layout. If there are more tabs than fit in the tab bar,
navigation buttons will appear.
[[figure.tabsheet.example1]]
.A Simple TabSheet Layout
image::img/tabsheet-example1.png[]
[[layout.tabsheet.adding]]
== Adding Tabs
You add new tabs to a tab sheet with the [methodname]#addTab()# method. The
simple version of the method takes as its parameter the root component of the
tab. You can use the root component to retrieve its corresponding
[classname]#Tab# object. Typically, you put a layout component as the root
component.
You can also give the caption and the icon as parameters for the
[methodname]#addTab()# method. The following example demonstrates the creation
of a simple tab sheet, where each tab shows a different [classname]#Label#
component. The tabs have an icon, which are (in this example) loaded as Java
class loader resources from the application.
[source, java]
----
TabSheet tabsheet = new TabSheet();
layout.addComponent(tabsheet);
// Create the first tab
VerticalLayout tab1 = new VerticalLayout();
tab1.addComponent(new Embedded(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,
new ThemeResource("img/planets/Venus.jpg")));
tab2.setCaption("Venus");
tabsheet.addTab(tab2).setIcon(
new ThemeResource("img/planets/Venus_symbol.png"));
...
----
[[layout.tabsheet.tab]]
== Tab Objects
Each tab in a tab sheet is represented as a [classname]#Tab# object, which
manages the tab caption, icon, and attributes such as hidden and visible. You
can set the caption with [methodname]#setCaption()# and the icon with
[methodname]#setIcon()#. If the component added with [methodname]#addTab()# has
a caption or icon, it is used as the default for the [classname]#Tab# object.
However, changing the attributes of the root component later does not affect the
tab, but you must make the setting through the [classname]#Tab# object. The
[methodname]#addTab()# returns the new [classname]#Tab# object, so you can
easily set an attribute using the reference.
[source, java]
----
// Set an attribute using the returned reference
tabsheet.addTab(myTab).setCaption("My Tab");
----
[[layout.tabsheet.tab.disabling]]
=== Disabling and Hiding Tabs
A tab can be disabled by setting [methodname]#setEnabled(false)# for the
[classname]#Tab# object, thereby disallowing selecting it.
A tab can be made invisible by setting [methodname]#setVisible(false)# for the
[classname]#Tab# object. The [methodname]#hideTabs()# method allows hiding the
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[]
endif::web[]
[[layout.tabsheet.events]]
== Tab Change Events
Clicking on a tab selects it. This fires a
[classname]#TabSheet.SelectedTabChangeEvent#, which you can handle by
implementing the [classname]#TabSheet.SelectedTabChangeListener# interface. You
can access the tabsheet of the event with [methodname]#getTabSheet()#, and find
the new selected tab with [methodname]#getSelectedTab()#.
You can programmatically select a tab with [methodname]#setSelectedTab()#, which
also fires the [classname]#SelectedTabChangeEvent# (beware of recursive events).
Reselecting the currently selected tab does not fire the event.
Notice that when the first tab is added, it is selected and the change event is
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
In the following example, we create the tabs as empty content layouts, and add
the tab content dynamically when a tab is selected:
[source, java]
----
TabSheet tabsheet = new TabSheet();
// Create tab content dynamically when tab is selected
tabsheet.addSelectedTabChangeListener(
new TabSheet.SelectedTabChangeListener() {
public void selectedTabChange(SelectedTabChangeEvent event) {
// Find the tabsheet
TabSheet tabsheet = event.getTabSheet();
// Find the tab (here we know it's a layout)
Layout tab = (Layout) tabsheet.getSelectedTab();
// Get the tab caption from the tab object
String caption = tabsheet.getTab(tab).getCaption();
// Fill the tab content
tab.removeAllComponents();
tab.addComponent(new Image(null,
new ThemeResource("img/planets/"+caption+".jpg")));
}
});
// Have some tabs
String[] tabs = {"Mercury", "Venus", "Earth", "Mars"};
for (String caption: tabs)
tabsheet.addTab(new VerticalLayout(), caption,
new ThemeResource("img/planets/"+caption+"_symbol.png"));
----
endif::web[]
[[layout.tabsheet.closing]]
== Enabling and Handling Closing Tabs
You can enable a close button for individual tabs with the
[literal]#++closable++# property in the [classname]#TabSheet.Tab# objects.
[source, java]
----
// Enable closing the tab
tabsheet.getTab(tabComponent).setClosable(true);
----
[[figure.layout.tabsheet.closing]]
.TabSheet with Closable Tabs
image::img/tabsheet-tabclose.png[]
[[layout.tabsheet.closing.handling]]
=== Handling Tab Close Events
You can handle closing tabs by implementing a custom
[classname]#TabSheet.CloseHandler#. The default implementation simply calls
[methodname]#removeTab()# for the tab to be closed, but you can prevent the
close by not calling it. This allows, for example, opening a dialog window to
confirm the close.
[source, java]
----
tabsheet.setCloseHandler(new CloseHandler() {
@Override
public void onTabClose(TabSheet tabsheet,
Component tabContent) {
Tab tab = tabsheet.getTab(tabContent);
Notification.show("Closing " + tab.getCaption());
// We need to close it explicitly in the handler
tabsheet.removeTab(tab);
}
});
----
ifdef::web[]
[[layout.tabsheet.css]]
== CSS Style Rules
[source, css]
----
.v-tabsheet {}
.v-tabsheet-tabs {}
.v-tabsheet-content {}
.v-tabsheet-deco {}
.v-tabsheet-tabcontainer {}
.v-tabsheet-tabsheetpanel {}
.v-tabsheet-hidetabs {}
.v-tabsheet-scroller {}
.v-tabsheet-scrollerPrev {}
.v-tabsheet-scrollerNext {}
.v-tabsheet-scrollerPrev-disabled{}
.v-tabsheet-scrollerNext-disabled{}
.v-tabsheet-tabitem {}
.v-tabsheet-tabitem-selected {}
.v-tabsheet-tabitemcell {}
.v-tabsheet-tabitemcell-first {}
.v-tabsheet-tabs td {}
.v-tabsheet-spacertd {}
----
The entire tabsheet has the [literal]#++v-tabsheet++# style. A tabsheet consists
of three main parts: the tabs on the top, the main content pane, and decorations
around the tabsheet.
The tabs area at the top can be styled with [literal]#++v-tabsheet-tabs++#,
[literal]#++v-tabsheet-tabcontainer++# and [literal]#++v-tabsheet-tabitem*++#.
The style [literal]#++v-tabsheet-spacertd++# is used for any empty space after
the tabs. If the tabsheet has too little space to show all tabs, scroller
buttons enable browsing the full tab list. These use the styles
[literal]#++v-tabsheet-scroller*++#.
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[]
|