2013-06-21 38 views
0

我正在为我的游戏开发一个GUI库,并且我试图找到一种将GUI元素中的事件(例如从按钮单击事件)链接到事件处理器。事件处理程序的Java链接事件

说我有一个名为MyButton的按钮。 我会用下面的代码来设置它(不完整的,只是为了演示):

Button MyButton = new Button(); 
MyButton.SetParent(MyContainer); 
MyButton.SetText("Text inside my button!"); 
MyButton.SetTextColor(Color.BLACK); 

下面这段代码会在我gamestates的一个叫,什么我想要做的是这样的:

MyButton.OnClick(MyButtonClickEvent); 

public void MyButtonClickEvent(EventArgs event) { 

} 

我gamestates和容器和元素的结构为:

GameEngine-> GameState->容器 - >元素

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

回答

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用于按钮事件的内容。