简单快速的JTree Cell Editor

我有一个带有自定义TreeModel和自定义TreeRenderer的JTree。 树模型包含一堆不同类型的对象。 其中一种类型的显示方式与其他类型不同:显示的文本是对象的两个字段的串联。 当我编辑单元格时,我想用编辑的文本更新其中一个字段。 到目前为止,我的工作得很好。

我的问题:当编辑时显示的文本是2个字段的完整连接值时,即使您实际上只是编辑其中一个字段,也会让人感到困惑。 所以我想只显示用户开始编辑时正在编辑的一个字段的内容。

我尝试使用自定义CellEditor来做这件事,我看到它应该工作的方式,这种方法在我的情况下似乎有点过分。 我只是想在很多情况下改变显示的文本,所以我自然而然地希望实现它,而不是整个CellEditor来完成我的Tree的整个内容。

是否有更快速,更简单的方法,或者我必须使用自定义编辑器?

谢谢

没有办法绕过自定义编辑器,它是最简单的解决方案:-)此外,您需要在数据领域中有一些方法可以适当地解释编辑值并更新自身,自定义节点。

Fi(稍后会评论,我这台机器上的蹩脚firefox正在把我推上墙)

/** * Basic code stolen from @trashgod at * @see http://stackoverflow.com/a/11113648/230513 */ public class TreeEditDemo extends JPanel { private JTree tree; private DefaultMutableTreeNode root; private DefaultTreeCellEditor editor; public TreeEditDemo() { super.setLayout(new GridLayout()); root = new DefaultMutableTreeNode("Nodes"); root.add(new MyResourceNode(new Resource("one", "first"))); root.add(new MyResourceNode(new Resource("two", "first"))); tree = new JTree(root); tree.setEditable(true); editor = new MyTreeCellEditor(tree, (DefaultTreeCellRenderer) tree.getCellRenderer()); tree.setCellEditor(editor); this.add(new JScrollPane(tree)); } private static class MyTreeCellEditor extends DefaultTreeCellEditor { public MyTreeCellEditor(JTree tree, DefaultTreeCellRenderer renderer) { super(tree, renderer); } @Override public Component getTreeCellEditorComponent(JTree tree, Object value, boolean isSelected, boolean expanded, boolean leaf, int row) { if (value instanceof MyResourceNode) { value = ((MyResourceNode) value).getName(); } return super.getTreeCellEditorComponent(tree, value, isSelected, expanded, leaf, row); } @Override public boolean isCellEditable(EventObject e) { return super.isCellEditable(e) && ((TreeNode) lastPath.getLastPathComponent()).isLeaf(); } } public static class MyResourceNode extends DefaultMutableTreeNode { /** * @param resource */ public MyResourceNode(Resource resource) { super(resource); } @Override public void setUserObject(Object userObject) { if (userObject instanceof String) { setName((String) userObject); } else if (userObject instanceof Resource) { super.setUserObject(userObject); } } public void setName(String name) { if (getUserObject() != null) { getUserObject().setName(name); } } public String getName() { if (getUserObject() != null) { return getUserObject().getName(); } return null; } @Override public Resource getUserObject() { return (Resource) super.getUserObject(); } } private static class Resource { String name; private String category; public Resource(String name, String category) { this.name = name; this.category = category; } public void setName(String name) { this.name = name; } public String getName() { return name; } @Override public String toString() { // BEWARE: don't do this in production code! return name + " (" + category + ")"; } } private void display() { JFrame f = new JFrame("TreeEditorDemo"); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.add(this); f.pack(); f.setLocationRelativeTo(null); f.setVisible(true); } public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { @Override public void run() { new TreeEditDemo().display(); } }); } } 

需要自定义编辑器。 这里说明的MyTreeCellEditor显示了一种方法。 它更新userObject的任意属性,该属性名为Resource并保存在DefaultMutableTreeNode 。 由于属性是文本,因此它还使用DefaultTreeCellRenderer 。 您的自定义TreeModel可能管理一个类似的userObject ,它是“不同类型的对象”的父对象。