AWT组件库

JDK提供了能创建图形用户界面的许多组件。本模块考察这些AWT组件,以及非组件的AWT类,例如Color、Font和图形用户界面的打印。

AWT的特点

AWT提供了各种标准特性。本模块将介绍你可以使用的组件,并且概述了你需要知道的一些特殊情形。

首先将描述AWT的各个组件。它们用来创建用户界面。你需要知道所有图形用户界面组件,这样你就可以在创建你自己的界面时选择合适的组件。

AWT组件提供了控制界面外观的机制,包括用于文本显示的颜色和字体。

此外,AWT还支持打印。这个功能是在JDK1.1版中引入的。

按钮(Button)

你已经比较熟悉Button组件了。这个组件提供了“按下并动作”的基本用户界面。可以构造一个带文本标签的按钮,用来告诉用户它的作用。

Button b = new
Button("Sample");
b.addActionListener(this);
add(b);

任何实现了被注册为监听者的ActionListener接口的类,它的actionPerformed()方法将在一个按钮被鼠标点击“按下”时被调用。

public void
actionPerformed(ActionEvent ae) {
System.out.println("Button
press received.");
System.out.println("Button's
action command is: "  +
ae.getActionCommand());
}

按钮被按下时调用的getActionCommand()方法在缺省情况下将返回标签字符串。用按钮的setActionCommand()方法改变动作命令和标签。

Button b = new
Button("Sample");
b.setActionCommand("Action
Command Was Here!");
b.addActionListener(this);
add(b);

注-SampleButton和ActionCommandButton的完整源代码可以在course_examples目录下找到。

复选框(Checkbox)

Checkbox组件提供一种简单的“开/关”输入设备,它旁边有一个文本标签。

Frame f = new
Frame("Checkbox")
Checkbox one = new
Checkbox("One", true);
Checkbox two = new
Checkbox("Two", false);
Checkbox three = new
Checkbox("Three", true);
one.addItemListener(this);
two.addItemListener(this);
three.addItemListener(this);
f.add(one);
f.add(two);
f.add(three);

选取或不选取(取消)一个复选框的事件将被送往ItemListener接口。所传递的ItemEvent包含getStatechange()方法,它根据实际情况返回ItemEvent.DESELECTED或ItemEvent.SELECTED。getItem()方法将受到影响的复选框作为一个表示这个复选框标签的String对象返回。

class Handler implements ItemListener {
public void itemStateChanged(ItemEvent ev) {
String state = "deselected";
if (ev.getStateChange() == ItemEvent.SELECTED){
state = "selected";
}
System.out.println(ev.getItem() + " " + state);
}
}

复选框组-单选框(Checkbox group-Radio

Button)

复选框组提供了将多个复选框作为互斥的一个集合的方法,因此在任何时刻,这个集合中只有一个复选框的值是true。值为true的复选框就是当前被选中的复选框。你可以使用带有一个额外的CheckboxGroup参数的构造函数来创建一组中的每个复选框。正是这个CheckBoxGroup对象将各个复选框连接成一组。如果你这么做的话,那么复选框的外观会发生改变,而且所有和一个复选框组相关联的复选框将表现出“单选框”的行为。

Frame f = new Frame("Checkbox Group");
CheckboxGroup cbg = new CheckboxGroup();
Checkbox one = new Checkbox("One", false, cbg);
Checkbox two = new Checkbox("Two", false, cbg);
Checkbox three = new Checkbox("Three", true, cbg);
one.addItemListener(this);
two.addItemListener(this);
three.addItemListener(this);
f.add(one);
f.add(two);
f.add(three);

下拉列表(Choice)

下拉列表组件提供了一个简单的“从列表中选取一个”类型的输入。例如:

Frame f = new Frame("Choice");
Choice c = new Choice();
c.add("First");
c.add("Second");
c.add("Third");
c.addItemListener(this);
f.add(c);

点击下拉列表组件时,它会显示一个列表,列表中包含了所有加入其中的条目。注意所加入的条目是String对象。

ItemListener接口用来观察下拉列表组件的变化,其细节和复选框的相同。

画布(Canvas)

画布提供了一个空白(背景色)的空间。除非你用setSize()显式地定义它的大小,否则它的大小就是0×0。

画布的空间可以用来绘图、显示文本、接收键盘或鼠标的输入。后面的模块将告诉你如何有效地在AWT中绘图。

通常,画布用来提供一个一般的绘图空间或者为客户组件提供工作区域。

画布可以“监听”所有适用于一个普通组件的事件。特别地,你还可能想增加KeyListener、MouseMotionListener和MouseListener对象,以允许某种方式对用户输入作出反应。

注-如要在画布中接收键盘事件,必须调用画布的requestFocus()方法。如果缺少这个步骤,一般是不能将击键“导向”画布的。键盘事件会送往另一个组件,或整个地丢失了。

下面是画布的一个范例。每击一次键,这个程序就改变一次画布的颜色。

import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class MyCanvas extends Canvas
implements KeyListener {
int index;
Color colors[] = {Color.red, Color.green, Color.blue };
public
void paint(Graphics g) {
g.setColor(colors[index]);
g.fillRect(0,0,getSize().width,getSize().height);
}
public static void main(String args[]) {
Frame f = new Frame("Canvas");
MyCanvas mc = new MyCanvas();
f.add(mc,BorderLayout.CENTER);
f.setSize(150, 150);
mc.requestFocus();
mc.addKeyListener(mc);
f.setVisible(true);
}
public void keyTyped(KeyEvent ev) {
index++;
if (index == colors.length) {
index =0;
}
repaint();
}
public void keyPressed(KeyEvent ev) {
}
public void keyReleased(KeyEvent ev) {
}
}

标签(Label)

一个标签对象显示一行静态文本。程序可以改变文本,但用户不能改变。标签没有任何特殊的边框和装饰。

Label l = new Label( " Hello " );
add(l);

标签通常不处理事件,但也可以按照和画布相同的方式来处理事件。也就是说,只有调用了requestFocus()方法后,才能可靠地检取击键事件。

文本域(Textfield)

文本域是一个单行的文本输入设备。例如:

TextField f = new
TextField("Single line" " , 30);
f.addActionListener(this);
add(f);

因为只允许有一行,所以当按下Enter或Return键时,ActionListener可以通过actionPerformed()知道这个事件。如果需要,还可以增加其他的组件监听者。

除了注册一个ActionListener,你还可以注册一个TextListener来接收关于个别击键的通知。它的回调方法是textValueChanged(TextEvent)。

文本区(TextArea)

文本区是一个多行多列的文本输入设备。你可以用setEditable(boolean)将它设置成只读的。文本区将显示水平和垂直的滚动条。

下面这个范例创建了一个4行×30字符的文本,最初它含有“Hello!”。

TextArea t = new TextArea( " Hello! " , 4, 30);
t.addTextListener(this);
add(t);

你用addTexListener指定的监听者将以和文本域相同的方式接收到关于击键的通知。

你可以给文本区增加一般的组件监听者,然而,由于文本是多行的,按下Enter键将导致把另一个字符送入缓冲。如果你需要识别“输入的结束”,你可以在文本区旁放置一个“应用”或“确认”按钮,以便用户指明“输入的结束”。

文本组件(Text Components)

文本区和文本域的文档都分为两个部分。如果你查找一个称为文本组件的类,你会找到若干个文本区和文本域共有的方法。例如,文本区和文本域都是文本组件的子类。

你已经知道文本区和文本域类的构造函数允许你指定显示所用的列数。记住所显示的组件大小是由布局管理器决定的,因此这些设置可能被忽略。进而,列数是按所用字体的平均宽度计算的。如果使用一种空间比例字体,实际显示的字符数可能相差很大。

由于文本组件实现了TextListener,诸如文本域、文本区及其它子类都有对击键事件的内置支持。

列表(list)

一个列表将各个文本选项显示在一个区域中,这样就可以在同时看到若干个条目。列表可以滚动,并支持单选和多选两种模式。例如:

List l = new List(4, true);
1.add("Hello");
1.add("there");
1.add("how");
1.add("are");

构造函数的数值参数定义了按可见列计算的列表高度。这个值也可能被布局管理器覆盖。一个值为true的布尔型参数表明这个列表允许用户作多个选择。

选取或取消一个条目时,AWT将一个ItemEvent的实例送往列表。用户双击滚动列表中的一个条目时,单选模式和多选模式的列表都会产生一个ActionEvent。根据每个平台的约定来决定列表中的条目是否被选取。对于UNIX/Motif环境,单击会加亮列表中的一个条目,只有双击才会触发列表事件(选取条目)。

对话框(Dialog)

对话框组件与一个框架相关联。它是一个带有一些装饰的自由窗口。它与框架的区别在于所提供的一些装饰,而且你可以生成一个“模式”对话框,它在被关闭前将存储所有窗口的输入。

对话框可以是无模式和模式的。对于无模式对话框,用户可以同时与框架和对话框交互。“模式”对话框在被关闭前将阻塞包括框架在内的其他所有应用程序的输入。

由于对话框是窗口的子类,所以它的缺省布局管理器是Border Layout。

Dialog d = new Dialog(f, "Dialog", false);
d.add(new Label("Hello, I'm a
Dialog",Border.Layout.CENTER));
d.pack();

对话框在创建时通常是不可见的。通常在对按下按钮等用户输入作出反应时,才显示对话框。

public void actionPerformed(ActionEvent ev) {
d.setVisible(true);
}

要隐藏对话框,你必须调用setVisible(false)。典型的做法是对它添加一个WindowListener,并等待对那个监听者的windowClosing()调用。这和处理一个框架的关闭是平行的。

文件对话框(File Dialog)

文件对话框是文件选择设备的一个实现。它有自己的自由窗口,以及窗口元素,并且允许用户浏览文件系统,以及为以后的操作选择一个特定的文件。例如:

FileDialog d = new FileDialog(parentFrame, "FileDialog");
d.setVisible(true);// block here until OK selected
String fname = d.getFile();

通常并不需要处理FileDialog的事件。调用setVisible(true)将阻塞事件,直至用户选择OK,这时会请求用户选择的文件名。这个信息将作为一个String返回。

滚动面板(Scroll

Pane)

滚动面板提供了一种不能作为自由窗口的通用容器。它应当总是和一个容器相关联(例如,框架)。它提供了到一个更大的区域的视窗以及操纵这个视窗的滚动条。例如:

Frame f = new Frame("ScrollPane");
Panel p = new Panel();
ScrollPane sp = new ScrollPane();
p.setLayout(new GridLayout(3, 4));
sp.add(p);
f.add(sp, "Center");
f.setSize(200, 200);
f.serVisible(true);

滚动面板创建和管理滚动条,并持有一个组件。你不能控制它所用的布局管理器。你可以将一个面板加入到滚动面板中,配置面板的布局管理器,并在那个面板中放置你的组件。

通常,你不处理滚动面板上的事件;这些事件通过滚动面板所包含的组件进行处理。