JavaFX: gérer simultanément la combinaison de touches et l'événement de la souris


J'ai besoin de réagir sur une combinaison d'événements clé + souris comme:

Ctrl + Maj + R + left_mousebutton_clicked

, Mais je ne peux pas comprendre, comment gérer les "left_mousebutton_clicked" si et seulement si la combinaison de touches de Ctrl + Maj + R se produit.

Une solution comme

if(MouseEvent.isControlDown())

Ne fonctionnera pas car il peut y avoir différentes combinaisons de touches avec n'importe quel type de lettres.

Des idées?

Author: DVarga, 2017-04-05

2 answers

Vous pouvez utiliser un conteneur pour stocker les touches actuellement pressées:

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

Vous pouvez attacher des écouteurs au Scene du contrôle que vous souhaitez cibler avec le clic de souris:

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

Pendant que ces écouteurs maintiennent l'ensemble, vous pouvez simplement attacher un écouteur sur la cible 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!");
});

Exemple 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();
    }
}

Remarque: Les clés meta sont également stockées dans le Set mais elles ne sont pas utilisées par cet exemple. Les clés meta peuvent également être vérifiées dans l'ensemble plutôt que d'utiliser des méthodes sur l'événement mouse.

 3
Author: DVarga, 2017-04-05 11:03:58

Ctrl et shift peuvent être effectués de la manière dont vous l'avez approché. La touche gauche de la souris est le PrimaryButton

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

Et pour la clé "non spéciale" (comme r) I thnk, vous devez créer un booléen global - et un écouteur keyevent séparé pour cela. Donc:

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
}
});

Utilisez ensuite votre it avec les autres conditions...

    if(mouseEvent.isControlDown() && mouseEvent.isShiftDown && rIsDown &&  mouseEvent.isPrimaryKeyDown){
    // Do your stuff here
}
 0
Author: Lealo, 2017-08-10 21:23:43