Mục lục
Khởi tạo JTree
Bây giờ chúng ta hãy cố gắng xây dựng một JTree đơn giản. Giả sử chúng tôi muốn hiển thị danh sách các loại rau(vegetables) và trái cây(fruits) theo thứ bậc. Nút được đại diện trong Swing API dưới dạng TreeNode, là một interface. MutableTreeNode interface thừa kế TreeNode đại diện cho một nút có thể thay đổi được. API Swing cung cấp một triển khai của giao diện này ở dạng lớp DefaultMutableTreeNode.
Chúng ta sẽ sử dụng lớp DefaultMutableTreeNode để đại diện cho nút. Lớp này được cung cấp trong API Swing và chúng ta có thể sử dụng nó để đại diện cho các nút của mình.
Vì vậy, trước tiên chúng ta sẽ tạo nút gốc. Và sau đó chúng ta có thể thêm đệ quy các nút vào gốc đó. Hãy để chúng tôi bắt đầu với một gốc đơn giản chỉ với 2 nút
import javax.swing.JFrame; import javax.swing.JTree; import javax.swing.SwingUtilities; import javax.swing.tree.DefaultMutableTreeNode; class TreeExample extends JFrame { private JTree tree; public TreeExample() { //create the root node DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root"); //create the child nodes DefaultMutableTreeNode vegetableNode = new DefaultMutableTreeNode("Vegetables"); DefaultMutableTreeNode fruitNode = new DefaultMutableTreeNode("Fruits"); //add the child nodes to the root node root.add(vegetableNode); root.add(fruitNode); //create the tree by passing in the root node tree = new JTree(root); add(tree); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setTitle("JTree Example"); this.setLocationRelativeTo(null); this.setSize(300, 100); this.setVisible(true); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { new TreeExample(); } }); } }
Output
Thêm nút vào JTree
Mỗi nút đều có thể thêm các nút con của nó vào bằng cách sử dụng add() method.
import javax.swing.JFrame; import javax.swing.JTree; import javax.swing.SwingUtilities; import javax.swing.tree.DefaultMutableTreeNode; class TreeExample extends JFrame { private JTree tree; public TreeExample() { //create the root node DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root"); //create the child nodes DefaultMutableTreeNode vegetableNode = new DefaultMutableTreeNode("Vegetables"); vegetableNode.add(new DefaultMutableTreeNode("Capsicum")); vegetableNode.add(new DefaultMutableTreeNode("Carrot")); vegetableNode.add(new DefaultMutableTreeNode("Tomato")); vegetableNode.add(new DefaultMutableTreeNode("Potato")); DefaultMutableTreeNode fruitNode = new DefaultMutableTreeNode("Fruits"); fruitNode.add(new DefaultMutableTreeNode("Banana")); fruitNode.add(new DefaultMutableTreeNode("Mango")); fruitNode.add(new DefaultMutableTreeNode("Apple")); fruitNode.add(new DefaultMutableTreeNode("Grapes")); fruitNode.add(new DefaultMutableTreeNode("Orange")); //add the child nodes to the root node root.add(vegetableNode); root.add(fruitNode); //create the tree by passing in the root node tree = new JTree(root); add(tree); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setTitle("JTree Example"); this.setLocationRelativeTo(null); this.setSize(300, 300); this.setVisible(true); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { new TreeExample(); } }); } }
Thêm JScrollPane vào JTree
Có vẽ một component như JTree có thể chứa rất nhiều nút dữ liệu, vì vậy khả năng cao là kích thước của JFrame bên ngoài sẽ không thể đáp ứng đủ. Vì vậy chúng ta có thể sử dụng JScrollPane để tạo thanh cuộn cho JTree khi nó chứa quá nhiều nút.
Để thêm JScrollPane cho JTree chúng ta chỉ cần bọc bên ngoài JTree một JScrollPane như sau:
add(new JScrollPane(tree));
Để thanh cuộn xuất hiện khi chúng ta bung các nút con thì mình sẽ giảm kích thước JFrame đi một chút. Mã nguồn đầy đủ như sau:
import javax.swing.*; import javax.swing.tree.DefaultMutableTreeNode; class TreeExample extends JFrame { private JTree tree; public TreeExample() { //create the root node DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root"); //create the child nodes DefaultMutableTreeNode vegetableNode = new DefaultMutableTreeNode("Vegetables"); vegetableNode.add(new DefaultMutableTreeNode("Capsicum")); vegetableNode.add(new DefaultMutableTreeNode("Carrot")); vegetableNode.add(new DefaultMutableTreeNode("Tomato")); vegetableNode.add(new DefaultMutableTreeNode("Potato")); DefaultMutableTreeNode fruitNode = new DefaultMutableTreeNode("Fruits"); fruitNode.add(new DefaultMutableTreeNode("Banana")); fruitNode.add(new DefaultMutableTreeNode("Mango")); fruitNode.add(new DefaultMutableTreeNode("Apple")); fruitNode.add(new DefaultMutableTreeNode("Grapes")); fruitNode.add(new DefaultMutableTreeNode("Orange")); //add the child nodes to the root node root.add(vegetableNode); root.add(fruitNode); //create the tree by passing in the root node tree = new JTree(root); add(new JScrollPane(tree)); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setTitle("JTree Example"); this.setLocationRelativeTo(null); this.setSize(300, 200); this.setVisible(true); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { new TreeExample(); } }); } }
Ẩn root node trong JTree
Để ẩn nút cha trong JTree chúng ta có thể sử dụng tree.setRootVisible(false);
Hiển thị nút đóng/mở rộng trong root node
Nếu các bạn để ý nảy giờ thì nút cha không có nút mũi tên đóng mở. Để thêm đóng mở vào nút cha chúng ta có thể sử dụng setShowsRootHandles(true)
Xử lý sự kiện trong JTree
Chúng ta cần thêm một TreeSelectionListener để lắng nghe các sự kiện lựa chọn. Đây là một giao diện được định nghĩa trong API Swing và chúng ta cần triển khai phương thức valueChanged (). Nguồn của vùng chọn được chuyển làm tham số cho phương thức này.
Đầu tiên chúng ta sẽ thêm một JLabel sẽ được hiển thị ở dưới cùng. Bất cứ khi nào một nút trong cây được chọn, chúng tôi sẽ hiển thị đường dẫn của nút đã chọn.
Để thêm xử lý sự kiện vào JTree chúng ta sẽ sử dụng tree.getSelectionModel().addTreeSelectionListener() method.
import javax.swing.*; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; import javax.swing.tree.DefaultMutableTreeNode; import java.awt.*; class TreeExample extends JFrame { private JTree tree; private JLabel selectedLabel; public TreeExample() { //create the root node DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root"); //create the child nodes DefaultMutableTreeNode vegetableNode = new DefaultMutableTreeNode("Vegetables"); vegetableNode.add(new DefaultMutableTreeNode("Capsicum")); vegetableNode.add(new DefaultMutableTreeNode("Carrot")); vegetableNode.add(new DefaultMutableTreeNode("Tomato")); vegetableNode.add(new DefaultMutableTreeNode("Potato")); DefaultMutableTreeNode fruitNode = new DefaultMutableTreeNode("Fruits"); fruitNode.add(new DefaultMutableTreeNode("Banana")); fruitNode.add(new DefaultMutableTreeNode("Mango")); fruitNode.add(new DefaultMutableTreeNode("Apple")); fruitNode.add(new DefaultMutableTreeNode("Grapes")); fruitNode.add(new DefaultMutableTreeNode("Orange")); //add the child nodes to the root node root.add(vegetableNode); root.add(fruitNode); //create the tree by passing in the root node tree = new JTree(root); add(new JScrollPane(tree)); tree.setShowsRootHandles(true); tree.getSelectionModel().addTreeSelectionListener(new TreeSelectionListener() { @Override public void valueChanged(TreeSelectionEvent e) { selectedLabel.setText(e.getPath().toString()); } }); // Add label to jframe selectedLabel = new JLabel(); add(selectedLabel, BorderLayout.SOUTH); this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); this.setTitle("JTree Example"); this.setLocationRelativeTo(null); this.setSize(300, 200); this.setVisible(true); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { new TreeExample(); } }); } }
Nguồn tham khảo
https://www.codejava.net/java-se/swing/jtree-basic-tutorial-and-examples
http://www.java2s.com/Tutorials/Java/Java_Swing/1200__Java_Swing_JTree.htm