2010-12-12 4 views
1

J'ai une classe VerticalPanel gwt dont j'ai besoin pour gérer les événements KeyDown. la méthode i utilisé pour implémenter gestionnaire de clavier dans ma classe est: i ajouter:Enregistrer KeyDownHandler sur GWT VerticalPanel

this.sinkEvents(Event.ONKEYDOWN); 

au constructeur alors i méthode remplacement onBrowserEvent() pour gérer l'événement clé vers le bas.

@Override 
public void onBrowserEvent(Event event) { 
// TODO Auto-generated method stub 
    super.onBrowserEvent(event); 
    int type = DOM.eventGetType(event); 
    switch (type) { 
    case Event.ONKEYDOWN: 
         //call method to handle this keydown event 
    onKeyDownEvent(event); 
    break; 
    default: 
    return; 

    } 
} 

Cependant, cette méthode ne fonctionne pas pour ce VerticalPanel class.no KeyDown événement est déclenché lorsque j'appuie sur une touche!

Il existe des widgets gwt spécifiques qui prennent en charge KeyDownHandler comme Button, etc .. VerticalPanel n'en fait pas partie. Nous avons donc besoin de travailler pour enregistrer un KeyDownHandler sur une classe qui étend VerticalPanel. pouvez-vous suggérer une idée ou un indice?

grâce

Répondre

9

Vous pouvez créer un Composite qui wrappes un FocusPanel et un VerticalPanel. De cette façon, vous pouvez capturer tous les événements clés à condition que le FocusPanel soit ciblé. déléguer tout simplement les méthodes nécessaires aux panneaux:

public void onModuleLoad() { 
    ExtendedVerticalPanel panel = new ExtendedVerticalPanel(); 
    panel.add(new Label("some content")); 
    panel.addKeyDownHandler(new KeyDownHandler() { 

     @Override 
     public void onKeyDown(KeyDownEvent event) { 
      if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) { 
       Window.alert("enter hit"); 
      } 
     } 
    }); 
    RootPanel.get().add(panel); 
} 

private class ExtendedVerticalPanel extends Composite implements HasWidgets, HasAllKeyHandlers { 

    private VerticalPanel fVerticalPanel; 
    private FocusPanel fFocusPanel; 

    public ExtendedVerticalPanel() { 
     fVerticalPanel = new VerticalPanel(); 
     fFocusPanel = new FocusPanel(); 
     fFocusPanel.setWidget(fVerticalPanel); 
     initWidget(fFocusPanel); 
    } 

    @Override 
    public void add(Widget w) { 
     fVerticalPanel.add(w); 
    } 

    @Override 
    public void clear() { 
     fVerticalPanel.clear(); 
    } 

    @Override 
    public Iterator<Widget> iterator() { 
     return fVerticalPanel.iterator(); 
    } 

    @Override 
    public boolean remove(Widget w) { 
     return fVerticalPanel.remove(w); 
    } 

    @Override 
    public HandlerRegistration addKeyUpHandler(KeyUpHandler handler) { 
     return fFocusPanel.addKeyUpHandler(handler); 
    } 

    @Override 
    public HandlerRegistration addKeyDownHandler(KeyDownHandler handler) { 
     return fFocusPanel.addKeyDownHandler(handler); 
    } 

    @Override 
    public HandlerRegistration addKeyPressHandler(KeyPressHandler handler) { 
     return fFocusPanel.addKeyPressHandler(handler); 
    } 
} 

MISE À JOUR

Votre question sur la façon d'empêcher le navigateur de défilement lorsque les touches fléchées sont enfoncées. Voici un petit exemple qui fonctionne pour moi:

public void onModuleLoad() { 
    ExtendedVerticalPanel panel = new ExtendedVerticalPanel(); 
    // make panel reeeeaally big 
    panel.setHeight("3000px"); 
    panel.add(new TextBox()); 
    panel.addKeyDownHandler(new KeyDownHandler() { 

     @Override 
     public void onKeyDown(KeyDownEvent event) { 
      if (event.getNativeKeyCode() == KeyCodes.KEY_DOWN) { 
       Window.alert("down hit"); 
       event.preventDefault(); 
      } 
     } 
    }); 
    RootPanel.get().add(panel); 
} 

Ajouter les gestionnaires dont vous avez besoin et appelez preventDefault() sur les événements du navigateur ne doit pas prendre en charge.

+0

oui solution parfaite. En fait, j'ai réalisé que FocusPanel était la solution en enveloppant mon VerticalPanel dans un FocusPanel. Cependant, votre code est très élégant. J'ai aimé l'idée d'écrire un ExtendedVerticalPanel. Merci beaucoup! – othman

+0

De rien. – z00bs

+0

Bonjour, J'ai une autre question: Quand j'inscris keyDownHandler pour mon ExtendedVerticalPanel et que j'utilise les touches Haut/Bas, il fait défiler le défilement de la fenêtre du navigateur tout en tirant des événements de touche haut/bas pour mon Panel. ce comportement n'est pas acceptable. J'ai essayé un correctif en appelant event.stopPropagation() au début de la méthode KeyDownHandler.onKeyDown (KeyDownEvent event). le problème est que la propagation d'événements d'arrêt désactive tous les événements clés pour les widgets dans mon Panel comme TextBox ect .. Comment puis-je empêcher le défilement de la fenêtre du navigateur de défiler tout en utilisant la touche haut/bas sur mon Panel? Merci beaucoup. – othman