我开发了一个应用程序来搜索JTree
中的节点。只要单击“获取原始树”按钮,就应使用原始数据填充clonedRoot
。所有处理都在clonedRoot
上进行。
除了更新的clonedRoot
未在面板上呈现外,一切正常(扣除控制台输出)。
clonedRoot填充了原始数据
if(ae.getSource()==getOriginalTree)
{
System.out.println("Get original tree");
System.out.println("Nodes present under cloned Root before deep copying");
DisplayNodes(clonedRoot);
getDeepCopy();
System.out.println("Nodes present under cloned Root after deep copying");
DisplayNodes(clonedRoot);
DefaultTreeModel newModel = new DefaultTreeModel(clonedRoot);
clonedTree.setModel(newModel);
for (int i = 0; i < clonedTree.getRowCount(); i++)
{
clonedTree.expandRow(i);
}
System.out.println("Updated tree");
}
执行搜索操作后clonedRoot
Console Output on clicking "Get Original Tree"-
Get original tree
Nodes present under cloned Root before deep copying
A
A1
Cloning done
Nodes present under cloned Root after deep copying
A
A1
A2
A3
B
B1
B2
B3
C
C1
C2
C3
D
D1
D2
D3
E
E1
E2
E3
Updated tree
Initialization Code in ctor
{
root = new DefaultMutableTreeNode("Root");
tree = new JTree(root);
setLAF();
populateTree();
copyBuilder = new DeepCopyJTreeAlt(tree);
getDeepCopy();
System.out.println("Original Tree");
displayTree(tree);
System.out.println("Cloned Tree");
displayTree(clonedTree);
label = new JLabel("Serach Node");
field = new JTextField();
for (int i = 0; i < clonedTree.getRowCount(); i++)
{
clonedTree.expandRow(i);
}
tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
pane = new JScrollPane(clonedTree);
centralPanel = new JPanel();
centralPanel.setLayout(new BorderLayout());
submit = new JButton("Search");
submit.addActionListener(new SearchActionListener());
getOriginalTree = new JButton("Get Original Tree");
getOriginalTree.addActionListener(new SearchActionListener());
buttonPanel = new JPanel();
buttonPanel.setLayout(new GridLayout(0, 4));
buttonPanel.add(label);
buttonPanel.add(field);
buttonPanel.add(submit);
buttonPanel.add(getOriginalTree);
centralPanel.add(pane, BorderLayout.CENTER);
centralPanel.add(buttonPanel, BorderLayout.SOUTH);
frame = new JFrame();
frame.add(centralPanel);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(600, 500);
frame.setVisible(true);
}
private void populateTree()
{
A = addAFile("A", root);
A1 = addAFile("A1", A);
A2 = addAFile("A2", A);
A3 = addAFile("A3", A);
B = addAFile("B", root);
B1 = addAFile("B1", B);
B2 = addAFile("B2", B);
B3 = addAFile("B3", B);
C = addAFile("C", root);
C1 = addAFile("C1", C);
C2 = addAFile("C2", C);
C3 = addAFile("C3", C);
D = addAFile("D", root);
D1 = addAFile("D1", D);
D2 = addAFile("D2", D);
D3 = addAFile("D3", D);
E = addAFile("E", root);
E1 = addAFile("E1", E);
E2 = addAFile("E2", E);
E3 = addAFile("E3", E);
}
private DefaultMutableTreeNode addAFile(String fileName, DefaultMutableTreeNode parentFolder) {
DefaultMutableTreeNode newFile = new DefaultMutableTreeNode(fileName);
parentFolder.add(newFile);
return newFile;
}
答案 0 :(得分:0)
我认为你应该在设置模型后调用treeModel.reload()
if(ae.getSource()==getOriginalTree)
{
System.out.println("Get original tree");
System.out.println("Nodes present under cloned Root before deep copying");
DisplayNodes(clonedRoot);
getDeepCopy();
System.out.println("Nodes present under cloned Root after deep copying");
DisplayNodes(clonedRoot);
DefaultTreeModel newModel = new DefaultTreeModel(clonedRoot);
clonedTree.setModel(newModel);
newModel.reload();
for (int i = 0; i < clonedTree.getRowCount(); i++)
{
clonedTree.expandRow(i);
}
System.out.println("Updated tree");
}
我做了一个简单的课程,有点像你的工作。如您所见,在设置单击按钮后,将使用新模型刷新树。由于您的代码类似,我认为您的clonedTree可能无法正确显示,也许它不是窗口中唯一的树。
public class JTreeTest extends JPanel {
private static DefaultMutableTreeNode root;
public static void main(String[] args) {
JPanel panel = new JPanel(new GridLayout());
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(panel);
frame.setSize(400, 400);
root = new DefaultMutableTreeNode("A");
DefaultTreeModel model = new DefaultTreeModel(root);
model.insertNodeInto(new DefaultMutableTreeNode("A1"), root, 0);
model.insertNodeInto(new DefaultMutableTreeNode("A2"), root, 0);
model.insertNodeInto(new DefaultMutableTreeNode("A3"), root, 0);
final JTree tree = new JTree(model);
tree.setRootVisible(true);
panel.add(tree);
JButton refresh = new JButton("Refresh") ;
panel.add(refresh);
refresh.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
root = new DefaultMutableTreeNode("B");
DefaultTreeModel newModel = new DefaultTreeModel(root);
tree.setModel(newModel);
}
});
frame.setVisible(true);
}
}
我已将您的代码放入测试类中并制作了以下克隆方法:
private static void cloneRoot(DefaultMutableTreeNode updatableRoot) {
updatableRoot.removeAllChildren();
for (int i = 0; i < root.getChildCount() / 2; i++) {
updatableRoot.add((javax.swing.tree.MutableTreeNode) root.getChildAt(i));
}
}
但经过一些测试后,我发现了一个很大的错误。 DefaultMutableTreeNode.add()
方法从父节点中删除节点并将其置于新父节点下。你是否制作了节点的深层副本?
克隆它的正确方法是
private DefaultMutableTreeNode cloneRoot() {
DefaultMutableTreeNode updatableRoot = new DefaultMutableTreeNode("Root");
for (int i = 0; i < root.getChildCount(); i++) {
DefaultMutableTreeNode parent = new DefaultMutableTreeNode(root.getChildAt(i));
updatableRoot.add(parent);
Enumeration<DefaultMutableTreeNode> children = root.getChildAt(i).children();
while (children.hasMoreElements()) {
parent.add(new DefaultMutableTreeNode(children.nextElement()));
}
}
return updatableRoot;
}
我发现了问题所在。你的getDeepCopy()方法如下所示:
public void getDeepCopy() {
clonedTree = copyBuilder.cloneTree();
TreeModel model = clonedTree.getModel();
clonedRoot = (DefaultMutableTreeNode) model.getRoot();
}
这意味着您每次进行复制时都要创建一个新的JTree并将其分配给clonedTree变量。通过这样做,您丢失了对在构造函数中创建并在JFrame上显示的初始JTree的引用。我通过更新getDeepCopyMethod()
为您的问题添加了以下解决方案 private void getDeepCopy() {
final JTree initialTree = copyBuilder.cloneTree();
final TreeModel model = initialTree.getModel();
clonedRoot = (DefaultMutableTreeNode) model.getRoot();
if (clonedTree != null) {
clonedTree.setModel(model);
} else {
clonedTree = initialTree;
}
}
另一种解决方案是从JScrollPane中删除clonedTree,并在更新后再次添加它。