实验六
组件与事件处理
【目的】
①学习处理ActionEvent事件;
②学习处理ItemEvent事件和paint方法;
③学习使用布局类。
【内容】
1.算术测试。
²
实验要求:
编写一个算术测试小软件,用来训练小学生的算术能力。程序由3个类组成,其中Teacher类对象负责给出算术题目,并判断回答者的答案是否正确;ComputerFrame类对象负责为算术题目提供视图,比如用户可以通过ComputerFrame类对象提供的GUI界面看到题目,并通过该GUI界面给出题目的答案;MainClass是软件的主类。
²
程序模板:
Teacher.java
public
class Teacher
{
int numberOne,numberTwo;
String operator="";
boolean right;
public int giveNumberOne(int n)
{
numberOne=(int)(Math.random()*n)+1;
return numberOne;
}
public int giveNumberTwo(int n)
{
numberTwo=(int)(Math.random()*n)+1;
return numberTwo;
}
public String giveOperator()
{ double
d=Math.random();
if(d>=0.5)
operator="+";
else
operator="-";
return operator;
}
public boolean getRight(int answer)
{
if(operator.equals("+"))
{
if(answer==numberOne+numberTwo)
right=true;
else
right=false;
}
else if(operator.equals("-"))
{
if(answer==numberOne-numberTwo)
right=true;
else
right=false;
}
return right;
}
}
ComputerFrame.java
import java.awt.*;
import java.awt.event.*;
public
class ComputerFrame extends Frame implements
ActionListener
{
TextField textOne,textTwo,textResult;
Button getProblem,giveAnwser;
Label operatorLabel,message;
Teacher teacher;
ComputerFrame(String s)
{ super(s);
teacher=new Teacher();
setLayout(new FlowLayout());
textOne=【代码1】
//创建textOne,其可见字符长是10
textTwo=【代码2】
//创建textTwo,其可见字符长是10
textResult=【代码3】
//创建textResult,其可见字符长是10
operatorLabel=new Label("+");
message=new Label("你还没有回答呢");
getProblem=new Button("获取题目");
giveAnwser=new
Button("确认答案");
add(getProblem);
add(textOne);
add(operatorLabel);
add(textTwo);
add(new Label("="));
add(textResult);
add(giveAnwser);
add(message);
textResult.requestFocus();
textOne.setEditable(false);
textTwo.setEditable(false);
【代码4】//将当前窗口注册为getProblem的ActionEvent事件监视器
【代码5】//将当前窗口注册为giveAnwser的ActionEvent事件监视器
【代码6】//将当前窗口注册为textResult的ActionEvent事件监视器
setBounds(100,100,450,100);
setVisible(true);
validate();
addWindowListener(new WindowAdapter()
{ public
void windowClosing(WindowEvent e)
{
System.exit(0);
}
}
);
}
public void actionPerformed(ActionEvent e)
{ if(【代码7】)
//判断事件源是否是getProblem
{ int number1=teacher.giveNumberOne(100);
int number2=teacher.giveNumberTwo(100);
String operator=teacher.givetOperator();
textOne.setText(""+number1);
textTwo.setText(""+number2);
operatorLabel.setText(operator);
message.setText("请回答");
textResult.setText(null);
}
if(【代码8】)
//判断事件源是否是giveAnwser
{ String
answer=textResult.getText();
try{
int result=Integer.parseInt(answer);
if(teacher.getRight(result)==true)
{
message.setText("你回答正确");
}
else
{ message.setText("你回答错误");
}
}
catch(NumberFormatException ex)
{
message.setText("请输入数字字符");
}
}
textResult.requestFocus();
validate();
}
}
MainClass.java
public
class MainClass
{
public static void main(String args[])
{
ComputerFrame frame;
frame=【代码9】//创建窗口,其标题为:算术测试
}
}
²
实验后的练习:
1. 给上述程序增加测试乘、除的功能。
2.信号灯。
²
实验要求:
编写一个带有窗口的应用程序。在窗口的北面添加一个下拉列表,该下拉列表有“”、“”和“”三个选项。在窗口的中心添加一个画布,当用户在下拉列表选择某项后,画布上绘制相应的信号灯。
²
程序模板:
SignalCanvas.java
import
java.awt.*;
public
class SignalCanvas extends Canvas
{
int red,green,yellow,x,y,r;
SignalCanvas()
{
setBackground(Color.white);
}
public void setRed(int r)
{
red=r;
}
public void setGreen(int g)
{
green=g;
}
public void setYellow(int y)
{
yellow=y;
}
public void setPosition(int x,int y)
{
this.x=x;
this.y=y;
}
public void setRadius(int r)
{
this.r=r;
}
public void paint(Graphics g)
{
if(red==1)
{
g.setColor(Color.red);
}
else if(green==1)
{
g.setColor(Color.green);
}
else if(yellow==1)
{
g.setColor(Color.yellow);
}
g.fillOval(x,y,2*r,2*r);
}
}
SignalFrame.java
import
java.awt.*;
import
java.applet.*;
import
java.awt.event.*;
public
class SignalFrame extends Frame implements ItemListener
{
Choice choice;
SignalCanvas signal=null;
String
itemRed="红灯",itemYellow="黄灯",itemGreen="绿灯";
public SignalFrame()
{
choice=【代码1】
//创建choice
【代码2】
//创建choice添加itemRed
【代码3】
//创建choice添加itemYellow
【代码4】
//创建choice添加itemGreen
【代码5】
//将当前窗口注册为choice的ItemEvent事件监视器
add(choice,BorderLayout.NORTH);
try{ Class
cs=Class.forName("SignalCanvas");
signal=(SignalCanvas)cs.newInstance();
add(signal,BorderLayout.CENTER);
}
catch(Exception
e)
{ add(new Label("您还没有编写SignalCanvas类"),BorderLayout.CENTER);
}
setBounds(100,100,360,300);
setVisible(true);
validate();
addWindowListener(new WindowAdapter()
{ public
void windowClosing(WindowEvent e)
{
System.exit(0);
}
}
);
}
public
void itemStateChanged(ItemEvent e)
{ String
item=
【代码6】
// choice返回被选中的条目
int w=signal.getBounds().width;
int h=signal.getBounds().height;
int m=Math.min(w,h);
signal.setRadius(m/6);
if(item.equals(itemRed))
{ if(signal!=null)
{ signal.setRed(1);
signal.setYellow(0);
signal.setGreen(0);
signal.setPosition(w/3,0);
signal.repaint();
}
}
else if(item.equals(itemYellow))
{ if(signal!=null)
{ signal.setRed(0);
signal.setYellow(1);
signal.setGreen(0);
signal.setPosition(w/3,h/3);
signal.repaint();
}
}
else if(item.equals(itemGreen))
{ if(signal!=null)
{ signal.setRed(0);
signal.setYellow(0);
signal.setGreen(1);
signal.setPosition(w/3,2*h/3);
signal.repaint();
}
}
}
}
SignalMainClass.java
public
class SignalMainClass
{
public static void main(String args[])
{
SignalFrame frame;
frame=new SignalFrame() ;
frame.setTitle("信号灯");
}
}
²
实验后的练习:
1.
改进上述程序,在下拉列表中增加“熄灭所有灯”选项,当选中该项时,画布上绘制一个半径为0,位置是(0,0)的圆。
3.布局与日历。
²
实验要求:
编写一个应用程序,有一个窗口,该窗口为BorderLayout布局。窗口的中心添加一个Panel容器:pCenter,pCenter的布局是7行7列的GriderLayout布局,pCenter中放置49个标签,用来显示日历。窗口的北面添加一个Panel容器pNorth,其布局是FlowLayout布局,pNorth放置两个按钮:nextMonth和previousMonth,单击nextMonth按钮,可以显示当前月的下一月的日历;单击previousMonth按钮,可以显示当前月的上一月的日历。窗口的南面添加一个Panel容器pSouth,其布局是FlowLayout布局,pSouth中放置一个标签用来显示一些信息。
²
程序模板:
CalendarBean.java
import java.util.Calendar;
public class CalendarBean
{
String
day[];
int
year=2005,month=0;
public void setYear(int year)
{
this.year=year;
}
public int getYear()
{
return year;
}
public void setMonth(int month)
{
this.month=month;
}
public int getMonth()
{
return month;
}
public String[] getCalendar()
{
String a[]=new String[42];
Calendar
日历=Calendar.getInstance();
日历.set(year,month-1,1);
int
星期几=日历.get(Calendar.DAY_OF_WEEK)-1;
int day=0;
if(month==1||month==3||month==5||month==7||month==8||month==10||month==12)
{
day=31;
}
if(month==4||month==6||month==9||month==11)
{
day=30;
}
if(month==2)
{
if(((year%4==0)&&(year0!=0))||(year@0==0))
{
day=29;
}
else
{
day=28;
}
}
for(int i=星期几,n=1;i<</FONT>星期几+day;i++)
{
a[i]=String.valueOf(n) ;
n++;
}
return a;
}
}
CalendarFrame.java
import java.util.*;
import java.awt.*;
import
java.awt.event.*;
import java.applet.*;
public class CalendarFrame extends Frame implements
ActionListener
{
Label labelDay[]=new Label[42];
Button titleName[]=new Button[7];
String name[]={"日","一","二","三",
"四","五","六"};
Button nextMonth,previousMonth;
int year=2006,month=10;
CalendarBean calendar;
Label showMessage=new Label("",Label.CENTER);
public CalendarFrame()
{ Panel
pCenter=new Panel();
【代码1】
//将pCenter的布局设置为7行7列的GridLayout
布局。
for(int i=0;i<7;i++)
{
titleName[i]=new Button(name[i]);
【代码2】//pCenter添加组件titleName[i]。
}
for(int i=0;i<42;i++)
{
labelDay[i]=new Label("",Label.CENTER);
【代码3】//pCenter添加组件labelDay[i]。
}
calendar=new
CalendarBean();
calendar.setYear(year);
calendar.setMonth(month);
String day[]=calendar.getCalendar();
for(int i=0;i<42;i++)
{
labelDay[i].setText(day[i]);
}
nextMonth=new Button("下月");
previousMonth=new Button("上月");
nextMonth.addActionListener(this);
previousMonth.addActionListener(this);
Panel pNorth=new Panel(),
pSouth=new Panel();
pNorth.add(previousMonth);
pNorth.add(nextMonth);
pSouth.add(showMessage);
showMessage.setText("日历:"+calendar.getYear()+"年"+
calendar.getMonth()+"月"
);
ScrollPane scrollPane=new ScrollPane();
scrollPane.add(pCenter);
【代码4】//
窗口添加scrollPane在中心区域
【代码5】//
窗口添加pNorth
在北面区域
【代码6】//
窗口添加pSouth
在南区域。
}
public void actionPerformed(ActionEvent e)
{
if(e.getSource()==nextMonth)
{ month=month+1;
if(month>12)
month=1;
calendar.setMonth(month);
String day[]=calendar.getCalendar();
for(int i=0;i<42;i++)
{ labelDay[i].setText(day[i]);
}
}
else if(e.getSource()==previousMonth)
{ month=month-1;
if(month<1)
month=12;
calendar.setMonth(month);
String day[]=calendar.getCalendar();
for(int i=0;i<42;i++)
{
labelDay[i].setText(day[i]);
}
}
showMessage.setText("日历:"+calendar.getYear()+"年"+calendar.getMonth()+"月"
);
}
}
CalendarMainClass.java
public class CalendarMainClass
{ public static void main(String args[])
{
CalendarFrame frame=new CalendarFrame();
frame.setBounds(100,100,360,300);
frame.setVisible(true);
frame.validate();
frame.addWindowListener(new
java.awt.event.WindowAdapter()
{
public void windowClosing(java.awt.event.WindowEvent
e)
{
System.exit(0);
}
}
);
}
}
²
实验后的练习:
1.
请在CalendarFrame类中增加一个TextField文本框,用户可以通过在文本框中输入年份来修改calendar对象的int成员year。
实验七 输入输出处理
【目的】
①
了解流式输入输出的基本原理。
②
掌握类File、FileInputStream、FileOutputStream、RandomAccessFile的使用方法。
【内容】
1.运行下面的程序,学习文件和目录的简单操作。
import
java.io.*;
public
class
FileOperation {
public
static
void
main(String args[]) {
try
{
BufferedReader din =
new
BufferedReader(new
InputStreamReader(
System.in));
String sdir =
"test";
String sfile;
File Fdir1 =
new
File(sdir);
if
(Fdir1.exists() && Fdir1.isDirectory()) {
System.out.println("There
is a directory "
+ sdir +
" exists.");
for
(int
i = 0; i < Fdir1.list().length;
i++)
//
列出目录下内容
System.out.println((Fdir1.list())[i]);
File Fdir2 =
new
File("test\\temp");
if
(!Fdir2.exists())
Fdir2.mkdir();
//
创建原不存在的目录
System.out.println();
System.out.println("Now
the new list after create a new dir:");
for
(int
i = 0; i < Fdir1.list().length;
i++)
//
检查目录是否已建立
System.out.println((Fdir1.list())[i]);
System.out.println();
System.out.println("Enter
a file name in this directory:");
sfile = din.readLine();
//
选取指定目录下一个文件
File Ffile =
new
File(Fdir1, sfile);
if
(Ffile.isFile()) {
//
显示文件有关信息
System.out.println("File
"
+ Ffile.getName() +
" in Path "
+ Ffile.getPath() +
" is "
+ Ffile.length()
+
" in length. ");
}
}
else
{
System.out.println("the
directory doesn''t exist!");
}
}//
try
catch
(Exception e) {
System.out.println(e.toString());
}
}
}
2.创建一个顺序文件,向其中写入部分用户键盘输入的字符,并回显在屏幕上。
3.运行下面的程序,学习随机文件的读写
import
java.io.*;
public
class
testRandom {
public
static
void
main(String args[]) {
try
{
RandomAccessFile rf =
new
RandomAccessFile("rtest.dat",
"rw");
for
(int
i = 0; i < 10; i++)
rf.writeDouble(i * 1.414);
rf.close();
rf =
new
RandomAccessFile("rtest.dat",
"rw");
rf.seek(5 * 8);
rf.writeDouble(47.0001);
rf.close();
rf =
new
RandomAccessFile("rtest.dat",
"r");
for
(int
i = 0; i < 10; i++)
System.out.println("Value
"
+ i +
": "
+ rf.readDouble());
rf.close();
}
catch
(IOException e) {
System.out.println(e.toString());
}
}
}
4.
写一程序统计纯文本文件“Early-Precaution.txt”的大写字母、小写字母个数,并将所有小写字母转换为大写字母,输出到result.txt.
5.
设计一个类FileRWTest,实现从input.txt文件中读入数据到字符数组cBuffer中,然后再写入到文件“output.txt”中。
思考题
1.字符流和字节流的区别是什么?
2.对文件进行读写操作的过程是什么?
实验八 Java
Swing应用程序设计
实验8-1:组合使用文本区与滚动窗口
实验内容
编程实现文本区与滚动条的综合使用,实现了4个按钮jbArray[1]、jbArray[2]、jbArray[3]、jbArray[4],按下4个按钮分别改变文本区的换行状态,包括自动换行、不换行、单词边界、字符边界。运行后效果如图8-1所示。
http://s1/bmiddle/0030bwcPgy6WWBks74Y90&690
图8-2
实验8-1运行结果
实验目的
通过这个简单的实例让大家学习文本区域滚动窗口的使用。在自动换行的情况下,当文本内容超过一行时,文本区自动换行。当文本区超过滚动窗口的大小时,滚动窗口根据需要自动出现水平或垂直滚动条。在单词边界换行的情况下,文本区在自动换行时不会把单词拆开;而在字符边界换行的情况下,文本区在自动换行时会根据需要将单词拆开。
实验8-2:使用滑块与进度条
实验内容
编程实现滑块与进度条的综合使用,设置滑块值为1000,并为两个组件注册事件监听器ChangeEvent,实现当滑块滑动后进度条将指示滑块的当前值。运行后效果如图6-9所示。
http://s13/bmiddle/0030bwcPgy6WWBluztGfc&690
图8-3
实验82运行结果
实现思路
使用了一个滑块与一个进度条,滑块设置为绘制主副刻度及主刻度标签,进度条设置为显示进度百分比的普通模式。同时,代码中为滑块注册了ChangeEvent事件监听器,当滑块被拖动时进度条即时显示对应的百分比。
实验8-3:文件、颜色对话框综合案例
实验内容
编程实现文件、颜色对话框的综合使用;通过选择“设置”菜单中的“设置颜色”可以设置标签字体的颜色,通过选择“设置”菜单中的“打开文件”可以动态在标签中显示打开文件的名称。运行后效果如图8-4所示。
http://s4/mw690/0030bwcPgy6WWBpxQ2vd3&690
图8-4
实验8-3运行结果
实现思路
在窗体中放置了一个标签,通过选择“设置”菜单中的“设置颜色”可以设置标签字体的颜色,通过选择“设置”菜单中的“打开文件”可以动态地在标签中显示打开文件的名称。actionPerformed事件处理方法中,根据选择菜单项的不同弹出对应的对话框设置标签字体的颜色或修改标签的内容。
加载中,请稍候......