|
How do you perk up a plain-looking list of items in a display so that each
category of item stands out? One way to do it is to color code each category.
Then the items in each category will show in their respective color. That's
what an engineer on the Java Developer Connection (JDC) team recently did
to enhance the status panel of an application used to send JDC email. And
he did it by using JLists and Cell Renderers
Here, for example, is a program that uses JList to create a list of three
items. The
Notice the use of
Because the program uses the default cell renderer, the list items can only include plain text and icons. In this example, the list is plain text only. Nothing fancy here. JLists and Customized Cell RenderersIf you want to to do something fancier with a list, like display background color in different cells, you need to do the following:
Create a class that models the items in the listHere's an example of a class that models the items in a list. The class encapsulates the background color and text.
Create a class that implements the
|
class MyCellRenderer extends JLabel
implements ListCellRenderer {
public MyCellRenderer () {
// Don't paint behind the component
setOpaque(true);
}
// Set the attributes of the
//class and return a reference
public Component
getListCellRendererComponent(JList list,
Object value, // value to display
int index, // cell index
boolean iss, // is selected
boolean chf) // cell has focus?
{
// Set the text and
//background color for rendering
setText(((ListItem)value).getValue());
setBackground(((
ListItem)value).getColor());
// Set a border if the
//list item is selected
if (iss) {
setBorder(BorderFactory.createLineBorder(
Color.blue, 2));
} else {
setBorder(BorderFactory.createLineBorder(
list.getBackground(), 2));
}
return this;
}
}
|
Notice a few things about MyCellRenderer:
JLabel,
another JFC Project Swing component.
JLabel
is used to display text or images. Extending JLabel
is a convenient
way to display selectable text or images.getListCellRendererComponent,
the only method
in the ListCellRenderer
interface . This method sets
the attributes of the class and then returns a reference to the class.
setText
method uses the string value stored in the ListItem object
to set the JLabel
text, and the setBackground
method
uses the color value stored in the ListItem object to set the background color
of the JLabel.
iss
parameter of
getListCellRendererComponent
is true, MyCellRenderer
uses the setBorder
method to
set a two-pixel blue border around the list item. The border around the
item signals that the item is selected.setCellRender method
Here's a class that creates a JList object using the cell renderer that was created in the previous example.
It's a class that calls the setCellRenderer method and specifies as an argument
an instance of the MyCellRenderer class.
public class CustomList {
// Create a window
public static void main(
String args[]) {
JFrame frame = new JFrame(
"Custom List Demo");
frame.addWindowListener(
new WindowAdapter() {
public void windowClosing(
WindowEvent e) {
System.exit(0);
}
});
// Use a list model that
//allows for updates
DefaultListModel model =
new DefaultListModel();
JList statusList =
new JList(model);
statusList.setCellRenderer(
new MyCellRenderer());
// Create some dummy list items.
ListItem li = new ListItem(
Color.cyan, "test line one");
model.addElement(li);
li = new ListItem(
Color.yellow, "foo foo foo");
model.addElement(li);
li = new ListItem(
Color.green, "quick brown fox");
model.addElement(li);
// Display the list
JPanel panel = new JPanel();
panel.add(statusList);
frame.getContentPane().add(
"Center", panel);
frame.pack();
frame.setVisible(true);
}
}
|
CustomList creates an instance of the DefaultListModel
class. Remember this allows for changes to the items in the list. It then
creates the JList object, statusList.
Next it uses the custom cell renderer;
notice the method call to statusList.setCellRenderer(newMyCellRenderer()).
Now to put the ListItem, MyCellRenderer, and CustomList
classes into a complete program for demonstration.
import javax.swing.JList;
import javax.swing.ListCellRenderer;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JFrame;
import javax.swing.BorderFactory;
import javax.swing.DefaultListModel;
import java.awt.Color;
import java.awt.Component;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
class ListItem {
private Color color;
private String value;
public ListItem(Color c, String s) {
color = c;
value = s;
}
public Color getColor() {
return color;
}
public String getValue() {
return value;
}
}
class MyCellRenderer extends
JLabel implements ListCellRenderer {
public MyCellRenderer () {
// Don't paint behind the component
setOpaque(true);
}
// Set the attributes of the
//class and return a reference
public Component
getListCellRendererComponent(JList list,
Object value, // value to display
int index, // cell index
boolean iss, // is selected
boolean chf) // cell has focus?
{
// Set the text and color
//background for rendering
setText(((ListItem)value).getValue(
));
setBackground(((
ListItem)value).getColor());
// Set a border if the list
//item is selected
if (iss) {
setBorder(
BorderFactory.createLineBorder(
Color.blue, 2));
} else {
setBorder(
BorderFactory.createLineBorder(
list.getBackground(), 2));
}
return this;
}
}
public class CustomList {
// Create a window
public static void main(String args[]) {
JFrame frame = new JFrame(
"Custom List Demo");
frame.addWindowListener(
new WindowAdapter() {
public void windowClosing(
WindowEvent e) {
System.exit(0);
}
});
// Use a list model that
//allows for updates
DefaultListModel model =
new DefaultListModel();
JList statusList =
new JList(model);
statusList.setCellRenderer(
new MyCellRenderer());
// Create some dummy
//list items.
ListItem li = new ListItem(
Color.cyan, "test line one");
model.addElement(li);
li = new ListItem(
Color.yellow, "foo foo foo");
model.addElement(li);
li = new ListItem(
Color.green, "quick brown fox");
model.addElement(li);
// Display the list
JPanel panel = new JPanel();
panel.add(statusList);
frame.getContentPane(
).add("Center", panel);
frame.pack();
frame.setVisible(true);
}
}
|
If you run the program, you'll see the following display:

Exactly what you want, a list whose list items display different color backgrounds.
And what about the "real thing," the status panel of the application used by the JDC staff? Here's what that looks like.
The customization possibilities don't end here. By having the MyCellRenderer class extend a component other than JLabel, you can create a wide variety of visually engaging lists. Imagine using the JSlider class instead of JLabel to render your list elements. The possibilities are endless. To learn more about the JList class and other Swing components, take a look at the Swing Short Courses.
![]()
Gregory Layer is a senior engineer in the JDC group. He is the principle architect of the Bug Parade and the JDC bulk mailing system. He invites any feedback you have about the article or the code, such as enhancements or potential bugs. If you have comments, please send them to : Greg Layer.
Edward Ort is a staff member of the Java Developer Connection. He has written extensively about relational database technology and programming languages.
|
| ||||||||||||