第六章Java图形用户接口

来源:互联网 发布:数据分散程度的统计量 编辑:程序博客网 时间:2024/05/29 19:23

 

 

对一个优秀的应用程序来说,良好的图形用户接口是必不可少的。缺少良好的图形用户接口,将会给用户理解和使用应用程序带来很多不便。很难想象用户为了学会使用一个应用程序,去记一大堆命令。

 

Java提供了生成一个良好的图形用户接口所需要的一些基本元件:

面板(Panel)、按钮(Button)、标签(Label)、画板(Canvases)、滚动条(Scrollbar)、列表框(List)、文本域(Text Field)、文本区(Text Area)。

6.1 面板

面板提供了建立应用程序的空间。你可以把图形元件(包括其他面板)放在一个面板上。Applet类提供了一个基本的面板。

6.1.1 布局管理

Java提供了几种布局:顺序布局(Flow Layout)、边界布局(Border Layout)和网格布局(Grid Layout)。

6.1.1.1 顺序布局

顺序布局(Flow Layout)是最基本的一种布局,面板的缺省布局就是顺序布局。顺序布局指的是把图形元件一个接一个地放在面板上。下面是一个顺序布局的例子:

import java.awt.*;

import java.applet.Applet;

public class myButtons extends Applet {

Button button1, button2, button3;

public void init() {

button1 = new Button("确 定");

button2 = new Button("打 开");

button3 = new Button("关 闭");

add(button1);

add(button2);

add(button3);

}

}

6.1.1.2 边界布局

边界布局包括五个区:北区、南区、东区、西区和中区。这几个区在面板上的分布规律是“上北下南,左西右东”。下面是一个边界布局的例子:

import java.awt.*;

import java.applet.Applet;

public class buttonDir extends Applet {

Button buttonN, buttonS, buttonW, buttonE, buttonC;

public void init() {

setLayout(new BorderLayout());

buttonN = new Button("水");

buttonS = new Button("火");

buttonE = new Button("木");

buttonW = new Button("金");

buttonC = new Button("土");

add("North", buttonN);

add("South", buttonS);

add("East", buttonE);

add("West", buttonW);

add("Center", buttonC);

}

}

6.1.1.3 网格布局

网格布局把面板分成一个个的网格,你可以给出网格的行数和列数。下面是一个网格布局的例子:

import java.awt.*;

import java.applet.Applet;

public class buttonGrid extends Applet {

Button button1, button2, button3, button4, button5, button6, button7, button8;

public void init() {

setLayout(new GridLayout(4,2));

button1 = new Button("乾");

button2 = new Button("坤");

button3 = new Button("艮");

button4 = new Button("震");

button5 = new Button("坎");

button6 = new Button("离");

button7 = new Button("巽");

button8 = new Button("兑");

add(button1);

add(button2);

add(button3);

add(button4);

add(button5);

add(button6);

add(button7);

add(button8);

}

}

6.2 按钮

6.2.1 按钮事件

用户点一下按钮,就会有一个按钮事件发生。你可以通过覆盖一个applet的action成员函数来捕捉按钮事件。

public boolean action (Event e, Object o) {

if (e.target instanceof Button) {

system.out.println ((string) o);

}else{

System.out.println ("Non-button event");

}

return true;

}

6.2.2 按钮类型

Java提供了标准的按压式按钮,同时也提供了选择式按钮和标记式按钮。

6.2.2.1 选择式按钮

选择式按钮提供了从几个选项中选一个选项的功能。下面是从几个市中选一个市的例子,市名放在选择式按钮中:

CityChooser = new Choice();

CityChooser.addItem("北京");

CityChooser.addItem("上海");

CityChooser.addItem("天津");

add(CityChooser);

6.2.2.2 标记式按钮

标记式按钮的状态作为标记框事件的对象参数返回。下面是一个标记式按钮的例子:

Checkbox fillStyleButton;

fillStyleButton = new Checkbox("Solid");

public boolean action(Event e, Object arg) {

if (e.target instanceof Checkbox) {

System.out.println("Checkbox: " + arg);

}

return true;

}

6.2.2.3 按键式按钮

按键式按钮是一组按钮,用户可以选中其中一个,同时这一组中的其他按钮将被关闭。下面是一个按键式按钮的例子:

public class CheckBox extends Applet {

CheckboxGroup cbg;

public void init() {

cbg = new CheckboxGroup();

add (new Checkbox("one ", cbg, true));

add (new Checkbox("two ", cbg,false));

add (new Checkbox("three", cbg, false));

}

}

