How to fire a click event on a Label

1,760 views
Skip to first unread message

treeder

unread,
Oct 16, 2007, 2:16:53 PM10/16/07
to Google Web Toolkit
Can't seem to find how to fire a click event programmatically on a
Label and since there is no getClickListeners, I can't fire it on the
ClickListenerCollection either.

Peter Blazejewicz

unread,
Oct 16, 2007, 6:04:34 PM10/16/07
to Google Web Toolkit
hi,

there is no underlying "click" for label implemented and exposed, also
listeners are private and not exposed,
so are we out of luck? no,

try that:

package com.mycompany.project.client;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.ClickListener;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.Widget;

/**
* Entry point classes define <code>onModuleLoad()</code>.
*/
public class TestJSIO implements EntryPoint, ClickListener {
private Label label;
private RootPanel rootPanel;

public void onModuleLoad() {
rootPanel = RootPanel.get();

label = new Label("New Label");
rootPanel.add(label);
label.addClickListener(this);
click(label.getElement());
}

private static native void click(Element label)/*-{
label.click();
}-*/;

public void onClick(final Widget sender) {
Window.alert("Woohoo. label clicked!");
}
}


hth,
regards,
Peter

Reinier Zwitserloot

unread,
Oct 17, 2007, 7:16:02 AM10/17/07
to Google Web Toolkit
Or, more generally, the concepts of 'private', package private (, and
as an aside, 'final') don't exist in JSNI. You can freely tinker and
play with any of those variables. Hence, you can use JSNI to get at
the ClickListenerCollection of any SourcesClickEvents unit (all
classes that implements SourcesClickEvents in the core GWT libraries
use a ClickListenerCollection, though of course in theory other
classes don't have to do so), and then run fireClick with it.

This is obviously not supported API, which means future versions of
GWT can break it, but, that happends under your control (GWT doesn't
upgrade itself, it's something you need to actively go and do), and it
should be trivial to switch your JSNI code to match any changes. At
this point in time there are no grand overhauls of the event system
planned, so I fully expect this hack to continue to work without
changes at least into GWT 1.5, and likely into GWT 1.6 as well.

This would work for ANY event, not just clicks.

On Oct 17, 12:04 am, Peter Blazejewicz <peter.blazejew...@gmail.com>
wrote:

Travis Reeder

unread,
Oct 17, 2007, 1:25:13 PM10/17/07
to Google-We...@googlegroups.com
I ended up just subclassing Label, overriding all the click related method (only a few), then adding a click() method. 

click() should be on the SourcesClickEvents interface.

Travis

Ian Petersen

unread,
Oct 17, 2007, 1:27:25 PM10/17/07
to Google-We...@googlegroups.com
Why do you need to programmatically fire a click event?

The only valid reason I can think of is for some kind of automated
test suite where you need to simulate user interaction. Every other
use case I can think of would be better implemented by changing the
design such that the label's click listener calls a method on some
backing model and "firing a click event" is semantically equivalent to
directly calling the same method on the backing model. There are
several reasons why this would be a better design, but the most
obvious is that you don't have to muck about with private internals of
the Label class.

Ian

--
Tired of pop-ups, security holes, and spyware?
Try Firefox: http://www.getfirefox.com

Travis Reeder

unread,
Oct 17, 2007, 3:10:38 PM10/17/07
to Google-We...@googlegroups.com
Ian,

Reason 1: The exact same reasons you would want to call the already existing click() method on Button.
Reason 2: You may have multiple buttons/labels that should fire the same event (this is what I want it for).
Reason 3: Unit testing like you said.
Reason 4: If you can add ClickListener's to widget, then you should be able to get at them somehow without requiring user interaction.

Sure, I could manage all my own ClickListenerCollections, but why? They are already on the widgets.

Ian Petersen

unread,
Oct 17, 2007, 5:54:24 PM10/17/07
to Google-We...@googlegroups.com
On 10/17/07, Travis Reeder <tre...@gmail.com> wrote:
> Reason 1: The exact same reasons you would want to call the already existing
> click() method on Button.

Besides unit testing, I don't have any reasons for calling click() on a button.

> Reason 2: You may have multiple buttons/labels that should fire the same
> event (this is what I want it for).

Then do one of two things:

- add the same instance of ClickListener to all of the widgets
- refactor such that each ClickListener does nothing but call a
central method on your
model

> Reason 3: Unit testing like you said.

In this case, it makes sens to muck about in JSNI to access private members.

> Reason 4: If you can add ClickListener's to widget, then you should be able
> to get at them somehow without requiring user interaction.

I disagree with this. A click event represents a user action.
Programmes aren't users and therefore shouldn't generate user actions
(except in the case of unit testing, in which case you're simulating a
user).

> Sure, I could manage all my own ClickListenerCollections, but why? They are
> already on the widgets.

Exactly. You shouldn't. You should write code that performs some
kind of semantic action, not a nearly-meaningless "click". A click is
nothing but a mousedown followed by a mouseup (or, in the case of
keyboards, a keydown followed by a keyup). Only the context of the
click (the widget that was clicked) gives the click meaning. In your
code, the widget that you're "clicking" isn't really relevant. What's
relevant is the side effect that's generated as a result of the click.
If you have a button labeled "Log In" and you want to
programmatically log in, then you should call a method named logIn(),
not click().

Reinier Zwitserloot

unread,
Oct 18, 2007, 4:14:03 AM10/18/07
to Google Web Toolkit
This discussion has been held before on GWT-C, and the consensus was,
overwhelmingly, that there will NOT be programmatic access to the
event engine. The only practical use-case back then was determined to
be testing as well, and as a general rule, APIs should -never- cater
for testing. Instead, the tests should hack their way around any
limitations. Fortunately the JSNI hack is an excellent way to do so.

If you need this functionality for non-testing, you'll need to
refactor in one of the many ways Ian mentioned.
.

Reply all
Reply to author
Forward
0 new messages