# 13

## JCSplitterWindow and JCSeparator

Introduction · Sample Program Code · Orientation

JCSplitterWindow Size Characteristics · JCSeparator Size Characteristics

JCSeparator Orientation · Property Listing · Example Program

### Introduction

`A s` plit window is a standard windows control that allows a user to adjust the boundary between two or more adjoining windows. The division between the window panes is called the split bar. JClass BWT's `JCSplitterWindow` is a container similar in function to Motif's `XmPanedWindow`, which manages one or more vertically or horizontally oriented children. The user can adjust the size of the panes by dragging the separator, which is controlled by a `JCSeparator` component that separates each pair of child windows. When creating `JCSplitterWindow`, the programmer does not have to add a `JCSeparator`, as it is added automatically. `JCSeparator` can be used within other BWT components. Both `JCSplitterWindows` and `JCSeparator` share a number of the same options, including the ability to set its orientation (either horizontal or vertical), and size.

There is no equivalent to `JCSplitterWindow` or `JCSeparator` in the Java Development Kit (JDK). `JCSplitterWindow` and `JCSeparator` conform to standard Windows 95 "look and feel" and behavior.

#### Behavior

- When a cursor passes over a `JCSeparator`, the cursor changes to a double-arrow.
- A user selecting a `JCSeparator` with the cursor can drag it across the area of either of the windows it divides. When the cursor is released, both contents of both windows are redrawn to fit to the new size.

#### Keyboard Traversal

There are no keyboard traversal routines that apply to `JCSplitterWindow` or `JCSeparator`.

### Sample Program Code

The following lengthy code example shows how a `JCSplitterWindow` can incorporate a `JCMultiColumnList` and a `JCOutliner`. All that needs to be done is to create a window and then add components to it.

    package jclass.bwt.examples;
    import jclass.bwt.BWTEnum;
    import jclass.bwt.JCItemEvent;
    import jclass.bwt.JCMultiColumnList;
    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.bwt.JCSplitterWindow;
    import jclass.contrib.ContribFrame;
    import jclass.util.JCUtilConverter;
    import jclass.util.JCVector;
    import java.awt.*;

    /**
     * This example demonstrates a several components in a JCSplitterWindow.
     */
    public class splitterWindow 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 };

    JCMultiColumnList list;

    /**
     * JCOutlinerListener methods
     */

    /*
     * Writes a folder's items to the list when it is selected
     * It simulates the reading of the data from a database.
     */
    public void itemStateChanged(JCItemEvent item_ev) {
    	JCOutlinerEvent ev = (JCOutlinerEvent) item_ev;
    	JCOutlinerFolderNode folder = (JCOutlinerFolderNode) ev.getNode();
    	JCOutliner outliner = (JCOutliner) ev.getSource();

    	// Ignore root node
    	if (folder == outliner.getRootNode()) {
    		list.clear();
    		return;
    	}

    	// Add children to list
    	if (ev.getStateChange() == JCItemEvent.SELECTED) {
    		list.setBatched(true);
    		list.clear();
    		int pos = ((Integer)folder.getUserData()).intValue();
    		String[] items = item_data[pos];
    		for (int i=0; i < items.length; i++) {
    			JCVector label = outliner.getConverter()
    				.toVector(this, items[i], '|', false);
    			list.addItem(label);
    		}
    		list.setBatched(false);
    	}
    }

    public void outlinerFolderStateChangeBegin(JCOutlinerEvent ev) {}
    public void outlinerFolderStateChangeEnd(JCOutlinerEvent ev) {}
    public void outlinerNodeSelectBegin(JCOutlinerEvent ev) {}
    public void outlinerNodeSelectEnd(JCOutlinerEvent ev) {}

    public void init() {
    	Image folder_closed = JCUtilConverter.toImage(this, "../images/folderc.gif");
    	Image top = JCUtilConverter.toImage(this, "../images/top.gif");

    	// Force contents to be the same size as the 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_closed);

    	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(150, 300);
    	outliner.addItemListener(this);

    	list = new JCMultiColumnList();
    	list.getList().setBackground(Color.white);
    	list.setColumnLabels(column_labels);
    	list.setPreferredSize(500, 300);

    	// Open last folder
    	outliner.selectNode(f, null);
    	outliner.setNodeState(f, BWTEnum.FOLDER_OPEN_ALL, true);

    	JCSplitterWindow window = new JCSplitterWindow(BWTEnum.HORIZONTAL);
    	window.add(outliner);
    	window.add(list);

    	add(window);
    }

    public static void main(String args[]) {
    	ContribFrame frame = new ContribFrame("SplitterWindow");
    	splitterWindow s = new splitterWindow();

    	s.init();
    	frame.add(s);
    	frame.pack();
    	frame.show();
    }
    }

