Buat acara khusus di Jawa

Jawaban:

421

Anda mungkin ingin melihat ke dalam pola pengamat .

Berikut beberapa contoh kode untuk memulai:

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

Artikel terkait: Java: Membuat acara khusus

aioobe
sumber
Apakah ada alasan yang sah stackoverflow.com/suggested-edits/237242 tidak melalui? Ini menunjukkan bagaimana melakukan ini dengan 2 kelas sebagai pertanyaan yang awalnya diajukan.
GlassGhost
2
Bagaimana jika banyak utas membuat acara sumber, apakah ini akan disinkronkan dengan benar?
Mike G
Tergantung pada siruation. Setiap pendengar akan diberitahu sesuai dengan urutan mereka terdaftar. (Btw, saya tidak mengerti apa yang Anda maksud dengan beberapa utas di sini. Kode pendengar akan ditampilkan pada utas yang sama yang menyebabkan peristiwa itu terjadi.)
aioobe
8
@GlassGhost: Ditolak karena pada dasarnya adalah penulisan ulang total. Pengeditan untuk jawaban orang lain baik jika mereka memperbaiki kesalahan ketik dan pemformatan dan tautan rusak dan semacamnya, tetapi mereka tidak boleh mengubah konten secara radikal. (Beberapa pengecualian berlaku untuk posting bertanda "komunitas wiki".)
cHao
1
Apakah java tidak memiliki hal bawaan untuk ini? Saya benar-benar lebih suka melakukan ini dalam pola abstrak, tidak menerapkan untuk loop untuk setiap peristiwa.
Tomáš Zato - Reinstate Monica
27

Yang Anda inginkan adalah implementasi dari pola pengamat . Anda dapat melakukannya sendiri sepenuhnya, atau menggunakan kelas java seperti java.util.Observerdanjava.util.Observable

Bozho
sumber
2
Reuse - Recycle. Tetapi lihat stackoverflow.com/questions/2380676/…
count0
21

Ada 3 cara berbeda yang ingin Anda atur:

  1. Thrower di dalam Catcher
  2. Catcher di dalam Thrower
  3. Throwerdan Catcherdi dalam kelas lain dalam contoh iniTest

CONTOH GITHUB BEKERJA AKU DATANG Default ke Opsi 3, untuk mencoba yang lain cukup batalkan komentar pada Optionalblok kode " " dari kelas yang ingin Anda , dan atur kelas itu sebagai${Main-Class} variabel dalam build.xmlfile:

4 Hal yang diperlukan untuk membuang kode samping:

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 Hal yang diperlukan dalam file kelas untuk menerima acara dari kelas

/*_______________________________________________________________*/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 . . .
}
GlassGhost
sumber
6
@GlassGhost: Masalahnya adalah mainstatis, dan tidak ada yang namanya thisfungsi statis. Anda perlu membuat suatu new Catcher1()tempat, dan meneruskan contoh itu sebagai gantinya. 1.5 juga tidak memungkinkan thisdalam konteks statis; Saya cukup yakin itu tidak pernah diizinkan.
cHao
6
@GlassGhost: Kode yang digunakan thisadalah dalam konstruktor, bukan dalam main. Itu sebabnya ini bekerja. Pindahkan ke main, dan saya jamin tidak. Itulah yang orang coba katakan kepada Anda, dan apa jawaban Anda coba lakukan. Saya tidak peduli apa yang ada di github - saya peduli apa yang ada di SO. Dan apa yang Anda miliki di SO rusak.
cHao
7
@GlassGhost: Saya rasa jawaban Anda tidak memadai secara keseluruhan. Masalah saya melihat dengan itu adalah bahwa kode tidak akan bekerja seperti - Anda mencoba untuk menggunakan thisdari main, yang tidak dapat dikompilasi dalam versi dirilis Jawa. Jika bagian itu ada di konstruktor sebagai gantinya, atau jika mainmembuat new Catcher1()dan menggunakannya this, itu harus bekerja, bahkan dalam 1,6+.
cHao
6
@GlassGhost: "Metode yang dideklarasikan staticdisebut metode kelas. Metode kelas selalu dipanggil tanpa merujuk ke objek tertentu. Upaya untuk mereferensikan objek saat ini menggunakan kata kunci thisatau kata kunci superatau untuk referensi parameter tipe di sekitarnya deklarasi dalam tubuh metode kelas menghasilkan kesalahan waktu kompilasi. " - JLS untuk Java 5, §8.4.3.2
cHao
31
Ini adalah salah satu gaya kode paling aneh yang pernah saya lihat
Eric
4

Berikut ini tidak persis sama tetapi serupa, saya sedang mencari cuplikan untuk menambahkan panggilan ke metode antarmuka, tetapi menemukan pertanyaan ini, jadi saya memutuskan untuk menambahkan cuplikan ini bagi mereka yang mencari seperti saya dan menemukan pertanyaan ini :

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

Penggunaannya adalah sebagai berikut:

myClassObj.setDataLoadFinishedListener(new MyClass.DataLoadFinishedListener() {
            @Override
            public void onDataLoadFinishedListener(int data_type) {
                }
            });
Ivan
sumber