Java에서 사용자 정의 이벤트 작성


193

Java에서 이와 같은 작업을 수행하고 싶지만 방법을 모르겠습니다.

"object 1 say"hello ""이벤트가 발생하면 object 2는 "hello"라고 말하여 해당 이벤트에 응답합니다.

누군가 나에게 힌트 나 샘플 코드를 줄 수 있습니까?



답변:


421

아마도 관찰자 패턴 을 조사하고 싶을 것 입니다 .

시작하기위한 샘플 코드는 다음과 같습니다.

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 : 사용자 정의 이벤트 작성


stackoverflow.com/suggested-edits/237242 가 통과하지 않은 합법적 인 이유 가 있습니까? 원래 질문 한대로 2 개의 클래스 로이 작업을 수행하는 방법을 보여줍니다.
GlassGhost

2
여러 스레드가 소스 이벤트를 생성하는 경우 올바르게 동기화됩니까?
Mike G

siruation에 따라 다릅니다. 각 리스너는 등록한 순서에 따라 알림을받습니다. (Btw, 여기에서 다중 스레드의 의미를 이해하지 못합니다. 리스너 코드는 이벤트가 발생한 동일한 스레드에서 실행됩니다.)
aioobe

8
@GlassGhost : 기본적으로 완전히 다시 작성 되었기 때문에 거부되었습니다. 다른 사람의 답변을 수정하면 오타 및 서식을 수정하고 링크를 끊는 등의 작업을 수행하는 것이 좋지만 내용을 크게 변경해서는 안됩니다. ( "community wiki"로 표시된 게시물에는 예외가 있습니다.)
cHao

1
자바에 내장 된 것이 없습니까? 모든 이벤트에 대해 for 루프를 구현하지 않고 추상 패턴 으로이 작업을 수행하는 것이 좋습니다.
Tomáš Zato-복직 모니카


21

이를 설정하는 방법에는 3 가지가 있습니다.

  1. Thrower 내면에 Catcher
  2. Catcher 내면에 Thrower
  3. Thrower그리고 Catcher본 실시 예에서 다른 클래스의 내부Test

인용 작업 GitHub의 예 I AM 단지의 주석 "다른 사람을 시도 옵션 3에 기본값Optional은 AS"코드는 주로 지정할 클래스의 블록 및 설정 클래스를${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 . . .
}

6
@ GlasGhost : 문제는 main정적이며 this정적 함수 와 같은 것은 없습니다 . new Catcher1()어딘가에 생성하고 대신 해당 인스턴스를 전달해야합니다. 1.5 this정적 컨텍스트에서도 허용하지 않았다 . 나는 그것이 결코 허용되지 않았다고 확신합니다.
cHao

6
@GlassGhost : 사용하는 코드 this는에있는 것이 아니라 생성자에 main있습니다. 그것이 작동하는 이유입니다. 로 이동하면 main보장하지 않습니다. 그것은 사람들이 당신에게 말하려고했던 것과 당신의 대답이하려고하는 것입니다. 나는 github에있는 것을 망설이지 않는다. 나는 SO에있는 것을 좋아한다. 그리고 당신이 그렇게 가지고있는 것은 깨졌습니다.
cHao

7
@ GlassGhost : 귀하의 답변이 전체적으로 부적절하다고 생각하지 않습니다. 당신이 사용하려는 - 내가 그것으로 볼 문제는 같은 코드가 작동하지 않습니다이다 this에서 main자바의 릴리스 버전에서 컴파일되지 않을 것이다. 경우에 그 부분 대신 생성자에 있던, 또는 경우 main을 만들어 new Catcher1()대신의 것을 사용 this, 그것도 1.6에서 작동합니다.
cHao

6
@GlassGhost : "선언 된 메소드를 static클래스 메소드라고합니다. 클래스 메소드는 항상 특정 객체를 참조하지 않고 호출됩니다. 키워드 this또는 키워드를 사용하여 현재 객체 super를 참조하거나 주변의 유형 매개 변수를 참조 하려는 시도 클래스 메소드의 본문에서 선언하면 컴파일 타임 오류가 발생합니다. " - 자바 5에 대한 JLS, §8.4.3.2
차오

31
이것은 내가 본 것 중 가장 이상한 코드 스타일 중 하나입니다.
Eric

4

다음은 정확히 동일하지는 않지만 인터페이스 메소드에 호출을 추가하기 위해 스 니펫을 검색했지만이 질문을 찾았으므로 나처럼 그것을 검색하고있는 사람들을 위해이 스 니펫을 추가하기로 결정했습니다. :

 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) {
                }
            });
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.