20187101021-王方《面面相对象程序设计java》第十三周实验总结

项目

内容

这个作业属于哪个课程

https://www.cnblogs.com/nwnu-daizh/

这个作业的要求在哪里

https://www.cnblogs.com/nwnu-daizh/p/11435127.html

 

 

 

作业学习目标是什么

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

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

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

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

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

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

 

第一部分  基础知识

(一)事件处理基础

1.实例:处理按钮点击事件

          在java中,都将事件的相关信息封装在一个事件对象中,所有的事件对象都最终派生于java.util.EventObje类。当然,每个事件类型还有子类,例如ActionEvent和WindowEvent。不同的事件源可以产生不同类别的事件。例如,按钮可以发送一个ActionEvent对象,而窗口可以发送WindowEvent对象在这个示例中,想要在一个面板中放置三个按钮,添加三个监听器对象用来作为按钮的动作监听器。只要用户点击面板上的任何一个按钮,相关的监听器对象就会接收到一个Action Event对象,他表示有个按钮被点击了。在示例程序中,监听器对象将改变面板的背景颜色。

 

2.简介地制定监听器

(1) 事件三要素:事件源  时间   事件主题消息

对应监听器事件模型构成: 事件   事件源    事件监听器

事件流传过程:(1)事件源注册监听器 -> (2)事件发生 -> (3)通知监听器 -> (4)监听器处理

(2)监视器:事件源要产生事件,必须要有什么东西去监视它,以便作出相应啊,那就是监视器,监视器的作用是对事件源进行监视,以便对发生的时间进行处理。
事件源通过相应的方法注册自己的监听器。比如addListener(监听器);
(3)处理事件的接口:监视器负责处理事件源发生的事件,监视器是一个对象,为了处理事件源发生的事件,监视器这个对象会自动调用一个方法来处理事件。被调用的这个方法就是所说的处理事件的接口中的方法。
(4) 事件源
  事件最初由事件源产生,事件源可以是GUI组件Java Bean或由生成事件能力的对象,在GUI组件情况下,事件源或者是组件的同位体(对于Abstract Window Toolkit[awt]GUI组件来说)或组件本身(对于Swing组件来说)。
(5)在java中,每一个组件会产生什么样的事件,已经被定义好了。或者说,对于任何一个事件来说,哪些组件可以产生它,已经是确定的了。
java.awt.event包中定义的常用事件适配器类包括以下几个:
  1.ComponentAdapter( 组件适配器)
  2.ContainerAdapter( 容器适配器)
  3.FocusAdapter( 焦点适配器)
  4.KeyAdapter( 键盘适配器)
  5.MouseAdapter( 鼠标适配器)
  6.MouseMotionAdapter( 鼠标运动适配器)
  7.WindowAdapter( 窗口适配器)
监听器对象就是一个实现了特定监听器接口的类的实例,那么监听器接口就是我们所关心的问题了。在监听器接口的最顶层接口是java.util.EventListener,这个接口是所有事件侦听器接口必须扩展的标记接口。感到诧异的是这个接口完全是空的,里面没有任何的抽象方法的定义,查看源代码里面空空如也啊!
事件监听器类(监听器对象所属的类)必须实现事件监听器接口或继承事件监听器适配器类。
 事件监听器接口定义了处理事件必须实现的方法。
 事件监听器适配器类是对事件监听器接口的简单实现。目的是为了减少编程的工作量。
  事件监听器的接口命名方式为:XXListener,而且,在java中,这些接口已经被定义好了。用来被实现,它定义了事件处理器(即事件处理的方法原型,这个方法需要被重新实现)。
例如:ActionListener接口、MouseListener接口、WindowListener接口、KeyListener接口、ItemListener接口、MouseMotionListener接口、FocusListener接口、ComponentListener接口等
1.6 事件源与监听器的对应关系

 

 

3.实例:改变观感

