Introduction · Concepts · Sample Program Code
Color and Fonts Properties · Outliner Sizing
Column and Row Display Properties · Row and Column Visibility
Scrollbar Properties · Setting the Selection Mode
Node Properties · Folder Appearance · Events
Property Listing · Example Program
Outliners (also known as "trees") are standard Graphical User Interface (GUI) components common to most windowing systems, which enables the display hierarchically-organized data. The data items can be organized into columns for easier display. The JCOutliner component enables Java developers to display hierarchical data such as file systems, catalogs, ordered lists, and organization charts in the form of a tree. Each item is either a folder (a tree branch) or an item (a tree leaf). Each folder or item is displayed with an icon to its left. The appearance of each node is specified by a style. Column labels can also be optionally added. JCOutliner has many features including column resizing and reordering. There is no equivalent to JCOutliner in the classes provided with the AWT.
The user can control whether the data contained in a folder is to be displayed. The user can collapse or uncollapse a folder by either double-clicking on the folder, hitting the space key, or clicking on an optional shortcut button displayed to the left of the folder. Typing a character will cause the first item which starts with the character to be made visible and selected. If no item can be found, no action is taken.
The following illustration shows examples of the kinds of data that can be displayed using JCOutliner:
The data displayed by the JCOutliner component is assumed to be in the form of a tree. Each item of data is either a folder (a branch of the tree) or an item (a leaf of the tree).
The end-user can control whether the data contained in a folder is to be displayed or not; if the data is not displayed, the folder is collapsed. The end-user can collapse or un-collapse a folder by either clicking on the folder or clicking on the shortcut button. JCOutliner follows standard Windows 95 behavior in this regard.
The shortcut button contains a character that indicates whether a folder is collapsed. If the button contains a "+" character, the folder is collapsed. If it contains a "--" character, the data contained in a folder is displayed.
The cursor keys can be used within a JCOutliner to navigate through its various nodes and folders. The UP and DOWN cursor keys enables the user to move between items. If the user is over a closed folder and click the RIGHT cursor key, it opens the folder and displays its children. Alternately, clicking the ENTER key toggles the state of the folder that has focus. The PAGE UP and PAGE DOWN move focus to the top and bottom of the displayed outline respectively, and the HOME and END keys take the user to the top and bottom of the outline respectively.
The JCOutliner component is a component that displays hierarchical information in the form of a tree. Each item of data in the tree is called a node; the node data itself consists of one or more text strings called node labels. The area in which nodes are displayed is called the node area.
Nodes are of two types: items and folder nodes. The only difference between these two types of nodes is that a folder node can have zero or more children. Each node is indented to the right of it parent, and a root node must exist. The root node need not be visible, in which case all of its children are displayed to the right margin. can optionally There are two different node types in JCOutliner: the JCOutlinerNode object, which represents an item, and the JCOutlinerFolderNode object, which represents a folder node. The JCOutlinerFolderNode object is subclassed from the JCOutlinerNode object, which means that JCOutlinerFolderNode can use methods defined for JCOutlinerNode.
The following figure illustrates these components and objects, and the tree concept.
The best way to describe many of the common features to be found in JClass BWT JCOutliner is to examine the code for a sample program that uses it. The following code builds a simple, interactive Outline using JCOutliner components:
package jclass.bwt.examples; import jclass.bwt.BWTEnum; import jclass.bwt.JCItemEvent; import jclass.bwt.JCOutliner; import jclass.bwt.JCOutlinerEvent; import jclass.bwt.JCOutlinerFolderNode; import jclass.bwt.JCOutlinerListener; import jclass.bwt.JCOutlinerNode; import jclass.bwt.JCOutlinerNodeStyle; import jclass.contrib.ContribFrame; import jclass.util.JCUtilConverter; import jclass.util.JCVector; import java.awt.*; /** * This example demonstrates the use of a JCOutliner and its events. */ public class outliner extends java.applet.Applet implements JCOutlinerListener { final static String[] column_labels = { "Name", "Title", "Address", "Phone", "Salary" }; final static String dept[] = { "Management", "Accounting", "R&D" }; final static String mgmt_items[] = { "John Kricfalusi|President|983 Nickelodeon Street, Rexdale Ontario|(414) 999-9876|$10,000", "Hikaru Takei|VP|134 Adelaide Street, Suite 204, Toronto Ontario|(416) 594-1026|$23K", "James Q. Doohan|Director|1701 Planetia Blvd., Anytown, U.S.A.||$245,000" }; final static String accounting_items[] = { "Hikaru I. Takei|Payroll|134 Adelaide Street E., Suite 204, Anytown, U.S.A.|(999) 594-1026", "Melissa A. Truman|Receivable|475 Woodview Line, Anytown, U.S.A.|(999) 555-9030|$50,250", "Stephanie L. Truman|Payroll|388 Appleby Road, Anytown, U.S.A.|(999) 555-2642|$85,750" }; final static String rd_items[] = { "James Q. Doohan|Engineer|1701 Planetia Blvd., Anytown, U.S.A.||$245,000", "John F. Kricfalusi|Physicist|983 Nickelodeon Street, Anytown, U.S.A.|(999) 555-9876|$10,000", "Marc Lenard|Engineer|6 Gene Crescent, Anytown, U.S.A.|(999) 555-1212|$10/hr.", "Hikaru I. Takei|Musician|134 Adelaide Street E., Suite 204, Anytown, U.S.A.|(999) 594-1026|50%", "Melissa A. Truman|QA|475 Woodview Line, Anytown, U.S.A.|(999) 555-9030|$50,250", "Stephanie L. Truman|Technical Writer|388 Appleby Road, Anytown, U.S.A.|(999) 555-2642|$85,750", "Bill West|System Analyst|1001 Spumco Way, Anytown, U.S.A.|(999) 555-9966|$17,500" }; final static String[][] item_data = { mgmt_items, accounting_items, rd_items }; Image content_icon; /** * JCOutlinerListener methods */ /* * Adds items to a folder if it is opened, and destroys them * when it is closed. * It simulates the reading of the data from a database. */ public void outlinerFolderStateChangeBegin(JCOutlinerEvent ev) { JCOutlinerFolderNode folder = (JCOutlinerFolderNode) ev.getNode(); JCOutliner outliner = (JCOutliner) ev.getSource(); // Ignore root node if (folder == outliner.getRootNode()) return; // Create and add children to folder else if (ev.getNewState() == BWTEnum.FOLDER_OPEN_ALL) { if (folder.getChildren() != null) return; int pos = ((Integer)folder.getUserData()).intValue(); String[] items = item_data[pos]; JCOutlinerNodeStyle style = new JCOutlinerNodeStyle(); style.setItemIcon(content_icon); for (int i=0; i < items.length; i++) { JCVector label = outliner.getConverter() .toVector(this, items[i], '|', false); JCOutlinerNode newItem = new JCOutlinerNode(label); newItem.setStyle(style); folder.addNode(newItem); } } // Destroy folder's nodes else if (ev.getNewState() == BWTEnum.FOLDER_CLOSED) { folder.setChildren(null); } outliner.folderChanged(folder); } public void outlinerFolderStateChangeEnd(JCOutlinerEvent ev) {} public void outlinerNodeSelectBegin(JCOutlinerEvent ev) {} public void outlinerNodeSelectEnd(JCOutlinerEvent ev) {} public void itemStateChanged(JCItemEvent ev) {} public void init() { Image folder_opened = JCUtilConverter.toImage(this, "../images/foldero.gif"); Image folder_closed = JCUtilConverter.toImage(this, "../images/folderc.gif"); Image top = JCUtilConverter.toImage(this, "../images/top.gif"); content_icon = JCUtilConverter.toImage(this, "../images/content.gif"); // Force outliner to be same size as applet setLayout(new GridLayout(1,1)); setBackground(Color.lightGray); JCOutlinerNodeStyle style = new JCOutlinerNodeStyle(); style.setFolderOpenIcon(top); style.setFolderClosedIcon(top); JCOutlinerFolderNode root = new JCOutlinerFolderNode(null, "Personnel"); root.setStyle(style); JCOutlinerNodeStyle folder_style = new JCOutlinerNodeStyle(); folder_style.setFolderClosedIcon(folder_closed); folder_style.setFolderOpenIcon(folder_opened); folder_style.setShortcut(true); JCOutlinerFolderNode f = null; for (int i=0; i < dept.length; i++) { f = new JCOutlinerFolderNode(null, BWTEnum.FOLDER_CLOSED, dept[i]); f.setUserData(new Integer(i)); f.setStyle(folder_style); root.addNode(f); } JCOutliner outliner = new JCOutliner(root); outliner.getOutliner().setBackground(Color.white); outliner.setPreferredSize(400, 300); outliner.setColumnLabels(column_labels); outliner.setNumColumns(column_labels.length); outliner.getDefaultNodeStyle().setShortcut(true); outliner.addItemListener(this); // Open last folder outliner.setNodeState(f, BWTEnum.FOLDER_OPEN_ALL, true); add(outliner); } public Insets insets() { return new Insets(5,5,5,5); } public static void main(String args[]) { ContribFrame frame = new ContribFrame("Outliner"); outliner o = new outliner(); o.init(); frame.add(o); frame.pack(); frame.show(); } }When this code is inserted into a program, it produces the following results:
This sample code is incorporated into the example file outliner.class provided with JClass BWT. For information on how to run this program, see the "Example Program" section at the end of this chapter.
There are several properties which can be used to customize the display of a JCOutliner. The Background and Foreground properties can be used to set the color of the background and text/foreground elements of a JCOutliner. Foreground not only sets the color of any alphanumeric characters contained in the node label, but also of the arrow buttons and of the cursor within the text field.
The display of fonts within a JCOutliner is controlled by the Font property. For a listing of available fonts, see Appendix A: Colors and Fonts.
The size of a JCOutliner can be set using the PreferredSize property, which sets the container's preferred size. If either dimension is set to NOVALUE, it is calculated by the subclass.
The individual PreferredWidth and PreferredHeight methods each deal with the subclass' preferred width (default: 100). The subclass should not include the inset sizes in its calculation, as these are added by JCOutliner.
Whenever possible, the JCOutliner component is sized to its preferred width when displayed. If this is not possible, the width of the node area is reduced accordingly. If the width of the component is greater than the preferred width, the node area is stretched accordingly. If a multi-column display is defined, the last column is stretched.
The display of the text contained within a JCOutliner is controlled by the VisibleRows and the various Column properties (ColumnAlignments, ColumnButtons, ColumnLabels, ColumnLeftMargin, ColumnRightMargin, ColumnWidths).
VisbleRows takes an integer value equal to the number of rows to be displayed. If VisibleRows is set to 0 (default), the text field attempts to resize itself so that all of its items are visible.
The ColumnAlignments property is used to set a column's alignment. It uses the parameter align, which can take any of the following values: TOPLEFT, TOPCENTER, TOPRIGHT, MIDDLELEFT, MIDDLECENTER, MIDDLERIGHT, BOTTOMLEFT, BOTTOMCENTER and BOTTOMRIGHT. By default, ColumnAlignments is set to MIDDLELEFT.
To add labels to a column, use the ColumnLabels property, which takes a string value or a JCString. To create labels that look and behave like buttons, use the ColumnButtons property instead. This property turns each label into a button that the user can interact with. There are cases when it desirable to allow the user to sort the information contained within an outliner. The ColumnLabelSort property is used to specify whether a column is sorted when its button is clicked (default: true).
Instead of adding string values for each label, it is also possible to assign vectors or JCVectors as labels to the node.
Margin values for JCOutliner columns can be explicitly set using the ColumnLeftMargin and ColumnRightMargin properties. Each sets the column's respective margins as a pixel value. They take an integer value corresponding to the column being set, and the value in pixels of the column margin. By default, both are set to 5 pixels.
To set the width of the columns appearing in a JCOutliner, use the ColumnWidths property. If a column's value is set to VARIABLE, the width of the column is set to the widest value contained within in the column.
The spacing between rows is set by the Spacing property (default: 0).
The VisibleRows property sets the number of rows that are visible in a JCOutliner. If set to 0 (default), the list will attempt to resize itself so that four items are visible. If it is set to another value, only the number of row specified will be displayed. VisibleRows only works if the list is made visible beforehand.
Column visibility in JCOutliner is set using the NumColumns property. If set to VARIABLE (default), all columns are displayed.
If an outline is too large to be displayed within the node area, scrollbars are displayed. The end-user can click on these scrollbars to specify the portion of the tree to be displayed in the node area. By default, horizontal scrollbars, vertical scrollbars, or both appear whenever appropriate. These are separate components which are defined as children of the JCOutliner component, and are controlled by ScrollbarDisplay.
The ScrollbarDisplay property is used to set and under what circumstances the scrollbars are to be displayed. ScrollbarDisplay can take one of five different values: DISPLAY_ALWAYS (scrollbars are always displayed), DISPLAY_AS_NEEDED (scrollbars are displayed as necessary), DISPLAY_VERTICAL_ONLY (the vertical scrollbars is always displayed), DISPLAY_HORIZONTAL_ONLY (the horizontal scrollbar is always displayed), DISPLAY_NONE (never display scrollbars). By default, ScrollbarDisplay is set to DISPLAY_AS_NEEDED.
The ScrollbarOffset property sets the amount of space between the scrollbar and the component for the JCOutliner in pixels (default: 5).
The AutoSelect property can be used to set the selection mode for an item or items that have focus with a JCOutliner. If set to true (default), the node which currently has focus is also selected. If AutoSelect is set to false, the node which currently has focus in not automatically selected. The latter setting is useful in situations where the user is expected to use the keyboard rather than the mouse to traverse and select multiple items within a JCOutliner, as it allows the user to move about the various nodes of the outliner without automatically selecting individual items.
There are two properties that control the display of nodes within a JCOutliner: NodeHeight and NodeIndent.
NodeHeight is used to explicitly set the height of each node in pixels. By default it is set to 0, at which point the height of the node is determined using the largest font and image height that appears in the list of node styles.
NodeIndent is used to set the indentation of each node relative to its parent in pixels (default: 15).
The appearance of nodes can be changed from the default by using the various properties derived from JCOutlinerNodeStyle. Several nodes can share a JCOutlinerNodeStyle instance. The following are a list of node style properties that can be used:
One additional property, RootVisible, is used to specify whether the root node is displayed. If true (default), the root node is drawn.
Normally, two states are defined for a folder: closed and open. A folder is closed if its children are not visible. A folder is open if its children are visible. By default, a folder state change (such as a double-click of the mouse button) toggles between these two states.
It is possible to specify additional folder states that are somewhere between completely closed and completely open using the StateList property. StateList sets a list of values used for double-clicking on a folder or clicking its shortcut button. The folder's state is cycled through the list. StateList can take one of five different values: FOLDER_CLOSED (the folder is closed and no children are visible), FOLDER_OPEN_NONE (the folder is open and no children are visible), FOLDER_OPEN_FOLDERS (the folder is open, but only the folder children are visible), FOLDER_OPEN_ITEMS (the folder is open, but only the non-folder children are visible, or FOLDER_OPEN_ALL (the folder is open, and all children are visible).
A class can be notified when the user presses the ENTER key or double-clicks a node within an JCOutliner by implementing the JCActionListener interface and registering itself with the outliner via addActionListener, as the following code demonstrates:
public interface JCActionListener { public void actionPerformed(JCActionEvent e); } public class JCActionEvent { // Returns the component where the event originated. public Object getSource() // Returns the event type: ACTION_PERFORMED. public int getId() }A class can be notified when the user selects an item in a JCOutliner by implementing the JCItemListener interface and registering itself with the outliner via addItemListener:
public interface JCItemListener { public void itemStateChanged(JCItemEvent e); } public class JCItemEvent { // Returns the component where the event originated. public Object getSource() // Returns the event type: ITEM_STATE_CHANGED. public int getId() // Returns the node where the event occurred. public Object getItem() // Returns the state change type which generated the event: SELECTED or DESELECTED public int getStateChange() }To receive additional information, a class can implement the JCOutlinerListener interface, and register itself with the outliner via addItemListener.
public interface JCOutlinerListener extends JCNodeListener { // Invoked before an node is selected. The event's values can be modified via its setXXX methods. public void outlinerNodeSelectBegin(JCOutlinerEvent e); // Invoked after an node is selected. Any changes made to the event are ignored. public void outlinerNodeSelectEnd(JCOutlinerEvent e); // Invoked before a folder's state is changed. The event's values can be modified via its setXXX methods. public void outlinerFolderStateChangeBegin(JCOutlinerEvent e); // Invoked after a folder's state is changed. Any changes made to the event are ignored. public void outlinerFolderStateChangeEnd(JCOutlinerEvent e); }It will then be passed to JCOutlinerEvents:
public class JCOutlinerEvent extends JCItemEvent { // Gets the node whose state will be changed. public JCOutlinerNode getNode() // Gets the node's current state public int getState() // Gets the node's new state. public int getNewState() // Sets the node's new state. This is ignored if the node is not a folder. public void setNewState(int v) // Gets the current AllowChange value. public boolean getAllowChange() // Determines whether the selection or state change should be allowed (default: true). public void setAllowChange(boolean v) }
Name |
Method |
Inherited from |
---|---|---|
AutoSelect |
setAutoSelect |
jclass.bwt.JCOutliner |
Background |
setBackground |
jclass.bwt.JCContainer |
ColumnAlignments |
setColumnAlignments |
jclass.bwt.JCOutliner |
ColumnAlignments |
setColumnAlignments |
jclass.bwt.JCMultiColumnWindow |
ColumnLabelSort |
setColumnLabelSort |
jclass.bwt.JCMultiColumnWindow |
ColumnLeftMargin |
setColumnLeftMargin |
jclass.bwt.JCMultiColumnWindow |
ColumnRightMargin |
setColumnRightMargin |
jclass.bwt.JCMultiColumnWindow |
ColumnWidths |
setColumnWidths |
jclass.bwt.JCMultiColumnWindow |
Font |
setFont |
jclass.bwt.JCContainer |
Foreground |
setForeground |
jclass.bwt.JCContainer |
Insets |
setInsets |
jclass.bwt.JCContainer |
NodeHeight |
setNodeHeight |
jclass.bwt.JCOutliner |
NodeIndent |
setNodeIndent |
jclass.bwt.JCOutliner |
NumColumns |
setNumColumns |
jclass.bwt.JCOutliner |
NumColumns |
setNumColumns |
jclass.bwt.JCMultiColumnWindow |
PreferredSize |
setPreferredSize |
jclass.bwt.JCContainer |
RootVisible |
setRootVisible |
jclass.bwt.JCOutliner |
ScrollbarDisplay |
setScrollbarDisplay |
jclass.bwt.JCScrolledWindow |
ScrollbarOffset |
setScrollbarOffset |
jclass.bwt.JCScrolledWindow |
Spacing |
setSpacing |
jclass.bwt.JCMultiColumnWindow |
StateList |
setStateList |
jclass.bwt.JCOutliner |
UserData |
setUserData |
jclass.bwt.JCContainer |
VisibleRows |
setVisibleRows |
jclass.bwt.JCMultiColumnWindow |
Demonstration programs and example code containing JCOutliner come with JClass BWT. The examples can be viewed in applet form by launching index.html within the /jclass/bwt/examples directory. outliner.class can also be run as stand-alone Java applications from the command prompt by typing:
java jclass.bwt.examples.outliner