【发布时间】:2015-05-10 17:43:22
【问题描述】:
因此,对于我正在处理的项目,我需要来自文件管理器的文件树,它显示系统中的所有目录和文件。我找到了一个完整的工作文件管理器,名为 FileManager.Java,可以在此页面上看到:https://codereview.stackexchange.com/questions/4446/file-browser-gui
但是,正如我所说,我只需要其中的树部分。我已经实现了这一点,并将 FileManager.java 代码分解为我认为必要的部分。代码在这里:
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Component;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.tree.*;
import javax.swing.filechooser.FileSystemView;
import java.util.List;
import java.io.*;
class FileManager {
/** Provides nice icons and names for files. */
private FileSystemView fileSystemView;
/** File-system tree. Built Lazily */
private JTree tree;
private DefaultTreeModel treeModel;
/** Directory listing */
private JProgressBar progressBar;
public Container getGui() {
fileSystemView = FileSystemView.getFileSystemView();
// the File tree
DefaultMutableTreeNode root = new DefaultMutableTreeNode();
treeModel = new DefaultTreeModel(root);
TreeSelectionListener treeSelectionListener = new TreeSelectionListener() {
public void valueChanged(TreeSelectionEvent tse){
DefaultMutableTreeNode node =
(DefaultMutableTreeNode)tse.getPath().getLastPathComponent();
showChildren(node);
}
};
// show the file system roots.
File[] roots = fileSystemView.getRoots();
for (File fileSystemRoot : roots) {
DefaultMutableTreeNode node = new DefaultMutableTreeNode(fileSystemRoot);
root.add( node );
//showChildren(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);
tree.setVisibleRowCount(15);
JPanel simpleOutput = new JPanel(new BorderLayout(3,3));
progressBar = new JProgressBar();
simpleOutput.add(progressBar, BorderLayout.EAST);
progressBar.setVisible(false);
return tree;
}
public void showRootFile() {
// ensure the main files are displayed
tree.setSelectionInterval(0,0);
}
/** Add the files that are contained within the directory of this node.
Thanks to Hovercraft Full Of Eels. */
private void showChildren(final DefaultMutableTreeNode node) {
tree.setEnabled(false);
progressBar.setVisible(true);
progressBar.setIndeterminate(true);
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) {
// if (child.isDirectory()) {
publish(child);
// }
}
}
}
return null;
}
@Override
protected void process(List<File> chunks) {
for (File child : chunks) {
node.add(new DefaultMutableTreeNode(child));
}
}
@Override
protected void done() {
progressBar.setIndeterminate(false);
progressBar.setVisible(false);
tree.setEnabled(true);
}
};
worker.execute();
}
}
/** A TreeCellRenderer for a File. */
class FileTreeCellRenderer extends DefaultTreeCellRenderer {
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;
}
}
当我将它调用到我的实际程序中时,一切正常,除了目录句柄。我不知道如何让它们在程序启动后立即显示。出于某种原因,您必须先单击该目录才能显示它。如果有人有任何想法,将不胜感激。
如果有帮助,当我将其调用到我的程序中时,我所做的就是
FileManager fm = new FileManager();
JScrollPane fmsp = new JScrollPane(fm.getGUI);
【问题讨论】:
-
我建议您调整您的样本,使其包含
main()方法,允许我们复制/粘贴/复制。还请确保它尽可能小。 -
似乎每个节点的文件子树都是按设计延迟创建的,如代码 cmets
/* GUI options/containers for new File/Directory creation. Created lazily. */中所述,该创建的触发器是TreeSelectionEvent,这需要您首先在创建子树之前单击树中的节点。