项目 |
内容 |
这个作业属于哪个课程 |
https://www.cnblogs.com/nwnu-daizh/ |
这个作业的要求在哪里 |
https://www.cnblogs.com/zyja/p/11918987.html |
作业学习目标 |
(1) 掌握事件处理的基本原理,理解其用途; (2) 掌握AWT事件模型的工作机制; (3) 掌握事件处理的基本编程模型; (4) 了解GUI界面组件观感设置方法; (5) 掌握WindowAdapter类、AbstractAction类的用法; (6) 掌握GUI程序中鼠标事件处理技术。 |
1.总结第十一章理论知识
11.1 事件处理基础
• 事件源(event source):能够产生事件的对象都可以成为事件源,如文本框、按钮等。一个事件源是一个能够注册监听器并向监听器发送事件对象的对象。
• 事件监听器(event listener):事件监听器对象接收事件源发送的通告(事件对象),并对发生的事件作出响应。一个监听器对象就是一个实现了专门监听器接口的类实例,该类必须实现接口中的方法,这些方法当事件发生时,被自动执行。
• 事件对象(event object):Java将事件的相关信息封装在一个事件对象中,所有的事件对象都最终派生于java.util.EventObject类。不同的事件源可以产生不同类别的事件。
2.AWT事件处理机制的概要:
• 监听器对象: 是一个实现了特定监听器接口(listener interface)的类实例。
• 事件源:是一个能够注册监听器对象并发送事件对象的对象。
• 当事件发生时,事件源将事件对象自动传递给所有注册的监听器。
• 监听器对象利用事件对象中的信息决定如何对事件做出响应。
3. GUI设计中,程序员需要对组件的某种事件进行响应和处理时,必须完成两个步骤:
1) 定义实现某事件监听器接口的事件监听器类,并具体化接口中声明的事件处理抽象方法。
2) 为组件注册实现了规定接口的事件监听器对象;
4. 注册监听器方法: eventSourseObject.addEventListener(eventListenerObject)
示例: ActionListener listener = ...;
JButton button = new JButton("OK");
button.addActionListener(listener);
5. 动作事件(ActionEvent):当特定组件动作(点击按钮)发生时,该组件生成此动作事件。
• 该 事 件 被 传 递 给 组 件 注 册 的 每 一 个ActionListener 对 象 , 并 调 用 监 听 器 对 象 的actionPerformed方法以接收这类事件对象。
• 能够触发动作事件的动作,主要包括:
(1) 点击按钮
(2) 双击一个列表中的选项;
(3) 选择菜单项;
11.2 监听器接口的实现
• 监听器类必须实现与事件源相对应的接口,即必须提供接口中方法的实现。
• 监听器接口中方法实现:
class Mylistener implements ActionListener
{
public void actionPerformed(ActionEvent event) {...}
}
2. 命令按钮JButton的API
• 创建按钮对象
JButton 类常用的构造方法:
1)JButton(String text): 创建一个带文本的按钮
2) JButton(Icon icon) : 创建一个带图标的按钮
3)JButton(String text, Icon icon): 创建一个带文本和图标的按钮
• 按钮对象的常用方法
1) getLabel(): 返回按钮的标签字符串
2) setLabel(String s): 设置按钮的标签为字符串S
11.3 用匿名类,lambda表达式简化程序
1)使用字符串构造按钮对象
2)把按钮添加到面板上
3)用对应的颜色构造一个动作监听器
4)注册动作监听器
11.4 改变观感的方法
Swing 程序默认使用Metal观感,采用两种方式改变观感。
1)在Java安装的子目录jre/lib下的文件swing.properties中,将属性swing.defaultlaf设置为所希望的观感类名 swing.defaultlaf = com.sun.java.swing.plaf.motif.MotifLookAndFeel
2)调用静态的UIMananger.setLookAndFeel方法,动态的改变观感,提供所想要的观感类名,再调用静态方法SwingUtilities.updateComponenetTreeUI来刷新全部组件集。
11.5 适配器类
捕获窗口事件的监听器: WindowListener listener = .....;
frame.addWindowListener(listener);
11.6 动作事件
1. 在AWT时间模型中,可设置用不同方式下达命令,其操作动作都是一样的。
2. Swing包提供了非常实用的机制来封装动作命令,并将它们连接多个事件源,这就是Action接口
3. 动作对象是一个封装下列内容的对象: 命令的说明和执行命令所需要的参数。
4. Action 是一个接口,而不是一个类。
5. AbstractAction类实现了Action接口中除actionPerformed方法之外的所有方法,这个类存储了所有名对,并管理着属性变更监听器。
6. 在动作处理应用中,可以直接扩展AbstractActon类,并在扩展类中实现actionPerformed方法。
11.7 击键关联映射
1. 将一个动作对象添加到击键中,以便让用户敲击键盘命令来执行这个动作。
2. 将动作与击键关联起来,需生成keyStroke类对象
11.8 鼠标事件
1. 用户点击鼠标按钮时,会调用三个监听器方法:
- 鼠标第一次被按下时调用mousePressed方法;
- 鼠标被释放是调用mouseReleased方法;
- 两个动作完成之后,调用mouseClicked方法;
2. 鼠标在组件上移动时,会调用mouseMoved方法
3. 如果鼠标在移动的时候还按下了鼠标,则会调用mouseDragged方法
4. 鼠标事件返回值: 鼠标事件的类型是MouseEvent,当发生鼠标事件时:MouseEvent类自动创建一个事件对象,以及事件发生位置的x和y坐标,作为事件返回值
5. MouseEvent 类中的重要方法:
- public int getX();
- public int getY();
- public Point getPoint();
- public int getClickCount();
6. 设置光标:
11.9 AWT事件继承层次
1. 所有的事件都是由java.util包中的EventObject类扩展而来
2. AWT将事件分为低级(low-level)事件(形成语义事件的事件)和语义事件(表达用户动作的事件)
3. AWT常用的语义事件:
- ActionEvent(对应按钮点击,菜单选择,选择列表项或在文本域中键入ENTER)
- AdjustmentEvent(用户调节滚动条)
- ItemEvent(用户从复选框或列表项中选择一项)
4. 低层事件
-KeyEvent(一个键被按下或被释放)
-MouseEvent(鼠标被按下,释放,移动或拖动)
-MouseWheelEvent(鼠标滚轮被传动)
-FocusEvent(某个组件获得或失去焦点)
-WindowEvent(窗口状态改变)
2、实验内容和步骤
实验1: 导入第11章示例程序,测试程序并进行代码注释。
测试程序1:
ButtonFrame.java:
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 { 10 private JPanel buttonPanel; 11 private static final int DEFAULT_WIDTH = 300; 12 private static final int DEFAULT_HEIGHT = 200; 13 14 public ButtonFrame() 15 { 16 setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); 17 //创造按钮 18 JButton yellowButton = new JButton("Yellow"); 19 JButton blueButton = new JButton("Blue"); 20 JButton redButton = new JButton("Red"); 21 22 buttonPanel = new JPanel();//创建面板对象 23 24 // 增加按钮到面板 25 buttonPanel.add(yellowButton); 26 buttonPanel.add(blueButton); 27 buttonPanel.add(redButton); 28 29 // 增加面板到框架 30 add(buttonPanel); 31 32 //创建按钮动作(创建监听器对象) 33 ColorAction yellowAction = new ColorAction(Color.YELLOW); 34 ColorAction blueAction = new ColorAction(Color.BLUE); 35 ColorAction redAction = new ColorAction(Color.RED); 36 37 // 将动作与按钮关联 38 yellowButton.addActionListener(yellowAction); 39 blueButton.addActionListener(blueAction); 40 redButton.addActionListener(redAction); 41 } 42 43 44 //当按钮被点击时,将面板的颜色设置为指定的颜色,这个颜色存储在监听器类中 45 private class ColorAction implements ActionListener//实现监听器接口 46 { 47 private Color backgroundColor; 48 49 public ColorAction(Color c) 50 { 51 backgroundColor = c; 52 } 53 54 public void actionPerformed(ActionEvent event)//实现actionPerformed方法,接收事件对象 55 { 56 buttonPanel.setBackground(backgroundColor); 57 } 58 } 59 }
ButtonTest.java:
1 import java.awt.*; 2 import javax.swing.*; 3 4 /** 5 * @version 1.35 2018-04-10 6 * @author Cay Horstmann 7 */ 8 public class ButtonTest 9 { 10 public static void main(String[] args) 11 { 12 EventQueue.invokeLater(() -> { 13 ButtonFrame frame = new ButtonFrame(); 14 frame.setTitle("ButtonTest"); //给出框架的标题 15 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 16 frame.setVisible(true);//该框架是可见的 17 }); 18 } 19 }
用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 { 10 private JPanel buttonPanel; 11 private static final int DEFAULT_WIDTH = 300; 12 private static final int DEFAULT_HEIGHT = 200; 13 14 public void makeButton(String name,Color backgroundColor) 15 { 16 JButton button = new JButton(name); 17 buttonPanel.add(button); 18 button.addActionListener((e)->{ 19 buttonPanel.setBackground(backgroundColor); 20 }); 21 } 22 23 public ButtonFrame() 24 { 25 setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); 26 27 makeButton("yellow", Color.YELLOW); 28 makeButton("blue", Color.BLUE); 29 makeButton("red", Color.RED); 30 buttonPanel = new JPanel(); 31 32 // add panel to frame 33 add(buttonPanel); 34 35 // create button actions 36 ColorAction yellowAction = new ColorAction(Color.YELLOW); 37 ColorAction blueAction = new ColorAction(Color.BLUE); 38 ColorAction redAction = new ColorAction(Color.RED); 39 40 } 41 /** 42 * An action listener that sets the panel's background color. 43 */ 44 private class ColorAction implements ActionListener 45 { 46 private Color backgroundColor; 47 48 public ColorAction(Color c) 49 { 50 backgroundColor = c; 51 } 52 53 public void actionPerformed(ActionEvent event) 54 { 55 buttonPanel.setBackground(backgroundColor); 56 } 57 } 58 }
运行结果如下:
测试程序2:
PlafFrame.java
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 for (UIManager.LookAndFeelInfo info : infos) 20 makeButton(info.getName(), info.getClassName());//得到每一种观感的名字和类名 21 22 add(buttonPanel); 23 pack();//通过放置的组件来设置窗口的大小,是指正好能容纳这些组件 24 } 25 26 /** 27 * Makes a button to change the pluggable look-and-feel. 28 * @param name the button name 29 * @param className the name of the look-and-feel class 30 */ 31 private void makeButton(String name, String className) 32 { 33 // 增加按钮到面板 34 35 JButton button = new JButton(name); 36 buttonPanel.add(button); 37 38 //设置按钮动作 39 button.addActionListener(event -> { 40 // 按钮动作:切换到新的外观和感觉 41 try 42 { 43 UIManager.setLookAndFeel(className);//调用静态的UIManager.setLookAndFeel(className)方法,并提供了所想要的观感类名“className" 44 SwingUtilities.updateComponentTreeUI(this);//调用静态方法 SwingUtilities.updateComponentTreeUI()来刷新全部的组件集 45 pack(); 46 } 47 catch (Exception e) 48 { 49 e.printStackTrace(); 50 } 51 }); 52 } 53 }
Plaf.Test.java:
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:
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 //定义动作 21 22 ColorAction yellowAction = new ColorAction("Yellow", new ImageIcon("yellow-ball.gif"), Color.YELLOW); 23 ColorAction blueAction = new ColorAction("Blue", new ImageIcon("blue-ball.gif"), Color.BLUE); 24 ColorAction redAction = new ColorAction("Red", new ImageIcon("red-ball.gif"), Color.RED); 25 26 // 给这些动作添加按钮 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 // 将Y,B,R与姓名关联
35 InputMap inputMap = buttonPanel.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);//得到顶层组件的WHEN_ANCESTOR_OF_FOCUSED_COMPONENT输入映射 36 inputMap.put(KeyStroke.getKeyStroke("ctrl Y"), "panel.yellow"); 37 inputMap.put(KeyStroke.getKeyStroke("ctrl B"), "panel.blue"); 38 inputMap.put(KeyStroke.getKeyStroke("ctrl R"), "panel.red"); 39 40 // 将姓名与动作关联 41 ActionMap actionMap = buttonPanel.getActionMap(); 42 actionMap.put("panel.yellow", yellowAction); 43 actionMap.put("panel.blue", blueAction); 44 actionMap.put("panel.red", redAction); 45 } 46 47 public class ColorAction extends AbstractAction 48 { 49 /** 50 * Constructs a color action. 51 * @param name the name to show on the button 52 * @param icon the icon to display on the button 53 * @param c the background color 54 */ 55 public ColorAction(String name, Icon icon, Color c) 56 { 57 putValue(Action.NAME, name); 58 putValue(Action.SMALL_ICON, icon); 59 putValue(Action.SHORT_DESCRIPTION, "Set panel color to " + name.toLowerCase()); 60 putValue("color", c); 61 } 62 63 public void actionPerformed(ActionEvent event) 64 { 65 Color color = (Color) getValue("color"); 66 buttonPanel.setBackground(color); 67 } 68 } 69 }
ActionTest.java:
1 import java.awt.*; 2 import javax.swing.*; 3 public class ActionTest 4 { 5 public static void main(String[] args) 6 { 7 EventQueue.invokeLater(() -> { 8 ActionFrame frame = new ActionFrame(); 9 frame.setTitle("ActionTest"); 10 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 11 frame.setVisible(true); 12 }); 13 } 14 }
运行结果如下:
测试程序4:
1 package 第13周; 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 public class MouseComponent extends JComponent 10 { 11 private static final int DEFAULT_WIDTH = 300; 12 private static final int DEFAULT_HEIGHT = 200; 13 14 private static final int SIDELENGTH = 10; 15 private ArrayList<Rectangle2D> squares; 16 private Rectangle2D current; 17 // 包含鼠标光标的正方形 18 public MouseComponent() 19 { 20 squares = new ArrayList<>(); 21 current = null; 22 23 addMouseListener(new MouseHandler()); 24 addMouseMotionListener(new MouseMotionHandler()); 25 } 26 27 public Dimension getPreferredSize() { return new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT); } 28 29 public void paintComponent(Graphics g) 30 { 31 Graphics2D g2 = (Graphics2D) g; 32 33 // 画所有的正方形 34 for (Rectangle2D r : squares) 35 g2.draw(r); 36 } 37 38 public Rectangle2D find(Point2D p) 39 { 40 for (Rectangle2D r : squares) 41 { 42 if (r.contains(p)) return r; 43 } 44 return null; 45 } 46 47 public void add(Point2D p) 48 { 49 double x = p.getX(); 50 double y = p.getY(); 51 52 current = new Rectangle2D.Double(x - SIDELENGTH / 2, y - SIDELENGTH / 2, SIDELENGTH, 53 SIDELENGTH); 54 squares.add(current); 55 repaint(); 56 } 57 58 public void remove(Rectangle2D s) 59 { 60 if (s == null) return; 61 if (s == current) current = null; 62 squares.remove(s); 63 repaint(); 64 } 65 66 private class MouseHandler extends MouseAdapter 67 { 68 public void mousePressed(MouseEvent event) 69 { 70 // 如果光标不在正方形内,则添加一个新正方形 71 current = find(event.getPoint()); 72 if (current == null) add(event.getPoint()); 73 } 74 75 public void mouseClicked(MouseEvent event) 76 { 77 // 如果双击,删除当前方块 78 current = find(event.getPoint()); 79 if (current != null && event.getClickCount() >= 2) remove(current); 80 } 81 } 82 83 private class MouseMotionHandler implements MouseMotionListener 84 { 85 public void mouseMoved(MouseEvent event) 86 { 87 // 如果鼠标光标在内部,将其设置为十字准线 88 // 一个矩形 89 90 if (find(event.getPoint()) == null) setCursor(Cursor.getDefaultCursor()); 91 else setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR)); 92 } 93 94 public void mouseDragged(MouseEvent event) 95 { 96 if (current != null) 97 { 98 int x = event.getX(); 99 int y = event.getY(); 100 // 拖动当前矩形将其置于(x,y)中心 101 current.setFrame(x - SIDELENGTH / 2, y - SIDELENGTH / 2, SIDELENGTH, SIDELENGTH); 102 repaint(); 103 } 104 } 105 } 106 }
1 package 第13周; 2 3 import javax.swing.*; 4 5 /** 6 * 7 包含用于测试鼠标操作的面板的框架 8 */ 9 public class MouseFrame extends JFrame 10 { 11 public MouseFrame() 12 { 13 add(new MouseComponent()); 14 pack(); 15 } 16 }
1 package 第13周; 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 }
运行结果如下:
实验2:结对编程练习
利用班级名单文件、文本框和按钮组件,设计一个有如下界面(图1)的点名器,要求用户点击开始按钮后在文本输入框随机显示2018级计算机科学与技术(1)班同学姓名,如图2所示,点击停止按钮后,文本输入框不再变换同学姓名,此同学则是被点到的同学姓名。
整体思路:点名器需要有一个定时器,还要有一个循环,设计一个GUI图形界面,读取文件里面学生的姓名,在actionPerformed方法中,当jButton的内容为"begin"时,启动定时器,利用随机数来得到学生的姓名,当jButton的内容为"stop"时,调用Timer类对象的cancel方法停用定时器,由此得到。
1 package tuxing; 2 import java.awt.Color; 3 import java.awt.event.ActionEvent; 4 import java.awt.event.ActionListener; 5 import java.io.BufferedInputStream; 6 import java.io.BufferedReader; 7 import java.io.File; 8 import java.io.FileInputStream; 9 import java.io.FileNotFoundException; 10 import java.io.IOException; 11 import java.io.InputStreamReader; 12 import java.io.StringBufferInputStream; 13 import java.util.ArrayList; 14 import java.util.Timer; 15 import java.util.TimerTask; 16 17 import javax.swing.JButton; 18 import javax.swing.JFrame; 19 import javax.swing.JLabel; 20 import javax.swing.JPanel; 21 22 public class ButtonFrame extends JFrame { 23 private JPanel buttonPanel; 24 private static final int DEFAULT_WIDTH = 600; 25 private static final int DEFAULT_HEIGHT = 500; 26 private JButton jButton; 27 private ArrayList<String> arrayList; 28 29 public ButtonFrame() { 30 setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); 31 buttonPanel = new JPanel(); 32 buttonPanel.setLayout(null); 33 buttonPanel.setBackground(Color.blue); 34 add(buttonPanel); 35 jButton = new JButton("Begin"); 36 jButton.setBackground(Color.blue); 37 jButton.setBounds(200, 100, 120, 60); 38 jButton.setBounds(200, 240, 120, 60); 39 arrayList = new ArrayList<>(); 40 //读文件 41 File file = new File("2019studentlist.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 } catch (FileNotFoundException e1) { 52 // TODO Auto-generated catch block 53 e1.printStackTrace(); 54 } catch (IOException e1) { 55 // TODO Auto-generated catch block 56 e1.printStackTrace(); 57 } 58 59 jButton.addActionListener(new ActionListener() { 60 Timer timer; 61 62 public void actionPerformed(ActionEvent e) { 63 if (jButton.getText().equals("Begin")) { 64 timer = new Timer();; 65 TimerTask timerTask = new TimerTask() { 66 public void run() { 67 jButton.setText("Stop"); 68 jButton.setBackground(Color.red); 69 jButton.setText(arrayList.get((int) (Math.random() * 35))); 70 } 71 }; 72 timer.schedule(timerTask, 0, 20); 73 } 74 if (jButton.getText().equals("Stop")) { 75 timer.cancel(); 76 jButton.setText("Begin"); 77 jButton.setBackground(Color.blue); 78 } 79 } 80 }); 81 buttonPanel.add(jButton); 82 buttonPanel.add(jButton); 83 add(buttonPanel); 84 85 } 86 }
运行结果:
结对编程照片:
实验总结:本次实验中,主要学到了事件源,事件监听器,和事件对象,以及动作事件,在事件监听器中,必须要实现actionPerform()方法,用来接收事件对象。创建按钮对象中JButton类的构造方法很常用,也很重要。用匿名内部类和lambda表达式简化程序是一个很重要的方法,我掌握的一般,会继续努力。观感和鼠标事件我觉得比前面的难一点,通过测试程序和看书,还是知道了一点点,最后的结对编程很难,通过网上查找,寻求其他同学的帮助,然后还有自己琢磨,也还差不多了,但是问题还是很多,我也会自己抓紧的。