1. 程式人生 > >201771010137 趙棟 《面向物件程式設計(java)》第十三週學習總結

201771010137 趙棟 《面向物件程式設計(java)》第十三週學習總結

 

 

 

 

 

 

 

 

 

 

 

 

 

第一部分:理論知識

 第11章 事件處理(事件處理基礎; 動作; 滑鼠事件;AWT事件繼承層次)

1. 事件源(event source):能夠產生事件的物件都可 以成為事件源,如文字框、按鈕等。一個事件源是一個 能夠註冊監聽器並向監聽器傳送事件物件的物件。

2. 事件監聽器(event listener):事件監聽器物件接 收事件源傳送的通告(事件物件),並對發生的事件作 出響應。一個監聽器物件就是一個實現了專門監聽器接 口的類例項,該類必須實現介面中的方法,這些方法當 事件發生時,被自動執行。

3. 事件物件(event object):Java將事件的相關資訊 封裝在一個事件物件中,所有的事件物件都最終派生於 java.util.EventObject類。不同的事件源可以產生不 同類別的事件

4.AWT事件處理機制的概要:

(1) 監聽器物件:是一個實現了特定監聽器介面( listener interface)的類例項。

(2)事件源:是一個能夠註冊監聽器物件併發送事件對 象的物件。

(3)當事件發生時,事件源將事件物件自動傳遞給所 有註冊的監聽器。

(4) 監聽器物件利用事件物件中的資訊決定如何對事 件做出響應。

5.GUI設計中,程式設計師需要對元件的某種事件進行響應和處理時,必須完成兩個步驟:

(1) 定義實現某事件監聽器介面的事件監聽器類,並具體化介面中宣告的事件處理抽象方法。

(2) 為元件註冊實現了規定介面的事件監聽器物件;

6.註冊監聽器方法 eventSourceObject.addEventListener(eventListenerObject)

下面是監聽器的一個示例: ActionListener listener = …;

JButton button=new JButton(“Ok”); button.addActionListener(listener);

7.動作事件(ActionEvent):當特定元件動作(點 擊按鈕)發生時,該元件生成此動作事件。

(1) 該 事 件 被 傳 遞 給 組 件 注 冊 的 每 一 個 ActionListener 物件, 並 調 用 監 聽 器 對 象 的 actionPerformed方法以接收這類事件物件。

(2)能夠觸發動作事件的動作,主要包括:

      1) 點選按鈕

     2) 雙擊一個列表中的選項;

    3) 選擇選單項;

   4) 在文字框中輸入回車。

8. 監聽器介面的實現

監聽器類必須實現與事件源相對應的介面,即必須提供介面中方法的實現。

⚫ 監聽器介面方法實現

class Mylistener implements ActionListener
{
public void actionPerformed (ActionEvent event)
{ …… }
}

9.命令按鈕Jbutton主要API
a.建立按鈕物件
JButton類常用的一組構造方法:
(1) JButton(String text):建立一個帶文字的按鈕。
(2) JButton(Icon icon) :建立一個帶圖示的按鈕。
(3)JButton(String text, Icon icon) :建立一個帶文字和圖示
的按鈕。
b.按鈕物件的常用方法
① getLabel( ):返回按鈕的標籤字串;
② setLabel(String s):設定按鈕的標籤為字串s。

10. 用匿名類、lambda表示式簡化程式

 例ButtonTest.java中,各按鈕需要同樣的處理:
1) 使用字串構造按鈕物件;
2) 把按鈕新增到面板上;
3) 用對應的顏色構造一個動作監聽器;
4) 註冊動作監聽器。

11.介面卡類

12.用匿名類簡化

13.動作事件

14.滑鼠事件


第二部分:實驗部分

實驗十三  圖形介面事件處理技術

實驗時間 2018-11-22

1、實驗目的與要求

(1) 掌握事件處理的基本原理,理解其用途;

(2) 掌握AWT事件模型的工作機制;

(3) 掌握事件處理的基本程式設計模型;

(4) 瞭解GUI介面元件觀感設定方法;

(5) 掌握WindowAdapter類、AbstractAction類的用法;

(6) 掌握GUI程式中滑鼠事件處理技術。

2、實驗內容和步驟

實驗1: 匯入第11章示例程式,測試程式並進行程式碼註釋。

測試程式1:

l 在elipse IDE中除錯執行教材443頁-444頁程式11-1,結合程式執行結果理解程式;

l 在事件處理相關程式碼處添加註釋;

l 用lambda表示式簡化程式;

l 掌握JButton元件的基本API;

l 掌握Java中事件處理的基本程式設計模型。

package First;

