201871010128-杨丽霞《面向对象程序设计(java)》第十三周学习总结
项目 |
内容 |
这个作业属于哪个课程 |
https://www.cnblogs.com/nwnu-daizh/ |
这个作业的要求在哪里 |
https://www.cnblogs.com/nwnu-daizh/p/11888568.html |
作业学习目标 |
(1) 掌握事件处理的基本原理,理解其用途; (2) 掌握AWT事件模型的工作机制; (3) 掌握事件处理的基本编程模型; (4) 了解GUI界面组件观感设置方法; (5) 掌握WindowAdapter类、AbstractAction类的用法; (6) 掌握GUI程序中鼠标事件处理技术。
|
随笔博文正文内容包括:
第一部分:总结第十一章理论知识(35分)
第十一章 事件处理
1.事件:当用户在界面上执行一个操作,例如按下键盘、拖动或者单击鼠标时,都将产生一个事件。Java中事件是用来描述不同类型用户操作的对象,Java中有很多不同类型的事件。例如:单击,双击,右击,拖动,键盘的按下、释放,文本域内容改变等。
事件源:产生事件的组件就是一个事件源。例如,当在一个Button上单击鼠标是,将产生一个ActionEvent类型的事件,而这个Button就是事件源
事件监听器:就是调用事件处理方法的对象。当界面操作事件产生并被发送到产生事件的组件时,该组件将把事件发送给能接受和处理该事件的监听器。
2.1.事件编程步骤:
①编写事件处理类(事件监听者)
②根据需求给事件处理类实现监听接口
③在事件处理类中重写(实现),其事件处理函数
④在事件源类中指定该事件的监听器(响应者)是谁,即注册监听
3.事件源与监听器的关系:
4.为简化编程,JDK针对大多数事件监听器接口定义了相应的实现类——事件适配器类,在适配器中,实现了相应监听器接口中的所有的方法,但不做任何事情。
所以定义的监听器类可以继承事件适配器类,并只重写所需要的方法。
有如下适配器:
- ComponentAdapter (组件适配器)
- ContainerAdapter (容器适配器)
- FocusAdapter (焦点适配器)
- KeyAdapter (键盘适配器)
- MouseAdapter (鼠标适配器)
- MouseMotionAdapter (鼠标运动适配器)
- WindowAdapter (窗口适配器)
1.Java 用匿名类、lambda表达式简化程序
1) 使用字符串构造按钮对象
2) 把按钮添加到面板上
3) 用对应的颜色构造一个动作监听器
4) 注册动作监听器
6.Java应用swing改变观感
Java默认的是Metal观感,可以通过设置属性或者动态来改变观感。本文主要针对方法一中的文件位置问题。
设置swing.properties
本方法主要是修正针对jdk6.0,网上的说法都是在JAVA_HOME/jre/lib里有这个文件,但是jdk6.0是没有这个文件的。其实正确的位置应该是在你的安装Java的目录下的jre,按照jdk6.0的,应该是在安装时第二次选路径的那个jre6下的lib文件夹。举例来说,我的jdk目录是:D:/Java/JDK6.0,而我们要找的这个不在D:/Java/JDK6.0/jre/lib,而是在D:/Java/jre6。
而没有的话要自己建立一个swing.properties文件。
内容可以写上自己想要的默认观感,例如:swing.defaultlaf = com.sun.java.swing.plaf.windows.WindowsLookAndFeel
而其实可以如下通过添加或者去除“#”来静态选择观感。
#swing.defaultlaf = javax.swing.plaf.metal.MetalLookAndFeel
#swing.defaultlaf = com.sun.java.swing.plaf.motif.MotifLookAndFeel
swing.defaultlaf = com.sun.java.swing.plaf.windows.WindowsLookAndFeel
7. Swing包提供了一种非常实用的机制来封装命令,并将它们连接到多个事件源,这就是Action接口。一个动作是一个封装下列内容的对象:
× 命令的说明(一个文本字符串和一个可选图标);
× 执行命令所需要的参数(例如,在列举的例子中请求改变的颜色)。
Action接口包含下列内容:
1.public void actionPerformed(ActionEvent e); 2.public void setEnabled(boolean b); 3.public boolean isEnabled(); 4.public void putValue(String key, Object value); 5.public Object getValue(String key); 6.public void addPropertyChangeListener(PropertyChangeListener listener); public void removePropertyChangeListener(PropertyChangeListener listener);
actionPerformed方法是ActionListener接口中的一个:实际上,Action接口扩展于ActionListener接口,因此,可以在任何需要ActionListener对象的地方使用Action对象。
8.
1.AWT事件类的继承关系图:
2.Java事件处理采用的是面向对象的方法
有些swing组件会生成其他类型事件的对象,它们都直接扩展与EventObject,而不是AWTEvent
事件对象封装了事件源于监听器彼此通信的事件信息。在必要的时候,可以对传递给监听器对象的事件进行分析。
在按钮例子中,是借助getSourse()和getActionCommand()方法实现对象分析的。
AWT(Abstract Window Toolkit),中文译为抽象窗口工具包
3.AWT将事件分为底层事件和语义事件。语义事件是表示用户动作的时间。
ActionEvent是一个语义事件。底层事件时形成那些事件的事件
调节滚动条是一个语义事件,但是拖动鼠标时一个底层事件
9.鼠标事件:MouseEvent.
鼠标监听器接口:MouseListener,MouseMotionListener
鼠标监听器适配器:MouseAdapter,MouseMotionAdapter
用户点击鼠标按钮时,会调用三个监听器方法:
a.鼠标第一次被按下时调用mousePressed方法;
b.鼠标被释放时调用mouseReleased方法;
c.两个动作完成之后,调用mouseClicked方法。
鼠标在组件上移动时,会调用mouseMoved方法。
鼠标事件返回值:鼠标事件的类型是MouseEvent,当发生鼠标事件时:MouseEvent类自动创建一个事件对象,以及事件发生位置的x和y坐标,作为事件返回值。
监听鼠标点击事件,实现MouseListener接口.
第二部分:实验部分
实验1:测试程序1(5分)
l 在elipse IDE中调试运行教材443页-444页程序11-1,结合程序运行结果理解程序;
l 在事件处理相关代码处添加注释;
l 用lambda表达式简化程序;
l 掌握JButton组件的基本API;
l 掌握Java中事件处理的基本编程模型。
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表达式 { var frame = new ButtonFrame(); frame.setTitle("ButtonTest");//标题 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true);//可见 }); } }
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); // create buttons var yellowButton = new JButton("Yellow"); var blueButton = new JButton("Blue"); var redButton = new JButton("Red"); buttonPanel = new JPanel(); // add buttons to panel buttonPanel.add(yellowButton); buttonPanel.add(blueButton); buttonPanel.add(redButton); // add panel to frame add(buttonPanel); // 按钮将要执行的操作 ColorAction yellowAction = new ColorAction(Color.YELLOW); 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//实现监听器接口 { private Color backgroundColor;//定义背景色 public ColorAction(Color c) { backgroundColor = c; } public void actionPerformed(ActionEvent event)//按钮单机操作 { buttonPanel.setBackground(backgroundColor); } } }
运行截图:
实验1:测试程序2(5分)
l 在elipse IDE中调试运行教材449页程序11-2,结合程序运行结果理解程序;
l 在组件观感设置代码处添加注释;
l 了解GUI程序中观感的设置方法。
11-2代码:
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(); UIManager.LookAndFeelInfo[] infos = UIManager.getInstalledLookAndFeels(); for (UIManager.LookAndFeelInfo info : infos) makeButton(info.getName(), info.getClassName()); add(buttonPanel); pack(); } /** * 创建一个按钮来更改可插入的外观. * @param name the button name * @param className the name of the look-and-feel class */ private void makeButton(String name, String className) { //添加按钮到面板 JButton button = new JButton(name); buttonPanel.add(button); //设置按钮要进行的操作 button.addActionListener(event -> { // 按钮操作结果: 切换到新的外观 try //可能出错的代码放入try子句中 { UIManager.setLookAndFeel(className); SwingUtilities.updateComponentTreeUI(this); pack(); } catch (Exception e) { e.printStackTrace(); } }); } }
1 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:测试程序3(5分)
l 在elipse IDE中调试运行教材457页-458页程序11-3,结合程序运行结果理解程序;
l 掌握AbstractAction类及其动作对象;
l 掌握GUI程序中按钮、键盘动作映射到动作对象的方法。
11-3程序:
1 package Damo; 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 var frame = new ActionFrame(); 16 frame.setTitle("ActionTest"); 17 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 18 frame.setVisible(true); 19 }); 20 } 21 }
1 package Damo; 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 // 定义操作 23 var yellowAction = new ColorAction("Yellow", new ImageIcon("C:\Users\83583\Desktop\java\corejava\v1ch11\yellow-ball.gif"), 24 Color.YELLOW); 25 var blueAction = new ColorAction("Blue", new ImageIcon("C:\Users\83583\Desktop\java\corejava\v1ch11\blue-ball.gif"), Color.BLUE); 26 var redAction = new ColorAction("Red", new ImageIcon("C:\Users\83583\Desktop\java\corejava\v1ch11\red-ball.gif"), Color.RED); 27 28 // 为这些操作添加按钮 29 buttonPanel.add(new JButton(yellowAction));//注册 30 buttonPanel.add(new JButton(blueAction)); 31 buttonPanel.add(new JButton(redAction)); 32 33 // 将 panel 添加置 frame 34 add(buttonPanel); 35 36 // 将Y、B和R键与名称关联 37 InputMap inputMap = buttonPanel.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); 38 inputMap.put(KeyStroke.getKeyStroke("ctrl Y"), "panel.yellow"); 39 inputMap.put(KeyStroke.getKeyStroke("ctrl B"), "panel.blue"); 40 inputMap.put(KeyStroke.getKeyStroke("ctrl R"), "panel.red"); 41 42 // 将名称与操作关联 43 ActionMap actionMap = buttonPanel.getActionMap(); 44 actionMap.put("panel.yellow", yellowAction); 45 actionMap.put("panel.blue", blueAction); 46 actionMap.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 public void actionPerformed(ActionEvent event) 66 { 67 var color = (Color) getValue("color"); 68 buttonPanel.setBackground(color); 69 } 70 } 71 }
运行截图:
实验1:测试程序1(5分)
l 在elipse IDE中调试运行教材462页程序11-4、11-5,结合程序运行结果理解程序;
l 掌握GUI程序中鼠标事件处理技术。
源代码:
1 package Damo; 2 3 import java.awt.*; 4 import javax.swing.*; 5 6 /** 7 * @version 1.35 2018-04-10 8 * @author Cay Horstmann 9 */ 10 public class MouseTest 11 { 12 public static void main(String[] args) 13 { 14 EventQueue.invokeLater(() -> { 15 var frame = new MouseFrame(); 16 frame.setTitle("MouseTest"); 17 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 18 frame.setVisible(true); 19 }); 20 } 21 }
1 package Damo; 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 Damo; 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; // 包含鼠标光标的正方形 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() 31 { 32 return new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT); 33 } 34 35 public void paintComponent(Graphics g) 36 { 37 var g2 = (Graphics2D) g; 38 39 // 绘制所有正方形 40 for (Rectangle2D r : squares) 41 g2.draw(r); 42 } 43 44 /** 45 * Finds the first square containing a point. 46 * @param p a point 47 * @return the first square that contains p 48 */ 49 public Rectangle2D find(Point2D p) 50 { 51 for (Rectangle2D r : squares) 52 { 53 if (r.contains(p)) return r; 54 } 55 return null; 56 } 57 58 /** 59 * Adds a square to the collection. 60 * @param p the center of the square 61 */ 62 public void add(Point2D p) 63 { 64 double x = p.getX(); 65 double y = p.getY(); 66 67 current = new Rectangle2D.Double(x - SIDELENGTH / 2, y - SIDELENGTH / 2, 68 SIDELENGTH, SIDELENGTH); 69 squares.add(current); 70 repaint(); 71 } 72 73 /** 74 * Removes a square from the collection. 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); 82 repaint(); 83 } 84 85 private class MouseHandler extends MouseAdapter 86 { 87 public void mousePressed(MouseEvent event) 88 { 89 // 如果光标不在正方形内,则添加新的正方形 90 current = find(event.getPoint()); 91 if (current == null) 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) remove(current); 99 } 100 } 101 102 private class MouseMotionHandler implements MouseMotionListener 103 { 104 public void mouseMoved(MouseEvent event) 105 { 106 // 如果鼠标光标位于矩形内,请将其设置为十字光标 107 108 if (find(event.getPoint()) == null) setCursor(Cursor.getDefaultCursor()); 109 else setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR)); 110 } 111 112 public void mouseDragged(MouseEvent event) 113 { 114 if (current != null) 115 { 116 int x = event.getX(); 117 int y = event.getY(); 118 119 // 拖动当前矩形使其居中(x,y) 120 current.setFrame(x - SIDELENGTH / 2, y - SIDELENGTH / 2, SIDELENGTH, SIDELENGTH); 121 repaint(); 122 } 123 } 124 } 125 126}
运行截图:
实验2:结对编程练习包含以下4部分:(20分)
1) 程序设计思路简述;
2) 符合编程规范的程序代码;
3) 程序运行功能界面截图;
4) 结对过程描述,提供两人在讨论、细化和编程时的结对照片(非摆拍)。
利用班级名单文件、文本框和按钮组件,设计一个有如下界面(图1)的点名器,要求用户点击开始按钮后在文本输入框随机显示2018级计算机科学与技术(1)班同学姓名,如图2所示,点击停止按钮后,文本输入框不再变换同学姓名,此同学则是被点到的同学姓名,如图3所示。
代码如下:
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); }); } }
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.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
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;
{
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 //可能出错的程序放入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;
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);
}
运行截图:
结队编程照片:
实验总结:(20分)