更改配置文件
  配置文件在Java安装目录的子目录jre/lib下,一个名为swing.properties的文件,在这个文件中,将属性swing.defaultlaf设置为所希望的观感器类名。
注意:Metal观感器位于javax.swing包中。其他的观感器包位于com.sun.java包中。采用这种方式开启观感器时必须重新启动程序。Swing程序只在启动时读取该配置文件。
动态地改变观感
方法很简单:调用UIManager.setLookAndFeel方法,并提供所想要的观感器类名,然后调用静态方法SwingUtilities.updateComponentTreeUI来刷新全部的组件集。这里需要向这个方法提供一个组件,并由此找到其他的所有组件。

4.适配器类

有时候监听接口中有很多抽象方法,在实现接口的时候,需要重写所有的方法,但是我们经常只会用到其中的一个或两个,这无疑是一种劳累,多余。
于是就有了适配器类,出于简化的目的,每个还有多个方法的的监听器接口都配有一个适配器类,这个类实现了接口中的所有方法,但是每个方法没有做任何事情。
比如:
FocusAdapter,KeyAdapter,MouseAdapter,MouseMotionAdapter,
WindowAdapter.
这就提供另一种方法,就是继承适配器类,重写其中的需要使用的方法,不必重写全部的方法,简单方便。

(二)动作

动作事件的监听接口是ActionListener接口,在这个接口中的抽象方法如下:public void actionPerformed(ActionEvent e) .

Action接口 由AbstractAction类实现 包含以下方法:

void actionPerformed(ActionEvent event); //扩展于ActionListener接口
void setEnabled(boolean b); //启用或禁用这个这个动作
boolean isEnabled(); //检查动作是否启用
void putValue(String key, Object value); //存储名/值对到动作对象中
Object getvalue(String key); //检索动作对象中的任意名/值对
void addPropertyChangeListener(PropertyChangeListener listener);
void remove PropertyChangeListener(PropertyChangeListener listener); 
//最后两个方法能够让其他对象在动作对象的属性发生变化时得到通告

(三)鼠标事件

如果只希望用户点击按钮或菜单,则不需要显式地处理鼠标事件。然而,如果希望用户使用鼠标画图,就需要捕获鼠标移动点击和拖动事件。

鼠标点击事件:

MouseHandler类 extends MouseAdapter类 implement MouseListener接口

鼠标第一次被按下时,调用mouse Pressed方法;鼠标被释放时调用mouseReleased方法;最后调用mouseClicked方法。如果只对最终的点击事件感兴趣,可以忽略前两个方法。

扩展——getModifiersEx方法能够准确地报告鼠标事件的鼠标按钮和键盘修饰符。有下列

  BUTTON1_DOWN_MASK

  BUTTON2_DOWN_MASK

  BUTTON3_DOWN_MASK

  SHIFT_DOWN_MASK

  CTRL_DOWN_MASK

  ALT_DOWN_MASK

  ALT_GRAPH_DOWN_MASK

  META_DOWN_MASK

鼠标移动与拖动事件:

MouseMotionHandler类 implement MouseMotionListener接口

鼠标移动调用mouseMoved方法,鼠标拖动调用mouseDragged方法。

鼠标光标可以参考Cursor类的getPredefinedCursor方法。

(四)AWT事件继承层次

1)AWT将事件分为低级事件和语义事件;
  语义事件:表达用户动作的事件;
  AWT事件中常用的语义事件:
  ActionEvent (对应按钮点击、菜单选择、选择列表项或在文本域键中键入ENTER);
  AdjustmentEvent(用户调节滚动条);
  ItemEvent(用户从复选框或列表项中选择一项);
  低级事件:形成语义事件的事件;
  AWT事件中常用的5个低级事件:
  KeyEvent(一个键被按下或释放);
  MouseEvent(鼠标被按下、释放、移动或者拖动);
  MouseWheelEvent(鼠标滚轮被转动);
  FocusEvent(某个组件获得或失去焦点);
  WindowEvent(窗口状态改变)

