• 201771010126 王燕《面向对象程序设计(Java)》第十三周学习总结


    实验十三  图形界面事件处理技术

    实验时间 2018-11-22

    1、实验目的与要求

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

    事件源 (eventevent eventeventsource source source ):能够产生事件的对象都可 :能够产生事件的对象都可 :能够产生事件的对象都可 :能够产生事件的对象都可 :能够产生事件的对象都可 :能够产生事件的对象都可 :能够产生事件的对象都可 :能够产生事件的对象都可 :能够产生事件的对象都可 :能够产生事件的对象都可 :能够产生事件的对象都可 :能够产生事件的对象都可 以成为事件源 ,如文本框 、按钮等 。一个 事件源是能够注册监听器并向发送事件对象 的能够注册监听器并向发送事件对象 的能够注册监听器并向发送事件对象 的能够注册监听器并向发送事件对象 的。
    . 事件监听器 事件监听器 事件监听器 事件监听器 事件监听器 (eventeventeventeventeventlistenerlistener listener listenerlistener ):事件监听器对象接 :事件监听器对象接 :事件监听器对象接 :事件监听器对象接 :事件监听器对象接 :事件监听器对象接 :事件监听器对象接 :事件监听器对象接 :事件监听器对象接 收事件源发送的通告 (事件对象 ),并对发生的事件作 出响应 。一个监听器对象就是实现了专门接 口的类实例 ,该类必须实现接口中的方法 ,这些方法当 事件发生时 ,被自动执行 。
    . 事件对象 事件对象 事件对象 事件对象 (event eventevent object object object ):JavaJava Java将事件的相关信息 将事件的相关信息 将事件的相关信息 将事件的相关信息 将事件的相关信息 将事件的相关信息 将事件的相关信息 将事件的相关信息 封装在一个事件对象中 ,所有的事件对象都最终派生于 javajava java.utilutil util.EventObject EventObjectEventObject EventObject EventObject EventObject 类。不 同的事件源可以产生不 同的事件源可以产生不 同的事件源可以产生不 同的事件源可以产生不 同的事件源可以产生不 同的事件源可以产生不 同的事件源可以产生不 同的事件源可以产生不 同的事件源可以产生不 同的事件源可以产生不 同的事件源可以产生同类别的事件 。

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

    监听器对象是一个实现了特定监听器接口(listener interface)的类的实例。 事件源是一个能够注册监听器对象并发送事件对象的对象。 当事件发生时,事件源将事件对象传递给所有注册的监听器。 监听器对象将利用事件对象中的信息决定如何对事件做出响应。

    (3) 掌握事件处理的基本编程模型;

     

    (4) 了解GUI界面组件观感设置方法;

    在默认情况下,Swing程序使用Metal观感,可以采用两种方式改变观感。 第一种方式是在Java安装的子目录jre/lib下有一个文件swing.properties。在这个文件中,将属性swing.defaultlaf设置为所希望的观感类名。 swing.defaultlaf = com.sun.java.swing.plaf.motif.MotifLookAndFeel 第二种方式是动态地改变观感,需要调用静态的UIManager.setLookAndFeel方法,并提供所想要的观感类名,然后再调用静态方法SwingUtilities. updateComponentTreeUI来刷新全部的组件集。

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

    扩展WindowAdapter类,继承六个空方法,并覆盖WindowClosing()方法: class Terminator extends WindowAdapter { public void windowClosing(WindowEvent e) { if(user agress) System.exit(0); } }、

    (6) 掌握GUI程序中鼠标事件处理技术。

    用户点击鼠标按钮时,会调用三个监听器方法: 鼠标第一次被按下时调用mousePressed方法; 鼠标被释放时调用mouseReleased方法; 两个动作完成之后,调用mouseClicked方法。 鼠标在组件上移动时,会调用mouseMoved方法。 如果鼠标在移动的时候还按下了鼠标,则会调用mouseDragged方法。

    2、实验内容和步骤

    实验1: 导入第11章示例程序,测试程序并进行代码注释。

    测试程序1:

    l 在elipse IDE中调试运行教材443页-444页程序11-1,结合程序运行结果理解程序;

    l 在事件处理相关代码处添加注释;

    l 用lambda表达式简化程序;

    l 掌握JButton组件的基本API;

    l 掌握Java中事件处理的基本编程模型。

     1 package button;
     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 ButtonTest
    11 {
    12    public static void main(String[] args)
    13    {
    14       EventQueue.invokeLater(() -> {
    15          JFrame frame = new ButtonFrame();
    16          frame.setTitle("ButtonTest");       //设置框架名称
    17          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  //窗口关闭按钮设置为可用
    18          frame.setVisible(true);                //将框架设置为可见
    19       });
    20    }
    21 }
    View Code
     1 package button;
     2 
     3 import java.awt.*;
     4 import java.awt.event.*;
     5 import javax.swing.*;
     6 
     7 /**
     8  * 按钮面板框架
     9  */
    10 public class ButtonFrame extends JFrame
    11 {
    12    private JPanel buttonPanel;
    13    private static final int DEFAULT_WIDTH = 600;//设置面板的私有属性,长和宽
    14    private static final int DEFAULT_HEIGHT = 400;
    15 
    16    public ButtonFrame()
    17    {      
    18       setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
    19 
    20       JButton yellowButton = new JButton("Yellow");// 创建以Yellow,Blue,Red命名的三个按钮
    21       JButton blueButton = new JButton("Blue");
    22       JButton redButton = new JButton("Red");
    23 
    24       buttonPanel = new JPanel();
    25 
    26       buttonPanel.add(yellowButton);    // 在面板中添加按钮
    27       buttonPanel.add(blueButton);
    28       buttonPanel.add(redButton);
    29 
    30       add(buttonPanel);// 添加框架
    31 
    32       ColorAction yellowAction = new ColorAction(Color.YELLOW);  // 创建三个响应按钮
    33       ColorAction blueAction = new ColorAction(Color.BLUE);
    34       ColorAction redAction = new ColorAction(Color.RED);
    35 
    36       yellowButton.addActionListener(yellowAction);// 将按钮与事件进行关联
    37       blueButton.addActionListener(blueAction);
    38       redButton.addActionListener(redAction);
    39    }
    40 
    41   
    42    private class ColorAction implements ActionListener//设置面板背景色的事件监听器
    43    {
    44       private Color backgroundColor;//添加背景色的私有属性
    45 
    46       public ColorAction(Color c)
    47       {
    48          backgroundColor = c;
    49       }
    50 
    51       public void actionPerformed(ActionEvent event)
    52       {
    53          buttonPanel.setBackground(backgroundColor);
    54       }
    55    }
    56 }
    View Code

     

    测试程序2:

    l 在elipse IDE中调试运行教材449页程序11-2,结合程序运行结果理解程序;

    l 在组件观感设置代码处添加注释;

    l 了解GUI程序中观感的设置方法。

     1 package plaf;
     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 public class PlafFrame extends JFrame//设置框架和面板的外观
    10 {
    11    private JPanel buttonPanel;
    12 
    13    public PlafFrame()
    14    {
    15       buttonPanel = new JPanel();//创建一个按钮面板对象
    16 
    17       UIManager.LookAndFeelInfo[] infos = UIManager.getInstalledLookAndFeels();//获取所有的显示样式
    18       for (UIManager.LookAndFeelInfo info : infos)
    19          makeButton(info.getName(), info.getClassName());
    20 
    21       add(buttonPanel);
    22       pack();
    23    }
    24 
    25    /**
    26                                                                                          点击按钮时插入可变的外观
    27     * @param name the button name
    28     * @param className the name of the look-and-feel class
    29     */
    30    private void makeButton(String name, String className)
    31    {
    32       
    33       JButton button = new JButton(name);//创建按钮面板
    34       buttonPanel.add(button);
    35 
    36 
    37       button.addActionListener(event -> //创建按钮事件
    38       {
    39          // 按钮事件作为开启新外观的开关按钮
    40          try
    41          {
    42             UIManager.setLookAndFeel(className);//将树结构中的每个节点转到 updateUI()
    43             SwingUtilities.updateComponentTreeUI(this);
    44             pack();
    45          }
    46          catch (Exception e)//捕获异常
    47          {
    48             e.printStackTrace();
    49          }
    50       });
    51    }
    52 }
    View Code
     1 package plaf;
     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 }
    View Code

     

     

    测试程序3:

    l 在elipse IDE中调试运行教材457页-458页程序11-3,结合程序运行结果理解程序;

    l 掌握AbstractAction类及其动作对象;

    l 掌握GUI程序中按钮、键盘动作映射到动作对象的方法。

     1 package action;
     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 }
    View Code
     1 package action;
     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 = 600;    //设置面板的私有属性,长和宽
    14    private static final int DEFAULT_HEIGHT = 400;
    15 
    16    public ActionFrame()
    17    {
    18       setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
    19 
    20       buttonPanel = new JPanel();        //创建按钮面板对象
    21  
    22       Action yellowAction = new ColorAction("Yellow", new ImageIcon("yellow-ball.gif"),//定义三个事件
    23             Color.YELLOW);
    24       Action blueAction = new ColorAction("Blue", new ImageIcon("blue-ball.gif"), Color.BLUE);
    25       Action redAction = new ColorAction("Red", new ImageIcon("red-ball.gif"), Color.RED);
    26 
    27       buttonPanel.add(new JButton(yellowAction));//添加按钮对应的事件
    28       buttonPanel.add(new JButton(blueAction));
    29       buttonPanel.add(new JButton(redAction));
    30 
    31       add(buttonPanel);//在框架中添加面板
    32                                               
    33       InputMap imap = buttonPanel.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);//关联Y,R,B,与事件
    34       imap.put(KeyStroke.getKeyStroke("ctrl Y"), "panel.yellow");
    35       imap.put(KeyStroke.getKeyStroke("ctrl B"), "panel.blue");
    36       imap.put(KeyStroke.getKeyStroke("ctrl R"), "panel.red");
    37 
    38       ActionMap amap = buttonPanel.getActionMap();// 将名称与事件联系起来
    39       amap.put("panel.yellow", yellowAction);
    40       amap.put("panel.blue", blueAction);
    41       amap.put("panel.red", redAction);
    42    }
    43    
    44    public class ColorAction extends AbstractAction
    45    {
    46       /**
    47        * Constructs a color action.
    48        * @param name the name to show on the button
    49        * @param icon the icon to display on the button
    50        * @param c the background color
    51        */
    52       public ColorAction(String name, Icon icon, Color c)
    53       {
    54          putValue(Action.NAME, name);                //在构造器中设置键值对映射,设置的属性将会被JPanel读取
    55          putValue(Action.SMALL_ICON, icon);
    56          putValue(Action.SHORT_DESCRIPTION, "Set panel color to " + name.toLowerCase());
    57          putValue("color", c);
    58       }
    59 
    60       public void actionPerformed(ActionEvent event)
    61       {
    62          Color c = (Color) getValue("color");
    63          buttonPanel.setBackground(c);
    64       }
    65    }
    66 }
    View Code

     

    测试程序4:

    l 在elipse IDE中调试运行教材462页程序11-4、11-5,结合程序运行结果理解程序;

    l 掌握GUI程序中鼠标事件处理技术。

     1 package Mouse;
     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 MouseFrame();
    16          frame.setTitle("MouseTest");            //设置框架名称
    17          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);    //窗口关闭按钮设置为可用
    18          frame.setVisible(true);        //将框架设置为可见
    19       });
    20    }
    21 }
    View Code
     1 package mouse;
     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());//向框架中添加一个JComponent对象
    13       pack();//根据窗口大小, 使组件可被容纳
    14    }
    15 }
    View Code
      1 package mouse;
      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  * 一个带有鼠标操作的用于添加和删除正方形的组件。 
     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; //定义矩形类
     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       for (Rectangle2D r : squares)// 绘制正方形 
     37          g2.draw(r);
     38   
     39    }
     40 
     41    /**
     42     * 判断在这个坐标上是否有图形
     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)) //判断坐标是否在图形内部
     51              return r;
     52       }
     53       return null;
     54 
     55    }
     56 
     57    /**
     58     * 在这个坐标位置增加一个图形 
     59     * @param p the center of the square
     60     */
     61    public void add(Point2D p)
     62    {
     63       double x = p.getX();
     64       double y = p.getY();
     65       
     66       current = new Rectangle2D.Double(x - SIDELENGTH / 2, y - SIDELENGTH / 2, SIDELENGTH,//构建一个新的正方形
     67             SIDELENGTH);
     68 
     69       squares.add(current);//构建的正方形的数据添加到队列中
     70       repaint();
     71    }
     72 
     73    /**
     74     * 从集合中移除正方形。 
     75     * @param s the square to remove
     76     */
     77    public void remove(Rectangle2D s)
     78    {
     79       if (s == null) return;
     80       if (s == current) current = null;
     81       squares.remove(s);//将s从squares的列表中直接删去
     82       repaint();//重绘component的方法
     83    }
     84 
     85    private class MouseHandler extends MouseAdapter//移动鼠标的构造器
     86    {
     87       public void mousePressed(MouseEvent event)
     88       {
     89          current = find(event.getPoint());
     90          if (current == null)
     91              add(event.getPoint());
     92       }
     93 
     94       public void mouseClicked(MouseEvent event)//点击鼠标的构造器
     95       {
     96          // 如果双击,删除当前方块 
     97          current = find(event.getPoint());
     98          if (current != null && event.getClickCount() >= 2) 
     99              remove(current);
    100       }
    101    }
    102 
    103    private class MouseMotionHandler implements MouseMotionListener
    104    {
    105       public void mouseMoved(MouseEvent event)//如果鼠标移动
    106       {
    107          if (find(event.getPoint()) == null) 
    108              setCursor(Cursor.getDefaultCursor());//将光标的图像设置为默认的图像
    109          else 
    110              setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
    111       }
    112 
    113       public void mouseDragged(MouseEvent event)//拖动鼠标时的构造器
    114       {
    115          if (current != null)
    116          {
    117             int x = event.getX();
    118             int y = event.getY();       
    119             current.setFrame(x - SIDELENGTH / 2, y - SIDELENGTH / 2, SIDELENGTH, SIDELENGTH)
    120             repaint();//重绘图像
    121          }
    122       }
    123    }   
    124 }
    View Code

    实验2:结对编程练习

    利用班级名单文件、文本框和按钮组件,设计一个有如下界面(图1)的点名器,要求用户点击开始按钮后在文本输入框随机显示2017级网络与信息安全班同学姓名,如图2所示,点击停止按钮后,文本输入框不再变换同学姓名,此同学则是被点到的同学姓名。

     View Code

     1 import java.awt.Color;
     2 import java.awt.event.ActionEvent;
     3 import java.awt.event.ActionListener;
     4 import java.io.BufferedInputStream;
     5 import java.io.BufferedReader;
     6 import java.io.File;
     7 import java.io.FileInputStream;
     8 import java.io.FileNotFoundException;
     9 import java.io.IOException;
    10 import java.io.InputStreamReader;
    11 import java.io.StringBufferInputStream;
    12 import java.util.ArrayList;
    13 import java.util.Timer;
    14 import java.util.TimerTask;
    15 
    16 import javax.swing.JButton;
    17 import javax.swing.JFrame;
    18 import javax.swing.JLabel;
    19 import javax.swing.JPanel;
    20 
    21 public class ButtonFrame extends JFrame {
    22     private JPanel buttonPanel;
    23     private static final int DEFAULT_WIDTH = 600;
    24     private static final int DEFAULT_HEIGHT = 500;
    25     private JButton jButton;
    26     private JLabel jLabel;
    27     private ArrayList<String> arrayList;
    28 
    29     public ButtonFrame() {
    30         setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
    31         buttonPanel = new JPanel();
    32         buttonPanel.setLayout(null);
    33         add(buttonPanel);
    34         jLabel = new JLabel("Random roll call device");
    35         jButton = new JButton("Bagin");
    36         jButton.setBackground(Color.blue);
    37         jLabel.setBounds(200, 100, 120, 60);
    38         jButton.setBounds(200, 240, 120, 60);
    39         arrayList = new ArrayList<>();
    40         //读文件
    41         File file = new File("D:/studentnamelist.txt");
    42         FileInputStream fis;
    43         try {
    44             fis = new FileInputStream(file);
    45             InputStreamReader in = new InputStreamReader(fis);
    46             BufferedReader buf = new BufferedReader(in);
    47             String readLine;
    48             while ((readLine = buf.readLine())!=null) {
    49                 arrayList.add(readLine);
    50                 
    51             }
    52         } catch (FileNotFoundException e1) {
    53             // TODO Auto-generated catch block
    54             e1.printStackTrace();
    55         } catch (IOException e1) {
    56             // TODO Auto-generated catch block
    57             e1.printStackTrace();
    58         }
    59         
    60         jButton.addActionListener(new ActionListener() {
    61             Timer timer;
    62 
    63             public void actionPerformed(ActionEvent e) {
    64                 if (jButton.getText().equals("Bagin")) {
    65                     timer = new Timer();;
    66                     TimerTask timerTask = new TimerTask() {
    67                         public void run() {
    68                             jButton.setText("Stop");
    69                             jButton.setBackground(Color.red);
    70                             jLabel.setText(arrayList.get((int) (Math.random() * 43)));
    71                         }
    72 
    73                     };
    74                     timer.schedule(timerTask, 0, 10);
    75                 }
    76                 if (jButton.getText().equals("Stop")) {
    77                     timer.cancel();
    78                     jButton.setText("Begin");
    79                     jButton.setBackground(Color.blue);
    80                 }
    81             }
    82         });
    83         buttonPanel.add(jLabel);
    84         buttonPanel.add(jButton);
    85         add(buttonPanel);
    86 
    87     }
    88 }
    View Code

    点名器启动界面

     

    点名器点名界面

     

     实验总结:通过本章的学习,掌握了如何将框架中的按钮与事件响应联系起来,在上一章中只是了解了如何在框架中插入按钮,而按钮并不想平常生活中看到的那样具有交互性,只是一个摆设,这周通过对事件以及监听器的学习,对按钮实现人机交互所必需的的一些编程机制有了进一步的理解,但是实现的窗口比较简陋,与平常生活中接触到的相差甚远,所以,应该进一步学习窗口的程序设计,是的呈现出来的窗口更加美观。

  • 相关阅读:
    pthread_once函数的简单示例
    pthread_join直接决定资源是否能够及时释放
    非分离线程未使用join函数例子:
    一个HTTP打趴80%面试者
    BM和KMP字符串匹配算法学习
    STL 几个容器的底层实现
    指针的引用(*&)与指针的指针(**)
    Maven 环境变量设置
    配置JAVA的环境变量
    Maven报错 解决方案。ERROR: No goals have been specified for this build. You must specify a valid lifecycle phase or a goal in the format <plugin-prefix>:<goal> or <plugin-group-id>:<plugin-artifact-id
  • 原文地址:https://www.cnblogs.com/wy201771010126/p/10002405.html
Copyright © 2020-2023  润新知