How do you make components of JPanel as a node in JTree usable?

旧时模样 提交于 2019-11-29 15:59:08

Start by taking a look at Concepts: Editors and Renderers.

A renderer is simply a "rubber stamp" which is used to "stamp" the view of the data that the component is renderering, it's not a life component. Each cell in the view is rendered using the same instance of the renderering.

A editor on the other hand is a live component, which can respond to user interaction. A view only has one active editor at a time.

You models should never carry components, they should simply carry state information you need in order to render (and edit) it.

import java.awt.Component;
import java.awt.EventQueue;
import javax.swing.AbstractCellEditor;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeCellEditor;
import javax.swing.tree.TreeCellRenderer;

public class Test {

    public Test() {

        JTree tree = createTree();
        tree.setToggleClickCount(0);
        tree.setCellRenderer(new StateRenderer());
        tree.setCellEditor(new StateEditor());
        tree.setEditable(true);

        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(new JScrollPane(tree));

        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    private JTree createTree() {
        int children = 4;
        int grandChildren = 2;
        DefaultMutableTreeNode root = new DefaultMutableTreeNode(new State("Films", false));
        DefaultMutableTreeNode node;

        String[] cat = {"Sci-Fi", "Fantasy", "Action", "Comedy"};
        String[][] films = {
            {"Star Wars", "Star Trek"},
            {"Lord of the Rings", "Conan"},
            {"Terminator", "Transformers"},
            {"Cheaper by the Doze", "Father of the Bride"}
        };
        for (int j = 0; j < children; j++) {
            node = new DefaultMutableTreeNode(new State(cat[j], false));
            root.add(node);
            for (int k = 0; k < grandChildren; k++) {
                node.add(new DefaultMutableTreeNode(new State(films[j][k], false)));
            }
        }
        DefaultTreeModel model = new DefaultTreeModel(root);
        return new JTree(model);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }
                new Test();
            }
        });
    }

    public class State {

        private String text;
        private boolean selected;

        public State(String text, boolean selected) {
            this.text = text;
            this.selected = selected;
        }

        public String getText() {
            return text;
        }

        public boolean isSelected() {
            return selected;
        }

        public void setSelected(boolean selected) {
            this.selected = selected;
        }

    }

    public class StateEditor extends AbstractCellEditor implements TreeCellEditor {

        //JPanel panel;
        private JCheckBox checkBox;

        private State editorValue;

        public StateEditor() {
            checkBox = new JCheckBox();
            checkBox.setOpaque(false);
        }

        @Override
        public Object getCellEditorValue() {
            editorValue.setSelected(checkBox.isSelected());
            return editorValue;
        }

        @Override
        public Component getTreeCellEditorComponent(JTree tree, Object value, boolean isSelected, boolean expanded, boolean leaf, int row) {

            System.out.println("...");

            if (value instanceof DefaultMutableTreeNode) {
                DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
                State state = (State) node.getUserObject();
                editorValue = state;
                checkBox.setText(state.getText());
                checkBox.setSelected(state.isSelected());
            } else {
                checkBox.setText("??");
                checkBox.setSelected(false);
            }

            return checkBox;

        }

    }

    public class StateRenderer implements TreeCellRenderer {

        private JCheckBox checkBox;

        public StateRenderer() {
            checkBox = new JCheckBox();
            checkBox.setOpaque(false);
        }

        @Override
        public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded,
                        boolean leaf, int row, boolean hasFocus) {

            if (value instanceof DefaultMutableTreeNode) {
                DefaultMutableTreeNode node = (DefaultMutableTreeNode) value;
                State state = (State) node.getUserObject();
                checkBox.setText(state.getText());
                checkBox.setSelected(state.isSelected());
            } else {
                checkBox.setText("??");
                checkBox.setSelected(false);
            }

            if (selected) {
                checkBox.setBackground(UIManager.getColor("Tree.selectionBackground"));
                checkBox.setForeground(UIManager.getColor("Tree.selectionForeground"));
            } else {
                checkBox.setForeground(tree.getForeground());
            }

            checkBox.setOpaque(selected);

            return checkBox;
        }
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!