【发布时间】:2011-09-10 08:08:01
【问题描述】:
我想在 Java 中做这样的事情,但我不知道怎么做:
当事件“object 1 say 'hello'”发生时, 然后对象 2 通过说“你好”来响应该事件。
谁能给我一个提示或示例代码?
【问题讨论】:
标签: java events listener handler
我想在 Java 中做这样的事情,但我不知道怎么做:
当事件“object 1 say 'hello'”发生时, 然后对象 2 通过说“你好”来响应该事件。
谁能给我一个提示或示例代码?
【问题讨论】:
标签: java events listener handler
您可能想查看observer pattern。
这里有一些示例代码可以帮助您入门:
import java.util.*;
// An interface to be implemented by everyone interested in "Hello" events
interface HelloListener {
void someoneSaidHello();
}
// Someone who says "Hello"
class Initiater {
private List<HelloListener> listeners = new ArrayList<HelloListener>();
public void addListener(HelloListener toAdd) {
listeners.add(toAdd);
}
public void sayHello() {
System.out.println("Hello!!");
// Notify everybody that may be interested.
for (HelloListener hl : listeners)
hl.someoneSaidHello();
}
}
// Someone interested in "Hello" events
class Responder implements HelloListener {
@Override
public void someoneSaidHello() {
System.out.println("Hello there...");
}
}
class Test {
public static void main(String[] args) {
Initiater initiater = new Initiater();
Responder responder = new Responder();
initiater.addListener(responder);
initiater.sayHello(); // Prints "Hello!!!" and "Hello there..."
}
}
【讨论】:
您想要的是observer pattern 的实现。你可以完全自己做,或者使用像java.util.Observer和java.util.Observable这样的java类
【讨论】:
您可能希望通过 3 种不同的方式进行设置:
Thrower 内部 Catcher
Catcher 内部 Thrower
Thrower 和 Catcher 在此示例中位于另一个类中 Test
THE WORKING GITHUB EXAMPLE I AM CITING 默认为选项 3,要尝试其他选项,只需取消注释您想成为主类的“Optional”代码块,并将该类设置为${Main-Class} build.xml 文件中的变量:
抛出侧代码所需的 4 件事:
import java.util.*;//import of java.util.event
//Declaration of the event's interface type, OR import of the interface,
//OR declared somewhere else in the package
interface ThrowListener {
public void Catch();
}
/*_____________________________________________________________*/class Thrower {
//list of catchers & corresponding function to add/remove them in the list
List<ThrowListener> listeners = new ArrayList<ThrowListener>();
public void addThrowListener(ThrowListener toAdd){ listeners.add(toAdd); }
//Set of functions that Throw Events.
public void Throw(){ for (ThrowListener hl : listeners) hl.Catch();
System.out.println("Something thrown");
}
////Optional: 2 things to send events to a class that is a member of the current class
. . . go to github link to see this code . . .
}
2 在类文件中接收来自类的事件所需的东西
/*_______________________________________________________________*/class Catcher
implements ThrowListener {//implement added to class
//Set of @Override functions that Catch Events
@Override public void Catch() {
System.out.println("I caught something!!");
}
////Optional: 2 things to receive events from a class that is a member of the current class
. . . go to github link to see this code . . .
}
【讨论】:
main 是静态的,在静态函数中没有this 这样的东西。您需要在某处创建new Catcher1(),然后传递该实例。 1.5 也不允许在静态上下文中使用this;我很确定它从未被允许。
this 的代码在构造函数中,而不是在main 中。这就是它起作用的原因。将其移至main,我保证不会。这就是人们一直试图告诉你的,也是你的答案试图做的。我不在乎 github 上的内容——我关心 SO 上的内容。你在 SO 上的东西已经坏了。
main 的this,它不会在任何已发布的Java 版本中编译。如果该部分是在构造函数中,或者如果 main 创建了一个 new Catcher1() 并使用它而不是 this,它应该可以工作,即使在 1.6+ 中也是如此。
static的方法称为类方法。类方法总是在不引用特定对象的情况下被调用。尝试使用关键字@引用当前对象987654348@ 或关键字 super 或引用类方法主体中任何周围声明的类型参数会导致编译时错误。” -- JLS for Java 5, §8.4.3.2
下面的不完全一样但是差不多,我一直在找一个sn-p来添加对接口方法的调用,结果发现了这个问题,所以决定添加这个sn-p给正在搜索的人它和我一样发现了这个问题:
public class MyClass
{
//... class code goes here
public interface DataLoadFinishedListener {
public void onDataLoadFinishedListener(int data_type);
}
private DataLoadFinishedListener m_lDataLoadFinished;
public void setDataLoadFinishedListener(DataLoadFinishedListener dlf){
this.m_lDataLoadFinished = dlf;
}
private void someOtherMethodOfMyClass()
{
m_lDataLoadFinished.onDataLoadFinishedListener(1);
}
}
用法如下:
myClassObj.setDataLoadFinishedListener(new MyClass.DataLoadFinishedListener() {
@Override
public void onDataLoadFinishedListener(int data_type) {
}
});
【讨论】:
术语
通常,当人们实现 observer pattern 时,他们需要 dispatcher 存在,然后任何 listener 才能订阅它。但是有一个更好的方法叫做Signals。
Signals 是一个事件库。它通过引入一个允许注册侦听器和调度事件的 Signal 对象来解耦调度程序的侦听器。信号是通过代理从接口自动创建的。它负责管理侦听器的所有样板代码,此外还添加了一些不错的糖代码 API。
interface Chat{
void onNewMessage(String s);
}
class Foo{
Signal<Chat> chatSignal = Signals.signal(Chat.class);
void bar(){
chatSignal.addListener( s-> Log.d("chat", s) ); // logs all the messaged to Logcat
}
}
class Foo2{
Signal<Chat> chatSignal = Signals.signal(Chat.class);
void bar2(){
chatSignal.dispatcher.onNewMessage("Hello from Foo2"); // dispatches "Hello from Foo2" message to all the listeners
}
}
在本例中,信号是从Chat 接口自动创建的。它允许Foo 注册它并允许Foo2 发送新消息而无需交互。
免责声明:我是 Signals 的作者。
【讨论】: