JTree 首次加载时不显示句柄
JTree isn't showing handles when it first loads up
因此,对于我正在处理的项目,我需要来自文件管理器的文件树,它显示系统中的所有目录和文件。我找到了一个名为 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);
everything works fine, except for the handles for the directories. I can't figure out how to get them to display as soon as the program starts.
有两种方法:
使用depthFirstEnumeration()
调用scrollPathToVisible()
; assuming DefaultMutableTreeNode
, you can obtain a suitable TreePath
as shown here。
为每个要展开的节点调用expandRow()
:
for (int i = 0; i < tree.getRowCount(); i++) {
tree.expandRow(i);
}
因此,对于我正在处理的项目,我需要来自文件管理器的文件树,它显示系统中的所有目录和文件。我找到了一个名为 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);
everything works fine, except for the handles for the directories. I can't figure out how to get them to display as soon as the program starts.
有两种方法:
使用
depthFirstEnumeration()
调用scrollPathToVisible()
; assumingDefaultMutableTreeNode
, you can obtain a suitableTreePath
as shown here。为每个要展开的节点调用
expandRow()
:for (int i = 0; i < tree.getRowCount(); i++) { tree.expandRow(i); }