如何在包含复合对象的子对象上公开事件?

时间:2011-08-20 00:47:13

标签: gwt event-handling

我有一个包含许多按钮的复合小部件(例如Button1,Button2等)。我无法想象如何在复合小部件上公开按钮单击事件。我试图避免创建自定义事件,如Button1ClickEvent和Button2ClickEvent,而是重用现有的GWT ClickEvent。以下代码片段可以让我知道我正在尝试做什么:

public class WidgetWithTwoButtons extends Composite {
    ...

    @UiField Button button1;
    @UiField Button button2;

    @UiHandler("button1")
    void onButton1Click(ClickEvent event) {
            // TODO fire click event on Button1ClickHandler
    }

    public HandlerRegistration addButton1ClickHandler(ClickHandler handler) {
            return addDomHandler(handler, ClickEvent.getType());
    }

    @UiHandler("button2")
    void onButton1Click(ClickEvent event) {
            // TODO fire click event on Button2ClickHandler
    }

    public HandlerRegistration addButton2ClickHandler(ClickHandler handler) {
            return addDomHandler(handler, ClickEvent.getType());
    }
}

我认为这不是最好的做法。如果您在答案中指出针对此问题的推荐解决方案/示例,我将不胜感激。谢谢!

1 个答案:

答案 0 :(得分:3)

我开始考虑您的问题并首先注意到,而不是使用addDomHandler,您可以将当前addButton1ClickHandler(ClickHandler handler)更改为:

public HandlerRegistration addButton1ClickHandler(ClickHandler handler) {
    return button1.addClickHandler(handler);
}

如果您只有一个按钮,则可以通过制作复合工具HasClickHandlers来展示它,并实现以下方法将其传递给您的按钮:

@Override
public HandlerRegistration addClickHandler(ClickHandler handler) {
    return button1.addClickHandler(handler);
}

但是由于你有很多按钮,你需要一个方法,将你想要添加clickHandler的按钮作为参数,例如:

public HandlerRegistration addClickHandlerToButton(ClickHandler handler, Button target){
    return target.addClickHandler(handler);
}

这种方法的问题是,要使用它,您需要引用按钮,这意味着您需要为复合中的按钮定义getter方法,例如public Button getButton1()。当你像这样暴露你的按钮时,问题是不再需要复合的直通方法,因为他/她可以直接访问按钮,无论如何使得上面的方法将目标按钮作为参数过时。最糟糕的是他/她甚至可以改变样式,甚至可以分离这些按钮。

要解决此问题,您可以通过HasClickHandlers界面公开按钮。

所以恕我直言,这是我应该做的事情:

public class ComplexComposite extends Composite {

    private Button button1 = new Button("btn1");
    private Button button2 = new Button("btn2");

    public ComplexComposite(){
        HorizontalPanel panel = new HorizontalPanel();
        panel.add(button1);
        panel.add(button2);
        initWidget(panel);
    }   
    public HasClickHandlers getButton1(){
        return button1;
    }
    public HasClickHandlers getButton2(){
        return button2;
    }   
}

使用此方法,您只需在所需界面上显示按钮,即可添加 点击处理程序,例如:

ComplexComposite composite = new ComplexComposite();
composite.getButton1().addClickHandler(new ClickHandler() {
    @Override
    public void onClick(ClickEvent event) {
        ...
    }
});