Java运用GUI实现文本文档功能

一、概述

运用图形界面工具实现文本文档的界面,再通过I/O流进行文件的读取和保存,以此实现文本文档的新建、保存、打开、另存外等功能。

二、具体实现

新建一个名为notepad的java项目。

1.新建util包

util包中用来存放一些静态的工具方法。这里存放两个文件选择器,分别为文件打开选择器和文件保存选择器。

代码如下:

package util;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import javax.swing.JFileChooser;
import javax.swing.filechooser.FileFilter;
import javax.swing.filechooser.FileNameExtensionFilter;

public class FileChoose {
	private static final String path = ".";// 表示当前目录
	
	public static void main(String[] args) {
		new FileChoose();
	}

	public FileChoose() {
//		System.out.println(getFileChoose());
		
		System.out.println(saveFile());
	}

	/**
	 * 文件选择
	 */
	public static File getFileChoose() {
		JFileChooser jf = new JFileChooser(path);// 实例化文件选择器
		/*
		 * 设置可选类型 参数有三个 分别为 
		 * •JFileChooser.FILES_ONLY  仅仅选择文件
		 * •JFileChooser.DIRECTORIES_ONLY 仅仅选择目录
		 * •JFileChooser.FILES_AND_DIRECTORIES  既选择文件又选择目录
		 */
		jf.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
		// 设置文件过滤,会覆盖原有过滤
		jf.setFileFilter(new FileFilter() {// FileFilter 为抽象类
			// 注意:这个不是实例化FileFilter类 , 这是采用内部类的方式

			@Override
			public String getDescription() {// 显示为指定后缀名的文件
				return ".java";
			}

			@Override
			public boolean accept(File f) {// 判断文件是否以java结尾
				if (f.getName().endsWith("java")) {
					return true;
				} else {
					return false;
				}
			}
		});
			
		//添加文本文件过滤
		jf.addChoosableFileFilter(new FileFilter() {// FileFilter 为抽象类
			// 注意:这个不是实例化FileFilter类 , 这是采用内部类的方式

			@Override
			public String getDescription() {// 显示为指定后缀名的文件
				return ".txt";
			}

			@Override
			public boolean accept(File f) {// 判断文件是否以txt结尾
				if (f.getName().endsWith("txt")) {
					return true;
				} else {
					return false;
				}
			}
		});
		
		jf.showOpenDialog(null);// 设置打开时的窗口 null表示没有父窗口
		return jf.getSelectedFile(); // 返回得到选择器选择的文件
	}
	
	//文件保存
	public static File saveFile() {
		
		
		//弹出文件选择框
		JFileChooser chooser = new JFileChooser();	
		//后缀名过滤器
		FileNameExtensionFilter filter = new FileNameExtensionFilter(
		        "文本文件(*.txt)", "txt");
		chooser.setFileFilter(filter);
		chooser.setSelectedFile(new File("*.txt"));//初始化文件名
		
		//下面的方法将阻塞,直到【用户按下保存按钮且“文件名”文本框不为空】或【用户按下取消按钮】
		int option = chooser.showSaveDialog(null);
		
		if(option==JFileChooser.APPROVE_OPTION){//假如用户选择了保存
			File file = chooser.getSelectedFile();		
			String fname = chooser.getName(file);//从文件名输入框中获取文件名
			
//			while(fname.indexOf("*") == -1)
			
			//假如用户填写的文件名不带我们制定的后缀名,那么我们给它添上后缀
			if(fname.indexOf(".txt") == -1){
				file=new File(chooser.getCurrentDirectory(),fname+".txt");
			}	
			
			return file;
		}
		return null;
	}

	

}

2.新建service包

service包用来存放逻辑层的代码,这里新建了一个输入流和一个输出流的接口并进行实现。

a.输入流接口

package service;

public interface Input {
	//打开文件,并获取内容
	String[] getFile() throws Exception;
	
}

b.输入流接口实现

package service;

import java.io.File;
import java.io.FileInputStream;

import util.FileChoose;

public class InputImpl implements Input{

	@Override
	public String[] getFile() throws Exception {
		//从文件选择器获取文件
		File file = FileChoose.getFileChoose();
		//文件内容读取
		FileInputStream ips = new FileInputStream(file);
		
		byte[] bt = new byte[1024];//创建直接数组用来读取文件内容
		
		StringBuffer s = new StringBuffer();//创建字符串流将读取的字符串合并
		
		String[] strArray = new String[2];//存储文件名和文件读取内容
		
		int len;
		while((len = ips.read(bt)) != -1) {
			String str = new String(bt,0,len);//将读取的字节转换为字符串
			s.append(str);
		}
		
        ips.close();
		strArray[0] = file.toString();
		strArray[1] = s.toString();
		return strArray;
	}

}

