如何使JPanel的组件作为JTree中的节点可用?

当我点击JButton时没有任何反应。 这甚至适用于我放入的JScrollPane(它显示但不会滚动)。 为什么JPanel不在前面? 我觉得有些东西必须被覆盖。 它应该是不是箭头的部分的扩展吗? 如果是这样,那怎么办?

import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.*; import javax.swing.tree.*; public class test { public test() { JTree tree = createTree(); tree.setToggleClickCount(0); tree.setRowHeight(50); tree.setCellRenderer(new PanelRenderer()); JFrame f = new JFrame(); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.add(new JScrollPane(tree)); f.setSize(400, 400); f.setLocation(200, 200); f.setVisible(true); } private JTree createTree() { int children = 4; int grandChildren = 3; DefaultMutableTreeNode root = new DefaultMutableTreeNode(); DefaultMutableTreeNode node; for (int j = 0; j < children; j++) { node = new DefaultMutableTreeNode(); root.add(node); for (int k = 0; k < grandChildren; k++) node.add(new DefaultMutableTreeNode()); } DefaultTreeModel model = new DefaultTreeModel(root); return new JTree(model); } public static void main(String[] args) { new test(); } } class PanelRenderer implements TreeCellRenderer { JPanel panel; public PanelRenderer() { panel = new JPanel(new BorderLayout()); } public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) { panel.add(new JLabel("aloha"), BorderLayout.WEST); JButton fg = new JButton("fg"); panel.add(fg, BorderLayout.EAST); fg.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent d) { System.out.println("hello"); } }); panel.setPreferredSize(new Dimension(200, 500)); return panel; } } 

这适用于MadProgrammer,他说Renderers和Editors会对你所放下的内容进行描述。 在此示例中,JButtons是可单击的。

 import javax.swing.*; import javax.swing.tree.*; import java.awt.event.*; import java.awt.*; import javax.swing.event.*; import java.util.*; public class test extends JFrame { public test() { super("TreeDemo"); setSize(500, 500); JPanel p = new JPanel(); p.setLayout(new BorderLayout()); JButton theParent = new JButton("Feature Set #1"); JButton thefeature = new JButton("sdfdsfds"); JButton feature2 = new JButton("Second Feature"); JButton feature3 = new JButton("Third Feature"); DefaultMutableTreeNode top = new DefaultMutableTreeNode(theParent, true); DefaultMutableTreeNode n1 = new DefaultMutableTreeNode(thefeature, true); DefaultMutableTreeNode n2 = new DefaultMutableTreeNode(feature2, true); DefaultMutableTreeNode n3 = new DefaultMutableTreeNode(feature3, false); n1.add(n3); top.add(n1); top.add(n2); JTree tree = new JTree(top); p.add(tree, BorderLayout.NORTH); getContentPane().add(p); TestRenderer tr = new TestRenderer(); TestEditor1 te = new TestEditor1(); tree.setEditable(true); tree.setCellRenderer(tr); tree.setCellEditor(te); } public class TestEditor1 implements TreeCellEditor { public TestEditor1() { } public void addCellEditorListener(CellEditorListener l) { } public void cancelCellEditing() { } public Object getCellEditorValue() { return this; } public boolean isCellEditable(EventObject evt) { if (evt instanceof MouseEvent) { MouseEvent mevt = (MouseEvent) evt; if (mevt.getClickCount() == 1) { return true; } } return false; } public void removeCellEditorListener(CellEditorListener l) { } public boolean shouldSelectCell(EventObject anEvent) { return true; } public boolean stopCellEditing() { return false; } public Component getTreeCellEditorComponent(JTree tree, Object value, boolean isSelected, boolean expanded, boolean leaf, int row) { DefaultMutableTreeNode temp = (DefaultMutableTreeNode) value; JComponent temp2 = (JComponent) temp.getUserObject(); return temp2; } } public class TestRenderer implements TreeCellRenderer { transient protected Icon closedIcon; transient protected Icon openIcon; public TestRenderer() { } public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) { DefaultMutableTreeNode temp = (DefaultMutableTreeNode) value; JComponent temp2 = (JComponent) temp.getUserObject(); temp2.setBackground(UIManager.getColor("Tree.textBackground")); return temp2; } public void setClosedIcon(Icon newIcon) { closedIcon = newIcon; } public void setOpenIcon(Icon newIcon) { openIcon = newIcon; } } public static void main(String args[]){ JFrame frame = new test(); frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); frame.pack(); frame.setVisible(true); } 

首先来看看Concepts:Editors和Renderers 。

渲染器只是一个“橡皮图章”,用于“标记”组件渲染的数据视图,它不是生命组件。 视图中的每个单元格都使用相同的渲染实例进行渲染。

另一方面,编辑器是一个可以响应用户交互的实时组件。 视图一次只有一个活动编辑器。

你的模型永远不应该携带组件,它们应该只是携带你需要的状态信息,以便渲染(和编辑)它。

TreeEditor

 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; } } }