Java'da özel bir etkinlik oluşturma


Yanıtlar:


421

Muhtemelen gözlemci modeline bakmak istersiniz .

Başlamak için bazı örnek kodlar şunlardır:

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

İlgili makale: Java: Özel bir etkinlik oluşturma


Stackoverflow.com/suggested-edits/237242'nin geçmemesi için meşru bir neden var mı ? Sorunun başlangıçta sorulduğu gibi 2 sınıfla nasıl yapılacağını gösterir.
GlassGhost

2
Kaynak olayları birden çok iş parçacığı oluşturuyorsa, bu düzgün şekilde eşitlenir mi?
Mike G

Siruasyona bağlıdır. Her dinleyici, kaydettikleri sıraya göre bilgilendirilir. (Btw, burada birden çok iş parçacığı ile ne demek istediğini anlamıyorum. Dinleyici kodu, olayın gerçekleşmesine neden olan aynı iş parçacığında gerçekleştirilecektir.)
aioobe

8
@GlassGhost: Temelde tam bir yeniden yazma olduğu için reddedildi. Başka birinin cevabındaki düzenlemeler, yazım hatalarını, biçimlendirmeyi ve kopuk bağlantıları ve benzerlerini düzeltirse iyidir, ancak içeriği kökten değiştirmemelidir. ("Topluluk wiki" olarak işaretlenmiş yayınlar için bazı istisnalar geçerlidir.)
cHao

1
Java'nın bunun için yerleşik bir şeyi yok mu? Gerçekten her olay için döngü için uygulamak değil, soyut desen yapmayı tercih ederim.
Tomáš Zato - Monica'yı eski durumuna döndür


21

Bunu ayarlamak için 3 farklı yol vardır:

  1. Thrower içinde Catcher
  2. Catcher içinde Thrower
  3. Throwerve Catcherbu örnekte başka bir sınıfın içindeTest

ÇALIŞAN GITHUB ÖRNEĞİ VERİYORUM Seçenek 3 varsayılanları, diğerleri sadeceOptionalana olmak istediğiniz sınıfın"" kod bloğunuuncomment denemekve bu sınıfıdosyada${Main-Class}değişkenolarak ayarlamakiçinbuild.xml:

4 Yan kodu atmak için gereken şeyler:

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 Sınıftaki olayları almak için sınıf dosyasında gereken şeyler

/*_______________________________________________________________*/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
@GlassGhost: Sorun mainstatik olmasıdır ve thisstatik fonksiyonda olduğu gibi bir şey yoktur . Bir yer oluşturmanız new Catcher1()ve bunun yerine bu örneği iletmeniz gerekir. 1.5 de thisstatik bir bağlamda izin vermedi ; Hiç izin verilmediğinden eminim.
cHao

6
@GlassGhost: Kullanılan kod, thisbir yapıcıda değil, içinde main. Bu yüzden çalışıyor. Taşı main, ve garanti etmeyeceğim. İnsanlar size bunu anlatmaya çalışıyor ve cevabınız bunu yapmaya çalışıyor. Github'da olanlara lanet etmiyorum - SO'da ne olduğunu umursuyorum. Ve SO'da sahip olduğunuz şey bozuldu.
cHao

7
@GlassGhost: Cevabınızın genel olarak yetersiz olduğunu düşünmüyorum. Kullanmak için çalışıyoruz - i onunla bkz sorundur olarak kod çalışma alışkanlık olduğunu thisgelen mainherhangi bir Java yayımlanan sürümünde derlemek olmaz, hangi. Eğer o parça bunun yerine bir kurucudaysa veya bunun yerine mainbir oluşturulmuş new Catcher1()ve kullanılmışsa this1.6'dan sonra bile çalışmalıdır.
cHao

6
@GlassGhost: "Bildirilen bir yönteme staticsınıf yöntemi denir. Bir sınıf yöntemi her zaman belirli bir nesneye başvurmadan çağrılır. Anahtar sözcük thisveya anahtar sözcük kullanarak geçerli nesneye superbaşvuruda bulunma veya herhangi bir çevrenin tür parametrelerine başvurma girişimi bir sınıf yönteminin gövdesinde bildirim derleme zamanı hatasına neden olur. " - Java 5 için JLS, §8.4.3.2
cHao

31
Bu şimdiye kadar gördüğüm en garip kod stillerinden biri
Eric

4

Aşağıdaki tam olarak aynı değil, benzer, arayüz yöntemine çağrı eklemek için bir snippet arıyordum, ancak bu soruyu buldum, bu yüzden bu snippet'i benim gibi arayanlar için eklemeye karar verdim ve bu soruyu buldum :

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

Kullanımı aşağıdaki gibidir:

myClassObj.setDataLoadFinishedListener(new MyClass.DataLoadFinishedListener() {
            @Override
            public void onDataLoadFinishedListener(int data_type) {
                }
            });
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.