P R
P R

Reputation: 1301

JTree and dropdown options on right clicking nodes

I'm trying to use the JTree and implement different drop downs for all the parent nodes and the children nodes.

Here's what I've done:

pmTree.addMouseListener(new java.awt.event.MouseAdapter() {
        @Override
        public void mouseClicked(java.awt.event.MouseEvent evt) {
            try {
            if(evt.getButton() == evt.BUTTON1) {
            }
            else if (evt.getButton() == evt.BUTTON3) {
                TreePopup(evt);
                //pmTree.updateUI();
            }
            }catch (Exception e) {}
        }
    });

and PopupCode:

public void TreePopup(java.awt.event.MouseEvent evt) {
    DefaultMutableTreeNode node = (DefaultMutableTreeNode)  pmTree.getLastSelectedPathComponent();
    popup = new JPopupMenu();
    popup.setInvoker(pmTree);
    PopupHandler handler = new PopupHandler(pmTree, popup);
    if(node.getLevel() == 1)
    {
        popup.add(getMenuItem("Parent Node", handler));
    }
    else if(node.getLevel() == 2)
    {
        popup.add(getMenuItem("Child", handler));
     }
     }

and PopUpHandler:

public class PopupHandler extends javax.swing.JFrame implements ActionListener {
JPopupMenu popup;
Point loc;

public PopupHandler(JTree tree, JPopupMenu popup) {
    //this.tree = NewJFrame.pmTree;
    this.popup = popup;
    tree.addMouseListener(ma);
}

and also the

public void actionPerformed(java.awt.event.ActionEvent evt)  

for the Child or Parent node being clicked.

However, when I run the program, I get the SAME right click popups for both the child and parent node.

Sorry for the huge chunk of code. I've been stuck with it for 2 days and yet not successful. Thanks!

Upvotes: 2

Views: 3781

Answers (3)

Bryan
Bryan

Reputation: 11

Awesome. I was successfully able to put the setSelectionPath() call inside the override of getPopupLocaiton(). I had been trying to do it inside the ActionListener of my JMenuItem to no avail.

public Point getPopupLocation( MouseEvent e ) {
    Point point = null;
    if( e != null ) {
        TreePath path = getClosestPathForLocation( e.getX(), e.getY() );
        setSelectionPath( path );
        point = e.getPoint();
    }
    return point;
}

Upvotes: 1

kleopatra
kleopatra

Reputation: 51535

Don't go as low-level as a MouseListener, instead use the api around componentPopupMenu. Doing so, the general approach is dynamically configure the componentPopup in the getPopupLocation method, some simple example snippet:

    JPopupMenu popup = new JPopupMenu();
    final Action action = new AbstractAction("empty") {

        @Override
        public void actionPerformed(ActionEvent e) {
            // TODO Auto-generated method stub
        }
    };
    popup.add(action); 
    JTree tree = new JTree() {

        /** 
         * @inherited <p>
         */
        @Override
        public Point getPopupLocation(MouseEvent e) {
            if (e != null) {
               // here do your custom config, like f.i add/remove menu items based on context
               // this example simply changes the action name 
               TreePath path = getClosestPathForLocation(e.getX(), e.getY());
               action.putValue(Action.NAME, String.valueOf(path.getLastPathComponent()));
               return e.getPoint();
            }
            action.putValue(Action.NAME, "no mouse"); 
            return null;
        }

    };
    tree.setComponentPopupMenu(popup);

Upvotes: 4

Ingo Kegel
Ingo Kegel

Reputation: 48105

You check the selected node:

DefaultMutableTreeNode node = (DefaultMutableTreeNode)pmTree.getLastSelectedPathComponent();

to see if you have a "parent" or a "child" node. You should select the node at the mouse position first, otherwise it will not be the right node. Call

TreePath path = pmTree.getPathForLocation(evt.getX(), evt.getY());
if (path != null) {
    pmTree.setSelectionPath(path);
} else {
    return;
}

at the beginning of treePopup. (methods in Java should start with a lower case letter!)

Upvotes: 2

Related Questions