你可能注意到了:如果编译并运行了前面的applet,当按下按钮的时候,什么也没发生。
现在就是应该深入进来,编写一些代码以决定发生什么动作的时候了。事件驱动编程(包
含了许多关于GUI的内容)的主要内容,就是把事件同处理事件的代码相关联起来。
在Swing中,这种关联的方式就是通过把接口(图形组件)和实现(当和组件相关的事件
发生时,你要执行的代码)清楚地分离而实现的。每个Swing组件都能够报告其上所有可
能发生的事件,并且它能单独报告每种事件。所以,你要是对诸如“鼠标移动到按钮上”
这样的事件不感兴趣的话,那么你不注册这样的事件就可以了。这种处理事件驱动编程的
方式非常直接和优雅,一旦你理解了其基本概念,就能够很容易将其应用到甚至从未见过
Swing组件之上。实际上,只要是JavaBean(本章后面讨论),这个模式都适用。
首先,我们针对所使用的组件,看看对什么事件感兴趣。对于JButton,这个“感兴趣的事
件”就是按钮被按下。为了表明你对按钮按下事件感兴趣,可以调用JButton的
addActionListener( )方法。这个方法接受一个实现了ActionListener接口的对象作为参
数,ActionListener接口只包含了actionPerformed( )方法。所以要想把事件处理代码和
JButton关联,就先要用一个类实现ActionListener接口,然后把这个类的对象通过
addActionListener( )方法注册给JButton。这样按钮按下的时候就会调用
actionPerformed( )方法了(通常这也称为回调)。
但是按钮按下的时候应该有什么结果呢?我们希望看到屏幕有所改变,所以在这里介绍一
个新的 Swing 组件:JTextField。这个组件能够输入文本,在本例里,将由程序插入文本。
尽管有很多方法可以创建 JTextField,但是最简单的就是告诉其构造器你所希望的文本域
宽度。一旦 JTextField 被放置到了窗体上,你就可以使用 setText( )方法来修改它的内容
了(JTextField 还有很多方法,不过你应该先到 java.sun.com 看一下 HTML 格式的 JDK
文档)。下面就是其具体程序:
//: c14:Button2.java
// Responding to button presses.
// <applet code=Button2 width=200 height=75></applet>
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import com.bruceeckel.swing.*;
public class Button2 extends JApplet {
private JButton
b1 = new JButton("Button 1"),
b2 = new JButton("Button 2");
private JTextField txt = new JTextField(10);
class ButtonListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
String name = ((JButton)e.getSource()).getText();
txt.setText(name);
}
}
private ButtonListener bl = new ButtonListener();
public void init() {
b1.addActionListener(bl);
b2.addActionListener(bl);
Container cp = getContentPane();
cp.setLayout(new FlowLayout());
cp.add(b1);
cp.add(b2);
cp.add(txt);
}
public static void main(String[] args) {
Console.run(new Button2(), 200, 75);
}
} ///:~
创建JTextField并把它放置在窗体上的步骤,同JButton或者其它Swing组件所采用的步骤
相同。这里与前面例子的不同之处在于创建了一个ButtonListener对象,它实现了前面提
到过的ActionListener接口。actionPerformed()方法的参数是ActionEvent类型,它包
含了事件源和事件的所有信息。本例中,我希望表明是哪个按钮被按下;getSource( )方
法产生的对象表明了事件的来源,我假设(使用了类型转换)这个对象是JButton。getText( )
方法将返回按钮上的文本,这个文本被写进JTextField,以证明当按钮按下的时候代码确
实被调用了。
在init( )中,使用了addActionListener( )方法来将ButtonListener对象注册给按钮。
通常,把ActionListener实现成匿名内部类会显得更方便,尤其是对每个监听器类只使用
一个实例的时候更是如此。可以向下面这样修改Button2.java,这里使用了匿名内部类:
//: c14:Button2b.java
// Using anonymous inner classes.
// <applet code=Button2b width=200 height=75></applet>
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import com.bruceeckel.swing.*;
public class Button2b extends JApplet {
private JButton
b1 = new JButton("Button 1"),
b2 = new JButton("Button 2");
private JTextField txt = new JTextField(10);
private ActionListener bl = new ActionListener() {
public void actionPerformed(ActionEvent e) {
String name = ((JButton)e.getSource()).getText();
txt.setText(name);
}
};
public void init() {
b1.addActionListener(bl);
b2.addActionListener(bl);
Container cp = getContentPane();
cp.setLayout(new FlowLayout());
cp.add(b1);
cp.add(b2);
cp.add(txt);
}
public static void main(String[] args) {
Console.run(new Button2b(), 200, 75);
}
} ///:~
现在就是应该深入进来,编写一些代码以决定发生什么动作的时候了。事件驱动编程(包
含了许多关于GUI的内容)的主要内容,就是把事件同处理事件的代码相关联起来。
在Swing中,这种关联的方式就是通过把接口(图形组件)和实现(当和组件相关的事件
发生时,你要执行的代码)清楚地分离而实现的。每个Swing组件都能够报告其上所有可
能发生的事件,并且它能单独报告每种事件。所以,你要是对诸如“鼠标移动到按钮上”
这样的事件不感兴趣的话,那么你不注册这样的事件就可以了。这种处理事件驱动编程的
方式非常直接和优雅,一旦你理解了其基本概念,就能够很容易将其应用到甚至从未见过
Swing组件之上。实际上,只要是JavaBean(本章后面讨论),这个模式都适用。
首先,我们针对所使用的组件,看看对什么事件感兴趣。对于JButton,这个“感兴趣的事
件”就是按钮被按下。为了表明你对按钮按下事件感兴趣,可以调用JButton的
addActionListener( )方法。这个方法接受一个实现了ActionListener接口的对象作为参
数,ActionListener接口只包含了actionPerformed( )方法。所以要想把事件处理代码和
JButton关联,就先要用一个类实现ActionListener接口,然后把这个类的对象通过
addActionListener( )方法注册给JButton。这样按钮按下的时候就会调用
actionPerformed( )方法了(通常这也称为回调)。
但是按钮按下的时候应该有什么结果呢?我们希望看到屏幕有所改变,所以在这里介绍一
个新的 Swing 组件:JTextField。这个组件能够输入文本,在本例里,将由程序插入文本。
尽管有很多方法可以创建 JTextField,但是最简单的就是告诉其构造器你所希望的文本域
宽度。一旦 JTextField 被放置到了窗体上,你就可以使用 setText( )方法来修改它的内容
了(JTextField 还有很多方法,不过你应该先到 java.sun.com 看一下 HTML 格式的 JDK
文档)。下面就是其具体程序:
//: c14:Button2.java
// Responding to button presses.
// <applet code=Button2 width=200 height=75></applet>
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import com.bruceeckel.swing.*;
public class Button2 extends JApplet {
private JButton
b1 = new JButton("Button 1"),
b2 = new JButton("Button 2");
private JTextField txt = new JTextField(10);
class ButtonListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
String name = ((JButton)e.getSource()).getText();
txt.setText(name);
}
}
private ButtonListener bl = new ButtonListener();
public void init() {
b1.addActionListener(bl);
b2.addActionListener(bl);
Container cp = getContentPane();
cp.setLayout(new FlowLayout());
cp.add(b1);
cp.add(b2);
cp.add(txt);
}
public static void main(String[] args) {
Console.run(new Button2(), 200, 75);
}
} ///:~
创建JTextField并把它放置在窗体上的步骤,同JButton或者其它Swing组件所采用的步骤
相同。这里与前面例子的不同之处在于创建了一个ButtonListener对象,它实现了前面提
到过的ActionListener接口。actionPerformed()方法的参数是ActionEvent类型,它包
含了事件源和事件的所有信息。本例中,我希望表明是哪个按钮被按下;getSource( )方
法产生的对象表明了事件的来源,我假设(使用了类型转换)这个对象是JButton。getText( )
方法将返回按钮上的文本,这个文本被写进JTextField,以证明当按钮按下的时候代码确
实被调用了。
在init( )中,使用了addActionListener( )方法来将ButtonListener对象注册给按钮。
通常,把ActionListener实现成匿名内部类会显得更方便,尤其是对每个监听器类只使用
一个实例的时候更是如此。可以向下面这样修改Button2.java,这里使用了匿名内部类:
//: c14:Button2b.java
// Using anonymous inner classes.
// <applet code=Button2b width=200 height=75></applet>
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import com.bruceeckel.swing.*;
public class Button2b extends JApplet {
private JButton
b1 = new JButton("Button 1"),
b2 = new JButton("Button 2");
private JTextField txt = new JTextField(10);
private ActionListener bl = new ActionListener() {
public void actionPerformed(ActionEvent e) {
String name = ((JButton)e.getSource()).getText();
txt.setText(name);
}
};
public void init() {
b1.addActionListener(bl);
b2.addActionListener(bl);
Container cp = getContentPane();
cp.setLayout(new FlowLayout());
cp.add(b1);
cp.add(b2);
cp.add(txt);
}
public static void main(String[] args) {
Console.run(new Button2b(), 200, 75);
}
} ///:~
本书中的例子将倾向于(可能的话)使用匿名内部类的方式。