3

我正在编写一个 setonclick 列表器,我希望能够引用该按钮,以便我可以更改其属性。即使其禁用?

我收到这条消息:

不能在不同方法中定义的内部类中引用非最终变量 confirmButton

        confirmButton.setOnClickListener(new View.OnClickListener() {

        public void onClick(View view) {
            confirmButton.setEnabled(false);    
        }



    }); 
4

4 回答 4

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某处或使用staticfinal属性声明方法外部的按钮。特别是如果您计划通过另一个元素触发的操作来修改某些元素。

于 2010-06-26T14:49:24.613 回答
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”替换,您可以在任何地方为此目的使用它),并且您的代码将整体设计得更好。

于 2010-06-26T15:31:11.757 回答
0

匿名内部类只能从外部范围访问变量,如果它们是final. 假设您只分配confirmButton一次,我建议只需将其标记为final.

final JButton confirmButton = new JButton();
于 2010-06-26T17:43:43.203 回答
0

在匿名类中引用的 var 需要像final在 Java 中一样定义。Jon Skeet 在这篇文章中有一个很好的例子。

于 2010-06-26T14:49:53.040 回答