我有一个带有自定义TreeModel和自定义TreeRenderer的JTree.树模型包含一堆不同类型的对象.
其中一种类型的显示方式与其他类型不同:显示的文本是对象的两个字段的串联.当我编辑单元格时,我想用编辑的文本更新其中一个字段.到目前为止,我的工作得很好.
其中一种类型的显示方式与其他类型不同:显示的文本是对象的两个字段的串联.当我编辑单元格时,我想用编辑的文本更新其中一个字段.到目前为止,我的工作得很好.
我的问题:编辑时显示的文本是令人困惑的
2个字段的完整连接值,即使您实际上只是编辑其中一个字段.所以我想只显示用户开始编辑时正在编辑的一个字段的内容.
我尝试使用自定义CellEditor来做这件事,我看到它应该工作的方式,这种方法在我的情况下似乎有点过分.我只是想在很多情况下改变显示的文本,所以我自然而然地希望实现它,而不是整个CellEditor来完成我的Tree的整个内容.
谢谢
解决方法
没有办法绕过自定义编辑器,这是最简单的解决方案:-)此外,您需要在数据领域中有一些方法可以适当地解释编辑值并更新自身,f.i.自定义节点.
F.i(稍后会发表评论,我这台机器上的蹩脚firefox正在把我推到墙上)
/** * Basic code stolen from @trashgod at * @see https://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(); } }); } }