如何在Java中引发自定义事件和句柄。一些链接会有所帮助。
感谢。
答案 0 :(得分:15)
Java中没有一流的事件。所有事件处理都使用接口和侦听器模式完成。例如:
// Roughly analogous to .NET EventArgs
class ClickEvent extends EventObject {
public ClickEvent(Object source) {
super(source);
}
}
// Roughly analogous to .NET delegate
interface ClickListener extends EventListener {
void clicked(ClickEvent e);
}
class Button {
// Two methods and field roughly analogous to .NET event with explicit add and remove accessors
// Listener list is typically reused between several events
private EventListenerList listenerList = new EventListenerList();
void addClickListener(ClickListener l) {
clickListenerList.add(ClickListener.class, l)
}
void removeClickListener(ClickListener l) {
clickListenerList.remove(ClickListener.class, l)
}
// Roughly analogous to .net OnEvent protected virtual method pattern -
// call this method to raise the event
protected void fireClicked(ClickEvent e) {
ClickListener[] ls = listenerList.getListeners(ClickEvent.class);
for (ClickListener l : ls) {
l.clicked(e);
}
}
}
客户端代码通常使用匿名内部类来注册处理程序:
Button b = new Button();
b.addClickListener(new ClickListener() {
public void clicked(ClickEvent e) {
// handle event
}
});
答案 1 :(得分:5)
Java缺乏内部事件处理,但有一些库可以帮助您实现这一目标。查看javaEventing,http://code.google.com/p/javaeventing/ 它在C#中的工作方式与您首先定义事件,然后注册事件侦听器一样。您可以使用EventManager.triggerEvent(.. someEvent)触发事件。它还允许您为事件提供自定义条件和有效负载。
鲍勃
答案 2 :(得分:3)
Java没有内置支持C#等委托和事件。您需要自己实施Observer或Publish/Subscribe模式。
答案 3 :(得分:2)
如果您正在寻找.net类型的委托事件,我建议使用这个模板解决方案。 它的优点是不需要硬强制转换,只要侦听器使用不同的事件类,它就可以实现几个“事件”。
import java.util.EventListener;
import java.util.EventObject;
// replaces the .net delegate
public interface GenericEventListener<EventArgsType extends EventObject>
extends EventListener {
public void eventFired(EventArgsType e);
}
//------------------------------------------------
import java.util.EventObject;
import java.util.Vector;
// replaces the .net Event keyword
public class GenericEventSource<EventArgsType extends EventObject> {
private Vector<GenericEventListener<EventArgsType>> listenerList =
new Vector<GenericEventListener<EventArgsType>>();
//TODO handle multi-threading lock issues
public void addListener(GenericEventListener<EventArgsType> listener) {
listenerList.add(listener);
}
//TODO handle multi-threading lock issues
public void raise(EventArgsType e) {
for (GenericEventListener<EventArgsType> listener : listenerList) {
listener.eventFired(e);
}
}
}
//------------------------------------------------
// like a .net class extending EventArgs
public class MyCustomEventArgs extends EventObject {
private int arg;
public MyCustomEventArgs(Object source, int arg) {
super(source);
this.arg = arg;
}
public int getArg() {
return arg;
}
}
//------------------------------------------------
// replaces the .net event handler function. Can be put in a nested class, Java style
// Listener can handle several event types if they have different EventArg classes
public class MyCustomListener implements GenericEventListener<MyCustomEventArgs> {
private Object source = null;
private int arg;
public void eventFired(MyCustomEventArgs e) {
source = e.getSource();
arg = e.getArg();
// continue handling event...
}
}
//------------------------------------------------
import GenericEventListener;
import GenericEventSource;
// this is the class that would like to throw events (e.g. MyButton)
public class MyCustomEventSource {
// This is like declaring a .net public Event field of a specific delegate type
GenericEventSource<MyCustomEventArgs> myEvent = new GenericEventSource<MyCustomEventArgs>();
public GenericEventSource<MyCustomEventArgs> getEvent() {
return myEvent;
}
}
//------------------------------------------------
// Examples of using the event
MyCustomListener myListener1 = new MyCustomListener();
MyCustomEventSource mySource = new MyCustomEventSource();
mySource.getEvent().addListener( myListener1 );
mySource.getEvent().raise( new MyCustomEventArgs(mySource,5));
答案 4 :(得分:1)
答案 5 :(得分:0)
Java没有对事件处理的语言支持。但是有些课程可以提供帮助。你可以看java.awt.Event
课; java.awt.event
和java.beans
个包。第一个包是AWT和Swing GUI库中事件处理的基础。 java.beans
包包含Java Beans specification的支持内容,包括属性更改事件和bean上下文事件。
通常,事件处理是根据观察者或发布/订阅模式实现的(如kgiannakakis所述)