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

Gwt 如何在包含复合对象的子对象上公开事件?,gwt,event-handling,Gwt,Event Handling,我有一个包含许多按钮的复合小部件(例如Button1、Button2等)。我不知道如何在复合小部件上公开按钮单击事件。我试图避免创建自定义事件,如Button1ClickEvent和Button2ClickEvent,而是将现有的GWT ClickEvent重新用于这两个事件。下面的代码片段可以说明我正在尝试做什么: public class WidgetWithTwoButtons extends Composite { ... @UiField Button button1

我有一个包含许多按钮的复合小部件(例如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());
    }
}

我认为这不是最好的做法。如果你能在你的答案中给出建议的解决方案/例子,我将不胜感激。谢谢

我开始思考您的问题,首先注意到您可以将当前的
addButton1ClickHandler(ClickHandler)
更改为:

public HandlerRegistration addButton1ClickHandler(ClickHandler handler) {
    return button1.addClickHandler(handler);
}
如果只有一个按钮,则可以通过使复合实现并实现以下方法将其传递到按钮来公开该按钮:

@Override
public HandlerRegistration addClickHandler(ClickHandler handler) {
    return button1.addClickHandler(handler);
}
但由于您有许多按钮,因此需要一种方法,将要添加clickHandler的按钮作为参数,例如:

public HandlerRegistration addClickHandlerToButton(ClickHandler handler, Button target){
    return target.addClickHandler(handler);
}
ComplexComposite composite = new ComplexComposite();
composite.getButton1().addClickHandler(new ClickHandler() {
    @Override
    public void onClick(ClickEvent event) {
        ...
    }
});
这种方法的问题是,要使用它,您需要对按钮进行引用,这意味着您需要为组合中的按钮定义getter方法,例如
public Button getButton1()
。当你像这样暴露你的按钮时,问题是一个人不再需要复合上的passthrough方法,因为他/她无论如何都可以直接访问按钮,这使得上述将目标按钮作为参数的方法过时了。最糟糕的是,他/她甚至可以更改样式,甚至可以拆下这些按钮

要解决这个问题,您可以在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;
    }   
}
使用这种方法,您只能在所需的界面上显示按钮,并且可以添加 单击处理程序,例如:

public HandlerRegistration addClickHandlerToButton(ClickHandler handler, Button target){
    return target.addClickHandler(handler);
}
ComplexComposite composite = new ComplexComposite();
composite.getButton1().addClickHandler(new ClickHandler() {
    @Override
    public void onClick(ClickEvent event) {
        ...
    }
});

谢谢你完整的回答。确实很有帮助