views:

180

answers:

2

I've used an anon inner class to get a button obj:

Button modButton = new Button("Modify");
modButton.addClickHandler(new ClickHandler() {
    @Override
    public void onClick(ClickEvent event) {
        //TODO: link to a pop-up, and do a refresh on exit
    }
});

I want to use this in an arbitrarily sized GWT FlexTable (which is basically an auto re-sizing table).

if i do something like this:

currentTable.setText(3, 0, "elec3");
currentTable.setWidget(3, 2, modButton);

currentTable.setText(4, 0, "elec4");
currentTable.setWidget(4, 2, modButton);

The button only shows up for the latter one (since there is only one instance). Since the table above will be populated programatically, its not really practical to define a new button for each possible instance.

I tried this the following:

currentTable.setText(4, 0, "elec4");
currentTable.setWidget(4, 2, new Button("Modify");
modButton.addClickHandler(new ClickHandler() {
    @Override
    public void onClick(ClickEvent event) {
        //TODO: link to a pop-up, and do a refresh on exit
    }
});
);

However, this won't compile at all (the first; I guess), I'm a bit lost - how can I accomplish this effect?

Thanks

+1  A: 

Your syntax is incorrect in the third example, but in any case, using an anonymous class in that case is impossible. You are trying to call addClickHandler on the newly-instantiated object, which is not stored in any variable. Theoretically, you could put that code in a constructor for your anonymous class and call that function on "this". The problem is, because of the peculiarities of Java's (absolutely atrocious) anonymous class syntax, it is impossible to define a constructor (what would it be called?).

I'm not 100% sure I understand what you are trying to accomplish, but could you define a function that just returned a new, correctly-configured button instance each time you called it? For example,

private Button newModButton() {
    Button modButton = new Button("Modify");
    modButton.addClickHandler(new ClickHandler() {
        @Override
        public void onClick(ClickEvent event) {
            //TODO: link to a pop-up, and do a refresh on exit
        }
    });
    return modButton;
}

Then you would call

currentTable.setWidget(4, 2, newModButton());
Tim Yates
+1 Alternatively, it might be possible to extend `Button` and implement `ClickHandler`, too.
trashgod
thanks! this works. trashgod, not sure i fully follow - do you mean i should define a class and just create (anon?) instances of it, in the setWidget?
flyingcrab
No, I think he meant it as creating a new class (might be private, package/default, inner - depends on the scope you want to use it in) like this: `MyButton extends Button implements ClickHandler` and then implement and set the `ClickHandler` just like in my answer - the big difference is that you don't really need to extend `Button` (and it's actually discouraged) - since you are not introducing any other custom behavior, you just want to pass a common `ClickHandler` to many `Button`s.
Igor Klimer
You might also consider reusing one instance of a ClickHandler--if their behavior is not varying per Button--rather than calling `new ClickHandler()` every time.
Bluu
A: 

The most efficient way (both from the view of GWT's and amount of code) is for your class to implement ClickHandler and then for each row create a new Button (you can't add the same Widget twice to the DOM):

class Foo extends Composite implements ClickHandler {

    public Foo() {
        FlexTable currentTable = new FlexTable();

        Button button = new Button("Button1");
        // Add this class as the ClickHandler
        button.addClickHandler(this);
        currentTable.setText(3, 0, "elec3");
        currentTable.setWidget(3, 2, button);

        button = new Button("Button2");
        // Add this class as the ClickHandler
        button.addClickHandler(this);
        currentTable.setText(4, 0, "elec4");
        currentTable.setWidget(4, 2, modButton);
    }


    public void onClick(ClickEvent event) {
        //TODO: link to a pop-up, and do a refresh on exit
    }

}

Notice what we are doing here - there are no anonymous classes, we implement the ClickHandler interface once. This is more efficient than creating an anonymous class for every button (when you want all the buttons to behave the same way), because otherwise GWT would have to create additional code for every button you add - instead, the ClickHandler is implemented in one place and referenced by all the buttons.

PS: Maybe you should consider using an IDE like Eclipse (with the Google Plugin for Eclipse) - it makes GWT development a breeze and would catch syntax errors like the one in your last code snippet.

Igor Klimer
Thanks for this - i guess eclipse does look like the way forward. i want to use these buttons in a loop, so i guess defining them individually doesnt really seem practical, but i see your point about the clickhandler, this should make the code much cleaner. Thanks!
flyingcrab