import java.awt.*;
import javax.swing.*;

/**
 * @version 1.34 2015-06-12
 * @author Cay Horstmann
 */
public class ButtonTest
{
   public static void main(String[] args)
   {
      EventQueue.invokeLater(() -> {
         JFrame frame = new ButtonFrame();//建立物件;超類量引用子類物件;
         frame.setTitle("ButtonTest");//程式/軟體的名字
         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//設定關閉操作;
         frame.setVisible(true);//使介面視覺化;
      });
   }
}
 1 package First;
 2 
 3 import java.awt.*;
 4 import java.awt.event.*;
 5 import javax.swing.*;
 6 
 7 /**
 8  * A frame with a button panel
 9  */
10 public class ButtonFrame extends JFrame {
11     private JPanel buttonPanel;
12     private static final int DEFAULT_WIDTH = 300*2;
13     private static final int DEFAULT_HEIGHT = 200*2;
14 
15     public ButtonFrame() {
16         setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
17         buttonPanel = new JPanel();
18         makeButton("黃色", Color.yellow);
19         makeButton("藍色", Color.blue);
20         makeButton("紅色", Color.red);
21         makeButton("綠色",Color.green);
22             //新增面板到框架裡
23         add(buttonPanel);
24 
25     }
26 
27     protected void makeButton(String name,Color backgound) {
28         // 建立按鈕
29         JButton button = new JButton(name);
30         // //把按鈕新增到面板上
31         buttonPanel.add(button);
32         // create button actions
33         //方法一:通過內部類方式實現
34         /*
35                //構造一個物件,並將物件設定為按鈕監聽器   
36               ColorAction action = new ColorAction(backgound);
37         // 為按鈕新增監聽器
38         button.addActionListener(action);*/
39         //方法二:匿名內部類方式實現
40         /*button.addActionListener(new ActionListener() {
41             
42             @Override
43             public void actionPerformed(ActionEvent e) {
44                 // TODO 自動生成的方法存根
45                 buttonPanel.setBackground(backgound);
46             }
47         });*/
48         //方法三通過lambad表示式實現
49         button.addActionListener((e)->{
50             buttonPanel.setBackground(backgound);
51         });
52         
53     }
54 
55     /**
56      * An action listener that sets the panel's background color.
57      */
58     //這是實現了 ActionListener介面的內部類
59     /*private class ColorAction implements ActionListener {
60         private Color backgroundColor;
61 
62         public ColorAction(Color c) {
63             backgroundColor = c;
64         }
65             //實現ActionListener介面,監聽器類必須有一個actionPerformed方法
66         public void actionPerformed(ActionEvent event) {
67             buttonPanel.setBackground(backgroundColor);
68         }
69     }*/
70 

 

 

測試程式2:

l 在elipse IDE中除錯執行教材449頁程式11-2,結合程式執行結果理解程式;

l 在元件觀感設定程式碼處添加註釋;

l 瞭解GUI程式中觀感的設定方法。

複製程式碼
 1 package Second;
 2 
 3 import java.awt.*;
 4 import javax.swing.*;
 5 
 6 /**
 7  * @version 1.32 2015-06-12
 8  * @author Cay Horstmann
 9  */
10 public class PlafTest
11 {
12    public static void main(String[] args)
13    {
14       EventQueue.invokeLater(() -> {
15          JFrame frame = new PlafFrame();
16          frame.setTitle("PlafTest");
17          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
18          frame.setVisible(true);
19       });
20    }
21 }
複製程式碼                
1 package Second;
 2 
 3 import javax.swing.JButton;
 4 import javax.swing.JFrame;
 5 import javax.swing.JPanel;
 6 import javax.swing.SwingUtilities;
 7 import javax.swing.UIManager;
 8 
 9 /**
10  * A frame with a button panel for changing look-and-feel
11  */
12 public class PlafFrame extends JFrame
13 {
14    private JPanel buttonPanel;
15 
16    public PlafFrame()
17    {
18       buttonPanel = new JPanel();
19       //獲取所有安裝的觀感實現
20 
21       UIManager.LookAndFeelInfo[] infos = UIManager.getInstalledLookAndFeels();
22       for (UIManager.LookAndFeelInfo info : infos)
23          makeButton(info.getName(), info.getClassName());
24 
25       add(buttonPanel);
26       pack();
27    }
28 
29    /**
30     * Makes a button to change the pluggable look-and-feel.
31     * @param name the button name
32     * @param className the name of the look-and-feel class
33     */
34    private void makeButton(String name, String className)
35    {
36       // 向面板新增按鈕;
37 
38       JButton button = new JButton(name);
39       buttonPanel.add(button);
40 
41       // 設定按鈕動作;
42 
43       button.addActionListener(event -> {
44          // 按鈕動作:切換到新的外觀和感覺
45          try
46          {
47             UIManager.setLookAndFeel(className);
48             //呼叫靜態方法,重新整理全部的元件集。這裡需要向方法提供一個元件,並由此找到其他的所有元件
49             //外部物件的this引用必須將外部類名作為字首
50 
51             SwingUtilities.updateComponentTreeUI(this);
52             pack();
53          }
54          catch (Exception e)
55          {
56             e.printStackTrace();
57          }
58       });
59    }
60 }

 

 

 

測試程式3:

l 在elipse IDE中除錯執行教材457頁-458頁程式11-3,結合程式執行結果理解程式;

l 掌握AbstractAction類及其動作物件;

l 掌握GUI程式中按鈕、鍵盤動作對映到動作物件的方法。

1 package Third;
 2 
 3 import java.awt.*;
 4 import javax.swing.*;
 5 
 6 /**
 7  * @version 1.34 2015-06-12
 8  * @author Cay Horstmann
 9  */
10 public class ActionTest
11 {
12    public static void main(String[] args)
13    {
14       EventQueue.invokeLater(() -> {
15          JFrame frame = new ActionFrame();
16          frame.setTitle("ActionTest");
17          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
18          frame.setVisible(true);
19       });
20    }
21 }

 

1 package Third;
 2 
 3 import java.awt.*;
 4 import java.awt.event.*;
 5 import javax.swing.*;
 6 
 7 /**
 8  * A frame with a panel that demonstrates color change actions.
 9  */
10 public class ActionFrame extends JFrame
11 {
12    private JPanel buttonPanel;
13    private static final int DEFAULT_WIDTH = 300;
14    private static final int DEFAULT_HEIGHT = 200;
15 
16    public ActionFrame()
17    {
18       setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
19 
20       buttonPanel = new JPanel();
21 
22       // define actions
23       Action yellowAction = new ColorAction("Yellow", new ImageIcon("yellow-ball.gif"),
24             Color.YELLOW);
25       Action blueAction = new ColorAction("Blue", new ImageIcon("blue-ball.gif"), Color.BLUE);
26       Action redAction = new ColorAction("Red", new ImageIcon("red-ball.gif"), Color.RED);
27 
28     //用Action物件構造按鈕,把動作和按鈕關聯起來
29 
30       buttonPanel.add(new JButton(yellowAction));
31       buttonPanel.add(new JButton(blueAction));
32       buttonPanel.add(new JButton(redAction));
33 
34       // add panel to frame
35       add(buttonPanel);
36      
37     //得到頂層元件的WHEN_ANCESTOR_OF_FOCUSED_COMPONENT輸入對映
38 
39       // associate the Y, B, and R keys with names
40       InputMap imap = buttonPanel.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
41      //將(按鍵,動作鍵)新增到輸入對映中
42       imap.put(KeyStroke.getKeyStroke("ctrl Y"), "panel.yellow");
43       imap.put(KeyStroke.getKeyStroke("ctrl B"), "panel.blue");
44       imap.put(KeyStroke.getKeyStroke("ctrl R"), "panel.red");
45 
46       // associate the names with actions、
47       //得到頂層元件的動作對映
48       ActionMap amap = buttonPanel.getActionMap();
49     //將(動作鍵,動作物件)新增到對映中
50 
51       amap.put("panel.yellow", yellowAction);
52       amap.put("panel.blue", blueAction);
53       amap.put("panel.red", redAction);
54    }
55    
56    public class ColorAction extends AbstractAction
57    {
58       /**
59        * Constructs a color action.
60        * @param name the name to show on the button
61        * @param icon the icon to display on the button
62        * @param c the background color
63        */
64       public ColorAction(String name, Icon icon, Color c)
65       {
66         //儲存命令的名稱、圖示、簡要說明和需要的顏色
67          putValue(Action.NAME, name);
68          putValue(Action.SMALL_ICON, icon);
69          putValue(Action.SHORT_DESCRIPTION, "Set panel color to " + name.toLowerCase());//顯示在工具提示裡
70 
71          putValue("color", c);
72       }
73 
74       public void actionPerformed(ActionEvent event)
75       {
76          Color c = (Color) getValue("color");
77          buttonPanel.setBackground(c);
78       }
79    }
80 }

 

測試程式4:

l 在elipse IDE中除錯執行教材462頁程式11-4、11-5,結合程式執行結果理解程式;

l 掌握GUI程式中滑鼠事件處理技術。

 1 package Forth;
 2 
 3 import java.awt.*;
 4 import javax.swing.*;
 5 
 6 /**
 7  * @version 1.34 2015-06-12
 8  * @author Cay Horstmann
 9  */
10 public class MouseTest
11 {
12    public static void main(String[] args)
13    {
14       EventQueue.invokeLater(() -> {
15          JFrame frame = new MouseFrame();
16          frame.setTitle("MouseTest");
17          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
18          frame.setVisible(true);
19       });
20    }
21 }

 

1 package Forth;
 2 
 3 import javax.swing.*;
 4 
 5 /**
 6  * A frame containing a panel for testing mouse operations
 7  */
 8 public class MouseFrame extends JFrame
 9 {
10    public MouseFrame()
11    {
12       add(new MouseComponent());
13       pack();
14    }
15 }

 

 1 package Forth;
  2 
  3 import java.awt.*;
  4 import java.awt.event.*;
  5 import java.awt.geom.*;
  6 import java.util.*;
  7 import javax.swing.*;
  8 
  9 /**
 10  * A component with mouse operations for adding and removing squares.
 11  */
 12 public class MouseComponent extends JComponent
 13 {
 14    private static final int DEFAULT_WIDTH = 300;
 15    private static final int DEFAULT_HEIGHT = 200;
 16 
 17    private static final int SIDELENGTH = 10;
 18    private ArrayList<Rectangle2D> squares;
 19    private Rectangle2D current; // the square containing the mouse cursor
 20 
 21    public MouseComponent()
 22    {
 23       squares = new ArrayList<>();
 24       current = null;
 25 
 26       addMouseListener(new MouseHandler());
 27       addMouseMotionListener(new MouseMotionHandler());
 28    }
 29 
 30    public Dimension getPreferredSize() { return new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT); }   
 31    
 32    public void paintComponent(Graphics g)
 33    {
 34       Graphics2D g2 = (Graphics2D) g;
 35 
 36       // draw all squares
 37       for (Rectangle2D r : squares)
 38          g2.draw(r);
 39    }
 40 
 41    /**
 42     * Finds the first square containing a point.
 43     * @param p a point
 44     * @return the first square that contains p
 45     */
 46    public Rectangle2D find(Point2D p)
 47    {
 48       for (Rectangle2D r : squares)
 49       {
 50          if (r.contains(p)) return r;
 51       }
 52       return null;
 53    }
 54 
 55    /**
 56     * Adds a square to the collection.
 57     * @param p the center of the square
 58     */
 59    public void add(Point2D p)
 60    {
 61       double x = p.getX();
 62       double y = p.getY();
 63 
 64       current = new Rectangle2D.Double(x - SIDELENGTH / 2, y - SIDELENGTH / 2, SIDELENGTH,
 65             SIDELENGTH);
 66       squares.add(current);
 67       repaint();
 68    }
 69 
 70    /**
 71     * Removes a square from the collection.
 72     * @param s the square to remove
 73     */
 74    public void remove(Rectangle2D s)
 75    {
 76       if (s == null) return;
 77       if (s == current) current = null;
 78       squares.remove(s);
 79       repaint();
 80    }
 81    
 82  //兩個獨立的介面MouseListener和MouseMotionListener,有利於提高效率。
 83    //當用戶移動滑鼠時,只關心滑鼠點選的監聽器就不會被多餘的滑鼠移動所困擾。
 84    private class MouseHandler extends MouseAdapter
 85    {
 86       public void mousePressed(MouseEvent event)
 87       {
 88          // add a new square if the cursor isn't inside a square
 89         //getPoint方法返回事件源元件左上角的x y座標
 90           //判斷該處是否已經繪製圖形
 91          current = find(event.getPoint());
 92          if (current == null) add(event.getPoint());
 93       }
 94 
 95       public void mouseClicked(MouseEvent event)
 96       {
 97          // remove the current square if double clicked
 98          current = find(event.getPoint());
 99        //雙擊滑鼠,擦除方塊
100          if (current != null && event.getClickCount() >= 2) remove(current);
101       }
102    }
103 
104    private class MouseMotionHandler implements MouseMotionListener
105    {
106      //移動滑鼠的同時按下滑鼠,呼叫mouseMoved
107       public void mouseMoved(MouseEvent event)
108       {
109          // set the mouse cursor to cross hairs if it is inside
110          // a rectangle
111         //游標在一個小方塊之上時變成另外一種形狀(十字)
112          if (find(event.getPoint()) == null) setCursor(Cursor.getDefaultCursor());
113          else setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
114       }
115 
116     //更新游標位置
117       public void mouseDragged(MouseEvent event)
118       {
119          if (current != null)
120          {
121             int x = event.getX();
122             int y = event.getY();
123            //設定形狀座標和大小
124             // drag the current rectangle to center it at (x, y)
125             current.setFrame(x - SIDELENGTH / 2, y - SIDELENGTH / 2, SIDELENGTH, SIDELENGTH);
126             repaint();
127          }
128       }
129    }   
130 }

 

