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中事件处理的基本编程模型。
代码:

1 ackage 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 }

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 = 300;
14 private static final int DEFAULT_HEIGHT = 200;
15
16 public ButtonFrame()
17 {
18 setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
19
20 // 创建按钮
21 JButton yellowButton = new JButton("Yellow");
22 JButton blueButton = new JButton("Blue");
23 JButton redButton = new JButton("Red");
24
25 buttonPanel = new JPanel();
26
27 // 向面板添加按钮
28 buttonPanel.add(yellowButton);
29 buttonPanel.add(blueButton);
30 buttonPanel.add(redButton);
31
32 // 将面板添加到帧
33 add(buttonPanel);
34
35 // 创建按钮动作
36 ColorAction yellowAction = new ColorAction(Color.YELLOW);
37 ColorAction blueAction = new ColorAction(Color.BLUE);
38 ColorAction redAction = new ColorAction(Color.RED);
39
40 // 用按钮关联动作
41 yellowButton.addActionListener(yellowAction);
42 blueButton.addActionListener(blueAction);
43 redButton.addActionListener(redAction);
44 }
45
46 /**
47 * 设置面板背景颜色的ActualListInter.
48 */
49 private class ColorAction implements ActionListener
50 {
51 private Color backgroundColor;
52
53 public ColorAction(Color c)
54 {
55 backgroundColor = c;
56 }
57
58 public void actionPerformed(ActionEvent event)
59 {
60 buttonPanel.setBackground(backgroundColor);
61 }
62 }
63 }



用lambda表达式简化后:
代码:

1 package lambda;
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 }

1 package lambda;
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 add(buttonPanel);
23
24 }
25
26 protected void makeButton(String name, Color backgound) {
27 JButton button = new JButton(name);
28 buttonPanel.add(button);
29 button.addActionListener((e) -> {
30 buttonPanel.setBackground(backgound);
31 });
32 }
33 }
实验结果:

测试程序2:
l 在elipse IDE中调试运行教材449页程序11-2,结合程序运行结果理解程序;
l 在组件观感设置代码处添加注释;
l 了解GUI程序中观感的设置方法。

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 }

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 /**
10 * 带有按钮面板的框架,用于改变外观和感觉
11 */
12 public class PlafFrame extends JFrame
13 {
14 private JPanel buttonPanel;
15
16 public PlafFrame()
17 {
18 buttonPanel = new JPanel();
19
20 UIManager.LookAndFeelInfo[] infos = UIManager.getInstalledLookAndFeels();//获取所有的显示样式
21 for (UIManager.LookAndFeelInfo info : infos)
22 makeButton(info.getName(), info.getClassName());
23
24 add(buttonPanel);//增加按钮点击事件
25 pack();
26 }
27
28 /**
29 * 制作一个按钮来改变可插入的外观和感觉
30 * @param 命名按钮名称
31 * @param 类名:外观类的名称
32 */
33 private void makeButton(String name, String className)
34 {
35 // 向面板添加按钮
36
37 JButton button = new JButton(name);
38 buttonPanel.add(button);
39
40 // 设置按钮动作
41
42 button.addActionListener(event -> {
43 // 按钮动作:切换到新的外观和感觉
44 try
45 {
46 UIManager.setLookAndFeel(className);//设置外观的显示方式
47 SwingUtilities.updateComponentTreeUI(this);//给定一个组件后,更新所有的组件。
48 pack();//依据放置的组件设定窗口的大小,使之正好能容纳放置的所有组件
49 }
50 catch (Exception e)
51 {
52 e.printStackTrace();
53 }
54 });
55 }
56 }



测试程序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 }

