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

huangapple go评论71阅读模式
英文:

Java JFXPanel: eventHandler returning button held instead of button pressed

问题

以下是您提供的内容的翻译部分:

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

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

例如,如果我按住主按钮并点击中间按钮,上述代码将在控制台打印Button pressed: PRIMARY

我在一个纯JavaFX应用程序中尝试过,在那里getButton()始终返回被按下的按钮;问题实际上出现在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() {
        // 在JPanel内设置JFXPanel
        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);

        // 错误地返回按住的按钮而不是按下的按钮的事件处理程序
        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中都存在。在MOUSE_RELEASEDMOUSE_CLICKED事件中也存在这种问题。

英文:

I am trying to setup an event handler for a click, to added on a scene within a JFXPanel:

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

Strangely enough, if I hold the primary button and click the secondary or middle button, the button returned by event.getButton() is the primary button, not the button that triggered the click.

So for example if I hold the primary button down and click on the middle button, the code above will have the console print Button pressed: PRIMARY.

I tried in a purely JavaFX application, and there getButton() always returns the button pressed; the issue is thus with the JFXPanel.

Is there an explanation, or workaround for this strange behavior?

Here is a complete example:

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

Run the code above and click the secondary button while holding down the primary to get the message "Button pressed: PRIMARY" instead of "Button pressed: SECONDARY".

I tested it out and the behavior is present in both Java 10 and Java 14.It is also present for MOUSE_RELEASED and MOUSE_CLICKED.

答案1

得分: 0

这是Java中的一个当前错误。

错误的源头在于包com.sun.javafx.embed.swing中的类SwingEvents中的函数mouseButtonToEmbedMouseButton

该函数的目的是将Swing鼠标按钮转换为JavaFX鼠标按钮。

举例来说,以下代码

SwingEvents.mouseButtonToEmbedMouseButton(intButton, MouseEvent.BUTTON1_DOWN_MASK)

无论intButton取什么值,都将始终返回1

mouseButtonToEmbedMouseButton的源代码可以看出,问题在于这个if语句

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

其中extModifiers是该函数的第二个参数。因此,如果extModifiersMouseEvent.BUTTON1_DOWN_MASK,那么abstractButton(返回值)将始终被设置为1。

英文:

It's a current bug in Java.

The source of the bug is the function mouseButtonToEmbedMouseButton in class SwingEvents of package com.sun.javafx.embed.swing.

The function is supposed to convert a Swing mouse button into a JavaFX mouse button.

As an illustration, the following code

SwingEvents.mouseButtonToEmbedMouseButton(intButton, MouseEvent.BUTTON1_DOWN_MASK)

will always return 1, no matter what value intButton takes.

Looking at the source code for mouseButtonToEmbedMouseButton, the problem is the if statement

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

where extModifiers is the second argument of the function. So if extModifiers is MouseEvent.BUTTON1_DOWN_MASK, the abstractButton (what is returned) will always be set to 1.

huangapple
  • 本文由 发表于 2020年4月8日 17:04:58
  • 转载请务必保留本文链接:https://go.coder-hub.com/61097035.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定