c.输出流接口

package service;

public interface Output {
	
	//新建一个文件并将内容保存到新建文件中
	void createAndSave(String text) throws Exception;
	
	//保存文件
	void saveFile(String fileName,String text) throws Exception;

}

d.输出流接口实现

package service;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import util.FileChoose;

public class OutputImpl implements Output{

	@Override
	public void createAndSave(String text) throws Exception {
		File newFile = FileChoose.saveFile();//从文件选择器中获取文件

		if(newFile != null){//如果文件不为空
			newFile.createNewFile();//创建文件
			byte[] bt = text.getBytes();
			FileOutputStream ops = new FileOutputStream(newFile);
			ops.write(bt,0,bt.length);
			ops.close();
		}			
	}

	@Override
	public void saveFile(String fileName,String text) throws Exception {
		FileOutputStream ops = new FileOutputStream(new File(fileName));
		byte[] bt = text.getBytes();
		ops.write(bt,0,bt.length);
		ops.close();		
	}
}

3.图形界面设计

新建一个用来存放图形界面的名为view的包,并创建一个Notepad类,作为文本文档的主要界面,并根据功能需求添加监听事件,并实现。

代码如下:

package view;

import java.awt.BorderLayout;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;

import service.Input;
import service.InputImpl;
import service.Output;
import service.OutputImpl;

import java.awt.Toolkit;
import javax.swing.JMenu;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.SwingConstants;
import javax.swing.BoxLayout;
import java.awt.GridLayout;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JTextArea;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;

public class Notepad extends JFrame {
	
	private String fileName = null; 
	
