[ Overview ] [ User's Guide ] [ Tutorial ] [ Requirements ]
Tutorial | API Documentation |
This tutorial shows you how to use a MultiColumnListbox Bean to build a simple applet that displays a series of names and graphic status icons. This tutorial describes how to create this applet in the following steps:
See the API Documentation for a complete list of the methods and features provided by the MultiColumnListbox Bean.
To begin building this applet, create the basic listbox. Later you can add the additional features such as column sorting and graphical elements.
There are three basic steps required to set up a new listbox:
1. Create a new MultiColumnListbox instance:
MultiColumnListbox listbox = new MultiColumnListbox();
2. Add three columns:
listbox.addColumn("#"); listbox.addColumn("First"); listbox.addColumn("Last"); OR String columns[] = { "#", "First Name", "Last Name" }; listbox.addColumns(columns);
3. Add rows of data:
// Some sample data Object rows[][] = { { "2", "Andy", "Clark" }, { "1", "Carl", "Danowski" }, { "3", "Rich", "Gutierrez" }, { "2", "Eugene", "Shumulinsky" }, { "1", "Charlie", "Cleveland" }, { "3", "Tad", "Kollar" } }; // Add the data to the listbox listbox.addRows(rows);
Notice that there are two different ways to create columns and add data to the listbox. Both methods are interchangable.
Inserting the previous code into the following applet creates a simple MultiColumnListbox with three columns and several rows of data:
import java.awt.*; import COM.taligent.widget.*; // Applet public class SampleMultiColumnListbox extends java.applet.Applet { //// SAMPLE DATA //// // Setup applet public void init() { setBackground(Color.lightGray); setLayout(new BorderLayout()); //// SAMPLE CODE //// add("Center", listbox); setSize(180, 140); setVisible(true); } }
That's all that's really required to create a MultiColumnListbox. You're finished if you only want to display rows of text information. If you want more than the basic listbox, however, you need to do a little more work. The following sections describe how to change column settings, capture listbox events, add graphical elements, and also introduce you to some advanced features of the listbox.
Now that you've created a few columns and filled them with data, you can modify some of the column attributes.
Let's allow the user to sort the First Name and Last Name columns. You can use any custom Sorter class you want but for our purposes we'll use the SelectionSorter provided. We also need to decide what comparison is to be used. Do we compare the elements as Strings, or as integers? Again, you can create your own custom Comparator, but the Sorter class, by default, compares String elements using the StringComparator provided, so that's what we'll use.
Column indexes, like row indexes, start at zero:
// Change settings for status column ListboxColumn column = listbox.getColumnInfo(0); column.setWidth(30); column.setResizable(false); // Change settings for first name column column = listbox.getColumnInfo(1); column.setSorter(new SelectionSorter()); // Change settings for last name column column = listbox.getColumnInfo(2); column.setWidth(100); column.setSorter(new SelectionSorter());
The width of the status column is set to 30 and not resizable by the user. The First Name and Last Name columns are now sortable. The next section demonstrates how to add event handling to enable the applet to catch events that are produced when the user manipulates the listbox.
The MultiColumnListbox follows the Java 1.1 event delegation model. Components implement listener interfaces and then register themselves with the Bean to receive event notifications.
The program using the MultiColumnListbox can receive events when the user selects or deselects rows and when the user selects or resizes a caption. A ListboxListener is notified of row selections and deselections. A CaptionBarListener is notified of caption selection and resizing.
To implement the listbox listener interfaces and register the applet as a listener, you can do the following. The code marked in bold shows the applet implementing the listbox listeners. The code marked in red registers the applet as a listener instance with the listbox:
import COM.taligent.widget.event.*; public class SampleMultiColumnListbox extends java.applet.Applet implements CaptionBarListener, ListboxListener { // Setup applet public void init() { //// SAMPLE CODE //// // Add listeners listbox.addCaptionBarListener(this); listbox.addListboxListener(this); } /** Column was selected. */ public void captionSelected(CaptionBarEvent evt) { System.out.println(evt.toString()); } /** Column was resized. */ public void captionResized(CaptionBarEvent evt) { System.out.println(evt.toString()); } /** Row was selected. */ public void rowSelected(ListboxEvent evt) { System.out.println(evt.toString()); } /** Row was deselected. */ public void rowDeselected(ListboxEvent evt) { System.out.println(evt.toString()); } }
The listener methods are called as the user interacts with the listbox and produces events. It it important to note that only user events are passed to the listeners. No events are passed when the program alters the listbox.
The MultiColumnListbox Bean can contain any graphical element you create that implements the Paintable interface. In this section we are going to replace the status numbers in the first column with graphic icons saved as transparent GIFs.
The StatusIcon class below implements Paintable so that we can draw the icon. It also implements Comparator so that we can use the same graphic object to sort the status column.
import java.awt.*; public class StatusIcon extends Object implements COM.taligent.widget.Paintable, COM.taligent.util.Comparator { // Data private Image image; private int status; // Constructor. public StatusIcon(Image image, int status) { this.image = image; this.status = status; } // Getters public Image getImage() { return image; } public int getStatus() { return status; } // Methods for Paintable interface public Dimension getSize() { return new Dimension(20, 20); } public void paint(Graphics g) { g.drawImage(image, 0, 0, null); } // Method for Comparator interface public int compare(Object a, Object b) { int aval = ((StatusIcon)a).getStatus(); int bval = ((StatusIcon)b).getStatus(); if (aval < bval) return 1; if (aval > bval) return 1; return 0; } }
The Paintable interface requires us to define the getSize and paint methods in our object. The MultiColumnListbox Bean doesn't need to know what the size of the Paintable object is but the method is part of the interface for other classes that use Paintable objects and need to know the size of the element before painting them.
Tip: The graphics context that your Paintable object receives from the MultiColumnListbox when it is drawn only includes the area of the element in the listbox. You can provide your own centering and scaling of the Paintable object by first determining the size of the graphics context in the paint method. You can do this by calling getClipBounds. This method returns a Rectangle object with which you can extract the width and height information.
The Comparator interface required us to define the compare method which compares objects a and b and returns a negative number if a < b; a positive number if a > b; and zero if the two objects are equal to each other.
Once we have created the StatusIcon class, we need to load the images and add them to the listbox. We will do this in two steps. The image files referenced here are included in the documentation folder shipped with this bean, or you can substitute your own image files:
// Load the status icons URL baseURL = getCodeBase(); Image images[] = { getImage(baseURL, "one.gif"), getImage(baseURL, "two.gif"), getImage(baseURL, "three.gif") }; StatusIcon icons[] = new StatusIcon[3]; MediaTracker tracker = new MediaTracker(this); for (int i = 0; i <images.length; i++) { tracker.addimage(images[i], i); icons[i]="new" statusicon(images[i], i); } try { tracker.waitforall(); } catch (exception e) { system.out.println("not all images loaded."); }
// Status icons for names StatusIcon statusicons[] = { icons[1], icons[0], icons[2], icons[1], icons[0], icons[2] }; // Replace the status numbers with icons listbox.replaceColumn(statusicons, 0); // Allow status column to be sorted listbox.getColumnInfo(0) .setSorter(new SelectionSorter()) .getSorter().setComparator(icons[0]); // Resort the listbox listbox.sort();
The listbox has a few advanced features that are quite useful. One of these features is the ability to display multi-line captions in the caption bar. In addition, each row can display multi-line, text strings.
To display multi-line captions in the caption bar, you need to do two things:
// Create three columns String columns[] = { "#", "First Name", "Last Name" }; listbox.addColumns(columns);
to:
String columns[] = { "#", "First\nName", "Last\nName" }; listbox.addColumns(columns);
// Resize CaptionBar height listbox.setCaptionBarHeight(listbox.getCaptionBarHeight() * 2);
This is the simplest way to enable the caption bar to display 2 line caption headers. However, you could use a multiple of the FontMetrics height of the listbox font to determine the caption bar height.
Setting the listbox to handle multi-line text element is the
same: use newline characters in your strings and set
the listbox row height using the setRowHeight(int) method.
Another powerful feature of the listbox is its ability to include any Java Component as an element in the listbox.
Tip: the more Component elements you add, the more overhead you add to positioning and sizing those components. Use common sense and include components only where they are needed.
Let's add a handful of components to the sample applet. Change the sample data from:
// Some sample data Object rows[][] = { { "2", "Andy", "Clark" }, { "1", "Carl", "Danowski" }, { "3", "Rich", "Gutierrez" }, { "2", "Eugene", "Shumulinsky" }, { "1", "Charlie", "Cleveland" }, { "3", "Tad", "Kollar" } };
to:
// Some sample data Label andy = new Label("Andy"); Checkbox rich = new Checkbox("Rich"); Button gutierrez = new Button("Gutierrez"); TextField eugene = new TextField("Eugene"); Button kollar = new Button("Kollar"); Object rows[][] = { { "2", andy, "Clark" }, { "1", "Carl", "Danowski" }, { "3", rich, gutierrez }, { "2", eugene, "Shumulinsky" }, { "1", "Charlie", "Cleveland" }, { "3", "Tad", kollar } };
Because the added AWT Components are standard components we can register the applet to listen to the various events that the components send out.
You're now ready to add the additional code, recompile, and view the applet. To see everything put together, refer to the source code file shipped with this documentation (SampleMultiColumnListbox.java).
Copyright ©
Taligent, Inc. 1996 - 1997.
Copyright © IBM Corporation 1996 - 1997.
All Rights Reserved.