События JavaFX для взаимодействия с мышью не запускаются при нажатии клавиши

JavaFX не выполняет такие события, как ActionEvent для Button или CheckBox, если нажата клавиша-модификатор, например CTRL или SHIFT. Насколько я понимаю, это поведение реализовано в ButtonBehavior (например, обратите внимание на выражение ! keyDown в следующем методе из этого класса):

@Override public void mouseReleased(MouseEvent e) {
    // if armed by a mouse press instead of key press, then fire!
    final ButtonBase button = getControl();
    if (! keyDown && button.isArmed()) {
        button.fire();
        button.disarm();
    }
}

Во-первых, я не очень понимаю причину этого. Какова цель не запускать кнопку, если клавиша нажата?

Это мой вариант использования: я хочу реализовать флажок, который можно установить/снять, как обычно. Это переключит некоторое состояние в модели. Но у него должна быть дополнительная функция: если пользователь нажимает какую-либо клавишу, например CTRL, во время проверки/снятия отметки с помощью мыши, в модели должен быть установлен дополнительный флаг, называемый «заблокировано» или «защищено», что предотвратит возможность изменения состояния. перезаписывается какой-то другой логикой приложения.

Это должно дать представление о прецеденте, но если нет, это не имеет большого значения для моего фактического вопроса: как я могу сделать так, чтобы CheckBox все еще можно было переключать (или нажимать Button), даже если пользователь нажимает ключ-модификатор?

Спасибо за вашу помощь!


person Till F.    schedule 14.01.2019    source источник


Ответы (1)


Это странно, что вы можете реализовать это самостоятельно так

public class Main extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception{
        VBox vBox = new VBox();
        vBox.setAlignment(Pos.CENTER);

        CheckBox checkBox = new CheckBox();
        checkBox.setOnMouseClicked(event -> {
            if(event.isControlDown()) {
                System.out.print("Control down click ");
                checkBox.setSelected(!checkBox.isSelected());
            }
            else
                System.out.print("Normal click ");

            System.out.println("Checked Status:"+checkBox.isSelected());
        });

        Button button = new Button("Button");
        button.setOnMouseClicked(event -> {
            if(event.isControlDown())
                System.out.println("Control down click");
            else
                System.out.println("Normal click");
        });

        vBox.getChildren().addAll(new Label("Click the box"),checkBox,button);


        primaryStage.setScene(new Scene(vBox));
        primaryStage.show();
    }

    public static void main(String[] args) { launch(args); }

}

Вывод для CheckBox:

Normal click Checked Status:true
Normal click Checked Status:false
Control down click Checked Status:true
Control down click Checked Status:false

Вывод для кнопки:

Normal click
Control down click
person Matt    schedule 14.01.2019
comment
Хорошо спасибо. Это решение, о котором я думал сам. Это означает, что мы повторно реализуем поведение щелчка флажка. Может быть, у вас есть умная идея, как мы можем повторно использовать обработчик по умолчанию? В противном случае нам придется также учитывать состояние indeterminate, т.е. если allowIndeterminate истинно. - person Till F.; 14.01.2019