该浏览器可以实现网页访问、保存,以及操作的前进、后退等功能。理论基础部分详细地介绍事件处理、Swing相关组件和输入输出的相关知识。具体要求如下:
1.通过在地址栏中输入URL地址,可以访问相应的网页。
2.另存为:可以保存正在访问的页面。
3.前进:访问当前页面的上一个页面。
4.后退:访问当前页面的下一个页面。
5.查看源文件:查看访问页面的HTML源文件,并且提供保存功能。
各种事件的名称和描述。事件可以分为两种类型:低级事件和语义事件。
低级事件:视窗操作系统发生的事件,或者是低级的输入事件,如鼠标和键盘事件。这些事件的事件类包括ComponentEvent、FocusEvent、InputEvent、KeyEvent、MouseEvent、ContainerEvent、WindowEvent等。
语义事件:包括接口组件产生的用户定义信息,如用户单击按钮,或者在文
本框中输入文字后按Enter键等。这些事件的事件类包括ActionEvent、AdjustmentEvent、ItemEvent、TextEvent等。
事件监听器是一个类的实例,该类实现了一个特殊的接口,称为Listener Interface。每类事件都至少需要一个事件监听类。当事件源产生了一个事件以后,监听器对象根据事件对象内封装的信息,决定如何响应这个事件。 在这里,我们需要指出的是,在列举的监听器中,只有6种是所有Swing组件都支持的,分别是ComponentListener、FocusListener、KeyListener、MouseListener、MouseMotionListener以及MouseWheelListener。
大部分监听器接口包含多个方法。通常,一个监听器类都会实现一个接口,但是只能处理一件事情,也就是说仅仅关注其中的一种方法。而根据Java的语法要求,类必须实现接口的所有方法,于是除了被使用的方法外,其他的方法都是空的。这样就造成了代码的复杂性大大增加,同时降低了可读性。
为了避免这种事情的发生,Java提供了适配器类。适配器类实现了事件监听器接口中的所有方法,但这些方法都是空方法。我们的监听器类只需要继承相应的适配器类,并且重写相应的方法就可以了,其他的方法则不需要考虑了。
Java 1.0的出现带来了抽象窗口工具箱(AWT)。但是,AWT是针对不同的操作系统编写的,所以,对于AWT而言,“一次编写,随处运行”很难彻底实现。
在Java 1.2中,Sun公司推出了新的用户界面库:Swing。相对于AWT来说,Swing的功能更强大,使用更方便。更重要的是,Swing中的类完全是用Java编写的。也就是说,在任何平台之上,其运行结果都是一样的,真正地实现了Sun公司提出的口号“一次编写,随处运行”。
与其他类相似,Swing类也被打成了不同的包。列举了Swing包的概况。
包含Swing组件的程序必须包含一个顶级容器,但Swing组件不可以直接加入到顶级容器中。而JFrame是顶级容器,通常把Swing组件加入到JFrame。
可以看出,JFrame类是由Frame类扩展而来的,因此Frame类的绝大部分方法都可以被JFrame调用,但是二者也存在着一定的差异。与其他的JFC/Swing顶级容器一样,根窗格是JFrame唯一的组件,内容窗格则用来负责JFrame其他组件的显示。
比如,在Frame中,我们可以通过add方法来添加一个组件:
frameName.add(child);
但是,对于JFrame而言,如果我们要添加一个组件,就需要将该组件添加至JFrame的内容面板:
jFrameName.getContentPane( ).add(child);
以Word为例,每当我们要建立一个新的文件时,需要从菜单栏中选择”文件”→”新建”命令。这里我们所说的”文件”就是菜单组,”新建”就是菜单项。
菜单栏(JMenuBar):菜单栏JMenuBar组件是用来摆放JMenu组件的容器。通过JMenuBar组件,可以将建立完成的JMenu组件添加到窗口中。JMenuBar只有一种构造函数,其具体形式如下:
JMenuBar();//建立一个新的JMenuBar;
构造一个空的JMenuBar之后,需要将它放置在框架的顶端,可以通过框架所提供的setJMenuBar()方法来完成这项任务。具体的执行语句如下:
JFrame myframe = new JFrame("框架");
JMenuBar mymenubar = new JMenuBar( );
myframe.setJMenuBar(mymenubar);
此时,我们所建立的菜单栏就呈现在框架之上了,但是其中没有任何内容。在下面的部分中,将为大家介绍如何添加菜单组。
菜单组(JMenu):JMenu组件是用来存放菜单项的组件。单击菜单组,其所包含的菜单项就会显示出来。
菜单组的构造函数包括以下几种。
JMenu(String s, Boolean b):建立一个具有名称的JMenu对象,并确定这个菜单组的下拉式属性。
菜单项(JMenuItem):菜单项是包含具体操作的项,因此需要为执行操作的菜单项建立ActionListener监听器,监听用户的操作。
菜单项的构造函数包括以下几种。
JLable是不可编辑的显示区域,可以容纳文字、图像等。标签的使用简单方便,应用广泛。
Lable的构造函数包括以下几种。
按钮(JButton)的继承关系。
JButton共有4个构造函数。
要是想将JButton内的文字或图像设置为水平排列方式,可以利用AbstractButton抽象类所提供的setHorizontalAlignment()方法来实现。
通常情况下,在图形界面上放置按钮,最终目的就是想让用户通过单击按钮,产生事件,执行必要的操作。这样的话,我们需要为每个按钮添加一个ActionListener动作监听类,以便监听和执行相应的鼠标单击事件。
文本框(JTextField)是最常用的文本组件。JTextField类可以编辑单行文本,其构造函数如下。
在特定环境下,消息框可以生成对话框,即创建简洁的专用对话框。比如我们在建立一个新的文本文件,退出之前如果没有保存的话,系统将会弹出一个对话框,提示我们是否保存。其实这种类型的对话框就是消息框的一种。
OptionPane的构造函数包括以下几种。
使用JOptionPane对象所得到的对话框的操作模式是modal属性为true的形式,也就是说必须先关闭对话框才能回到产生对话框的窗口。要利用JOptionPane类来输出对话框,通常我们不会新建一个JOptionPane对象,而是使用JOptionPane所提供的一些静态方法,不用产生JOptionPane对象就可以直接使用,这些方法都是以showXxxxxDialog的形式出现的。若对话框是出现在InternalFrame上,可以用showInternalXxxxxDialog的各种方法产生对话框。下面介绍JOptionPane提供输出对话框的所有静态方法。
显示消息对话框(Message Dialog)的具体方法如下。
显示消息对话框中只含有一个按钮,通常是“确定”按钮,例如在程序出现错误时,会弹出一个消息对话框予以提示。
showMessageDialog(Component parentComponent, Object message)
showMessageDialog(Component parentComponent, Object message, String
title, int messageType)
showMessageDialog(Component parentComponent, Object message, String
title, int messageType, Icon icon)
这些静态方法中各参数的含义分别如下。
显示确认对话框(Confirm Dialog)的具体方法如下。
确认对话框通常会询问用户一个问题,然后由用户回答“是”或“不是”,用户选择的结果将通过不同的返回值来体现。例如当我们在编辑文档后没有保存便退出时,系统往往会弹出该类对话框,以确认是否保存。
showConfirmDialog(Component parentComponent, Object message)
showConfirmDialog(Component parentComponent, Object message, String
title, int optionType)
showConfirmDialog(Component parentComponent, Object message, String
title, int optionType, int messageType)
showConfirmDialog(Component parentComponent, Object message, String
title, int optionType, int messageType, Icon icon)
这些静态方法中各参数的含义分别如下。
InputStream是一个定义了Java流式字节输入模式的抽象类,同时也是基本的输入类。该类的所有方法在出错条件下将引发一个IOException 异常。表4.5显示了InputStream所定义的方法。
read()方法没有带参数,是由于该方法被重载,提供了3种从流读取数据的方法。
int read():如果下一个字节可读则返回一个整型,遇到文件尾时返回-1。
int read(byte buffer[]):试图读取buffer.length个字节到buffer中,并返回实际成功读取的字节数。遇到文件尾时返回-1。
int read(byte buffer[], int offset, int numBytes):试图读取buffer中从buffer[offset]开始的numBytes个字节,返回实际读取的字节数。遇到文件尾时返回-1。
OutputStream是定义了流式字节输出模式的抽象类,同时也是基本的输出类。该类的所有方法都返回一个void 值,并且在出错情况下将引发一个IOException异常。表4.6列出了OutputStream类的方法。
write()方法没有带参数,是由于该方法也被重载并提供3种向流写入数据的方法。
void write(int b):向输出流写入单个字节。注意参数是一个整型数,不必把参数转换成字节型就可以调用write()。
void write(byte buffer[]):向一个输出流写入一个完整的字节数组。
void write(byte buffer[], int offset, int numBytes):把以buffer[offset]为起点的numBytes个字节区域内容写入到流中。
字符流的输入输出类。
Reader是定义Java的流式字符输入模式的抽象类。该类的所有方法在出错情况下都将引发IOException 异常。Reader类的方法。
read()方法总共有3种被重载的方法,分别如下。
abstract int read(char buffer[], int offset, int numChars):试图读取buffer中从buffer[offset]开始的numChars个字符,返回实际成功读取的字符数。遇到文件尾时返回-1
Writer 是定义流式字符输出的抽象类。所有该类的方法都返回一个void 值并在出错条件下引发IOException 异常。列出了Writer类的方法。
write()方法总共有5种被重载的方法,分别如下。
FileReader继承自Reader类,与FileInputStream类似,其作用是读取文件内
容。它最常用的
构造函数如下:
FileReader(String filePath)
FileReader(File fileObj)
每个构造函数都能引发一个FileNotFoundException异常。
FileWriter继承自Writer类,其作用是创建写文件。它最常用的构造函数如下:
FileWriter(String filePath)
FileWriter(String filePath, boolean append)
FileWriter(File fileObj)
在Java 2以前,控制台输入是通过字节流完成的。尽管运用字节流读取控制台输入在技术上仍是可行的,但这种方法现在已经不推荐使用。在Java 2中读取控制台输入的首选方法是字符流。
在Java中,控制台输入由从System.in中读取数据来完成。为获得属于控制台的字符流,需要在BufferedReader对象中包装System.in。BufferedReader 支持缓冲输入流,可以将文本写到字符输出流,并且可以通过缓冲来有效地提高输入性能。它最常见的构造函数如下:
BufferedReader(Reader inputReader)
里,inputReader是链接被创建的BufferedReader实例的流。前面已经讲过,Reader是一个抽象类,它的一个具体的子类是InputStreamReader,该子类把字节转换成字符。为获得System.in中的一个InputStreamReader对象,可以用下面的构造函数:
InputStreamReader(InputStream inputStream)
因为System.in引用了InputStream 类型的对象,它可以用于inputStream。综上所述,可以用下面的代码创建与键盘相连的BufferedReader对象。
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
上述语句执行后,br是通过System.in生成的链接控制台的字符流。
控制台输出最为简单的方式是用前面讲过的print()和println()方法来完成的。这两种方法由PrintStream(System.out引用的对象类型)定义。System.out是一个字节流,我们完全可以用它实现简单程序的输出。
PrintStream继承自OutputStream的输出流,它同样可以实现低级方法write(),write()可用来向控制台写数据。PrintStream 定义的write()方法的最简单形式如下:
void write(int bytevalue)
该方法按照bytevalue指定的数值向文件写字节。尽管bytevalue 定义成整数,但只有低位的8个字节被写入。
网页浏览器的程序由WebBrowser.java和ViewSourceFrame.java两个文件组成。
此文件包含名为WebBrowser的public类,其主要功能为生成网页浏览器的主体框架,实现框架上各个组件的事件侦听。WebBrowser.java主要包括4个模块:图形用户界面的构建、组件监听接口的实现、文件保存功能的实现、查看源代码框架的生成。
此文件包含名为ViewSourceFrame的类,其主要功能是实现了源文件查看的主体框架,并实现了源文件的保存功能。ViewSourceFrame.java主要包括两个模块:图形用户界面的构建和组件监听接口的实现。
实现监听器接口的hyperlinkUpdate函数
程序的运行情况。
要发布这个应用程序,需要将该应用程序打包。使用jar.exe,可以把应用程序中涉及的类和图片压缩成一个jar文件,这样便可以发布程序。
首先编写一个清单文件,名为MANIFEST.MF,代码如下:
Manifest-Version: 1.0
Created-By: 1.6.0 (Sun Microsystems Inc.)
Main-Class: WebBrowser
此清单文件保存到C:\Javawork\CH04目录下。
然后,使用如下命令生成jar文件:
jar cfm WebBrowser.jar MANIFEST.MF *.class
其中,参数c表示要生成一个新的jar文件;f表示要生成的jar文件的名字;m表示清单文件的名字。
如果安装过WinRAR解压软件,并将.jar文件与该解压缩软件做了关联,那么WebBrowser.jar文件的类型是WinRAR,使得Java程序无法运行。因此,在发布软件时,还应该再写一个有如下内容的bat文件(WebBrowser.bat):
javaw -jar WebBrowser.jar
可以通过双击WebBrowser.bat来运行程序。