Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JTree rightclick behaviour like in any Filebrowser

I am trying to implement a JTree to represent a database! The Root is the database, which can have several relations. Each relation can have attributes and functional dependencies. Each node (database, relation, attribute and fd) has a different rightclick menu. The first step was to implement the popdown menu in the standard way (first leftclick on a node, then rightclick to show popupmenu).

Now I want to change it to the standard behaviour of file-explorers. A rightclick selects the node and shows the correct popupmenu.

Currently I am able to rightclick and show a popupmenu, but the menu is incorrect. It is the menu of the previous selected node.

Here is an examplepicture of the tree:

enter image description here

This here is my class:

public class ShowPopupMouseListener extends MouseAdapter {
  // Refernece: http://goo.gl/plojB
  private JTree tree;
  private JPopupMenu dbPopUpMenu;
  private JPopupMenu relPopUpMenu;
  private JPopupMenu attrPopUpMenu;
  private JPopupMenu fdPopUpMenu;
  private AttrPopupFactory attrPopupFactory;

  public ShowPopupMouseListener(JTree jTree) {
    this.tree = jTree;
    DbPopupFactory dbPopupFactory = new DbPopupFactory(tree);
    dbPopUpMenu = dbPopupFactory.getDbPopupMenu();

    RelPopupFactory relPopupFactory = new RelPopupFactory(tree);
    relPopUpMenu = relPopupFactory.getRelPopupMenu();

    attrPopupFactory = new AttrPopupFactory(tree);
    attrPopUpMenu = attrPopupFactory.getAttrPopupMenu();

    FdPopupFactory fdPopupFactory = new FdPopupFactory(tree);
    fdPopUpMenu = fdPopupFactory.getFdPopupMenu();
  }

  public void mousePressed(MouseEvent e) {
    showMenuIfPopupTrigger(e);
  }

  public void mouseClicked(MouseEvent e) {
    showMenuIfPopupTrigger(e);
  }

  public void mouseReleased(MouseEvent e) {
    showMenuIfPopupTrigger(e);
  }

  private void showMenuIfPopupTrigger(final MouseEvent e) {

    if (e.isPopupTrigger()) {
      setSelectedItemsOnPopupTrigger(e);

      if (tree.getLastSelectedPathComponent() instanceof DatabaseNode) {
        addRightClickPopUpMenu(tree, dbPopUpMenu);
      } else if (tree.getLastSelectedPathComponent() instanceof RelationNode) {
        addRightClickPopUpMenu(tree, relPopUpMenu);
      } else if (tree.getLastSelectedPathComponent() instanceof AttributeNode) {
        attrPopupFactory.updateKeyCheckboxes();
        addRightClickPopUpMenu(tree, attrPopUpMenu);
      } else if (tree.getLastSelectedPathComponent() instanceof FunctionalDependencyNode) {
        addRightClickPopUpMenu(tree, fdPopUpMenu);
      }
    }
  }

  private void addRightClickPopUpMenu(Component component,
      final JPopupMenu popUpMenu) {
    component.addMouseListener(new MouseAdapter() {
      public void mousePressed(MouseEvent e) {
        if (e.isPopupTrigger()) {
          showPopUpMenu(e);
        }
      }

      public void mouseReleased(MouseEvent e) {
        if (e.isPopupTrigger()) {
          showPopUpMenu(e);
        }
      }

      private void showPopUpMenu(MouseEvent e) {
        popUpMenu.show(e.getComponent(), e.getX(), e.getY());
      }
    });
  }

  private void setSelectedItemsOnPopupTrigger(MouseEvent e) {
    TreePath p = tree.getPathForLocation(e.getX(), e.getY());
    if (!tree.getSelectionModel().isPathSelected(p)) {
      tree.getSelectionModel().setSelectionPath(p);
    }
  }

}

And in my tree I initialize it the following way:

UIManager.put("PopupMenu.consumeEventOnClose", Boolean.FALSE);
tree.getSelectionModel().setSelectionMode(TreeSelectionModel.DISCONTIGUOUS_TREE_SELECTION);
tree.addMouseListener(new ShowPopupMouseListener(tree));

Any suggestions why this is not working?

like image 623
Andreas Freitag Avatar asked May 09 '12 09:05

Andreas Freitag


1 Answers

You should try keeping things simple, the following is all you really need:

 class RightMouseListener implements MouseListener {

    @Override
    public void mouseClicked(MouseEvent e) {

        if (SwingUtilities.isRightMouseButton(e)) {

            int row = tree.getClosestRowForLocation(e.getX(), e.getY());
            tree.setSelectionRow(row);
            popupMenu.show(e.getComponent(), e.getX(), e.getY());
        }
    }

    ...

    //other overrides

    ...
 };

This is the bare minimum you need to achieve the functionality you're asking for, you can obviously add more custom functionality as needed.

like image 176
arkon Avatar answered Sep 29 '22 07:09

arkon