JavaFX:同时处理键组合和鼠标事件

时间:2017-04-05 07:45:53

标签: java events javafx key mouse

我需要对键+鼠标事件组合作出反应,如:

Ctrl + Shift + R + left_mousebutton_clicked

但我无法弄清楚,如何处理" left_mousebutton_clicked"仅当 Ctrl + Shift + R 的组合键出现时。

这样的解决方案
if(MouseEvent.isControlDown())

不起作用,因为可能存在与任何类型的字母不同的组合键。

有什么想法吗?

2 个答案:

答案 0 :(得分:3)

您可以使用容器存储当前按下的键:

private final Set<KeyCode> pressedKeys = new HashSet<>();

您可以通过鼠标单击将侦听器附加到您要定位的控件的Scene

scene.setOnKeyPressed(e -> pressedKeys.add(e.getCode()));
scene.setOnKeyReleased(e -> pressedKeys.remove(e.getCode()));

虽然这些侦听器维护了集合,但您只需在目标Node上附加一个侦听器:

Label targetLabel = new Label("Target Label");
targetLabel.setOnMouseClicked(e -> {
    if (e.getButton() == MouseButton.PRIMARY &&
        pressedKeys.contains(KeyCode.R) && 
        e.isShortcutDown() &&
        e.isShiftDown()) 

        System.out.println("handled!");
});

示例Application

public class MouseClickExample extends Application {

    private final Set<KeyCode> pressedKeys = new HashSet<>();

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

    @Override public void start(Stage stage) {
        VBox root = new VBox();
        Scene scene = new Scene(root, 450, 250);

        scene.setOnKeyPressed(e -> pressedKeys.add(e.getCode()));
        scene.setOnKeyReleased(e -> pressedKeys.remove(e.getCode()));

        Label targetLabel = new Label("Target Label");
        targetLabel.setOnMouseClicked(e -> {
            if (e.getButton() == MouseButton.PRIMARY && pressedKeys.contains(KeyCode.R) && e.isShortcutDown() && e.isShiftDown())
                System.out.println("handled!");
        });

        root.getChildren().add(targetLabel);
        stage.setScene(scene);
        stage.show();
    }
}

注意:元键也存储在Set中,但此示例不使用它们。也可以在集合中检查元键,而不是使用鼠标事件上的方法。

答案 1 :(得分:1)

ctrl和shift都可以按照你在那里的方式完成。鼠标左键是PrimaryButton

if(mouseEvent.isControlDown() && mouseEvent.isShiftDown && mouseEvent.isPrimaryKeyDown){
    // Do your stuff here
}

对于&#34;非特殊&#34; key(比如r)我认为你需要创建一个全局布尔值 - 以及一个单独的keyevent监听器。所以:

boolean rIsDown = false;

scene.setOnKeyPressed(e -> {
if(e.getCode() == KeyCode.R){
    System.out.println("r was pressed");
    //set your global boolean "rIsDown" to true
}
});

scene.setOnKeyReleased(e -> {
if(e.getCode() == KeyCode.R){
    System.out.println("r was released");
    //set it rIsDown back to false
}
});

然后将它与其他条件一起使用......

    if(mouseEvent.isControlDown() && mouseEvent.isShiftDown && rIsDown &&  mouseEvent.isPrimaryKeyDown){
    // Do your stuff here
}