6
votes

Java - En attente d'un type de touche, appuyez sur pour continuer

Quel est le meilleur moyen de mettre en œuvre un type de chose "Appuyez sur X pour continuer" en Java?

Spécifiquement, j'ai une classe personnalisée qui étend jframe et une classe personnalisée qui s'étend jPanel. J'ai un Main.java (qui a une instance de ma classe de jframe), et il y a un point où je ne veux pas continuer tant que l'utilisateur a appuyé sur la barre d'espace: P>

Main.java: xxx pré>

Donc, dans ma classe de cadre, comment puis-je implémenter ceci: p>

myFrame.java: p>

/* This method only finishes when the space bar is pressed */
public void waitForSpace() {

}


0 commentaires

4 Réponses :


2
votes

Mettez ce que vous voulez faire lorsque l'utilisateur appuie sur l'espace dans ce gestionnaire. Très probablement, vous ne voulez pas faire (peu importe) chaque fois que la barre d'espace est pressée, mais seulement une partie du temps; Par conséquent, le gestionnaire d'événements devrait être conditionné sur la valeur de certaines variables et le code qui fonctionne avant vous souhaitez que l'utilisateur appuie sur l'espace doit définir cette variable à la valeur qui signifie "le faire". Le gestionnaire doit remettre la variable à la valeur par défaut après son exécution.


0 commentaires

1
votes

N'utilisez pas de Keylistener.

Utiliser des liaisons de clés. Vous avez déjà reçu un lien avec le tutoriel des clés de clés.


0 commentaires

2
votes

N'oubliez pas que les interface graphique swing sont conduites par l'événement. Alors n'attendez rien. Au lieu de cela, donnez à votre classe un champ d'état de classe d'une sorte, peut-être un booléen, changez la variable d'état sur la touche Presse, peut-être à l'aide de liaisons clés, puis n'autorise que certains comportements que si l'État n'a pas été modifié (via si les déclarations).


0 commentaires

1
votes

Utiliser un Nombre de comptage à rebours strong> Lorsque vous attendez () est appelé, le fil principal actuel () attendra jusqu'à ce que la méthode de compte à rebours () soit appelée à partir d'un autre thread.

Le KeyEventDispatcher Strong> vous permet d'ajouter une auditeur de frappe à l'échelle mondiale. Donc, chaque fois qu'une touche est appuyée sur DispatchKeyEvent () est appelée à partir de l'EDT (filetage de l'événement de répartition) et vous pouvez rechercher «l'espace» étant enfoncé et relâchez le verrou de compte à rebours que le loquet principal () est en attente. P>

Toutefois, si le fil qui appelle WaitingForSpace () est l'EDT, vous forcerez l'EDT à attendre lui-même, causant une impasse forte>. Il est impossible d'attendre sur l'EDT et de recevoir toujours des événements clés autant que je sache. P>

Cela fonctionnera tant que JFRAME se concentre: P>

public void waitForSpace() {
    final CountDownLatch latch = new CountDownLatch(1);
    KeyEventDispatcher dispatcher = new KeyEventDispatcher() {
        // Anonymous class invoked from EDT
        public boolean dispatchKeyEvent(KeyEvent e) {
            if (e.getKeyCode() == KeyEvent.VK_SPACE)
                latch.countDown();
            return false;
        }
    };
    KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(dispatcher);
    latch.await();  // current thread waits here until countDown() is called
    KeyboardFocusManager.getCurrentKeyboardFocusManager().removeKeyEventDispatcher(dispatcher);
}


8 commentaires

Cela vous dérangeriez-vous d'élaborer cela? Je n'ai jamais fait quelque chose comme ça avant. Où va ce code?


Cela enregistre-t-il seulement une fois si la barre d'espace est typée? Il semble s'inscrire plus d'une fois.


Chaque fois que la méthode est appelée un nouveau KeyEventDisPatcher sera ajoutée aux auditeurs, mais une fois que l'espace est enfoncé, il sera supprimé.


Mais si je tiens de la place, plusieurs événements sont tirés. Comment puis-je faire cela afin qu'il soit basé sur l'espace dactylographié, pas d'espace pressé?


Spécifiquement, si vous ajoutez une inscription d'impression au-dessus du «LOCK.Countdown», puis sur l'espace, il imprimera deux fois.


Un couvrant le loquet est utilisé lorsque vous souhaitez attendre que plusieurs threads travailleurs se terminent ce qui n'est pas ce que l'OP essaie de faire.


Vérifiez si e.getid () == keyevent.Key_Releed


Bien que cela soit une bonne façon de faire des choses, comme @gnon dit, cela ne fonctionne pas dans ce qui est probablement le cas le plus courant: où le code qui veut attendre est lui-même exécuté sur le fil de l'événement.