我正在编写一个setonclick listner,我希望能够引用该按钮,以便我可以更改其属性。即让它禁用?
我得到了这个消息:
不能在不同方法
中定义的内部类中引用非最终变量confirmButton confirmButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
confirmButton.setEnabled(false);
}
});
答案 0 :(得分:3)
这是因为您可能正试图从以这种方式使用的匿名类访问该按钮:
button.addActionListener(
new MyListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
//do your things on button }
}
}
);
这不起作用,因为在Java中,匿名类无法查看在声明它们的方法中声明的变量,因为它们的作用域是分开的。让你的类看到它的唯一方法是强制final
约束,它确保编译器在初始化后变量不会改变,允许它将其范围扩展到匿名类。
要快速解决此问题,您可以访问ActionEvent
内的actionPerformed
按钮:
((JButton)e.getSource()).setEnabled(false)
否则,您必须在某处具体声明您的ActionListener
或使用static
或final
属性声明方法外的按钮..特别是如果您计划通过某个操作修改某些元素被另一个元素解雇了。
答案 1 :(得分:1)
我建议反对getSource
;文档不保证它将是您的按钮。您可以在范围内创建按钮final
,也可以使用更复杂的类
public class ComponentRelevantOnClickListener implements View.OnClickListener {
private JComponent component;
public ComponentRelevantOnClickListener(JComponent component) {
this.component = component;
}
}
// then, in your code...
confirmButton.setOnClickListener(new ComponentRelevantOnClickListener(confirmButton) {
public void onClick(View view) {
component.setEnabled(false);
}
});
如果你转向动作和监听器类而不是匿名子类的设计,你将有更多的机会重新使用(你已经可以看到ComponentRelevantOnClickListener
可以替换为你可以使用的“DisableOnClickListneer”在任何地方为此目的),你的代码将整体设计得更好。
答案 2 :(得分:0)
匿名类中引用的变量需要在Java中定义为final
。 Jon Skeet在this article内有一个很好的例子。
答案 3 :(得分:0)
匿名内部类只能访问外部作用域中的变量final
。假设您只分配给confirmButton
一次,我建议您将其标记为final
。
final JButton confirmButton = new JButton();