Ch04 事件處理 物件導向系統實務
事件(1/2) 事件(event)其實是就是一種物件。 元件透過傳送事件物件(event object)的方式,傳達使用者按下滑鼠按鈕或鍵盤按鍵等事件。 GUI元件必須對鍵盤、滑鼠等動作有所反應 在Java中,按下鍵盤某個鍵或移動滑鼠,都是事件的觸發 2019/1/12
事件(2/2) 欲讓事件能順利由來源元件傳送給傾聽者處理,必須將傾聽者指定給元件(相當於一種註冊動作)。 事件本身就存在特定的事件資訊,接收事件的傾聽者可以由事件的資訊進行處理。 AWT元件可以使用的事件和傾聽者都包含在java.awt.event套件裡。 2019/1/12
傾聽者 每個傾聽者都必須實作傾聽者介面或是繼承自轉接者(Adapter)。 轉接者為實作傾聽者介面的類別,其定義的傾聽者方法都是空方法,不對事件作任何處理。 傾聽者方法都是以 void定義,參數為事件,不回傳任何值。 傾聽者介面都以Listener為識別字尾,而轉接者都以Adapter為識別字尾 2019/1/12
事件與傾聽者間的關係(1/2) [按鈕1]若未委任 一個MouseListener 物件,以滑鼠敲擊 [按鈕1],只會看到 它被敲擊,但不會 有其他回應 事件:敲擊滑鼠按鍵 (mouseClick) 按鈕1 2019/1/12
事件與傾聽者間的關係(2/2) 屬java.awt.event.* 的mouseListener介面,介面中定義了mouseClick, mousePress…等方法 [按鈕1]委任一個 MouseListener 物件,以接收並回 應mouseClick 事件源 事件:敲擊滑鼠按鍵 (mouseClick) 屬java.awt.*的Button內的方法 addMouseListener(…) 按鈕1 接收及回應 mouseClick MouseListener物件 委任一個 2019/1/12
委託事件處理模型 Java SDK 1.1版的事件處理是一種「委託事件處理模型」(Delegation Event Model),分為「事件來源」(Event Source)和處理事件的「傾聽者」(Listener)物件,如下圖所示:
AWTEvent事件-說明 在Java事件來源物件產生的事件就是一個物件,這些事件物件都屬於AWTEvent的子類別,AWTEvent事件可以分為「低階事件」(Low-level Events)和「語意事件」(Semantic Events)兩種。
AWTEvent事件-低階事件(Low-level Events) 低階事件是一些基本輸入和視窗操作等相關的事件,如下表所示:
AWTEvent事件-語意事件(Semantic Events) 語意事件是指使用者與GUI元件互動操作所產生的相關事件,如下表所示:
事件來源-低階事件 「事件來源」(Event Source)是指哪一個物件產生此事件,首先是低階事件的來源類別,如下表所示:
事件來源-語意事件 語意事件的來源類別,如下表所示:
事件傾聽者-說明 當事件來源類別產生AWT事件後,Java程式需要委託類別處理此事件,也就是將類別指定成傾聽者,其相關方法,如下表所示:
事件傾聽者-傾聽者介面1 一旦類別新增為傾聽者,該類別需要實作傾聽者介面的所有方法,如下表所示:
事件傾聽者-傾聽者介面2
事件傾聽者-程式架構 import java.applet.Applet; import java.awt.Graphics; import java.awt.event.*; public class Ch16_6_2 extends Applet implements MouseListener { public void paint(Graphics g) { ……… } public void init() { addMouseListener(this); } // 事件處理方法 public void mouseClicked(MouseEvent evt){ } public void mouseEntered(MouseEvent evt){ } public void mouseExited(MouseEvent evt){ } public void mousePressed(MouseEvent evt){ } public void mouseReleased(MouseEvent evt){ } }
實作Listener介面的作法 設計[滑鼠敲擊]事件的三個步驟: (假設有一個Buttom元件B1) 加入所需的傾聽能力 B1.addMouseListener(MouseListener l) 自訂一個實作XXXListener的類別 class myMouseListener(MouseListener l) { public void mouseClicked(MouseEvent e) { } 產生XXXListener物件實體 將步驟1中,改成 B1.addMouseListener(new myMouseListener()) 2019/1/12
範例1:按幾次按鈕(1/3) import javax.swing.*; import java.awt.*; import java.awt.event.*; public class Ch05_01 extends JFrame implements ActionListener { private static String labelString = "按鈕按幾次: "; private int num = 0; private JLabel label; //建構子, 設定初始視窗的元件 public Ch05_01() super("Swing應用程式範例 "); //視窗標題文字 Container c = getContentPane(); //取得ContentPane c.setLayout(new FlowLayout()); //版面配置 label = new JLabel(labelString + num); //設定框線 label.setBorder(BorderFactory.createLineBorder(Color.blue)); JButton button = new JButton("按一下(Alt_K)"); //設定快速鍵Alt_K button.setMnemonic(KeyEvent.VK_K); //新增事件處理 button.addActionListener(this); //設定JPanel物件 JPanel jpane = new JPanel(); //設定框線 jpane.setBorder(BorderFactory.createLineBorder(Color.yellow)); //將lable元件新增到jpane上 jpane.add(label); //將button元件新增到jpane上 jpane.add(button); //將jpane新增到c上 c.add(jpane); } //實作事件處理方法 public void actionPerformed(ActionEvent evt) { num++; label.setText(labelString + num); //重設文字內容
範例1:按幾次按鈕(2/3) public static void main(String [] args) { //建立Swing應用程式的物件 Ch05_01 app = new Ch05_01(); //關閉視窗事件,結束程式的執行 app.addWindowListener(new WindowAdapter() public void windowClosing(WindowEvent evt) System.exit(0); } } ); app.setSize(300, 100); app.setVisible(true); class myWindowListener implements WindowListener { public void windowActivated(WindowEvent evt){} public void windowClosed(WindowEvent evt){} public void windowDeactivated(WindowEvent evt){} public void windowDeiconified(WindowEvent evt){} public void windowOpened(WindowEvent evt){} public void windowIconified(WindowEvent evt){} public void windowClosing(WindowEvent evt) { System.exit(0); }
事件改編者Event Adapter-說明 在AWT的java.awt.event套件提供XXXAdapter改編者類別,如下表所示: 2019/1/12 20 20
事件改編者Event Adapter-範例 當元件新增事件後,需在傾聽者類別實作所有介面方法,但是我們只會使用到其中幾個方法。 例如:在主程式main()使用WindowListener事件傾聽者,這個介面一共有7個方法,但是我們只實作windowClosing()一個方法,如下所示: app.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent evt) { System.exit(0); } }); 2019/1/12 21 21
動動手時間(1) 將範例1的程式自己輸入一次, 並且編譯及執行
事件的傳送 元件加入傾聽者是使用add???Listener()方法,???表示某種型態的事件。 元件解除和傾聽者之間的關係,不再將發生的事件傳給傾聽者,使用remove???Listener()方法。 一個事件來源可以將事件傳送給多個傾聽者,而多個不同來源的事件也可以傳送給單一個傾聽者。 2019/1/12
傾聽者的介面 容器的傾聽者介面 所有容器的傾聽者介面 傾聽者方法 ContainerListener componentAdded() componentRemoved() 2019/1/12
所有元件的傾聽者介面 傾聽者方法 ComponentListener componentResized() componentMoved() componentShown() componentHidden() FocusListener focusGained() focusLost() KeyListener keyTyped() keyPressed() keyRelease() MouseListener mouseClicked() mousePressed() mouseReleased() mouseEntered() mouseExited() MouseMotionListener (與MouseListener傾聽相同的事件MouseEvent) mouseDragged() mouseMoved 2019/1/12
adjustmentValueChanged() ScrollBar 傾聽者介面 傾聽者方法 事件來源元件 ActionListener actionPerformed() Button List TextField AdjustmentListener adjustmentValueChanged() ScrollBar ItemListener itemStateChanged() CheckBox Choice TextListener textValueChanged () TextArea WindowListener windowActivated() windowClosed() windowClosing() windowDeactivated() windowDeiconified() windowIconified() windowOpened() Frame Dialog 2019/1/12