所以,通常,我是C,C ++和C#程序员,我在C#WPF中拥有大部分GUI经验。我被安排在一个使用Java的项目上,我发现我的C#词汇与Java不相符。
我遇到过一个与JButton有关的问题,可能是C#中所谓的“委托”。从example开始,有一些代码:
jbnButton1.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
jtfInput.setText("Button 1!");
}
});
简单地说,这是什么叫做,将函数定义为参数(或作为参数传递)?这也是最佳做法吗?在我正在进行的项目中,Initialize()函数用于按钮,复选框等功能,这使得它成为一个相当不实用的功能。我更喜欢在类级别定义,而不是在Initialize()中。
这将我带到另一个example(顶级代码示例)。使用以下代码行:
b1.addActionListener(this);
b3.addActionListener(this);
...
}
public void actionPerformed(ActionEvent e) {
if ("disable".equals(e.getActionCommand())) {
b2.setEnabled(false);
b1.setEnabled(false);
b3.setEnabled(true);
} else {
b2.setEnabled(true);
b1.setEnabled(true);
b3.setEnabled(false);
}
}
本质上,代码将按钮1,b1和按钮3,b3的动作分配给同一事件处理程序,该处理程序在我喜欢的范围(在按钮初始化之外)定义。有没有办法让它们指向不同的功能?另外,通过调用
.addActionListener(this);
编译器如何在此使用actionPerformed(ActionEvent e)?是预先定义的,表示操作将解析为'actionPerformed(ActionEvent e)'?
答案 0 :(得分:1)
您给出的第一个示例称为“匿名内部类”。您正在定义ActionListener
的匿名子类,重写其actionPerformed
方法,实例化它(创建此子类的实例),然后将对该实例的引用传递给方法jbnButton1.addActionListener
。这是目前最接近Java的“封闭”(至少在Java 8之前)。
当动作侦听器很简单时,这是惯用的,但您可以将其重新编码为
class MyListener extends ActionListener
{
public void actionPerformed(ActionEvent e)
{
jtfInput.setText("Button 1!");
}
}
...
jbnButton1.addActionListener(new MyListener());
但是您可能需要安排MyListener
的构造函数来接受并保存jtfInput
引用。内联定义简化了这一点。但是对于更复杂的情况,您可能希望将该类定义为外联。
至于第二个问题:
.addActionListener(this);
出现此类的类必须实现ActionListener
接口,因此它必须具有actionPerformed()
方法。这就是让框架“知道”调用内容的原因。
答案 1 :(得分:1)
您的第一个示例称为匿名类。它通常用于监听器(如ActionListener
s),但只有在您不必删除监听器时才应使用它,因为没有保存引用。
对于问题的第二部分,编译器不知道何时调用actionPerformed
。它在ActionListener
documentation:
当动作事件发生时,将调用该对象的actionPerformed方法。
因此,JButton
有责任在发生操作时添加到其中的所有actionPerformed
上调用ActionListener
。
无法让b1
和b3
指向不同的方法。这是一个很好的例子,说明匿名类可以用于更好的设计:
b1.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
b2.setEnabled(false);
b1.setEnabled(false);
b3.setEnabled(true);
}
});
b3.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
b2.setEnabled(true);
b1.setEnabled(true);
b3.setEnabled(false);
}
});
假设b1
有标签“禁用”。然后this
将不再需要实施ActionListener
。
答案 2 :(得分:1)
对于您的第二个代码示例:
它知道使用actionperformed()
,因为您用来将actionlistener
- s添加到按钮的类正在实现接口ActionListener
如果你传递addActionListener
方法你自己的类(this),你必须实现actionPerformed
方法,它就像anonymous classes
一样,因为它是ActionListener
addActionListener
方法知道它有一个actionPerformed
方法(它必须有一个),所以它会自动调用