| <?xml version="1.0" encoding="UTF-8"?> |
| <!-- |
| Licensed to the Apache Software Foundation (ASF) under one or more |
| contributor license agreements. See the NOTICE file distributed with |
| this work for additional information regarding copyright ownership. |
| The ASF licenses this file to you under the Apache License, |
| Version 2.0 (the "License"); you may not use this file except in |
| compliance with the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| --> |
| |
| <document id="tab-panes"> |
| <properties> |
| <title>Tab Panes</title> |
| <explore>TabPane</explore> |
| </properties> |
| |
| <body> |
| <p> |
| Functionally, tab panes are similar to card panes in that they show only one of a |
| collection of components at a time. Unlike card panes, tab panes include built-in |
| support for navigating between the components, which are called "tabs". The following |
| example demonstrates the use of the <tt>TabPane</tt> component: |
| </p> |
| |
| <application class="org.apache.pivot.wtk.ScriptApplication" |
| width="680" height="480"> |
| <libraries> |
| <library>core</library> |
| <library>wtk</library> |
| <library>wtk-terra</library> |
| <library>tutorials</library> |
| </libraries> |
| <startup-properties> |
| <src>/org/apache/pivot/tutorials/navigation/tab_panes.bxml</src> |
| </startup-properties> |
| </application> |
| |
| <p> |
| The BXML source that produces this example is as follows. The tab pane contains three |
| tabs, each of which are flow panes containing bordered labels at different sizes. Like |
| <tt>CardPane</tt>, the preferred size of a tab pane is the maximum of the preferred |
| widths and heights of the tabs, plus the size of the area allocated to the tab |
| navigation, and each tab is sized to fill the entire space allocated to the tabs. The |
| tab pane itself is contained in a flow pane so that changes to its preferred size are |
| easily visible. |
| </p> |
| |
| <p> |
| Note that, like the <a href="forms.html">Form</a> container, <tt>TabPane</tt> defines |
| attributes that a caller can set to customize the appearance of the tab. |
| <tt>TabPane</tt> currently defines two attributes: "label" and "icon" (additional |
| attributes may be added in the future to support closeable tabs or other such features). |
| Also note that disabling a tab component also disables its corresponding tab button, |
| preventing the user from navigating to that tab: |
| </p> |
| |
| <source type="xml" location="org/apache/pivot/tutorials/navigation/tab_panes.bxml"> |
| <![CDATA[ |
| <navigation:TabPanes title="Tab Panes" maximized="true" |
| xmlns:bxml="http://pivot.apache.org/bxml" |
| xmlns:content="org.apache.pivot.wtk.content" |
| xmlns:navigation="org.apache.pivot.tutorials.navigation" |
| xmlns="org.apache.pivot.wtk"> |
| <bxml:define> |
| <Prompt bxml:id="confirmCloseTabPrompt" title="Confirm Close Tab" |
| message="Really close this tab?" |
| options="['Cancel', 'OK']" selectedOptionIndex="1"/> |
| </bxml:define> |
| |
| <TablePane styles="{padding:8, horizontalSpacing:6}"> |
| <columns> |
| <TablePane.Column width="1*"/> |
| <TablePane.Column/> |
| </columns> |
| |
| <TablePane.Row height="1*"> |
| <Border styles="{padding:12}"> |
| <BoxPane> |
| <TabPane bxml:id="tabPane"> |
| <corner> |
| <BoxPane bxml:id="cornerBoxPane" styles="{horizontalAlignment:'right'}"> |
| <TextInput textSize="10"/> |
| </BoxPane> |
| </corner> |
| |
| <BoxPane styles="{horizontalAlignment:'center', verticalAlignment:'center'}"> |
| <TabPane.tabData> |
| <content:ButtonData icon="/org/apache/pivot/tutorials/bell.png" |
| text="Bell"/> |
| </TabPane.tabData> |
| <Border styles="{padding:2}"> |
| <Label text="240x180" preferredWidth="240" preferredHeight="180" |
| styles="{horizontalAlignment:'center', verticalAlignment:'center'}"/> |
| </Border> |
| </BoxPane> |
| |
| <BoxPane styles="{horizontalAlignment:'center', verticalAlignment:'center'}"> |
| <TabPane.tabData> |
| <content:ButtonData icon="/org/apache/pivot/tutorials/clock.png" |
| text="Clock"/> |
| </TabPane.tabData> |
| <Border styles="{padding:2}"> |
| <Label text="320x240" preferredWidth="320" preferredHeight="240" |
| styles="{horizontalAlignment:'center', verticalAlignment:'center'}"/> |
| </Border> |
| </BoxPane> |
| |
| <BoxPane styles="{horizontalAlignment:'center', verticalAlignment:'center'}"> |
| <TabPane.tabData> |
| <content:ButtonData icon="/org/apache/pivot/tutorials/house.png" |
| text="House"/> |
| </TabPane.tabData> |
| <Border styles="{padding:2}"> |
| <Label text="480x360" preferredWidth="480" preferredHeight="360" |
| styles="{horizontalAlignment:'center', verticalAlignment:'center'}"/> |
| </Border> |
| </BoxPane> |
| |
| <BoxPane enabled="false"> |
| <TabPane.tabData> |
| <content:ButtonData icon="/org/apache/pivot/tutorials/star.png" |
| text="Star"/> |
| </TabPane.tabData> |
| |
| <Border styles="{padding:2}"> |
| <Label text="480x360 (disabled)" preferredWidth="480" preferredHeight="360" |
| styles="{horizontalAlignment:'center', verticalAlignment:'center'}"/> |
| </Border> |
| </BoxPane> |
| </TabPane> |
| </BoxPane> |
| </Border> |
| |
| <Border styles="{padding:2}"> |
| <BoxPane orientation="vertical" styles="{padding:4, spacing:6}"> |
| <Checkbox bxml:id="closeableCheckbox" buttonData="Closeable"/> |
| <Checkbox bxml:id="collapsibleCheckbox" buttonData="Collapsible"/> |
| |
| <Label text="Tab orientation:"/> |
| <bxml:define> |
| <ButtonGroup bxml:id="tabOrientation"/> |
| </bxml:define> |
| <RadioButton bxml:id="horizontalRadioButton" buttonData="Horizontal" selected="true" |
| buttonGroup="$tabOrientation"/> |
| <RadioButton bxml:id="verticalRadioButton" buttonData="Vertical" |
| buttonGroup="$tabOrientation"/> |
| </BoxPane> |
| </Border> |
| </TablePane.Row> |
| </TablePane> |
| </navigation:TabPanes> |
| ]]> |
| </source> |
| |
| <p> |
| The default tab pane skin provides some styles for customizing the appearance and |
| behavior of the tab pane: "collapsible" and "tabOrientation". The "collapsible" style |
| is a boolean that controls how the tab pane responds to clicks on the tab buttons. When |
| set to <tt>true</tt>, clicking on the selected tab causes the tab pane to "collapse" |
| such that only the tab buttons remain visible. This is handy in situations where screen |
| real estate is at a premium, or when the content of the tab pane may be only |
| periodically relevant to the user but should still be conveniently accessible. The |
| "tabOrientation" style controls how the buttons themselves are laid out - either |
| horizontally or vertically. |
| </p> |
| |
| <p> |
| The Java source for this example is as follows. It is fairly simple, consisting mostly |
| of event handling code for the radio buttons and checkbox: |
| </p> |
| |
| <source type="java" location="org/apache/pivot/tutorials/navigation/TabPanes.java"> |
| <![CDATA[ |
| package org.apache.pivot.tutorials.navigation; |
| |
| import java.net.URL; |
| |
| import org.apache.pivot.beans.Bindable; |
| import org.apache.pivot.collections.Map; |
| import org.apache.pivot.util.Resources; |
| import org.apache.pivot.util.Vote; |
| import org.apache.pivot.wtk.Button; |
| import org.apache.pivot.wtk.ButtonStateListener; |
| import org.apache.pivot.wtk.Checkbox; |
| import org.apache.pivot.wtk.BoxPane; |
| import org.apache.pivot.wtk.Orientation; |
| import org.apache.pivot.wtk.Prompt; |
| import org.apache.pivot.wtk.RadioButton; |
| import org.apache.pivot.wtk.Sheet; |
| import org.apache.pivot.wtk.SheetCloseListener; |
| import org.apache.pivot.wtk.TabPane; |
| import org.apache.pivot.wtk.TabPaneListener; |
| import org.apache.pivot.wtk.Window; |
| |
| public class TabPanes extends Window implements Bindable { |
| private Prompt confirmCloseTabPrompt = null; |
| private TabPane tabPane = null; |
| private Checkbox closeableCheckbox = null; |
| private Checkbox collapsibleCheckbox = null; |
| private RadioButton horizontalRadioButton = null; |
| private RadioButton verticalRadioButton = null; |
| private BoxPane cornerBoxPane = null; |
| |
| private boolean confirmCloseTab = true; |
| |
| @Override |
| public void initialize(Map<String, Object> namespace, URL location, Resources resources) { |
| confirmCloseTabPrompt = (Prompt)namespace.get("confirmCloseTabPrompt"); |
| tabPane = (TabPane)namespace.get("tabPane"); |
| closeableCheckbox = (Checkbox)namespace.get("closeableCheckbox"); |
| collapsibleCheckbox = (Checkbox)namespace.get("collapsibleCheckbox"); |
| horizontalRadioButton = (RadioButton)namespace.get("horizontalRadioButton"); |
| verticalRadioButton = (RadioButton)namespace.get("verticalRadioButton"); |
| cornerBoxPane = (BoxPane)namespace.get("cornerBoxPane"); |
| |
| tabPane.getTabPaneListeners().add(new TabPaneListener.Adapter() { |
| @Override |
| public Vote previewRemoveTabs(final TabPane tabPane, final int index, final int count) { |
| Vote vote; |
| if (confirmCloseTab) { |
| confirmCloseTabPrompt.open(TabPanes.this, new SheetCloseListener() { |
| @Override |
| public void sheetClosed(Sheet sheet) { |
| if (confirmCloseTabPrompt.getResult() |
| && confirmCloseTabPrompt.getSelectedOptionIndex() == 1) { |
| confirmCloseTab = false; |
| |
| int n = tabPane.getTabs().getLength(); |
| if (index < n - 1) { |
| tabPane.setSelectedIndex(index + 1); |
| } else { |
| tabPane.setSelectedIndex(index - 1); |
| } |
| |
| tabPane.getTabs().remove(index, count); |
| |
| confirmCloseTab = true; |
| } |
| } |
| }); |
| |
| vote = Vote.DENY; |
| } else { |
| vote = Vote.APPROVE; |
| } |
| |
| return vote; |
| } |
| }); |
| |
| ButtonStateListener checkboxStateListener = new ButtonStateListener() { |
| @Override |
| public void stateChanged(Button button, Button.State previousState) { |
| updateTabPane(); |
| } |
| }; |
| |
| closeableCheckbox.getButtonStateListeners().add(checkboxStateListener); |
| collapsibleCheckbox.getButtonStateListeners().add(checkboxStateListener); |
| |
| ButtonStateListener radioButtonStateListener = new ButtonStateListener() { |
| @Override |
| public void stateChanged(Button button, Button.State previousState) { |
| if (button.isSelected()) { |
| updateTabPane(); |
| } |
| } |
| }; |
| |
| horizontalRadioButton.getButtonStateListeners().add(radioButtonStateListener); |
| verticalRadioButton.getButtonStateListeners().add(radioButtonStateListener); |
| |
| updateTabPane(); |
| } |
| |
| private void updateTabPane() { |
| tabPane.setCloseable(closeableCheckbox.isSelected()); |
| tabPane.setCollapsible(collapsibleCheckbox.isSelected()); |
| |
| if (horizontalRadioButton.isSelected()) { |
| tabPane.getStyles().put("tabOrientation", Orientation.HORIZONTAL); |
| if (tabPane.getCorner() == null) { |
| tabPane.setCorner(cornerBoxPane); |
| } |
| } else { |
| tabPane.getStyles().put("tabOrientation", Orientation.VERTICAL); |
| if (tabPane.getCorner() == cornerBoxPane) { |
| tabPane.setCorner(null); |
| } |
| } |
| } |
| } |
| ]]> |
| </source> |
| |
| <p> |
| Note that this example also demonstrates the use of the tab pane corner component. For |
| horizontally oriented tabs, this component appears in the upper right corner; for |
| vertical tabs, it appears in the lower left. The corner component in this example is a |
| flow pane containing a text input; it is hidden when the orientation is changed to |
| vertical because the corner component itself is not rotated and would cause the button |
| area to grow horizontally. |
| </p> |
| </body> |
| </document> |