是否可以在Java中创建包含多个侦听器类型的自己的事件侦听器列表? [英] Is it possible to create my own event listener list in Java containing multiple listener types?

查看:271
本文介绍了是否可以在Java中创建包含多个侦听器类型的自己的事件侦听器列表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在实施一个客户端-服务器系统,其中客户端处于连续阻塞的读取循环中,以侦听来自服务器的消息。收到消息后,我想根据消息的类型引发一个事件,其他GUI类可能会添加侦听器。我对C#事件比较熟悉,因此我仍然习惯于Java的处理方式。

I'm implementing a client-server system where the client is in a continuous blocking read loop listening for messages from the server. When a message is received I'd like to raise an "event" based on the type of the message, which other GUI classes may add listeners to. I'm more familiar with C# events so I am still getting used to the Java way of doing things.

会有很多消息类型,因此我需要一个接口分别将其称为MessageTypeAListener,MessageTypeBListener等,它们每个都包含一个处理方法,我的GUI类将实现该方法。但是,将有许多类型,而不是为每个类型维护一个侦听器列表,而是使用几种 fire方法,我想拥有一个大侦听器列表和一个类型化的fire方法。然后fire方法可能会说仅是我指定类型的fire监听器。

There will be many message types so I will need an interface for each, call it MessageTypeAListener, MessageTypeBListener, etc., each of which will contain one handle method, which my GUI classes will implement. However, there will be be many types and instead of maintaining a list of listeners per type and having several "fire" methods I wanted to have one big listener list and a typed fire method. Then the fire method could say "only fire listeners whose type is what I specify."

例如(伪代码):

ListenerList.Add(MessageTypeAListener); 
ListenerList.Add(MessageTypeBListener);

<T> fire(message) {
    ListenerList.Where(type is T).handle(message)
}

...  

fire<MessageTypeAListener>(message);

但是,类型擦除似乎使这变得困难。我可以尝试强制转换并捕获异常,但这似乎是错误的。有没有一种干净的方法可以实现此目的,还是为每种类型保留一个单独的侦听器列表是否更明智,即使会有很多类型呢?

However, type erasure seems to be making this difficult. I could try casting and catching exceptions but that seems wrong. Is there a clean way of implementing this or is it just wiser to keep a separate list of listeners for every type, even though there will be tons of types?

推荐答案

我实现了类似的方法,因为我内心不喜欢Java的EventListenerList。首先,您实现一个通用的侦听器。我根据接收到的事件定义了侦听器,基本上使用了一种方法

I implemented something like this, cause I have a visceral dislike of Java's EventListenerList. First, you implement a generic Listener. I defined the listener based upon the Event it was receiving, with basically one method

interface GenericListener<T extends Event> {
   public void handle(T t);
}

这样可以省去定义ListenerA,ListernerB等的麻烦。用ListenerA,ListenerB等以自己的方式进行操作,它们都扩展了MyListener之类的基础。两种方法都有优缺点。

This saves you having to define ListenerA, ListernerB etc... Though you could do it your way with ListenerA, ListenerB, etc, all extending some base like MyListener. Both ways have plusses and minuses.

然后,我使用 CopyOnWriteArraySet 来容纳所有这些侦听器。设置集是要考虑的原因,因为太松散的编码人员经常将侦听器添加两次。 YMMV。但是,实际上,您有一个 Collection< GenericListener< T扩展Event>>。或Collection< MyListener>

I then used a CopyOnWriteArraySet to hold all these listeners. A set is something to consider cause all too often listeners get added twice by sloppy coders. YMMV. But, effectively you have a Collection<GenericListener<T extends Event>> or a Collection<MyListener>

现在,您已经发现,使用类型擦除,Collection只能容纳一种类型的侦听器。这通常是一个问题。解决方案:使用地图。

Now, as you've discovered, with type erasure, the Collection can only hold one type of listener. That is often a problem. Solution: Use a Map.

由于我将一切都基于事件,因此我使用了

Since I'm basing everything upon the event, I used

Map<Class<T extends Event>, Collection<GenericListener<T extends Event>>>

根据事件的类别,获取要获取该事件的侦听器的列表。 br>
您的替代方法是基于侦听器的类

based upon the class of the event, get the list of listeners who want to get that event.
Your alternative is to base it upon the class of the listener

Map<Class<T extends MyListener>, Collection<MyListener>>

上面可能有一些错别字...

There's probably some typos above...

这篇关于是否可以在Java中创建包含多个侦听器类型的自己的事件侦听器列表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