Simple and fast JTree Cell Editor

I have a JTree with a custom TreeModel and a custom TreeRenderer. The tree model contains a bunch of objects of different types. One of these types is displayed differently than the others: the displayed text is a concatenation of two fields of an object. When I edit a cell, I want to update one of these fields with the edited text. So far I have worked very well.

My problem: it is confusing when the text displayed during editing is the full concatenated value of 2 fields, even if you are actually editing one of the fields. Therefore, I want to display only the contents of one field that you are editing when the user starts editing.

I tried to do this using a special CellEditor, and I saw how it should work, and the approach seems redundant in my case. I just want to change the displayed text in one of many cases, so naturally, I want to implement this, and not the whole CellEditor for the entire contents of my tree.

Is there a faster and easier way to do this, or do I need to use my own editor?

thanks

+5
source share
2 answers

There is no way to create a custom editor, and this is the shortest possible solution :-) In addition, you will need some tools in the data area that can interpret the editing value appropriately and update themselves, fi user node.

Fi (will comment on this later, my lame firefox on this machine pushes me to the walls)

/** * 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(); } }); } } 
+8
source

A custom editor is required. MyTreeCellEditor , pictured here , shows one approach. It updates an arbitrary userObject attribute called Resource and is stored in DefaultMutableTreeNode . Because the attribute is text, it also uses the DefaultTreeCellRenderer . Your custom TreeModel probably controls a similar userObject , which is the parent of your "objects of different types."

+3
source

Source: https://habr.com/ru/post/890010/


All Articles