easy and fast JTree Cell Editor

后端 未结 2 575
闹比i
闹比i 2020-12-03 23:26

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

相关标签:
2条回答
  • 2020-12-03 23:29

    A custom editor is required. MyTreeCellEditor, illustrated here, shows one approach. It updates an arbitrary attribute of a userObject, which is named Resource and held in a DefaultMutableTreeNode. As the attribute is text, it also uses the DefaultTreeCellRenderer. Your custom TreeModel probably manages a similar userObject that is the parent of your "objects of different types."

    0 讨论(0)
  • 2020-12-03 23:32

    There is no way around a custom editor and it is the shortest solution possible :-) Additionally, you'll need some means in the data realm that can interpret the editing value as appropriate and update itself, f.i. a custom node.

    F.i (will comment it later, my lame firefox on this machine is driving me up 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();
                }
            });
        }
    }
    
    0 讨论(0)
提交回复
热议问题