Java JFXPanel: кнопка возврата eventHandler удерживается вместо нажатой кнопки - PullRequest
0 голосов
/ 08 апреля 2020

Я пытаюсь настроить обработчик события для клика, добавляемого в сцену в JFXPanel:

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

Как ни странно, если я удерживаю первичную кнопку и нажимаю вторичную или среднюю кнопку, кнопка, возвращаемая event.getButton(), является основной кнопкой, а не кнопкой, которая вызвала щелчок.

Так, например, если я удерживаю основную кнопку и нажимаю среднюю кнопку, приведенный выше код будет иметь консоль print 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() {
        // 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);
    }
}

Запустите код выше и нажмите вторичную кнопку, удерживая нажатой первичную, чтобы получить сообщение «Кнопка нажата: ПЕРВИЧНАЯ» вместо «Кнопка нажата: ВТОРИЧНАЯ».

Я проверил это, и поведение присутствует в обоих Java 10 и Java 14. Он также присутствует для MOUSE_RELEASED и MOUSE_CLICKED.

1 Ответ

0 голосов
/ 08 апреля 2020

Это текущая ошибка в Java.

Источником ошибки является функция mouseButtonToEmbedMouseButton в классе SwingEvents пакета com.sun.javafx.embed.swing.

Предполагаемая функция преобразовать кнопку мыши Swing в кнопку мыши JavaFX.

В качестве иллюстрации следующий код

SwingEvents.mouseButtonToEmbedMouseButton(intButton, MouseEvent.BUTTON1_DOWN_MASK)

всегда будет возвращать 1, независимо от значения intButton.

Если посмотреть на исходный код mouseButtonToEmbedMouseButton, проблема заключается в операторе if

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

, где extModifiers - второй аргумент функции. Поэтому, если extModifiers равно MouseEvent.BUTTON1_DOWN_MASK, abstractButton (что возвращается) всегда будет установлено на 1.

...