2014-08-31 112 views
9

我剛剛開始使用Swing學習GUI,但並不完全瞭解actionPerformed方法的工作原理。請考慮以下代碼:如何在不明確調用「actionPerformed」方法的情況下調用該方法?

//code to create a button and change its text when clicked 
public class simplegui implements ActionListener { 
    JButton button; 

    public static void main(String[] args) { 
    simplegui gui=new simplegui(); 
    gui.go(); 
    } 

    public void go() { 
    JFrame frame=new Frame(); 
    button=new JButton("click Me"); 
    button.addActionListener(this); 

    frame.getContentPane().add(button); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.setSize(300,300); 
    frame.setVisible(true); 
    } 

    public void actionPerformed(ActionEvent event) { 
    button.setText("I've been clicked!"); 
    } 
} 

不應該在引發方法之前爲其創建對象(靜態方法除外)?

當按鈕被點擊時actionPerformed方法被調用,但如何?通話在哪裏?我已經實現了接口ActionListener,但知道何時發生操作的'ActionEvent'對象應該發送到'actionPerformed'方法的代碼在哪裏?它是否存在於Button類中? Button類中存在addActionListener方法嗎?

當我點擊按鈕時,系統調用操作如何執行以及執行代碼的位置是gui.actionPerformed()

我遵循Java的OO概念,靜態等,直到現在,但這整個事件驅動編程是混亂。

+1

但有**是**特定調用此方法,只它不會發生在您的代碼中,而是發生在JVM中。按鈕推動引發內部事件,導致JVM通知按鈕通知其所有聽衆已被推送。這將導致所有連接的ActionListener的actionPerformed方法被調用。 – 2014-08-31 12:49:39

+1

@HovercraftFullOfEels我建議添加一個完整的答案(可能與指向Java/swing運行時庫源的鏈接) – hexafraction 2014-08-31 12:52:11

+0

是的,我明白了,但是如果在其他地方有一個調用是在任何這些類中的代碼,如果是這樣,請將我的相關API文檔鏈接到清楚的地方? – 2014-08-31 12:53:35

回答

11

每個事件都由一個對象表示,該對象提供有關事件的信息並標識事件源。事件源通常是組件或模型,但其他類型的對象也可以是事件源。

在這裏,你註冊了偵聽器, 就是

button.addActionListener(this); 

被添加到聽衆的名單,而當JVM接收到事件(請在這種情況下),它會調用適當的方法上列表中的所有聽衆。

這是怎麼發生的?嗯,我想你應該閱讀關於在java中的Callback機制。

您還可以使用回撥機制創建自己的聽衆。 考慮下面的代碼:

的代碼是一個信用卡應用simulation.In下面的代碼中,pinChanged()方法時changePin()方法被調用就會自動調用。

public interface PinChangeListener { 
    public void pinChanged(); 
} 

public class CreditCard { 
    public PinChangeListener pinChangeListener; 

    private int pin; 

    public changePin(int pin) { 
     this.pin = pin; 
     if (pinChangeListener != null) { 
      pinChangeListener.pinChanged(); 
     } 
    } 
} 

一個回調/監聽器連接到信用卡,你只需要實現PinChangeListener方法:

creditCard.pinChangeListener = new PinChangeListener() { 
    public void pinChanged() { 
     System.out.println("The pin has been changed"); 
    } 
}; 

同樣,當您將一個監聽到一個按鈕,點擊由JVM檢測,(您可能不想進入檢測點擊的方式!),並且附加的偵聽器的actionPerformed()由JVM爲您調用。希望這個清除。

+0

非常感謝,這是一個非常明確的解釋。 – 2014-08-31 13:32:50

+0

我很高興它幫助:) – 2014-08-31 13:38:28

4

但是有一個特定的調用這個方法,只是它不是在你的代碼中發生,而是在JVM中發生。按鈕推動引發內部事件,導致JVM通知按鈕通知其所有聽衆已被推送。這將導致所有連接的ActionListener的actionPerformed方法被調用。

要看到這是如何工作的,在先來看看在那裏你會找到方法

protected void fireActionPerformed(ActionEvent event) 

通知已註冊對獲得此事件的通知感興趣的所有偵聽信息類型。事件實例是使用事件參數延遲創建的。

然後,有關詳細信息,您將希望超越Java API的源代碼,可以找到here。如果檢查出的Java 8.0的源代碼存在,並期待的javax揮杆,然後AbstractButton中,你會發現一個fireActionPerformed(ActionEvent event)方法:

2002 protected void More ...fireActionPerformed(ActionEvent event) { 
2003  // Guaranteed to return a non-null array 
2004  Object[] listeners = listenerList.getListenerList(); 
2005  ActionEvent e = null; 
2006  // Process the listeners last to first, notifying 
2007  // those that are interested in this event 
2008  for (int i = listeners.length-2; i>=0; i-=2) { 
2009   if (listeners[i]==ActionListener.class) { 
2010    // Lazily create the event: 
2011    if (e == null) { 
2012      String actionCommand = event.getActionCommand(); 
2013      if(actionCommand == null) { 
2014       actionCommand = getActionCommand(); 
2015      } 
2016      e = new ActionEvent(AbstractButton.this, 
2017           ActionEvent.ACTION_PERFORMED, 
2018           actionCommand, 
2019           event.getWhen(), 
2020           event.getModifiers()); 
2021    } 
2022    ((ActionListener)listeners[i+1]).actionPerformed(e); 
2023   } 
2024  } 
2025 } 
+2

作爲參考,這種方法在['EventListenerList'](http://docs.oracle.com/javase/8/docs/api/javax/swing/event/ EventListenerList.html)API,檢查[這裏](http://stackoverflow.com/q/2159803/230513)。 – trashgod 2014-08-31 13:41:26

+0

非常感謝你 – 2014-09-01 14:51:03

+0

嗨,@Hovercraft。是否可以從方法actionPerformed()調用方法。例如: - 我想調用一個_void_方法** add()**並將3個變量傳遞給它'add(int a,int b,int c)',然後獲取這些變量和我想要的過程在** add()**方法中。提前致謝。 – Learner 2017-01-11 09:02:08

相關問題