Java基础知识:GUI之事件处理

2020年1月23日03:33:41
评论

  事件处理可以简单地这么理解,当有一个事件产生,程序要根据这个事件做出响应。比如,我们做了一个可以通过按钮改变背景颜色的窗口,当我们点击按钮时便产生了一个事件,程序会根据这个事件来做出响应,也就是去改变背景的颜色。

 

Java基础知识:GUI之事件处理Java基础知识:GUI之事件处理Java基础知识:GUI之事件处理

运行结果

 

  那么程序是怎样做出响应的呢?这就需要事件监听器ActionListener,这是一个接口,里面包含了actionPerformed方法(也就是根据事件去执行的操作),所以我们要实现这个接口(实现接口里的actionPerformed方法)做出一个监听器对象出来,并且用按钮来注册这个监听器对象,这样当按钮被点击的时候,就会调用这个监听器来执行响应了。

 

Java基础知识:GUI之事件处理

事件处理机制

 

  代码(第42行开始为实现接口):


Java基础知识:GUI之事件处理
 1
package
buttonPanel;

2


3
import Java.awt.*
;

4
import java.awt.event.*;
//
事件监听器接口ActionListener的位置。


5
import javax.swing.*
;

6


7
public
class ButtonFrame
extends
JFrame {

8   
private
ButtonPanel buttonPanel;
9   
private
static
final
int DEFAULT_WIDTH = 300
;

10   
private
static
final
int DEFAULT_HEIGHT = 200
;

11   


12   
public
ButtonFrame() {

13
        setSize(DEFAULT_WIDTH,DEFAULT_HEIGHT);

14        setLocationByPlatform(
true
);

15       


16       
//
构造按钮


17        JButton redButton =
new JButton("RED"
);

18        JButton yellowButton =
new JButton("YELLOW"
);

19        JButton blueButton =
new JButton("BLUE"
);

20       


21        buttonPanel =
new
ButtonPanel();

22       


23       
//
添加按钮到面板


24
        buttonPanel.add(redButton);

25
        buttonPanel.add(yellowButton);

26
        buttonPanel.add(blueButton);

27       


28
        add(buttonPanel);

29       


30       
//
构造对应颜色的动作监听器


31        ColorAction redAction =
new
ColorAction(Color.red);

32        ColorAction yellowAction =
new
ColorAction(Color.yellow);

33        ColorAction blueAction =
new
ColorAction(Color.blue);

34       


35       
//
每个按钮注册对应的监听器


36
        redButton.addActionListener(redAction);                   

37
        yellowButton.addActionListener(yellowAction);

38
        blueButton.addActionListener(blueAction);

39
    }

40   


41   
//
为了方便调用buttonPanel,将ColorAction作为ButtonFrame的内部类。


42   
private
class ColorAction
implements
ActionListener {

43       
private
Color backgroundColor;

44       
public
ColorAction(Color c) {

45            backgroundColor =
c;

46
        }

47       
public
void
actionPerformed(ActionEvent event) {

48
            buttonPanel.setBackground(backgroundColor);

49
        }

50
    }

51   


52   
public
static
void
main(String[] args) {

53        EventQueue.invokeLater(
new
Runnable() {

54           
public
void
run() {

55                JFrame frame =
new
ButtonFrame();

56                frame.setTitle("ColorButton"
);

57
                frame.setDefaultCloseOperation(EXIT_ON_CLOSE);

58                frame.setVisible(
true
);

59
            }

60
        });

61
    }

62
}

63


64
class ButtonPanel
extends
JPanel {

65   
private
static
final
int DEFAUT_WIDTH = 300
;

66   
private
static
final
int DEFAUT_HEIGHT = 200
;

67


68
    @Override

69   
protected
void
paintComponent(Graphics g) {

70
        g.create();

71       
super
.paintComponent(g);

72
    }

73


74
    @Override

75   
public
Dimension getPreferredSize() {

76       
return
new
Dimension(DEFAUT_WIDTH,DEFAUT_HEIGHT);

77
    }

78 }
Java基础知识:GUI之事件处理
ButtonFrame

  -------------------------------------------------------------------------------------------------------------------------

  在上述代码中,为了方便监听器调用buttonPanel,将ColorAction作为ButtonFrame的内部类。如果将ColorAction类独立出去,需要将buttonPanel传递到ColorAction,实现如下:


