Java swing: 實現ActionListener監聽器的三種途徑


Swing是目前Java中不可缺少的窗口工具組,是用戶建立圖形化用戶界面(GUI)程序的 強大工具。Java Swing組件自動產生各種事件來響應用戶行為。如當用戶點擊按鈕或選擇菜單項目時,Swing組件會產生一個 ActionEvent。Swing組件會產生許多事件,如ActionEvents,ChangeEvents,ItemEvents等,來響應用戶的鼠標點擊行為,列表框中值的改變,計時器的開始計時等行為。在Java Swing編程中,通過注冊監聽器,我們可以監聽事件源產生的事件,從而在事件處 理程序中處理我們所需要處理的用戶行為。
  
  Java Swing中處理各組件事件的一般步驟是:
  
  1. 新建一個組件(如JButton)。
  
  2. 將該組件添加到相應的面板(如JPanel)。
  
  3. 注冊監聽器以監聽事件源產生的事件(如通過ActionListener來響應用戶點擊按鈕)。
  
  4. 定義處理事件的方法(如在ActionListener中的actionPerformed中定義相應方法)。
  
  以上步驟我們可以用多種方法實現。但人們通常用二種方法。第一種方法是只利用一個監聽器以及多個if語句來決定是哪個組件產生的事件;第二種方法是使用多個內部類來響應不同組件產生的各種事件,其具體實現又分兩種方式,一種是匿名內部類,一種是一般內部類。
  
   為了說明如何使用上述三種方法實現事件的處理方法,我們建立一個簡單的應用程序。該程序界面有兩個按鈕,當用戶點擊相應的按鈕,就會彈出一個對話框顯示相應的內容。通過這個簡單程序,你可以實現自己更多、更復雜的用戶界面程序。 
  
  首先,我們利用單個監聽器來實現該程序。我們定義一個名為Simple1的類來包括所有代碼。所有的用戶行為(如點擊按鈕)由一個監聽器SimpleListenner中的actionPerformed方法來處理。以下是代碼:

 /**   * Simple1.java - 處理事件的第一種方法   * 在這個例子中,利用一個ActionListener來監聽事件源產生的事件   * 用一些if語句來決定是哪個事件源   */         import java.awt.*;   import java.awt.event.*;   import javax.swing.*;      public class Simple1   {        private static JFrame frame; // 定義為靜態變量以便main使用        private static JPanel myPanel; // 該面板用來放置按鈕組件        private JButton button1; // 這里定義按鈕組件         private JButton button2; // 以便讓ActionListener使用            public Simple1() // 構造器, 建立圖形界面        {            // 新建面板            myPanel = new JPanel();            // 新建按鈕            button1 = new JButton("按鈕1"); // 新建按鈕1            button2 = new JButton("按鈕2");               SimpleListener ourListener = new SimpleListener();           // 建立一個actionlistener讓兩個按鈕共享            button1.addActionListener(ourListener);            button2.addActionListener(ourListener);               myPanel.add(button1); // 添加按鈕到面板            myPanel.add(button2);        }           private class SimpleListener implements ActionListener        {        /**        * 利用該內部類來監聽所有事件源產生的事件        * 便於處理事件代碼模塊化        */            public void actionPerformed(ActionEvent e)            {                // 利用getActionCommand獲得按鈕名稱                // 也可以利用getSource()來實現                // if (e.getSource() ==button1)                   String buttonName = e.getActionCommand();                if (buttonName.equals("按鈕1"))                JOptionPane.showMessageDialog(frame,                "按鈕1 被點擊");                else if (buttonName.equals("按鈕2"))                JOptionPane.showMessageDialog(frame,                "按鈕2 被點擊");                else                JOptionPane.showMessageDialog(frame,                "Unknown event" );            }        }           public static void main(String s[])        {            Simple1 gui = new Simple1(); // 新建Simple1組件                        frame = new JFrame("Simple1"); // 新建JFrame            // 處理關閉事件的通常方法            frame.addWindowListener(new WindowAdapter() {            public void windowClosing(WindowEvent e)            {System.exit(0);} });                       frame.getContentPane().add(myPanel);            frame.pack();             frame.setVisible(true);        }   }   


  讓我們來看看以上代碼是如何工作的。在main方法中,我們定義了一個JFrame,然后將面板Jpanel添加到窗體中,該面板包括兩個按鈕。相應的變量Frame,button1,button2定義在程序的開頭部分。
  
  在程序入口main方法中,首先新建Simple1組件,通過構造器建立用戶GUI,定義一個面板Jpanle,,增加兩個按鈕,然后利用 JButton.addActionListerner將兩個按鈕加入到一個活動監聽器SimpleLister中,最后,兩個按鈕添加到面板。當GUI 建立后,我們將面板添加到窗體並顯示結果。當用戶點擊按鈕時,程序調用actionPerformed方法,通過if語句來判斷是哪一個按鈕被點擊,然后在對話框中顯示相應的內容。
  
  利用一個監聽器來處理事件的缺點是,當程序比較復雜時,需要一大串的if 語句來實現,程序代碼較難閱讀與維護。當然,如果處理的事件較少,這種方式比較簡單。
  
  通過使用匿名內部類可以解決上述存在的問題。使用簡單的匿名內部類作為addActionListener的變量即可。以下是實現代碼:

 /**   * Simple2.java - 處理事件的第二種方法   * 在這個例子中,利用匿名內部類來監聽每一個事件源產生的事件   * 避免使用一些if語句來決定是哪個事件源   */      import java.awt.*;   import java.awt.event.*;   import javax.swing.*;      public class Simple2   {        private static JFrame frame; // 定義為靜態變量以便main使用        private static JPanel myPanel; // 該面板用來放置按鈕組件        private JButton button1; // 這里定義按鈕組件         private JButton button2; // 以便讓ActionListener使用                public Simple2() // 構造器, 建立圖形界面        {            // 新建面板            myPanel = new JPanel();            // 新建按鈕            button1 = new JButton("按鈕1"); // 新建按鈕1            button2 = new JButton("按鈕2");                       // 每一個事件源需要一個監聽器            // 定義一個匿名內部類來監聽事件源產生的事件            button1.addActionListener(                new ActionListener()                {                    public void actionPerformed(ActionEvent e)                    {                        JOptionPane.showMessageDialog(frame,"按鈕1 被點擊");                    }                }            );                       button2.addActionListener(                new ActionListener()                {                    public void actionPerformed(ActionEvent e)                    {                        JOptionPane.showMessageDialog(frame,"按鈕2 被點擊");                    }                }            );                       myPanel.add(button1); // 添加按鈕到面板            myPanel.add(button2);         }                    public static void main(String s[])         {             Simple2 gui = new Simple2(); // 新建Simple2組件                                             frame = new JFrame("Simple2"); // 新建JFrame             // 處理關閉事件的通常方法             frame.addWindowListener(new WindowAdapter() {             public void windowClosing(WindowEvent e)             {System.exit(0);} });             frame.getContentPane().add(myPanel);             frame.pack();              frame.setVisible(true);         }   }


  使用匿名內部類同樣存在許多另外的問題。首先,根據組件在代碼中被定義的不同位置,類的定義以及處理事件的代碼將分散在程序的各個部分,不是集中在一塊,同樣不便於閱讀與維護。各事件的處理全部由嵌套的程序塊組成,視覺上很難定位程序代碼。如果事件處理程序比較復雜,內部類中的代碼將變得很長,你將找不到相應的組件定義位置。最后,當工具欄、菜單欄目等需要處理同樣的用戶行為時,該方法將使代碼更難維護。
  
  我們使用一般的命名內部類可以解決以上許多問題。所有的事件處理方法都集中在一塊,並且都具有有意義的名稱,程序非常容易閱讀與維護。單個的事件處理程序也可以被工具欄、菜單欄等重復使用,
  
  以下是實現代碼:

 /**   * Simple3.java - 處理事件的第三種方法   * For this example, we will use inner member classes to   * 在這個例子中,利用一般內部類來監聽每個事件源產生的事件   * 該方法避免了第二種方法中由於使用匿名內部類而導致的代碼混亂   * 便於集中處理事件代碼   * 每一個Hander可以被工具欄或菜單多次使用   */   import java.awt.*;   import java.awt.event.*;   import javax.swing.*;      public class Simple3   {        private static JFrame frame; // 定義為靜態變量以便main使用        private static JPanel myPanel; // 該面板用來放置按鈕組件        private JButton button1; // 這里定義按鈕組件         private JButton button2; // 以便讓ActionListener使用                // 利用一般內部類來監聽每一個事件源產生的事件如(button1, button2)        private class Button1Handler implements ActionListener        {            public void actionPerformed(ActionEvent e)            {                JOptionPane.showMessageDialog(frame,"按鈕1 被點擊");            }        }                private class Button2Handler implements ActionListener        {            public void actionPerformed(ActionEvent e)            {                JOptionPane.showMessageDialog(frame,"按鈕2 被點擊");            }        }                public Simple3() // // 構造器, 建立圖形界面        {            // 新建面板            myPanel = new JPanel();            // 新建按鈕            button1 = new JButton("按鈕1"); // 新建按鈕1            button2 = new JButton("按鈕2");                       // 對每一個組件注冊監聽內部類            button1.addActionListener(new Button1Handler());            button2.addActionListener(new Button2Handler());                       myPanel.add(button1); // 添加按鈕到面板            myPanel.add(button2);        }               public static void main(String s[])        {            Simple3 gui = new Simple3(); // 新建Simple3組件                       frame = new JFrame("Simple3"); // 新建JFrame            // 處理關閉事件的通常方法             frame.addWindowListener(new WindowAdapter() {                public void windowClosing(WindowEvent e)                {System.exit(0);} });                       frame.getContentPane().add(myPanel);            frame.pack();             frame.setVisible(true);        }   }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM