?
http://www.phptr.com/articles/printerfriendly.asp?p=26327&rl=1
und
package treeDemo02;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Collection;
import java.util.EventObject;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.WindowConstants;
import javax.swing.event.CellEditorListener;
import javax.swing.event.ChangeEvent;
import javax.swing.event.TreeModelListener;
import javax.swing.tree.DefaultTreeCellEditor;
import javax.swing.tree.TreeModel;
import javax.swing.tree.TreePath;
/**
* The Frame.
*
* @author user
*/
public class TreeTest extends javax.swing.JFrame {
private JScrollPane sp;
private CustomTree tree;
public static void main(String[] args) {
TreeTest inst = new TreeTest();
inst.setVisible(true);
}
public TreeTest() {
super();
initGUI();
}
private void initGUI() {
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
sp = new JScrollPane();
tree = new CustomTree(new TestTreeModel());
tree.setEditable(true);
tree.setCellEditor(new TestCellEditor(tree));
sp.setViewportView(tree);
getContentPane().add(sp);
pack();
setSize(400, 300);
}
}
/**
* The TreeModel.
*
* @author user
*/
class TestTreeModel implements TreeModel{
private Node root = new Node(){
@Override
public String toString() {
return getContent();
}
};
/*
* methods
*/
public Object getRoot() {
return root;
}
public Object getChild(Object parent, int index) {
return ((Node) parent).getChildAt(index);
}
public int getChildCount(Object parent) {
return ((Node) parent).getChildCount();
}
public boolean isLeaf(Object node) {
return ((Node) node).isLeaf();
}
public int getIndexOfChild(Object parent, Object child) {
return ((Node) parent).getChildIndexOf(((Node) child).getContent());
}
/*
* default methods unimplemented!?
*/
public void valueForPathChanged(TreePath path, Object newValue) {
Node node = (Node) path.getLastPathComponent();
String sz = newValue.toString();
node.setContent(sz);
}
public void addTreeModelListener(TreeModelListener l) {
// no adding
}
public void removeTreeModelListener(TreeModelListener l) {
// no removing
}
}
/**
* The node type.
*
* @author user
*/
class Node{
protected String content;
private Node[] children;
private Node parent;
private Entry entry = null;
private int level;
/**
* ctor for root node
*/
public Node(){
init( "rootnode", null, 0);
}
public Node(String someText, Node parentNode){
init(someText, parentNode, parentNode.getLevel() + 1);
}
public Node(Entry someEntry, Node parentNode){
entry = someEntry;
init(someEntry.getElementAt(someEntry.getSelectedElementIndex()) , parentNode, parentNode.getLevel() + 1);
}
/*
* methods
*/
private void init(String text, Node parentNode, int thisLevel){
setLevel(thisLevel);
setContent(text);
setParent(parentNode);
}
public Node getChildAt(int index) {
generateChildNodes();
return children[index];
}
public int getChildIndexOf(String szChildContent) {
for(int cnt = 0; cnt < children.length; ++cnt){
if(children[cnt].getContent().equals(szChildContent))
return cnt;
}
return -1;
}
public String getContent() {
return content;
}
public boolean isLeaf() {
return (getLevel() == 2);
}
public int getChildCount(){
if(children == null){
generateChildNodes();
}
return children.length;
}
/**
* Contains the structure of the tree.
*/
private void generateChildNodes(){
if(children == null){
if(level == 0){
children = new Node[2];
children[0] = new Node("box", this);
children[1] = new Node("text", this);
}
if(level == 1){
children = new Node[1];
if(this.getContent().equals("box")){
children[0] = new Node(new Entry(0, "tripple click me", "click", "last"), this);
}else if(this.getContent().equals("text")){
children[0] = new Node("This text should be editable!", this);
}
}
}
}
public String toString(){
return getContent();
}
public Entry getEntry() {
return entry;
}
public void setEntry(Entry newEntry) {
this.entry = newEntry;
setContent(entry.getElementAt(entry.getSelectedElementIndex()));
}
public int getLevel() {
return level;
}
public void setLevel(int level) {
this.level = level;
}
public Node getParent() {
return parent;
}
public void setParent(Node parent) {
this.parent = parent;
}
public void setContent(String content) {
this.content = content;
}
public boolean hasEntryBox(){
if(!this.isLeaf()) return false;
return this.entry != null;
}
public boolean hasTextField(){
if(!this.isLeaf()) return false;
return this.entry == null;
}
}
/**
* The entry type used for the JComboBox later on.
*
* @author user
*/
class Entry{
private String[] elements;
private int iSelected = 0;
/*
* Constructor.
*/
public Entry(int selectedIndex, String...items ){
elements = items;
setSelectedIndex(selectedIndex);
}
/*
* methods
*/
public int getElementsCount(){
return elements.length;
}
public String getElementAt(int index){
return elements[index];
}
public int getSelectedElementIndex(){
return iSelected;
}
public void setSelectedIndex(int idx){
iSelected = idx;
}
@Override
public String toString() {
return getElementAt(getSelectedElementIndex() );
}
}
/**
* The TreeCellEditor class.
*
* @author user
*/
class TestCellEditor extends DefaultTreeCellEditor{
private Collection<CellEditorListener> listeners = new ArrayList<CellEditorListener>();
private DefaultComboBoxModel model;
private JComboBox box;
private JTextField tf;
private Component selected;
public TestCellEditor(JTree tree) {
super(tree, null);
}
/*
* methods
*/
public Component getTreeCellEditorComponent(JTree tree, Object value, boolean isSelected, boolean expanded, boolean leaf, int row) {
cancelCellEditing();
Node node = (Node) value;
if(node.hasEntryBox()){
model = new DefaultComboBoxModel();
box = new JComboBox(model);
box.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
stopCellEditing();
}
});
Entry entry = node.getEntry();
model.removeAllElements();
for(int cnt = 0; cnt < entry.getElementsCount(); ++cnt){
model.addElement(entry.getElementAt(cnt));
}
model.setSelectedItem(model.getElementAt(entry.getSelectedElementIndex()));
this.selected = this.box;
return box;
}else if(node.hasTextField()){
tf = new JTextField(node.getContent());
tf.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
stopCellEditing();
}
});
this.selected = this.tf;
return tf;
}
return null;
}
public Object getCellEditorValue() {
if(selected.equals(this.box)){
String[] elements = new String[model.getSize()];
for(int cnt = 0; cnt < elements.length; ++cnt){
elements[cnt] = (String) model.getElementAt(cnt);
}
int iSelected = model.getIndexOf( model.getSelectedItem());
return new Entry(iSelected, elements);
}else if(selected.equals(this.tf)){
return tf.getText();
}
return null;
}
public boolean isCellEditable(EventObject anEvent) {
if(anEvent instanceof MouseEvent){
return (((MouseEvent)anEvent).getClickCount() > 2);
}else{
return true;
}
}
public boolean shouldSelectCell(EventObject anEvent) {
return true;
}
public boolean stopCellEditing() {
ChangeEvent event = new ChangeEvent(this);
for(CellEditorListener listener : listeners){
listener.editingStopped(event);
}
return true;
}
public void cancelCellEditing() {
ChangeEvent event = new ChangeEvent(this);
for(CellEditorListener listener:listeners){
listener.editingCanceled(event);
}
}
public void addCellEditorListener(CellEditorListener l) {
listeners.add(l);
}
public void removeCellEditorListener(CellEditorListener l) {
listeners.remove(l);
}
}
/**
*
* @author user
*/
class CustomTree extends JTree{
public CustomTree(TestTreeModel model){
super(model);
}
public boolean isPathEditable(TreePath path){
if (isEditable()){
return getModel().isLeaf( path.getLastPathComponent());
}
return false;
}
}