import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.EventObject;
import javax.swing.AbstractCellEditor;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellEditor;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.DefaultTreeSelectionModel;
import javax.swing.tree.TreeCellEditor;
import javax.swing.tree.TreePath;
/**
* @ClassName: TreeDemo9
* @Description: 以key,value对为节点数据的树,包括树的节点显示、节点删除、节点添加、节点修改
* @author Li
* @date 2012-4-29 下午02:32:59
*
*/
public class TreeDemo9 extends JFrame {
private static final long serialVersionUID = 1L;
private JTree itree;
private JTextField ifld;
public TreeDemo9() {
itree = new JTree();
// 插入初始数据
DefaultMutableTreeNode root = new DefaultMutableTreeNode(new KeyValue(
"lhl", "god"));
DefaultMutableTreeNode other = new DefaultMutableTreeNode(new KeyValue(
"tongtong", "tiandao"));
root.add(other);
other = new DefaultMutableTreeNode(new KeyValue("xidian", "myschool"));
root.add(other);
DefaultTreeModel model = new DefaultTreeModel(root);
itree.setModel(model);
// 显示包括子节点的分支节点的把手
itree.setShowsRootHandles(true);
// 设置单元编辑器
// 使用DefaultTreeCellEditor帮助控制何时开启单元编辑器及其它的位置
itree.setCellEditor(new DefaultTreeCellEditor(itree,
new DefaultTreeCellRenderer(), new MyTreeCellEditor()));
itree.setEditable(true);
// 树的节点信息显示,即树节点选择事件
// 设置选择模型,只能一次选择一个节点
itree.getSelectionModel().setSelectionMode(
DefaultTreeSelectionModel.SINGLE_TREE_SELECTION);
itree.addTreeSelectionListener(new TreeSelectionListener() {
@Override
public void valueChanged(TreeSelectionEvent arg0) {
JTree tree = (JTree) arg0.getSource();
DefaultMutableTreeNode node = (DefaultMutableTreeNode) tree
.getLastSelectedPathComponent();
if(node!=null){//可能关闭分支节点,这时候没有被选中的节点
KeyValue keyvalue = (KeyValue) node.getUserObject();
ifld.setText(keyvalue.value);
}else
ifld.setText("");
}
});
// 添加节点删除,节点新建的右键
JPopupMenu menu=new JPopupMenu();
JMenuItem item=new JMenuItem("add");
item.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("add node!!");
DefaultMutableTreeNode node=(DefaultMutableTreeNode) itree.getLastSelectedPathComponent();
DefaultTreeModel model=(DefaultTreeModel)itree.getModel();
DefaultMutableTreeNode newnode=new DefaultMutableTreeNode(new KeyValue("new", "noe"));
model.insertNodeInto(newnode ,node, node.getChildCount());
itree.scrollPathToVisible(new TreePath(newnode.getPath()));
itree.setSelectionPath(new TreePath(newnode.getPath()));
}
});
menu.add(item);
item=new JMenuItem("delete");
item.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent arg0) {
System.out.println("delete node!!");
DefaultMutableTreeNode node=(DefaultMutableTreeNode)itree.getLastSelectedPathComponent();
DefaultTreeModel model=(DefaultTreeModel)itree.getModel();
model.removeNodeFromParent(node);
itree.setSelectionRow(0);
}
});
menu.add(item);
itree.addMouseListener(new MyTreeMouseAdapter(menu));
add(new JScrollPane(itree), BorderLayout.WEST);
ifld = new JTextField();
add(ifld, BorderLayout.CENTER);
}
public static void main(String[] args) {
TreeDemo9 it = new TreeDemo9();
it.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
it.pack();
it.setLocationRelativeTo(null);
// it.setLocation(it.getX() - 150, it.getY() - 150);
it.setSize(300, 300);
it.setVisible(true);
}
}
class MyTreeMouseAdapter extends MouseAdapter {
JPopupMenu imenu;
public MyTreeMouseAdapter(JPopupMenu amenu) {
imenu = amenu;
}
@Override
// 鼠标发开和鼠标按下都调用显示右键菜单,否则可能显示不出来,swing的bug吧
public void mousePressed(MouseEvent e) {
showPopupMenu(e);
}
@Override
public void mouseReleased(MouseEvent e) {
showPopupMenu(e);
}
private void showPopupMenu(MouseEvent e) {
if (e.isPopupTrigger()) {
JTree tree = (JTree) e.getSource();
TreePath path = tree.getPathForLocation(e.getX(), e.getY());
if (path != null&&path.getParentPath()!=null) {//没有父节点就是根节点
imenu.show(tree, e.getX(), e.getY());
tree.setSelectionPath(path);
}
}
}
}
class MyTreeCellEditor extends AbstractCellEditor implements TreeCellEditor {
private static final long serialVersionUID = 1L;
private KeyValue ikeyvalue;
private KeyValueFrame iframe;
private JLabel ilabel;
public MyTreeCellEditor() {
iframe = new KeyValueFrame(this);
ilabel = new JLabel();
}
@Override
public Object getCellEditorValue() {
return ikeyvalue;
}
@Override
public Component getTreeCellEditorComponent(JTree arg0, Object arg1,
boolean arg2, boolean arg3, boolean arg4, int arg5) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode) arg1;
ikeyvalue = (KeyValue) node.getUserObject();
ilabel.setText(ikeyvalue.key);
ilabel.setForeground(Color.red);
ilabel.setBackground(Color.red);// 没有效果,可能是JTree自己调整了吧
iframe.setKeyValue(ikeyvalue.key, ikeyvalue.value);
return ilabel;
}
@Override
public boolean isCellEditable(EventObject arg0) {
return true;
}
@Override
public boolean shouldSelectCell(EventObject arg0) {
iframe.pack();
iframe.setLocationRelativeTo(null);
// iframe.setLocation(iframe.getX() - iframe.getWidth() / 2, iframe.getY()
// - iframe.getHeight() / 2);
iframe.setVisible(true);
return true;
}
@Override
public void cancelCellEditing() {
iframe.setVisible(false);
super.cancelCellEditing();
}
@Override
public boolean stopCellEditing() {
iframe.setVisible(false);
KeyValue buf = iframe.getKeyValue();
if (buf.key.equals("")) {
super.stopCellEditing();
return false;
} else {
ikeyvalue = buf;
super.stopCellEditing();// 修改getCellEditorValue返回值后,在通知其他监听者
return true;
}
}
}
class KeyValue {
public String key;
public String value;
public KeyValue(String akey, String avalue) {
key = akey;
value = avalue;
}
@Override
public String toString() {
return key;
}
}
一个JTree的例子,参考网页包括 http://docs.oracle.com/javase/tutorial/uiswing/components/tree.html和 http://www.iteedu.com/plang/java/jtswingchxshj/index.php。其中单元编辑器部分是一种风格,swing一些复杂的组件都是使用的它。