I created a JTree and also created a class which implements TreeSelectionListener then I pass that object into the JTree's function addTreeSelectionListener.

In the JavaDocs, there is an example where they implemented the function public void valueChanged(TreeSelectionEvent e) within the main class and passed this into addTreeSelectionListener. I tried to implement this into my class, but it didn't work.

package tutorials;

import java.awt.Dimension;

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JTree;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeSelectionModel;

public class TreeDemo extends JFrame{
    private JTree tree;
    public TreeDemo() {
        super("Tree Demo");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setPreferredSize(new Dimension(500, 300));

        DefaultMutableTreeNode structure = new DefaultMutableTreeNode("Main Tree");
        DefaultMutableTreeNode subTree1 = new DefaultMutableTreeNode("SubTree 1");
        DefaultMutableTreeNode subTree2 = new DefaultMutableTreeNode("SubTree 2");
        DefaultMutableTreeNode subTree3 = new DefaultMutableTreeNode("SubTree 3");

        subTree1.add(new DefaultMutableTreeNode("SubSubTree"));
        subTree1.add(new DefaultMutableTreeNode("SubSubTree2"));
        subTree1.add(new DefaultMutableTreeNode("SubSubTree3"));
        subTree1.add(new DefaultMutableTreeNode("SubSubTree4"));

        structure.add(subTree1);
        structure.add(subTree2);
        structure.add(subTree3);

        tree = new JTree(structure);
        tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
        tree.addTreeSelectionListener(new treeListnerHandler());

        pack();
        add(tree);
    }

    private class treeListnerHandler implements TreeSelectionListener {
        public void valueChanged(TreeSelectionEvent event) {
            JOptionPane.showMessageDialog(null, event.getPath().getLastPathComponent().toString());
        }
    }

    public static void main(String[] args) {
        TreeDemo x = new TreeDemo();
        x.setVisible(true);
    }
}

but it didn't work.

Was the "this" class defined to be a TreeSelectionListener? That is the data type required by the addTreeSelectionListener() method for its argument.
One way give a class a type is by having it implement an interface.

NormR1
Was the "this" class defined to be a TreeSelectionListener? That is the data type required by the addTreeSelectionListener() method for its argument.
One way give a class a type is by having it implement an interface.

Yup that was it, I was an idiot and forgot to add implements TreeSelectionListener. Thanks for the help.

This is what my code looks like now:

package tutorials;

import java.awt.Dimension;

import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JTree;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.TreeSelectionModel;

public class TreeDemo extends JFrame implements TreeSelectionListener {
    private JTree tree;
    public TreeDemo() {
        super("Tree Demo");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setPreferredSize(new Dimension(500, 300));

        DefaultMutableTreeNode structure = new DefaultMutableTreeNode("Main Tree");
        DefaultMutableTreeNode subTree1 = new DefaultMutableTreeNode("SubTree 1");
        DefaultMutableTreeNode subTree2 = new DefaultMutableTreeNode("SubTree 2");
        DefaultMutableTreeNode subTree3 = new DefaultMutableTreeNode("SubTree 3");

        subTree1.add(new DefaultMutableTreeNode("SubSubTree"));
        subTree1.add(new DefaultMutableTreeNode("SubSubTree2"));
        subTree1.add(new DefaultMutableTreeNode("SubSubTree3"));
        subTree1.add(new DefaultMutableTreeNode("SubSubTree4"));

        structure.add(subTree1);
        structure.add(subTree2);
        structure.add(subTree3);

        tree = new JTree(structure);
        tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
        tree.addTreeSelectionListener(this);

        pack();
        add(tree);
    }

    public void valueChanged(TreeSelectionEvent event) {
        JOptionPane.showMessageDialog(null, event.getPath().getLastPathComponent().toString());
    }

    public static void main(String[] args) {
        TreeDemo x = new TreeDemo();
        x.setVisible(true);
    }
}

Although in this case your code is simpler with <this> as the listener, as a general practice it doesn't work so well. As you add more and more controls (menus, buttons, toolbars...) and maybe mouse or keyboard listeners your class gets cluttered with more and more methods whose purpose is not immediately obvious. Plus many of those require the same method signature (eg actionPerformed...) so you end up having loads of if tests in thse methods to see where the event originated.
Your original structure - with a private class for each source/event combination looks longer at first, but it scales to the most complex UIs in a very clear and linear way.

ps: If you now have the answer to your original problem please mark this thread "solved" and start a new thread if you have a new problem - it helps to keep all this info properly organised and usable for others.

Edited 4 Years Ago by JamesCherrill

This article has been dead for over six months. Start a new discussion instead.