事件处理可以简单地这么理解,当有一个事件产生,程序要根据这个事件做出响应。比如,我们做了一个可以通过按钮改变背景颜色的窗口,当我们点击按钮时便产生了一个事件,程序会根据这个事件来做出响应,也就是去改变背景的颜色。
那么程序是怎样做出响应的呢?这就需要事件监听器actionlistener,这是一个接口,里面包含了actionperformed方法(也就是根据事件去执行的操作),所以我们要实现这个接口(实现接口里的actionperformed方法)做出一个监听器对象出来,并且用按钮来注册这个监听器对象,这样当按钮被点击的时候,就会调用这个监听器来执行响应了。
运行结果
代码(第42行开始为实现接口):
package buttonpanel;
import java.awt.*;
import java.awt.event.*; //事件监听器接口actionlistener的位置。
import javax.swing.*;
public class buttonframe extends jframe {
private buttonpanel buttonpanel;
private static final int default_width = 300;
private static final int default_height = 200;
public buttonframe() {
setsize(default_width,default_height);
setlocationbyplatform(true);
//构造按钮
jbutton redbutton = new jbutton(red);
jbutton yellowbutton = new jbutton(yellow);
jbutton bluebutton = new jbutton(blue);
buttonpanel = new buttonpanel();
//添加按钮到面板
buttonpanel.add(redbutton);
buttonpanel.add(yellowbutton);
buttonpanel.add(bluebutton);
add(buttonpanel);
//构造对应颜色的动作监听器
coloraction redaction = new coloraction(color.red);
coloraction yellowaction = new coloraction(color.yellow);
coloraction blueaction = new coloraction(color.blue);
//每个按钮注册对应的监听器
redbutton.addactionlistener(redaction);
yellowbutton.addactionlistener(yellowaction);
bluebutton.addactionlistener(blueaction);
}
//为了方便调用buttonpanel,将coloraction作为buttonframe的内部类。
private class coloraction implements actionlistener {
private color backgroundcolor;
public coloraction(color c) {
backgroundcolor = c;
}
public void actionperformed(actionevent event) {
buttonpanel.setbackground(backgroundcolor);
}
}
public static void main(string[] args) {
eventqueue.invokelater(new runnable() {
public void run() {
jframe frame = new buttonframe();
frame.settitle(colorbutton);
frame.setdefaultcloseoperation(exit_on_close);
frame.setvisible(true);
}
});
}
}
class buttonpanel extends jpanel {
private static final int defaut_width = 300;
private static final int defaut_height = 200;
@override
protected void paintcomponent(graphics g) {
g.create();
super.paintcomponent(g);
}
@override
public dimension getpreferredsize() {
return new dimension(defaut_width,defaut_height);
}
}
在上述代码中,为了方便监听器调用buttonpanel,将coloraction作为buttonframe的内部类。如果将coloraction类独立出去,需要将buttonpanel传递到coloraction,实现如下:
package buttonpanel2;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class buttonframe2 extends jframe {
private buttonpanel buttonpanel;
private static final int default_width = 300;
private static final int default_height = 200;
public buttonframe2() {
setsize(default_width,default_height);
setlocationbyplatform(true);
jbutton redbutton = new jbutton(red);
jbutton yellowbutton = new jbutton(yellow);
jbutton bluebutton = new jbutton(blue);
buttonpanel = new buttonpanel();
buttonpanel.add(redbutton);
buttonpanel.add(yellowbutton);
buttonpanel.add(bluebutton);
add(buttonpanel);
//将此对象通过this传到coloraction的构造器。
coloraction redaction = new coloraction(this,color.red);
coloraction yellowaction = new coloraction(this,color.yellow);
coloraction blueaction = new coloraction(this,color.blue);
redbutton.addactionlistener(redaction);
yellowbutton.addactionlistener(yellowaction);
bluebutton.addactionlistener(blueaction);
}
public void setbuttonpanelsbackground(color backgroundcolor) {
buttonpanel.setbackground(backgroundcolor);
}
public static void main(string[] args) {
eventqueue.invokelater(new runnable() {
public void run() {
jframe frame = new buttonframe2();
frame.settitle(colorbutton);
frame.setdefaultcloseoperation(exit_on_close);
frame.setvisible(true);
}
});
}
}
class coloraction implements actionlistener {
private buttonframe2 buttonframe;
private color backgroundcolor;
//通过构造器的方法把buttonframe2对象传过来,这个对象包含了成员变量buttonpanel,以便对其更换背景色。
public coloraction(buttonframe2 buttonframe,color c) {
this.buttonframe = buttonframe; //this.buttonframe只是对象管理者,管理的还是buttonframe的对象frame。
backgroundcolor = c;
}
public void actionperformed(actionevent event) {
buttonframe.setbuttonpanelsbackground(backgroundcolor);
//这是我们在buttonframe2中添加的新方法。
}
}
class buttonpanel extends jpanel {
private static final int defaut_width = 300;
private static final int defaut_height = 200;
public buttonpanel() {
setbackground(color.pink);
}
@override
protected void paintcomponent(graphics g) {
g.create();
super.paintcomponent(g);
}
@override
public dimension getpreferredsize() {
return new dimension(defaut_width,defaut_height);
}
}
buttonframe2
代码存在一个缺陷,就是在构造按钮、添加按钮到面板、构造相应颜色的监听器和注册监听器的时候有代码复制的情况,为了避免代码复制,我们可以创建一个makebutton方法,把这些重复的操作包含在内,实现如下:
package buttonpanel3;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class buttonframe3 extends jframe {
private buttonpanel buttonpanel;
private static final int default_width = 300;
private static final int default_height = 200;
public buttonframe3() {
setsize(default_width,default_height);
setlocationbyplatform(true);
buttonpanel = new buttonpanel();
add(buttonpanel);
makebutton(red,color.red);
makebutton(yellow,color.yellow);
makebutton(blue,color.blue);
}
//为了避免代码重复,我们将重复的操作放在这个函数里。
public void makebutton(string name,final color bg) {
jbutton button = new jbutton(name);
buttonpanel.add(button);
button.addactionlistener(new actionlistener() { //可以new一个接口出来,但是后面必须接花括号实现内部方法。
public void actionperformed(actionevent event) {
buttonpanel.setbackground(bg);
}
});
}
public static void main(string[] args) {
eventqueue.invokelater(new runnable() {
public void run() {
jframe frame = new buttonframe3();
frame.settitle(colorbutton);
frame.setdefaultcloseoperation(exit_on_close);
frame.setvisible(true);
}
});
}
}
class buttonpanel extends jpanel {
private static final int defaut_width = 300;
private static final int defaut_height = 200;
@override
protected void paintcomponent(graphics g) {
g.create();
super.paintcomponent(g);
}
@override
public dimension getpreferredsize() {
return new dimension(defaut_width,defaut_height);
}
}
buttonframe3
在代码中,监听器只被调用了一次,也就是在addactionlistener()时。所以我们没有必要为监听器单独做一个类出来,而是只需在用到监听器时直接new一个actionlistener接口出来,并在花括号里实现接口方法即可。