第二部分  实验部分

2、实验内容和步骤

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

测试程序1:(5分)

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

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

实验代码如下:

package button;
 
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
 
/**
 * A frame with a button panel.
 */
public class ButtonFrame extends JFrame   //ButtonFrame类继承JFrame类
{
   private JPanel buttonPanel;      //设置私有属性
   private static final int DEFAULT_WIDTH = 300;   //设置长和宽为常量值
   private static final int DEFAULT_HEIGHT = 200;
 
   public ButtonFrame()     //ButtonFrame构造器
   {      
      setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);     //设置大小
 
      // create buttons
      JButton yellowButton = new JButton("Yellow");   //创建三个不同颜色的按钮
      JButton blueButton = new JButton("Blue");
      JButton redButton = new JButton("Red");
 
      buttonPanel = new JPanel();  //创建一个JPanel类对象buttonPanel
 
      // add buttons to panel
      buttonPanel.add(yellowButton);      //通过buttonPanel来调用add方法添加按钮到平板上
      buttonPanel.add(blueButton);
      buttonPanel.add(redButton);
 
      // add panel to frame
      add(buttonPanel);    //将平板添加到框架里
 
      // create button actions
      ColorAction yellowAction = new ColorAction(Color.YELLOW);    //创建颜色动作监听器ColorAction
      ColorAction blueAction = new ColorAction(Color.BLUE);
      ColorAction redAction = new ColorAction(Color.RED);
 
      // associate actions with buttons
      yellowButton.addActionListener(yellowAction);   //事件源,将操作与按钮相关联
      blueButton.addActionListener(blueAction);
      redButton.addActionListener(redAction);
   }
 
   /**
    * An action listener that sets the panel's background color.
    */
   private class ColorAction implements ActionListener   //创建一个实现ActionListener监听器接口的类ColorAction
   {
      private Color backgroundColor;    //创建一个颜色类  背景颜色
 
      public ColorAction(Color c)//内部类,ColorAction构造器
      {
         backgroundColor = c;
      }
 
      public void actionPerformed(ActionEvent event)    //事件对象的入口参数,按钮单击方法
      {
         buttonPanel.setBackground(backgroundColor);//通过调用setBackground方法设置背景
      }
   }
}
package button;
import java.awt.*;
import javax.swing.*;
 
/**
 * @version 1.35 2018-04-10
 * @author Cay Horstmann
 */
public class ButtonTest
{
   public static void main(String[] args)
   {
      EventQueue.invokeLater(() -> {    //Lambda表达式
         ButtonFrame frame = new ButtonFrame();   //创建一个ButtonFrame类对象 frame
         frame.setTitle("ButtonTest");//通过对象名调用setTitle方法来设置标题
         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  //通过frame来调用setDefaultCloseOperation,用来设置关闭窗口的操作 
         frame.setVisible(true);  //调用setVisible方法设置组件是否可见
      });
   }
}

实验输出结果截图为:  

                                 

 

 点击不同的按钮将会出现不同的颜色。

用lambda表达式简化程序;

实验代码如下:

package button;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
 
/**
 * A frame with a button panel.
 */
public class ButtonFrame extends JFrame
{
   private JPanel buttonPanel;
   private static final int DEFAULT_WIDTH = 300;
   private static final int DEFAULT_HEIGHT = 200;
 
   public ButtonFrame()
   {    
      setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
           buttonPanel = new JPanel();
       
      makeButton("yellow",Color.YELLOW);
      makeButton("blue",Color.BLUE);
      makeButton("red",Color.RED);
            add(buttonPanel);
 
   }
    
    public void makeButton(String name,Color backgroundColor)
   {
       JButton button=new JButton(name);
       buttonPanel.add(button);
       button.addActionListener(event->
           buttonPanel.setBackground(backgroundColor));
   }
}

