第5章 图形用户界面设计
本章习题解答
一、简答题
1.什么是AWT?AWT的基本思想是什么?
答:AWT(抽象窗口工具包)是一组应用程序接口(API),其中包括各种Java程序员用来创建图形用户界面(GUI)的类,这些类分别对应着Java图形用户界面的构成成份:组件和容器。组件通常为图形用户界面中的可见部分,例如按钮(button)和标签(label)等。容器是图形用户界面中容纳其他组件的部分,一个容器中可以容纳一个或多个组件,甚至还可以容纳其他的容器。
AWT的基本思想是将图形用户界面(GUI)看作一系列嵌套的构件,最外层是窗口这样的容器,容器内又可以包含其他的组件和容器。这样由表及里,所有的构件构成了一个嵌套的树,一个构件在这棵树中的位置决定了它显示在屏幕上的位置以及事件的传递途径。
2.容器主要有哪些作用?Java中有哪些常见的容器。它们之间有什么异同? 答:容器组件的主要作用是包容其他组件或容器并按一定的方式组织排列它们,同一个容器的所有构件通常总是同时被显示和同时被隐藏的。
Java中常见的容器有Frame(框架)、Panel(面板)和Applet 框架Frame是一个带有边框的独立的窗口,可以移动、放大、缩小、关闭。 是独立于Applet和浏览器的一个窗口,是Application程序最外层的容器。面板是包
含在窗口中的一个不带边框的区域。不是一个单独的窗口,它只是包含在窗口中的一个区域,是可以将许多组件组合起来的一种容器,必须将面板添加到窗体中才能
正常显示出来 。Applet也是无边框的容器,是Applet程序最外层的容器。
3.布局管理器的作用是什么?Java提供了哪几种布局管理器? 答:布局管理器用来控制组件在容器中的摆放位置。
Java提供了5种布局管理器,它们是:顺序布局管理器(FlowLayout)、边界布局管理器(BorderLayout)、网格布局管理器(GridLayout)、卡片布局管理器(CardLayout)、网格包布局管理器(GridBagLayout)
4.设计和实现图形用户界面的主要工作有哪些?
答:设计和实现图形用户界面的工作主要有两个:一是创建组成界面的各种容器和组件,指定它们的属性和位置关系,根据具体需要排列它们,从而构成完整的图形用户界面的物理外观;二是定义图形用户界面的事件和各界面元素对不同事件的响应,从而实现图形用户与用户的交互功能。
5.简述事件对象、事件源、监听者的概念? 答:这三个概念的基本念义如下:
事件对象:通常当用户在用户接口上进行某种操作时,如按下键盘上某个键或移动鼠标,均会引发一个事件。事件对象是用来描述所发生事件相关信息的对象,对应用户操作的不同种类有不同类型的事件类(对象)与之对应。
事件源:是指一个事件的产生者。例如,当在一个按纽(Button)上单击鼠标时就会产生一个ActionEvent的事件对象,事件源就是该按纽。通过ActionEvent对象的有关方法可以获得该事件的有关信息,
事件监听器:用来调用事件处理方法的对象。
6. JDK1.1的事件处理机制是什么?其原理是什么?
答:JDK1.1的事件处理机制采用委托事件模型来处理事件。委托事件模型的原理如下:
? 确定事件源。图形界面的每个可能产生事件的组件称为事件源,不同事件源上发生的事件的种类不同。
? 注册事件源。如果希望事件源上发生的事件被程序处理,就要把事件源注册给能够处理该事件源上那种类型的事件监听者。监听者是属于一个类的实例,这个类实现了一个特殊的接口,名为“监听者接口”。
? 委托处理事件。当事件源上发生监听者可以处理的事件时,事件源把这个事件作为实际参数传递给监听者中负责处理这类事件的方法,该方法根据事件对象中封装的信息来确定如何响应这个事件。 二、编程题
1.编写代码,创建标题为“基本GUI”编程的窗口。 参考代码如下: import java.awt.*;
class NewFrame extends Frame { public static void main(String args[]) { NewFrame mainFrame = new NewFrame(); mainFrame.setTitle(\基本GUI编程\
mainFrame.setSize(200, 200);
mainFrame.setVisible(true); } }
2.编写代码,创建标题为“使用面板的基本GUI编程”的面板。 参考代码如下: import java.awt.*;
class NewPanel extends Panel {
public static void main(String args[]) {
NewPanel np=new NewPanel();
Frame f=new Frame(\使用面板的基本GUI编程!\f.add(np);
f.setSize(300,200); f.setVisible(true);
} }
3.创建一个窗口,包括一个标签、一个文本框和一个按钮,当用户单击按钮时,程序把文本框中的内容复制到标签中。请使用两种以上的布局管理器布局窗口的组件。
参考代码如下: import java.awt.*; import java.awt.event.*;
public class CopyText extends Frame implements ActionListener{ Panel p; Label l; TextField t; Button b;
public CopyText(){ p=new Panel();
l=new Label(\ \l.setBackground(Color.BLUE); t=new TextField(20);
b=new Button(\复制文本\
p.add(t); p.add(l);
add(\
add(\
b.addActionListener(this); //给按钮注册活动事件监听器 setVisible(true);
this.setTitle(\文本复制示例\ setSize(400,200); pack(); }
public void actionPerformed(ActionEvent e){ if(e.getSource()==b) {
l.setText(t.getText()); }
}
public static void main(String args[]){ CopyText ct=new CopyText();
} }
4.编写一个程序,创建一个AWT面板,该面板包含标有三个不同颜色名称的三个按钮,单击每个按钮时应使窗口的背景色显示为相应的颜色。
import java.awt.*;
import java.awt.event.*;
class ChangeBgColor extends Frame implements ActionListener{ Panel p;
Button btn1,btn2,btn3; ChangeBgColor(){
p=new Panel();
btn1= new Button(\红色\ btn2=new Button(\蓝色\ btn3=new Button(\黄色\ this.add(p); p.add(btn1); p.add(btn2); p.add(btn3);
btn1.addActionListener(this); btn2.addActionListener(this); btn3.addActionListener(this); }
public static void main(String args[]) {
ChangeBgColor mainFrame = new ChangeBgColor(); mainFrame.setTitle(\基本GUI编程\ mainFrame.setSize(200, 200); mainFrame.setVisible(true);
}
public void actionPerformed(ActionEvent e){ if (e.getSource()==btn1) { p.setBackground(Color.red); }
else if(e.getSource()==btn2){
p.setBackground(Color.blue); }
else
p.setBackground(Color.yellow); } }
第6章 AWT组件库
本章习题解答
一、简答题
1.说明文本框和标签之间的区别?
答:文本框定义了一个单行条形文本区,可以输出任何基于文本的信息,也可以接受用户的输入,并有事件响应。标签可以显示一行静态的文本,它只起信息说明作用,不接受用户的输入,无事件响应。
2.试列举Java中常用的基本控制组件。如果有二到三种取值可能,采用哪种组件合适?如果取值的可能大于5种,采用哪种组件合适?
答:基本控制组件是图形用户界面的最小单位之一,它里面不再包含其他成分。基本控制组件的作用是完成与用户的一次交互。目前常用的基本控制组件有: 标签(Label)、文本编辑区(TextField、TextArea)、按钮(Button)、复选框(Checkbox)、单选按钮(CheckboxGroup、Checkbox)、下拉列表(List或Choice)。 如果这两到三种取值是互斥的话,采用单选按钮表示比较合适,否则采用复选按钮表示;如果5种以上的取值只能多选一的话,采用Choice下拉列表,否则采用List下拉列表。
3.什么是选择事件?可能产生选择事件的GUI组件有哪些? 答:选择事件是当选择项的选中状态发生变化时所引起的事件。
可能产生选择事件的GUI组件有下拉列表类(Choice)、列表类(List)复选
按钮类(CheckBox)、检测盒菜单项(CheckboxMenuItem) 4.设计一个菜单的步骤是什么?
答:设计菜单的步骤是:
? 用MenuBar构造函数构造菜单栏对象。 ? 用Menu构造函数构造菜单对象。
? 用MenuItem构造函数构造菜单项对象。
? 用Menu类的add方法将菜单项加入菜单中。
? 用MenuBar类的add方法将菜单加菜单栏中。
? 用Frame类的setMenuBar方法将菜单栏加入窗口中。
5.有模式的对话框最突出的特点是什么?如果一个对话框的目的在于警告或提醒用户(例如删除数据库记录的确认),这个对话框应该是有模式的还是无模式的?
答:有模式对话框是指打开后必须作出响应的对话框。如果一个对话框的目的在于警告或提醒用户,应该为有模式的对话框。
6.Swing组件与AWT组件的区别是什么?
答:AWT组件是JDK1.0和1.1平台用于开发GUI的工具,尽管Java2平台仍然支持AWT组件,但是,使用Swing组件来开发GUI已经成为一种发展趋势。 为了标识Swing组件,Swing组件的在其名称前冠以J字母,例如,在AWT中的Button类,在Swing中为JButton。另外,AWT存在于java.awt包中,Swing组件存在于javax.swing包中。
Swing组件与AWT组件的最大不同是:Swing组件完全由Java语言实现,功能更强大,而AWT而不是。
Swing组件还提供了AWT组件无法实现的功能:
? Swing按钮类和标签类除了显示文本标题,还可以显示图形标题 ? Swing容器可以加边框
? Swing组件可以自动适应操作系统的外观,而AWT组件总是保持相同的外观
? Swing组件可以设计成圆形,而不一定是矩形 ? 通过Swing组件的方法改变其外观和形为
? 不能在Swing的顶层容器(如JApplet、JFrame)直接加入组件,而要先获得容器,再在容器中加入组件。
二、编程题
1.如图6-17所示。标签1的字号比文本框的字号大,当单击按钮时若输入文框中的数正确,则标签2文本显示正确,否则显示不正确。
标签2 标签1 6+9= 正确 15 OK 文本框 图6-17
参考代码如下:
import java.awt.*;
import java.awt.event.*;
public class program1 extends Frame implements ActionListener{ Label lb1=new Label(\
Label lb2=new Label(\ \TextField tf=new TextField(3); Button bt=new Button(\
public program1(){ lb1.setFont(new Font(\
setLayout(new FlowLayout()); add(lb1); add(tf); add(lb2);
add(bt);
bt.addActionListener(this); setSize(150,200); setVisible(true);
}
public void actionPerformed(ActionEvent e){ if(e.getSource()==bt) { String str=tf.getText(); }
public static void main(String args[]){ new program1(); }
}
本程序的运行结果如图6-18、6-19所示。
if(str.equals(\ lb2.setText(\正确\else
lb2.setText(\不正确\
}
图6-18 图6-19
2.编写代码,创建一个JFrame窗口,为其构建两个单选按钮,程序运行的初始界面如图6-20所示。当用户单击“禁用”按钮时,显示图6-21所示的界面,单击“启用”按钮时,显示图6-22所示的界面。
图6-20 图6-21
图6-22
参考代码如下: import java.awt.*; import java.awt.event.*; import javax.swing.*;
import java.lang.String;
public class MyRadiobuttons extends JFrame implements ActionListener{ JRadioButton rad1,rad2;
ButtonGroup rbgrp=new ButtonGroup(); public MyRadiobuttons(){ setTitle(\单选按钮\
JPanel cpane=(JPanel)getContentPane(); cpane.setLayout(new GridLayout()); rad1=new JRadioButton(\启用\
rad1.addActionListener(this); rad1.setSelected(true);
rad1.setEnabled(false);
rad2=new JRadioButton(\禁用\rad2.addActionListener(this); rad2.setSelected(false); cpane.add(rad1); cpane.add(rad2); rbgrp.add(rad1); rbgrp.add(rad2);
radadapter radapp=new radadapter(); addWindowListener(radapp);
}
class radadapter extends WindowAdapter{
public void windowClosing(WindowEvent e){ System.exit(0); }
}
public void actionPerformed(ActionEvent e){ if(e.getSource()==rad1){
setTitle(\启用第一个单选的按钮\ rad1.setEnabled(false); rad2.setEnabled(true);
}
else if(e.getSource()==rad2){
setTitle(\启用第二个单选按钮\ rad1.setEnabled(true); rad2.setEnabled(false);
} }
public static void main(String args[]){
MyRadiobuttons radb=new MyRadiobuttons(); radb.setSize(200,100); radb.setVisible(true);
} }
3.创建一个菜单程序。添加一个菜单:文件。在“文件”下添加三个菜单选项:“功
能1”、“功能2”和“退出”,“功能2”和“退出”两项之间用分隔线分开。当用户点击菜单项时,在窗口的标题栏显示相应的命令文本,如图6-23所示。(通过查阅JDK文档,思考如何用Swing创建此菜单程序)
图6-23
参考代码如下: import java.awt.*;
import java.awt.event.*;
public class MyMenu extends Frame implements ActionListener{ MenuBar mb=new MenuBar(); Menu mu=new Menu(\文件\ MenuItem mt1=new MenuItem(\功能1\ MenuItem mt2=new MenuItem(\功能2\ MenuItem mt3=new MenuItem(\退出\ public MyMenu(){ }
mu.add(mt1); mu.add(mt2);
mu.addSeparator(); mu.add(mt3);
mb.add(mu);
//将菜单项注册给事件监听者 mt1.addActionListener(this); mt2.addActionListener(this); mt3.addActionListener(this); setMenuBar(mb); setTitle(\创建菜单\setSize(200,200); setVisible(true);
public void actionPerformed(ActionEvent e){ MenuItem mt=(MenuItem)e.getSource(); setTitle(mt.getActionCommand()); }
public static void main(String args[]){ new MyMenu(); } }
第7章 多媒体编程
本章习题解答
一、简答题
1.Applet有什么安全限制?
答:Applet不能加载客户端的类与定义客户端的方法,Applet不能访问客户端的文件,包括阅读、修改、删除,Applet不能在客户端创建网络连接,防止客户端的资料被盗取,Applet不能在客户端启动任何程序。
2.Applet是什么?简述Applet在浏览器中执行的工作原理。
答:Applet也叫小应用程序,是一种在浏览器环境下运行的Java程序。当某一个浏览器向服务器请求下载嵌入了Applet的HTML文件时,浏览器会根据Applet的名字和位置自动把字节码文件从WWW服务器上下载到本地,然后浏览器利用本身拥有的Java解释器直接执行该字节码文件。
3.简述浏览器调用Applet类的生命周期方法的过程。 答:一个Applet的生命周期与Web页面有关。当首次加载含Applet的页面时,浏览器调用init()方法,完成Applet的初始化。然后调用start()方法,完成有关动作的执行。接着调用paint()方法在浏览器上绘制内容。当用户离开页面时,浏览器调用 stop()方法停止小程序运行。若用户关闭浏览器将使Applet停止运行,浏览器调用destory()方法终止,使小应用程序有机会释放其存在期间锁定的资源。只要用户不关闭浏览器,重新加载页面,浏览器则只调用start()方法和paint()方法重新绘制并运行小程序。
4.简述paint()、repaint()和update()三个方法之间的调用关系。
答:paint()、repaint()和update()是与显示及刷新有关的重要的Applet方法,它们都是在java.awt.Component类中声明的。
Applet的显示和刷新由一个独立的线程控制,称为AWT线程。当Applet首次
被加载或Applet部分显示内容被其他窗口覆盖,那么当其他窗口关闭或移开时,AWT线程会自动调用paint()方法。当在程序中使用repaint()方法通知系统更新显示内容时,AWT线程会自动调用update()方法,该方法首先将当前显示画面清空,然后调用paint()方法绘制新的内容。
5.在Applet中如何显示图像?
答:在Applet中显示图像的方法如下:
? 在Applet的init( )方法中用Applet类的getImage( )方法装载一个Image对象 ? 在Applet的paint( )方法中用Graphics类的drawImage( )方法将该对象画在屏幕上。
6.在Applet中如何播放声音?
答:在Applet中播放声音文件有两种不同的方式: 第一种方法:利用Applet类的play( )方法直接播入。
第二种方法:利用Applet的getAudioClip()方法创建声音剪辑对象,加载指定文件,返回AudioClip对象,然后利用AudioClip对象的声音文件处理方法play( )或loop( )方法播放声音。
二、编程题
1.试绘制一面国旗。程序的运行结果如图7-11所示:
图7-11
程序代码如下: import java.awt.*; import java.awt.Graphics; import java.awt.event.*; import java.applet.Applet;
public class CountryFlag extends Applet { public void paint(Graphics g){
//下面两行是大五角星的10个拐点的X坐标和Y坐标
int xs1[]={80,85,98,87,92,80,68,73,63,75,80};
int ys1[]={40,54,54,62,76,67,76,62,54,54,40};
//下面两行是第1个小五角星的10个拐点X坐标和Y坐标 int xs2[]={115,117,120,117,118,115,112,113,110,113,115}; int ys2[]={34,38,38,40,44,42,44,40,38,38,34}; g.setColor(Color.red); g.fillRect(40,20,250,150);
g.setColor(Color.yellow);
Polygon p1=new Polygon(xs1,ys1,11); g.fillPolygon(p1);
Polygon p2=new Polygon(xs2,ys2,11); g.fillPolygon(p2);//绘制小五角星
g.copyArea(110,34,10,10,10,11);//复制绘出第二个小五星 g.copyArea(110,34,10,10,10,26);//复制绘出第三个小五星 g.copyArea(110,34,10,10,0,38);//复制绘出第四个小五星
} }
2.编写一个Applet,实现一个字符串沿正弦曲线移动。 参考代码如下:
public class BallMove extends Applet { int x,y;
int h;
Dimension d; public void init(){ d = size(); h=d.height / 2;
x=20; }
public void paint(Graphics g) { if(x y = (int)((1.0 + Math.sin((x)*0.05))*h); x++; } else x=20; g.drawString(\你好\ try{ Thread.sleep(50); } catch(InterruptedException e) { showStatus(e.toString()); } repaint(); } } 3.当鼠标单击事件发生时,利用Math类的方法Random( )产生3个随机数,同时获得鼠标位置坐标,在鼠标单击处绘制圆。圆的颜色由三个随机数决定。程序的输出结果如图7-12所示。 图7-12 程序参考代码如下: import java.awt.*; import java.awt.event.*; import java.applet.*; public class DrawDot extends Applet { int i,j,k; int x,y; Color mycolor; public void init(){ this.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent e) { this_mouseClicked(e); } }); } void this_mouseClicked(MouseEvent e) { x = e.getX() ; y = e.getY() ; i = (int)(255*Math.random()); j = (int)(255*Math.random()); k = (int)(255*Math.random()); repaint(); } public void paint(Graphics g){ mycolor = new Color(i,j,k); g.setColor(mycolor); g.fillOval(x-10,y-10,20,20); } //重载update( )方法,使每次单击鼠标所绘制的点圆得以保留。 public void update(Graphics g){ paint(g); } } 4.编写一个Applet,显示一幅图像并配上背景音乐。 请参考7.1.2节和7.3.1节内容。 第8章 异常处理 本章习题解答 一、简答题 1.什么是异常?异常产生的原因有哪些? 答:异常就是Java程序在运行过程中出现的错误。这类错误使程序非正常终止,但通过修正后还可以继续运行。 异常产生的原因有: (1)JVM检测到非正常的执行状态,这些状态可能由以下情况引起的: ? 表达式违反了Java语言的语义,如除数为0 ? 装入或链接程序时出错 ? 超出了资源限制,如内存不足,这种异常是程序员无法预知的 (2)程序代码中的throw语句被执行 (3)因为代码段不同步而产生,可能的原因是: ? Thread(线程)的stop方法被调用 ? JVM内部发生错误。 2.为什么Java的异常处理技术优于传统程序的异常处理技术? 答:在没有异常处理机制的程序设计语言中进行异常处理,通常是在程序设计中使用if-else或switch-case语句所能设想的到的错误情况,以捕捉程序中可能发生的错误。在这种处理方式的程序中,对异常的监视、报告和处理的代码与程序中完成正常功能的代码交织在一起,即在完成正常功能的程序的许多地方插入了与处理异常有关的程序块。这种处理方式虽然在异常发生点可以看到程序如何处理异常,但它干扰了人们对程序正常功能的理解,使程序的可读性和可维护性下降,并且由于人的思维限制,常常会遗漏一些意想不到的异常。 Java的异常处理机制是在程序中监视可能发生异常的程序块,将一个程序中的所有异常收集起来放到程序的某一段中处理,而不必在被监视的程序块中多处插入处理异常的代码,使完成功能的程序代码与进行异常处理的程序代码分开,增强了程序的可读性和可靠性,减少了编程人员的工作量,增加了程序的灵活性。此外,这种机制可以及时有效地处理程序运行中的异常,可以预防因错误的程序代码或系统错误所造成的不可预期的结果发生,并且当这些不可预期的错误发生时,异常处理机制会尝试恢复异常发生前的状态或对这些错误结果做一些善后处理。 3.在Java代码中可用来处理异常的方式有哪些? 答:在Java代码中可用来处理异常的方式有两种: (1)在可能产生异常的方法中,采用Java语言提供的try-catch-finally语句块处理异常 (2)如果一个方法可能生成某种异常,但是并不能确定如何处理这种异常,则此方法应声明抛弃该种异常,表明该方法将不对此类异常进行处理,而由该方法的调用者负责处理。此时需在方法声明中包含throws子句。 4.如果发生了一个异常,但没有找到适当的异常处理程序,则会发生什么情况? 答:如果发生了一个异常,但没有找到适当的异常处理程序,则Java系统会采用Java异常处理机制预设处理方法来处理异常,即一旦程序发生异常,程序就会被终止并显示相应的错误信息给用户。 5.说明throw与throws有什么不同? 答:throw与throws的不同之处在于: throw语句是一个独立的语句,用来明确地抛出一个异常,其作用是改变程序的 执行流程,使程序跳到相应的异常处理语句中执行。而throws语句总是和方法定义结合起来用,在有些情况下,不需要一个方法处理本身可能产生的异常,而是希望把异常向上移交给调用这个方法的方法来处理,就需要通过throws语句来实现。 6.在设计catch块处理不同的的异常时,一般应注意哪些问题? 答:应注意如下的问题: (1)catch块中的语句应根据异常的不同执行不同的操作,比较通用的操作是打印异常的相关信息,包括异常名称、产生异常的方法名等。 (2)由于异常对象与catch块的匹配是按catch块的先后排列顺序进行的,所以在处理多异常进应注意认真设计各catch块的排列顺序。一般地,处理较具体和较常见的异常的catch块应放在前面,而可以与多种异常相匹配的catch块应放在较后的位置。 第二种方法:利用Applet的getAudioClip()方法创建声音剪辑对象,加载指定文件,返回AudioClip对象,然后利用AudioClip对象的声音文件处理方法play( )或loop( )方法播放声音。 二、编程题 1.编写一个程序,用来将作为命令行参数输入的值转换为数字,如果输入的值无法转换为数字,则程序应显示相应的错误消息,要求通过异常处理方法解决。 程序代码如下: class NumberException{ public static void main(String arg[]) { try{ int i=Integer.parseInt(arg[0]); System.out.println(\输入的字符串可以转换为一个有效数字\ } catch(NumberFormatException e){ System.out.println(\请输入一个有效数字\ } } } 2.编写一个程序,用于将来自用户的两个数字接受为命令行参数。将第一个数字除以第二次数字并显示结果。代码应当处理引发的异常,即在输入的参数数量不是两个或用户输入0作为参数时引发异常。 程序参考代码如下: class MulException{ public static void main(String args[]) { int x,y,z; try{ x=Integer.parseInt(args[0]); y=Integer.parseInt(args[1]); z=x/y; System.out.println(x+\} catch(ArrayIndexOutOfBoundsException e){ System.out.println(\输入的参数数量不是两个\} catch(ArithmeticException e){ System.out.println(\第二个参数不能为零\ } finally{ System.out.println(\程序运行结束\ } } } 3.编写一个程序,说明在一个catch处理程序中引发一个异常时会发生什么情况。 参考代码如下: public class catchException{ public static void main(String args[]) { try{ throw new NullPointerException(\空指针异常\} catch(NullPointerException e){ System.out.println(\捕捉第一次产生的空指针异常\ throw new ArithmeticException (\数学异常\} finally{ System.out.println(\程序正常执行完毕!\ } } } 当在异常处理程序中引发了异常时,该异常应由原try块的外层程序来处理,如果没有捕获处理,异常将向上级传递。 4.编写一个可演示用户自定义异常用法的程序,该程序接受用户输入的学生人数,当输入一个负数时,认为是非法的。用户自定义异常捕获此错误。 程序参考代码: import java.io.*; class MyException { public static void main(String args[]){ String s=\ int t; while(true){ try{ System.out.print(\请输入学生人数:\ BufferedReader in=new BufferedReader(new InputStreamReader(System.in)); s=in.readLine(); t=Integer.parseInt(s); if(t<0) throw new NegException(\人数不能为负数!\ System.out.println(\你输入的人数是:\ break; } catch(IOException e){ System.out.println(e);} catch(NegException e){System.out.println(e);} } } } class NegException extends Exception{ public NegException(String message){ super(message); } } 第9章 输入输出与文件处理 本章习题解答 一、简答题 1.什么叫流?对流的分类通常有几种方式? 答:流是指一组有顺序的、有起点和终点的字节结合。 流的分类方式有多种: ? 根据数据流动的方向,可分为输入流和输出流。 输入流:只能从中读取数据,而不能向其写出数据 输出流:只能向其写出数据,而不能从中读取数据 ? 根据处理数据的单位划分,可分为字符流和字节流 字节流:以字节为单位进行数据传输,每次传送一个或多个字节 字符流:以Unicode字符为单位进行数据传输,每次传送一个或多个字符 ? 根据数据流所关联的是数据源还是其他数据流,可分为节点流和处理流 节点流:直接从指定的位置(如磁盘文件或内存区域)读或写 处理流:对一个巳存在的流的连接和封装,通过对所封装的流的功能调用实现数据的读/写功能,处理流并不直接连接到数据流。 2.Java的所有I/O流都是四个抽象类的子类,这四个抽象类是什么? 答: ? InputStream:是所有字节输入流的父类 ? OutputStream:是所有字节输出流的父类 ? Reader:是所有输入字符流的父类 ? Writer:是所有输出字符流的父类 3.写出下面这些输入输出流类的输入输出操作的特点。 (1) InputStream和OutputStream (2) DataInputStream 和DataOutputStream (3) FileInputStream和FileOutputStream (4) PrintStream (5) RandomAccessFile 答: (1)一个字节一个字节地输入输出数据 (2)按照不同的数据类型输入输出数据 (3)一个字节一个字节地输入输出数据 (4)把数据转化成字符串输出 (5)按照不同的数据类型输入输出数据 4.File类的作用是什么? 答:File类是I/O包中唯一能够代表磁盘文件本身的对象,使用File类,我们可以方便地建立与某磁盘文件的连接。一个对应着某磁盘文件或目录的File对象一经创建,我们就可以通过调用它的方法来获得该文件或目录的属性,File类中还定义了一些对文件或目录进行管理、操作的方法,利用这些方法可以完成对文件和目录的建立、删除、查询、重命名等操作。 5.Java语言是否可以读入和写出文本格式的文件?如果可以,使用的类是什么? 答:可以。 public class URLReader { public static void main(String[] args) { try{ URL tirc=new URL(\ BufferedReader in= new BufferedReader(new InputStreamReader(tirc.openStream())); String s; while((s=in.readLine())!=null) System.out.println(s); in.close(); }catch(MalformedURLException e){ System.out.println(e); } catch(IOException e){ System.out.println(e); } } } 2.编写Applet,访问并显示或播放指定URL地址处的图像和声音资源。 答案略 3.编写程序,程序的界面如图11-8所示,单击获取按钮,在下面的文本框中将显示本机的IP地址。 图11-8 参考代码如下: import java.awt.*; import java.awt.event.*; import java.net.*; public class getIpAddress extends Frame implements ActionListener{ Button button1 = new Button(); Label label1 = new Label(); TextField textField1 = new TextField(); public getIpAddress(){ this.setResizable(true); this.setSize(new Dimension(281, 168)); this.setTitle(\得到本机IP地址\ button1.setLabel(\获取\ button1.addActionListener(this); label1.setFont(new java.awt.Font(\ label1.setText(\本机的IP地址是:\ textField1.setColumns(15); textField1.setEditable(false); textField1.setFont(new java.awt.Font(\ this.setLayout(new FlowLayout()); add(button1); add(label1); add(textField1); } public void actionPerformed(ActionEvent e){ try{ InetAddress localHost = InetAddress.getLocalHost(); String ipAdd = localHost.getHostAddress(); textField1.setText(ipAdd); }catch(Exception ex){ textField1.setText(\ } } public static void main(String[] args) { getIpAddress frm=new getIpAddress(); frm.setVisible(true); } } 4.采用套接字的连接方式编写一个程序,允许客户向服务器提出一个文件的名字。如果文件存在就把文件的内容发送回客户,否则指出文件不存在。 假设文本文件score.txt的文件内容如下: VB Java C++ 90 87 70 91 84 88 92 81 90 服务器端的运行结果如图11-9所示。 图11-9 客户端的运行结果如图11-10所示。 图11-10 程序参考代码如下: ? 服务器端程序 import java.net.*; import java.io.*; public class SocketServer { public static final int port=8000; public static void main(String[] args) { String str; try{ ServerSocket server=new ServerSocket(port); System.out.println(\ Socket socket=server.accept(); System.out.println(\ InputStream fln=socket.getInputStream(); OutputStream fOut=socket.getOutputStream(); InputStreamReader isr=new InputStreamReader(fln); BufferedReader in=new BufferedReader(isr); PrintStream out=new PrintStream(fOut); File sourceFile; BufferedReader source; System.out.println(\等待客户端的消息...\ str=in.readLine(); System.out.println(\客户端:\ sourceFile=new File(str); System.out.println(\等待客户发送:\ try{ source=new BufferedReader(new FileReader(sourceFile)); while((str=source.readLine())!=null) {out.println(str);} out.println(\ }catch(FileNotFoundException e) { System.out.println(\文件不存在:\ out.println(\ } socket.close(); server.close(); }catch(Exception e){ System.out.println(\异常:\ } } } ? 客户端程序 import java.net.*; import java.io.*; public class ServerClient { public static void main(String[] args) { String str; try{ InetAddress addr=InetAddress.getByName(\ Socket socket=new Socket(addr,8000); System.out.println(\ InputStream fIn=socket.getInputStream(); OutputStream fOut=socket.getOutputStream(); InputStreamReader isr=new InputStreamReader(fIn); BufferedReader in=new BufferedReader(isr); PrintStream out=new PrintStream(fOut); InputStreamReader userisr=new InputStreamReader(System.in); BufferedReader userin=new BufferedReader(userisr); System.out.print(\发送字符串:\ str=userin.readLine(); out.println(str); System.out.println(\等待获取服务器字符串\ if(str.equalsIgnoreCase(\ { System.out.println(str); throw new FileNotFoundException(\文件不存在异常!\ } while(true){ str=in.readLine(); if(str.equals(\ System.out.println(str); } socket.close(); } catch(Exception e){ System.out.println(\异常:\ } } }