22功能流图形化界面.docx
《22功能流图形化界面.docx》由会员分享,可在线阅读,更多相关《22功能流图形化界面.docx(29页珍藏版)》请在冰豆网上搜索。
22功能流图形化界面
功能流、图形化界面
1.功能流
1.1.功能流介绍
前面学习的都是最基本的IO流对象,字节流和字符流。
它们的操作规律基本是一致。
读取数据使用read方法,写数据write方法。
功能流:
在IO流体系中,还有其他的流对象,这些流对象都是基于字节或者字符流而存在一些IO流,它们在字节或者字符流的基础上增强了特定的功能。
当在开发中如果需要这些特定的功能,才能使用这些功能流,如果不需要这些特定功能,但还需要读写数据,那么我们依然使用前面学习的字节或者字符流操作。
学习功能流:
记住每个功能流是完成什么功能即可。
1.2.Properties介绍
Properties:
它本身属于Map集合体系中一员。
但是它有可以和IO流结合使用。
Propertis类本身中存放的key和value这样具有一定对应关系的数据,当和IO流结合在一起的时候,可以直接将集合中的数据存储在指定的文件中,或者从文件加载数据,当数据加载完成之后,数据就已经被存放在集合中。
Properties类表示了一个持久的属性集。
Properties可保存在流中或从流中加载。
属性列表中每个键及其对应值都是一个字符串。
1.2.1.Properties写数据
/*
*演示将Properties集合中的数据使用IO流写到文件中
*store(OutputStreamout,Stringcomments)
*/
publicstaticvoidwrite()throwsIOException{
//创建Properties集合对象
Propertiesprop=newProperties();
//给集合中保存数据
prop.put("zhangsan","beijing");
prop.put("lisi","shanghai");
prop.put("wangwu","wuhan");
prop.put("zhaoliu","guangzhou");
//将集合中的数据保存到文件中
prop.store(newFileOutputStream("d:
/prop.properties"),"buzhidaoxiesha");
}
使用Properties和IO流结合将集合中的数据保存到文件中:
在实际开发中,我们将有对应关系的数据通过io流保存到文件中之后,在文件中得到了key=value这样的数据。
这类文件在开发中被称为配置文件。
配置文件:
这个文件主要存在的价值是配置软件启动或者运行过程中需要的一些参数信息的。
key=value。
在程序中我们可以通过这key得到对应的value值,进而就可以通过这个value决定软件应该如何运行以及程序应该怎么去处理接下来的问题。
例如:
QQ软件:
第一次登陆QQ之后,如果选择了记住密码,下次再登陆QQ的时候,就直接显示账号和密码。
而不用填写。
肯定在第一次运行QQ的过程中,将账号和密码保存到文件中。
QQ=123456
pwd=abc123
在配置文件中的以#开始的数据,称为配置文件中的注释数据,它不属于配置文件中的有效数据。
在使用Properties类和IO结合将map中的数据保存到文件中,如果map中有中文,所有的中文都会被编码。
编码的过程使用的不是本地默认的GBK编码表,而是使用的JDK中自带的unicode编码表对中文件进行的编码:
在JDK中有一个命令专门负责中文字符的编码:
1.2.2.Properties读取数据
/*
*演示Properties读取文件中的数据
*/
publicstaticvoidread()throwsIOException{
//创建Properties对象,用于存放IO流读取到的数据
Propertiesprop=newProperties();
/*
*加载数据
*当Properties中的load方法执行完成之后,
*数据就已经被加载到Properties集合中
*/
prop.load(newFileInputStream("d:
/prop.properties"));
//正常操作集合
Set
for(Iteratorit=set.iterator();it.hasNext();){
Objectkey=it.next();
Objectvalue=prop.get(key);
System.out.println(key+"...."+value);
}
}
1.3.SequenceInputStream介绍
SequenceInputStream表示其他输入流的逻辑串联。
它从输入流的有序集合开始,并从第一个输入流开始读取,直到到达文件末尾,接着从第二个输入流读取,依次类推,直到到达包含的最后一个输入流的文件末尾为止。
SequenceInputStream它属于字节输入流。
它的主要功能是将多个输入流合并成一个输入流。
输入流按照先后次序进行逻辑串联。
需求:
需要将三个文件中的数据合并到第四个文件中。
/*
*演示SequenceInputStream将多个输入流合并成一个输入流
*/
publicclassSequenceInputStreamDemo{
publicstaticvoidmain(String[]args)throwsIOException{
//创建List集合
Listlist=newArrayList();
for(inti=1;i<=3;i++){
FileInputStreamfis=newFileInputStream("d:
/"+i+".txt");
//将流添加到list集合中
list.add(fis);
}
//使用Collections工具类,获取到Enumeration对象
Enumerationen=Collections.enumeration(list);
//创建序列输入流
SequenceInputStreamsis=newSequenceInputStream(en);
//创建输出流
FileOutputStreamfos=newFileOutputStream("d:
/4.txt");
//模版代码读写数据
byte[]buf=newbyte[1024];
intlen=0;
while((len=sis.read(buf))!
=-1){
fos.write(buf,0,len);
}
//关流
sis.close();
fos.close();
}
}
1.4.序列化和反序列化流
序列化和反序列化:
这两个流对象可以将Java中new出来的对象直接保存到文件中。
或者将保存在文件中的对象读取到程序中。
例如:
PersonP=newPerson(“张三”,“男”,23);
序列化:
将对象保存到文件中
反序列化:
将文件中的对象读取到程序中。
1.4.1.序列化
ObjectOutputStream将Java对象的基本数据类型和图形写入OutputStream。
可以使用ObjectInputStream读取(重构)对象。
通过在流中使用文件可以实现对象的持久存储。
如果流是网络套接字流,则可以在另一台主机上或另一个进程中重构对象。
ObjectOutputStream:
它可以将Java中创建出的对象(在堆内存中),直接写到文件中。
ObjectOutputStream:
它可以将堆中的对象中的所有数据进行编码,转成二进制数据,但是它不能将这些二进制数据写到文件中,因此创建对象的时候,需要给其传递一个可以和底层文件交互的流对象。
/*
*序列化流对象ObjectOutputStream
*
*/
publicclassObjectOutputStreamDemo{
publicstaticvoidmain(String[]args)throwsIOException{
//创建需要被序列化的流对象
Personp=newPerson("张三",23);
//创建用于将对象持久保存的序列化流对象
ObjectOutputStreamoos=newObjectOutputStream(
newFileOutputStream("d:
/obj.obj"));
//调用写的方法
oos.writeObject(p);
//关流
oos.close();
}
}
上述的程序需要将Person对象持久的保存到文件中。
但是运行的时候发生了异常。
在Java中当需要将一个对象持久的保存(文件、网络),Java中规定这个对象所属的类必须实现序列化接口,只要对象没有实现序列化接口在运行的时候都会发生没有实现序列化异常java.io.NotSerializableException。
异常的解决方案:
让Person类实现序列化接口。
Java中定义了Serializable接口,它规定只有实现了这个接口的类的对象才能使用ObjectOutputStream实现对象的持久保存。
在Java中有部分接口中并没有任何的方法需要实现,这些接口的存在的意义仅仅是为了进行某些特定功能的限定或者是为了声明某些需要JVM检测的功能。
这类接口被称为标记型接口。
1.4.2.反序列化
ObjectInputStream对以前使用ObjectOutputStream写入的基本数据和对象进行反序列化。
创建ObjectInputStream对象的时候需要传递一个可以从底层读取字节的输入流,传递的字节输入流是从文件中将所有的字节读取到程序中,ObjectInputStream它是将读取到的字节数据重新解码成对应的Java对象。
/*
*演示反序列化ObjectInputStream
*/
publicclassObjectInputStreamDemo{
publicstaticvoidmain(String[]args)throwsIOException,ClassNotFoundException{
//创建反序列化流对象
ObjectInputStreamois=newObjectInputStream(
newFileInputStream("d:
/obj.obj"));
//读取对象
Objectobj=ois.readObject();
//Personp=(Person)obj;
System.out.println(obj);
}
}
反序列读取多个对象的模版代码:
/*
*演示反序列化ObjectInputStream
*/
publicclassObjectInputStreamDemo{
publicstaticvoidmain(String[]args)throwsIOException,ClassNotFoundException{
//创建反序列化流对象
ObjectInputStreamois=newObjectInputStream(
newFileInputStream("d:
/obj.obj"));
try{
//反序列化读取多个对象时的模版代码
Objectobj=null;
while((obj=ois.readObject())!
=null){
System.out.println(obj);
}
}catch(EOFExceptione){
System.out.println("数据读取完成");
}
ois.close();
}
}
1.4.3.序列化和反序列化的细节
1、当序列化的对象在被反序列化的时候,也需要依赖本地对应的class文件,如果本地的class文件和序列化时使用的不是同一个,在反序列化过程中会发生异常。
发生上述异常的原因是:
我们在序列化的时候创建的Person对象依赖的class文件是原始的。
而在序列化结束之后Person的class文件被人为修改过。
导致在反序列化的时候本地的Person.class文件和序列化时的不一致。
而反序列化数据的时候,需要使用一个称为版本号的数字来验证码当前的class文件和序列化时使用的是否一致。
如果不一致上就发生上述的异常。
上述异常的解决方案:
需要在被序列化的类添加版本号。
2、类中的静态成员变量在序列化的时候不会被序列化。
序列化,仅仅是将对象在堆中的所有数据持久保存起来。
而静态成员在方法区中。
3、瞬态关键字。
如果对象中某些成员变量在序列化的时候,不需要被序列化,这时可以使用瞬态关键字修饰这个成员变量。
这样的成员变量只能保存在内存中。
序列化和反序列化结论:
1、被序列化的对象所属的类必须实现序列化接口
2、被序列化的类中必须添加一个版本号。
1.5.打印流
打印流属于输出流,主要功能是将内存中的数据打印到不同的平台上。
例如:
可以将数据打印到文件中,控制台中,网络中,或者其他的可以打印的设备等。
1.5.1.PrintStream
PrintStream为其他输出流添加了功能,使它们能够方便地打印各种数据值表示形式。
它还提供其他两项功能。
与其他输出流不同,PrintStream永远不会抛出IOException;而是,异常情况仅设置可通过checkError方法测试的内部标志。
另外,为了自动刷新,可以创建一个PrintStream;这意味着可在写入byte数组之后自动调用flush方法,可调用其中一个println方法,或写入一个换行符或字节('\n')。
PrintStream:
它主要是将数据打印(写)到不同的设备上。
如果我们希望调用PrintStream的时候,可以完成自动刷新功能,这时一定要使用的是它的接收OutputStream的这个构造方法。
并且只有在调用其中的println方法时才能刷新。
/*
*PrintStream演示
*/
publicclassPrintStreamDemo{
publicstaticvoidmain(String[]args){
//输出语句
System.out.write(353);//只能输出最低位的一个字节数据
PrintStreamps=System.out;
ps.println("你好");
}
}
1.5.2.PrintWriter
向文本输出流打印对象的格式化表示形式。
此类实现在PrintStream中的所有print方法。
它不包含用于写入原始字节的方法,对于这些字节,程序应该使用未编码的字节流进行写入。
与PrintStream类不同,如果启用了自动刷新,则只有在调用println、printf或format的其中一个方法时才可能完成此操作,而不是每当正好输出换行符时才完成。
这些方法使用平台自有的行分隔符概念,而不是换行符。
/*
*演示PrintWriter。
*/
publicclassPrintWriterDemo{
publicstaticvoidmain(String[]args)throwsIOException{
method2();
}
/*
*演示PrintWriter自己的刷新功能
*PrintWriter启动的了自动刷新,只有在调用println、printf、format方法时才能刷新
*调用其他的方法,即使有刷新也不刷新。
*/
publicstaticvoidmethod2()throwsIOException{
//创建对象
PrintWriterpw=newPrintWriter(newFileWriter("d:
/pw2.txt"),true);
pw.write("aaaaa");
pw.write("bbbbb");
pw.write("ccccc");
pw.write("ddddd");
pw.flush();
pw.close();
}
publicstaticvoidmethod()throwsFileNotFoundException{
//创建对象
PrintWriterpw=newPrintWriter("d:
/pw.txt");
pw.println("aaaaa");
pw.println("bbbbb");
pw.println("ccccc");
pw.println("ddddd");
pw.close();
}
}
1.6.随机访问流
此类的实例支持对随机访问文件的读取和写入。
随机访问文件的行为类似存储在文件系统中的一个大型byte数组。
存在指向该隐含数组的光标或索引,称为文件指针;输入操作从文件指针开始读取字节,并随着对字节的读取而前移此文件指针。
如果随机访问文件以读取/写入模式创建,则输出操作也可用;输出操作从文件指针开始写入字节,并随着对字节的写入而前移此文件指针。
写入隐含数组的当前末尾之后的输出操作导致该数组扩展。
该文件指针可以通过getFilePointer方法读取,并通过seek方法设置。
RandomAccessFile:
它支持随机访问文件中某个位置上的数据。
并且它可以完成读和写操作。
/*
*随机访问文件的流对象RandomAccessFile
*/
publicclassRandomAccessFileDemo{
publicstaticvoidmain(String[]args)throwsIOException{
method();
}
//读取数据
publicstaticvoidmethod2()throwsIOException{
//创建对象
RandomAccessFileraf=newRandomAccessFile("d:
/raf.txt","r");
//随机去读文件中的数据
//Randomr=newRandom();
raf.seek
(2);
System.out.println(raf.read());
raf.close();
}
//写数据
publicstaticvoidmethod()throwsIOException{
//创建对象
RandomAccessFileraf=newRandomAccessFile("d:
/raf.txt","rw");
raf.seek
(2);
raf.write("ab".getBytes());
raf.close();
}
}
2.图形化界面
2.1.图形化界面介绍
软件的运行方式分成两类:
1、命令行方式:
它需要记忆具体的命令,不利于普及,并且不利于操作。
2、图形化界面方式:
它是通过界面来操作对应的命令,用户不需要记忆任何命令,就可以完成相应的操作,方便简单易用。
GUI
GraphicalUserInterface(图形用户接口)。
用图形的方式,来显示计算机操作的界面,这样更方便更直观。
CLI
CommandlineUserInterface(命令行用户接口)
就是常见的Dos命令行操作。
需要记忆一些常用的命令,操作不直观。
Java中也提供可以制作界面的类和接口:
早期Java中提供的制作界面的所有类和接口都保存在awt包下。
awt包下的创建界面的类和接口,它们本身是不能创建界面。
而是将不同操作系统内部创建界面的命令封
装到对应的类和接口中,Java程序员使用awt包下的类和接口创建界面的时候其实是通过Java程序调用操
作系统创建界面的程序。
awt创建界面的程序严重依赖操作系统,导致不同的操作系统创建的界面外观不一致。
Java针对AWT包下的大部分和创建界面相关的类进行了升级。
后期升级后的所有类和接口保存在swing包
下。
后期使用Java开发图形界面,都使用swing包下的类和接口。
swing包下的类和接口,它们创建的界面,不再依赖操作系统,任何操作系统下界面一致。
IBM公司,在java的swing基础上设计出新的一套图形界面类和接口,名称swt。
Java的图形化界面已经开发中被废弃。
后期就业班学习的JavaEE技术,基本不用图形化界面中的任何东西。
2.2.Java中图形界面相关类
2.3.图形界面演示
/*
*使用swing包下的类创建窗口
*/
publicclassMyWindow3{
publicstaticvoidmain(String[]args){
JFrame.setDefaultLookAndFeelDecorated(true);
JFramef=newJFrame("我的窗口");
//设置窗口的大小和位置
f.setBounds(300,150,400,200);
//设置背景颜色
//f.setBackground(Color.YELLOW);
//给界面上添加一个按钮
JButtonbtn=newJButton("确定");
JButtonbtn2=newJButton("取消");
//将按钮添加到界面上
f.add(btn);
f.add(btn2);
//设置窗口可见
f.setVisible(true);
}
}
上面的界面发现确定按钮并看不到。
这时因为Jframe它有自己默认的组件布局方式,导致取消的按钮将确定的按钮覆盖掉。
2.4.布局管理器
容