1. 文字编辑与保存:
(1). 打开文件的处理流程:
首先定义出当使用者选取菜单上的“打开”命令时,所需的处理流程:检查目前编辑中的文件是否已保存,若是,则希望出现对话框供使用者选取所需的文件、打开它然后显示在文字编辑敬;否则出现对话框显示“文件已修改是否保存?”的消息,若单击“是”按钮则保存文件,单击“否”按钮放弃当前文件直接打开。
上面的这几个流程可以分为几个子流程,例如检查文件是否保存、打开文件、保存文件,这几个子流程可以先定义为方法,待会再来实现。因而可以先实现以下的程序内容:
private void openFile()
{
if(isCurrentFileSaved())
{
//判断文件是否为保存状态
open(); //打开
}
else
{
//显示对话框
int option = JOptionPane.showConfirmDialog(
null,"文件已修改,是否保存?","保存文件?",JOptionPane.YES_NO_OPTION,JOptionPane.WARNING_MESSAGE,null);
switch(option)
{
//确认文件保存
case JOptionPane.YES_OPTION;
saveFile(); //保存文件
break;
case JOptionPane.NO_OPTION;
open();
break;
}
}
}
private void opek(){}
private boolean isCurrentFileSaved()
{
return false;
}
在判断文件是否保存的方法上,主要是根据状态栏来进行判断。实现出的内容如下:
private boolean isCurrentFileSaved()
{
if(stateBar.getText().equals("未修改"))
return false;
else
return true;
}
打开文件是使用javax.swing.JFileChooser来显示文件选取的对话框,参见以下程序片段及注释:
private void open()
{
//fileChooser是JFileChooser的实例
//显示文件选取的对话框
int option = fileChooser.showDialog(null,null);
//使用者单击"确认"按钮
if(option == JFileChooser.APPROVE_OPTION)
{
try
{
//打开选取的文件
BufferedReader buf =
new BufferedReader(
new FileReader(fileChooser.getSelectedFile()));
//设定文件标题
setTitle(fileChooser.getSelectedFile().toString());
//删除前一次文件
textArea.setText("");
//设定状态栏
stateBar.setText("未修改");
//取得系统相依的换行字符
String lineSeparator = System.getProperty("line.separator");
//读取文件并附加至文字编辑区
String text;
while((text = buf.readLine()) != null)
{
textArea.append(text);
textArea.append(lineSeparator);
}
buf.close();
}
catch (IOException e)
{
JOptionPane.showMessageDialog(null,e.toString(),"开户文件失败",JOptionPane.ERROR_MESSAGE);
}
}
}
(2)保存文件的流程处理:
在菜单上有“保存”及“另存为”两个选项,但事实上另存为只是多了个显示文件选择框的动作,在设定好文件之后,所使用的仍是保存的流程。
在执行另存为时,显示文件选择对话框,让使用者输入文件名称,在确认后将文字编辑区的内容保存至指定的文件中。而在单击“保存”按钮时,如果标题栏上有指定文件的路径,则直接依该路径保存文件,否则执行“另存为”的流程。
程序实现的片段如下所示:
private void saveFile()
{
//从标题栏取得文件名称
File file = new File(getTitle());
//若指定的文件不存在
if(!file.exists())
{
//执行另存为
saveFileAs();
}
else
{
try
{
//打开指定的文件
BufferedWriter buf =
new BufferedWriter(new FileWriter(file));
//将文件编辑区的文字写入文件
buf.write(textArea.getText());
buf.close();
//设置状态栏为未修改
stateBar.setText("未修改");
}
catch(IOException e)
{
JOptionPane.showMessageDialog(null,e.toString(),"写入文件失败",JOptionPane.ERROR_MESSAGE);
}
}
}
private void saveFileAs()
{
//显示文件对话框
int option = fileChooser.showDialog(null,null);
//如果确认选取文件
if(option == JFileChooser.APPROVE_OPTION)
{
//取得选择的文件
File file = fileChooser.getSelectedFile();
//在标题栏上设定文件名称
setTitle(file.toString());
try
{
//建立文件
file.createNewFile();
//进行文件保存
saveFile();
}
catch (IOException e)
{
JOptionPane.showMessage(null,e.toString(),"无法建立新文件",JOptionPane.ERROR_MESSAGE);
}
}
}
(3) 关闭文件的流程处理:
关闭文件之前,主要必须检查文字编辑区的内容变动是否已保存。如果没有保存,则出现对话框提示使用者确认是否保存,若确认保存则进行保存或另存为的动作,否则直接关闭文件。程序的实现如下所示:
private void closeFile()
{
//是否已保存文件
if(isCurrentFileSaved())
{
//释放窗口资源,而后关闭程序
dispose();
}
else
{
int option = JOptionPane.showConfirmDialog(
null,"文件已修改,是否保存?",
"保存文件",JOptionPane.YES_NO_OPTION,
JOptionPane.WARNING_MESSAGE,null);
switch(option)
{
case JOptionPane.YES_OPTION:
saveFile();
break;
case JOptionPane.NO_OPTION:
dispose();
}
}
}
(4) 文字区的编辑、剪切、复制和粘贴
在文字编辑区进行剪切、复制、粘贴的动作,可以直接调用JTextArea的cut()、copy()、paste()方法,还特别处理了快捷菜单以及状态栏的问题。如下:
private void cut()
{
textArea.cut();
stateBar.setText("已修改");
popUpMenu.setVisible(false);
}
private void copy()
{
textArea.copy();
popUpMenu.setVisible(false);
}
private void paste()
{
textArea.paste();
stateBar.setText("已修改");
popUpMenu.setVisible(false);
}
private void processTextArea()
{
stateBar.setText("已修改");
}
至此,整个文字编辑器大致上都已经完成。完整的程序代码如下:
package ysu.hxy;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import javax.swing.BorderFactory;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.KeyStroke;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingConstants;
public class JNotePadUI extends JFrame {
private JMenuItem menuOpen;
private JMenuItem menuSave;
private JMenuItem menuSaveAs;
private JMenuItem menuClose;
private JMenu editMenu;
private JMenuItem menuCut;
private JMenuItem menuCopy;
private JMenuItem menuPaste;
private JMenuItem menuAbout;
private JTextArea textArea;
private JLabel stateBar;
private JFileChooser fileChooser;
private JPopupMenu popUpMenu;
public JNotePadUI() {
super("新建文本文件");
setUpUIComponent();
setUpEventListener();
setVisible(true);
}
private void setUpUIComponent() {
setSize(640, 480);
// 菜单栏
JMenuBar menuBar = new JMenuBar();
// 设置「文件」菜单
JMenu fileMenu = new JMenu("文件");
menuOpen = new JMenuItem("打开");
// 快捷键设置
menuOpen.setAccelerator(
KeyStroke.getKeyStroke(
KeyEvent.VK_O,
InputEvent.CTRL_MASK));
menuSave = new JMenuItem("保存");
menuSave.setAccelerator(
KeyStroke.getKeyStroke(
KeyEvent.VK_S,
InputEvent.CTRL_MASK));
menuSaveAs = new JMenuItem("另存为");
menuClose = new JMenuItem("关闭");
menuClose.setAccelerator(
KeyStroke.getKeyStroke(
KeyEvent.VK_Q,
InputEvent.CTRL_MASK));
fileMenu.add(menuOpen);
fileMenu.addSeparator(); // 分隔线
fileMenu.add(menuSave);
fileMenu.add(menuSaveAs);
fileMenu.addSeparator(); // 分隔线
fileMenu.add(menuClose);
// 设置「编辑」菜单
JMenu editMenu = new JMenu("编辑");
menuCut = new JMenuItem("剪切");
menuCut.setAccelerator(
KeyStroke.getKeyStroke(KeyEvent.VK_X,
InputEvent.CTRL_MASK));
menuCopy = new JMenuItem("复制");
menuCopy.setAccelerator(
KeyStroke.getKeyStroke(KeyEvent.VK_C,
InputEvent.CTRL_MASK));
menuPaste = new JMenuItem("粘贴");
menuPaste.setAccelerator(
KeyStroke.getKeyStroke(KeyEvent.VK_V,
InputEvent.CTRL_MASK));
editMenu.add(menuCut);
editMenu.add(menuCopy);
editMenu.add(menuPaste);
// 设置「关于」菜单
JMenu aboutMenu = new JMenu("关于");
menuAbout = new JMenuItem("关于JNotePad");
aboutMenu.add(menuAbout);
menuBar.add(fileMenu);
menuBar.add(editMenu);
menuBar.add(aboutMenu);
setJMenuBar(menuBar);
// 文字编辑区域
textArea = new JTextArea();
textArea.setFont(new Font("宋体", Font.PLAIN, 16));
textArea.setLineWrap(true);
JScrollPane panel = new JScrollPane(textArea,
ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
Container contentPane = getContentPane();
contentPane.add(panel, BorderLayout.CENTER);
// 状态栏
stateBar = new JLabel("未修改");
stateBar.setHorizontalAlignment(SwingConstants.LEFT);
stateBar.setBorder(
BorderFactory.createEtchedBorder());
contentPane.add(stateBar, BorderLayout.SOUTH);
popUpMenu = editMenu.getPopupMenu();
fileChooser = new JFileChooser();
}
private void setUpEventListener() {
// 按下窗口关闭钮事件处理
addWindowListener(
new WindowAdapter() {
public void windowClosing(WindowEvent e) {
closeFile();
}
}
);
// 菜单 - 打开
menuOpen.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent e) {
openFile();
}
}
);
// 菜单 - 保存
menuSave.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent e) {
saveFile();
}
}
);
// 菜单 - 另存为
menuSaveAs.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent e) {
saveFileAs();
}
}
);
// 菜单 - 关闭文件
menuClose.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent e) {
closeFile();
}
}
);
// 菜单 - 剪切
menuCut.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent e) {
cut();
}
}
);
// 菜单 - 复制
menuCopy.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent e) {
copy();
}
}
);
// 菜单 - 粘贴
menuPaste.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent e) {
paste();
}
}
);
// 菜单 - 关于
menuAbout.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent e) {
// 显示对话框
JOptionPane.showOptionDialog(null,
"程序名称:\n JNotePad \n" +
"程序设计:\n 良葛格\n" +
"简介:\n 一个简单的文字编辑器\n" +
" 可作为验收Java的实现对象\n" +
" 欢迎网友下载研究交流\n\n" +
"http://caterpillar.onlyfun.net/",
"关于JNotePad",
JOptionPane.DEFAULT_OPTION,
JOptionPane.INFORMATION_MESSAGE,
null, null, null);
}
}
);
// 编辑区键盘事件
textArea.addKeyListener(
new KeyAdapter() {
public void keyTyped(KeyEvent e) {
processTextArea();
}
}
);
// 编辑区鼠标事件
textArea.addMouseListener(
new MouseAdapter() {
public void mouseReleased(MouseEvent e) {
if(e.getButton() == MouseEvent.BUTTON3)
popUpMenu.show(editMenu, e.getX(), e.getY());
}
public void mouseClicked(MouseEvent e) {
if(e.getButton() == MouseEvent.BUTTON1)
popUpMenu.setVisible(false);
}
}
);
}
private void openFile() {
if(isCurrentFileSaved()) { // 文件是否为保存状态
open(); // 打开
}
else {
// 显示对话框
int option = JOptionPane.showConfirmDialog(
null, "文件已修改,是否保存?",
"保存文件?", JOptionPane.YES_NO_OPTION,
JOptionPane.WARNING_MESSAGE, null);
switch(option) {
// 确认文件保存
case JOptionPane.YES_OPTION:
saveFile(); // 保存文件
break;
// 放弃文件保存
case JOptionPane.NO_OPTION:
open();
break;
}
}
}
private boolean isCurrentFileSaved() {
if(stateBar.getText().equals("已修改")) {
return false;
}
else {
return true;
}
}
private void open() {
// fileChooser 是 JFileChooser 的实例
// 显示文件选取的对话框
int option = fileChooser.showDialog(null, null);
// 使用者按下确认键
if(option == JFileChooser.APPROVE_OPTION) {
try {
// 开启选取的文件
BufferedReader buf =
new BufferedReader(
new FileReader(
fileChooser.getSelectedFile()));
// 设定文件标题
setTitle(fileChooser.getSelectedFile().toString());
// 清除前一次文件
textArea.setText("");
// 设定状态栏
stateBar.setText("未修改");
// 取得系统相依的换行字符
String lineSeparator = System.getProperty("line.separator");
// 读取文件并附加至文字编辑区
String text;
while((text = buf.readLine()) != null) {
textArea.append(text);
textArea.append(lineSeparator);
}
buf.close();
}
catch(IOException e) {
JOptionPane.showMessageDialog(null, e.toString(),
"开启文件失败", JOptionPane.ERROR_MESSAGE);
}
}
}
private void saveFile() {
// 从标题栏取得文件名称
File file = new File(getTitle());
// 若指定的文件不存在
if(!file.exists()) {
// 执行另存为
saveFileAs();
}
else {
try {
// 开启指定的文件
BufferedWriter buf =
new BufferedWriter(
new FileWriter(file));
// 将文字编辑区的文字写入文件
buf.write(textArea.getText());
buf.close();
// 设定状态栏为未修改
stateBar.setText("未修改");
}
catch(IOException e) {
JOptionPane.showMessageDialog(null, e.toString(),
"写入文件失败", JOptionPane.ERROR_MESSAGE);
}
}
}
private void saveFileAs() {
// 显示文件对话框
int option = fileChooser.showSaveDialog(null);
// 如果确认选取文件
if(option == JFileChooser.APPROVE_OPTION) {
// 取得选择的文件
File file = fileChooser.getSelectedFile();
// 在标题栏上设定文件名称
setTitle(file.toString());
try {
// 建立文件
file.createNewFile();
// 进行文件保存
saveFile();
}
catch(IOException e) {
JOptionPane.showMessageDialog(null, e.toString(),
"无法建立新文件", JOptionPane.ERROR_MESSAGE);
}
}
}
private void closeFile() {
// 是否已保存文件
if(isCurrentFileSaved()) {
// 释放窗口资源,而后关闭程序
dispose();
}
else {
int option = JOptionPane.showConfirmDialog(
null, "文件已修改,是否保存?",
"保存文件?", JOptionPane.YES_NO_OPTION,
JOptionPane.WARNING_MESSAGE, null);
switch(option) {
case JOptionPane.YES_OPTION:
saveFile();
break;
case JOptionPane.NO_OPTION:
dispose();
}
}
}
private void cut() {
textArea.cut();
stateBar.setText("已修改");
popUpMenu.setVisible(false);
}
private void copy() {
textArea.copy();
popUpMenu.setVisible(false);
}
private void paste() {
textArea.paste();
stateBar.setText("已修改");
popUpMenu.setVisible(false);
}
private void processTextArea() {
stateBar.setText("已修改");
}
public static void main(String[] args) {
new JNotePadUI();
}
}