我正在尝试修改标准的 Swing JTree 以混合带有和不带有复选框的节点。这是一个例子:
当我尝试选中/取消选中其中一个复选框(本示例中的“用户 01”节点)时,树会丢失节点:
我的代码是对这个例子的改编:http ://forums.sun.com/thread.jspa?threadID=5321084&start=13 。
而不是像这样在 DefaultMutableTreeNode 中嵌入 JCheckBox:
new DefaultMutableTreeNode(new CheckBoxNode("Accessibility", true));
我认为创建一个从 DefaultMutableTreeNode 派生的模型节点更有意义,我称之为 JTreeNode。此类自动将 DefaultMutableTreeNode 的 UserObject 设置为 JCheckBox。TreeCellRenderer 使用类的 ShowCheckBox 属性来确定是使用 JCheckBox 还是 DefaultTreeCellRenderer。JTreeNode 是这样使用的:
JTreeNode user01 = new JTreeNode("User 01");
user01.setShowCheckBox(true);
user01.setSelected(true);
我相信问题出在实现 TreeCellEditor 的类上,特别是在 getCellEditorValue() 或 getTreeCellEditorComponent() 方法中。我怀疑这个问题与 getCellEditorValue() 返回 DefaultMutableTreeNode 的派生而不是更简单的模型实例有关。
public Object getCellEditorValue() {
JCheckBox checkBox = renderer.getCheckBoxRenderer();
JTreeNode node = new JTreeNode(checkBox.getText());
node.setShowCheckBox(true);
node.setSelected(checkBox.isSelected());
return node;
}
public Component getTreeCellEditorComponent(JTree tree, Object value, boolean isSelected, boolean expanded, boolean leaf, int row) {
Component editor = renderer.getTreeCellRendererComponent(tree, value, true, expanded, leaf, row, true);
// editor always selected / focused
ItemListener itemListener = new ItemListener() {
public void itemStateChanged(ItemEvent itemEvent) {
if (stopCellEditing()) {
fireEditingStopped();
}
}
};
if (editor instanceof JCheckBox) {
((JCheckBox) editor).addItemListener(itemListener);
}
return editor;
}
这是 TreeCellRender 的 getTreeCellRendererComponent() 方法:
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
Component component;
//if object being passed for rendering is a JTreeNode that should show a JCheckBox, attempt to render it so
if (((JTreeNode) value).getShowCheckBox()) {
String stringValue = tree.convertValueToText(value, selected, expanded, leaf, row, false);
//set default JCheckBox rendering
checkBoxRenderer.setText(stringValue);
checkBoxRenderer.setSelected(false); //not checked
checkBoxRenderer.setEnabled(tree.isEnabled());
if (selected) {
//removed colorization
//checkBoxRenderer.setForeground(selectionForeground);
//checkBoxRenderer.setBackground(selectionBackground);
}
else {
checkBoxRenderer.setForeground(textForeground);
checkBoxRenderer.setBackground(textBackground);
}
//DefaultMutableTreeNode
if ((value != null) && (value instanceof JTreeNode)) {
//userObject should be a JTreeNode instance
//DefaultMutableTreeNode
//Object userObject = ((JTreeNode) value).getUserObject();
//if it is
//if (userObject instanceof JTreeNode) {
//cast as a JTreeNode
//JTreeNode node = (JTreeNode) userObject;
JTreeNode node = (JTreeNode) value;
//set JCheckBox settings to match JTreeNode's settings
checkBoxRenderer.setText(node.getText());
checkBoxRenderer.setSelected(node.isSelected());
//}
}
component = checkBoxRenderer;
}
//if not, render the default
else {
component = defaultRenderer.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
}
return component;
}
任何想法都非常感谢。