Java基础知识:GUI之事件处理

 1 package buttonPanel2;
 2 
 3 import java.awt.*;
 4 import java.awt.event.*;
 5 import javax.swing.*;
 6 
 7 public class ButtonFrame2 extends JFrame {
 8     private ButtonPanel buttonPanel;
 9     private static final int DEFAULT_WIDTH = 300;
10     private static final int DEFAULT_HEIGHT = 200;
11     
12     public ButtonFrame2() {
13         setSize(DEFAULT_WIDTH,DEFAULT_HEIGHT);
14         setLocationByPlatform(true);
15         
16         JButton redButton = new JButton("RED");
17         JButton yellowButton = new JButton("YELLOW");
18         JButton blueButton = new JButton("BLUE");
19         
20         buttonPanel = new ButtonPanel();
21         
22         buttonPanel.add(redButton);
23         buttonPanel.add(yellowButton);
24         buttonPanel.add(blueButton);
25         
26         add(buttonPanel);
27         
28         //将此对象通过this传到ColorAction的构造器。
29         ColorAction redAction = new ColorAction(this,Color.red);
30         ColorAction yellowAction = new ColorAction(this,Color.yellow);
31         ColorAction blueAction = new ColorAction(this,Color.blue);
32         
33         redButton.addActionListener(redAction);
34         yellowButton.addActionListener(yellowAction);
35         blueButton.addActionListener(blueAction);
36     }
37     
38     public void setButtonPanelsBackground(Color backgroundColor) {
39         buttonPanel.setBackground(backgroundColor);
40     }
41     
42     public static void main(String[] args) {
43         EventQueue.invokeLater(new Runnable() {
44             public void run() {
45                 JFrame frame = new ButtonFrame2();
46                 frame.setTitle("ColorButton");
47                 frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
48                 frame.setVisible(true);
49             }
50         });
51     }
52 }
53 
54 class ColorAction implements ActionListener {
55     private ButtonFrame2 buttonFrame;
56     private Color backgroundColor;
57     
58     //通过构造器的方法把ButtonFrame2对象传过来,这个对象包含了成员变量buttonPanel,以便对其更换背景色。
59     public ColorAction(ButtonFrame2 buttonFrame,Color c) {
60         this.buttonFrame = buttonFrame; //this.buttonFrame只是对象管理者,管理的还是ButtonFrame的对象frame。
61         backgroundColor = c;
62     }
63     public void actionPerformed(ActionEvent event) {
64         buttonFrame.setButtonPanelsBackground(backgroundColor);
65         //这是我们在ButtonFrame2中添加的新方法。
66     }
67 }
68 
69 class ButtonPanel extends JPanel {
70     private static final int DEFAUT_WIDTH = 300;
71     private static final int DEFAUT_HEIGHT = 200;
72     
73     public ButtonPanel() {
74         setBackground(Color.pink);
75     }
76 
77     @Override
78     protected void paintComponent(Graphics g) {
79         g.create();
80         super.paintComponent(g);
81     }
82 
83     @Override
84     public Dimension getPreferredSize() {
85         return new Dimension(DEFAUT_WIDTH,DEFAUT_HEIGHT);
86     }
87 }