This code, with the addition of data string values, produces the following results:

#####

##### A JCSplitterWindow enclosing a JCMultiColumnList and a JCOutliner

Even though the code does not specifically add a `JCSeparator` statement, it is invoked automatically by the `JCSplitterWindow` in the program.

Note how in the illustration the cursor is positioned over the `JCSeparator`, and how it changes to a double-arrow state to indicate the presence of a `JCSplitterWindow`.

This sample code is incorporated into the example file splitterWindow.class provided with JClass BWT. For information on how to run this program, see the " Example Program" section at the end of this chapter.

### Orientation

By default, the `JCSplitterWindow` constructor creates an empty vertical window. To set the orientation of the `JCSeparator` that divides the windows, use `HORIZONTAL` or `VERTICAL`, as shown in the following code fragment:

    JCSplitterWindow window = new JCSplitterWindow(VERTICAL);
            window.add(outliner);
            window.add(list);
            add(window);

The current orientation of a `JCSplitterWindow` can also be set or read using the `Orientation` method. `Orientation` takes one of two parameters: `HORIZONTAL` or `VERTICAL`.

### JCSplitterWindow Size Characteristics

Typically, `JCSplitterWindow`s are sized to match the height or width of the component it controls. By default, the `preferredHeight` and the `preferredWidth` methods return the sum of all children's preferred width if orientation is horizontal; otherwise it returns the maximum preferred width of all children.

In programs where the it is desirable to set a limit on the extent to which a user can resize a window, use the `MinChildSize` method, which set a minimum size (in pixels) to which a child can be resized by the user (default: 20).

### JCSeparator Size Characteristics

Though it is most often in conjunction with `JCSplitterWindow`, `JCSeparator` can be used within other components. When used separately from `JCSplitterWindow`, it can be directly manipulated from with a program.

Both `preferredHeight` and `preferredWidth` returns the shadow thickness value if it is a horizontal or vertical separator respectively; otherwise it returns a value of 100.

### JCSeparator Orientation

Normarly the `JCSeparator` orientation is set by the `JCSeparator` constructor. By default, a horizontal orientation is created unless specified otherwise.

The current orientation of a `JCSeparator` can also be set or read using the `Orientation` method. Orientation takes one of two parameters: `HORIZONTAL` or `VERTICAL`.

### Property Listing

The following is a listing of available properties for `JCSplitterWindow.`

#### jclass.bwt.JCSeparator

#####

Name | Method | Inherited from
--- | --- | ---
`Background` | `setBackground` | `jclass.bwt.JCContainer`
`Font` | `setFont` | `jclass.bwt.JCContainer`
`Foreground` | `setForeground` | `jclass.bwt.JCContainer`
`Insets` | `setInsets` | `jclass.bwt.JCContainer`
`MinChildSize` | `setMinChildSize` | `jclass.bwt.JCSplitterWindow`
`Orientation` | `setOrientation` | `jclass.bwt.JCSplitterWindow`
`PreferredSize` | `setPreferredSize` | `jclass.bwt.JCContainer`
`UserData` | `setUserData` | `jclass.bwt.JCContainer`

#### jclass.bwt.JCSplitterWindow

#####

Name | Method | Inherited from
--- | --- | ---
`Background` | `setBackground` | `jclass.bwt.JCComponent`
`DoubleBuffer` | `setDoubleBuffer` | `jclass.bwt.JCComponent`
`Insets` | `setInsets` | `jclass.bwt.JCComponent`
`Orientation` | `setOrientation` | `jclass.bwt.JCSeparator`
`PreferredSize` | `setPreferredSize` | `jclass.bwt.JCComponent`
`UserData` | `setUserData` | `jclass.bwt.JCComponent`

### Example Program

Demonstration programs and example code containing `JCSplitterWindow` come with JClass BWT. The examples can be viewed in applet form by launching index.html within the /jclass/bwt/examples directory. splitterWindow.class can also be run as a stand-alone Java application from the command prompt by typing:

         java jclass.bwt.examples.splitterWindow