2013-07-16 88 views
2

我經常實現一些面板,它們提供了像控件一樣的常用功能。爲此,我希望能夠添加偵聽器,以便調用者可以附加到控件並獲取有關更改的通知。如何正確地將ActionListeren添加到自定義JComponent中

到目前爲止,我只是簡單地使用我自己的List,在那裏我保持聽衆,當我想要觸發一個動作時,我循環訪問列表並調用監聽器。從外部看,這基本上看起來像其他Swing控制,但我想知道這是否真的應該使用的方法。

特別是我想知道是否在循環中調用聽衆本身也是Swing,或者如果有某種類型的隊列將放置操作,以便Swing決定何時執行此類操作。

當我investiaged這個我遇到了這個代碼:

protected void fireActionPerformed(ActionEvent event) 
{ 
    Object[] listeners = listenerList.getListenerList(); 
    ActionEvent e = null; 

    // Process the listeners last to first, notifying 
    // those that are interested in this event 
    for (int i = listeners.length-2; i>=0; i-=2) 
    { 
     if(listeners[i] instanceof ActionListener) 
     { 
      // Lazily create the event: 
      if (e == null) 
      { 
       String actionCommand = event.getActionCommand(); 

       e = new ActionEvent(this, 
         ActionEvent.ACTION_PERFORMED, 
         actionCommand, 
         event.getWhen(), 
         event.getModifiers()); 
       e.setSource(event.getSource()); 
      } 
      ((ActionListener)listeners[i+1]).actionPerformed(e); 
     } 
    } 
} 

JComponentlistenerList直接訪問的成員,whcih感覺有點怪怪的。但是到目前爲止我還沒有找到更好的方法。還加入了新的監聽器,這個時候,我現在就做如下圖所示,但我不知道這是否真的是用適當的方式:

public void addQueryListener(ActionListener oListener) 
{ 
    listenerList.add(ActionListener.class, oListener); 
} 

public void removeQueryListener(ActionListener oListener) 
{ 
    listenerList.remove(ActionListener.class, oListener); 
} 

所以我想知道,在訪問listenerList成員添加和刪​​除偵聽器的正確方法,以便它們像任何其他標準控件一樣工作?還是有一些best practice這應該怎麼做,我到目前爲止失蹤?

回答

1

記住限制擺動創造gui。以這種方式訪問​​ **偵聽器**沒有任何危害。可能是這不是最好的辦法。 Swing假設爲單線程並且不是線程安全的。

http://codeidol.com/java/java-concurrency/GUI-Applications/Why-are-GUIs-Single-threaded/

的addListener和需要的removeListener要呼籲EDT(事件指派線程) 瞧瞧http://en.wikipedia.org/wiki/Event_dispatching_thread

另請參見Listenere即重複,當你調用getActionListeners

其創建ListenersList的副本,並返回你回來

下面的代碼從EventListenerList對象

public <T extends EventListener> T[] getListeners(Class<T> t) { 
Object[] lList = listenerList; 
int n = getListenerCount(lList, t); 
    T[] result = (T[])Array.newInstance(t, n); 
int j = 0; 
for (int i = lList.length-2; i>=0; i-=2) { 
    if (lList[i] == t) { 
    result[j++] = (T)lList[i+1]; 
    } 
} 
return result; 
} 
1

有一個在一個很好的例子EventListenerList文檔,並且此Converter示例在ConverterRangeModel中使用自己的listenerList

+0

我想這是我從哪裏開始發射事件的樣本,因爲我不記得我發現它的具體位置。那麼,訪問listenerList似乎是一種方式,即使直接訪問成員感覺有點奇怪。 :) – Devolus

+0

我已經看到它在'JComponent'子類中使用,也像'JFreeChart'一樣。 –

相關問題