tags:

views:

1064

answers:

3

If i have a GWT composite widget with three text boxes like for SSN, and i need to fire change event only when focus is lost from the widget as a whole, not from individual text boxes how to go about doing that?

A: 

You need to implement the Observer Pattern on your composite, and trigger a new notification everytime:

  • the focus is lost on a specific text box AND
  • the focus was not transferred to any of the other text boxes.
ivo
that won't work because of no guarantee on the order of events of focus lost and focus gained on different boxes.
retrobrain
Using DeferredCommand might do the trick:http://google-web-toolkit.googlecode.com/svn/javadoc/1.6/com/google/gwt/user/client/DeferredCommand.html
ivo
Clarifying: 1. Catch the event of focus lost from one of the text boxes; 2. Use DefferredCommand to check if the focus was not gained on the other text boxes; 3. If the other text boxes didn't gained focus, then your composite fires a "focus lost" (or whatever) notification
ivo
That won't work again, because in the deferred command you cannot be sure which text boxes deferred command in the focus gained method gets called first.
retrobrain
A: 

If you want just the event when your whole widget loses focus (not the text boxes), then make the top level of your widget be a FocusPanel, and expose the events that it gives you.

rustyshelf
That's the first thing i tried but for some reason no events are fired.FocusPanel holds a HorizontalPanel which has Three text boxes.
retrobrain
A: 

Couldn't you use a timer? On lost focus from a text box, start a 5ms (or something small) timer that when it hits, will check focus on all 3 TextBox instances. If none have focus, then you manually notify your observers. If one has focus, do nothing.

Put this in your Composite class:

private Map<Widget, Boolean> m_hasFocus = new HashMap<Widget, Boolean>();

And then add this to each one of your TextBox instances:

new FocusListener() {
  public void onFocus(Widget sender) {
    m_hasFocus.put(sender, Boolean.TRUE);
  }

  public void onLostFocus(Widget sender) {
    m_hasFocus.put(sender, Boolean.FALSE);
    new Timer() {
      public void run() {
        for (Boolean bool : m_hasFocus.values()) {
          if (bool) { return; }
        }
        notifyObservers();
      }
    };
  }
};
Steve Armstrong