【发布时间】:2011-01-04 17:47:43
【问题描述】:
我正在尝试修改标准 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;
}
非常感谢任何想法。
【问题讨论】:
-
这是基于截图的纯粹猜测,但可能是渲染问题。您可以在节点消失后尝试使用 SwingUtilities.updateComponentTreeUI。如果这有帮助,那么树只是没有正确重绘。
-
来吧伙计们,为什么没有人支持这个问题? 26 次浏览,你们中没有一个人认为这家伙投入了创造一个好问题的工作?嘘,你们都是骗子。 /咆哮
标签: java swing rendering jtree jcheckbox