摘要
通过本章的学习,读者应能知道gui(图形用户界面)的概念,并且能够使用java语言来构建一个令人赏心悦目的gui界面,使你的程序更具有感召力。掌握标签、按钮、文本框、选择框、滚动条……等等各种gui部件的使用方法。
--------------------------------------------------------------------------------
本章目标:
通过本章的学习,读者应能知道gui(图形用户界面)的概念,并且能够使用java语言来构建一个令人赏心悦目的gui界面,使你的程序更具有感召力。掌握标签、按钮、文本框、选择框、滚动条……等等各种gui部件的使用方法。
9.1 用什么构建gui
传授新知
早期,电脑向用户提供的是单调、枯燥、纯字符状态的“命令行界面(cli)”。就是到现在,我们还可以依稀看到它们的身影:在windows中开个dos窗口,就可看到历史的足迹。
后来,apple公司率先在电脑的操作系统中实现了图形化的用户界面(graphical user interface,简称gui),但由于apple公司封闭的市场策略,自己完成电脑硬件、操作系统、应用软件一条龙的产品,与其它pc不兼容。这使得apple公司错过了一次一统全球pc的好机会。
后来,著名的microsoft公司推出了风靡全球的windows操作系统,它凭借着优秀的图形化用户界面,一举奠定了操作系统标准的地位。这也造就了世界首富---比尔.盖茨和it业的泰山北斗微软公司。
在这图形用户界面风行于世的今天,一个应用软件没有良好的gui是无法让用户接受的。而java语言也深知这一点的重要性,它提供了一套可以轻松构建gui的工具。在本章和下一章中,我们将向你充分证明这一点。
在java语言提供的gui构建工具中,可以分为“部件”(component)和“容器”(container)两种。
在java语言中,提供了以下部件:
§ 按钮
§ 标签
§ 复选框
§ 单选按钮
§ 选择框
§ 列表框
§ 文本框
§ 滚动条
§ 画布
§ 菜单
这些部件,我们在使用windows操作系统时都遇到过,你通过操作它们来实现与程序的交互。
而光有“部件”就组不成程序,我们必须使用“容器”将这些“部件”装配起来,使其成为一个整体。java语言还提供了以下“容器”:
§ 程序的启动封面
§ 窗体(form)
§ 对话框(dialog)
java语言是通过awt(抽象窗口化工具包)和java基础类(jfc或更常用的swing)来提供这些gui部件的。
其中java.awt是最原始的gui工具包,存放在java.awt包中。现在有许多功能被已被swing取代并得到了很大的增加与提高,因此一般我们很少再使用java.awt,但是awt中还是包含了最核心的功能,通常,一个java的gui程序至少还要使用下面几个类:
§ java.awt.color:基本颜色定义
§ java.awt.font:基本字体定义
§ java.awt.cursor:光标操作定义
而swing则存放在javax.swing包中。
我们可以在java的gui程序的最前面加上以下两句就可以了:
import java.awt.*;
import javax.swing.*;
这样就可以一劳永逸了。
用java开发一个gui程序,通常需要以下几步:
1) 构建一个顶层容器;
2) 构建一个部件;
3) 用容器的add方法将部件加入到这个容器中;
我们马上就开始!
自测练习
1) 在java语言中,用来构建gui的工具可以分为________和__________。
a.控件 b.部件 c.窗体 d.容器
2) 下面不属于“部件”的是__________。
a.选择框 b.窗体 c.菜单
3) 下面不属于“容器”的是__________。
a.文本框 b.对话框 c.窗体
4) 容器可以被添加到其它容器中去。________
a.正确 b.不正确
5) 部件可以被添加到容器中去。_______
a.正确 b.不正确
6) 容器可以被添加到部件中去。_______
a.正确 b.不正确
7) 部件可以被添加到其它部件中去。_______
a.正确 b.不正确
练习答案
1)b、d 在java语言中,gui构建工具可以分为部件与容器。
2)b 窗体是一种容器,不是部件。
3)a 文本框是一种部件,不是容器。
4)a 有些容器可以被包含到其它容器中去。
5)a 容器就是用来放置各种部件的。
6)b 将部件装到容器去,就象“把桶装到水中”一样可笑。
7)b “把水装到水中”也是可笑的呀。
9.2 使用button(按钮)
实例说明
1.首先,我们使用文字编辑软件输入下源程序。
源程序:usebutton.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class usebutton extends japplet
{
jbutton button1;
public void init()
{
jpanel panel1=(jpanel)getcontentpane();
panel1.setlayout(new flowlayout());
button1=new jbutton(“beep!”);
panel1.add(button1);
button1.addactionlistener(new actionlistener()
{
public void actionperformed(actionevent evt)
{
toolkit.getdefaulttoolkit().beep();
}
});
}
}
2.执行以下命令,编译这个程序:
c:javastudy> javac usebutton.java
由于,这是一个java applet(小应用程序),需要在网页上显示,所以我们需要编辑一个包含这个小应用程序的html文件。形如:
源程序:usebutton.html
<html><body>
<applet code="usebutton.class" width=150 height=100>
</applet>
</body></html>
3.然后使用appletviewer来运行这个程序:
c:javastudy> appletviewer usebutton.html
程序输出如下图所示:
图9-1 程序usebutton的运行结果
你试着按一下“beep!”这个按钮,每按一下就会响一声。
传授新知
我们一起来看一下这个冗长而且令人费解的程序段。
1)
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
这一段程序是用来将构建gui程序所需的包包含进来。
2)
public class usebutton extends japplet
这一句用来声明类usebutton,说明它是从japplet中继承而来的子类。japplet是applet类的一种增强类。因此,从这里可以看出这个程序是java小应用程序,而不是java应用程序。
3)
jpanel panel1=(jpanel)getcontentpane();
panel1.setlayout(new flowlayout());
这一段程序创建了一个jpanel(面板)容器:panel1,然后调用setlayout方法显示它。
4)
button1=new jbutton(“beep!”);
panel1.add(button1);
这一段程序创建了一个新的部件:button1按钮,并将按钮上显示标签“beep!”。然后调用容器panel1的add方法将这个按钮添加到这个面板上。
5)
button1.addactionlistener(new actionlistener()
{
public void actionperformed(actionevent evt)
{
toolkit.getdefaulttoolkit().beep();
}
});
这是一个特殊的事件,它为按钮buuton1添加上一个actionlistener(action:行动、事件;listener:监听者),也就是事件监视器。这个监视器做什么呢?
当actionperformed(action:行动、事件;performed:执行,表演),就是当这个事件执行时(什么事件呢?actionevent evt,按下按钮时),将执行:toolkit.getdefaulttoolkit().beep()
也就是响铃。
自测练习
1)按钮类中提供了一个方法,可以修改按钮文本的颜色。以下就是一个应用实例:
button1.setforeground(color.green);
其中button1是按钮名,setforeground则方法名,set就是设置,foreground就是前景,也就是设置前景色。参数是color.green,绿色。相对应的,红色就是color.red,蓝色就是color.blue。
请编写一个程序,在面板上显示三个按钮,按钮上的标签分别是:set red,set green,set blue(颜色为黑色)。当按下set red按钮,则三个按钮的标签都变成红色;而按下set green则变成绿色;按下set blue则变成蓝色。
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
2)按钮类中还提供了一个方法,可以修改按钮标签。以下就是一个应用实例:
button1.settext(“ok”);
其中button1是按钮名,settext是方法名,set就是设置,text就是文本,也就是设置按钮上的文本色。参数是”ok”。这样就会将button1的标签改为”ok”。
请使用这个方法修改程序usebutton,使得按钮上显示按过的次数,如果没有按下,则仍显示“beep!”。只需写出修改的部分。
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
练习答案
1) 以下就是一个实现实例:
源程序:lianxi901.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class lianxi901 extends japplet
{
jbutton buttonred;
jbutton buttongreen;
jbutton buttonblue;
public void init()
{
jpanel panel1=(jpanel)getcontentpane();
panel1.setlayout(new flowlayout());
buttonred=new jbutton(“set red”);
buttongreen=new jbutton(“set green”);
buttonblue=new jbutton(“set blue”);
panel1.add(buttonred);
panel1.add(buttongreen);
panel1.add(buttonblue);
buttonred.addactionlistener(new actionlistener()
{
public void actionperformed(actionevent evt)
{
buttonred.setforeground(color.red);
buttongreen.setforeground(color.red);
buttonblue.setforeground(color.red);
}
});
buttongreen.addactionlistener(new actionlistener()
{
public void actionperformed(actionevent evt)
{
buttonred.setforeground(color.green);
buttongreen.setforeground(color.green);
buttonblue.setforeground(color.green);
}
});
buttonblue.addactionlistener(new actionlistener()
{
public void actionperformed(actionevent evt)
{
buttonred.setforeground(color.blue);
buttongreen.setforeground(color.blue);
buttonblue.setforeground(color.blue);
}
});
}
}
通过构建一个html文件,使其包含这个applet后,以下就是一个运行效果之一:
图9-2 练习的输出
2) 要实现这个功能很简单,只需做两个修改:
a. 在变量定义处加入一个新的变量定义:
int counter=0;
b.在button1的addactionlistener方法中的actionperformed中加入一行:
button1.settext(string.valueof(++counter));
9.3 使用label(标签)
实例说明
1.首先,我们使用文字编辑软件输入下源程序。
源程序:uselabel.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class uselabel extends japplet
{
jlabel label1;
public void init()
{
label1=new jlabel(“this is a java label!”);
label1.sethorizontalalignment(swingconstants.center);
label1.setverticalalignment(swingconstants.top);
label1.setbackground(color.red);
label1.setopaque(true);
label1.setforeground(color.white);
label1.settooltiptext(“hello,i am a java label!”);
panel1.add(label1);
}
}
2.使用javac编译这个程序。
3.编辑一个显示这个java applet的页面:
源程序:uselabel.html
<html><body>
<applet code="uselabel.class" width=150 height=100>
</applet>
</body></html>
4.最后使用appletviewer来运行这个程序:
c:javastudy> appletviewer uselabel.html
程序输出如下图所示:
图9-3 程序uselabel的运行结果
传授新知
我们可以看到这一段程序,与usebutton.java十分类似,在类的前面,包含了编写gui程序要使用的包:javax.swing.*、java.awt.*和java.awt.event.*。
接着,通过使用“extends japplet”说明uselabel类也是一个小应用程序(applet)。在init方法中,首先创建了一个容器---panel,用来放置后面创建的“标签”。我们下面就认真地看一下关于label的语句:
1)
label1=new jlabel(“this is a java label!”);
类似的,我们使用new来创建一个label实例,参数“this is a java label!”就是标签要显示的内容。如果省略这个标签,将创建一个空标签,什么也不会显示。
一些提示:
在java语言中,标签提供了一个settext方法,可以用来设置它显示的内容。
2)
label1.sethorizontalalignment(swingconstants.center);
label1.setverticalalignment(swingconstants.top);
label类提供两个设置其对齐方式的方法:
§ sethorizontalalignment:设置水平对齐方式;
它的有效参数是:
¨ swingconstants.left:左对齐;(默认值,也就是不设置时则左对齐)
¨ swingconstants.center:居中对齐;
¨ swingconstants.right:右对齐;
§ setverticalalignment:设置垂直对齐方式;
它的有效参数是:
¨ swingconstants.top:向上对齐;
¨ swingconstants.center:居中对齐;(默认值,也就是不设置时居中对齐)
¨ swingconstants.bottom:向下对齐;
3) label1.setbackground(color.red);
label1.setopaque(true);
setbackground方法用来设置标签的背景色。但是java的swing部件默认状态下是不透明的,在这种状态下是无法显示背景色的。因此,我们还需使用setopaque(true)方法使该部件变为透明的。
4)
label1.setforeground(color.white);
与按钮一样,我们可以使用setforeground方法来设置字符颜色。
5)
label1.settooltiptext(“hello,i am a java label!”);
在windows的界面中,许多工具按钮都提供了一个这样的功能:当你将鼠标放在这个按钮上面一会儿,就会出现一个帮助性的提示。在java语言中,我们可以很简单地使用:
部件.settooltiptext(“提示信息”)
来实现这个功能。
一些提示:
其实“按钮”部件也可以使用这个方法来显示提示信息。
6)
panel1.add(label1);
最后,我们使用容器panel的add方法,将这个标签放置到容器中。
自测练习
1) 标签label上显示的文本信息一经定后,就不能在程序中动态修改。________
a. 错 b.对
2) 对于一个label来说,默认的水平对齐方式是:________。
a.swingconstants.center b.swingconstants.right
c.swingconstants.left
3) 对于一个label来说,默认的垂直对齐方式是:________。
a.swingconstants.center b.swingconstants.bottom
c.swingconstants.top
4) 要获得一个label上显示的文本信息,应使用_________方法。
a.settext b.gettext c.getcontent
5)标签类中提供了一个方法,可以修改标签上显示的文本。以下就是一个 应用实例:
label1.settext(“new text!”);
请编写一个程序,在面板左边显示一个标签,右边显示一个按钮,按钮上显示“plus one”,标签显示为“0”。每按一次按钮,标签上显示的数字就加1.
一些提示:
在java中,我们还可以使用gettext来获得标签上显示的文本信息。
程序显示如下图所示:
图9-4 练习输出
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
练习答案
1)a 在程序中可以使用settext方法动态修改label显示的文本信息。
2)c 默认是水平左对齐。
3)a 默认是垂直居中对齐。
4)b settext方法是设置文本,gettext是获取文本,并没有getcontent方法。
5)以下就是一个实现该功能的程序实例:
源程序:lianxi902.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class lianxi902 extends japplet
{
jbutton button1;
jlabel label1;
int counter=0;
public void init()
{
jpanel panel1=(jpanel)getcontentpane();
panel1.setlayout(new flowlayout());
label1=new jlabel(string.valueof(counter));
label1.seticon("winupd.ico");
button1=new jbutton("plus one");
panel1.add(label1);
panel1.add(button1);
button1.addactionlistener(new actionlistener()
{
public void actionperformed(actionevent evt)
{
label1.settext(string.valueof(++counter));
}
});
}
}
9.4 复选框与单选按钮
实例说明
1.首先,我们使用文字编辑软件输入下源程序。
源程序:usecheckbox.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class usecheckbox extends japplet
{
jbutton button1;
int counter=0;
checkbox setbeep,setcounter,red,green,blue;
checkboxgroup colorsel;
public void init()
{
jpanel panel1=(jpanel)getcontentpane();
panel1.setlayout(new flowlayout());
setbeep=new checkbox("beep when press button");
setcounter=new checkbox("counter press time");
panel1.add(setbeep);
panel1.add(setcounter);
colorsel=new checkboxgroup();
red=new checkbox("set red",colorsel,true);
green=new checkbox("set green",colorsel,false);
blue=new checkbox("set blue",colorsel,false);
panel1.add(red);
panel1.add(green);
panel1.add(blue);
red.additemlistener(new itemlistener()
{
public void itemstatechanged(itemevent evt)
{
if(evt.getstatechange()==itemevent.selected)
button1.setforeground(color.red);
}
});
green.additemlistener(new itemlistener()
{
public void itemstatechanged(itemevent evt)
{
if(evt.getstatechange()==itemevent.selected)
button1.setforeground(color.green);
}
});
blue.additemlistener(new itemlistener()
{
public void itemstatechanged(itemevent evt)
{
if(evt.getstatechange()==itemevent.selected)
button1.setforeground(color.blue);
}
});
button1=new jbutton("press me");
panel1.add(button1);
button1.addactionlistener(new actionlistener()
{
public void actionperformed(actionevent evt)
{
dobutton1action();
}
});
}
public void dobutton1action()
{
if (setbeep.getstate())
toolkit.getdefaulttoolkit().beep();
if (setcounter.getstate())
button1.settext("press: "+string.valueof(++counter));
else
button1.settext("press me");
}
}
2.使用javac编译这个程序,然后编辑一个显示这个java applet的页面:
源程序:usecheckbox.html
<html><body>
<applet code="usecheckbox.class" width=320 height=150>
</applet>
</body></html>
4.最后使用appletviewer来运行这个程序,这个程序的输出如下图所示:
图9-5 程序usecheckbox的运行结果
传授新知
从我们学习java开始,这个示例程序是大家遇到的最长的一个。大家不要被它吓退,这个程序阅读起来一样并不困难。下面,我们就对程序做一些点评。
1)
setbeep=new checkbox("beep when press button");
setcounter=new checkbox("counter press time");
panel1.add(setbeep);
panel1.add(setcounter);
在这一段程序中,我们定义了两个checkbox:setbeep和setcounter。什么是checkbox呢?如下图所示:
图9-6 复选框
在java语言中,checkbox类定义了复选框。复选框用来让用户做出某种选择,正如上图所示,允许选中多个复选框。
在前两句中,我们使用new创建了这两个复选框;而在后两句中,我们使用容器panel的add方法将它们装入panel。
2)
colorsel=new checkboxgroup();
red=new checkbox("set red",colorsel,true);
green=new checkbox("set green",colorsel,false);
blue=new checkbox("set blue",colorsel,false);
panel1.add(red);
panel1.add(green);
panel1.add(blue);
而这一段程序则是用来定义red、green和blue三个单选按钮。在java语言中,单选按钮被看作是一组特殊的复选框。我们使用一个checkboxgroup将它们组成一个组,这样就只允许这个组里的“复选框”只能有一定被选中,这就形成了单选按钮。
单选按钮与复选框在外观上也不同:复选框是一个正方形的小框,而单选按钮则是一个小小的圆,如下图所示:
图9-7 单选按钮
在上面的程序中,我们首先定义了一个组:colorsel。接下来的三条语句使用new操作符创建了三个checkbox,并在参数列表中指定了它所在的组,其语法格式为:
单选按钮名=new checkbox(“提示文本”,所在组名,初值);
其中初值是布尔型的:true表示选中,false表示未选中。
注意:
一组单选按钮中仅能有一个按钮的初值是true,因为是“单选”嘛。
最后,我们再次调用了panel的add方法,将它们装入容器panel中。
3)
red.additemlistener(new itemlistener()
{
public void itemstatechanged(itemevent evt)
{
if(evt.getstatechange()==itemevent.selected)
button1.setforeground(color.red);
}
});
这段程序用到了许多我们没有遇到过的东西!不过不要紧,做为初学者还是要学会“黑盒子”学习方法,也就是在学习的初级阶段要将某些东西当作一个整体来接受,而不是每一个都要剖析清楚,那样就会影响学习效果的。正如这段程序,大家只要会用,会理解就行了,不一定要搞懂为什么这么写。
第一行中red.additemlistener用来为单选按钮red增加一个监测器。监测什么呢?第3行说明监测itemstatechanged(状态改变时)。第5行说明当监测到状态改变时,就判断改变后的状态是不是“选中”的。如果是,就执行第6行,将按钮button1的前景色设置为红色。
在后面的两段中,我们采用相同的方法为单选按钮green和blue分别创建了一个监测器,使得当其被“选中”时,就将按钮button1的前景色设置为相应的颜色(绿色和蓝色)。
4)
button1.addactionlistener(new actionlistener()
{
public void actionperformed(actionevent evt)
{
dobutton1action();
}
});
这一段程序,我们在9.2小节中就遇到过。它是用来为按钮button1创建一个监测器。不同的是,当时我们是直接说明了当按钮按下时所要执行的语句。而在此,我们则是让其去执行一个dobutton1action方法。这个方法,是在我们后面的程序中定义的。
5)
public void dobutton1action()
{
if (setbeep.getstate())
toolkit.getdefaulttoolkit().beep();
if (setcounter.getstate())
button1.settext("press: "+string.valueof(++counter));
else
button1.settext("press me");
}
这就是当按下按钮button1时,执行的方法dobutton1action。整个方法可以分为两个部分的工作:
其一是:
if (setbeep.getstate())
toolkit.getdefaulttoolkit().beep();
即,首先判断复选框setbeep否被选中(使用复选框的getstate方法获得其状态,如果被选中,返回true;如果未被选中,返回false)。如果被选中,就响铃。
把整个程序逻辑串起来讲就是:当按钮button1按下时,将检查复选框setbeep是否被选中,如果被先中,就响铃,否则无任何反应。
其二是:
if (setcounter.getstate())
button1.settext("press: "+string.valueof(++counter));
else
button1.settext("press me");
即,首先判断复选框setcounter是否被选中。如果被选中,则改变按钮button1的显示文本,将其改为press:按下总次数;否则,让其显示最初的“press me”。
自测练习
1) 在java语言中,复选框类名是____________。
a.button b.checkbox c.checkbox d.label
2) 在java语言中,单选框类名是____________。
a.label b.checkbox c.button d.checkbox
3) 假设有cb1、cb2、cb3三个对象,属于同一个checkboxgroup,则它们是________。
a.单选按钮 b.复选框
4) 复选框的外观是________。
a.一个小正方形 b.一个小圆形 c.一个小三角形
5) 单选框的外观是________。
a.一个小正方形 b.一个小圆形 c.一个小三角形
6) 编写一段程序,使其运行结果如下图所示:
图9-8 练习903题图
并且,当选中了no.1,则按钮显示为no.1;选中了no.2,则按钮显示为no.2。
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
练习答案
1)b 复选框类名为checkbox,第一个字母“c”是大写字母。
2)d 单选按钮也是checkbox,与复选框的不同是,单选按钮是属于一个checkboxgroup的。
3)a 加入了同一个checkboxgroup,就成为一组,一组中仅有一个能够被选中,称为单选按钮。
4)a 请参看图9-6。
5)b 请参看图9-7。
6)以下是一个实现实例:
源程序:lianxi903.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class lianxi903 extends japplet
{
jbutton button1;
checkbox theone,thetwo;
checkboxgroup cbg1;
public void init()
{
jpanel panel1=(jpanel)getcontentpane();
panel1.setlayout(new flowlayout());
cbg1=new checkboxgroup();
theone=new checkbox("no.1",cbg1,true);
thetwo=new checkbox("no.2",cbg1,false);
button1=new jbutton("button");
panel1.add(theone);
panel1.add(thetwo);
panel1.add(button1);
theone.additemlistener(new itemlistener()
{
public void itemstatechanged(itemevent evt)
{
if(evt.getstatechange()==itemevent.selected)
button1.settext("no.1");
}
});
thetwo.additemlistener(new itemlistener()
{
public void itemstatechanged(itemevent evt)
{
if(evt.getstatechange()==itemevent.selected)
button1.settext("no.2");
}
});
}
}
9.5 使用列表框
实例说明
1.首先,我们使用文字编辑软件输入下源程序。
源程序:uselist.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class uselist extends japplet
{
label label1;
list colorlist;
public void init()
{
jpanel panel1=(jpanel)getcontentpane();
panel1.setlayout(new flowlayout());
colorlist=new list();
colorlist.add("red");
colorlist.add("green");
colorlist.add("blue");
colorlist.select(0);
panel1.add(colorlist);
label1=new label("you selected red");
label1.setforeground(color.red);
panel1.add(label1);
colorlist.additemlistener(new itemlistener()
{
public void itemstatechanged(itemevent evt)
{
string selstring;
string sel;
int selnum;
if(evt.getstatechange()==itemevent.selected)
{
selnum=colorlist.getselectedindex();
sel=colorlist.getitem(selnum);
selstring="you selected "+sel;
label1.settext(selstring);
switch(selnum)
{
case 0:
label1.setforeground(color.red);
break;
case 1:
label1.setforeground(color.green);
break;
case 2:
label1.setforeground(color.blue);
break;
}
}
}
});
}
}
2.使用javac编译这个程序,然后编辑一个显示这个java applet的页面:
3.最后使用appletviewer来运行这个程序,这个程序的输出如下图所示:
图9-9 程序uselist的运行结果
当你选择green后,标签将以绿色显示you selected green;而若你选择blue后,标签将以蓝色显示you selected blue。
传授新知
这一节中,我们将遇到一个新的部件---列表框。下面,就对刚才这个程序做一些点评。
1)
colorlist=new list();
colorlist.add("red");
colorlist.add("green");
colorlist.add("blue");
colorlist.select(0);
panel1.add(colorlist);
在这一段程序中,我们定义了一个列表框list:colorlist。列表框用来将多个表项列出来,以供用户选择,如下图所示:
图9-10 列表框
首先,我们使用new操作符创建一个colorlist,然后调用列表框的add方法,增加可供选择的表项(red、green和blue)。最后,使用select方法,使得缺省选择是red(第0项)。
最后使用容器panel的add方法将它们装入panel。
一些提示:
如果要让缺省选择的是blue,则应该使用colorlist.select(2)。
为列表框的指定位置上增加项目,可以使用方法:
public synchronized void add(string item,int index)
其中,item是一个字符串,用来存放要显示的标签文本。而index则是添加的位置。列表框的位置是一个从0开始的数,所以,如果用户在位置0处增加项目,那么该项目将增加在列表框的顶部。如果用户试图在-1处或大于列表框中项目数(甚至象例子中,不给出index参数)的位置上增加项目,那么将增加到列表框的末尾。
如果你想删除某一项,则可以使用方法:
public synchronized void remove(int position)
其中position就是你要删除项目的位置。如果你想删除掉所有的项,则可调用方法:
public synchronized void removeall()
2)
colorlist.additemlistener(new itemlistener()
{
public void itemstatechanged(itemevent evt)
{
……
}
});
与其它部件一样,可以使用additemlistener方法为其设置一个监测器,当列表框选择项改变时就会激活这个监测器。
3)
if(evt.getstatechange()==itemevent.selected)
{
selnum=colorlist.getselectedindex();
sel=colorlist.getitem(selnum);
selstring="you selected "+sel;
label1.settext(selstring);
在这一段程序中,我们首先调用了列表框的getselectedindex ()方法取得你所选择项目的编号。这个项目返回的是一个整型的索引号。
接着,我们再使用这个索引号调用列表框的getitem方法获取该项目的标签文本。
为了让标签中显示的文本更加清晰、易懂,我们在标签文本的前面加上了“you selected”,然后调用标签label1的settext方法改变标签所显示的文本。
4)
switch(selnum)
{
case 0:
label1.setforeground(color.red);
break;
case 1:
label1.setforeground(color.green);
break;
case 2:
label1.setforeground(color.blue);
break;
}
这是一个多分支结构,它根据所选择的项目编号(前面,我们已经调用getselectedindex ()方法取得了项目编号,存放在变量selnum中)来做相应的操作。
<1> case 0:假设selnum=0,那么就执行
label1.setforeground(color.red);
break;
也就是,将标签label1的前景色(字的颜色)设置为红色,然后退出switch-case语句。
<2> case 1:假设selnum=1,那么就执行
label1.setforeground(color.green);
break;
将标签label1的前景色设置为绿色,然后退出switch-case语句。
<3> case 2:假设selnum=2,那么就执行
label1.setforeground(color.blue);
break;
将标签label1的前景色设置为蓝色,然后退出switch-case语句。
文本,将其改为press:按下总次数;否则,让其显示最初的“press me”。
自测练习
1) 在程序中要构建一个列表框,要使用_________类。
a.checkbox b.listbox c.list d.label
2) 列表框中第一项的项目编号(也称索引)是________。
a.0 b.1 c.-1 d.10
3) 假设有一个列表框listbox1,要在其最后添加一项,应使用________________语句。
a.listbox.add(“the end item”,0) b. listbox.add(“the end item”,10)
c. listbox.add(“the end item”,-1) d. listbox.add(“the end item”, 1)
4) 我们可以使用__________________方法,取得当前选择的项目的索引值。
a. getselectedindex() b. getitem() c. getnumber()
5) 编写一段程序,使其运行结果如下图所示:
图9-11 练习903题图
当按下add按钮,就在列表框上增加一项:no.x(x是顺序号),当按下remove按钮,就删除最后一项。
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
练习答案
1)c 在java中,类list实现了列表框。
2)a 从0开始,而不是1。
3)c 要在这后一项添加有三种方法。其一:以-1为位置参数;其二:以大于最大项目索引数的数为位置参数;其三:不带位置参数。因此在此,只有c。
4)a getitem是获得显示的内容。
5)下面,我们给出一个实现的实例。
源程序:lianxi904.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class lianxi904 extends japplet
{
list listbox1;
jbutton buttonadd,buttonremove;
int counter=0;
public void init()
{
jpanel panel1=(jpanel)getcontentpane();
panel1.setlayout(new flowlayout());
listbox1=new list();
buttonadd=new jbutton("add");
buttonremove=new jbutton("remove");
panel1.add(listbox1);
panel1.add(buttonadd);
panel1.add(buttonremove);
buttonadd.addactionlistener(new actionlistener()
{
public void actionperformed(actionevent evt)
{
listbox1.add("no."+string.valueof(counter++));
}
});
buttonremove.addactionlistener(new actionlistener()
{
public void actionperformed(actionevent evt)
{
listbox1.remove(counter-1);
counter-=1;
}
});
}
}
9.6 使用文本部件
9.6.1 普通文本框
实例说明
1.编辑以下源程序,生成usetext.java文件。
源程序:usetextfield.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class usetextfield extends japplet
{
jbutton buttonok;
jtextfield text1;
public void init()
{
jpanel panel1=(jpanel)getcontentpane();
panel1.setlayout(new flowlayout());
buttonok=new jbutton("ok");
text1=new jtextfield(20);
panel1.add(text1);
panel1.add(buttonok);
buttonok.addactionlistener(new actionlistener()
{
public void actionperformed(actionevent evt)
{
showstatus(text1.gettext());
}
});
}
}
2.使用javac编译这个程序,然后编辑一个显示这个java applet的页面:
3.最后使用appletviewer来运行这个程序,这个程序的输出如下图所示:
图9-12 程序usetextfield.java的运行结果(1)
正如上图所示,屏幕上出现了一个宽度为20的文本框和一个ok按钮。我们可以在这个文本框内写入字符。我们输入“haha,i’m writing to java’s textfield!!”,然后单击ok按钮,这时屏幕变为:
图9-13 程序usetextfield.java的运行结果(2)
也就是,我们按下ok按钮后,在状态栏上出现了我们输入的文本信息。
传授新知
多次阅读java语言源程序,应该为大家积累了不少经验,我想大家在阅读这个程序的时候,因为不再觉得那么费劲了吧。如果你还是觉得读程序是一件痛苦的事的话,我希望你还是好好反省一下,看前面的章节时是不是走马观花了。
好了,言归正传,我们一起来看一下上面的这个程序。这个程序中的大部分语句,大家应该都耳熟能详了,陌生的只有关于本小节的主人公---文本框textfield的语句了:
1)
jtextfield text1;
……
text1=new jtextfield(20);
首先,我们定义了一个jtextfield类的对象text1,然后使用new操作符来创建这个对象text1(也就是一个文本框)
大家还记得new后面的这个与类名相同的方法称为什么吗?对,构造器。这个类有三种带不同参数的构造器。
a. jtextfield(int columns)
第一种构造器,就是我们在本例中调用的那个,它带了一个整型参数columns,这个单词的中文意思是列,也就是说,这个参数指定了我们要创建的textfield的列宽。这里的列宽指长度,而不是可包含的字符数。
那么20,到底是多少宽呢?java是这样定义的:
能够显示20个小写“m”(当前选择的字体)的宽度。
注意:
得再次强调一下,这里的列宽是一种长度,而不是字符数。你可以试一试,在我们这个程序执行后,再这个文本框中输入小写字母“m”,看一看能够输入多少个。但大家也应该注意到,我们在例子中输入的字符数远不止20个。
b. jtextfield(string text)
第二种构造器则带的是一个字符串型参数text,这个字符串将会在程序一执行时就显示在文本框中。
c.jtextfield(string text,int columns)
而如果你既想设置默认的字符串,又想设置它的宽度,就可以调用第三种构造器。
注意:
调用jtextfield的构造器时,一定要带上参数,否则将会出错。
2)
buttonok.addactionlistener(new actionlistener()
{
public void actionperformed(actionevent evt)
{
showstatus(text1.gettext());
}
});
大家看到这个语句,应该不会感到陌生吧!它为按钮buttonok增加一个监测器,监测是否按下按钮。如果按下按钮,就执行:showstatus(text1.gettext())语句。
这个语句中,有两个新的知识。
其一是:showstatus(string test)方法,它用来在状态栏上显示字符串。
其二是:gettext()方法,它是jtextfield类的一个成员方法,用来获取文本框内的文本。例如本例中text1.gettext()就将获得文本框text1中的文本。也就是我们输入的那些东西。
整个串起来,得到:
当我们按下ok按钮时,程序将获取文本框text1中的文本,然后将它们显示到状态栏上。
用gettext()方法可以获取文本框中的文本,相应的,我们可以使用settext()方法设置文本框中的文本。其语法是:
文本框对象.settext(string text)
这样,就将文本框中的文本改成了字符串text。
除此之外,我们还可以使用sethorizontalalignment方法来设置字符串中文本的对齐方式,具体来说:
sethorizontalalignment(swing constants.center) 居中对齐
sethorizontalalignment(swing constants.left) 左对齐
sethorizontalalignment(swing constants.right) 右对齐
9.6.2 口令文本框
传授新知
口令文本框(jpasswordfield)是一种特殊的文本框,在口令文本框中输入任何字符串都将显示成为“*”,这样就可以不让别人知道你输入的是什么,这种文本框比较适合与密码、口令的输入,所以称之为口令文本框。
为了安全起见,获取口令文本框中的密码(口令)使用的方法与普通文本框不同。它使用方法:getpassword()。
“越麻烦越安全”,所以,java语言中为你获取口令再添加了一层麻烦(我看来是一种不必要的麻烦),getpassword()方法将返回一个char数组,我们还得将其转换成为字符串。以下就是一个转换的实例:
string passwd=new string(passwdtextfield.getpassword())
9.6.3 文本区
实例说明
正如我们看到的一样,普通文本框textfield只能输入一行,如果要提供一个多行的输入界面,那怎么办呢?下面我们就看一下下面这个程序:
源程序:usetextarea.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class usetextarea extends japplet
{
jbutton buttonclear;
jtextarea textarea1;
public void init()
{
jpanel panel1=(jpanel)getcontentpane();
panel1.setlayout(new flowlayout());
buttonclear=new jbutton("clear all");
textarea1=new jtextarea("enter new text",5,15);
panel1.add(textarea1);
panel1.add(buttonclear);
buttonclear.addactionlistener(new actionlistener()
{
public void actionperformed(actionevent evt)
{
textarea1.settext("");
}
});
}
}
2.使用javac编译这个程序,然后编辑一个显示这个java applet的html页面,建议高度为100,宽度为300。
3.最后我们再使用appletviewer来运行这个程序,这个程序的输出如下图所示:
图9-14 程序usetextarea.java的运行结果
接着,我们就可以在这个文本区内写多行文本了。大家在按下“clear all”按钮之前,想一下,会发现什么结果?
传授新知
这个程序中,主要需要说明的只有关于textarea部件(文本区)的一些语句:
1)
jtextarea textarea1;
……
textarea1=new jtextarea("enter new text",5,15);
首先,我们定义了一个jtextarea类的对象textarea1,然后使用new操作符来创建这个对象textarea1(也就是一个文本区)。与文本框类似,文本区的构造器也有三种:
a. jtextfield(int rows,int columns)
在这个构造器中,有两个整型参数rows(这个单词的中文意思是行)和columns(这个单词的中文意思是列),也就是说,这两参数用来指令文本区的行数,与列宽。
这里的列宽与文本框一样,是一种长度,用能够显示多少个个小写“m”(当前选择的字体)来衡量的宽度。而行数,就很好理解了,就是能够输入的行数。
要注意的是,这里的行数、列数都是只显示出来的框的大小。如果一行中超过了列宽,将会使文本区变得越来越宽,如下图所示:
图9-15 超过了列宽
由于输入的文本超过了文本区原来的宽度,使得文本区变得越来越宽,把按钮都挤到下一行中去了。
注意:
如果把多出来的文本删除掉后,文本区将变成原来的大小。
同样的,如果输入太多行,将引起如下图所示的情况:
图9-16 超过了行数
b. jtextarea(string text)
也可以只带一个字符串型参数text调用构造器方法,这个字符串将会在程序一执行时就显示在文本区中。
c. jtextfield(string text ,int rows,int columns)
而如果你既想设置默认的字符串,又想设置它的宽度,就可以调用第三种构造器。在本例中,我们就是调用这个构造器,构建了一个5行,15个“m”宽的文本区,让其一启动就显示一段文本:“enter new text”。
注意:
同样的,调用jtextarea的构造器时,一定要带上参数,否则将会出错。
2)
buttonclear.addactionlistener(new actionlistener()
{
public void actionperformed(actionevent evt)
{
textarea1.settext("");
}
});
在这一段程序中,我们为按钮buttonclear增加了一个监测器,使得当这个按钮按下时就执行:textarea1.settext(“”)。与文本框textfield一样,文本区textarea也提供了设置显示文本的方法:settext(string text)。
大家想想,将显示文本设置为“”,意味着什么,对!就是让其什么也不显示,这也就是前面那个问题(大家在按下“clear all”按钮之前,想一下,会发现什么结果?)的答案。
到现在,我们已经读懂了这个程序,但通过执行程序时,我们发现了一个十分不好的问题,那就是在文本区内不会自动换行。我们并不希望文本区变得越来越宽!
怎么办呢?java为文本区textarea提供了一个方法,使得自动换行成为可能:
textarea1.setlinewrap(true)
只需将这条语句加入程序,就会使得我们编辑到右边时会自动换行。如果我们要恢复成不自动换行,就调用:
textarea1.setlinewrap(false)
自测练习
1) 部件____________适合于提供密码输入界面。
a. jtextarea b.jtextfield c.jpasswordfield
2) 在文本区中________输入超过程序中定义的行数。
a.能 b.不能
3) 我们可以使用______________来清除文本框text1中的文本。
a.text1.cleartext() b.text1.settext(“”)
c.text1.deletetext() d.以上都可以
4) 如果我们调用____________来获得口令文本框passwd1中的文本。
a.passwd1.gettext() b.passwd1.getpassword()
5) 在程序中_______________,就能够防止因为在一行中输入过多的文本,而使文本区textarea1变宽。
a.不需要做任何考虑 b.textarea1.setlinewrap(true)
c.textarea1.setlinewrap(false) d.textarea1.nowrap()
6) 如果我们使用textfield1=new jtextfield(“test”)来创建一个文本框,那么这个文本框的宽度有多大?
____________________________________________________________________
7) 请在程序usetextarea.java中加入textarea1.setlinewrap(true),然后再执行这个程序,发现一下,还存在什么样的问题。
____________________________________________________________________
____________________________________________________________________
8) 根据以下要求,编写程序
设置两个文本框,一个用来输入username,另一个用来输入password;再设置一个按钮ok和一个文本区。
如果我们按下ok按钮,则右边的文本区中就会显示:
username:用户名
password:密码
其中用户名、密码就是用户输入的内容,如果没有输入则不显示。程序输出如下图所示:
图9-17 程序lianxi905.java的输出
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
练习答案
1)c 由于输入密码的地方,应该不能明文显示,否则容易被边上的人从偷看到,我们可以借助java中提供的口令文本框passwordfield来实现。这样,你输入的内容就变成了星号,不怕被人偷看到了。
2)a 能,而且会使得文本区的行数增加。
3)b 一个文本框并不存在cleattext()方法,也没有提供delete()方法,但我们可以通过调用settext(“”)来实现,这是因为,我们让它显示的文本变成了“”。也就空文本,这难道不是清除所有文本吗?
4)b 口令文本框要使用特殊的方法getpassword()来获得口令文本。
5)b 通过使文本区自动换行,就可以有效地避免这个问题。
6)这个文本框的宽度就是字符串“test”的大小。如下图所示:
图9-18 练习答案参考图(1)
7)还存在一个问题,那就是这个程序十分愚笨,它虽然会自动换行,但是却常把一个单词分在两行里,如下图所示:
图9-19 练习答案参考图(2)
一些提示:
其实文本区部件还提供了一个方法来解决这个问题,那就是:
public void setwrapstyleword(boolean word)
如果在程序中,加入textarea1.setwrapstyleword(true),那么程序输入则是:
图9-20 练习答案参考图(3)
怎么样,效果是不是更好了!
8) 请参考以下实现实例:
源程序:lianxi905.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class lianxi905 extends japplet
{
label label1,label2;
jtextfield username;
jpasswordfield passwd;
jbutton buttonok;
jtextarea showresult;
string out;
public void init()
{
jpanel panel1=(jpanel)getcontentpane();
panel1.setlayout(new flowlayout());
label1=new label("please input your name:");
username=new jtextfield(15);
label2=new label("please input your password:");
passwd=new jpasswordfield(15);
buttonok=new jbutton("ok");
showresult=new jtextarea(2,15);
panel1.add(label1);
panel1.add(username);
panel1.add(label2);
panel1.add(passwd);
panel1.add(buttonok);
panel1.add(showresult);
buttonok.addactionlistener(new actionlistener()
{
public void actionperformed(actionevent evt)
{
out="username: "+username.gettext()+" ";
out=out+"password: "+new string(passwd.getpassword());
showresult.settext(out);
}
});
}
}
请大家注意到,我们是如何生成在文本区showresult显示的文本信息(存放在字符串变量out中)的:
out="username: "+username.gettext()+" ";
out=out+"password: "+new string(passwd.getpassword());
先让out等于“username:”+username.gettext(),这就使其包含了提示字符“username:”,而后面的内容是另一部分的,所以我们在这个后面加上了“ ”,这是一个转义符,代表回车(也就是另起一行)。
然后再将其加上提示字符“password:”,最后是调用了getpassword()方法,然后将其转换为字符串型。
闽公网安备 35060202000074号