实验输出结果截图为:

 

 简化后的程序输出结果相同。

掌握JButton组件的基本API;

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

测试程序2:(5分)

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

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

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

实验代码为:

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
 
public class PlafFrame extends JFrame
{
   private JPanel buttonPanel;    //私有属性的定义
 
   public PlafFrame()//构造器
   {
         buttonPanel = new JPanel();   //创建一个JPanel类对象
         UIManager.LookAndFeelInfo[] infos = UIManager.getInstalledLookAndFeels();  //列举安装的所有观感实现的数组对象,调用此方法
         for (UIManager.LookAndFeelInfo info : infos)        //利用给定的类名设置当前的观感
         makeButton(info.getName(), info.getClassName());    //调用getName和getClassName方法得到每一种观感的名字和类名
         add(buttonPanel);
         pack();
   }
   private void makeButton(String name, String className)    //辅助方法makeButton指定按钮动作
   {
      //添加按钮到面板
      JButton button = new JButton(name);
      buttonPanel.add(button);
      //设置按钮要进行的操作
      button.addActionListener(event -> {
         // 按钮操作结果: 切换到新的外观
         try //可能出错的代码放入try子句中
         {
            UIManager.setLookAndFeel(className);
            SwingUtilities.updateComponentTreeUI(this);   //this指示外围对象
            pack();  //pack方法调整此窗口的大小,以适合其子组件的首选大小和布局
         }
         catch (Exception e)
         {
            e.printStackTrace();
         }
      });
   }
}
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
 
public class PlafFrame extends JFrame
{
   private JPanel buttonPanel;    //私有属性的定义
 
   public PlafFrame()//构造器
   {
         buttonPanel = new JPanel();   //创建一个JPanel类对象
         UIManager.LookAndFeelInfo[] infos = UIManager.getInstalledLookAndFeels();  //列举安装的所有观感实现的数组对象,调用此方法
         for (UIManager.LookAndFeelInfo info : infos)        //利用给定的类名设置当前的观感
         makeButton(info.getName(), info.getClassName());    //调用getName和getClassName方法得到每一种观感的名字和类名
         add(buttonPanel);
         pack();
   }
   private void makeButton(String name, String className)    //辅助方法makeButton指定按钮动作
   {
      //添加按钮到面板
      JButton button = new JButton(name);
      buttonPanel.add(button);
      //设置按钮要进行的操作
      button.addActionListener(event -> {
         // 按钮操作结果: 切换到新的外观
         try //可能出错的代码放入try子句中
         {
            UIManager.setLookAndFeel(className);
            SwingUtilities.updateComponentTreeUI(this);   //this指示外围对象
            pack();  //pack方法调整此窗口的大小,以适合其子组件的首选大小和布局
         }
         catch (Exception e)
         {
            e.printStackTrace();
         }
      });
   }
}
import java.awt.*;
import javax.swing.*;
 
public class PlafTest
{
   public static void main(String[] args)
   {
      EventQueue.invokeLater(() -> {
         JFrame frame = new JFrame();   //创建一个JFrame类对象frame
         frame.setTitle("PlafTest");     //调用setTitle方法设置标题
         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);   //调用setDefaultCloseOperation方法设置窗口是否可见
         frame.setVisible(true);  //调用setVisible方法设置组件可见
      });
   }
}

实验输出结果截图为:

 

 

 

 

 

 测试程序3:(5分)

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

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

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

实验代码如下:

package action;
 
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
 
/**
 * A frame with a panel that demonstrates color change actions.
 */
public class ActionFrame extends JFrame             //ActionFrame类继承JFrame类
{
   private JPanel buttonPanel;                      //设置私有属性
   private static final int DEFAULT_WIDTH = 300;    //常量长和宽的定义
   private static final int DEFAULT_HEIGHT = 200;
    
