这几天,我自学了一点Java Swing界面,用Java Swing界面写出了文件操作管理器。这方面的东西并不是很难,没有使用IO流那样复杂,主要是要记的东西比较多,下面是代码和我的想法以及收获。
题目:
源代码:
Test类:
package ZLTPWORK;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.io.IOException;
import javax.swing.*;
public class Test {
//定义一个String类型的字符串来记录要输入进文件的内容
static String str="";
public static void main(String[] args) throws IOException {
//实例化FileOperation类
FileOperation fo = new FileOperation();
//创建一个JFrame窗体
JFrame j =new JFrame("文件操作管理器");
//设置窗体的坐标和大小
j.setBounds(350,150,650,450);
//设置窗体的关闭规则,关闭窗口时关闭程序
j.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//创建一个容器
Container c = j.getContentPane();
//使该容器采用绝对布局
c.setLayout(null);
//标签1:
JLabel l=new JLabel("请输入您要输入进文件的字符串:");
l.setFont(new Font("黑体",Font.BOLD,15));
//标签2:
JLabel console =new JLabel();
console.setFont(new Font("黑体",Font.BOLD,15));
//文本域1:
JTextArea area1 = new JTextArea();
area1.setText("");
area1.setRows(7);
area1.setColumns(7);
area1.setFont(new Font("黑体",Font.PLAIN,20));
//激活自动换行功能
area1.setLineWrap(true);
//激活断行不断字功能
area1.setWrapStyleWord(true);
//标签3:(提醒用户在文本域1输入字符串)
JLabel A =new JLabel();
area1.addFocusListener(new FocusListener(){
@Override
public void focusGained(FocusEvent e) {
// TODO Auto-generated method stub
A.setText("");
}
@Override
public void focusLost(FocusEvent e) {
// TODO Auto-generated method stub
A.setText("请在这里输入");
A.setForeground(Color.red);
}
});
//标签4:
JLabel B=new JLabel("您已经输入进文件的字符串为:");
B.setFont(new Font("黑体",Font.BOLD,15));
//文本域2:
JTextArea area2 = new JTextArea();
area2.setText("");
area2.setRows(10);
area2.setColumns(10);
area2.setFont(new Font("黑体",Font.PLAIN,20));
//激活自动换行功能
area2.setLineWrap(true);
//激活断行不断字功能
area2.setWrapStyleWord(true);
//标签5:
JLabel C=new JLabel("文件的保存地址为:");
C.setFont(new Font("黑体",Font.BOLD,15));
//文本框1:
JTextField jt = new JTextField(fo.file.getAbsolutePath());
jt.setColumns(45);
//按钮2:
JButton b =new JButton("重选保存地址");
b.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//调用文件操作类中的Chadd()方法
fo.Chadd();
//把新的保存地址写到文字框1中
jt.setText(fo.file.getAbsolutePath());
}
});
//按钮1:
JButton btn =new JButton("写入文件");
btn.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//获取文本框中的文本值
str=area1.getText();
System.out.println("您刚刚输入进文件的内容为:\n"+str);
//清空文本框中的内容
area1.setText("");
//获取焦点,获取光标
area1.requestFocus();
try {
if(fo.writeMsg(str)) {
console.setText("字符串已写入文件");
area2.setText(fo.readMsg());
}
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
});
//按钮3:
JButton bt =new JButton("删除文件");
bt.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JFrame f =new JFrame("是否删除");
//设置窗体的坐标和大小
f.setBounds(550,330,250,150);
//设置窗体的关闭规则,关闭窗口时关闭程序
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//添加容器a
Container a = f.getContentPane();
//容器a采用绝对布局
a.setLayout(null);
//设置窗口为可见
f.setVisible(true);
//标签6:
JLabel p=new JLabel("是否删除文件");
p.setFont(new Font("黑体",Font.BOLD,15));
p.setBounds(70, 10, 150, 50);
//按钮4:
JButton b1 =new JButton("是");
b1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//删除文件
fo.deletefile();
//清空文本域2的字符串
area2.setText("");
//将窗口关闭
f.setVisible(false);
}
});
b1.setBounds(35, 50, 50, 30);
//按钮5:
JButton b2 =new JButton("否");
b2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//按否则将窗口关闭
f.setVisible(false);
}
});
b2.setBounds(145, 50, 50, 30);
//添加组件到容器a中
a.add(b1);
a.add(b2);
a.add(p);
}
});
//添加组件到容器c中
c.add(l);
c.add(area1);
c.add(A);
c.add(B);
c.add(btn);
c.add(console);
c.add(B);
c.add(area2);
c.add(C);
c.add(b);
c.add(jt);
c.add(bt);
//设置每个组件的具体位置:
//标签1:
l.setBounds(20, 20, 300, 35);
//文本域1:
area1.setBounds(20, 70, 170, 200);
//标签2:
console.setBounds(195, 230, 180, 40);
//标签3:
A.setBounds(195, 80, 150, 40);
//按钮1:
btn.setBounds(200, 200, 100, 30);
//标签4:
B.setBounds(350, 20, 300, 35);
//文本域2:
area2.setBounds(350, 70, 200, 200);
//标签5:
C.setBounds(20, 300, 150, 20);
//按钮2:
b.setBounds(170, 290, 120, 30);
//文本框1:
jt.setBounds(20, 330, 450, 20);
//按钮3:
bt.setBounds(500, 310, 90, 35);
//设置窗口为可见
j.setVisible(true);
}
}
FileOperation类:
package ZLTPWORK;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import javax.swing.JFileChooser;
public class FileOperation {
//为该类设置一个File类型的属性file
File file;
//文件操作类构造函数(保证在编译开始是就让用户选择保存地址)
FileOperation() throws IOException{
String st ="";
JFileChooser jf = new JFileChooser();
jf.setFileSelectionMode(JFileChooser.SAVE_DIALOG);
jf.showDialog(null, "选择保存地址");
file = jf.getSelectedFile();
st=file.getAbsolutePath();
st = st+ "\\user.db.txt";
//在构造函数中对属性file进行初始化
file = new File(st);
}
//重选地址方法:
public void Chadd() {
String s ="";
JFileChooser j = new JFileChooser();
j.setFileSelectionMode(JFileChooser.SAVE_DIALOG);
j.showDialog(null, "重新选择保存地址");
file = j.getSelectedFile();
s=file.getAbsolutePath();
s = s+ "\\user.db.txt";
file = new File(s);
}
//该方法是为了实现将Test类传过来的字符串msg写入文件file中
public boolean writeMsg(String msg) throws IOException {
//创建文件输出流对象writer
FileWriter writer;
try {
//将writer对象进行初始化,true要求不覆盖之前写入文件的内容
writer = new FileWriter(file,true);
//往file文件里写字符串msg的内容
writer.write(msg);
//刷新输出流并强制任何缓存输入字符被写出
writer.flush();
//关闭输出流并释放系统资源
writer.close();
//程序能走到这里说明对文件正常写入,返回一个true告诉Test类已经成功写入文件
return true;
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
//程序能走到这里说明对文件没有正常写入,返回一个false告诉Test类没有成功写入文件
return false;
}
}
//该方法是为了实现读取文件file的内容,并且在控制台上输出文件消息和文件内容
public String readMsg() throws IOException {
String str="";
//创建文件输入流对象reader
FileReader reader;
try {
//将reader对象进行初始化
reader = new FileReader(file);
//定义一个int类型变量来记录读到的文件内容
int i=0;
/*因为read()只能每次读一个字符,所以用while循环来一直读文件的字符
并且把读到的每个字符逐一赋值给变量i,让它来接收字符,直到文件读完(也就是返回-1时)*/
while((i= reader.read())!=-1) {
//每次循环都在控制台上输出读到的内容,并且把内容强制装换成char类型
str+=(char)i;
}
//关闭输入流并释放系统资源
reader.close();
return str;
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return str;
}
//该方法是为了执行文件的删除操作
public void deletefile() {
//返回一个true则说明文件删除成功,返回一个false则说明文件删除失败
file.delete();
}
}
运行结果:
点击运行后,就可以选择保存的地址,这是Java自带的文件选择器
点击保存地址后,程序会自动加上\user.db.txt来命名文件名,如果用户还想重新选择保存地址,可以点击重选保存地址的按钮。
点击重选保存地址后,就可以把用户刚刚选的地址重新打印在文字框中。
用户把字符串写入左边的文本域后,点击写入文件按钮就可以把刚刚写入文本域1的内容写入文件中。
如果用户要删除文件,则会弹出一个小窗口再次询问是否要删除文件,如果点是,则文件删除,文本域2的内容自动清空,并且退出该窗口,如果点否,则直接退出该窗口。
编写中遇到的问题和收获:
编写Java Swing界面其实可以是一次次试错的过程,每次运行,我都可以知道一点点的原理,不过,在这期间我也遇到了很多问题。比如要选择哪个布局,刚开始时我用了一下流式布局,觉得还可以,不过这个布局虽然编写简单,但是如果窗口变化了,就会导致我设置的组件也跟着改变,这是很不好的,还有就是边界布局和网格(组)布局,虽然这两个布局写起来比较轻松,也容易理解,但是大多数情况下只能用于只有按钮的窗口中,如果有文本域和文字框,那就十分难看了,所以,我最终还是选择了绝对布局,直接设置每个组件的位置信息,虽然设置起来比较复杂繁琐,但是比较美观,后期容易调整位置,这是比较好的。还有就是像这样按钮文本比较多的窗口中,每个组件一定要有自己的编号,不然每次调整的时候都要找好久,这是比较重要的。还有其实我本来想把那个删除文件的窗口代码写的简单一点,写成(int n =JOptionPane.showConfirmDialog(null, "是否删除", "是否删除", JOptionPane.YES_NO_CANCEL_OPTION);)
这样,通过n的值来判断要执行的动作,但是我觉得它的窗口偏丑:
所以,我还是决定自己写一个小一点的JFrame窗体来询问用户是否删除文件。最后,我想说因为我用这个Swing界面来实现原本的文件操作任务,有些要求我直接去掉或者改变了,比如每次传入字符串时我就没有用end来结尾,还有就是读文件的方法里我返回一个字符串来直接让文本域显示文件信息,请大家多多见谅。
这几天我的收获还是比较大的,了解了Java Swing的基本运行原理,希望我可以在Java这条路上继续努力,哈哈哈。