Java链接事件到事件处理程序

时间:2013-06-21 01:48:50

标签: java events

我正在为我的游戏开发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->容器 - >元素

对此最近的解决方案是什么?提前谢谢。

1 个答案:

答案 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.awtjavax.swing中 - 请参阅例如java.awt.event.ActionListener,这是什么AWT用于按钮事件。