简体   繁体   中英

GWT Event Handling best practice

I'm quite new to interface design and struggling to figure out what the best way to handle events is. In the straight forward case of the handler and the (in this case) buttons causing the event being in the same class, that's fine, I get it. The handler can see the buttons so that it can say:

if (event.getSource() == myButton)

and also, the handler is in the same class so it can add tabs to an object local to that class or similar.

Problem: I don't know how I should be dealing with the case when the handlers and event generators are in different classes.

eg

From my main layout class I create and show a custom dialog. That dialog is implemented in its own class. Ideally dialog would use the handler from the main layout class (it implements ClickHandler), which would be fine, but my application has a few different ClickEvents. I distinguish between them as above by checking the source. In this case the buttons are in the dialog class though, so I can't simply say:

if (event.getSource() == myDialogbutton)

as myDialogButton is not in scope.

Any hints for how this should work would be appreciated.

D

Perhaps I can help you with my solution ...

I inherited ClickHandler to an own class which is generic. You can give the ClickHandler any kind of object you want and will be able to access it from the method within.

Example:

import com.google.gwt.event.dom.client.ClickHandler;

public abstract class ClickHandlerData<T> implements ClickHandler {
    private T data;

    public ClickHandlerData(T data)
    {
        this.data = data;
    }

    public T getData()
    {
        return data;
    }

    public void setData(T data)
    {
        this.data = data;
    }
}

Now, in case of a button:

Button btn = new Button("click me");
btn.addClickHandler(new ClickHandlerData<Button>(btn)) {
    public void onClick(ClickEvent event) {
        Button btn = getData();
        ...
    }
}

I use this class to pass parameters like Integers or something else to the ClickHandler. For instance:

for (int i=0;i<10;i++)
{
    Button btn = new Button("click me");
    btn.addClickHandler(new ClickHandlerData<Integer>(i)) {
        public void onClick(ClickEvent event) {
            Window.alert("you klicked button "+getData());
            ...
        }
    }
}

I also do the same for AsyncCallbacks, for Commands, for everything else I need to pass data to.

Hope this helped you a bit.

It appears to me that you are trying to use one listener for multiple buttons, unless several of the buttons have the same function they should have different listeners.

In general you should try to have one listener per function, instead of one listener per "event generator".

If you have for example a logout button, it may have a listener from the LoginStatusWidget (displaying who the client is logged in as) and a listener from an object responsable of notefying the server of the logout.

It will serve to seperate the components from each other.

Try creating a new listener for each anonymous or serial widget eg button in a FlexTable. That way their life cycles are connected and they only refer to each other.

  1. Extend the widget
  2. Give it an id and add it to the constructor [make sure the id is one of a kind]
  3. Implement the listener class.
  4. create a new instance of the listener each time you create an item of the same kind.
  5. I'm guessing there are specific objects connected to the widgets. If so keep a HashMap.

May the force be with you

At first i recommend you to try to collect your Buttons and their ClickHandlers in the same class, but if in your case it is not possible, I have a suggestion to you:

When you are creating your Button you can add some information to them:

Button button = new Button("submit");
button.setLayoutData(someObj);

And then after firing event you can get your Button from event in your ClickHandler and find out which button it is :

Button button = (Button) event.getSource();
MetaData someObj = (MetaData) button.getLayoutData(); 

Can't you just do:

final Button source= new Button("My Button");

button.addClickHandler(new ClickHandler() {
   @Override
   public void onClick(ClickEvent event) {
         doSomething(source);
   }
}

Note the button instance has to be marked final.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM