Java JFXPanel:事件处理程序返回按住按钮而不是按下按钮

Java JFXPanel: eventHandler returning button held instead of button pressed

我正在尝试为单击设置一个事件处理程序,以添加到 JFXPanel 中的场景中:

scene.addEventHandler(MouseEvent.MOUSE_PRESSED, event -> System.out.println("Button pressed: " + event.getButton().name()));

奇怪的是,如果我按住主按钮并单击辅助按钮或中间按钮,event.getButton() 返回的按钮是主按钮,而不是触发点击的按钮。

例如,如果我按住主按钮并单击中间按钮,上面的代码将使控制台打印 Button pressed: PRIMARY

我在纯 JavaFX 应用程序中尝试过,getButton() 总是 returns 按钮被按下;因此,问题出在 JFXPanel 上。

是否有针对这种奇怪行为的解释或解决方法?

这是一个完整的例子:

import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.input.MouseEvent;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class Test {
    public static void main(String[] args) { SwingUtilities.invokeLater(Test::initAndShowGUI); }

    private static void initAndShowGUI() {
        // Setup the JFXPanel inside a JPanel
        JFrame frame = new JFrame();
        final JFXPanel fxPanel = new JFXPanel();
        frame.add(fxPanel);
        frame.setSize(300, 200);
        frame.setVisible(true);

        Platform.runLater(() -> initFX(fxPanel));
    }

    private static void initFX(JFXPanel fxPanel) {
        Group  root = new Group();
        Scene scene = new Scene(root);

        // The event handler that incorrectly returns the button held instead of the one pressed
        scene.addEventHandler(MouseEvent.MOUSE_PRESSED, event -> System.out.println("Button pressed: " + event.getButton().name()));

        fxPanel.setScene(scene);
    }
}

运行 上面的代码并在按住主按钮的同时单击辅助按钮以获取消息 "Button pressed: PRIMARY" 而不是 "Button pressed: SECONDARY".

我对其进行了测试,Java 10 和 Java 14.It 都存在这种行为 MOUSE_RELEASEDMOUSE_CLICKED

这是 Java 中的当前错误。

错误的来源是包 com.sun.javafx.embed.swing.

的 class SwingEvents 中的函数 mouseButtonToEmbedMouseButton

该函数应该将 Swing 鼠标按钮转换为 JavaFX 鼠标按钮。

作为示例,下面的代码

SwingEvents.mouseButtonToEmbedMouseButton(intButton, MouseEvent.BUTTON1_DOWN_MASK)

将始终 return 1,无论 intButton 取什么值。

查看mouseButtonToEmbedMouseButton的源代码,问题出在if语句

if ((extModifiers & MouseEvent.BUTTON1_DOWN_MASK) != 0){
    abstractButton = AbstractEvents.MOUSEEVENT_PRIMARY_BUTTON;}

其中 extModifiers 是函数的第二个参数。因此,如果 extModifiersMouseEvent.BUTTON1_DOWN_MASK,则 abstractButton(returned)将始终设置为 1。