关于在XML中为Swing组件指定事件监听器的解决方案


已有方案存在的问题:会把事件监听器作为普通属性来看待,会引起误解。但对于不同的时间,处理方法不同,比如:
ActionListener的处理方法为actionPerformed(ActionEvent e);
对于MouseListener有几个处理方法:mouseEnter,mouseExit,mouseOver等等。
由此引起事件处理器形式不统一。为了让xps跟html形式类似,即对于一个组件可以通过如下形式指定:
<JButton onClick="#handleClick" onMouseEnter="#handleMouseEnter"/>
而handleMouseEnter,handleClick等方法只是一个普通类(不需要实现相应的接口)的实例成员方法(此实例可在xps开头处指定)。
因此最终实现的目标是这样的:
<JPanel controller="org.your.controller.Controller">
    <items>
        <JButton onClick="# handleClick"  text="button"/>   
</items>
</JPanel>
org.your.controller.Controller是自定义的控制器,handleClick是 org.your.controller.Controller类中的一个成员方法
但要求 handleClick具有这样的签名:public void handleClick(ActionEvent event);
这样swing的UI界面的构造可跟事件处理逻辑完全分开。
为实现这种形式,的定义一个实现所有swing以及awt中EventListener
即定义一个这样的类
public class Handler implements MouseListener,ComponentListener,KeyListener...(不再列出)
这样一个Handler类的实例可以处理任何事件。
但是 Handler自己并不处理这些事件,而是不这些事件交给 org.your.controller.Controller实例中的相应方法
例如对于ActionEvent的监听器ActionListener,Handler 的实现应该这样
@Override
void actionPerformed(ActionEvent event){
    Object ctrl = getController();
    //接下来利用java的反射调用控制器中的相应方法

    //寻找控制器中名为actionPerformed方法
    Method method = findMethod("actionPerfomed",ctrl.getClass());
    if(method != null && method.getParameters().length == 1
        && method.getParameters() [0].equals(ActionEvent.class) )//检查方法是否符合规范
    
    //将事件交给控制器
     method.invoke(ctrl,event);
}
注意,对于控制器类没有做任何假设,它不需要实现任何接口,不需要继承任何类,
如果控制器重定义了相应的方法则调用之,否则Handler就当控制器不打算处理这个事件。则什么都不做。
对于控制器事件处理方法的访问控制的说明:此处必须为保证为public。最起码保证Handler类可以访问那个方法。
当如果java虚拟机给了Handler类的代码足够的权限,即使是private的方法Handler也能调用,但毕竟Handler不是java核心API
其代码的权限可能会被限制,因此为保证代码可以再不同环境中运行,访问控制必须为public

转载于:https://my.oschina.net/cichee/blog/88647

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值