使用我的方法,您可以以“传统方式”编写按钮单击事件处理程序,就像在VB或MFC中一样;)
假设我们有一个包含2个按钮的框架窗口类:
class MainWindow {
Jbutton searchButton;
Jbutton filterButton;
}
你可以使用我的“路由器”类将事件路由回你的MainWindow类:
class MainWindow {
JButton searchButton;
Jbutton filterButton;
ButtonClickRouter buttonRouter = new ButtonClickRouter(this);
void initWindowContent() {
searchButton.addActionListener(buttonRouter);
filterButton.addActionListener(buttonRouter);
}
void on_searchButton() {
}
void on_filterButton() {
}
}
你喜欢它吗?:)
如果你喜欢这种方式,而讨厌Java的匿名子类方式,那么你和我一样老了。'addActionListener(new ActionListener {...})'的问题在于它将所有按钮处理程序挤入一个外部方法中,使程序看起来很奇怪。(假设你在一个窗口中有多个按钮)
最后,路由器类在下面。你可以将它复制到你的程序中,无需任何更新。
只有一件事需要提醒:按钮字段和事件处理程序方法必须对这个路由器类可访问!简单地说,如果你将这个路由器类复制到你程序的同一个包中,你的按钮字段和方法必须是包访问级别。否则,它们必须是公共的。
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class ButtonClickRouter implements ActionListener {
private Object target;
ButtonClickRouter(Object target) {
this.target = target;
}
@Override
public void actionPerformed(ActionEvent actionEvent) {
Object sourceButton = actionEvent.getSource();
Field fieldOfSourceButton = null;
for (Field field : target.getClass().getDeclaredFields()) {
try {
if (field.get(target).equals(sourceButton)) {
fieldOfSourceButton = field;
break;
}
} catch (IllegalAccessException e) {
}
}
if (fieldOfSourceButton == null)
return;
String methodName = "on_" + fieldOfSourceButton.getName();
Method expectedHanderMethod = null;
for (Method method : target.getClass().getDeclaredMethods()) {
if (method.getName().equals(methodName)) {
expectedHanderMethod = method;
break;
}
}
if (expectedHanderMethod == null)
return;
try {
expectedHanderMethod.invoke(target);
} catch (IllegalAccessException | InvocationTargetException e) { }
}
}
我是Java的初学者(不是编程),所以也许上面的代码有什么不妥之处,请在使用之前进行审核。
main(String[])
中实例化一个框架。4) 通常认为最好为每个需要的 GUI 元素添加一个动作监听器,而不是使用一个巨大的 if/else 级联的actionPerformed(ActionEvent)
方法。5) 如果遵循第四条建议,问题基本上就消失了。