按钮的嵌套匿名内部类

5

我使用了匿名内部类来获取一个按钮对象:

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
    }
});

我希望在一个任意大小的GWT FlexTable中使用它(基本上是一个自动调整大小的表格)。

如果我像这样做:

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

currentTable.setText(4, 0, "elec4");
currentTable.setWidget(4, 2, modButton);
仅适用于后者(因为只有一个实例)。由于上面的表将通过编程方式填充,因此为每个可能的实例定义新按钮并不实际。我尝试了以下方法:
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
    }
});
);

然而,这根本无法编译(第一个; 我猜),我有点迷惑 - 我该如何实现这种效果呢?
谢谢

1
如果你移除最后的 );,我相信最后一段代码片段将会编译通过。 - Tyler
2个回答

1

你在第三个例子中的语法是不正确的,但无论如何,在那种情况下使用匿名类是不可能的。你试图在新实例化的对象上调用addClickHandler,但该对象未存储在任何变量中。理论上,你可以将该代码放在匿名类的构造函数中,并在“this”上调用该函数。问题是,由于Java(绝对糟糕)匿名类语法的特殊性质,不可能定义一个构造函数(它应该叫什么?)。

我不确定我完全理解你想要实现什么,但你能否定义一个函数,每次调用它时返回一个新的、正确配置的按钮实例?例如:

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;
}

然后你会调用

currentTable.setWidget(4, 2, newModButton());

2
+1 另外,也可以通过扩展“Button”并实现“ClickHandler”来实现。 - trashgod
谢谢!这个有效。trashgod,我不确定我完全明白 - 你的意思是我应该定义一个类并在setWidget中创建(匿名?)实例吗? - malangi
不,我认为他的意思是创建一个新类(可以是私有的、包级别的、默认的或内部类 - 取决于你想要使用它的范围),像这样:MyButton extends Button implements ClickHandler,然后像我的答案一样实现并设置ClickHandler - 重要的区别是你不需要真的去扩展Button(而且实际上是不鼓励扩展) - 因为你没有引入任何其他自定义行为,你只是想把一个通用的 ClickHandler 传递给多个 Button - Igor Klimer
您还可以考虑重用一个ClickHandler实例——如果它们的行为不因每个按钮而异,而不是每次调用new ClickHandler() - Bluu

0
最有效的方式(从GWT和代码量的角度来看)是让您的类实现ClickHandler,然后为每一行创建一个新的Button(您无法将相同的Widget两次添加到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
    }

}

注意我们在这里所做的 - 没有匿名类,我们只实现了一次 ClickHandler 接口。这比为每个按钮创建匿名类更高效(当您想让所有按钮以相同方式行事时),因为否则 GWT 将不得不为您添加的每个按钮创建额外的代码 - 相反,ClickHandler 在一个地方实现并被所有按钮引用。
附注:也许您应该考虑使用像 Eclipse 这样的 IDE(带有 Google Plugin for Eclipse) - 它使 GWT 开发轻松,并且可以捕获您最后一个代码片段中遇到的语法错误。

谢谢!我想Eclipse看起来确实是前进的方向。我希望在一个循环中使用这些按钮,那么逐个定义它们似乎不太实际,但是我理解你的点击处理器观点,这应该使代码更加清晰。谢谢! - malangi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接