JTree - TreeCellEditor 实现更改节点对象 Class
JTree - TreeCellEditor Implemetation changing the Node Object Class
我正在尝试构建一个带有 TestObjectCheckBoxNode 叶子的 JTree,其中每个叶子都包含一个 TestObject,一切似乎都正常工作,除非我选中叶子中的框,它正在将节点从 TestObjectCheckBoxNode 更改为 CheckBoxNode 超类。我知道这发生在 TreeCellEditor 实现中,特别是 CheckBoxNodeEditor:getCellEditorValue(),因为它正在从该节点的 UI 创建更新的 TreeCellRenderer。
CheckBoxNode checkBoxNode =
new CheckBoxNode(checkBoxPanel.label.getText(),
checkBoxPanel.checkBox.isSelected());
return checkBoxNode;
我完全不知道如何以我可以访问 CheckBoxNodeEditor 中选定节点的 TestObject 的方式执行此操作,所以我可以这样做:
TestObjectCheckBoxNode testObjectCheckBoxNode =
new TestObjectCheckBoxNode(testObject,
checkBoxPanel.checkBox.isSelected());
return testObjectCheckBoxNode;
下面是完整的代码:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseEvent;
import java.awt.font.TextAttribute;
import java.util.Collections;
import java.util.Enumeration;
import java.util.EventObject;
import java.util.Vector;
import javax.swing.AbstractCellEditor;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.UIManager;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.TreeCellEditor;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
public class JCheckBoxTreeTest
{
private TestObjectCheckBoxTree tree;
public static void main(String... s)
{
new JCheckBoxTreeTest();
}
public JCheckBoxTreeTest()
{
JFrame frame = new JFrame("JCheckBoxTreeTest Tree");
Vector rootVector = new Category("Root", new Object[]
{
new Category("POI",
new TestObjectCheckBoxNode[] {
new TestObjectCheckBoxNode(new TestObject("TestObject 1"),true),
new TestObjectCheckBoxNode(new TestObject("TestObject 2"),true),
}),
});
tree = new TestObjectCheckBoxTree(rootVector);
tree.addTreeSelectionListener(new TreeSelectionListener()
{
public void valueChanged(TreeSelectionEvent e)
{
DefaultMutableTreeNode node = (DefaultMutableTreeNode)tree.getLastSelectedPathComponent();
if (node == null) return;
Object userObject = ((DefaultMutableTreeNode) node).getUserObject();
System.err.println("node: " + node.toString());
System.err.println("userObject: " + userObject.toString());
}
});
tree.expandAll();
JScrollPane scrollPane = new JScrollPane(tree);
frame.getContentPane().add(scrollPane, BorderLayout.NORTH);
frame.setSize(360, 600);
frame.setVisible(true);
}
class TestObject
{
String name;
public TestObject(String inStr)
{
name = inStr;
}
}
public class CheckBoxNode
{
String text;
boolean selected;
public CheckBoxNode(String text, boolean selected)
{
this.text = text;
this.selected = selected;
}
public boolean isSelected() { return selected; }
public void setSelected(boolean newValue) { selected = newValue; }
public String getText() { return text; }
public void setText(String newValue) { text = newValue; }
public String toString() { return getClass().getName() + "[" + text + "/" + selected + "]"; }
}
public class TestObjectCheckBoxNode extends CheckBoxNode
{
TestObject testObject;
public TestObjectCheckBoxNode(TestObject testObject, boolean selected)
{
super(testObject.name, selected);
this.testObject = testObject;
}
}
public class CheckBoxTree extends JTree
{
public CheckBoxTree(Vector rootVector)
{
super(rootVector);
CheckBoxNodeRenderer renderer = new CheckBoxNodeRenderer();
setCellRenderer(renderer);
setCellEditor(new CheckBoxNodeEditor());
setEditable(true);
}
public void expandAll()
{
expandAll(this, new TreePath(((DefaultMutableTreeNode)this.treeModel.getRoot()).getPath()), true);
}
private void expandAll(JTree tree, TreePath path, boolean expand) {
TreeNode node = (TreeNode) path.getLastPathComponent();
if (node.getChildCount() >= 0) {
Enumeration<? extends TreeNode> enumeration = node.children();
while (enumeration.hasMoreElements()) {
TreeNode treeNode = enumeration.nextElement();
TreePath treePath = path.pathByAddingChild(treeNode);
expandAll(tree, treePath, expand);
}
}
if (expand) {
tree.expandPath(path);
} else {
tree.collapsePath(path);
}
}
}
class CheckBoxPanel extends JPanel
{
public JCheckBox checkBox;
public JLabel label;
public CheckBoxPanel()
{
super();
checkBox = new JCheckBox();
label = new JLabel();
checkBox.setBorder(new EmptyBorder(0, 0, 0, 0));
add(checkBox);
add(label);
}
}
class CheckBoxNodeRenderer implements TreeCellRenderer
{
private CheckBoxPanel leafRenderer = new CheckBoxPanel();
private DefaultTreeCellRenderer nonLeafRenderer = new DefaultTreeCellRenderer();
Color selectionBorderColor, selectionForeground, selectionBackground,
textForeground, textBackground;
protected CheckBoxPanel getLeafRenderer() {
return leafRenderer;
}
public CheckBoxNodeRenderer() {
Font fontValue;
fontValue = UIManager.getFont("Tree.font");
if (fontValue != null)
{
leafRenderer.checkBox.setFont(fontValue);
leafRenderer.label.setFont(fontValue);
//set the nonLeaf text to bold
nonLeafRenderer.setFont(fontValue.deriveFont(Collections.singletonMap(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD)));
}
Boolean booleanValue = (Boolean) UIManager.get("Tree.drawsFocusBorderAroundIcon");
leafRenderer.checkBox.setFocusPainted((booleanValue != null) && (booleanValue.booleanValue()));
selectionBorderColor = UIManager.getColor("Tree.selectionBorderColor");
selectionForeground = UIManager.getColor("Tree.selectionForeground");
selectionBackground = UIManager.getColor("Tree.selectionBackground");
textForeground = UIManager.getColor("Tree.textForeground");
textBackground = UIManager.getColor("Tree.textBackground");
}
public Component getTreeCellRendererComponent(JTree tree, Object value,
boolean selected, boolean expanded, boolean leaf, int row,
boolean hasFocus)
{
Component returnValue;
if (leaf)
{
String stringValue = tree.convertValueToText(value, selected,
expanded, leaf, row, false);
leafRenderer.checkBox.setSelected(false);
leafRenderer.label.setText(stringValue);
leafRenderer.setEnabled(tree.isEnabled());
if (selected) {
leafRenderer.setForeground(selectionForeground);
leafRenderer.setBackground(selectionBackground);
} else {
leafRenderer.setForeground(textForeground);
leafRenderer.setBackground(textBackground);
}
if ((value != null) && (value instanceof DefaultMutableTreeNode)) {
Object userObject = ((DefaultMutableTreeNode) value)
.getUserObject();
if (userObject instanceof CheckBoxNode) {
CheckBoxNode node = (CheckBoxNode) userObject;
leafRenderer.checkBox.setSelected(node.isSelected());
leafRenderer.label.setText(node.getText());
}
}
returnValue = leafRenderer;
}
else
{
returnValue = nonLeafRenderer.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
}
return returnValue;
}
}
class CheckBoxNodeEditor extends AbstractCellEditor implements TreeCellEditor {
CheckBoxNodeRenderer renderer = new CheckBoxNodeRenderer();
TestObject testObject;
ChangeEvent changeEvent = null;
public Object getCellEditorValue()
{
CheckBoxPanel checkBoxPanel = renderer.getLeafRenderer();
if (testObject != null)
{
return new TestObjectCheckBoxNode(testObject, checkBoxPanel.checkBox.isSelected());
}
else
{
return new CheckBoxNode(checkBoxPanel.label.getText(), checkBoxPanel.checkBox.isSelected());
}
}
public boolean isCellEditable(EventObject event) {
boolean returnValue = false;
if (event instanceof MouseEvent) {
MouseEvent mouseEvent = (MouseEvent) event;
JTree tree = (JTree)event.getSource();
TreePath path = tree.getPathForLocation(mouseEvent.getX(), mouseEvent.getY());
if (path != null) {
Object node = path.getLastPathComponent();
if ((node != null) && (node instanceof DefaultMutableTreeNode)) {
DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) node;
Object userObject = treeNode.getUserObject();
returnValue = ((treeNode.isLeaf()) && (userObject instanceof CheckBoxNode));
}
}
}
return returnValue;
}
public Component getTreeCellEditorComponent(JTree tree, Object value,
boolean selected, boolean expanded, boolean leaf, int row) {
Object userObject = ((DefaultMutableTreeNode)value).getUserObject();
if (userObject instanceof TestObjectCheckBoxNode)
{
testObject = ((TestObjectCheckBoxNode)userObject).testObject;
}
else
{
testObject = null;
}
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 CheckBoxPanel)
{
((CheckBoxPanel) editor).checkBox.addItemListener(itemListener);
}
return editor;
}
}
class Category extends Vector
{
String name;
public Category(String name)
{
this.name = name;
}
public Category(String name, Object elements[])
{
this.name = name;
for (int i = 0, n = elements.length; i < n; i++)
{
add(elements[i]);
}
}
public String toString()
{
return "[" + name + "]";
}
}
class TestObjectCheckBoxTree extends CheckBoxTree
{
public TestObjectCheckBoxTree(Vector rootVector)
{
super(rootVector);
}
}
}
编辑树节点时Swing调用CheckBoxNodeEditor.getTreeCellEditorComponent()
,当前节点作为value
参数。稍后当您停止编辑它调用的节点时 CheckBoxNodeEditor.getCellEditorValue()
.
你需要做什么:如果 getTreeCellEditorComponent()
中的 value
是一个 TestObjectCheckBoxNode
然后将其 testObject
字段存储到 [=19= 的实例字段中].
稍后调用 getCellEditorValue()
时,如果存储了 testObject
,您可以 return a TestObjectCheckBoxNode
,否则 return a ChechBoxNode
.
代码可能如下所示(缩写)示例:
class CheckBoxNodeEditor extends AbstractCellEditor implements TreeCellEditor {
CheckBoxNodeRenderer renderer = new CheckBoxNodeRenderer();
TestObject testObject;
public Object getCellEditorValue() {
CheckBoxPanel checkBoxPanel = renderer.getLeafRenderer();
if (testObject != null) {
return new TestObjectCheckBoxNode(testObject, checkBoxPanel.checkBox.isSelected());
} else {
return new CheckBoxNode(checkBoxPanel.label.getText(), checkBoxPanel.checkBox.isSelected());
}
}
public Component getTreeCellEditorComponent(
JTree tree, Object value,
boolean selected, boolean expanded, boolean leaf, int row
) {
Object realValue = ((DefaultMutableTreeNode) value).getUserObject();
if (realValue instanceof TestObjectCheckBoxNode n) {
testObject = n.testObject;
} else {
testObject = null;
}
// remaining code from your getTreeCellEditorComponent method
}
// other code removed for brevity
}
如果你不能使用新的pattern matching instanceof operator(因为你没有使用Java16或更高版本)getTreeCellEditorComponent
开头的if
语句需要写成
public Component getTreeCellEditorComponent(
JTree tree, Object value,
boolean selected, boolean expanded, boolean leaf, int row
) {
Object realValue = ((DefaultMutableTreeNode) value).getUserObject();
if (realValue instanceof TestObjectCheckBoxNode) {
TestObjectCheckBoxNode n = (TestObjectCheckBoxNode) value;
testObject = n.testObject;
} else {
testObject = null;
}
// remaining code from your getTreeCellEditorComponent method
}
为什么getTreeCellEditorComponent
中的value
是DefaultMutableTreeNode
?
解释是 JTree
只适用于 TreeNode
个实例。如果您使用 Vector
、Hashtable
或 Object[]
创建 JTree
,它会将这些包含在 JTree.DynamicUtilTreeNode
实例中的值包装起来,并将您的对象设置为 userObject
属性 在他们身上。
JTree.DynamicUtilTreeNode
扩展自 DefaultMutableTreeNode
。
我正在尝试构建一个带有 TestObjectCheckBoxNode 叶子的 JTree,其中每个叶子都包含一个 TestObject,一切似乎都正常工作,除非我选中叶子中的框,它正在将节点从 TestObjectCheckBoxNode 更改为 CheckBoxNode 超类。我知道这发生在 TreeCellEditor 实现中,特别是 CheckBoxNodeEditor:getCellEditorValue(),因为它正在从该节点的 UI 创建更新的 TreeCellRenderer。
CheckBoxNode checkBoxNode =
new CheckBoxNode(checkBoxPanel.label.getText(),
checkBoxPanel.checkBox.isSelected());
return checkBoxNode;
我完全不知道如何以我可以访问 CheckBoxNodeEditor 中选定节点的 TestObject 的方式执行此操作,所以我可以这样做:
TestObjectCheckBoxNode testObjectCheckBoxNode =
new TestObjectCheckBoxNode(testObject,
checkBoxPanel.checkBox.isSelected());
return testObjectCheckBoxNode;
下面是完整的代码:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseEvent;
import java.awt.font.TextAttribute;
import java.util.Collections;
import java.util.Enumeration;
import java.util.EventObject;
import java.util.Vector;
import javax.swing.AbstractCellEditor;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.UIManager;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.TreeCellEditor;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
public class JCheckBoxTreeTest
{
private TestObjectCheckBoxTree tree;
public static void main(String... s)
{
new JCheckBoxTreeTest();
}
public JCheckBoxTreeTest()
{
JFrame frame = new JFrame("JCheckBoxTreeTest Tree");
Vector rootVector = new Category("Root", new Object[]
{
new Category("POI",
new TestObjectCheckBoxNode[] {
new TestObjectCheckBoxNode(new TestObject("TestObject 1"),true),
new TestObjectCheckBoxNode(new TestObject("TestObject 2"),true),
}),
});
tree = new TestObjectCheckBoxTree(rootVector);
tree.addTreeSelectionListener(new TreeSelectionListener()
{
public void valueChanged(TreeSelectionEvent e)
{
DefaultMutableTreeNode node = (DefaultMutableTreeNode)tree.getLastSelectedPathComponent();
if (node == null) return;
Object userObject = ((DefaultMutableTreeNode) node).getUserObject();
System.err.println("node: " + node.toString());
System.err.println("userObject: " + userObject.toString());
}
});
tree.expandAll();
JScrollPane scrollPane = new JScrollPane(tree);
frame.getContentPane().add(scrollPane, BorderLayout.NORTH);
frame.setSize(360, 600);
frame.setVisible(true);
}
class TestObject
{
String name;
public TestObject(String inStr)
{
name = inStr;
}
}
public class CheckBoxNode
{
String text;
boolean selected;
public CheckBoxNode(String text, boolean selected)
{
this.text = text;
this.selected = selected;
}
public boolean isSelected() { return selected; }
public void setSelected(boolean newValue) { selected = newValue; }
public String getText() { return text; }
public void setText(String newValue) { text = newValue; }
public String toString() { return getClass().getName() + "[" + text + "/" + selected + "]"; }
}
public class TestObjectCheckBoxNode extends CheckBoxNode
{
TestObject testObject;
public TestObjectCheckBoxNode(TestObject testObject, boolean selected)
{
super(testObject.name, selected);
this.testObject = testObject;
}
}
public class CheckBoxTree extends JTree
{
public CheckBoxTree(Vector rootVector)
{
super(rootVector);
CheckBoxNodeRenderer renderer = new CheckBoxNodeRenderer();
setCellRenderer(renderer);
setCellEditor(new CheckBoxNodeEditor());
setEditable(true);
}
public void expandAll()
{
expandAll(this, new TreePath(((DefaultMutableTreeNode)this.treeModel.getRoot()).getPath()), true);
}
private void expandAll(JTree tree, TreePath path, boolean expand) {
TreeNode node = (TreeNode) path.getLastPathComponent();
if (node.getChildCount() >= 0) {
Enumeration<? extends TreeNode> enumeration = node.children();
while (enumeration.hasMoreElements()) {
TreeNode treeNode = enumeration.nextElement();
TreePath treePath = path.pathByAddingChild(treeNode);
expandAll(tree, treePath, expand);
}
}
if (expand) {
tree.expandPath(path);
} else {
tree.collapsePath(path);
}
}
}
class CheckBoxPanel extends JPanel
{
public JCheckBox checkBox;
public JLabel label;
public CheckBoxPanel()
{
super();
checkBox = new JCheckBox();
label = new JLabel();
checkBox.setBorder(new EmptyBorder(0, 0, 0, 0));
add(checkBox);
add(label);
}
}
class CheckBoxNodeRenderer implements TreeCellRenderer
{
private CheckBoxPanel leafRenderer = new CheckBoxPanel();
private DefaultTreeCellRenderer nonLeafRenderer = new DefaultTreeCellRenderer();
Color selectionBorderColor, selectionForeground, selectionBackground,
textForeground, textBackground;
protected CheckBoxPanel getLeafRenderer() {
return leafRenderer;
}
public CheckBoxNodeRenderer() {
Font fontValue;
fontValue = UIManager.getFont("Tree.font");
if (fontValue != null)
{
leafRenderer.checkBox.setFont(fontValue);
leafRenderer.label.setFont(fontValue);
//set the nonLeaf text to bold
nonLeafRenderer.setFont(fontValue.deriveFont(Collections.singletonMap(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD)));
}
Boolean booleanValue = (Boolean) UIManager.get("Tree.drawsFocusBorderAroundIcon");
leafRenderer.checkBox.setFocusPainted((booleanValue != null) && (booleanValue.booleanValue()));
selectionBorderColor = UIManager.getColor("Tree.selectionBorderColor");
selectionForeground = UIManager.getColor("Tree.selectionForeground");
selectionBackground = UIManager.getColor("Tree.selectionBackground");
textForeground = UIManager.getColor("Tree.textForeground");
textBackground = UIManager.getColor("Tree.textBackground");
}
public Component getTreeCellRendererComponent(JTree tree, Object value,
boolean selected, boolean expanded, boolean leaf, int row,
boolean hasFocus)
{
Component returnValue;
if (leaf)
{
String stringValue = tree.convertValueToText(value, selected,
expanded, leaf, row, false);
leafRenderer.checkBox.setSelected(false);
leafRenderer.label.setText(stringValue);
leafRenderer.setEnabled(tree.isEnabled());
if (selected) {
leafRenderer.setForeground(selectionForeground);
leafRenderer.setBackground(selectionBackground);
} else {
leafRenderer.setForeground(textForeground);
leafRenderer.setBackground(textBackground);
}
if ((value != null) && (value instanceof DefaultMutableTreeNode)) {
Object userObject = ((DefaultMutableTreeNode) value)
.getUserObject();
if (userObject instanceof CheckBoxNode) {
CheckBoxNode node = (CheckBoxNode) userObject;
leafRenderer.checkBox.setSelected(node.isSelected());
leafRenderer.label.setText(node.getText());
}
}
returnValue = leafRenderer;
}
else
{
returnValue = nonLeafRenderer.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
}
return returnValue;
}
}
class CheckBoxNodeEditor extends AbstractCellEditor implements TreeCellEditor {
CheckBoxNodeRenderer renderer = new CheckBoxNodeRenderer();
TestObject testObject;
ChangeEvent changeEvent = null;
public Object getCellEditorValue()
{
CheckBoxPanel checkBoxPanel = renderer.getLeafRenderer();
if (testObject != null)
{
return new TestObjectCheckBoxNode(testObject, checkBoxPanel.checkBox.isSelected());
}
else
{
return new CheckBoxNode(checkBoxPanel.label.getText(), checkBoxPanel.checkBox.isSelected());
}
}
public boolean isCellEditable(EventObject event) {
boolean returnValue = false;
if (event instanceof MouseEvent) {
MouseEvent mouseEvent = (MouseEvent) event;
JTree tree = (JTree)event.getSource();
TreePath path = tree.getPathForLocation(mouseEvent.getX(), mouseEvent.getY());
if (path != null) {
Object node = path.getLastPathComponent();
if ((node != null) && (node instanceof DefaultMutableTreeNode)) {
DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) node;
Object userObject = treeNode.getUserObject();
returnValue = ((treeNode.isLeaf()) && (userObject instanceof CheckBoxNode));
}
}
}
return returnValue;
}
public Component getTreeCellEditorComponent(JTree tree, Object value,
boolean selected, boolean expanded, boolean leaf, int row) {
Object userObject = ((DefaultMutableTreeNode)value).getUserObject();
if (userObject instanceof TestObjectCheckBoxNode)
{
testObject = ((TestObjectCheckBoxNode)userObject).testObject;
}
else
{
testObject = null;
}
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 CheckBoxPanel)
{
((CheckBoxPanel) editor).checkBox.addItemListener(itemListener);
}
return editor;
}
}
class Category extends Vector
{
String name;
public Category(String name)
{
this.name = name;
}
public Category(String name, Object elements[])
{
this.name = name;
for (int i = 0, n = elements.length; i < n; i++)
{
add(elements[i]);
}
}
public String toString()
{
return "[" + name + "]";
}
}
class TestObjectCheckBoxTree extends CheckBoxTree
{
public TestObjectCheckBoxTree(Vector rootVector)
{
super(rootVector);
}
}
}
编辑树节点时Swing调用CheckBoxNodeEditor.getTreeCellEditorComponent()
,当前节点作为value
参数。稍后当您停止编辑它调用的节点时 CheckBoxNodeEditor.getCellEditorValue()
.
你需要做什么:如果 getTreeCellEditorComponent()
中的 value
是一个 TestObjectCheckBoxNode
然后将其 testObject
字段存储到 [=19= 的实例字段中].
稍后调用 getCellEditorValue()
时,如果存储了 testObject
,您可以 return a TestObjectCheckBoxNode
,否则 return a ChechBoxNode
.
代码可能如下所示(缩写)示例:
class CheckBoxNodeEditor extends AbstractCellEditor implements TreeCellEditor {
CheckBoxNodeRenderer renderer = new CheckBoxNodeRenderer();
TestObject testObject;
public Object getCellEditorValue() {
CheckBoxPanel checkBoxPanel = renderer.getLeafRenderer();
if (testObject != null) {
return new TestObjectCheckBoxNode(testObject, checkBoxPanel.checkBox.isSelected());
} else {
return new CheckBoxNode(checkBoxPanel.label.getText(), checkBoxPanel.checkBox.isSelected());
}
}
public Component getTreeCellEditorComponent(
JTree tree, Object value,
boolean selected, boolean expanded, boolean leaf, int row
) {
Object realValue = ((DefaultMutableTreeNode) value).getUserObject();
if (realValue instanceof TestObjectCheckBoxNode n) {
testObject = n.testObject;
} else {
testObject = null;
}
// remaining code from your getTreeCellEditorComponent method
}
// other code removed for brevity
}
如果你不能使用新的pattern matching instanceof operator(因为你没有使用Java16或更高版本)getTreeCellEditorComponent
开头的if
语句需要写成
public Component getTreeCellEditorComponent(
JTree tree, Object value,
boolean selected, boolean expanded, boolean leaf, int row
) {
Object realValue = ((DefaultMutableTreeNode) value).getUserObject();
if (realValue instanceof TestObjectCheckBoxNode) {
TestObjectCheckBoxNode n = (TestObjectCheckBoxNode) value;
testObject = n.testObject;
} else {
testObject = null;
}
// remaining code from your getTreeCellEditorComponent method
}
为什么getTreeCellEditorComponent
中的value
是DefaultMutableTreeNode
?
解释是 JTree
只适用于 TreeNode
个实例。如果您使用 Vector
、Hashtable
或 Object[]
创建 JTree
,它会将这些包含在 JTree.DynamicUtilTreeNode
实例中的值包装起来,并将您的对象设置为 userObject
属性 在他们身上。
JTree.DynamicUtilTreeNode
扩展自 DefaultMutableTreeNode
。