Search code examples
javaswingjtree

How to disable a leaf of the JTree


I have a JTree that shows files and folders, I would like to have a access to nodes to set them enabled or disabled. For example if the button is pressed, or when their text is equal to a specific text, then set them disabled.

Here is my main class:

public FileViewer(){
        frame = new JFrame("File Viewer");
        panel = new JPanel(new BorderLayout());


        root = new File("D:\\Documents\\A X");
        FileSystemModel model = new FileSystemModel(root);

        tree = new JTree();
        tree.setModel(model);
        panel.add(tree, BorderLayout.CENTER);


        traverse(tree, "DS.png");

        frame.add(panel);
        frame.setSize(600, 600);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        // TODO code application logic here
        new FileViewer();
}

I could make a traverse method that check every child of the model and find a specific child:

public void traverse(JTree tree, String word) { 
    TreeModel model = tree.getModel();
    if (model != null) {
        Object root = model.getRoot();
        //System.out.println("THIS IS ROOOT >>>>>> " + root.toString());
        walk(model, root, word);    
        }
    else
       System.out.println("Tree is empty.");
    }
    protected void walk(TreeModel model, Object o, String word){
    int  cc;
    cc = model.getChildCount(o);
    for( int i=0; i < cc; i++) {
      Object child = model.getChild(o, i);
      if (model.isLeaf(child) && child.toString().equals(word)){
        System.out.println(child.toString());
      }
      else {
        //System.out.println("--" + child.toString());
        walk(model,child, word); 
        }
     }
}

JTree has the method setEnabled(Boolean), but its nodes don't. Is there any idea how to make the nodes disabled? This is my FileSystemModel file, if you like to know about it.


Solution

  • You should create custom DefaultTreeCellRenderer class and use it setEnabled method.

    enter image description here

    package com.company;
    
    import javax.swing.*;
    import javax.swing.tree.DefaultMutableTreeNode;
    import javax.swing.tree.DefaultTreeCellRenderer;
    import javax.swing.tree.DefaultTreeModel;
    import javax.swing.tree.TreeNode;
    import java.awt.*;
    
    public class Main {
    
        public static void main(String[] args) {
            TreeNode treeNode = new DefaultMutableTreeNode("Test");
    
            JTree tree = new JTree();
            tree.setModel(new DefaultTreeModel(treeNode));
            tree.setCellRenderer(new CustomDefaultTreeCellRenderer());
    
            JFrame frame = new JFrame();
            frame.setContentPane(tree);
            frame.setSize(320, 200);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
    
        static class CustomDefaultTreeCellRenderer extends DefaultTreeCellRenderer {
            @Override
            public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) {
                boolean enabled = false; // <-- here is your logic for enable/disable cell
    
                sel = enabled;
                hasFocus = enabled;
    
                Component treeCellRendererComponent = super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
                treeCellRendererComponent.setEnabled(enabled);
    
                return treeCellRendererComponent;
            }
        }
    }