我正在尝试开发一个小型应用程序,该应用程序使用 gui 从系统上的任何位置移动文件。我有可以移动文件的代码,并且在选择和按下按钮时确实会移动,但我不知道如何刷新文件系统查看器以反映更改。我必须设置系统查看器的代码如下:
public class FileMover {
//Start of Global Variables
private JTree tree;
private DefaultTreeModel treeModel;
private FileSystemView fileSystemView;
protected File currentFile;
protected LinkedList fileLocations;
protected JTree movedTree;
protected JPanel areaLeft;
protected JPanel areaRight;
protected JPanel areaMiddle;
protected final JFrame openFrame;
//end of global variables.
//Constructor for FileMover
public FileMover()
{
openFrame = new JFrame("File Mover");
createFileMover();
}
public void createFileMover(){
Container contentPane = this.openFrame.getContentPane();
fileLocations = new LinkedList();
contentPane.setLayout(new BorderLayout());
areaLeft = new JPanel();
areaRight = new JPanel();
areaMiddle = new JPanel();
contentPane.add(areaLeft, BorderLayout.WEST);
contentPane.add(areaRight, BorderLayout.EAST);
contentPane.add(areaMiddle, BorderLayout.CENTER);
areaLeft.add(createSystemView());
movedTree = new JTree(fileLocations.toArray());
JScrollPane movedPane = new JScrollPane(movedTree);
JButton moveRightButton = new JButton("->");
JButton moveLeftButton = new JButton("<-");
JButton refresh = new JButton("Refresh");
areaMiddle.setLayout(new GridLayout(1,2));
areaMiddle.add(moveRightButton);
areaMiddle.add(refresh);
areaMiddle.add(moveLeftButton);
//actualy move the file
moveRightButton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
System.out.println("Moving file: "+ currentFile.getName());
fileLocations.add(currentFile);
try {
//move the file to the correct location.
moveFile(currentFile);
} catch (IOException ex) {
Logger.getLogger(FileMover.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println(fileLocations.getFirst().toString());
}
});
//refresh the gui
refresh.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
refresh();
}
});
//finish setting up the frame
openFrame.setSize(1280, 768);
openFrame.setLocationRelativeTo(null);
openFrame.setDefaultCloseOperation(3);
openFrame.setResizable(false);
openFrame.pack();
openFrame.setVisible(true);
}
/** Add the files that are contained within the directory of this node.
*/
private void showChildren(final DefaultMutableTreeNode node) {
tree.setEnabled(false);
SwingWorker<Void, File> worker = new SwingWorker<Void, File>() {
@Override
public Void doInBackground() {
File file = (File) node.getUserObject();
if (file.isDirectory()) {
File[] files = fileSystemView.getFiles(file, true); //!!
if (node.isLeaf()) {
for (File child : files) {
publish(child);
}
}
}
return null;
}
@Override
protected void process(List<File> chunks) {
for (File child : chunks) {
node.add(new DefaultMutableTreeNode(child));
}
}
@Override
protected void done() {
tree.setEnabled(true);
}
};
worker.execute();
}
/** Update the File details view with the details of this File. */
private void setFileDetails(File file) {
System.out.println("Path: "+ file.getPath());
System.out.println("Name: "+ fileSystemView.getSystemDisplayName(file));
}
private void refresh(){
//refresh the tree here
}
private JScrollPane createSystemView(){
//file syatem hierarchy
fileSystemView = FileSystemView.getFileSystemView();
// the File tree
DefaultMutableTreeNode root = new DefaultMutableTreeNode();
treeModel = new DefaultTreeModel(root);
TreeSelectionListener treeSelectionListener = new TreeSelectionListener() {
@Override
public void valueChanged(TreeSelectionEvent tse){
DefaultMutableTreeNode node =
(DefaultMutableTreeNode)tse.getPath().getLastPathComponent();
showChildren(node);
setFileDetails((File)node.getUserObject());
currentFile = (File)node.getUserObject();
}
};
// show the file system roots.
File[] roots = fileSystemView.getRoots();
for (File fileSystemRoot : roots) {
DefaultMutableTreeNode node = new DefaultMutableTreeNode(fileSystemRoot);
root.add( node );
File[] files = fileSystemView.getFiles(fileSystemRoot, true);
for (File file : files) {
if (file.isDirectory()) {
node.add(new DefaultMutableTreeNode(file));
}
}
}
tree = new JTree(treeModel);
tree.setRootVisible(false);
tree.addTreeSelectionListener(treeSelectionListener);
tree.setCellRenderer(new FileTreeCellRenderer());
tree.expandRow(0);
JScrollPane treeScroll = new JScrollPane(tree);
tree.setVisibleRowCount(15);
Dimension preferredSize = treeScroll.getPreferredSize();
Dimension widePreferred = new Dimension(
200,
(int)preferredSize.getHeight());
treeScroll.setPreferredSize( widePreferred );
return treeScroll;
}
向左移动按钮和向右区域尚未完成,但我需要的是当我在树中选择一个节点并单击向右箭头按钮时,节点反映的文件/文件夹由我的 moveFile 代码在内部移动,并且有效。但是该更改并未反映在树中,因此如何在树中显示此更改,即刷新树以显示文件系统的当前状态?
我试过 treeModel.reload(); 但这似乎不起作用并引发空指针异常。
我试过了 :
areaLeft.removeAll();
areaLeft.add(createSystemView());
认为它可以通过重新创建系统视图来刷新它,但这似乎没有任何作用。
在这里的帮助将不胜感激!
编辑:以下是文件树渲染器的请求代码:
/** A TreeCellRenderer for a File. */
class FileTreeCellRenderer extends DefaultTreeCellRenderer {
private static final long serialVersionUID = -7799441088157759804L;
private FileSystemView fileSystemView;
private JLabel label;
FileTreeCellRenderer() {
label = new JLabel();
label.setOpaque(true);
fileSystemView = FileSystemView.getFileSystemView();
}
@Override
public Component getTreeCellRendererComponent(
JTree tree,
Object value,
boolean selected,
boolean expanded,
boolean leaf,
int row,
boolean hasFocus) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode)value;
File file = (File)node.getUserObject();
label.setIcon(fileSystemView.getSystemIcon(file));
label.setText(fileSystemView.getSystemDisplayName(file));
label.setToolTipText(file.getPath());
if (selected) {
label.setBackground(backgroundSelectionColor);
label.setForeground(textSelectionColor);
} else {
label.setBackground(backgroundNonSelectionColor);
label.setForeground(textNonSelectionColor);
}
return label;
}
}