1 package action;
2
3 import java.awt.*;
4 import java.awt.event.*;
5 import javax.swing.*;
6
7 /**
8 * 具有显示颜色变化动作的面板的框架
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 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 // 为这些操作添加按钮
29 buttonPanel.add(new JButton(yellowAction));
30 buttonPanel.add(new JButton(blueAction));
31 buttonPanel.add(new JButton(redAction));
32
33 // 将面板添加到框架
34 add(buttonPanel);
35
36 // 将Y、B和R键与名称关联
37 InputMap imap = buttonPanel.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
38 imap.put(KeyStroke.getKeyStroke("ctrl Y"), "panel.yellow");
39 imap.put(KeyStroke.getKeyStroke("ctrl B"), "panel.blue");
40 imap.put(KeyStroke.getKeyStroke("ctrl R"), "panel.red");
41
42 // 把名字和动作联系起来
43 ActionMap amap = buttonPanel.getActionMap();
44 amap.put("panel.yellow", yellowAction);
45 amap.put("panel.blue", blueAction);
46 amap.put("panel.red", redAction);
47 }
48
49 public class ColorAction extends AbstractAction
50 {
51 /**
52 * 构造颜色动作。
53 * @param 在按钮上显示要显示的名称
54 * @param 图标按钮上显示的图标
55 * @param 背景颜色
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 Color c = (Color) getValue("color");
68 buttonPanel.setBackground(c);
69 }
70 }
71 }

测试程序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 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 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());
13 pack();
14 }
15 }

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 // 绘制所有正方形
37 for (Rectangle2D r : squares)
38 g2.draw(r);
39 }
40
41 /**
42 * 找到包含一个点的第一个方块。
43 * @param P—A点
44 * @return 包含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 * 向集合中添加正方形
57 * @param p在正方形的中心
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 * 从集合中移除正方形.
72 * @param 从正方形中移除s
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 private class MouseHandler extends MouseAdapter
83 {
84 public void mousePressed(MouseEvent event)
85 {
86 // 如果光标不在正方形中,则添加一个新的正方形
87 current = find(event.getPoint());
88 if (current == null) add(event.getPoint());
89 }
90
91 public void mouseClicked(MouseEvent event)
92 {
93 // 如果双击,删除当前方块
94 current = find(event.getPoint());
95 if (current != null && event.getClickCount() >= 2) remove(current);
96 }
97 }
98
99 private class MouseMotionHandler implements MouseMotionListener
100 {
101 public void mouseMoved(MouseEvent event)
102 {
103 // set the mouse cursor to cross hairs if it is inside
104 // 一个长方形
105
106 if (find(event.getPoint()) == null) setCursor(Cursor.getDefaultCursor());
107 else setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
108 }
109
110 public void mouseDragged(MouseEvent event)
111 {
112 if (current != null)
113 {
114 int x = event.getX();
115 int y = event.getY();
116
117 // 拖动当前矩形将其置于(x,y)中心
118 current.setFrame(x - SIDELENGTH / 2, y - SIDELENGTH / 2, SIDELENGTH, SIDELENGTH);
119 repaint();
120 }
121 }
122 }
123 }

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

图1 点名器启动界面

图2 点名器点名界面

1 package dmq2;
2
3 import java.util.*;
4 import java.awt.*;
5 import javax.swing.*;
6 import java.awt.event.*;
7 import java.io.File;
8 import java.io.FileNotFoundException;
9
10 import javax.swing.event.*;
11
12 public class NameFrame extends JFrame implements ActionListener {
13 //private JLabel jla;
14 private JLabel jlb;
15 private JButton jba;
16 private static boolean flag = true;
17
18 public NameFrame() {
19 this.setLayout(null);
20
21 jlb = new JLabel("随机点名器");
22 jba = new JButton("开始");
23 this.add(jlb);
24 jlb.setOpaque(true);
25 jlb.setBackground(Color.cyan);
26 jlb.setFont(new Font("Courier", Font.PLAIN, 22));
27 jlb.setHorizontalAlignment(JLabel.CENTER);
28 jlb.setVerticalAlignment(JLabel.CENTER);
29 jlb.setBounds(120, 100, 150, 30);
30
31 this.add(jba);
32 jba.setBounds(150, 150, 80, 26);
33
34 jba.addActionListener(this);
35
36 this.setTitle("点名器");
37 this.setBounds(400, 400, 400, 300);
38 this.setVisible(true);
39 this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
40 }
41
42 public void actionPerformed(ActionEvent e) {
43 int i = 0;
44 String names[] = new String[50];
45 try {
46 Scanner in = new Scanner(new File("studentnamelist.txt"));
47 while (in.hasNextLine()) {
48 names[i] = in.nextLine();
49 i++;
50 }
51 } catch (FileNotFoundException e1) {
52 // TODO Auto-generated catch block
53 e1.printStackTrace();
54 }
55 if (jba.getText() == "开始") {
56 jlb.setBackground(Color.RED);
57 flag = true;
58 new Thread() {
59 public void run() {
60 while (NameFrame.flag) {
61 Random r = new Random();//
62 int i = r.nextInt(47);
63 jlb.setText(names[i]);
64 }
65 }
66 }.start();
67 jba.setText("停止");
68 jba.setBackground(Color.YELLOW);
69 } else if (jba.getText() == "停止") {
70 flag = false;
71 jba.setText("开始");
72 jba.setBackground(Color.RED);
73 jlb.setBackground(Color.gray);
74 }
75 }
76
77 public static void main(String arguments[]) {
78 new NameFrame();
79 }
80 }


来源:https://www.cnblogs.com/bmwb/p/10016194.html
