400 likes | 515 Views
驅動事件 , 委託事件. 所謂 被驅動物件 ,是程式完成初值設定之後, 不斷的等待使用者觸發的物件 ,觸發的來源包羅萬象,有可能滑鼠被按一下、有可能輸入值已改變、有可能鍵盤被按一下等事件。 所謂 受委託事件 就是 被驅動物件 將整個事件 (event) 處理的責任委託 (delegation) 給特定的物件,當 被驅動物件 發生指定的事件時,就通知所委託的物件,由這個物件來處理這個事件。. 怎麼 委託 ?. 用 addActionListener() method 來達成. btn.addActionListener(frm). 事件 驅動. 受委託事件.
E N D
驅動事件,委託事件 所謂被驅動物件,是程式完成初值設定之後,不斷的等待使用者觸發的物件,觸發的來源包羅萬象,有可能滑鼠被按一下、有可能輸入值已改變、有可能鍵盤被按一下等事件。 所謂受委託事件就是被驅動物件將整個事件(event)處理的責任委託(delegation)給特定的物件,當被驅動物件發生指定的事件時,就通知所委託的物件,由這個物件來處理這個事件。
怎麼委託? • 用addActionListener() method 來達成 btn.addActionListener(frm) 事件驅動 受委託事件
AWTEvent • AWTEvent 的類別是所有事件的超級類別 (super class),其繼承關係如右圖所示
ActionEvent 類別 • 動作事件類別 ActionEvent 是第一個高階的事件類別,當使用者選了1. (Button)按鈕元件、2. (List)表列資料項、3. (MenuItem)功能表資 料項、或4.輸入本文欄 (TextField)時按下 Enter 鍵,動作事件就在事件佇列找尋登記有案的動作事件傾聽物件來 處理。
XFrame.java import java.awt.*; import java.awt.event.*; class XFrame implements ActionListener { Frame frm =new Frame( "Action Event"); Button btn=new Button("Click Me"); public XFrame() { frm.setLayout(new FlowLayout()); frm.setSize(200,150); frm.add(btn); btn.addActionListener(this); frm.setVisible(true); } public void actionPerformed(ActionEvent e) { frm.setBackground(Color.yellow); } public static void main(String args[]) { new XFrame(); } }
設計一個Button元件的傾聽類別 import java.awt.*; import java.awt.event.*; class XFrame1 implements ActionListener { Frame frm =new Frame("ButtonEvent.java:按鈕事件測試"); TextArea ta= new TextArea(2,20); Button bt =new Button("Click Me"); int clickCount=0; public XFrame1() { frm.setLayout(new FlowLayout()); frm.setSize(300,120); frm.add(ta); frm.add(bt); bt.addActionListener(this); frm.setVisible(true); } public void actionPerformed(ActionEvent e) { clickCount++; ta.setText("您按Click Me鈕 " + clickCount + " 次"); } public static void main(String args[]) { new XFrame1(); } }
聽取事件來源 getSource()(方法1:被觸動的個別元件與處理事件的受委託者屬同類別) import java.awt.*; import java.awt.event.*; class FrmLis implements ActionListener { Frame frm =new Frame("Action Even"); Button b1=new Button("Yellow"); Button b2=new Button("Green"); Button b3=new Button("Exit"); public FrmLis() { b1.addActionListener(this); // 事件傾聽者向b1註冊 b2.addActionListener(this); // 事件傾聽者向b2註冊 b3.addActionListener(this); // 事件傾聽者向b3註冊 frm.setLayout(new FlowLayout(FlowLayout.CENTER)); frm.setSize(200,150); frm.add(b1); frm.add(b2); frm.add(b3); frm.setVisible(true); } public void actionPerformed(ActionEvent e) { Button btn=(Button) e.getSource(); // 取得事件來源物件 if(btn==b1) frm.setBackground(Color.yellow); // 如果是按下btn1按鈕 else if(btn==b2) frm.setBackground(Color.green);// 如果是按下btn2按鈕 else System.exit(0); // 如果是按下btn3按鈕 } public static void main(String args[]) { FrmLis lsn=new FrmLis(); } }
作業一(變色):用方法2寫一XFrame2 類別如下 • 變色Button: 紅Color.red -> 黃Color.yellow-> 綠Color.green-> 藍Color.blue-> • TextArea: 顯示變色Button被按幾次 • 結束Button: 結束程式 Button 變色 結束 Frame TextArea
ItemEvent 類別 • ItemEvent(項目事件) 一些物件會提供給使用者選項做選擇,例如像Choice,List,Checkbox,CheckboxMenuItem等,我們可以把事件委任給itemListener來處理: public interface itemListener extends EventListener { public void itemStateChanged(ItemEvent e); }
ItemListener import java.awt.*; import java.awt.event.*; class FrmLis implements ItemListener { Frame frm=new Frame("Item Event"); Checkbox ckb1=new Checkbox("Epson 5900L"); Checkbox ckb2=new Checkbox("HP LaserJet 4p");; Label lab=new Label(" Select a printer "); public FrmLis() { CheckboxGroup grp=new CheckboxGroup(); frm.setLayout(new FlowLayout(FlowLayout.LEFT)); ckb1.setCheckboxGroup(grp); // 將ckb1設為單選 ckb2.setCheckboxGroup(grp); // 將ckb2設為單選 lab.setBackground(Color.orange); ckb1.addItemListener(this); // 讓frm當成ckb1的傾聽者 ckb2.addItemListener(this); // 讓frm當成ckb2的傾聽者 frm.add(lab); frm.add(ckb1); frm.add(ckb2); frm.setSize(200,150); frm.setVisible(true); } public void itemStateChanged(ItemEvent e)//ItemEvent發生時的處理動作 { if(ckb1.getState()==true) // 如果是ckb1被選擇 lab.setText(" Epson 5900L"); else if(ckb2.getState()==true) // 如果是ckb2被選擇 lab.setText(" HP LaserJet 4p"); } public static void main(String args[]) { new FrmLis(); } }
作業二(換顏色) • .把作業一的Button 換顏色的功能, 1.改成以4個 CheckBox 物件 讓使用者選擇 Frame 的底色. o Green o Red o blue o yellow
作業(四則運算) • 此作業的程式功能執行如下:可將填入兩文字欄(TextField)中的數字,藉由選取的四則運算(+-*/)或%(餘數運算)符號以決定其運算,最後按下「等於」的按鈕(button),則結果出現在第三個文字欄內。
作業(方陣) 請寫一個程式,完成以下功能: • 可於螢幕顯示以下畫面。 • 按空白按鍵旁的按鍵 可使空白按鍵與此按鍵互換位置
TextEvent (文字事件)類別 文字事件是在TextField或是TextArea中的文字有所變動的時候所產生的,我們可以把TextEvent委任給TextListener來處理: public interface TextListener extends EventListener { public void textValueChanged(TextEvent e); } TextField 或 TextArea 元件本文內容改變,不管您是輸入資料或使用 setText()、append() 方法,都會觸發 TextEvent 事件。 事件觸發時會透過事件佇列找尋登記有案的傾聽物件來處理。
TextEvent的使用範例XFrame4.class import java.awt.*; import java.awt.event.*; public class XFrame4 implements TextListener, ActionListener { Frame frm=new Frame("Text Event"); TextField tf=new TextField(" "); TextArea txa1=new TextArea("",6,10,TextArea.SCROLLBARS_NONE); Button btn=new Button("加入"); public XFrame4() { frm.setLayout(new FlowLayout(FlowLayout.CENTER)); tf.addTextListener(this); btn.addActionListener(this); frm.add(btn); frm.add(tf); frm.add(txa1); frm.setSize(200,200); frm.setVisible(true); } // 當txa1元件裡的文字改變時,執行下列的程式碼 public void textValueChanged(TextEvent e) { frm.setTitle(tf.getText()); } public void actionPerformed(ActionEvent e) { txa1.append(tf.getText()); } public static void main(String args[]) { new XFrame4(); } }
作業: 判斷身份證正確與否 • 將第八章中判斷身份證正確與否的程式以TextField 輸入以TextListener頃聽, 再以LABEL 顯示正確與否 public interface TextListener extends EventListener { public void textValueChanged(TextEvent e); }
特獎號碼 請輸入發票號碼 頭獎號碼 作業:統一發票對獎 先輸入1個特獎號碼, 3個頭獎號碼 再輸入發票號碼(號碼由右至左輸入) 對獎
KeyEvent鍵盤事件 KeyEvent是發生在當使用者按了鍵盤上的的按鍵或是放開鍵盤上的按鍵時候所發生的,按鍵事件我們可以把事件委任給KeyListener介面: public interface KeyListener extends EventListener { public void KeyPressed(KeyEvent e); public void KeyReleased(KeyEvent e); public void KeyTyped(KeyEvent e); }
KeyLstn.java(KeyListener) import java.awt.*; import java.awt.event.*; class KeyLstn implements KeyListener { Frame frm= new Frame("KeyEvent.java:按鍵事件測試"); Label label=new Label("KeyEvent 測試, 請按一鍵:"); TextField textField=new TextField(20); TextArea ta=new TextArea(4,50); public KeyLstn() { frm.setLayout(new FlowLayout()); frm.add(label); frm.add(textField); frm.add(ta); frm.setSize(560,140); frm.setVisible(true); textField.addKeyListener(this); } public void keyTyped(KeyEvent e) { ta.append("keyTyped()= "+e.paramString()+"\n"); } public void keyPressed(KeyEvent e) { ta.append("keyPressed()= "+e.paramString()+"\n"); } public void keyReleased(KeyEvent e) { ta.append("keyReleased()= "+e.paramString()+"\n"); } public static void main(String args[]) { new KeyLstn(); } }
import javax.swing.*;import java.awt.event.*;import java.awt.*; public class CkeyFrame extends Frame implements KeyListener { ImageIcon icon1 = new ImageIcon("c:\\hills.jpg"); JLabel lblPic = new JLabel(icon1); int pos_x = 70, pos_y = 30; CkeyFrame() { lblPic.setBounds(pos_x, pos_y, 150, 160); add(lblPic); addKeyListener(this); setTitle("按方向鍵 移動圖形"); setLayout(null); setBounds(100, 100, 1000, 700); setVisible(true); } public void keyPressed(KeyEvent e) { switch(e.getKeyCode()) { case KeyEvent.VK_UP: // 向上 pos_y -= 5; break; case KeyEvent.VK_DOWN: // 向下 pos_y += 5; break; case KeyEvent.VK_LEFT: // 向左 pos_x -= 5; break; case KeyEvent.VK_RIGHT: // 向右 pos_x += 5; break; } lblPic.setLocation(pos_x, pos_y); } public void keyTyped(KeyEvent e) {} public void keyReleased(KeyEvent e) {} public static void main(String[] aegs) { new CkeyFrame(); } }
鬧鈴數字鐘 • 將數字鐘加上以下的功能1.可以用TextField 設定新時間2.可以用TextField設定數個鬧鈴時間3.可以用TextField設定每個鬧鈴時間到時要顯示的訊息 4.鬧鈴時間到時要改變Frame的顏色(白->紅)且顯示訊息 5.可以停止改變Frame的顏色 現在日期時間 鬧鈴日期時間 啟動 Message
(TextListener)1.加總 2.溫度轉換 從 到 的總和 1. 攝氏 華氏 2.
MouseEvent 類別 滑鼠事件是當我們移動了滑鼠或是按下了滑鼠上面的按鈕又或者釋放開了滑鼠上面的按鈕所產生的事件,我們可以把滑鼠事件委任給MouseListener介面: public interface MouseListener extends EventListener { public void mouseClicked(MouseEvent e); public void mouseEntered(MouseEvent e); public void mouseExited(MouseEvent e); public void mousePressed(MouseEvent e); public void mouseReleased(MouseEvent e); } • 滑鼠事件發生之後,較常使用的參數是滑鼠被按的次數以及滑鼠的座標(x,y) 。
void mouseEntered (MouseEvent e) • void mouseExit (MouseEvent e) • 當滑鼠進入或離開某一元件,產生以上事件。 • void mouseClicked (MouseEvent e) • void mousePressed (MouseEvent e) • void mouseReleased (MouseEvent e) • 當滑鼠按鍵被按一下或釋放時,產生以上事件。 • void mouseMoved (MouseEvent e) • 當滑鼠移動且按鍵未被按時,產生此事件。 • void mouseDragged (MouseEvent e) • 當滑鼠移動且按鍵被按時,產生此拖曳(Dragged)事件。 • 以下是滑鼠事件的常用方法。 • int getClickCount() • 傳回滑鼠被按的次數。
point getPoint() • 傳回相對於作用元件的(x,y)座標,傳回的類別為Point。。 • int getx() • 傳回相對於作用元件的x座標。 • int gety() • 傳回相對於作用元件的y座標。 • boolean isAltDown() • 傳回滑鼠事件產生的同時,是否也按下鍵盤Alt鍵。 • boolean isControlDown() • 傳回滑鼠事件產生的同時,是否也按下鍵盤Ctrl鍵。 • boolean isMetaDown() • 傳回滑鼠事件產生的同時,是否也按下滑鼠右鍵。 • boolean isShiftDown() • 傳回滑鼠事件產生的同時,是否也按下鍵盤Shift鍵。
MouseClickEvent(XFrame6.java) import java.awt.*; import java.awt.event.*; class XFrame6 implements MouseListener { Frame frm=new Frame("滑鼠按下等事件測試"); Label label= new Label(" "); public XFrame6() { frm.setLayout(new FlowLayout()); frm.add(label); frm.addMouseListener(this); frm.setSize(420, 100); frm.setVisible(true); } public void mouseClicked(MouseEvent e) { label.setText("Clicked at ["+e.getX()+", "+e.getY()+"]" );} public void mousePressed(MouseEvent e) { label.setText("Pressed at ["+e.getX()+", "+e.getY()+"]");} public void mouseReleased(MouseEvent e) { label.setText("Released at ["+e.getX()+", "+e.getY()+"]");} public void mouseEntered(MouseEvent e) { label.setText("Mouse in window"); } public void mouseExited(MouseEvent e) { label.setText("Mouse outside window"); } public static void main(String args[]) { new XFrame6(); } }
import javax.swing.*; import java.awt.event.*; import java.awt.*; class CMouseFrame extends Frame { ImageIcon icon1 = new ImageIcon("c://hills.jpg"); ImageIcon icon2 = new ImageIcon("c://Sun.jpg"); JLabel lblPic = new JLabel(icon1); int pos_x = 70, pos_y = 30; CMouseFrame() { lblPic.addMouseListener(new ClblPic()); lblPic.setBounds(pos_x, pos_y, 150, 160); add(lblPic); setTitle("點按滑鼠 切換圖形"); setBounds(100,100,300,250); setVisible(true); } class ClblPic implements MouseListener { public void mouseClicked(MouseEvent e) { if (lblPic.getIcon() == icon1) lblPic.setIcon(icon2); else lblPic.setIcon(icon1); } public void mousePressed(MouseEvent e) {} public void mouseReleased(MouseEvent e) {} public void mouseEntered(MouseEvent e) {} public void mouseExited(MouseEvent e) {} } public static void main(String[] aegs) { CMouseFrame frame = new CMouseFrame(); } }
MouseMotion類別常用的方法 在滑鼠移動的時候的我們可以委託給MouseMotionListener public interface MouseMotionListener extends EventListener { public void mouseDragged(MouseEvent e); public void mouseMoved(MouseEvent e); } • public int getX() 傳回水平座標。 • public int getY() 傳回垂直座標。 • public Point getPoint() 傳回點座標。 • public synchronized void translatePoint(int x,int y) 將本物件的水平座標以 x 取代,垂直座標以 y 取代。 • public int getClickCount() 傳回按鍵計數。 • public boolean isPopupTrigger() 傳回是否有突現式功能表,true 表有,false 表無。 • public String paramString() 傳回參數字串。
WindowEvent 類別 • 因視窗的開啟、正關閉、已關閉、圖示化、從圖示化還原 、操作中、閒置中 等動作所觸發的事件, • 使用 getWindow() 方法可取得發生事件的視窗。 WindowEvent 類別常用的方法說明如下: • public Window getWindow() 傳回視窗物件。 • public String paramString() 傳回參數字串。
視窗元件可 觸發下列 • 視窗元件可觸發下列事件: WINDOW_OPENED開啟 WINDOW_CLOSING正關閉 WINDOW_CLOSED已關閉 WINDOW_ICONIFIED圖示化WINDOW_DEICONIFIED從圖示化還原 WINDOW_ACTIVATED操作中 WINDOW_DEACTIVATED閒置 • Java 已經事先設計好一個 WindowAdapter 類別實做了這七 個事件的處理方法,您若只想處理其中的一個事件,例如 WINDOW_CLOSING,您只須設計一個事件傾聽類別繼承 WindowAdapter 類別,只實作其中的 windowClosing() 方法就 可以了,另外六個您就不用理會了。
WindowEventHandler(XFrame7.java) import java.awt.*; import java.awt.event.*; class XFrame7 implements WindowListener { Frame f =new Frame("WindowEventTest"); public XFrame7() { f.setSize(200,200); f.addWindowListener(this); f.setVisible(true); } public void windowClosing(WindowEvent e) { System.out.println("Window Closing event"); System.exit(0); } public void windowIconified(WindowEvent e) { System.out.println("Window Iconified event");} public void windowActivated(WindowEvent e) { System.out.println("Window Activated event"); } public void windowOpened(WindowEvent e) { } public void windowDeiconified(WindowEvent e) { } public void windowClosed(WindowEvent e) { } public void windowDeactivated(WindowEvent e) { } public static void main(String argv[]) { new XFrame7(); } }
XFrame7.java 【說明】 • 程式 中關閉視窗的動作事件 (按視窗右上角 關閉鈕所發生的事件) 委託給 MyWindowListener 事件的傾聽物件去處理,該傾聽物件繼承 WindowAdaptor 類別,使用 windowClosing() 方法,關閉 FrameEvent 所使用的框視窗。如此就將應用程式的 GUI 介面,如 FrameEvent,與事件處理 MyWindowListener 分開處理。 • 當您按視窗右上角的關閉鈕時,觸發一個關閉視窗事件 WINDOW_CLOSING,啟動 MyWindowListener 物件的 windowClosing() 方法,為什麼會啟動 MyWindowListener 這個物件呢?因為您在 FrameEvent.java 程式裡已經 使用 addWindowListener() 方法登記關閉視窗的事件要委託 MyWindowListener 物件處理了。這個事件傾聽物件就是 new MyWindowListener() 本例中 windowClosing() 方法只是 單純的將應用程式結束而已。
Adapter類別 • 什麼是adapter類別?對於一個具有多個方法的Listener,都有一個adapter,這些adapter類別實作了對應的界面,提供空的方法作為介面中所定義的預設實作方式,假如我們只需要處理特定的幾個事件而已,我們可以從這些adapter繼承下來,並且加以改寫我們想要處理的部份就可以,這樣設計者就不用實作所有的介面方法了。
MouseAdapter(XFrame8.java) import java.awt.*; import java.awt.event.*; class XFrame8 extendsMouseAdapter { Frame f= new Frame("MouseEvent test"); XFrame8() { f.addMouseListener(this); f.setSize(300,200); f.setVisible(true); } public void mouseClicked(MouseEvent e)//belongs to MouseEven(1/5) { f.setTitle("Mouse clicked!"); } public void mouseExited(MouseEvent e) //belongs to MouseEven(2/5) { f.setTitle("Mouse exited!"); } public static void main(String argv[]) { new XFrame8(); } }
extends MouseAdapter implements MouseMotionListenerXFrame9.java import java.awt.*; import java.awt.event.*; public class XFrame9 extends MouseAdapter implements MouseMotionListener { Frame f= new Frame("MouseEvent test"); public XFrame9() { f.addMouseListener(this); f.addMouseMotionListener(this); f.setSize(300,200); f.setVisible(true); } public void mouseClicked(MouseEvent e) // (1/5) { f.setTitle("Mouse clicked!"); } public void mouseExited(MouseEvent e) // (2/5) { f.setTitle("Mouse exited!"); } public void mouseMoved(MouseEvent e) // (1/2) { int x = e.getX(); int y = e.getY(); f.setTitle("Mouse moved at ("+x+", "+y+")"); } public void mouseDragged(MouseEvent e) { } //(2/2) public static void main(String argv[]) { new XFrame9(); } }
(XFrameA.java)KeyAdapter import java.awt.*; import java.awt.event.*; class XFrameA extends KeyAdapter { Frame f=new Frame("Key event test"); TextArea txa; public XFrameA() { txa=new TextArea(); f.add(txa); f.setSize(400,300); txa.setSize(390,290); txa.addKeyListener(this); f.setVisible(true); } public void keyPressed(KeyEvent e) { if (e.isActionKey()) txa.append("\nActionKey is pressed..."); txa.append("\nThe KeyCode:"+e.getKeyCode()); txa.append("\nModifier text:"+ KeyEvent.getKeyModifiersText(e.getModifiers())); txa.append("\nKey text:"+KeyEvent.getKeyText(e.getKeyCode())); } public void keyTyped(KeyEvent e) { txa.append("\nSome key typed..."); txa.append("\nThe KeyChar is "+e.getKeyChar()); } public static void main(String argv[]) { new XFrameA(); } } //不需implement所有的抽象方法(only implements 2/3 abstract methods)
MouseAdapter(XFrameB.java) import java.awt.*; import java.awt.event.*; public class XFrameB extends MouseAdapter { Frame f = new Frame("MouseEvent test"); public XFrameB() { f.setSize(200,100); f.addMouseListener(this); f.setVisible(true); } public void mouseClicked(MouseEvent e) { String str=""; switch (e.getModifiers()) { case InputEvent.BUTTON1_MASK: str = "Button1"; break; case InputEvent.BUTTON3_MASK: str = "Button3"; break; case InputEvent.CTRL_MASK+InputEvent.BUTTON1_MASK: str = "Ctrl + Button1"; break; case InputEvent.SHIFT_MASK+InputEvent.BUTTON3_MASK: str = "Shift + Button3"; break; case InputEvent.ALT_MASK+InputEvent.BUTTON1_MASK: str = "Alt + Button1"; break; } f.setTitle(str); } public static void main(String argv[]) { new XFrameB(); } }
WindowAdapter import java.awt.*; import java.awt.event.*; class Win1 extends WindowAdapter { Frame frm=new Frame("Event Demo"); TextField op1Field, op2Field, resultField; Choice opChoice; Button ansButton; public Win1() { frm.setLayout(new FlowLayout()); op1Field = new TextField(6); op2Field = new TextField(6); resultField = new TextField(7); opChoice = new Choice(); opChoice.addItem("+"); opChoice.addItem("-"); opChoice.addItem("*"); opChoice.addItem("/"); ansButton = new Button("="); frm.add(op1Field); frm.add(opChoice); frm.add(op2Field); frm.add(ansButton); frm.add(resultField); frm.setSize(300,100); frm.addWindowListener(this); frm.setVisible(true); } public void windowClosing(WindowEvent we) { System.out.println("Bye!!"); System.exit(0); } }
Cont. class EventDemo extends Win1 implements ActionListener { public EventDemo() { ansButton.addActionListener(this); } public void actionPerformed(ActionEvent ae) { int op1 = Integer.parseInt(op1Field.getText()); int op2 = Integer.parseInt(op2Field.getText()); int ans = 0; switch(opChoice.getSelectedIndex()) { case 0: ans = op1 + op2; break; case 1: ans = op1 - op2; break; case 2: ans = op1 * op2; break; case 3: ans = op1 / op2; } resultField.setText(""+ans); } public static void main(String[] arg) { EventDemo(); } }