2017-09-24 2 views
1

J'ai une erreur en disant que mes conditions sont toujours fausses. Fondamentalement, la convention pour la fermeture des applications sur OSX utilise la combinaison de touches "COMMAND + W"Liaisons de touches dans JavaFX en utilisant des expressions Lambda ne fonctionnant pas

Je suis en train de reproduire cela dans mon programme.

scene.setOnKeyPressed(e -> { 
     if ((e.getCode() == KeyCode.COMMAND) && (e.getCode() == KeyCode.W)) { 
      controller.exitClick(); 
     } 
    }); 

Il fonctionne si je n'ai que la première condition, mais bien sûr, je ne veux pas l'utilisateur de fermer l'application en appuyant simplement sur W.

Le contrôleur est juste une instance de ma classe de contrôleur où je emprunter la fonction de sortie à partir de parce que j'ai personnalisé sortie et minimiser les boutons sur mon application.

Que se passe-t-il ici?

Répondre

0

L'événement setOnKeyPressed détecte un touche à la fois, vous ne pouvez pas vérifier deux d'entre eux dans une condition, car il ne peut demander à un.

Ce que vous pouvez faire est de créer plusieurs boolean variables (un pour chaque touche) et setOnKeyPressed vous avez des conditions qui vérifient chaque touche séparément et si la actuelle touche pressée est l'un d'entre eux, vous définissez la variable correspondant à true. Après avoir vérifié quelle touche a été pressée, vous vérifiez les deux variables, si les deux sont true puis quelqu'un a appuyé sur les deux touches.

Un petit problème est que les variables ne sont jamais tournées vers false, que se passe-t-il si quelqu'un n'appuie pas sur la touche? Vous pouvez utiliser setOnKeyReleased qui est un événement clé appelé quand une clé est libérée. vérifiez chaque clé séparément et définissez les variables de condition sur false si la clé a été relâchée.

Donc, ça devrait le faire. Si vous avez besoin d'un exemple de code, il suffit de demander.

EDIT

L'exemple ci-dessous présente la détection de la presse multi-clé dans JavaFX.

D'abord j'ai besoin de définir des variables booléennes qui sauvegardent si oui ou non ma touche est pressée. Ils devraient être des variables de classe.

boolean keyCommand = false; 
boolean keyW = false; 

Ensuite, nous avons besoin d'ajouter 2 événements à notre scène:

événement onKeyPressed détecte lorsque chacun de notre touche est enfoncée. Rappelez-vous que l'événement est appelé séparément pour chaque clé.

L'événement onKeyReleased détectera que nos touches ne sont plus enfoncées. Cet événement est appelé pour chaque clé séparément.

scene.setOnKeyPressed(e -> { 
     if(e.getCode() == KeyCode.COMMAND) 
        keyCommand = true; 
     else if(e.getCode() == KeyCode.W) 
        keyW = true; 

      if(keyCommand && keyW) 
       //both are pressed 
       doSomething(); 

}); 

maintenant au deuxième événement:

scene.setOnKeyReleased(e -> { 
     if(e.getCode() == KeyCode.COMMAND) 
       keyCommand = false; 
     else if(e.getCode() === KeyCode.W) 
       keyW = false; 
}); 

Et voilà. Maintenant, les variables booléennes ne sont peut-être pas le moyen idéal pour stocker les données, BooleanProperty pourrait être préférable, mais cela devrait fonctionner aussi bien.

+0

Puis-je avoir un exemple de code? Je comprends à peine ce que vous voulez dire. – compute

+0

Voir, j'ai eu une idée quelque chose du genre que j'ai implémenté mais j'ai eu l'erreur que les variables utilisées dans les expressions lambda soient finales ou effectivement finales. Les deux variables booléennes ne peuvent donc pas être utilisées. – compute

+0

@compute les avez-vous définis comme des variables de classe, pas dans une méthode? – tomtzook

0

J'ai résolu cela en utilisant des entiers et une seule méthode.

Je ne connais pas les vulnérabilités potentielles pour le faire de cette façon mais voici le code.

scene.setOnKeyPressed(e -> { 
     if(e.getCode() == KeyCode.SHIFT) 
      count++; 
     else if(e.getCode() == KeyCode.W) 
      count++; 
     if(count == 3) 
      controller.exitClick(); 
    }); 

Il y a une valeur globale