简体   繁体   English

如何在 SwingGui 中调用鼠标右键单击事件?

[英]How can I call the mouse right click event in SwingGui?

I have a table.我有一张桌子。 If I right-click I got a JPopUpMenu but before the pop-up I want to select the row where the right-click event is done.如果我右键单击我得到一个 JPopUpMenu 但在弹出窗口之前我想选择完成右键单击事件的行。 Here is what I've tried.这是我尝试过的。

path_tbl.addMouseListener(new MouseAdapter() {
        @Override
        public void mousePressed(MouseEvent e) {
            System.out.println(e.getPoint());

            Point point = e.getPoint();
            int selectedRow = path_tbl.rowAtPoint(point);
            path_tbl.setRowSelectionInterval(selectedRow, selectedRow);
        }
    });

In that event, I cannot get any output from the console when I right-click.在那种情况下,当我右键单击时,我无法从控制台获得任何输出。 However, when I left-click, points are printed to the console.但是,当我左键单击时,点会打印到控制台。

java.awt.Point[x=105,y=76] java.awt.Point[x=105,y=76]

So, this event only works when I left-click.因此,此事件仅在我左键单击时有效。 How can I make this event work with right-click?如何通过右键单击使此事件起作用?

Since you want custom mouse behavior, you should not use setComponentPopupMenu .由于您需要自定义鼠标行为,因此不应使用setComponentPopupMenu

Instead, display the JPopupMenu yourself, using JPopupMenu's show method:相反,使用 JPopupMenu 的show方法自己显示 JPopupMenu:

JPopupMenu menu = /* ... */;

path_tbl.addMouseListener(new MouseAdapter() {
    private void showPopupMenuFor(MouseEvent e) {
        if (menu.isPopupTrigger(e)) {
            Point point = e.getPoint();
            int row = path_tbl.rowAtPoint(point);

            if (!path_tbl.isRowSelected(row)) {
                path_tbl.setRowSelectionInterval(row, row);
            }

            menu.show(path_tbl, e.getX(), e.getY());
        }
    }

    @Override
    public void mousePressed(MouseEvent e) {
        showPopupMenuFor(e);
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        showPopupMenuFor(e);
    }

    @Override
    public void mouseClicked(MouseEvent e) {
        showPopupMenuFor(e);
    }
});

You must check the MouseEvent in both mousePressed and mouseReleased, because exactly when a context menu is triggered depends on the platform and the look-and-feel.您必须在 mousePressedmouseReleased 中检查 MouseEvent,因为触发上下文菜单的确切时间取决于平台和外观。 (Checking in mouseClicked may or may not be necessary, but it doesn't hurt.) (检查 mouseClicked 可能是必要的,也可能不是必要的,但这并没有什么坏处。)

In most cases, I'm lazy, so if I don't need to do something, then I'd prefer not to.在大多数情况下,我很懒惰,所以如果我不需要做某事,那我宁愿不做。 In this case, I'd prefer to make use of the existing API works as much as possible, meaning, make use of JComponent#setComponentPopupMenu , as it will take care of the "how" and "when" the popup should be shown, based on the current platform.在这种情况下,我希望尽可能多地使用现有的 API 工作,也就是说,使用JComponent#setComponentPopupMenu ,因为它会处理弹出窗口应该显示的“方式”和“时间”,基于当前平台。

However, as you have discovered, by default, JTable will NOT select the row when the user presses the "right" mouse button, for that, you could just continue with your current workflow, but, checking to see if the MouseEvent is actually a "right" click.但是,正如您所发现的,默认情况下,当用户按下“右键”鼠标按钮时, JTable不会选择该行,为此,您可以继续当前的工作流程,但是,检查MouseEvent是否实际上是“右键点击。

Lucky for us, some of the original Swing developers were also "lazy" and they provided us with SwingUtilities.isRightMouseButton , yea 🎉幸运的是,一些最初的 Swing 开发人员也很“懒惰”,他们为我们提供了SwingUtilities.isRightMouseButton ,是的 🎉

在此处输入图像描述

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Vector;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.table.DefaultTableModel;

public final class Main {
    public static void main(String[] args) {
        new Main();
    }

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame frame = new JFrame();
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            setLayout(new BorderLayout());
            DefaultTableModel model = new DefaultTableModel(0, 10);
            for (int row = 0; row < 10; row++) {
                Vector data = new Vector(10);
                for (int col = 0; col < 10; col++) {

                    String value = row + "x" + ((char) (col + 'A'));
                    data.add(value);

                }
                model.addRow(data);
            }

            JPopupMenu menu = new JPopupMenu();
            menu.add("Hello");
            menu.add("This looks interesting");
            menu.add("I like bi-planes");

            JTable table = new JTable(model);
            table.setComponentPopupMenu(menu);
            table.addMouseListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    if (SwingUtilities.isRightMouseButton(e)) {
                        Point point = e.getPoint();
                        int row = table.rowAtPoint(point);

                        if (!table.isRowSelected(row)) {
                            table.setRowSelectionInterval(row, row);
                        }
                    }
                }

            });
            add(new JScrollPane(table));
        }

    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM