JTree右键单击任何Filebrowser中的行为

时间:2012-05-09 09:17:29

标签: java swing jtree jpopupmenu

我正在尝试实现一个JTree来表示数据库! Root是数据库,可以有多个关系。每个关系都可以具有属性和功能依赖性。 每个节点(数据库,关系,属性和fd)都有一个不同的右键菜单。 第一步是以标准方式实现弹出菜单(首先左键单击一个节点,然后右键单击以显示弹出菜单)。

现在我想将其更改为文件浏览器的标准行为。右键单击选择节点并显示正确的弹出菜单。

目前我可以右键单击并显示弹出菜单,但菜单不正确。它是上一个选定节点的菜单。

以下是树的示例图片:

enter image description here

这是我的班级:

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);
    }
  }

}

在我的树中,我按照以下方式初始化它:

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

为什么这不起作用的任何建议?

1 个答案:

答案 0 :(得分:9)

你应该试着保持简单,以下是你真正需要的:

 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

    ...
 };

这是您实现所需功能所需的最低限度,显然您可以根据需要添加更多自定义功能。