在GWT VerticalPanel上注册KeyDownHandler

在GWT VerticalPanel上注册KeyDownHandler,gwt,event-handling,Gwt,Event Handling,我有一个gwt VerticalPanel类,我需要为它处理KeyDown事件。 我在类中用于实现键盘处理程序的方法是: 我补充说: 建造师 然后我重写onBrowserEvent()方法来处理键关闭事件 @Override public void onBrowserEvent(Event event) { // TODO Auto-generated method stub super.onBrowserEvent(event); int type = DOM.eventGetTy

我有一个gwt VerticalPanel类,我需要为它处理KeyDown事件。 我在类中用于实现键盘处理程序的方法是: 我补充说:

建造师 然后我重写onBrowserEvent()方法来处理键关闭事件

 @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;

  }
 }
但是,此方法不适用于此VerticalPanel类。当我按键时,不会触发KeyDown事件

有一些特定的gwt小部件支持KeyDownHandler,比如Button等。VerticalPanel不是其中之一。因此,我们需要一种变通方法,在扩展VerticalPanel的类上注册KeyDownHandler。 你能提出一个想法或暗示吗


谢谢

您可以创建一个
组合
,其中包含一个
焦点面板
和一个
垂直面板
。这样,只要聚焦了
FocusPanel
,您就可以捕获所有关键事件。只需将所需的方法委派给面板:

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

添加所需的处理程序,并对浏览器不能处理的事件调用
preventDefault()

您可以创建一个
Composite
,其中包含一个
FocusPanel
和一个
VerticalPanel
。这样,只要聚焦了
FocusPanel
,您就可以捕获所有关键事件。只需将所需的方法委派给面板:

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

添加所需的处理程序,并对浏览器不能处理的事件调用
preventDefault()

是完美的解决方案。事实上,我确实意识到FocusPanel是一个解决方案,它将我的垂直面板包装在FocusPanel中。我喜欢写一个扩展的垂直面板的想法。多谢!您好,我还有一个问题:当我为ExtendedVerticalPanel注册keyDownHandler并使用向上/向下键时,它会滚动浏览器窗口滚动条,同时为我的面板触发向上/向下键事件。这种行为是不可接受的。我试图通过在KeyDownHandler.onKeyDown(KeyDownEvent事件)方法的开头调用event.stopPropagation()进行修复。问题是停止事件传播会禁用面板内小部件(如TextBox等)的所有按键事件。如何防止浏览器窗口滚动条在使用面板上的键向上/向下时滚动?非常感谢。是的,我使用了preventDefault(),它还禁用了面板上的关键事件。禁用键的文本框位于FocusPanel内。这可能是问题所在吗?preventDefault()似乎取消了面板内所有小部件的关键事件。知道出了什么问题吗?非常感谢你!我现在成功地处理了关键事件。非常感谢你的帮助!是的,完美的解决方案。事实上,我确实意识到FocusPanel是一个解决方案,它将我的垂直面板包装在FocusPanel中。我喜欢写一个扩展的垂直面板的想法。多谢!您好,我还有一个问题:当我为ExtendedVerticalPanel注册keyDownHandler并使用向上/向下键时,它会滚动浏览器窗口滚动条,同时为我的面板触发向上/向下键事件。这种行为是不可接受的。我试图通过在KeyDownHandler.onKeyDown(KeyDownEvent事件)方法的开头调用event.stopPropagation()进行修复。问题是停止事件传播会禁用面板内小部件(如TextBox等)的所有按键事件。如何防止浏览器窗口滚动条在使用面板上的键向上/向下时滚动?非常感谢。是的,我使用了preventDefault(),它还禁用了面板上的关键事件。禁用键的文本框位于FocusPanel内。这可能是问题所在吗?preventDefault()似乎取消了面板内所有小部件的关键事件。知道出了什么问题吗?非常感谢你!我现在成功地处理了关键事件。非常感谢你的帮助!
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);
}