Build a tree and populate it with custom renderers and editors
/*
Java Swing, 2nd Edition
By Marc Loy, Robert Eckstein, Dave Wood, James Elliott, Brian Cole
ISBN: 0-596-00408-7
Publisher: O'Reilly
*/
// EmailTree.java
//A Simple test to see how we can build a tree and populate it. This
//application also uses custom renderers and editors.
//
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.util.EventObject;
import java.util.Hashtable;
import java.util.Vector;
import javax.swing.CellEditor;
import javax.swing.ImageIcon;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellEditor;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.TreeCellEditor;
public class EmailTree extends JFrame {
JTree tree;
String[][] addresses = {
{ "paul@work.domain", "ptw@work.domain", "other@volunteer.domain" },
{ "paul@home.domain" },
{ "damian@work.domain", "damian@bigisp.domain" },
{ "paged@pager.domain" },
{ "damian@home.domain", "mosh@home.domain" }, { "angela@home.com" } };
public EmailTree() {
super("Hashtable Test");
setSize(400, 300);
setDefaultCloseOperation(EXIT_ON_CLOSE); // 1.3 & higher
// addWindowListener(new BasicWindowMonitor()); // 1.1 & 1.2
}
public void init() {
Hashtable h = new Hashtable();
Hashtable paul = new Hashtable();
paul.put("Work", addresses[0]);
paul.put("Home", addresses[1]);
Hashtable damian = new Hashtable();
damian.put("Work", addresses[2]);
damian.put("Pager", addresses[3]);
damian.put("Home", addresses[4]);
Hashtable angela = new Hashtable();
angela.put("Home", addresses[5]);
h.put("Paul", paul);
h.put("Damian", damian);
h.put("Angela", angela);
tree = new JTree(h);
DefaultTreeCellRenderer renderer = (DefaultTreeCellRenderer) tree
.getCellRenderer();
renderer.setOpenIcon(new ImageIcon("mailboxdown.gif"));
renderer.setClosedIcon(new ImageIcon("mailboxup.gif"));
renderer.setLeafIcon(new ImageIcon("letter.gif"));
EmailTreeCellEditor emailEditor = new EmailTreeCellEditor();
DefaultTreeCellEditor editor = new DefaultTreeCellEditor(tree,
renderer, emailEditor);
tree.setCellEditor(editor);
tree.setEditable(true);
getContentPane().add(tree, BorderLayout.CENTER);
}
public static void main(String args[]) {
EmailTree tt = new EmailTree();
tt.init();
tt.setVisible(true);
}
}
//EmailTreeCellEditor.java
//An editor that actually manages two separate editors: one for folders
//(nodes) that uses a combobox; and one for files (leaves) that uses a
//textfield.
//
class EmailTreeCellEditor implements TreeCellEditor {
EditorComboBox nodeEditor;
EmailEditor leafEditor;
CellEditor currentEditor;
static String[] emailTypes = { "Home", "Work", "Pager", "Spam" };
public EmailTreeCellEditor() {
EmailEditor tf = new EmailEditor();
EditorComboBox cb = new EditorComboBox(emailTypes);
nodeEditor = cb;
leafEditor = tf;
}
public Component getTreeCellEditorComponent(JTree tree, Object value,
boolean isSelected, boolean expanded, boolean leaf, int row) {
if (leaf) {
currentEditor = leafEditor;
leafEditor.setText(value.toString());
} else {
currentEditor = nodeEditor;
nodeEditor.setSelectedItem(((DefaultMutableTreeNode) value)
.getUserObject());
}
return (Component) currentEditor;
}
public Object getCellEditorValue() {
return currentEditor.getCellEditorValue();
}
// All cells are editable in this example...
public boolean isCellEditable(EventObject event) {
return true;
}
public boolean shouldSelectCell(EventObject event) {
return currentEditor.shouldSelectCell(event);
}
public boolean stopCellEditing() {
return currentEditor.stopCellEditing();
}
public void cancelCellEditing() {
currentEditor.cancelCellEditing();
}
public void addCellEditorListener(CellEditorListener l) {
nodeEditor.addCellEditorListener(l);
leafEditor.addCellEditorListener(l);
}
public void removeCellEditorListener(CellEditorListener l) {
nodeEditor.removeCellEditorListener(l);
leafEditor.removeCellEditorListener(l);
}
}
//EditorComboBox.java
//A CellEditor JComboBox subclass for use with Trees (and possibly tables).
//This version will work with any list of values passed as an Object[].
//
class EditorComboBox extends JComboBox implements CellEditor {
String value;
Vector listeners = new Vector();
// Mimic all the constructors people expect with ComboBoxes.
public EditorComboBox(Object[] list) {
super(list);
setEditable(false);
value = list[0].toString();
// Listen to our own action events so that we know when to stop editing.
addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
if (stopCellEditing()) {
fireEditingStopped();
}
}
});
}
// Implement the CellEditor methods.
public void cancelCellEditing() {
}
// Stop editing only if the user entered a valid value.
public boolean stopCellEditing() {
try {
value = (String) getSelectedItem();
if (value == null) {
value = (String) getItemAt(0);
}
return true;
} catch (Exception e) {
// Something went wrong.
return false;
}
}
public Object getCellEditorValue() {
return value;
}
// Start editing when the right mouse button is clicked.
public boolean isCellEditable(EventObject eo) {
if ((eo == null)
|| ((eo instanceof MouseEvent) && (((MouseEvent) eo)
.isMetaDown()))) {
return true;
}
return false;
}
public boolean shouldSelectCell(EventObject eo) {
return true;
}
// Add support for listeners.
public void addCellEditorListener(CellEditorListener cel) {
listeners.addElement(cel);
}
public void removeCellEditorListener(CellEditorListener cel) {
listeners.removeElement(cel);
}
protected void fireEditingStopped() {
if (listeners.size() > 0) {
ChangeEvent ce = new ChangeEvent(this);
for (int i = listeners.size() - 1; i >= 0; i--) {
((CellEditorListener) listeners.elementAt(i))
.editingStopped(ce);
}
}
}
}
//EmailEditor.java
//An extension of JTextField that requires an "@" somewhere in the field.
//Meant to be used as a cell editor within a JTable or JTree.
//
class EmailEditor extends JTextField implements CellEditor {
String value = "";
Vector listeners = new Vector();
// Mimic all the constructors people expect with text fields.
public EmailEditor() {
this("", 5);
}
public EmailEditor(String s) {
this(s, 5);
}
public EmailEditor(int w) {
this("", w);
}
public EmailEditor(String s, int w) {
super(s, w);
// Listen to our own action events so that we know when to stop editing.
addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
if (stopCellEditing()) {
fireEditingStopped();
}
}
});
}
// Implement the CellEditor methods.
public void cancelCellEditing() {
setText("");
}
// Stop editing only if the user entered a valid value.
public boolean stopCellEditing() {
try {
String tmp = getText();
int at = tmp.indexOf("@");
if (at != -1) {
value = tmp;
return true;
}
return false;
} catch (Exception e) {
// Something went wrong (most likely we don't have a valid integer).
return false;
}
}
public Object getCellEditorValue() {
return value;
}
// Start editing when the right mouse button is clicked.
public boolean isCellEditable(EventObject eo) {
if ((eo == null)
|| ((eo instanceof MouseEvent) && (((MouseEvent) eo)
.isMetaDown()))) {
return true;
}
return false;
}
public boolean shouldSelectCell(EventObject eo) {
return true;
}
// Add support for listeners.
public void addCellEditorListener(CellEditorListener cel) {
listeners.addElement(cel);
}
public void removeCellEditorListener(CellEditorListener cel) {
listeners.removeElement(cel);
}
protected void fireEditingStopped() {
if (listeners.size() > 0) {
ChangeEvent ce = new ChangeEvent(this);
for (int i = listeners.size() - 1; i >= 0; i--) {
((CellEditorListener) listeners.elementAt(i))
.editingStopped(ce);
}
}
}
}
Related examples in the same category