	Output op = new OutputImpl();//输出流对象
	Input in = new InputImpl();//输入流对象

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					Notepad frame = new Notepad();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the frame.
	 */
	public Notepad() {
		getJFram();
		this.setLocationRelativeTo(null);
		this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);//防止新窗口和旧窗口一起关闭
	}

	/**
	 * 初始化窗体的构造
	 */
	private void getJFram() {
		setIconImage(Toolkit.getDefaultToolkit().getImage("images\\图片1.png"));
		setTitle("记事本");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 729, 553);
		
		JTextArea textArea = new JTextArea();
		
		JMenuBar menuBar = new JMenuBar();
		setJMenuBar(menuBar);
		
		JMenu mnNewMenu = new JMenu("文本(F)");
		menuBar.add(mnNewMenu);
		
		JMenuItem mntmNewMenuItem = new JMenuItem("新建(N)");
		//给新建选项设置监听事件
		mntmNewMenuItem.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {			
				create(textArea);	
			}
		});	
		mnNewMenu.add(mntmNewMenuItem);
		
		JMenuItem mntmNewMenuItem_1 = new JMenuItem("新窗口(W)");
		//给新窗口添加监听事件
		mntmNewMenuItem_1.addActionListener(new ActionListener() {		
			@Override
			public void actionPerformed(ActionEvent e) {
				new Notepad().setVisible(true);
				
			}
		});
		mnNewMenu.add(mntmNewMenuItem_1);
		
		JMenuItem mntmNewMenuItem_2 = new JMenuItem("打开(O)");
		//给打开添加监听事件
		mntmNewMenuItem_2.addActionListener(new ActionListener() {		
			@Override
			public void actionPerformed(ActionEvent e) {
				String text;
				try {
					text = getFile();
					textArea.setText(text);
				} catch (Exception e1) {
					// TODO 自动生成的 catch 块
					e1.printStackTrace();
				}			
			}		
		});
		mnNewMenu.add(mntmNewMenuItem_2);
		
		JMenuItem mntmNewMenuItem_3 = new JMenuItem("保存(S)");
		//给保存添加监听事件
		mntmNewMenuItem_3.addActionListener(new ActionListener() {		
			@Override
			public void actionPerformed(ActionEvent e) {
				save(textArea.getText());
				
			}
		});
		mnNewMenu.add(mntmNewMenuItem_3);
		
		JMenuItem mntmNewMenuItem_4 = new JMenuItem("另存外(A)");
		//给另存外添加监听事件
		mntmNewMenuItem_4.addActionListener(new ActionListener() {		
			@Override
			public void actionPerformed(ActionEvent e) {
				otherSave(textArea.getText());

			}
		});
		mnNewMenu.add(mntmNewMenuItem_4);
		
		JMenu mnNewMenu_1 = new JMenu("编辑(E)");
		menuBar.add(mnNewMenu_1);
		
		JMenu mnNewMenu_2 = new JMenu("格式(O)");
		menuBar.add(mnNewMenu_2);
		
		JMenu mnNewMenu_3 = new JMenu("查看(V)");
		menuBar.add(mnNewMenu_3);
		
		JMenu mnNewMenu_4 = new JMenu("帮助(H)");
		menuBar.add(mnNewMenu_4);
		
		JPanel panel = new JPanel();
		GroupLayout groupLayout = new GroupLayout(getContentPane());
		groupLayout.setHorizontalGroup(
			groupLayout.createParallelGroup(Alignment.LEADING)
				.addComponent(panel, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 715, Short.MAX_VALUE)
		);
		groupLayout.setVerticalGroup(
			groupLayout.createParallelGroup(Alignment.LEADING)
				.addComponent(panel, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 493, Short.MAX_VALUE)
		);
		
		
		GroupLayout gl_panel = new GroupLayout(panel);
		gl_panel.setHorizontalGroup(
			gl_panel.createParallelGroup(Alignment.LEADING)
				.addComponent(textArea, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 715, Short.MAX_VALUE)
		);
		gl_panel.setVerticalGroup(
			gl_panel.createParallelGroup(Alignment.LEADING)
				.addComponent(textArea, Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, 493, Short.MAX_VALUE)
		);
		panel.setLayout(gl_panel);
		getContentPane().setLayout(groupLayout);
	}
	
	//另存外当前内容
	private void otherSave(String text) {
		if(text != null && !text.equals("")) {
			//如果当前文件内容不为空
			//新建文件并保存
			try {
				op.createAndSave(text);
			} catch (Exception e1) {
				// TODO 自动生成的 catch 块
				e1.printStackTrace();
			}		
		}
		
	}

	//保存当前内容
	private void save(String text) {
		if(this.fileName != null && text != null && !text.equals("")) {//如果当前内容为打开文件内容,则文件名不为空
			try {
				op.saveFile(fileName, text);
			} catch (Exception e) {
				// TODO 自动生成的 catch 块
				e.printStackTrace();
			}
		}else {//否则就保存进一个新文件中
			if(text != null && !text.equals("")){
				//如果当前文件内容不为空
				//新建文件并保存
				try {
					op.createAndSave(text);
				} catch (Exception e1) {
					// TODO 自动生成的 catch 块
					e1.printStackTrace();
				}		
			}
		}
	}

	/**
	 * @param textArea
	 *新建文件
	 */
	private void create(JTextArea textArea) {
		
		String text = textArea.getText();//获取文件内容
		if(text != null && !text.equals("")){
			//如果当前文件内容不为空
			//保存当前文件并打开一个新窗口
			save(text);
			new Notepad();
		}
	}	
	
	/*
	 * 打开文件
	 * */
	
	private String getFile() throws Exception {
		String[] file = in.getFile();
		this.fileName = file[0];
		return (file[1] == null) ? "" : file[1];
	}

	
}

三、测试

1.测试打开文件

我在桌面新建了一个txt文件,并适当添加了内容,如下:

 现在通过java编写的文本文档打开并获取此文档内容。

选择打开,如下:

 然后找到目标文件:

 结果如下:

 2.测试修改后保存

接着上面内容,先修改内容,在进行保存,如下:

 重新打开记事本文件,会发现内容已经被修改,如下:

3.测试文件另存外

继续接着上面内容,点击文件另存外:

 选择目标路径,输入新建文件名称,当文件名不包含后缀时默认使用txt作为后缀,如下:

 点击保存后,可以发现桌面以及多出来了一个新文件,如下:

 其内容为测试文件1中的内容,如下:

 四、部分功能说明

1.关于新建

当文本内容为空时,不做任何处理,否则会保存当前文本内容,然后再打开一个新窗口。

2.关于保存

若当前窗口的文本框内容是来源于打开其他文件获取的内容时,修改其内容后直接可以保存,若非从其他文件打开获取的内容,则保存时需要选择保存路径和保存文件的文件名称。

3.关于打开新窗口

点击打开新窗口,则会在原来的窗口上弹出一个新窗口,两者相互不影响。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值