6.2.3 自包含按钮

Java语言的面向对象特性使我们能够创建完全自包含的按钮。在自包含按钮里,你可以在扩展按钮类里建立事件控制函数。下面是一个自包含按钮的例子:

import java.awt.*;

import java.applet.Applet;

class okButton extends Button {

public okButton() {

setLabel("Ok");

}

public boolean action(Event e, Object arg) {

System.out.println("OKButton");

return true;

}

}

public class buttontest extends Applet {

okButton myOkButton;

public void init() {

myOkButton = new okButton();

add(myOkButton);

}

}

6.3 标签; 标签是一种放到面板上的静止的正文。下面是一个标签的例子:

import java.awt.*;

import java.applet.Applet;

public class label extends Applet {

public void init() {

setLayout(new FlowLayout(FlowLayout.CENTER, 10, 10));

Label label1 = new Label("你好!");

Label label2 = new Label("另一个标签");

add(label1);

add(label2);

}

}

6.4 列表框

列表框使用户易于操作大量的选项。创建列表框的方法和Choice button有些相似。列表框的所有条目都是可见的,如果选项很多,超出了列表框可见区的范围,则列表框的旁边将会有一个滚动条。

首先,创建列表框:

List l = new List(4, false);

这个成员函数创建了一个显示4行的列表框。第二个参数“false”表示这个列表框是单选的,如果是“true”,则表示是多选的。

下面增加列表框的选项:addItem("北京大学");addItem("清华大学");addItem("吉林大学");addItem("复旦大学"); addItem("南开大学");addItem("天津大学");addItem("南开大学"); add(l);

6.4.1 在列表框中进行选择

可以用成员函数getSelectedItem()或getSelectedItems()来接收在列表框中被选的选项。在单选列表框里,“双击” 一个选项就可以触发一个可被action()成员函数捕捉到的事件。

public boolean action(Event e, Object arg) {

. . .

if (e.target instanceof List) {

System.out.println("List entry:" + arg);

}

. . .

}

6.4.2 多选列表框

对于多选列表框,要使你的选择产生作用,需要使用其他的外部事件。例如,你可以使用按钮事件:

public boolean action(Event e, Object arg) {

. . .

if (e.target instanceof Button) {

. . .

if ("Ok".equals(arg)) {

string[] selected ;

selected = l.getSelectedItems( );

for (int i= 0; i< selected.length; i++) {

System.out.println(selected[i]);

}

}

}

}

6.5 文本域

文本域一般用来让用户输入象姓名、信用卡号这样的信息,它是一个能够接收用户的键盘输入的小块区域。

6.5.1 创建文本域

在创建文本域时,有四种类型供你选择:空的、空的并且具有指定长度、带有初始文本内容的和带有初始文本内容并具有指定长度的。下面是生成这四种文本域的代码:

TextField tf1, tf2, tf3, tf4;

//空的文本域

tf1 = new TextField();

//长度为20的空的文本域

tf2 = new TextField(20);

//带有初始文本内容的文本域

tf3 = new TextField("你好");

//带有初始文本内容并具有指定长度的文本域

tf4 = new TextField("你好", 30);

add(tf1);

add(tf2);

add(tf3);

add(tf4);

6.5.2 文本域事件

当用户在文本域里敲“回车”键时,就产生了一个文本域事件。象其他事件一样,你可以在成员函数action()中捕捉到这个事件。

public boolean action(Event e, Object arg) {

. . .

if (e.target instanceof TextField) {

System.out.println("TextField: "+arg);

}

. . .

}

6.6 文本区

文本区可以显示大段的文本。

6.6.1 创建文本区

与文本域类似,创建文本区时也有四种类型供选择,但如果指定文本区的大小,必须同时指定行数和列数。

TextArea ta1, ta2;

//一个空的文本区

ta1 = new TextArea();

//一个带有初始内容、大小为5x40的文本区

ta2 = new TextArea("你好!", 5, 40);

可以用成员函数setEditable()来决定用户是否可对文本区的内容进行编辑。

//使文本区为只读的

ta2.setEditable(false)

6.6.2 接收文本区的内容

可以用成员函数getText()来获得文本区的当前内容。例如:

System.out.println(ta1.getText());

文本区本身不产生自己的事件,但你可以用外部事件来接收文本区的内容:

