在不更改 userObject 的情况下更改 TreeNode 的名称
Change name of a TreeNode without changing the userObject
我有一个带有 DefaultTreeModel 和一些 DefaultMutableTreeNodes 的 JTree。
我正在寻找一种方法来更改节点的 displayName,但我不想更改 userObject,因为我需要它完全符合它的设置。
此外,我不能简单地覆盖我的 userObject 的 toString 方法,因为我在我的代码中的其他地方使用了 toString,在这些地方对此方法的相应更改是不合适的。
那么问题来了,是否可以通过上述条件实现节点重命名呢?
提前致谢
乌鸦
编辑:
一个小代码示例:
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JTree;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.DefaultMutableTreeNode;
public class TreeNodeRenameExample extends JFrame {
private JPanel contentPane;
private JTree tree;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
TreeNodeRenameExample frame = new TreeNodeRenameExample();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public TreeNodeRenameExample() {
initGUI();
}
private void initGUI() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
this.contentPane = new JPanel();
this.contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
this.contentPane.setLayout(new BorderLayout(0, 0));
setContentPane(this.contentPane);
{
this.tree = new JTree();
this.tree.setModel(new DefaultTreeModel(
new DefaultMutableTreeNode("JTree") {
{
add(new DefaultMutableTreeNode(new testObj("Peter")));
add(new DefaultMutableTreeNode(new testObj("Stephen")));
}
}
));
this.contentPane.add(this.tree, BorderLayout.CENTER);
}
}
public class testObj {
private String name;
public testObj(String name) {
this.name = name;
}
public String toString() {
return "Name: " + this.name;
}
}
}
我想做的是将 TreeNodes 上的文本更改为不同的内容。例如 "MyTreeNode1" 和 "MyTreeNode2" 但我想保留这两个节点的 userObject 我的 testObj 和 toString mehtod 也不能更改...
如果您想对树用户对象使用 TestObj
class 并且不想更改 toString
方法,您可以使用自定义 TreeNode
class(而不是 DefaultMutableTreeNode
class)。使用此自定义 class,可以覆盖 toString
方法以不(始终)使用用户对象,而是使用替代名称。
自定义 TreeNode
class 例如可以称为 AliasTreeNode
并且可以在创建节点时或稍后发生某些事件时接收别名(= 备用节点名称) . AliasTreeNode.toString
方法检查是否设置了别名;如果有别名,则返回此别名,否则返回 DefaultMutableTreeNode.toString()
。
您的代码的这个修改版本演示了该方法。节点在构造时获得别名,按下按钮时获得不同的别名:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.tree.*;
public class TreeNodeRenameExample extends JFrame {
private JPanel contentPane;
private JTree tree;
private AliasTreeNode peterNode = new AliasTreeNode(new TestObj("Peter"),
"Alias 1");
private AliasTreeNode stephenNode = new AliasTreeNode(new TestObj("Stephen"),
"Alias 2");
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
TreeNodeRenameExample frame = new TreeNodeRenameExample();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public TreeNodeRenameExample() {
initGUI();
}
private void initGUI() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
this.contentPane = new JPanel();
this.contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
this.contentPane.setLayout(new BorderLayout(0, 0));
setContentPane(this.contentPane);
{
this.tree = new JTree();
this.tree.setModel(new DefaultTreeModel(
new DefaultMutableTreeNode("JTree") {
{
add(peterNode);
add(stephenNode);
}
}
));
this.contentPane.add(this.tree, BorderLayout.CENTER);
JButton changeNamesButton = new JButton("Change node names");
this.contentPane.add(changeNamesButton, BorderLayout.SOUTH);
changeNamesButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
peterNode.setAlias("MyTreeNode1");
stephenNode.setAlias("MyTreeNode2");
}
});
}
}
public class TestObj {
private String name;
public TestObj(String name) {
this.name = name;
}
public String toString() {
return "Name: " + this.name;
}
}
public class AliasTreeNode extends DefaultMutableTreeNode {
private String alias;
public AliasTreeNode(Object userObject, String alias) {
super(userObject);
this.alias = alias;
}
public void setAlias(String alias) {
this.alias = alias;
// Notify the tree model of the changed node
// (see
((DefaultTreeModel) tree.getModel()).nodeChanged(this);
}
@Override
public String toString() {
return (alias != null) ? alias : super.toString();
}
}
}
我有一个带有 DefaultTreeModel 和一些 DefaultMutableTreeNodes 的 JTree。
我正在寻找一种方法来更改节点的 displayName,但我不想更改 userObject,因为我需要它完全符合它的设置。
此外,我不能简单地覆盖我的 userObject 的 toString 方法,因为我在我的代码中的其他地方使用了 toString,在这些地方对此方法的相应更改是不合适的。
那么问题来了,是否可以通过上述条件实现节点重命名呢?
提前致谢
乌鸦
编辑: 一个小代码示例:
import java.awt.BorderLayout;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JTree;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.DefaultMutableTreeNode;
public class TreeNodeRenameExample extends JFrame {
private JPanel contentPane;
private JTree tree;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
TreeNodeRenameExample frame = new TreeNodeRenameExample();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public TreeNodeRenameExample() {
initGUI();
}
private void initGUI() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
this.contentPane = new JPanel();
this.contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
this.contentPane.setLayout(new BorderLayout(0, 0));
setContentPane(this.contentPane);
{
this.tree = new JTree();
this.tree.setModel(new DefaultTreeModel(
new DefaultMutableTreeNode("JTree") {
{
add(new DefaultMutableTreeNode(new testObj("Peter")));
add(new DefaultMutableTreeNode(new testObj("Stephen")));
}
}
));
this.contentPane.add(this.tree, BorderLayout.CENTER);
}
}
public class testObj {
private String name;
public testObj(String name) {
this.name = name;
}
public String toString() {
return "Name: " + this.name;
}
}
}
我想做的是将 TreeNodes 上的文本更改为不同的内容。例如 "MyTreeNode1" 和 "MyTreeNode2" 但我想保留这两个节点的 userObject 我的 testObj 和 toString mehtod 也不能更改...
如果您想对树用户对象使用 TestObj
class 并且不想更改 toString
方法,您可以使用自定义 TreeNode
class(而不是 DefaultMutableTreeNode
class)。使用此自定义 class,可以覆盖 toString
方法以不(始终)使用用户对象,而是使用替代名称。
自定义 TreeNode
class 例如可以称为 AliasTreeNode
并且可以在创建节点时或稍后发生某些事件时接收别名(= 备用节点名称) . AliasTreeNode.toString
方法检查是否设置了别名;如果有别名,则返回此别名,否则返回 DefaultMutableTreeNode.toString()
。
您的代码的这个修改版本演示了该方法。节点在构造时获得别名,按下按钮时获得不同的别名:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.tree.*;
public class TreeNodeRenameExample extends JFrame {
private JPanel contentPane;
private JTree tree;
private AliasTreeNode peterNode = new AliasTreeNode(new TestObj("Peter"),
"Alias 1");
private AliasTreeNode stephenNode = new AliasTreeNode(new TestObj("Stephen"),
"Alias 2");
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
TreeNodeRenameExample frame = new TreeNodeRenameExample();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public TreeNodeRenameExample() {
initGUI();
}
private void initGUI() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
this.contentPane = new JPanel();
this.contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
this.contentPane.setLayout(new BorderLayout(0, 0));
setContentPane(this.contentPane);
{
this.tree = new JTree();
this.tree.setModel(new DefaultTreeModel(
new DefaultMutableTreeNode("JTree") {
{
add(peterNode);
add(stephenNode);
}
}
));
this.contentPane.add(this.tree, BorderLayout.CENTER);
JButton changeNamesButton = new JButton("Change node names");
this.contentPane.add(changeNamesButton, BorderLayout.SOUTH);
changeNamesButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
peterNode.setAlias("MyTreeNode1");
stephenNode.setAlias("MyTreeNode2");
}
});
}
}
public class TestObj {
private String name;
public TestObj(String name) {
this.name = name;
}
public String toString() {
return "Name: " + this.name;
}
}
public class AliasTreeNode extends DefaultMutableTreeNode {
private String alias;
public AliasTreeNode(Object userObject, String alias) {
super(userObject);
this.alias = alias;
}
public void setAlias(String alias) {
this.alias = alias;
// Notify the tree model of the changed node
// (see
((DefaultTreeModel) tree.getModel()).nodeChanged(this);
}
@Override
public String toString() {
return (alias != null) ? alias : super.toString();
}
}
}