4

我有一种情况,我在右键单击 JTable 时创建了一个弹出菜单。创建弹出菜单的标准方法:

aJTable.setComponentPopupMenu(rightClickMenu);

现在,在注册的操作中,我无法找出右键单击哪个单元格以显示该弹出菜单。

rightClickMenuItem.addActionListener(new AbstractAction() {
    @Override
    public void actionPerformed(ActionEvent e) {
        // Work out what cell was right clicked to generate the menu
    }

});

关于你如何做到这一点的任何想法?

4

3 回答 3

5

令人惊讶的事实:在安装了 componentPopupMenu 后,mouseListener 永远不会看到作为 popupTrigger 的 mouseEvent(原因是显示 componentPopup 是由 BasicLookAndFeel 安装的 AWTEventListener 全局处理的,并且该侦听器会使用该事件)。

唯一可以看到该触发器的 mousePosition 的地方是 getPopupLocation(MouseEvent),因此获取它的唯一可靠方法(用于执行与位置相关的配置/操作)是 @Mad 建议覆盖该方法并将值存储在某处以后使用。

下面的代码片段使用 clientProperty 作为存储位置:

final JTable table = new JTable(new AncientSwingTeam()) {

    @Override
    public Point getPopupLocation(MouseEvent event) {
        setPopupTriggerLocation(event);
        return super.getPopupLocation(event);
    }

    protected void setPopupTriggerLocation(MouseEvent event) {
        putClientProperty("popupTriggerLocation", 
                event != null ? event.getPoint() : null);
    }
};
JPopupMenu popup = new JPopupMenu();
Action action = new AbstractAction("show trigger location") {

    @Override
    public void actionPerformed(ActionEvent e) {
        JPopupMenu parent = (JPopupMenu) SwingUtilities.getAncestorOfClass(
                JPopupMenu.class, (Component) e.getSource());
        JTable invoker = (JTable) parent.getInvoker();
        Point p = (Point) invoker.getClientProperty("popupTriggerLocation");
        String output = p != null ? "row/col: " 
             + invoker.rowAtPoint(p) + "/" + invoker.columnAtPoint(p) : null; 
        System.out.println(output);
    }
};
popup.add(action);
popup.add("dummy2");
table.setComponentPopupMenu(popup);
于 2013-06-26T09:53:04.090 回答
3

@MadProgrammer 对 getPopupLocation 的建议看起来很有希望,但我不知道如何在表格和 actionEvent 之间获取信息......

我通过确保在您右键单击该行时选择该行来解决这个问题 - >因为弹出菜单阻止选择该行,您可以添加一个鼠标侦听器,以确保无论单击什么都选择该行(左或右)被按下。

aTable.addMouseListener(new MouseAdapter() {
    @Override
    public void mousePressed(MouseEvent e) {
        int r = aTable.rowAtPoint(e.getPoint());
        if (r >= 0 && r < clt.getRowCount()) {
            aTable.setRowSelectionInterval(r, r);
        } else {
            aTable.clearSelection();
        }
    }
});

这意味着在rightClickMenuItem的动作监听器中,可以抓取表格选中的单元格/行

rightClickMenuItem.addActionListener(new AbstractAction() {
    @Override
    public void actionPerformed(ActionEvent e) {
        aTable.get details about the selected one....
    }
});

太容易了!感谢大家的帮助。

于 2012-12-12T03:38:36.650 回答
0

JTable 有方法

int row = rowAtPoint(p);
int col = columnAtPoint(p);

所以传递 MouseEvent 的点并使用这些值

添加一个MouseListener并将最后一个右键单击点存储在某处。

于 2012-12-11T08:08:12.173 回答