Java JTree模型。节点更改(节点)丢失数据
我正在用Java JTree模型。节点更改(节点)丢失数据,java,eclipse,swing,jtree,Java,Eclipse,Swing,Jtree,我正在用JTree测试一些代码,我注意到model.reload()提供的输出与model.nodeChanged(currentNode)不同。从model.reload()获得正确的输出。以下是我对同一代码的两个输出: 我的代码如下: public class test { private JFrame frame; JTree tree; DefaultMutableTreeNode root; DefaultTreeModel model; p
JTree
测试一些代码,我注意到model.reload()
提供的输出与model.nodeChanged(currentNode)
不同。从model.reload()
获得正确的输出。以下是我对同一代码的两个输出:
我的代码如下:
public class test {
private JFrame frame;
JTree tree;
DefaultMutableTreeNode root;
DefaultTreeModel model;
private Map<String, DefaultMutableTreeNode> treeMap;
public static void main(String[] args) {
test t = new test();
try {
Thread.sleep(1000 * 5);
} catch (Exception e) {
}
t.add_new_folder("Data", "trial 0");
t.add_new_folder("Data/trial 0", "trial 1");
t.add_new_folder("Data/trial 0/trial 1", "trial 2");
t.add_new_folder("Data", "trial 1");
try {
Thread.sleep(1000 * 5);
} catch (Exception e) {
}
t.add_new_folder("Data/trial 1", "trial 2");
t.add_new_folder("Data", "trial 2");
}
public test() {
frame = new JFrame("using reload");
tree = new JTree();
root = new DefaultMutableTreeNode("Data");
model = new DefaultTreeModel(root);
tree.setModel(model);
frame.getContentPane().add(tree, BorderLayout.WEST);
frame.setVisible(true);
frame.setSize(500, 500);
treeMap = new HashMap<>();
treeMap.put("Data", root);
}
public void add_new_folder(String path, String name) {
DefaultMutableTreeNode currentNode = treeMap.get(path);
DefaultMutableTreeNode childNode = new DefaultMutableTreeNode(name);
currentNode.add(childNode);
treeMap.put(path + "/" + name, childNode);
model.reload();
//model.nodeChanged(currentNode);
}
}
公共类测试{
私有JFrame;
JTree树;
DefaultMutableTreeNode根;
DefaultTreeModel模型;
私有地图树图;
公共静态void main(字符串[]args){
测试t=新测试();
试一试{
线程。睡眠(1000*5);
}捕获(例外e){
}
t、 添加新文件夹(“数据”,“试用0”);
t、 添加新文件夹(“数据/试验0”、“试验1”);
t、 添加新文件夹(“数据/试验0/试验1”、“试验2”);
t、 添加新文件夹(“数据”,“试验1”);
试一试{
线程。睡眠(1000*5);
}捕获(例外e){
}
t、 添加新文件夹(“数据/试验1”、“试验2”);
t、 添加新文件夹(“数据”,“试验2”);
}
公开考试(){
frame=新JFrame(“使用重新加载”);
tree=newjtree();
root=新的DefaultMutableTreeNode(“数据”);
模型=新的DefaultTreeModel(根);
tree.setModel(model);
frame.getContentPane().add(树,BorderLayout.WEST);
frame.setVisible(true);
框架。设置尺寸(500500);
treeMap=newhashmap();
树映射put(“数据”,根);
}
public void add_new_文件夹(字符串路径、字符串名称){
DefaultMutableTreeNode currentNode=treeMap.get(路径);
DefaultMutableTreeNode childNode=新的DefaultMutableTreeNode(名称);
添加(子节点);
treeMap.put(路径+“/”+名称,子节点);
model.reload();
//model.nodeChanged(当前节点);
}
}
我还需要使用model.nodeChanged()
,因为它使扩展路径与model.reload不同。有什么解释以及如何修复
你知道为什么我会在树上遇到这个问题吗
如下所示,如果正确,结果是相同的。如图所示,您可以使用expandRow()
和scrollPathToVisible()
控制可见性。使用Thread.sleep()
只会阻塞调用它的线程。因为Swing是不可预测的,所以结果是不可预测的。而是根据需要使用或
尝试在添加节点和展开任何路径之间放置一些睡眠,在继续代码中,问题将出现,如我的问题中所述
因此,使用Thread.sleep()
的结果不可靠。使用java.swing.Timer
可以揭示问题:nodeChanged()
反映对节点本身的更改。因为您已经更改了节点的子节点,所以请调用nodeStructureChanged()
导入java.awt.BorderLayout;
导入java.awt.EventQueue;
导入java.awt.event.ActionEvent;
导入java.awt.event.ActionListener;
导入java.util.HashMap;
导入java.util.Map;
导入javax.swing.JFrame;
导入javax.swing.JTree;
导入javax.swing.Timer;
导入javax.swing.tree.DefaultMutableTreeNode;
导入javax.swing.tree.DefaultTreeModel;
公开课考试{
私有最终JFrame;
私有最终JTree树;
私有最终DefaultMutableTreeNode根;
私有最终DefaultTreeModel模型;
私有最终地图树图;
私有最终布尔重新加载;
私有整数索引;
私有最终字符串[]文件夹={
“数据”,“试用版0”,
“数据/试验0”、“试验1”,
“数据/试验0/试验1”,“试验2”,
“数据”,“试验1”,
“数据/试验1”、“试验2”,
“数据”,“试验2”
};
公共静态void main(字符串[]args){
EventQueue.invokeLater(()->{
新测试(正确);
新测试(假);
});
}
公共测试(布尔重新加载){
this.reload=重新加载;
frame=newjframe(String.valueOf(reload));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
treeMap=newhashmap();
root=新的DefaultMutableTreeNode(“数据”);
模型=新的DefaultTreeModel(根);
树=新的JTree(模型);
树映射put(“数据”,根);
框架。添加(树,边框布局。西);
frame.pack();
frame.setLocationRelativeTo(空);
frame.setVisible(true);
计时器t=新计时器(100,新ActionListener(){
@凌驾
已执行的公共无效操作(操作事件e){
如果(索引
你知道为什么我会在树上遇到这个问题吗
如下所示,如果正确,结果是相同的。如图所示,您可以使用expandRow()
和scrollPathToVisible()
控制可见性。使用Thread.sleep()
只会阻塞调用它的线程。因为Swing是不可预测的,所以结果是不可预测的。而是根据需要使用或
尝试在添加节点和展开任何路径之间放置一些睡眠,在继续代码中,问题将出现,如我的问题中所述
因此,使用Thread.sleep()
的结果不可靠。使用j
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashMap;
import java.util.Map;
import javax.swing.JFrame;
import javax.swing.JTree;
import javax.swing.Timer;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
public class Test {
private final JFrame frame;
private final JTree tree;
private final DefaultMutableTreeNode root;
private final DefaultTreeModel model;
private final Map<String, DefaultMutableTreeNode> treeMap;
private final boolean reload;
private int index;
private final String[] folders = {
"Data", "trial 0",
"Data/trial 0", "trial 1",
"Data/trial 0/trial 1", "trial 2",
"Data", "trial 1",
"Data/trial 1", "trial 2",
"Data", "trial 2"
};
public static void main(String[] args) {
EventQueue.invokeLater(() -> {
new Test(true);
new Test(false);
});
}
public Test(boolean reload) {
this.reload = reload;
frame = new JFrame(String.valueOf(reload));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
treeMap = new HashMap<>();
root = new DefaultMutableTreeNode("Data");
model = new DefaultTreeModel(root);
tree = new JTree(model);
treeMap.put("Data", root);
frame.add(tree, BorderLayout.WEST);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
Timer t = new Timer(100, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (index < folders.length) {
addNewFolder(folders[index++], folders[index++]);
for (int i = 0; i < tree.getRowCount(); i++) {
tree.expandRow(i);
}
frame.pack();
}
}
});
t.start();
}
private void addNewFolder(String path, String name) {
DefaultMutableTreeNode currentNode = treeMap.get(path);
DefaultMutableTreeNode childNode = new DefaultMutableTreeNode(name);
currentNode.add(childNode);
treeMap.put(path + "/" + name, childNode);
if (reload) {
model.reload();
} else {
model.nodeStructureChanged(currentNode);
}
}
}