EmailTree.java Source code

Java tutorial

Introduction

Here is the source code for EmailTree.java

Source

/*
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);
            }
        }
    }
}