Introduction · Sample Program Code · Changing the Active Tab
Controlling Tab Display · Tab Button Properties · Events
Property Listing · Example Program
Tabbed dialogs enable the programmer to create a "layer" of dialogs which the user can access through a set of tabs. Based on the visual metaphor of a sequence of file folders, users click a tab to display the contents of a specific file folder. Tabbed dialogs provide an easy way to provide users with a convenient and intuitive way of accessing options contained within with a well-organized interface.
The Java Development Kit (JDK) does not implement tab dialogs. JCTabButton
dialogs look and behave like their MS Windows 95 equivalents. JCTabButton
dialogs are created and controlled by JCTabManager
, which is a container that organizes its children into pages to simulate a sequence of file folders. The page components are defined as children of the JCTabManager
; a property is then used to associate a page with a particular tab button. Page components can be of any class (including any container). The tabs are subclassed from JCButton
, which can contain multiple lines of text, images, or contain both text and images. JCTabButton
dialogs use the new event model to update the tabbed page display.
JCTabButton
dialogs behave in the following manner:
To program tabbed dialogs, you need to create the following:
Together, the JCTabManager
and JCTabButton
simulate a sequence of file folders. The page components are defined as children of the JCTabManager
; a constraint property is then used to associate a page component with a particular JCTabButton
. Page components can be of any component or container.
The following figure illustrates the anatomy of a typical tabbed dialog.
The following code fragment creates a JCTabManager
container, then adds several tabs and pages as its children:
package jclass.bwt.examples; import jclass.bwt.BWTEnum; import jclass.bwt.JCCheckbox; import jclass.bwt.JCCheckboxGroup; import jclass.bwt.JCContainer; import jclass.bwt.JCGridLayout; import jclass.bwt.JCItemEvent; import jclass.bwt.JCItemListener; import jclass.bwt.JCLabel; import jclass.bwt.JCTabButton; import jclass.bwt.JCTabManager; import jclass.bwt.JCTabManagerEvent; import jclass.bwt.JCTabManagerListener; import jclass.contrib.ContribFrame; import jclass.util.JCString; import jclass.util.JCUtilConverter; import java.awt.*; import java.util.Date; /** * This example creates a JCTabManager which displays some of the other * examples. */ public class tabManager extends java.applet.Applet implements Runnable, JCTabManagerListener, JCItemListener { JCLabel label = new JCLabel(); JCTabManager tab_manager; transient Thread updater; // JCItemListener method public void itemStateChanged(JCItemEvent ev) { JCCheckboxGroup group = (JCCheckboxGroup) ((Component)ev.getSource()).getParent(); if (group.getTitle().equals("Shape")) tab_manager.setTabShape(group.getValue()); else if (group.getTitle().equals("Side")) tab_manager.setTabSide(group.getValue()); } /* * JCTabManagerListener methods */ // Sets the page when the Date or Vendor tab is clicked public void tabManagerChangeBegin(JCTabManagerEvent ev) { JCTabButton tab = ev.getNextTab(); if (tab.getName().equals("Date")) { label.setLabel(""+new Date()); start(); return; } // Stop date thread if it is running stop(); if (tab.getName().equals("Vendor")) { String url = System.getProperty("java.vendor.url"); JCString s = JCString.parse(this, "[COLOR=blue][href=" + url + " TARGET=_blank]" + url); label.setLabel(s); } } public void tabManagerChangeEnd(JCTabManagerEvent ev) {} public Insets insets() { return new Insets(5,5,5,5); } static String side_labels[] = { "Top", "Bottom" }; static int side_values[] = { BWTEnum.TOP, BWTEnum.BOTTOM } ; static String shape_labels[] = { "Rectangular", "Slanted" }; static int shape_values[] = { BWTEnum.RECTANGLE, BWTEnum.SLANTED }; public void init() { // Force tab manager to be same size as applet setLayout(new GridLayout(1,1)); tab_manager = new JCTabManager(); tab_manager.addTabManagerListener(this); setBackground(Color.lightGray); JCCheckboxGroup sides = JCCheckbox.makeGroup(side_labels, side_values, true); sides.setTitle("Side"); sides.addItemListener(this); JCCheckboxGroup shapes = JCCheckbox.makeGroup(shape_labels, shape_values, true); shapes.setTitle("Shape"); shapes.addItemListener(this); JCContainer panel = new JCContainer(); panel.setInsets(new Insets(0, 20, 0, 20)); panel.setLayout(new JCGridLayout(1, BWTEnum.VARIABLE, 10, 10)); panel.add(sides); panel.add(shapes); tab_manager.addPage("Tab Styles", panel); labels l = new labels(this); l.init(); l.setBackground(Color.yellow); tab_manager.addPage("Labels", l); buttons b = new buttons(this); b.init(); tab_manager.addPage("Buttons", b); /* * Add tabs which share the same page. The page contents will be set * in the listener method when the tab is clicked. */ label.setFont(new Font("TimesRoman", Font.BOLD, 20)); int pos = tab_manager.addPage("Java Vendor", label); tab_manager.getTab(pos).setName("Vendor"); pos = tab_manager.addPage("Current Date", label); tab_manager.getTab(pos).setName("Date"); add(tab_manager); } public void start() { if (updater == null) { updater = new Thread(this); updater.start(); } } public void stop() { if (updater != null) { updater.yield(); updater.stop(); } updater = null; } /** Writes the current time every second. */ public void run() { while (true) { try { Thread.sleep(1000); } catch (Exception e) {} if (!Thread.currentThread().isAlive() || updater == null) return; label.setLabel(""+new Date()); } } public static void main(String args[]) { ContribFrame frame = new ContribFrame("TabManager"); tabManager s = new tabManager(); s.init(); frame.add(s); frame.pack(); frame.show(); } }
This creates the following tabbed dialog display:
A sample JCTabManager with child JCTabButtons
This application consists of a Tab Manager, with four JCTabButtons
defined as its children. Each JCTabButton
has a page associated with it. Each page, in turn, has other BWT components defined as its child; in more complicated real-life applications, additional container components are defined as children of the pages.
To create a multi-level file folder, define another JCTabManager
as a page component.
This sample code is incorporated into the example file tabManager.class provided with JClass BWT. For information on how to run this program, see the " Example Program " section at the end of this chapter.
The JCTabManager
component provides two methods to control the display of the tab manager and its children:
JCTabManager
can be notified when a page has been changed and can be set at run-time; in other words, a number of tabs could share the same page and JCTabManager
could set the page contents after the user has clicked a tab.
The JCTabManagerInfo
constructor defines actions to be invoked whenever the value of TABMANAGER
changes, which can be set either interactively or programmatically. This enables you to control page display.
Each TABMANAGER
property is passed the following structure:
public JCTabManagerInfo(Event ev, Component current, Component next)
Each event is called both before and after the page change takes place. reason indicates which event is occurring, and is either BEGIN
(before page change) or END
(after page change).
The new page component and its number are specified by the current_page
and next_page
variables. These members can be modified, allowing you to control page changes in a JCTabManager
. The doit
field provides an easy way to suppress page changes. If doit
is set to false
and stage
is set to BEGIN
, the page change does not occur.
JCTabManager
enables you to control the following tab display features:
The TabResize
property specifies whether all tabs should be resized to the width or height of the largest tab in the same row. If TabResize
is true
(default), resizing is performed; if false
, each tab is only as large as necessary to display its label.
The TabStretch
property specifies whether all tabs should be stretched if necessary to fill the entire side.
To ensure that the tabs take up all the available visible space and are of the same size, set both TabResize
and TabStretch
to true
.
The TabShape
property sets the shape of the tab. There are two available values: RECTANGLE
(default), or SLANTED
. The effects of both values are depicted in the following illustration:
The two values of TabShape illustrated
The TabColorPolicy
property sets the color for individual tabs within JCTabManager
. TabColorPolicy
does not directly set the color for an individual tab, instead it either reads the color value from the tabbed page, or sets the tab's color to a value defined within the tab manager. The two values for TabColorPolicy
are COLOR_PAGE
, which sets the tab's color to the page's color (default), and COLOR_INHERIT
, which sets the tab's color to the tab manager's color.
The TabSide
property sets the placement for the displays of tabs within JCTabManager
. There are two values for TabSet
: TOP
and BOTTOM
. The effects of both values are depicted in the following illustration:
The two values of TabSide illustrated
The following sections describe how to use the JCTabButton
component.
The CurrentTabFont
property sets the current tab's font (default: bold version of the default font). It can be altered by specifying a different valid Java font name with the property, as in the following code fragment:
public void init() { JCImageCreator im = new JCImageCreator(this, 16, 16); im.setColor('X', Color.red); im.setColor('o', Color.black); im.setColor('.', Color.white); siteImage = im.create(site_icon); // Force tab manager to be same size as applet setLayout(new GridLayout(1,1)); setBackground(Color.lightGray); tab_manager = new JCTabManager(); tab_manager.setBackground(Color.lightGray); tab_manager.addTabManagerListener(this); // set the font for the selected Tab. Font newFont = new Font("Courier", Font.PLAIN, 16); tab_manager.setCurrentTabFont(newFont); theFTPPanel = new FTPPanel(this); for (int i=0; i<tabName.length; i++) { JCString name = new JCString(); name.add(siteImage); name.add(tabName[i]); tab_manager.setTabPage(i+1, name, theFTPPanel); } setTextFields(tab_manager.getCurrentTab()); tab_manager.setTabStretch(true); add(tab_manager); }
The result of this code can be seen in the following illustration:
Changing Fonts within the Tabs
This example uses a JCString to insert images within the tab buttons. For more information on JCStrings, see .
To specify a image for a JCTabButton
, specify an object in the JCTabButton
constructor. The JCTabButton
constructor can be passed a String, image or JCString.
The following code fragment displays how to add an image file as an object, and a subsequent tab to display a JCString:
/ This example uses a memory image // Static Variables static String tabName[] = { "Guru", "Gonzo", "KLG's ftp site", }; static final String site_icon[] = { " oooooooooo ", " o..........o ", " o..XXXXXX..o ", " o.X......X.o ", " o.X......X.o ", " o.X......X.o ", " o.X......X.o ", " o.X......X.o ", " o..XXXXXX..o ", " o..........o ", " o....XXXXX.o ", " o..........o ", " oooooooooooo ", " o........o ", " o........o ", " oooooooooo "}; public void init() { JCImageCreator im = new JCImageCreator(this, 16, 16); im.setColor('X', Color.red); im.setColor('o', Color.black); im.setColor('.', Color.white); Image siteImage = im.create(site_icon); // Force tab manager to be same size as applet setLayout(new GridLayout(1,1)); setBackground(Color.lightGray); tab_manager = new JCTabManager(); tab_manager.setBackground(Color.lightGray); tab_manager.addTabManagerListener(this); theFTPPanel = new FTPPanel(this); for (int i=0; i<tabName.length; i++) { JCString name = new JCString(); name.add(siteImage); name.add(tabName[i]); tab_manager.setTabPage(i+1, name, theFTPPanel); } setTextFields(tab_manager.getCurrentTab()); tab_manager.setTabStretch(true); add(tab_manager); }
The image is constructed within the code and not via a .GIF image file. The results can be seen in the following illustration.
Inserting images into tab buttons
Text and images can be aligned within a JCTabButton
by using the Alignment
property which has nine possible values: TOPLEFT
, TOPCENTER
, TOPRIGHT, MIDDLELEFT
, MIDDLECENTER
, MIDDLERIGHT, BOTTOMLEFT, BOTTOMCENTER,
and BOTTOMRIGHT
. All nine values are used with text strings in the following code sample whose results can be seen in the following illustration.
Tab Button text and pixmap layouts
Text and images can also be aligned using
JCStrings. This approach is limited to the three values possible with ALIGN
: TOP
, BOTTOM
and MIDDLE
. The following code fragment shows how to insert JCStrings within tab labels:
// Using a JCString with alignment information JCString s = JCString.parse(this, "[ALIGN=TOP]"+tabName[i]); tab_manager.setTabPage(i+1, s, theFTPPanel);
Each JCTabButton
component obtains its color specifications from the page component with which it is associated. To specify your own JCTabButton
colors, change the appropriate color properties (such as foreground
) after associating a page component with the JCTabButton
.
The shadow colors for each page component are, in turn, obtained from the JCTabButton
color specifications.
A class can be notified before and after a new JCTabManager
page is displayed by implementing the JCTabManagerListener
interface and registering itself with the tabManager
via addTabManagerListener
, as the following code demonstrates:
public interface JCTabManagerListener { // Invoked before the page is changed. The event's values can be modified via its setValue method. public void tabManagerChangeBegin(JCTabManagerEvent e); // Invoked after the page is changed. Any changes made to the event are ignored. public void tabManagerChangeEnd(JCTabManagerEvent e); } public class JCTabManagerEvent { // Returns the component where the event originated. public Object getSource() // Returns the event type. public int getId() // Gets the current page (null at initialization). public Component getCurrentPage() // Gets the page that will be displayed. public Component getNextPage() // Gets the current tab (null at initialization). public JCTabButton getCurrentTab() // Gets the tab that will be displayed. public JCTabButton getNextTab() // Sets the page that will be displayed. public void setNextPage(Component page) // Determines whether the page should change. public boolean getChangePage() // Determines whether the page should change (default: true). public void setChangePage(boolean v) }
The following summarizes the properties of JCTabManager
. Complete reference documentation is available online in standard
javadoc format in
jclass.bwt.JCTabManager.html.
Demonstration programs and example code containing JCTabButton
s and JCTabManager
s come with JClass BWT. The examples can be viewed in applet form by launching index.html within the /jclass/bwt/examples directory. tabManager.class
can also be run as a stand-alone Java application from the command prompt by typing:
java jclass.bwt.examples.tabManager