實驗2:結對程式設計練習

利用班級名單檔案、文字框和按鈕元件,設計一個有如下介面(圖1)的點名器,要求使用者點選開始按鈕後在文字輸入框隨機顯示2017級網路與資訊安全班同學姓名,如圖2所示,點選停止按鈕後,文字輸入框不再變換同學姓名,此同學則是被點到的同學姓名。

圖1 點名器啟動介面

 

圖2 點名器點名介面

 

 

 1 package practise1;
 2 
 3 import java.awt.*;
 4 import javax.swing.*;
 5 
 6 
 7 
 8 
 9 public class RandomName {
10 
11     public static void main(String[] args) {
12         // TODO Auto-generated method stub
13         
14            {
15               EventQueue.invokeLater(() -> {
16                  JFrame  A= new ButtonFrame();
17                  A.setTitle("點名器");
18                  A.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
19                  A.setVisible(true);
20               });
21            }
22     }
23 
24 }

 

 

  1 package practise1;
  2 
  3 import java.awt.Color;
  4 import java.awt.Container;
  5 import java.awt.event.*;
  6 import java.io.*;
  7 import java.util.*;
  8 import java.util.Timer;
  9 
 10 import javax.swing.*;
 11 
 12 public class ButtonFrame extends JFrame {
 13     private ArrayList arrayList;
 14 
 15 
 16 
 17     {
 18     arrayList = new ArrayList<>();
 19     //讀檔案
 20     File file = new File("H:/List.txt");
 21     FileInputStream fis;
 22     try {
 23         fis = new FileInputStream(file);
 24         InputStreamReader in = new InputStreamReader(fis);
 25         BufferedReader buf = new BufferedReader(in);
 26         String readLine;
 27         while ((readLine = buf.readLine())!=null) {
 28             arrayList.add(readLine);
 29             
 30         }
 31     } catch (FileNotFoundException e1) {
 32         // TODO Auto-generated catch block
 33         e1.printStackTrace();
 34     } catch (IOException e1) {
 35         // TODO Auto-generated catch block
 36         e1.printStackTrace();
 37     }
 38     }
 39     private JPanel buttonPanel;
 40     private static final int DEFAULT_WIDTH = 500;
 41     private static final int DEFAULT_HEIGHT = 300;
 42     
 43     
 44 
 45     public ButtonFrame() {
 46         setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
 47         buttonPanel = new JPanel();
 48         buttonPanel.setLayout(null);
 49         JLabel jLabel = new JLabel("隨機點名器");
 50         JButton jButton = new JButton("開始");
 51         jLabel.setBounds(200, 40, 65, 40);
 52         jButton.setBounds(200, 90, 65, 40);
 53         
 54         
 55         
 56         jButton.addActionListener(new ActionListener() {
 57 
 58             Timer timer;
 59 
 60  
 61 
 62             public void actionPerformed(ActionEvent e) {
 63 
 64                 if (jButton.getText().equals("開始")) {
 65 
 66                     timer = new Timer();;
 67 
 68                     TimerTask timerTask = new TimerTask() {
 69 
 70                         public void run() {
 71 
 72                             jButton.setText("停止");
 73 
 74                             jButton.setBackground(Color.red);
 75 
 76                             jLabel.setText((String) arrayList.get((int) (Math.random() * 43)));
 77 
 78                         }
 79 
 80  
 81 
 82                     };
 83 
 84                     timer.schedule(timerTask, 0, 10);
 85 
 86                 }
 87 
 88                 if (jButton.getText().equals("停止")) {
 89 
 90                     timer.cancel();
 91 
 92                     jButton.setText("開始");
 93 
 94                     jButton.setBackground(Color.gray);
 95 
 96                 }
 97 
 98             }
 99 
100         });
101         
102         
103         
104         
105         buttonPanel.add(jLabel);
106         buttonPanel.add(jButton);
107         add(buttonPanel);
108 
109     }
110          
111         
112 }

 

 

實驗總結:

測試程式環節當中,第一個測試程式花費的時間挺長的,對於將程式改成Lambda表示式還是不太懂。在結對程式設計環節當中,完全沒有任何的思路,想了很久還是不知道從何下手。看了學長的程式之後,還是不會。

      好文要頂 關注我 收藏該文