我正在为我的游戏开发GUI库,我正在尝试找到一种将GUI元素中的事件(例如从按钮点击事件)链接到事件处理程序的好方法。
假设我有一个名为MyButton的按钮。 我将使用以下代码进行设置(不完整,仅用于演示):
Button MyButton = new Button();
MyButton.SetParent(MyContainer);
MyButton.SetText("Text inside my button!");
MyButton.SetTextColor(Color.BLACK);
现在这个代码会在我的一个游戏状态中调用,我想做的是这样的:
MyButton.OnClick(MyButtonClickEvent);
public void MyButtonClickEvent(EventArgs event) {
}
我的游戏状态,容器和元素的结构是:
GameEngine-> GameState->容器 - >元素
对此最近的解决方案是什么?提前谢谢。
答案 0 :(得分:0)
Java没有将方法作为第一类函数,即该语言不提供对可以传递的方法的引用,就像在其他语言中一样。对于像你的问题中概述的那样的结构,你最好的选择是使用反射。
import java.lang.NoSuchMethodException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Set;
public class MyButton {
private Object onClickObject;
private Method onClickMethod;
public void OnClick(Object object, String methodName) throws NoSuchMethodException {
OnClick(object, object.getClass().getMethod(methodName));
}
public void OnClick(Object object, Method method) {
this.onClickObject = object;
this.onClickMethod = method;
}
// MyButton calls this method every time the button is clicked, in
// order to inform the external event handler about it
protected void onClick() throws IllegalAccessException, InvocationTargetException {
onClickMethod.invoke(onClickObject);
}
}
但是请注意因为方法不是一等公民,所以上面不是用Java实现事件监听器的规范方法。相反,Java方式是使用回调方法定义接口,可能是这样的:
public interface ButtonListener {
public void OnClick();
}
(这假设您不必将任何参数传递给事件处理程序。通常,这不能被假设,因此除了ButtonListener
之外,您还有一个ButtonEvent
它封装了参数,并传递给接口中定义的方法。)
然后,如果你编写一个有兴趣在点击某个按钮时接收事件的类,那么该类必须实现ButtonListener
。反过来,MyButton
类必须提供一种注册监听器的方法:
public MyButton {
protected List<ButtonListener> buttonListeners;
public void addButtonListener(ButtonListener listener) {
...
}
public void removeButtonListener(ButtonListener listener) {
...
}
protected void fireButtonEvent() {
...
}
}
我确定您已经在Java标准类库中看到了这种模式,特别是在java.awt
和javax.swing
中 - 请参阅例如java.awt.event.ActionListener
,这是什么AWT用于按钮事件。