2010-07-13 27 views
12

Khi tôi biết cách kích hoạt các sự kiện trong Java, tôi đã trở nên quen thuộc với EventListenerList. Khi tôi tạo ra thính giả của riêng tôi, tôi viết người nghe nên nó kéo dài EventListener, tôi lưu trữ chúng trong một EventListenerList, và phương pháp lửa của tôi sẽ đi qua nghe sự kiện như thế này:Khi nào sử dụng EventListenerList thay vì một bộ sưu tập chung của người nghe

protected void fireChangeOccurred(Change change) { 
    Object[] listeners = listenerList.getListenerList(); 
    for (int i = listeners.length-2; i>=0; i-=2) { 
     if (listeners[i]==ChangeListener.class) { 
      ((ChangeListener)listeners[i+1]).changeOccurred(change); 
     } 
    } 
} 

Bây giờ tôi đang xem xét mã mà chỉ đơn giản là đưa người nghe vào một HashMap (có thể là bất kỳ bộ sưu tập), giao diện người nghe không mở rộng EventListener, và phương pháp lửa trông như thế này:

protected void fireChangeOccurred(Change change) { 
    for (ChangeListener listener : listeners) { 
     listener.changeOccurred(change); 
    } 
} 

những lợi thế của việc sử dụng EventListenerList thay vì chỉ duy trì riêng của tôi là gì danh sách người nghe? Liệu nó có thực sự quan trọng nếu người nghe đang ở trong một thành phần Swing - nó có quan trọng đối với Chủ đề sự kiện không?

+5

Chỉ cần đảm bảo rằng bạn biết, 2 vòng lặp đó không giống nhau - vòng lặp đầu tiên lặp lại từ đầu đến cuối và vòng lặp thứ hai lặp lại từ đầu đến cuối. Nếu người nghe được phép xóa chính nó (thường là), thì bạn sẽ muốn lặp lại từ đầu đến cuối để tránh bỏ qua người nghe tiếp theo nếu người nghe hiện tại xóa chính nó. –

Trả lời

6

Với tôi, lợi thế chính của EventListenerList là nếu lớp chứa có (hoặc có thể có) nhiều hơn một loại của người nghe. Nhiều thành phần Swing làm; cái mà bạn đang đánh giá có thể không. Ví dụ thứ hai ngắn hơn, nhưng nó có giới hạn thiết kế ngầm định.

+0

Nhưng bạn sẽ không chỉ giữ một danh sách người nghe riêng biệt - Ví dụ: Danh sách so với Danh sách ? –

+0

@David: Có, v.v. cho từng loại người nghe; 'JTable' lên đến tám, nhưng vẫn chỉ có một danh sách. Mảng 'EventListenerList' là một di sản; cho các sự kiện không xoay, một bộ sưu tập có ý nghĩa. Tuy nhiên, tôi vẫn giữ nguyên loại mã thông báo. – trashgod

+0

@David: Để tham khảo, [tag: jfreechart] là ví dụ cụ thể về thư viện sử dụng 'EventListenerList' để quản lý nhiều loại sự kiện. – trashgod

3

Không có lợi thế lớn trong những ngày này. Chỉ cần tối ưu hóa nhỏ. Đây là những gì JavaDocs nói:

lợi ích chính mà lớp này cung cấp là rằng nó là tương đối rẻ trong trường hợp không có người nghe, và nó cung cấp serialization cho sự kiện nghe liệt kê ở một nơi duy nhất, như cũng như mức độ an toàn MT (khi được sử dụng chính xác)

Với JVM hiện đại và bộ sưu tập nó thực sự không quan trọng. Nhưng những gì bạn có thể làm với việc thực hiện của riêng bạn là cung cấp cách để kích hoạt thay đổi trên EDT nếu bạn sử dụng Swing - điều đó sẽ mang lại lợi ích.

7

EventListenerListmethod, getListeners(Class<T> t), đặc biệt cho trường hợp bạn chỉ quan tâm đến một loại sự kiện.

Dưới đây là một ví dụ về cách sử dụng nó:

protected void fireChangeOccurred(Change change) { 
    for (ChangeListener listener: 
     listenerList.getListeners(ChangeListener.class)) { 
      listener.stateChanged(new ChangeEvent(this)); 
    } 
} 

Nếu bạn chọn để duy trì bộ sưu tập của riêng bạn thính giả, tôi khuyên bạn nên một CopyOnWriteArrayList.

Các vấn đề liên quan