'Start the JTree with JTextField ENTER
I'm a new beginner and JTree made me sad. Can't keep on. So hope, you can help me.
What I really want is, Show a JTextField and JTree properly and when I write a path from my PC I want to see all folders and files as in JTree.
I did something but really wish you can help me. Thanks.
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
public class Main extends JFrame {
JTextField path = new JTextField();
public static void main(String[] args) {
new Main().setVisible(true);
}
private JTree jTree1;
private JTree jTree2;
File fileRoot;
File fileRoot2;
DefaultMutableTreeNode root = new DefaultMutableTreeNode(fileRoot);
DefaultTreeModel model = new DefaultTreeModel(root);
DefaultMutableTreeNode root2 = new DefaultMutableTreeNode(fileRoot2);
DefaultTreeModel model2 = new DefaultTreeModel(root2);
public Main() {
setLayout(new BorderLayout());
this.jTree1 = new JTree();
this.add(this.jTree1);
this.jTree2 = new JTree();
this.add(this.jTree2);
JScrollPane scrollpane = new JScrollPane();
scrollpane.setBounds(100, 100, 100, 300);
scrollpane.getViewport().add(jTree1);
add(BorderLayout.NORTH, path);
add(BorderLayout.WEST, scrollpane);
JScrollPane scrollpane2 = new JScrollPane();
scrollpane2.getViewport().add(jTree2);
add(BorderLayout.EAST, scrollpane2);
this.jTree1.setModel(model);
this.jTree2.setModel(model2);
this.pack();
path.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String JtreeString = path.getText().toString().replaceAll("[\\[\\]]", "")
.replace(", ", "\\");
fileRoot = new File(JtreeString);
File[] files = fileRoot.listFiles();
for (File file : files) {
root.add(new DefaultMutableTreeNode(file));
}
model.reload(root);
}
});
}
}
Solution 1:[1]
I rewrote your code.
It's not clear to me why you have two JTrees. The below code populates the left tree only.
(Explanations appear after the code.)
import java.awt.BorderLayout;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.io.File;
import java.nio.file.Path;
import java.nio.file.Paths;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
public class FileTree implements Runnable {
private DefaultTreeModel leftModel;
private JFrame frame;
private JTextField filePathTextField;
private JTree leftTree;
private JTree rightTree;
public void run() {
createAndDisplayGui();
}
private void createAndDisplayGui() {
frame = new JFrame("File Tree");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createTopPanel(), BorderLayout.PAGE_START);
frame.add(createTreesPanel(), BorderLayout.CENTER);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createTopPanel() {
JPanel topPanel = new JPanel();
topPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
JLabel label = new JLabel("Root Path");
label.setDisplayedMnemonic(KeyEvent.VK_R);
label.setLabelFor(filePathTextField);
topPanel.add(label);
filePathTextField = new JTextField(20);
filePathTextField.addActionListener(this::walkFileTree);
topPanel.add(filePathTextField);
return topPanel;
}
private JPanel createTreesPanel() {
JPanel treesPanel = new JPanel(new GridLayout(1, 0, 10, 0));
treesPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
leftTree = new JTree(new DefaultTreeModel(null));
leftTree.setShowsRootHandles(true);
JScrollPane leftScrollPane = new JScrollPane(leftTree);
leftScrollPane.setPreferredSize(new Dimension(300, 300));
treesPanel.add(leftScrollPane);
rightTree = new JTree(new DefaultTreeModel(null));
JScrollPane rightScrollPane = new JScrollPane(rightTree);
rightScrollPane.setPreferredSize(new Dimension(300, 300));
treesPanel.add(rightScrollPane);
return treesPanel;
}
private void expandAllNodes(JTree tree, int startingIndex, int rowCount){
for (int i = startingIndex; i < rowCount; ++i) {
tree.expandRow(i);
}
if (tree.getRowCount() != rowCount) {
expandAllNodes(tree, rowCount, tree.getRowCount());
}
}
private void walkFileTree(ActionEvent event) {
Object source = event.getSource();
if (source == filePathTextField) {
frame.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
String text = filePathTextField.getText();
Path rootPath = Paths.get(text);
File rootFile = rootPath.toFile();
DefaultMutableTreeNode root = new DefaultMutableTreeNode(rootFile);
leftModel = new DefaultTreeModel(root);
leftTree.setModel(leftModel);
walkTree(root, rootFile);
expandAllNodes(leftTree, 0, leftTree.getRowCount());
frame.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
}
private void walkTree(DefaultMutableTreeNode parent, File f) {
if (f.isDirectory()) {
File[] files = f.listFiles();
for (File file : files) {
DefaultMutableTreeNode node = new DefaultMutableTreeNode(file);
parent.add(node);
if (file.isDirectory()) {
walkTree(node, file);
}
}
}
}
public static void main(String[] args) {
FileTree gui = new FileTree();
EventQueue.invokeLater(gui);
}
}
- The default layout manager for [the content pane of] JFrame is
BorderLayoutso no need to explicitly set it. - In order to display the
JTrees side by side, I used GridLayout but there are other layout managers that will achieve the same result. - The more files there are under the file whose path you enter into
JTextFieldthe more time it will take to display the results. That's why I set the cursor to the "wait" cursor while the tree is being built. Note that this doesn't stop the user from using the mouse but while the tree is being built, the event dispatch thread (EDT) cannot respond to mouse clicks anyway. Basically it is a hint to the user that the application is busy. You may want to consider using a SwingWorker. - Method
expandAllNodeswas copied from the answer to this SO question: Completely expand all node of a Jtree (including children) this::walkFileTreeis the syntax for method reference.- How to Use Trees
Here is a screen capture:
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 |

