Search code examples
gwtuibinder

how to create a focusable widget


i have created my own gwt widgets that consist of a TextLabel and an image. I need that this widget be focusable. I extend this widget from the interface hasFocusHandler, focusable and blurhandler. Nothing is working. I am receiving neither focus nor blur event when i click on or outside of the widget. What should I do?

My code:

public class MyWidget extends ComplexPanel implements HasFocusHandlers, HasBlurHandlers, HasClickHandlers, Focusable{

  private Icon icon = new Icon();

  private TextNode text = new TextNode("");

  private static final FocusImpl impl = FocusImpl.getFocusImplForWidget();

  protected static FocusImpl getFocusImpl() {
    return impl;
  }

  public HandlerRegistration addClickHandler(ClickHandler handler) {
    return addDomHandler(handler, ClickEvent.getType());
  }

  @Override
  public HandlerRegistration addBlurHandler(BlurHandler handler) {
    return addDomHandler(handler,BlurEvent.getType());
  }

  @Override
  public HandlerRegistration addFocusHandler(FocusHandler handler) {
    return addDomHandler(handler, FocusEvent.getType());
  } 

  @Override
  public void onBrowserEvent(Event event) {
    switch (DOM.eventGetType(event)) {
        case Event.ONCLICK:
            if (isEnabled()) {
                super.onBrowserEvent(event);
            }
            break;
        default:
            super.onBrowserEvent(event);
            break;
    }
  }

  public int getTabIndex() {
    return impl.getTabIndex(getElement());  
  }

  @Override
  public void setAccessKey(char key) {
    DOM.setElementProperty(getElement(), "accessKey", "" + key);
  }

  @Override
  public void setFocus(boolean focused) {
    if (focused) {
        impl.focus(getElement());
    } else {
        impl.blur(getElement());
    }
  }    

  @Override
  public void setTabIndex(int index) {
    impl.setTabIndex(getElement(), index);
  }

  @Override
  protected void onAttach() {
    super.onAttach();

    int tabIndex = getTabIndex();
    if (-1 == tabIndex) {
        setTabIndex(0);
    }
  }
}

My implementation is not working (I am not receiving the onFocus call, when i click on the myWidget)

mywidget.addFocusHandler(new FocusHandler()
{
    @Override
    public void onFocus(FocusEvent event) {
    //DO SOMETHING                  
    }               
});

Solution

  • We should have more information, because I miss some code, for example, where do you attach the Icon and TextNode to the DOM?

    I have done one example and it works for me. Look:

    @UiField Label labelText;
    
    public MyWidget(String text) {
      super();
      //That is the key. Attach the widgets to the dom
      setElement(uiBinder.createAndBindUi(this).getElement()); 
      labelText.setText(text);
    }
    

    Also instead of having my internal widgets declared in the class, I have created a UiBinder class. Basically:

    <!DOCTYPE ui:UiBinder SYSTEM 'http://dl.google.com/gwt/DTD/xhtml.ent'>
    <ui:UiBinder xmlns:ui='urn:ui:com.google.gwt.uibinder' 
        xmlns:g='urn:import:com.google.gwt.user.client.ui'>
      <ui:style>
      </ui:style>
    
      <g:FlowPanel>
        <g:Label ui:field="labelText">
        </g:Label>      
      </g:FlowPanel>
    </ui:UiBinder> 
    

    In that case you can attach your widgets to the Panel quicker and easier. and in the constructor do only a setElement().

    If you have any doubt, just ask!