import java.awt.Component;

import java.util.EventObject;

import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.event.CellEditorListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeCellEditor;
import javax.swing.tree.TreeCellRenderer;

public class CheckBoxTreeDemo
{
  public CheckBoxTreeDemo()
  {
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.add(getCheckboxTree());
    frame.pack();
    frame.setVisible(true);
  }

  private JComponent getCheckboxTree()
  {
    DefaultMutableTreeNode root = new DefaultMutableTreeNode("Lunch");
    DefaultMutableTreeNode sandwiches = new
    DefaultMutableTreeNode("Sandwiches");
    DefaultMutableTreeNode cheese = new DefaultMutableTreeNode("Cheese");
    DefaultMutableTreeNode beef = new DefaultMutableTreeNode("Beef");
    DefaultMutableTreeNode ham = new DefaultMutableTreeNode("Ham");

    root.add(sandwiches);
    sandwiches.add(cheese);
    sandwiches.add(beef);
    sandwiches.add(ham);
   
    DefaultTreeModel model = new DefaultTreeModel(root);
    JTree tree = new JTree(model);
   
    tree.setCellEditor(new Editor());
    tree.setEditable(true);
    tree.setRowHeight(30);
    tree.setCellRenderer(new CheckboxCellRenderer());
    
    JScrollPane sp = new JScrollPane(tree);    
    return sp;
  }

  public static void main(String[] args)
  {
    SwingUtilities.invokeLater(new Runnable()
    {
      public void run()
      {
        new CheckBoxTreeDemo();
      }
    });
  }

  private class Editor extends JPanel implements TreeCellEditor
  {  

    public Editor()
    {
      setOpaque(false);
      checkbox = new JCheckBox();
      add(checkbox);
    }

    public Component getTreeCellEditorComponent(JTree tree, Object value,
                                                boolean isSelected,
                                                boolean expanded,
                                                boolean leaf, int row)
    {
      checkbox.setText(value.toString());
      checkbox.setSelected(false);
     
      //return checkbox;
      return this;
    }

    public Object getCellEditorValue()
    {
      return checkbox.isSelected();
    }

    public boolean isCellEditable(EventObject anEvent)
    {
      return true;
    }

    public boolean shouldSelectCell(EventObject anEvent)
    {
      return true;
    }

    public boolean stopCellEditing()
    {
      return true;
    }

    public void cancelCellEditing()
    {
    }

    public void addCellEditorListener(CellEditorListener l)
    {
    }

    public void removeCellEditorListener(CellEditorListener l)
    {
    }
    
    private JCheckBox checkbox;
  }
  
 
  private class CheckboxCellRenderer extends JPanel implements TreeCellRenderer
  {
    public CheckboxCellRenderer()
    {
      setOpaque(false);
      checkbox = new JCheckBox();
      add(checkbox);
    }

    public Component getTreeCellRendererComponent(JTree tree, Object value,
                                                  boolean selected,
                                                  boolean expanded,
                                                  boolean leaf, int row,
                                                  boolean hasFocus)
    {
      checkbox.setText(value.toString());
      checkbox.setSelected(false);
      return this;
    }
   
    private JCheckBox checkbox;
  }
}