楊玲 201771010133《面向物件程式設計(java)》第十三週學習總結
《面向物件程式設計(java)》第十三週學習總結
第一部分:理論知識學習部分
1、事件源(event source):能夠產生事件的物件都可 以成為事件源,如文字框、按鈕等。一個事件源是一個 能夠註冊監聽器並向監聽器傳送事件物件的物件。
事件監聽器(event listener):事件監聽器物件接 收事件源傳送的通告(事件物件),並對發生的事件作 出響應。一個監聽器物件就是一個實現了專門監聽器接 口的類例項,該類必須實現介面中的方法,這些方法當 事件發生時,被自動執行。
2、事件物件(event object):Java將事件的相關資訊 封裝在一個事件物件中,所有的事件物件都最終派生於 java.util.EventObject類。不同的事件源可以產生不 同類別的事件
AWT事件處理機制的概要:
3、監聽器物件:是一個實現了特定監聽器介面( listener interface)的類例項。
4、事件源:是一個能夠註冊監聽器物件併發送事件對 象的物件。
5、當事件發生時,事件源將事件物件自動傳遞給所 有註冊的監聽器。
6、監聽器物件利用事件物件中的資訊決定如何對事 件做出響應。
GUI設計中,程式設計師需要對元件的某種事件進行響應和處理時,必須完成兩個步驟:
1) 定義實現某事件監聽器介面的事件監聽器類,並具體化介面中宣告的事件處理抽象方法。
2) 為元件註冊實現了規定介面的事件監聽器物件;
7、註冊監聽器方法 eventSourceObject.addEventListener(eventListenerObject)
8、下面是監聽器的一個示例: ActionListener listener = …;
JButton button=new JButton(“Ok”); button.addActionListener(listener);
9、動作事件(ActionEvent):當特定元件動作(點 擊按鈕)發生時,該元件生成此動作事件。
10、該 事 件 被 傳 遞 給 組 件 注 冊 的 每 一 個 ActionListener 物件, 並 調 用 監 聽 器 對 象 的 actionPerformed方法以接收這類事件物件。
11、能夠觸發動作事件的動作,主要包括:
(1) 點選按鈕
(2) 雙擊一個列表中的選項;
(3) 選擇選單項;
(4) 在文字框中輸入回車。
第二部分:實驗部分
1.實驗名稱:實驗十三 圖形介面事件處理技術
2. 實驗目的:
(1) 掌握事件處理的基本原理,理解其用途;
(2) 掌握AWT事件模型的工作機制;
(3) 掌握事件處理的基本程式設計模型;
(4) 瞭解GUI介面元件觀感設定方法;
(5) 掌握WindowAdapter類、AbstractAction類的用法;
(6) 掌握GUI程式中滑鼠事件處理技術。
3.實驗內容和步驟
實驗1: 匯入第11章示例程式,測試程式並進行程式碼註釋。
測試程式1:
l 在elipse IDE中除錯執行教材443頁-444頁程式11-1,結合程式執行結果理解程式;
執行結果如下:
l 在事件處理相關程式碼處添加註釋;
1 import java.awt.*; 2 import java.awt.event.*; 3 import javax.swing.*; 4 5 /** 6 * A frame with a button panel 7 */ 8 public class ButtonFrame extends JFrame { 9 private JPanel buttonPanel; 10 private static final int DEFAULT_WIDTH = 300; 11 private static final int DEFAULT_HEIGHT = 200; 12 13 public ButtonFrame() { 14 setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); 15 16 // create buttons 17 JButton yellowButton = new JButton("Yellow"); 18 JButton blueButton = new JButton("Blue"); 19 JButton redButton = new JButton("Red"); 20 21 // 生成三個按鈕物件 22 buttonPanel = new JPanel(); 23 24 // add buttons to panel 25 buttonPanel.add(yellowButton); 26 buttonPanel.add(blueButton); 27 buttonPanel.add(redButton); 28 // 用add方法新增三個按鈕元件(只有容器元件有add方法) 29 // add panel to frame 30 add(buttonPanel); 31 32 // create button actions 33 34 ColorAction yellowAction = new ColorAction(Color.YELLOW); ColorAction 35 blueAction = new ColorAction(Color.BLUE); ColorAction redAction = new 36 ColorAction(Color.RED); 37 38 // 生成三個類物件ColorAction,顏色值為靜態常量值 39 // associate actions with buttons 40 41 yellowButton.addActionListener(yellowAction); 42 blueButton.addActionListener(blueAction); 43 redButton.addActionListener(redAction); 44 } 45 46 /** 47 * An action listener that sets the panel's background color. 48 */ 49 private class ColorAction implements ActionListener 50 // 定義一個私有類,監聽器類物件(ColorAction) 51 { 52 private Color backgroundColor; 53 54 public ColorAction(Color c) { 55 backgroundColor = c; 56 } 57 58 public void actionPerformed(ActionEvent event) 59 // 60 { 61 buttonPanel.setBackground(backgroundColor); 62 } 63 } 64 }
1 import java.awt.*; 2 import javax.swing.*; 3 4 /** 5 * @version 1.34 2015-06-12 6 * @author Cay Horstmann 7 */ 8 public class ButtonTest 9 { 10 public static void main(String[] args) 11 { 12 EventQueue.invokeLater(() -> { 13 JFrame frame = new ButtonFrame(); 14 frame.setTitle("ButtonTest");// 15 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 16 frame.setVisible(true); 17 }); 18 } 19 }
l 用lambda表示式簡化程式;
1 import java.awt.*; 2 import java.awt.event.*; 3 import javax.swing.*; 4 5 /** 6 * A frame with a button panel 7 */ 8 public class ButtonFrame extends JFrame { 9 private JPanel buttonPanel; 10 private static final int DEFAULT_WIDTH = 300; 11 private static final int DEFAULT_HEIGHT = 200; 12 13 public ButtonFrame() { 14 setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); 15 16 buttonPanel = new JPanel(); 17 18 add(buttonPanel); 19 20 makeButton("yellow",Color.YELLOW); 21 makeButton("blue",Color.BLUE); 22 makeButton("red", Color.RED); 23 makeButton("green", Color.GREEN); 24 25 } 26 27 public void makeButton(String name, Color backgroudColor) { 28 JButton button = new JButton(name); 29 buttonPanel.add(button); 30 ColorAction action = new ColorAction(backgroudColor); 31 button.addActionListener(action); 32 } 33 34 /** 35 * An action listener that sets the panel's background color. 36 */ 37 private class ColorAction implements ActionListener 38 // 定義一個私有類,監聽器類物件(ColorAction) 39 { 40 private Color backgroundColor; 41 42 public ColorAction(Color c) { 43 backgroundColor = c; 44 } 45 46 public void actionPerformed(ActionEvent event) 47 // 48 { 49 buttonPanel.setBackground(backgroundColor); 50 } 51 } 52 }
l 掌握JButton元件的基本API;
l 掌握Java中事件處理的基本程式設計模型。
測試程式2:
l 在elipse IDE中除錯執行教材449頁程式11-2,結合程式執行結果理解程式;
l 在元件觀感設定程式碼處添加註釋;
l 瞭解GUI程式中觀感的設定方法。
1 import javax.swing.JButton; 2 import javax.swing.JFrame; 3 import javax.swing.JPanel; 4 import javax.swing.SwingUtilities; 5 import javax.swing.UIManager; 6 7 /** 8 * A frame with a button panel for changing look-and-feel 9 */ 10 public class PlafFrame extends JFrame 11 { 12 private JPanel buttonPanel; 13 14 public PlafFrame() 15 { 16 buttonPanel = new JPanel(); 17 18 UIManager.LookAndFeelInfo[] infos = UIManager.getInstalledLookAndFeels(); 19 //獲得一個用於描述已安裝的觀感實現的物件陣列 20 for (UIManager.LookAndFeelInfo info : infos) 21 makeButton(info.getName(), info.getClassName()); 22 //返回觀感的顯示名稱 返回觀感的實現類的名稱 23 add(buttonPanel); 24 pack(); 25 } 26 27 /** 28 * Makes a button to change the pluggable look-and-feel. 29 * @param name the button name 30 * @param className the name of the look-and-feel class 31 */ 32 private void makeButton(String name, String className) 33 { 34 // add button to panel 35 36 JButton button = new JButton(name); 37 buttonPanel.add(button); 38 39 // set button action 40 41 button.addActionListener(event -> { 42 // button action: switch to the new look-and-feel 43 try 44 { 45 UIManager.setLookAndFeel(className); 46 //利用給定的類名設定當前的觀感 47 SwingUtilities.updateComponentTreeUI(this); 48 pack(); 49 } 50 catch (Exception e) 51 { 52 e.printStackTrace(); 53 } 54 }); 55 } 56 }
1 import java.awt.*; 2 import javax.swing.*; 3 4 /** 5 * @version 1.32 2015-06-12 6 * @author Cay Horstmann 7 */ 8 public class PlafTest 9 { 10 public static void main(String[] args) 11 { 12 EventQueue.invokeLater(() -> { 13 JFrame frame = new PlafFrame(); 14 frame.setTitle("PlafTest"); 15 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 16 frame.setVisible(true); 17 }); 18 } 19 }
執行結果如下:
測試程式3:
l 在elipse IDE中除錯執行教材457頁-458頁程式11-3,結合程式執行結果理解程式;
l 掌握AbstractAction類及其動作物件;
l 掌握GUI程式中按鈕、鍵盤動作對映到動作物件的方法。
1 import java.awt.*; 2 import java.awt.event.*; 3 import javax.swing.*; 4 5 /** 6 * A frame with a panel that demonstrates color change actions. 7 */ 8 public class ActionFrame extends JFrame 9 { 10 private JPanel buttonPanel; 11 private static final int DEFAULT_WIDTH = 300; 12 private static final int DEFAULT_HEIGHT = 200; 13 14 public ActionFrame() 15 { 16 setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); 17 18 buttonPanel = new JPanel(); 19 20 // define actions 21 Action yellowAction = new ColorAction("Yellow", new ImageIcon("yellow-ball.gif"), 22 Color.YELLOW); 23 Action blueAction = new ColorAction("Blue", new ImageIcon("blue-ball.gif"), Color.BLUE); 24 Action redAction = new ColorAction("Red", new ImageIcon("red-ball.gif"), Color.RED); 25 26 // add buttons for these actions 27 buttonPanel.add(new JButton(yellowAction)); 28 buttonPanel.add(new JButton(blueAction)); 29 buttonPanel.add(new JButton(redAction)); 30 31 // add panel to frame 32 add(buttonPanel); 33 34 // associate the Y, B, and R keys with names 35 InputMap imap = buttonPanel.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); 36 //獲得將按鍵對映到動作鍵的輸入對映 37 imap.put(KeyStroke.getKeyStroke("ctrl Y"), "panel.yellow"); 38 imap.put(KeyStroke.getKeyStroke("ctrl B"), "panel.blue"); 39 imap.put(KeyStroke.getKeyStroke("ctrl R"), "panel.red"); 40 //根據一個便於人們閱讀的說明建立一個按鍵(由空格分隔的字串序列) 41 // associate the names with actions 42 ActionMap amap = buttonPanel.getActionMap(); 43 //返回關聯動作對映鍵(可以是任意的物件)和動作物件的對映 44 amap.put("panel.yellow", yellowAction); 45 amap.put("panel.blue", blueAction); 46 amap.put("panel.red", redAction); 47 } 48 49 public class ColorAction extends AbstractAction 50 { 51 /** 52 * Constructs a color action. 53 * @param name the name to show on the button 54 * @param icon the icon to display on the button 55 * @param c the background color 56 */ 57 public ColorAction(String name, Icon icon, Color c) 58 { 59 putValue(Action.NAME, name); 60 putValue(Action.SMALL_ICON, icon); 61 putValue(Action.SHORT_DESCRIPTION, "Set panel color to " + name.toLowerCase()); 62 putValue("color", c); 63 //將名/值對放置在動作物件前 64 } 65 66 public void actionPerformed(ActionEvent event) 67 { 68 Color c = (Color) getValue("color"); 69 //返回被儲存的名/值對的值 70 buttonPanel.setBackground(c); 71 } 72 } 73 }
1 import java.awt.*; 2 import javax.swing.*; 3 4 /** 5 * @version 1.34 2015-06-12 6 * @author Cay Horstmann 7 */ 8 public class ActionTest 9 { 10 public static void main(String[] args) 11 { 12 EventQueue.invokeLater(() -> { 13 JFrame frame = new ActionFrame(); 14 frame.setTitle("ActionTest"); 15 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 16 frame.setVisible(true); 17 }); 18 } 19 }
執行結果如下:
測試程式4:
l 在elipse IDE中除錯執行教材462頁程式11-4、11-5,結合程式執行結果理解程式;
l 掌握GUI程式中滑鼠事件處理技術。
1 import java.awt.*; 2 import java.awt.event.*; 3 import java.awt.geom.*; 4 import java.util.*; 5 import javax.swing.*; 6 7 /** 8 * A component with mouse operations for adding and removing squares. 9 */ 10 public class MouseComponent extends JComponent 11 { 12 private static final int DEFAULT_WIDTH = 300; 13 private static final int DEFAULT_HEIGHT = 200; 14 15 private static final int SIDELENGTH = 10; 16 private ArrayList<Rectangle2D> squares; 17 private Rectangle2D current; // the square containing the mouse cursor 18 19 public MouseComponent() 20 { 21 squares = new ArrayList<>(); 22 current = null; 23 24 addMouseListener(new MouseHandler()); 25 addMouseMotionListener(new MouseMotionHandler()); 26 } 27 28 public Dimension getPreferredSize() { return new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT); } 29 30 public void paintComponent(Graphics g) 31 { 32 Graphics2D g2 = (Graphics2D) g; 33 34 // draw all squares 35 for (Rectangle2D r : squares) 36 g2.draw(r); 37 } 38 39 /** 40 * Finds the first square containing a point. 41 * @param p a point 42 * @return the first square that contains p 43 */ 44 public Rectangle2D find(Point2D p) 45 { 46 for (Rectangle2D r : squares) 47 { 48 if (r.contains(p)) return r; 49 } 50 return null; 51 } 52 53 /** 54 * Adds a square to the collection. 55 * @param p the center of the square 56 */ 57 public void add(Point2D p) 58 { 59 double x = p.getX(); 60 double y = p.getY(); 61 62 current = new Rectangle2D.Double(x - SIDELENGTH / 2, y - SIDELENGTH / 2, SIDELENGTH, 63 SIDELENGTH); 64 squares.add(current); 65 repaint(); 66 } 67 68 /** 69 * Removes a square from the collection. 70 * @param s the square to remove 71 */ 72 public void remove(Rectangle2D s) 73 { 74 if (s == null) return; 75 if (s == current) current = null; 76 squares.remove(s); 77 repaint(); 78 } 79 80 private class MouseHandler extends MouseAdapter 81 { 82 public void mousePressed(MouseEvent event) 83 { 84 // add a new square if the cursor isn't inside a square 85 current = find(event.getPoint()); 86 //返回事件發生時,事件源元件左上角的座標x和y,或點的資訊 87 if (current == null) add(event.getPoint()); 88 } 89 90 public void mouseClicked(MouseEvent event) 91 { 92 // remove the current square if double clicked 93 current = find(event.getPoint()); 94 if (current != null && event.getClickCount() >= 2) remove(current); 95 //返回與事件關聯的滑鼠連擊次數 96 } 97 } 98 99 private class MouseMotionHandler implements MouseMotionListener 100 { 101 public void mouseMoved(MouseEvent event) 102 { 103 // set the mouse cursor to cross hairs if it is inside 104 // a rectangle 105 106 if (find(event.getPoint()) == null) setCursor(Cursor.getDefaultCursor()); 107 else setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR)); 108 } 109 110 public void mouseDragged(MouseEvent event) 111 { 112 if (current != null) 113 { 114 int x = event.getX(); 115 int y = event.getY(); 116 117 // drag the current rectangle to center it at (x, y) 118 current.setFrame(x - SIDELENGTH / 2, y - SIDELENGTH / 2, SIDELENGTH, SIDELENGTH); 119 repaint(); 120 } 121 } 122 } 123 }
1 import javax.swing.*; 2 3 /** 4 * A frame containing a panel for testing mouse operations 5 */ 6 public class MouseFrame extends JFrame 7 { 8 public MouseFrame() 9 { 10 add(new MouseComponent()); 11 pack(); 12 } 13 }
1 import java.awt.*; 2 import javax.swing.*; 3 4 /** 5 * @version 1.34 2015-06-12 6 * @author Cay Horstmann 7 */ 8 public class MouseTest 9 { 10 public static void main(String[] args) 11 { 12 EventQueue.invokeLater(() -> { 13 JFrame frame = new MouseFrame(); 14 frame.setTitle("MouseTest"); 15 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 16 frame.setVisible(true); 17 }); 18 } 19 }
執行結果如下:
實驗2:結對程式設計練習
利用班級名單檔案、文字框和按鈕元件,設計一個有如下介面(圖1)的點名器,要求使用者點選開始按鈕後在文字輸入框隨機顯示2017級網路與資訊安全班同學姓名,如圖2所示,點選停止按鈕後,文字輸入框不再變換同學姓名,此同學則是被點到的同學姓名。
圖1 點名器啟動介面
圖2 點名器點名介面
程式碼編寫如下:
1 import java.awt.BorderLayout; 2 import java.awt.Color; 3 import java.awt.Container; 4 import java.awt.event.ActionEvent; 5 import java.awt.event.ActionListener; 6 import java.util.Random; 7 import javax.swing.JButton; 8 import javax.swing.JFrame; 9 import javax.swing.JLabel; 10 import javax.swing.SwingConstants; 11 public class RollCall { 12 JFrame rFrame=new JFrame("隨機點名器"); 13 String[] stuName={"王之泰","王穎奇","蘇浪浪","王斌龍","馬興德","汪慧和","王豔","馮志霞","王志成","張雲飛","王海珍","楊野","張燕","唐月晨","李瑞紅","李婷華","趙棟","張季躍","孔維瀅","窮吉","狄慧","達拉草","楊其菊","馬凱軍","陳亞茹","常惠琢","馬昕璐", "王玉蘭", "白瑪次仁", "王瑜", "楊蓉慶", "劉志梅", "周強","李清華","李曉菁","徐思","鄒豐蔚","羅鬆","楊玲","王燕","韓臘梅", "東文財", "焦旭超"}; 14 JLabel name = new JLabel(); 15 JButton btn = new JButton("開始點名"); 16 Random rd = new Random(); 17 public void init() { 18 JLabel jt= new JLabel("隨機點名器"); //設定標籤居中 19 jt.setHorizontalAlignment(SwingConstants.CENTER); //設定字型大小 20 jt.setFont(new java.awt.Font("隨機點名器",1,35)); //設定名字顯示的標籤居中 21 name.setHorizontalAlignment(SwingConstants.CENTER); //通過匿名類實現Action按鈕的監聽事件 22 btn.addActionListener(new ActionListener() { 23 24 public void actionPerformed(ActionEvent e) { 25 String a=getRandomName(); 26 //設定name標籤的文字 27 name.setText(a); 28 //設定字型 29 name.setFont(new java.awt.Font(a,2,28)); 30 //設定字型顏色 31 name.setForeground(Color.green); 32 } 33 }); 34 //獲取JFrame的面板 35 Container p = this.rFrame.getContentPane(); 36 //設定佈局方式,我採用的BorderLayout佈局 37 p.setLayout(new BorderLayout(3,1)); 38 p.add(jt,BorderLayout.NORTH); 39 //新增姓名標籤在中央 40 p.add(name,BorderLayout.CENTER); 41 p.add(btn,BorderLayout.SOUTH); 42 rFrame.pack(); //設定窗體大小 43 rFrame.setSize(250, 250); 44 //設定可以顯示 45 rFrame.setVisible(true); 46 } 47 //獲取隨機的姓名 48 public String getRandomName() { 49 int a = 0; 50 a = rd.nextInt(stuName.length); 51 return stuName[a]; 52 } 53 public static void main(String[] args) { 54 RollCall rn=new RollCall(); 55 rn.init(); 56 } 57 }
執行結果如下:
4. 實驗總結:
通過本次實驗我掌握了事件處理的基本原理,理解了其用途;掌握了AWT事件模型的工作機制;掌握了事件處理的基本程式設計模型;瞭解了GUI介面元件觀感設定方法;也掌握了WindowAdapter類、AbstractAction類的用法;還掌握了GUI程式中滑鼠事件處理技術。