0

我正在为我的游戏开发一个 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->Container->Elements

最接近的解决方案是什么?提前致谢。

4

1 回答 1

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();
}

(这是假设您不必将任何参数传递给事件处理程序。通常,这是不能假设的,因此除了 a 之外ButtonListener,您还有一个ButtonEvent封装参数并传递给方法(s ) 在接口中定义。)

然后,如果您编写一个有兴趣在单击某个按钮时接收事件的类,则该类必须实现ButtonListener. 反过来,MyButton该类必须提供一种方法来注册侦听器:

public MyButton {
    protected List<ButtonListener> buttonListeners;

    public void addButtonListener(ButtonListener listener) {
       ...
    }

    public void removeButtonListener(ButtonListener listener) {
       ...
    }

    protected void fireButtonEvent() {
       ...
    }
}

我相信您已经在 J​​ava 标准类库中看到过很多这种模式,尤其是在java.awtjavax.swing-- 例如java.awt.event.ActionListener,参见 AWT 用于按钮事件的模式。

于 2013-06-21T04:20:38.573 回答