   public ActionFrame()                             //ActionFrame构造器
   {
      setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);       //设置长和宽分别为 DEFAULT_WIDTH, DEFAULT_HEIGHT大小的框架
      buttonPanel = new JPanel();                   //创建一个JPanel类对象
      // define actions
      ColorAction yellowAction = new ColorAction("Yellow", new ImageIcon("yellow-ball.gif"),
            Color.YELLOW);                          //创建了三个ColorAction类的对象
      ColorAction blueAction = new ColorAction("Blue", new ImageIcon("blue-ball.gif"), Color.BLUE);
      ColorAction redAction = new ColorAction("Red", new ImageIcon("red-ball.gif"), Color.RED);
 
      //add buttons for these actions
      buttonPanel.add(new JButton(yellowAction));   //将这个动作和一个按钮关联起来,添加按钮到平板上
      buttonPanel.add(new JButton(blueAction));
      buttonPanel.add(new JButton(redAction));
 
      // add panel to frame
      add(buttonPanel);
 
      // associate the Y, B, and R keys with names
      InputMap inputMap = buttonPanel.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);   
      //调用getInputMap方法从组件中得到输入映射
      //输入映射,对应当这个组件包含了拥有键盘焦点的组件时这个条件
      //inputMap不能直接的将KeyStroke对象映射到ColorAction对象
      inputMap.put(KeyStroke.getKeyStroke("ctrl Y"), "panel.yellow");  //将KeyStroke对象映射到任意对象
      inputMap.put(KeyStroke.getKeyStroke("ctrl B"), "panel.blue");
      inputMap.put(KeyStroke.getKeyStroke("ctrl R"), "panel.red");
    //当在运行时按下Ctrl+Y,Ctrl+B,Ctrl+R会改变面板的背景颜色
      // associate the names with actions
      ActionMap actionMap = buttonPanel.getActionMap();   //由ActionMap类实现将对象映射到动作上的第二个映射
      actionMap.put("panel.yellow", yellowAction);
      actionMap.put("panel.blue", blueAction);
      actionMap.put("panel.red", redAction);
   }
    
   public class ColorAction extends AbstractAction   //实现一个ColorAction类继承AbstractAction类。多个相关的动作可以使用同一个类
   {
      /**
       * Constructs a color action.
       * @param name the name to show on the button
       * @param icon the icon to display on the button
       * @param c the background color
       */
      public ColorAction(String name, Icon icon, Color c)   //构造一个用于执行改变颜色命令的动作对象,ColorAction构造器
      {
         putValue(Action.NAME, name);        //将颜色存储在AbstractAction类提供的名/值对表中
         putValue(Action.SMALL_ICON, icon);  //putValue方法允许存储动作中的任意名/值
         putValue(Action.SHORT_DESCRIPTION, "Set panel color to " + name.toLowerCase());
         putValue("color", c);
      }
 
      public void actionPerformed(ActionEvent event)   //actionPerformed方法执行改变颜色的动作
      {
         Color color = (Color) getValue("color");     //检索动作对象中的任意名/值对,强转为Color类
         buttonPanel.setBackground(color);  //调用setBackground方法设置背景颜色
      }
   }
}
package action;
 
import java.awt.*;
import javax.swing.*;
 
/**
 * @version 1.34 2015-06-12
 * @author Cay Horstmann
 */
public class ActionTest
{
   public static void main(String[] args)
   {
      EventQueue.invokeLater(() -> {   //
         ActionFrame frame = new ActionFrame();   //创建一个ActionFrame类对象
         frame.setTitle("ActionTest");   //调用setTitle方法设置标题
         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//调用setDefaultCloseOperation方法来设置关闭窗口
         frame.setVisible(true);//调用setVisible方法设置组件是否可见
      });
   }
}

实验输出结果截图为:

 

 点击不同的按钮将会出现不同的颜色。

 测试程序4:(5分)

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

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

 实验代码如下:

package mouse;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.*;
import javax.swing.*;
 
