如何刷新 JTree UI
How to refresh JTree UI
我有一个显示目录的文件和文件夹的 JTree。还有一个按钮可以禁用 JTree
中的某些节点(使用 DefaultTreeCellRenderer
)。
当我按下按钮时该项目被禁用,但 JTree 没有将其显示为禁用项目。直到我点击某个地方,或者在树的项目上,然后它也会显示项目的禁用外观。
我知道 DefaultTreeModel
有一个 reload()
方法。但我使用定制模型。所以这个方法行不通。这是我用来列出文件和文件夹的模型:FileSystemModel
这是我的代码:
public class FileViewer {
JFrame frame;
JPanel panel;
JTree tree;
File root;
public ArrayList<String> disabledNodes = new ArrayList<String>();
public FileViewer(){
frame = new JFrame("File Viewer");
panel = new JPanel(new BorderLayout());
root = new File("D:\Documents\A X");
FileSystemModel model = new FileSystemModel(root);
tree = new JTree();
tree.setModel(model);
panel.add(tree, BorderLayout.CENTER);
JButton press = new JButton("Press");
panel.add(press, BorderLayout.SOUTH);
press.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e){
disabledNodes.add("folder1");
}
});
tree.setCellRenderer(new CustomDefaultTreeCellRenderer());
frame.add(panel);
frame.setSize(600, 600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
new FileViewer();
}
class CustomDefaultTreeCellRenderer extends DefaultTreeCellRenderer{
@Override
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus){
super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
File node = (File)value;
String name = node.getName();
for(String element : disabledNodes){
if(name.equals(element)){
this.setEnabled(false);
}
}
return this;
}
}
}
但是,在按钮的 ActionListener
中,我添加了 tree.updateUI();
并且效果很好。但不知何故,我听说更新 UI 是一种不好的做法,因为它会在以后产生其他问题。那么在这里使用 updateUI
正确吗?还是有更好的方法使 UI
通过点击和用户互动进行更新?
注意,我不会在树中添加或删除任何文件,我只需要 enable/disable 个节点。
更新:我只是注意到有一个 repaint()
选项对我有类似的功能。但是,它仍然是刷新 JTree 的正确方法吗?
在这种情况下 repaint() 是正确的API。
我有一个显示目录的文件和文件夹的 JTree。还有一个按钮可以禁用 JTree
中的某些节点(使用 DefaultTreeCellRenderer
)。
当我按下按钮时该项目被禁用,但 JTree 没有将其显示为禁用项目。直到我点击某个地方,或者在树的项目上,然后它也会显示项目的禁用外观。
我知道 DefaultTreeModel
有一个 reload()
方法。但我使用定制模型。所以这个方法行不通。这是我用来列出文件和文件夹的模型:FileSystemModel
这是我的代码:
public class FileViewer {
JFrame frame;
JPanel panel;
JTree tree;
File root;
public ArrayList<String> disabledNodes = new ArrayList<String>();
public FileViewer(){
frame = new JFrame("File Viewer");
panel = new JPanel(new BorderLayout());
root = new File("D:\Documents\A X");
FileSystemModel model = new FileSystemModel(root);
tree = new JTree();
tree.setModel(model);
panel.add(tree, BorderLayout.CENTER);
JButton press = new JButton("Press");
panel.add(press, BorderLayout.SOUTH);
press.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e){
disabledNodes.add("folder1");
}
});
tree.setCellRenderer(new CustomDefaultTreeCellRenderer());
frame.add(panel);
frame.setSize(600, 600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
new FileViewer();
}
class CustomDefaultTreeCellRenderer extends DefaultTreeCellRenderer{
@Override
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus){
super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
File node = (File)value;
String name = node.getName();
for(String element : disabledNodes){
if(name.equals(element)){
this.setEnabled(false);
}
}
return this;
}
}
}
但是,在按钮的 ActionListener
中,我添加了 tree.updateUI();
并且效果很好。但不知何故,我听说更新 UI 是一种不好的做法,因为它会在以后产生其他问题。那么在这里使用 updateUI
正确吗?还是有更好的方法使 UI
通过点击和用户互动进行更新?
注意,我不会在树中添加或删除任何文件,我只需要 enable/disable 个节点。
更新:我只是注意到有一个 repaint()
选项对我有类似的功能。但是,它仍然是刷新 JTree 的正确方法吗?
repaint() 是正确的API。