2009-12-16 3 views
3

J'essaie actuellement de recevoir des événements clés lors d'un glisser-déposer, mais il me semble que la mise au point est retirée en faisant glisser afin que je ne puisse pas écouter les événements clés.Comment recevoir des événements clés lors d'un glisser-déposer?

Je suis en train de faire glisser une sous-classe JComponent qui implémente KeyListener et demande le focus dans la méthode dragEnter de DragSourceListener, mais mon hypothèse est que le focus est retiré par la suite.

Maintenant, qui a le focus et comment puis-je le ramener à mon JComponent. Ou y at-il une approche différente qui convient mieux à dnd?

Merci d'avance.

MISE À JOUR:

Il y a beaucoup de code nécessaire pour faire ce travail, donc je vais seulement poster quelques extraits pour vous montrer ce que je suis en train de faire:

public class Stone extends JComponent implements Serializable, KeyListener { 

    public Stone(...) { 

     //... 

     setFocusable(true); 
     addKeyListener(this); 

     this.dragSource = DragSource.getDefaultDragSource(); 
     this.dgListener = new StoneDGListener(); 
     this.dsListener = new StoneDSListener(); 

     this.dragSource.createDefaultDragGestureRecognizer(
      this, 
      DnDConstants.ACTION_MOVE, 
      this.dgListener 
     ); 

     //... 

    } 

    //... 

    public void keyPressed(KeyEvent e) { 
     System.out.println("Stone: "+e.getKeyCode()); 
    } 

    //... 

    public class StoneDSListener implements DragSourceListener, Serializable { 

     //...  

     @Override 
     public void dragEnter(DragSourceDragEvent dsde) { 
      //... 
      Stone.this.requestFocus(); 
      addKeyListener(Stone.this); 
     } 

     //... 
    } 
} 

Qu'est-ce qui se passe est que avant que je suis en train de faire glisser le composant Stone mon JPanel a le focus afin qu'il reçoive les touches que je suis en train d'appuyer. Pendant le glisser je ne peux pas écouter les touches pressées (donc je ne sais pas qui a le focus), même si je le demande en dragEnter() et après que je publie le Stone tous les événements clés sont envoyés au Stone.

Il est probablement pas important pour la question, mais pour illustrer ce que je fais est ici une capture d'écran:

image showing the "drag" http://img685.imageshack.us/img685/1884/pico.png (Ici je traîne la Stone de la collection ci-dessous pour le terrain de jeu sur le dessus). Dans cet état, je ne sais pas comment savoir quelles touches sont enfoncées. Je dois comprendre cela afin de pouvoir faire tourner le Stone.

+0

est-il possible de mettre le code que vous utilisez? Et utilisez-vous un IDE? – medopal

+0

J'ai essayé de mettre autant de code que je le pensais utile. Je ne pense pas que cela fasse une différence, mais j'utilise Eclipse Ganymede sans aucun plugin. Btw. ce n'est pas une applet, mais une application de bureau standard. –

Répondre

3

Vous ne savez pas qui a le focus lors d'un glisser-déposer. Mais une solution alternative à votre problème serait d'ajouter un KeyEventDispatcher pour votre classe Stone au KeyboardFocusManager. De la JavaDoc:

Le KeyboardFocusManager est à la fois un emplacement centralisé pour le code client pour interroger le propriétaire de mise au point et initier des changements de mise au point, et un répartiteur d'événements pour tous FocusEvents, WindowEvents liés à focus, et KeyEvents +.

+ mon emphase.

Fondamentalement, nous utilisons un type similaire de code pour intercepter KeyEvents avant qu'ils ne touchent le composant qui a le focus. Il suffit de tester rapidement votre contexte de glisser-déposer et cela semble fonctionner (tant que votre application est centrée sur le système d'exploitation). Essentiellement quelque chose le long des lignes de:

Public Stone(...) { 
    // ... 

    KeyboardFocusManager fm = KeyboardFocusManager.getCurrentKeyboardFocusManager(); 
    fm.addKeyEventDispatcher(
     new KeyEventDispatcher() { 
      public boolean dispatchKeyEvent(KeyEvent e) { 
       System.out.println("Key Press: " + e.getKeyChar()); 
       return false; 
      }    
     } 
    ); 

    // ... 
} 

Vous aurez besoin de faire un peu de jambe travail sur l'activation et la désactivation lorsque l'utilisateur est plus glisser-déposer comme mon test imprime actuellement tout le temps.

Je me demande également s'il est possible d'utiliser le KeyboardFocusManager pour déterminer qui finit réellement avec le focus lors d'un glisser-déposer?

Quoi qu'il en soit, j'espère que cela vous donnera quelques nouvelles idées à essayer.

+0

Cela semble très prometteur et fonctionne très bien jusqu'à présent. Je n'ai pas eu le temps de travailler sur la partie activation/désactivation, mais cela ne semble pas très compliqué. J'accepterai votre réponse dès que j'aurai trouvé le temps de l'essayer. Merci beaucoup ! –

+0

A travaillé très bien. Merci! –

Questions connexes