/**
 * A component with mouse operations for adding and removing squares.
 */
public class MouseComponent extends JComponent   //MouseComponent类继承JComponent类
{
   private static final int DEFAULT_WIDTH = 300;     //私有整型常量DEFAULT_WIDTH和DEFAULT_HEIGHT的定义
   private static final int DEFAULT_HEIGHT = 200;
 
   private static final int SIDELENGTH = 10;
   private ArrayList<Rectangle2D> squares;      //定义Rectangle2D类型的泛型数组ArrayList类对象squares
   private Rectangle2D current;         // the square containing the mouse cursor
   //包含鼠标光标的方块
   public MouseComponent()              //MouseComponent类的构造器
   {
      squares = new ArrayList<>();      //创建一个泛型数组类对象squares
      current = null;                   //current 函数返回 数组中的当前元素,设置为null
     //MouseListener和addMouseMotionListener是两个独立的接口
      addMouseListener(new MouseHandler());   //MouseHandler和MouseMotionHandler演示了鼠标的点击监听、鼠标移动和拖动事件监听:
      addMouseMotionListener(new MouseMotionHandler());//鼠标移动与拖动事件定义在一个MouseMotionListener接口中。 
   }
 
   public Dimension getPreferredSize() //getPreferredSize方法定义,要覆盖这个方法,(返回)获取组件的首选大小。
   //Dimension类用来封装单个对象中组件的宽度和高度,与组件的某个属性关联.用Dimension类封装起来以方便管理和使用这两个属性。
   {
      return new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT);    //返回一个宽和长分别为DEFAULT_WIDTH, DEFAULT_HEIGHT的组件
   }   
    
   public void paintComponent(Graphics g)      //覆盖这个方法paintComponent方法,没有实例化,只是一个入口参数为Graphics类型的 g。来描述应该如何绘制自己的组件
   //paintComponent就是本身这个容器自己画出自己组件的方法,
   {
      Graphics2D g2 = (Graphics2D) g;
      //Graphics2D是Graphics的子类,父类型可以转换为子类型,因为子类包含了父类的所以属性,子类本身多出来的属性放空就可以
      // draw all squares
      for (Rectangle2D r : squares)     
         g2.draw(r);   //调用draw方法画出squares正方形
   }
 
   /**
    * Finds the first square containing a point.
    * @param p a point
    * @return the first square that contains p
    */
   public Rectangle2D find(Point2D p)    //find方法,入口参数为一个Point2D类型的p
   {
      for (Rectangle2D r : squares)      //创建一个Rectangle2D类对象r
      {
         if (r.contains(p)) return r;
      }
      return null;
   }
 
   /**
    * Adds a square to the collection.
    * @param p the center of the square
    */
   public void add(Point2D p)    //add方法来添加小方块
   {
      double x = p.getX();     //返回正方形左上角的x和y坐标
      double y = p.getY();
 
      current = new Rectangle2D.Double(x - SIDELENGTH / 2, y - SIDELENGTH / 2,
         SIDELENGTH, SIDELENGTH);  //利用给定的左上角、宽和高构造一个正方形
      squares.add(current);     //添加这个当前光标所指的正方形
      repaint();   //尽可能地重新绘制组件
   }
 
   /**
    * Removes a square from the collection.
    * @param s the square to remove
    */
   public void remove(Rectangle2D s)        //remove方法删除小方块,入口参数为Rectangle2D类型的s,
   {
      if (s == null) return;                //当s为空时,不删除
      if (s == current) current = null;     //当当前光标所指位置和s相等时,将当前的光标所指的位置置为null
      squares.remove(s);                    //调用remove方法将s删除
      repaint();
   }
 
   private class MouseHandler extends MouseAdapter      //MouseHandler内部类继承MouseAdapter类
   {
      public void mousePressed(MouseEvent event)    //mousePressed方法的定义,当鼠标点击在所有小方块的像素之外,就会绘制出一个新的小方块,
      {
         // add a new square if the cursor isn't inside a square
         current = find(event.getPoint());     //调用getPoint方法获取这个图形环境绘制属性
         if (current == null) add(event.getPoint());    //如果当前光标所指地正方形为空,添加正方形
      }
 
      public void mouseClicked(MouseEvent event)      //mouseClicked方法,当鼠标双击某个小方块时,就会将它擦除,
      {
         // remove the current square if double clicked
         current = find(event.getPoint());
         if (current != null && event.getClickCount() >= 2) remove(current);
         //当不为空,并且调用getClickCount方法,如果单击超过两次,就删除这个正方形
      }
   }
 
   private class MouseMotionHandler implements MouseMotionListener   //MouseMotionHandler类实现MouseMotionListener接口的内部类
   {
      public void mouseMoved(MouseEvent event)   //MouseMotionListener类中的mouseMoved方法
      {
         // set the mouse cursor to cross hairs if it is inside a rectangle
 
         if (find(event.getPoint()) == null) setCursor(Cursor.getDefaultCursor());
         else setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));    //代表“+”的光标形状
      }
 
      public void mouseDragged(MouseEvent event)     //mouseDragged方法,入口参数是MouseEvent类型,event
      {
         if (current != null)    //如果当前光标所指向的方块不为空。
         {
            int x = event.getX();        //调用getX和getY方法可以获得鼠标被按下时所在的x和y坐标
            int y = event.getY();
 
            // drag the current rectangle to center it at (x, y)
             current.setFrame(x - SIDELENGTH / 2, y - SIDELENGTH / 2, SIDELENGTH, SIDELENGTH);
            //调用setFrame方法得到
            repaint();     //尽可能快的重新绘制组件
         }
      }
   }   
}
package mouse;
import javax.swing.*;
/**
 * A frame containing a panel for testing mouse operations
 */