ButtonFrame2

   --------------------------------------------------------------------------------------------------------

  代码存在一个缺陷,就是在构造按钮、添加按钮到面板、构造相应颜色的监听器和注册监听器的时候有代码复制的情况,为了避免代码复制,我们可以创建一个makeButton方法,把这些重复的操作包含在内,实现如下:

 1 package buttonPanel3;
 2 
 3 import java.awt.*;
 4 import java.awt.event.*;
 5 import javax.swing.*;
 6 
 7 public class ButtonFrame3 extends JFrame {
 8     private ButtonPanel buttonPanel;
 9     private static final int DEFAULT_WIDTH = 300;
10     private static final int DEFAULT_HEIGHT = 200;
11     
12     public ButtonFrame3() {
13         setSize(DEFAULT_WIDTH,DEFAULT_HEIGHT);
14         setLocationByPlatform(true);
15         
16         buttonPanel = new ButtonPanel();        
17         add(buttonPanel);
18         
19         makeButton("RED",Color.red);
20         makeButton("YELLOW",Color.yellow);
21         makeButton("BLUE",Color.blue);
22     }
23     
24     //为了避免代码重复,我们将重复的操作放在这个函数里。
25     public void makeButton(String name,final Color bg) {
26         JButton button = new JButton(name);
27         buttonPanel.add(button);
28         button.addActionListener(new ActionListener() { //可以new一个接口出来,但是后面必须接花括号实现内部方法。
29             public void actionPerformed(ActionEvent event) {
30                 buttonPanel.setBackground(bg);
31             }
32         });
33     }
34     
35     public static void main(String[] args) {
36         EventQueue.invokeLater(new Runnable() {
37             public void run() {
38                 JFrame frame = new ButtonFrame3();
39                 frame.setTitle("ColorButton");
40                 frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
41                 frame.setVisible(true);
42             }
43         });
44     }
45 }
46 
47 class ButtonPanel extends JPanel {
48     private static final int DEFAUT_WIDTH = 300;
49     private static final int DEFAUT_HEIGHT = 200;
50 
51     @Override
52     protected void paintComponent(Graphics g) {
53         g.create();
54         super.paintComponent(g);
55     }
56 
57     @Override
58     public Dimension getPreferredSize() {
59         return new Dimension(DEFAUT_WIDTH,DEFAUT_HEIGHT);
60     }
61 }

  在代码中,监听器只被调用了一次,也就是在addActionListener()时。所以我们没有必要为监听器单独做一个类出来,而是只需在用到监听器时直接new一个ActionListener接口出来,并在花括号里实现接口方法即可。

  --------------------------------------------------------------------------------------------------------

 

 1 package buttonPanel4;
 2 
 3 import java.awt.*;
 4 import java.awt.event.*;
 5 import javax.swing.*;
 6 
 7 //将buttonPanel所在的ButtonFrame4实现接口。
 8 public class ButtonFrame4 extends JFrame implements ActionListener {
 9     private ButtonPanel buttonPanel;
10     private static final int DEFAULT_WIDTH = 300;
11     private static final int DEFAULT_HEIGHT = 200;
12     
13     public ButtonFrame4() {
14         setSize(DEFAULT_WIDTH,DEFAULT_HEIGHT);
15         setLocationByPlatform(true);
16         
17         buttonPanel = new ButtonPanel();        
18         add(buttonPanel);
19         
20         makeButton("RED");
21         makeButton("YELLOW");
22         makeButton("BLUE");
23     }
24     
25     public void makeButton(String name) {
26         JButton button = new JButton(name);
27         buttonPanel.add(button);
28         button.addActionListener(this);
29         //直接注册this这个接口。
30     }
31     
32     //覆盖接口方法,String getActionCommand()为java.awt.event.ActionEvent的方法,返回动作事件相关的命令字符串,在这里等于按钮标签。
33     //需要用到if else选择语句。
34     @Override
35     public void actionPerformed(ActionEvent event) {
36         String c = event.getActionCommand();
37         if(c == "RED") {
38             buttonPanel.setBackground(Color.red);
39         }else if(c == "YELLOW") {
40             buttonPanel.setBackground(Color.yellow);
41         }else {
42             buttonPanel.setBackground(Color.blue);
43         }
44     }
45     
46     public static void main(String[] args) {
47         EventQueue.invokeLater(new Runnable() {
48             public void run() {
49                 JFrame frame = new ButtonFrame4();
50                 frame.setTitle("ColorButton");
51                 frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
52                 frame.setVisible(true);
53             }
54         });
55     }
56 }
57 
58 class ButtonPanel extends JPanel {
59     private static final int DEFAUT_WIDTH = 300;
60     private static final int DEFAUT_HEIGHT = 200;
61 
62     @Override
63     protected void paintComponent(Graphics g) {
64         g.create();
65         super.paintComponent(g);
66     }
67 
68     @Override
69     public Dimension getPreferredSize() {
70         return new Dimension(DEFAUT_WIDTH,DEFAUT_HEIGHT);
71     }
72 }

企鹅博客
  • 本文由 发表于 2020年1月23日03:33:41
  • 转载请务必保留本文链接:https://www.qieseo.com/134399.html

发表评论