如果按下键,则不会触发鼠标交互的 JavaFX 事件

Posted

技术标签:

【中文标题】如果按下键,则不会触发鼠标交互的 JavaFX 事件【英文标题】:JavaFX Events for Mouse Interactions are not triggered if Key is pressed 【发布时间】:2019-01-14 15:57:14 【问题描述】:

如果按下 CTRL 或 SHIFT 之类的修饰键,JavaFX 不会执行诸如ButtonCheckBoxActionEvent 之类的事件。据我了解,这种行为是在 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 是按下)即使用户按下了修饰键?

感谢您的帮助!

【问题讨论】:

【参考方案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

【讨论】:

好的,谢谢。这就是我自己想的解决方案。这意味着我们重新实现了复选框的点击行为。也许您有一些聪明的想法,我们可以如何重用默认处理程序?否则我们将不得不考虑indeterminate 状态,即如果allowIndeterminate 为真。

以上是关于如果按下键,则不会触发鼠标交互的 JavaFX 事件的主要内容,如果未能解决你的问题,请参考以下文章

javafx KeyEvent触发两次

禁用键盘但让我的程序仍然知道何时按下键

Android - OnTouchListener如果已按下屏幕则不会触发

JavaFX区分拖动和单击

WPF 鼠标按下事件不会触发

为啥鼠标右键单击在按下时会触发“pointerdown”事件,但在释放时不会触发“pointerup”事件?