public class MouseFrame extends JFrame     //MouseFrame类继承JFrame类
{
   public MouseFrame()    //MouseFrame内部类
   {
      add(new MouseComponent());    //添加新创建的鼠标组件
      pack();     //pack方法调整此窗口的大小,以适合其子组件的首选大小和布局。
   }
}
package mouse;
 
import java.awt.*;
import javax.swing.*;
 
/**
 * @version 1.35 2018-04-10
 * @author Cay Horstmann
 */
public class MouseTest
{
   public static void main(String[] args)
   {
      EventQueue.invokeLater(() -> {     //Lambda表达式
         MouseFrame frame = new MouseFrame();     //创建一个MouseFrame类的对象frame
         frame.setTitle("MouseTest");  //通过调用setTitle方法来设置标题
         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //通过调用setDefaultCloseOperation方法来设置窗口是否可见
         frame.setVisible(true);    //调用setVisible方法设置组件是否可见
      });
   }
}
package mouse;
 
import java.awt.*;
import javax.swing.*;
 
/**
 * @version 1.35 2018-04-10
 * @author Cay Horstmann
 */
public class MouseTest
{
   public static void main(String[] args)
   {
      EventQueue.invokeLater(() -> {     //Lambda表达式
         MouseFrame frame = new MouseFrame();     //创建一个MouseFrame类的对象frame
         frame.setTitle("MouseTest");  //通过调用setTitle方法来设置标题
         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //通过调用setDefaultCloseOperation方法来设置窗口是否可见
         frame.setVisible(true);    //调用setVisible方法设置组件是否可见
      });
   }
}

实验输出结果截图为:

 

 

实验2:结对编程练习包含以下4部分:(20分)

1)   程序设计思路简述;

(1)首先创建一个控件,上面是一个随机点名器的标签和一个开始按钮,字体设置为宋体,并且在标签的中间,取消按钮文字周围的边框;

(2)初始化图形用户界面,设置背景的颜色,设置图形用户界面的标题等等,设置pane面板布局为空,自己调整组件位置;

