英文:
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_RELEASED
和MOUSE_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
是该函数的第二个参数。因此,如果extModifiers
为MouseEvent.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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论