2011-09-06 39 views
0

我想問你幾個關於Gui的問題。瞭解Gui和聽衆

我看到了下面的例子:

public class ShellWithButton { 
    public static void main(String[] args) { 
    Display display = Display.getDefault(); 
    Shell shell = newShell (display); 
    Button ok = newButton (shell, SWT.PUSH); 
    ok.setText ("Push Me!"); 
    ok.addSelectionListener(new ButtonHandler()); 
    ok.setLocation(0,0); 
    ok.setSize(100,30); 
    shell.pack(); 
    shell.open(); 
    while(!shell.isDisposed()) { 
    if(!display.readAndDispatch()) 
     display.sleep(); 
      } 
     display.dispose(); 
     } 
    }  

public class ButtonHandler 
implements SelectionListener { 
    public void widgetSelected(SelectionEvent e) { 
     if(e.getSource() instanceofButton) { 
      Button b = (Button) e.getSource(); 
      b.setText("Thanks!"); 
     } 
    } 
public voidwidgetDefaultSelected(SelectionEvent e){ 
// TODO Auto-generated method stub 
    } 
} 

(I) - 有人推按鈕 - 程序如何知道要激活widgetSelected? 我可以看到按鈕添加了ButtonHandler監聽器本身,但爲什麼按下按鈕而不是單擊該框會將事件發送到ButtonHandler? 我看不到只有推送發送給這個監聽者的地方。 (ii) - 爲什麼我要將一個ButtonHandler的實例發送給監聽器?那是什麼意思? (iii) - 當我按下按鈕時發生了什麼?這個事件是什麼?事件是按鈕本身的一個實例?

(iv) - Button b = (Button) e.getSource();爲什麼我需要此源代碼的投射?正如所寫的那樣,事件只能來自ok,這是按鈕的實例。

(v) - 爲什麼原始按鈕會改變它的標題?我們改變B.

非常感謝!

回答

2
  1. 當有人按下按鈕,該按鈕調用widgetSelected() ,因爲這是該庫是如何設計的;它需要調用一些 方法,所以你可以做一些事情,他們在這個方法上解決。 因爲它叫你widgetSelected()是因爲你給它你的 類爲它打電話。該按鈕知道您的班級有一個 widgetSelected()方法,因爲您實施了 SelectionListener,並且需要您執行 widgetSelected()方法。這是接口的原因, ,我建議你閱讀它們。只有點擊該按鈕, 纔會獲得按鈕來調用您的方法,因爲該按鈕僅在點擊時才知道 。當屏幕上有一個點擊時,只有需要知道它的小部件纔會被告知。

  2. 正如我上面提到的,您將您的處理程序發送到按鈕,以便 知道如何處理它。

  3. 當按鈕被按下時,它告訴你什麼樣的處理程序發生 ,等所有相關信息提供給您的 SelectionEvent。事件本身不是按鈕,但事件 會告訴您哪個按鈕被按下,以防您希望相同的處理程序 處理多個按鈕。

  4. 您需要的造型,因爲當事情發生時對各種GUI對象,不只是 按鈕您widgetSelected()方法可以 調用。因此,源代碼將作爲某些超類共同的 提供給所有可以調用您的方法的小部件,並且當您確定它是您的按鈕時,您需要將 轉換回按鈕。是的,在這個 程序中它只能被按鈕調用,但這並不總是 的情況。

  5. 按鈕的文本更改是因爲B和您創建並顯示的按鈕是同一個對象。 Java中的對象(和數組)是「指針」,它們告訴你對象在哪裏。當您將一個對象分配給另一個變量時,您不會複製該對象,而只是使用另一個變量指向同一個對象。

2

(I)GUI通常採用observer pattern,其中一個或多個對象訂閱事件,每當這個事件發生是發送給所有訂閱的對象,就像在你的按鈕的情況下。

(II)你爲了他們交往發送實例的聽衆,所以在適當的時候,他們可能會收到事件。

(III)什麼情況是,該事件導致觀察員收到您的按鈕被按下的通知,最終導致正在執行一些代碼。事件本身不是按鈕的實例,而是處理事件的單獨實例。

(IV)你需要轉換,因爲方法簽名僅僅是通用的,因爲它是用於多種類型的事件。

(V)它改變了它的標題,因爲使用觀察者模式,觀察者在這種情況下,當其按下按鈕事件發生的按鈕被通報。

+0

謝謝奧斯卡。這個聽衆是否總是與按鈕本身相關?假設我想更改外殼上的文本。我是否仍然需要將此偵聽器添加到按鈕?或者我可以添加到一個shell嗎? – Numerator

+0

@Nir yes只要此按鈕已註冊此事件,此監聽器就會將事件分派給按鈕。我不知道你的Shell類是什麼,但是如果你想改變它的文本,你將不得不將它添加爲一個監聽器,以便在事件發生時對其進行更改。 –

2

(i)「Listeners」背後的想法是,您希望提供將被通知事件的組件,對象,軟件模塊等的列表。按鈕點擊不僅僅是觸發事件的原因是因爲某些事情必須監聽該事件才能對其做出反應。可以添加任何實現適當Listener接口的對象(取決於事件的類型),並因此處理該事件。 (ii)這是一個回調。你必須告訴監聽者,「這是一個可以處理事件的對象實例,請將它添加到要通知的對象列表中。「這有點像訂閱RSS訂閱源,在某種意義上,列表中的每個人都會在發生更新時獲得更新。

(iii)事件是一個單獨的對象窗口系統(在某個深層,連接到底層操作系統的窗口庫)創建事件對象,然後沿着已註冊的監聽器列表向下,通知每個監聽器。這裏有一些例外(例如,監聽器可能吸收事件,阻止名單上的其他人聽到它,但這是它自己的一個單獨問題)

(iv)因爲getSource()返回一個組件的實例如果你想能夠訪問Button特定的方法(在下面的行中完成,使用setText,你有要處理該方法調用的Button實例來知道該做什麼(即,在哪個班上進行操作)。 (v)該按鈕不改變它的標題 - ButtonHandler正在做它。所以,當widget被選中時,在ButtonHandler中調用「widgetSelected」方法。然後檢查事件的來源(提供對原始按鈕的引用),然後更新按鈕的文本以反映它已被點擊。