(3)添加控件,添加按钮的点击事件,获取学生姓名,然后是一个计时器,每个50毫秒就是一个同学的名字,在运行的过程中,会自动生成0-30之间的随机数;

(4)定义一个数组用来保存学生姓名,读取文件,里面包含了读文件时会遇到的异常,用try  catch语句将其捕获,

2)   符合编程规范的程序代码;

3)   程序运行功能界面截图;

4)   结对过程描述,提供两人在讨论、细化和编程时的结对照片(非摆拍)。

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

 

 

 

 

 

 

 

结对编程代码如下:

package demo;

import java.awt.EventQueue;

import javax.management.Query; import javax.swing.JFrame;

public class Main {
    public static void main(String[] args) {
        EventQueue.invokeLater(()->{
            ButtonFrame buttonFrame = new ButtonFrame();
            buttonFrame.setVisible(true);
            buttonFrame.setTitle("点名器");
            buttonFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            
        });
    }
}
package demo;

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StringBufferInputStream;
import java.util.ArrayList;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class ButtonFrame extends JFrame {
    private JPanel buttonPanel;
    private static final int DEFAULT_WIDTH = 300 * 2;
    private static final int DEFAULT_HEIGHT = 200 * 2;
    private JButton jButton;
    private JLabel jLabel;
    private ArrayList<String> arrayList;

    public ButtonFrame() {
        setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
        buttonPanel = new JPanel();
        buttonPanel.setLayout(null);
        add(buttonPanel);
        jLabel = new JLabel("点名器");
        jButton = new JButton("开始");
        jButton.setBackground(Color.gray);
        jLabel.setBounds(100, 50, 60, 30);
        jButton.setBounds(100, 120, 60, 30);
        arrayList = new ArrayList<>();
        //读文件
        File file = new File("D:/studentnamelist.txt");
        FileInputStream fis;
        try {
            fis = new FileInputStream(file);
            InputStreamReader in = new InputStreamReader(fis);
            BufferedReader buf = new BufferedReader(in);
            String readLine;
            while ((readLine = buf.readLine())!=null) {
                arrayList.add(readLine);
                
            }
        } catch (FileNotFoundException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        } catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
        
        jButton.addActionListener(new ActionListener() {
            Timer timer;

            public void actionPerformed(ActionEvent e) {
                if (jButton.getText().equals("开始")) {
                    timer = new Timer();;
                    TimerTask timerTask = new TimerTask() {
                        public void run() {
                            jButton.setText("停止");
                            jButton.setBackground(Color.red);
                            jLabel.setText(arrayList.get((int) (Math.random() * 43)));
                        }

                    };
                    timer.schedule(timerTask, 0, 10);
                }
                if (jButton.getText().equals("停止")) {
                    timer.cancel();
                    jButton.setText("开始");
                    jButton.setBackground(Color.gray);
                }
            }
        });
        buttonPanel.add(jLabel);
        buttonPanel.add(jButton);
        add(buttonPanel);

    }
}

实验输出截图为:

 

 

 

 

 实验总结:上周我们主要学习了事件处理。其实通过上上周的内容对这周内容的理解有相当大的帮助,而且老师在上上周的课程讲解过程中有提到上周的内容,所以有帮助我理解这周的知识,而且事件处理这部分内容相对比较好容易理解一些。

事件处理这一板块主要包括四大部分,有事件处理基础(其中包括处理按钮点击事件,简洁地指定监听器,适配器以及改变观感的实例四大例子来说明),动作,鼠标事件以及AWT事件继承层次。其中比较难理解的监听器的部分,还有AWT事件继承层次部分,这方面主要是在程序的逻辑性方面理解还有点问题,其它部分老师讲解的很详细,也容易懂。
不太明白的地方我也会去搜集资料,多看书尽力理解。

posted @ 2019-11-25 21:58  计师-王方  阅读(196)  评论(4编辑  收藏  举报