How to fire events registered with a HandlerManager?

1,477 views
Skip to first unread message

jscheller

unread,
Aug 19, 2009, 8:33:27 PM8/19/09
to Google Web Toolkit
Hello -

So, I've got a composite that has something like this inside it...

private HandlerManager changeHandlers = new HandlerManager( null );

public HandlerRegistration addValueChangeHandler(ValueChangeHandler
handler)
{ return changeHandlers.addHandler(ValueChangeEvent.getType(),
handler); }

...and somewhere down the pipeline, I want to actually fire off an
event to anyone who registered a handler when the composite decides
it's represented value has changed and wants the rest of the world to
know. However, the syntax for actually constructing and firing the
event off has got me pulling my hair out.

I've tried variants of sending the event through the change
handlers...

changeHandlers.fireEvent( new ValueChangeEvent("foo") );
changeHandlers.fireEvent( new ValueChangeEvent<String>("foo") );

...and using the static fire() method in the event class itself...

ValueChangeEvent<String>.fire( changeHandlers, "foo");

...and Eclipse complains loudly about all of these constructions. I
mean, I know this can't be that hard, but I can't find any good
examples of things like this using the new (GWT 1.6 or later) event
handlers, and reading the code sends me down a DOM event/Java generics
rabbit hole that I'm frankly not experienced enough to deal with
yet...

Any help appreciated!

Jim

Thomas Broyer

unread,
Aug 20, 2009, 5:25:16 AM8/20/09
to Google Web Toolkit


On Aug 20, 2:33 am, jscheller <jschel...@csoftware.com> wrote:
> Hello -
>
> So, I've got a composite that has something like this inside it...
>
> private HandlerManager changeHandlers = new HandlerManager( null );
>
> public HandlerRegistration      addValueChangeHandler(ValueChangeHandler
> handler)
>    { return changeHandlers.addHandler(ValueChangeEvent.getType(),
> handler); }

You shouldn't ever instantiate a HandlerManager (except if you use one
as an "event bus"; but that's another story and at least this rule is
true for widgets); just call the Widget#addHandler(...) method.

public HandlerRegistration addValueChangeHandler
(ValueChangeHandler<String> handler) {
return addHandler(handler, ValueChangeEvent.getType());
}

> ...and somewhere down the pipeline, I want to actually fire off an
> event to anyone who registered a handler when the composite decides
> it's represented value has changed and wants the rest of the world to
> know. However, the syntax for actually constructing and firing the
> event off has got me pulling my hair out.
>
> I've tried variants of sending the event through the change
> handlers...
>
> changeHandlers.fireEvent( new ValueChangeEvent("foo") );
> changeHandlers.fireEvent( new ValueChangeEvent<String>("foo") );
>
> ...and using the static fire() method in the event class itself...
>
> ValueChangeEvent<String>.fire( changeHandlers, "foo");
>
> ...and Eclipse complains loudly about all of these constructions. I
> mean, I know this can't be that hard, but I can't find any good
> examples of things like this using the new (GWT 1.6 or later) event
> handlers, and reading the code sends me down a DOM event/Java generics
> rabbit hole that I'm frankly not experienced enough to deal with
> yet...
>
> Any help appreciated!

ValueChangeEvent.fire(this, "foo");

jscheller

unread,
Aug 20, 2009, 12:45:52 PM8/20/09
to Google Web Toolkit
Thanks Thomas... That and gazing wisely (or at least trying to give
the appearance of looking somewhat informed) at TextBoxBase.class got
me this...

public class MyComposite extends Composite implements
HasValueChangeHandlers<String> {

private void internalMethodToHandleUpdates() {
// handle validation and all sorts of other stuff, then
if
// if it looks good let outsiders know...

ValueChangeEvent.fire( this, "theNewValue" );
}

public HandlerRegistration addValueChangeHandler(ValueChangeHandler
handler) {
return addHandler(handler, ValueChangeEvent.getType());
}
}

..which looks like it should work. Still fuzzy on why the widget can't
manage an independent list of handlers under the hood, and the event
typing system still has me baffled, but this'll get me past the puzzle
box that kept me busy yesterday and seems less complex than what I was
doing... Thanks for your help!

