我想在Java中做这样的事情,但我不知道方法:

当事件“object 1 say 'hello'”发生时, 然后对象2通过说“hello”来响应该事件。

有人能给我一个提示或者示例代码吗?


当前回答

嗯哼,我最近需要做一些活动,我偶然发现了这个话题。 我决定基于c#版本的事件添加我自己的实现,也许有人会读到它,这对他很有用:

@FunctionalInterface
public interface Action{
    void accept(Object... args);
}

public class CustomEvent {

    protected List<Action> listeners = new ArrayList<>();

    public void addListener(Action arg0){
        listeners.add(arg0);
    }

    public void removeListener(Action arg0){
        listeners.remove(arg0);
    }

    public void invoke(Object... args){
        for (Action listener : listeners) {
            listener.accept(args);
        }
    }
}

public class Example1 {
    public CustomEvent onValueChanged;
    
    private void doSomething(){
        onValueChanged.invoke(); // or .invoke(arg0, arg1, ...)
    }
}

public class Example2 {
    private Example1 example1;
    private Action linkToAction;
    private void init(){
        example1 = new Example1();
        linkToAction = args -> {
            doSomethingAnother(); // or doSomethingAnother((Type)args[0], (Type)args[1], ...)
        }
        example1.onValueChanged.addListener(linkToAction);
    }
    
    public void doSomethingAnother(){}
    
    public void unsubscribe(){
        example1.onValueChanged.removeListener(linkToAction);
    }
}

这是一个简单的例子,Action接口的实现,我做的,是基于Consumer接口的,所以方法名是相似的,但是你也可以改变它。

其他回答

您需要的是观察者模式的实现。你可以完全自己做,或者使用java类,如java.util. observer和java.util. observable

你可能想看看观察者模式。

下面是一些示例代码,可以帮助您入门:

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..."
    }
}

相关文章:Java:创建自定义事件

嗯哼,我最近需要做一些活动,我偶然发现了这个话题。 我决定基于c#版本的事件添加我自己的实现,也许有人会读到它,这对他很有用:

@FunctionalInterface
public interface Action{
    void accept(Object... args);
}

public class CustomEvent {

    protected List<Action> listeners = new ArrayList<>();

    public void addListener(Action arg0){
        listeners.add(arg0);
    }

    public void removeListener(Action arg0){
        listeners.remove(arg0);
    }

    public void invoke(Object... args){
        for (Action listener : listeners) {
            listener.accept(args);
        }
    }
}

public class Example1 {
    public CustomEvent onValueChanged;
    
    private void doSomething(){
        onValueChanged.invoke(); // or .invoke(arg0, arg1, ...)
    }
}

public class Example2 {
    private Example1 example1;
    private Action linkToAction;
    private void init(){
        example1 = new Example1();
        linkToAction = args -> {
            doSomethingAnother(); // or doSomethingAnother((Type)args[0], (Type)args[1], ...)
        }
        example1.onValueChanged.addListener(linkToAction);
    }
    
    public void doSomethingAnother(){}
    
    public void unsubscribe(){
        example1.onValueChanged.removeListener(linkToAction);
    }
}

这是一个简单的例子,Action接口的实现,我做的,是基于Consumer接口的,所以方法名是相似的,但是你也可以改变它。

下面是不完全相同但类似的,我正在搜索一个片段来添加对接口方法的调用,但发现了这个问题,所以我决定为那些像我一样搜索它并发现这个问题的人添加这个片段:

 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) {
                }
            });

术语

侦听器是观察者/处理程序 Dispatcher是主题/观察者容器

通常,当人们实现观察者模式时,他们要求调度程序在任何侦听器可以订阅它之前存在。但有一种更好的方法叫做信号。

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
    }
}

在本例中,Signal是从Chat界面自动创建的。它允许Foo注册它,并且允许Foo2在没有交互的情况下发送新消息。

免责声明:我是信号的作者。