public boolean action(Event e, Object o) {

if (e.target instanceof Button) {

if ("send".equals(o)) {

String textToSend = ta1.getText ();

System.out.println("sending: " + textTosend);

mySendFunction(textToSend);

}

}else{

. . .

}

}

6.7 画板

画板能够捕捉到露事件、鼠标事件和其他类似的事件。基本的画板类不处理这些事件,但你可以扩展它来创建有你所需功能的画板类。

6.7.1 创建画板

import java.awt.*;

import java.applet.Applet;

public class superGUI extends Applet {

. . .

myCanvas doodle;

. . .

public void init() {

. . .

//建立我们的画板

doodle = new myCanvas();

doodle.reshape(0,0,100,100);

leftPanel.add("Center",doodle);

. . .

}

}

class myCanvas extends Canvas {

public void paint(Graphics g) {

g.drawRect(0, 0, 99, 99);

g.drawString("Canvas",15,40);

}

}

6.7.2 画板事件

你可以覆盖一般的事件处理成员函数。下面是一个包含了mouseDown事件处理的例子:

import java.awt.*;

import java.applet.Applet;

public class canvas extends Applet {

Button b1;

public void init() {

//Set our layout as a Border style

setLayout(new BorderLayout(15,15));

b1 = new Button("Test");

myCanvas c1 = new myCanvas(100,100);

//add the canvas and the button to the applet

add("Center", c1);

add("South", b1);

}

public boolean action(Event e, Object arg) {

System.out.println("Event: " + arg);

return true;

}

public boolean mouseDown(Event e, int x, int y) {

System.out.println("Mouse works: (" + x + "," + y + ")");

return true;

}

}

class myCanvas extends Canvas {

private int width;

private int height;

public myCanvas(int w, int h) {

width = w;

height = h;

reshape(0,0,w,h);

}

public void paint(Graphics g) {

g.setColor(Color.blue);

g.fillRect(0,0,width,height);

}

public boolean mouseDown(Event e, int x, int y) {

if (( x < width) && (y <height)) {

System.out.println("Canvas mouse works: (" + x + "," + y +")");

return true;

}

return false;

//Not our mouseDown

}

}

6.8 滚动条

在某些程序中,需要调整线性的值,这时就需要滚动条。滚动条提供了易于操作的值的范围或区的范围。

6.8.1 创建滚动条

当创建一个滚动条时,必须指定它的方向、初始值、滑块的大小、最小值和最大值。

public Scrollbar(int orientation, int initialValue, int sizeOfSlider, int minValue, int maxValue);

下面是一个例子:

Scrollbar redSlider;

public void init() {

redSlider = new Scrollbar(Scrollbar.VERTICAL,0,1,0,255);

add(redSlider);

}

6.8.2 滚动条事件

和其他接口元件一样,滚动条产生一个你可以控制的事件,但和其他事件不同,你必须直接使用成员函数handleEvent( ),而不能使用成员函数action( )。

public boolean handleEvent (Event e) {

if (e.target instanceof Scrollbar) {

System.out.println("Scrollbar: " + ((Scrollbar)e.target).getValue( ));

return true;

}

return super.handleEvent(e);

}

6.8.3 滚动条的值的显示

如果你想显示滑块所在位置的值,需要加一个自己的文本域。下面是一个例子:

import java.awt.*;

import java.applet.Applet;

public class redSlider extends Applet {

Scrollbar redslider;

TextField redvalue;

Label redlabel;

public void init( ) {

setLayout(new GridLayout(1, 3));

redslider = new Scrollbar(Scrollbar.HORIZONTAL,0,1,0,255);

redvalue = new TextField("0",5);

redvalue.setEditable(false);

redlable = new Label("Red (0-255)");

add(redlabel);

add(redslider);

add(redvalue);

}

public boolean handleEvent(Event e) {

if (e.target instanceof Scrollbar) {

redvalue.setText(Integer.toString(((Scrollbar)e.target).getValue()));

return true;

}

return super.handleEvent(e);

}

public boolean action(Event e, Object arg) {

System.out.println("Event" + arg);

return true;

}

}

本章小结

1. Java提供了生成一个良好的图形用户接口所需要的一些基本元件:面板(Panel)、按钮(Button)、标签(Label)、画板(Canvases)、滚动条(Scrollbar)、列表框(List)、文本域(Text Field)、文本区(Text Area)。

2. 大部分元件都有自己的事件,你可以捕捉并处理它们。