65.9K
CodeProject 正在变化。 阅读更多。
Home

LinkSet – Java 事件的替代方法

starIconstarIconstarIconstarIconemptyStarIcon

4.00/5 (9投票s)

2010年2月20日

LGPL3

3分钟阅读

viewsIcon

34708

downloadIcon

339

LinkSet 是一个小型库,旨在帮助程序员摆脱声明监听器接口的麻烦。

引言

LinkSet 是一个小型库,旨在帮助程序员摆脱声明监听器接口的麻烦。它利用了 Java 5 的特性,并被设计为传统 "监听器接口 + 匿名类" 解决方案的直接替代品。

Java 是一门很棒的语言,比 C# 干净得多。但在监听器方面,它落后于 C#。每次用 C# 编程时,我都会想:“我希望 Java 也有委托。” 我也喜欢 Qt 的信号/槽方法。 很久以前,我思考过:“我能否创建比那些语法上可怕的匿名类更干净、更易于使用的东西?” 于是 LinkSet (github.com/lbownik/linkset) 诞生了。 LinkSet 是一个小型库,它利用 Java 5 的特性来提供一种简单易用的监听器机制,该机制不需要监听器接口或匿名类。

LinkSet 的特性

在设计 LinkSet 时,我希望它

  1. 易于使用 - 库的使用应尽可能少地增加编程工作量。这意味着:不需要监听器接口,也不需要特殊的构建步骤。
  2. 灵活 - 实例方法和静态方法都可以是事件处理程序。
  3. 无侵入性 – 它不要求事件处理对象实现任何特定接口,并且事件处理方法可以是 private
  4. 易于学习 – 它仅由几个直观的类组成,易于使用
  5. 体积小,速度合理
  6. 免费 - LGPL 许可证

我希望我满足了这些要求。

使用 LinkSet

要开始使用 LinkSet,您需要访问项目的网站 (github.com/lbownik/linkset) 并下载 jar 文件。然后将其包含到项目的类路径中即可。

事件源

LinkSet 旨在简化事件源和事件处理程序类的开发。以下代码展示了一个事件源的类。

此代码展示了如何实现一个可以被监听器观察的类。

package com.mycompany.project1;

import org.linkset.DefaultListenerManager;
import org.linkset.ListenerManager;
import org.linkset.MethodPointer;

public class EventSource {

    // a multi-listener manager
    private final DefaultListenerManager clickListeners = 
       new DefaultListenerManager();
    // a single listener pointer - useful when a return value is
    // needed
    private MethodPointer vetoableListener;

    // some constants
    public final static int LeftButton = 0;
    public final static int RightButton = 1;

    public ListenerManager clickdListeners() {
        
        return this.clickListeners;
    }

    public void setVetoableListener(MethodPointer pointer) {

        this.vetoableListener = pointer;
    }

    public void doStuff() throws Exception {

        //fire click event
        this.clickListeners.invokeAll(LeftButton);

        // check if we can change state if we want to
        final boolean canChangeState
           (Boolean)this.vetoableListener.invoke();
        if(canChangeState == true) {

        }
    }
}

该类声明了两个 private 字段。 clickListenersDefaultListenerManager 类的一个对象。此类是事件处理程序的集合,当事件发生时应调用这些事件处理程序。 方法 clickListeners() 允许客户端通过在 ListenerManager 接口中定义的 add(…) 方法连接其处理程序。 这样,客户端可以使用类似的代码轻松连接到事件源

Source.clickListeners().add(….);

第二个字段名为 vetoableListenerMethodPointer 类的一个对象。此类实现了一个事件处理程序方法指针,当只需要一个监听器且其返回值在后续计算中(例如在可否决的观察者模式中)是必需的时,可以使用此指针。 方法 setVetoableListener(...) 允许客户端设置指针引用。 方法 doStuff() 包含使用适当的 invokeAll(…)invoke(…) 方法调用所有监听器的代码。

事件处理器

以下代码展示了如何实现一个提供监听事件的方法的类。

package com.mycompany.project1;

import org.linkset.HandlerMethod;
import org.linkset.MethodPointer;

public class EventHandler {

    private EventSource provider = new EventSource();
    public EventHandler() {

        // we set a reference to an object and handler method id
        this.provider.clickdListeners().add(this, "clickListener");

	// in case of static methods we need to pass a Class object
	// reference
	this.provider.setVetoablePointer(new
		MethodPointer(this.getClass(), "canChange"));
    }

    @HandlerMethod(id = "clickListener")
    private void clickListener(int button) {

        System.out.println("Button click=" + button);
    }

    @HandlerMethod(id = "canChange")
    private static boolean canChange() {

        System.out.println("Can change?");
        return false;
    }
    public static void main(String[] args) throws Exception {

        EventHandler handler = new EventHandler();
        handler.provider.doStuff();
    }
}

该类声明了两种方法。 private 实例方法 clickListener(…) 是在单击事件发生时调用的方法。它使用带有唯一 idHandlerMethod 注解进行注释。此 id 用于

this.provider.clickdListeners().add(this, "clickListener");

指向所提供对象中的正确方法。提供的标识符必须在类范围内是唯一的,但可以在不同的类中重复使用。

当调用 vetoableListener 时,将调用 private static 方法 canChange()。代码

this.provider.setVetoableListener(new MethodPointer(this.getClass(),"canChange"));

设置源对象所需的指针。值得注意的是,当提供 static 方法的 id 时,LinkSet 需要一个 Class 对象作为事件目标。

摘要

LinkSet 库是一个小型的 Perl,它形成于对 Java 默认处理事件方式的持续 раздражение(irritation)。 它小巧、简单且易于使用。 它是无需任何新语法结构(如闭包)即可直接替换的方案。

历史

  • 2010 年 2 月 19 日:初始发布
© . All rights reserved.