John V Denley

unread,
Sep 8, 2009, 10:37:02 AM9/8/09
to Google Web Toolkit
I sitll cant work out from the code in this article, how to fire an
event:

final ListBox dropBox = new ListBox(false);
dropBox.addItem("");
dropBox.addItem("a");
dropBox.addItem("b");
dropBox.addItem("c");
dropBox.addItem("d");

dropBox.addChangeHandler(new ChangeHandler()
{
// @Override
public void onChange(ChangeEvent event)
{
switch (dropBox.getSelectedIndex()) {
case 0:
ApptPrice.setText("");
break;
case 1:
ApptPrice.setText("8.50");
break;
case 2:
ApptPrice.setText("9.50");
break;
case 3:
ApptPrice.setText("10.50");
break;
case 4:
ApptPrice.setText("11.50");
break;
default:
ApptPrice.setText("should never see this");
break;

}
}
});
dropBox.setItemSelected(setitemtoselect, true);
dropBox.fireEvent(onChange);

Its this last line I want to implement, Im setting the selection
programattically (based on selections elsewhere in the code) and i
need to fire the onChange event because as stated in the javadoc:
"Note that setting the selection programmatically does not cause the
ChangeHandler.onChange(ChangeEvent) event to be fired. "

Thomas Broyer

unread,
Sep 8, 2009, 12:40:11 PM9/8/09
to Google Web Toolkit
Just keep a reference on your ChangeHandler and call its onChange
method directly (you can pass 'null' as the argument as you don't use
it):

ChangeHandler handler = new ChangeHandler () { ... }
dropBox.addChangeHandler(handler);
dropBox.setItemSelected(setitemtoselect, true);
handler.onChange(null);

If you really, really can't do that, then you can actually fire a
change event:
DomEvent.fireNativeEvent(Document.get().createChangeEvent(), dropBox);

Bulat Sirazetdinov

unread,
Sep 20, 2009, 11:03:28 PM9/20/09
to Google Web Toolkit
You should do it this way:
At first you'll need to create a class that implements
HasValueChangeHandlers interface. It is because of the fact that
ValueChangeEvent.fire() method requires a class that implements
HasValueChangeHandlers interface passed in a first parameter.
So let name that class MyHandlers (see below).

Then you should get an instance of MyHandlers class:
-----------------------
MyHandlers<String> exampleHandlers = new Handlers<String>();
-----------------------

and register ValueChangeHandler objects in that instance:
-----------------------
exampleHandlers.addValueChangeHandler(someHandler1);
exampleHandlers.addValueChangeHandler(someHandler2);
exampleHandlers.addValueChangeHandler(someHandler3);
-----------------------

Now you can fire ValueChangeEvent to all handlers that you've
registered in exampleHandlers object:
-----------------------
ValueChangeEvent.fire(exampleHandlers, "text");
-----------------------

MyHandlers class declaration:
-------------------------------------
public class MyHandlers<I> implements HasValueChangeHandlers<I> {

private final List<ValueChangeHandler<I>> list = new
ArrayList<ValueChangeHandler<I>>();

public void fireEvent(GwtEvent<?> event) {
if (event instanceof ValueChangeEvent) {
for (ValueChangeHandler<I> handler : list) {
handler.onValueChange((ValueChangeEvent<I>) event);
}
}
}

public HandlerRegistration addValueChangeHandler(final
ValueChangeHandler<I> handler) {
list.add(handler);
return new HandlerRegistration() {

public void removeHandler() {
list.remove(handler);
}
};
}
}
-------------------------------------

Hope that helps.
Best wishes!

John V Denley

unread,
Sep 29, 2009, 1:46:17 PM9/29/09
to Google Web Toolkit
Bulat, can you direct me to any documentation anywhere which explains
the use of the <?> and <I> constructs?

Thanks,
J

charlie

unread,
Sep 29, 2009, 1:50:11 PM9/29/09
to google-we...@googlegroups.com
Reply all
Reply to author
Forward
0 new messages