---
title: TabSheet
order: 9
layout: page
---

[[layout.tabsheet]]
= 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[width=50%, scaledwidth=70%]

[[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 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 Image(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.


[[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.

[[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"));
----


[[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[width=50%, scaledwidth=70%]

[[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);
    }
});
----



[[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++#.
'>plain</a>)
<table summary='blob content' class='blob'>
<tr><td class='linenumbers'><pre><a id='n1' href='#n1'>1</a>
<a id='n2' href='#n2'>2</a>
<a id='n3' href='#n3'>3</a>
<a id='n4' href='#n4'>4</a>
<a id='n5' href='#n5'>5</a>
<a id='n6' href='#n6'>6</a>
<a id='n7' href='#n7'>7</a>
<a id='n8' href='#n8'>8</a>
<a id='n9' href='#n9'>9</a>
<a id='n10' href='#n10'>10</a>
<a id='n11' href='#n11'>11</a>
<a id='n12' href='#n12'>12</a>
<a id='n13' href='#n13'>13</a>
<a id='n14' href='#n14'>14</a>
<a id='n15' href='#n15'>15</a>
<a id='n16' href='#n16'>16</a>
<a id='n17' href='#n17'>17</a>
<a id='n18' href='#n18'>18</a>
<a id='n19' href='#n19'>19</a>
<a id='n20' href='#n20'>20</a>
<a id='n21' href='#n21'>21</a>
<a id='n22' href='#n22'>22</a>
<a id='n23' href='#n23'>23</a>
<a id='n24' href='#n24'>24</a>
<a id='n25' href='#n25'>25</a>
<a id='n26' href='#n26'>26</a>
<a id='n27' href='#n27'>27</a>
<a id='n28' href='#n28'>28</a>
<a id='n29' href='#n29'>29</a>
<a id='n30' href='#n30'>30</a>
<a id='n31' href='#n31'>31</a>
<a id='n32' href='#n32'>32</a>
<a id='n33' href='#n33'>33</a>
<a id='n34' href='#n34'>34</a>
<a id='n35' href='#n35'>35</a>
<a id='n36' href='#n36'>36</a>
<a id='n37' href='#n37'>37</a>
<a id='n38' href='#n38'>38</a>
<a id='n39' href='#n39'>39</a>
<a id='n40' href='#n40'>40</a>
<a id='n41' href='#n41'>41</a>
<a id='n42' href='#n42'>42</a>
<a id='n43' href='#n43'>43</a>
<a id='n44' href='#n44'>44</a>
<a id='n45' href='#n45'>45</a>
<a id='n46' href='#n46'>46</a>
<a id='n47' href='#n47'>47</a>
<a id='n48' href='#n48'>48</a>
<a id='n49' href='#n49'>49</a>
<a id='n50' href='#n50'>50</a>
<a id='n51' href='#n51'>51</a>
<a id='n52' href='#n52'>52</a>
<a id='n53' href='#n53'>53</a>
</pre></td>
<td class='lines'><pre><code>