java记事本实现新建、打开、保存、另存为、退出功能

本文是对记事本中的新建、打开、保存、另存为和退出功能的实现和讲解。主要需要解决的问题有:如何从文件中读取内容并放入文本编辑区域?如何将对已有文件中内容的改变保存回文件中?如何创建新文件保存文本内容?接下来就逐个解决。

一、文件读取

首先是文件的读取,文件的读取方式有很多,以下是本人在实现记事本程序的时候参考的一种

String readFile() {
    // 声明缓冲字符流变量
    BufferedReader br = null;
    StringBuilder sb = null;
    try {
        br = new BufferedReader(new FileReader(jfilechoose.getSelectedFile()));
        sb = new StringBuilder();// 创建缓冲字符串
        String str;
        int count = 0;//控制添加换行符
        while ((str = br.readLine()) != null) {
            if (count == 0){
                sb.append(str);//第一行不换行
                count=1;
            }
            else
                sb.append("\n" + str);//后面的行为换行+内容
        }
    } catch (FileNotFoundException e1) {
        // 弹出“文件未找到”对话框,showMessageDialog中的null表示对话框采用默认框架
        JOptionPane.showMessageDialog(null, "未找到该文件!");
        return null;
    } catch (IOException e1) {
        // 弹出“文件读取异常”对话框,null表示对话框采用默认框架
        JOptionPane.showMessageDialog(null, "文件读取异常");
        return null;
    } finally {
        // 关闭字符流
        if (br != null)
            try {
                br.close();//关闭流
            } catch (IOException e1) {
                e1.printStackTrace();
            }
    }
    File file = jfilechoose.getSelectedFile();//获取选中的文件
    name = file.getName();//文件名
    filepath = file.getAbsolutePath();//文件绝对路径
    setTitle(name + " - 记事本");//设置记事本的标题
    return sb.toString();//转换成字符串输出
}

BufferedReader是从缓冲区中读取内容,作用是对带有换行符的文本内容的按行读取,创建时需要一个Reader的参数,由Reader去用流的方式读取数据,而BufferedReader只是解析流数据并组成一行一行的String。

StringBuilder()不传入参数时是构造一个字符串构建器,其中不包含任何字符,初始容量为16个字符,也可以传入参数指定初始容量和初始字符串内容。

readLine的读取方式为读取一行内容,直到换行符,但不读取换行符,因此在文本区域显示时要添加换行符。添加换行符的方式也可以采用“每行内容+换行符“的形式,这样无非是最后一行文本后多出一个空行,这对记事本而言是没有影响的。

对文件绝对路径的记录有助于了解当前文本区域显示内容属于哪个文件。

二、文件保存

void saveFile(File file) {
    BufferedWriter bw = null;
    try {
        bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file)));
        bw.write(jtext.getText());//写入文件
        bw.flush();
    } catch (FileNotFoundException e1) {
        JOptionPane.showMessageDialog(MyNotepad.this, "文件保存出错" + e1.getMessage());
    } catch (IOException e1) {
        e1.printStackTrace();
    } finally {
        try {
            if (bw != null)
                bw.close();
        } catch (IOException e1) {
        }
    }
}

BufferedWriter(Writer out, int size)传入size可以指定大小,不传则创建使用默认大小的输出缓冲区的缓冲字符输出流。

OutputStreamWriter是从字符流到字节流的桥接。

用FileOutputStream写入文件的流程图如下:

调用BufferedWriter的write方法时,数据写入缓冲区,并没有直接写到目的文件里,必须调用BufferedWriter的flush()方法刷新一下该缓冲流,把数据写入到目的文件里。

三、文件创建(另存为功能)

文件创建首先弹出一个是否保存的对话框,这个对话框在JFileChooser(文件选择器)这个类中。获取选中文件的文件名和绝对地址,文件名用于设置记事本标题,绝对地址用于记录当前文本内容的所属文件。对于选中文件判断是否以及存在于系统中,存在便询问是否覆盖原文件,覆盖或者文件不存在都可以调用上一步的文件保存方法;不覆盖则重新弹出文件保存对话框。

void createFile() {
    File file = null;
    // 选择保存或取消
    if (jfilechoose.showSaveDialog(MyNotepad.this) == JFileChooser.APPROVE_OPTION)
        file = jfilechoose.getSelectedFile();// 获取选中的文件
    else
        return;
    name = jfilechoose.getName(file);// 获取输入的文件名
    filepath = file.getAbsolutePath();//获取文件的绝对路径
    if (file.exists()) { // 若选择已有文件----询问是否要覆盖
        int select = JOptionPane.showConfirmDialog(null, "该文件已存在,是否覆盖原文件", "确认", JOptionPane.YES_NO_OPTION);
        if (select == JOptionPane.YES_OPTION)
            saveFile(file);
        else
            jfilechoose.showSaveDialog(MyNotepad.this);// 重新选择
    } 
    else//文件不存在,则直接保存
        saveFile(file);
}

另存为功能就是另外创建一个文件保存当前文件内容,因此另存为功能的实现如下

createFile();
setTitle(name + " - 记事本");

四、保存功能的实现

有了以上3个函数的支撑就可以开始实现保存功能了,保存分为两种情况,第一种是当前文本内容尚未存在过任何文件中,此时应该调用文件创建的方法;第二种是当前文本内容是从已有文件中读取出来的,此时应该调用文件保存的方法。

int Save() {
    int select = 0;
    // 判断文件是否已存在
    if (filepath == null) {
        select = JOptionPane.showConfirmDialog(MyNotepad.this, "是否保存修改?");
        if (select == JOptionPane.YES_OPTION)
            createFile();//文件不存在,则创建文件
    } 
    else {
        Boolean isSaved = jtext.getText().equals(readFile())//文本区域内容与文件中相同返回true
        if (!isSaved){// 文件未保存
            //去掉以下两行,保留第3行就是已有文件直接保存,不提醒        
            select = JOptionPane.showConfirmDialog(MyNotepad.this, "是否保存修改?");
            if(select == JOptionPane.YES_OPTION)
                saveFile(jfilechoose.getSelectedFile());
        }
    }
    return select;// 返回选项
}

filepath是文件的绝对路径,初始化为null,在读取文件和创建文件后会获取读取或创建文件的绝对路径。JOptionPane.YES_OPTION是弹出窗口的四个选项中的”是(Y)“。

否(N):JOptionPane.NO_OPTION

取消:JOptionPane.CANCEL_OPTION

右上角的X:JOptionPane.CLOSED_OPTION

则保存菜单的点击事件处理操作如下:

Save();//调用文件保存方法
setTitle(name + " - 记事本");//设置记事本标题

五、打开功能的实现

打开新文件之前要先判断当前文本内容是否保存,之后便是从文件选择器中选择要打开的文件,读取文件,设置记事本标题。如果写了撤销功能,还需要撤销所有的"撤销"操作,并将撤销功能设为不可用状态。

// 是否保存对原文件修改
int select = Save();
if (select == JOptionPane.CANCEL_OPTION||select == JOptionPane.CLOSED_OPTION)// 取消、关闭按钮,则返回
    return;
// 弹出一个 "Open File" 文件选择器对话框
select = jfilechoose.showOpenDialog(MyNotepad.this);
// 选择打开文件,则读写文件
if (select == JFileChooser.APPROVE_OPTION) {
    jtext.setText(readFile());// 写入文本框
    jtext.setCaretPosition(0);// 定位光标至行首

    undom.discardAllEdits(); //撤消所有的"撤消"操作  
    edit_undo.setEnabled(false);//撤销功能设为不可用
}

六、新建功能的实现

新建功能与打开功能类似,区别在于不需要打开文件,只要清空文本区域即可,还有文件路径和记事本标题的不同。

int select=showSaveDialog();
if (select == JOptionPane.CANCEL_OPTION||
select == JOptionPane.CLOSED_OPTION)//取消、关闭按钮,则返回
    return;
else{
    jtext.replaceRange("",0,jtext.getText().length());//清空文本区域
    setTitle("无标题 - 记事本");//设置记事本标题
    filepath=null;//当前文件路径为空

    undom.discardAllEdits(); //撤消所有的"撤消"操作  
    edit_undo.setEnabled(false);//撤销功能设为不可用
}

七、退出功能的实现

退出程序之前询问一下是否要保存当前文本内容,因为有新窗口功能的存在,所以退出是关闭当前窗口,而不是关闭程序。

int select = showSaveDialog();
if (select != JOptionPane.CANCEL_OPTION && 
    select != JOptionPane.CLOSED_OPTION)
    dispose();//释放窗体,dispose()

点击窗口右上角关闭的四种关闭方式:

1.this.setDefaultCloseOperation(0);// DO_NOTHING_ON_CLOSE,不执行任何操作。

2.this.setDefaultCloseOperation(1);//HIDE_ON_CLOSE,只隐藏界面,setVisible(false)。

3.this.setDefaultCloseOperation(2);//DISPOSE_ON_CLOSE,隐藏并释放窗体,dispose(),当最后一个窗口被释放后,则程序也随之运行结束。

4.this.setDefaultCloseOperation(3);//EXIT_ON_CLOSE,直接关闭应用程序,System.exit(0),一个main函数对应一整个程序。

上述四种关闭方式源自CSDN博主「Andrewlu58」的原创文章,链接附上:https://blog.csdn.net/xiangyong58/article/details/8252016,如果上述四种关闭方式对你有所帮助,可以点点链接前往原文章支持一波。

主界面窗口右上角关闭的操作与退出功能一样,不同的是dispose()用于windowClosing中会关闭全部的窗体,因此要用setDefaultCloseOperation(2)。

addWindowListener(new WindowAdapter() {
    @Override
    public void windowClosing(WindowEvent e) {
        int select = showSaveDialog();
        if (select != JOptionPane.CANCEL_OPTION &&
         select != JOptionPane.CLOSED_OPTION)
            setDefaultCloseOperation(2);//隐藏并释放窗体,dispose(),当最后一个窗口被释放后,则程序也随之运行结束。 
    }
});

  • 4
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是一个简单的记事本 Java 代码,实现新建打开保存另存为退出功能: ```java import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.UIManager; import javax.swing.filechooser.FileNameExtensionFilter; public class Notepad extends JFrame implements ActionListener { private static final long serialVersionUID = 1L; private JTextArea textArea; private JFileChooser fileChooser; private String fileName; public Notepad() { super("记事本"); // 设置菜单栏 JMenuBar menuBar = new JMenuBar(); JMenu fileMenu = new JMenu("文件"); JMenuItem newMenuItem = new JMenuItem("新建"); JMenuItem openMenuItem = new JMenuItem("打开"); JMenuItem saveMenuItem = new JMenuItem("保存"); JMenuItem saveAsMenuItem = new JMenuItem("另存为"); JMenuItem exitMenuItem = new JMenuItem("退出"); newMenuItem.addActionListener(this); openMenuItem.addActionListener(this); saveMenuItem.addActionListener(this); saveAsMenuItem.addActionListener(this); exitMenuItem.addActionListener(this); fileMenu.add(newMenuItem); fileMenu.add(openMenuItem); fileMenu.add(saveMenuItem); fileMenu.add(saveAsMenuItem); fileMenu.addSeparator(); fileMenu.add(exitMenuItem); menuBar.add(fileMenu); setJMenuBar(menuBar); // 设置文本区域 textArea = new JTextArea(); JScrollPane scrollPane = new JScrollPane(textArea); getContentPane().add(scrollPane, BorderLayout.CENTER); // 设置文件选择器 fileChooser = new JFileChooser(); fileChooser.setFileFilter(new FileNameExtensionFilter("文本文件(*.txt)", "txt")); // 设置窗口 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setSize(800, 600); setLocationRelativeTo(null); setVisible(true); } public static void main(String[] args) { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (Exception e) { e.printStackTrace(); } new Notepad(); } @Override public void actionPerformed(ActionEvent e) { String command = e.getActionCommand(); switch (command) { case "新建": newFile(); break; case "打开": openFile(); break; case "保存": saveFile(); break; case "另存为": saveAsFile(); break; case "退出": exit(); break; } } // 新建文件 private void newFile() { if (textArea.getText().length() > 0) { int option = JOptionPane.showConfirmDialog(this, "是否保存更改?", "记事本", JOptionPane.YES_NO_CANCEL_OPTION); if (option == JOptionPane.YES_OPTION) { saveFile(); } else if (option == JOptionPane.CANCEL_OPTION) { return; } } textArea.setText(""); fileName = null; } // 打开文件 private void openFile() { if (textArea.getText().length() > 0) { int option = JOptionPane.showConfirmDialog(this, "是否保存更改?", "记事本", JOptionPane.YES_NO_CANCEL_OPTION); if (option == JOptionPane.YES_OPTION) { saveFile(); } else if (option == JOptionPane.CANCEL_OPTION) { return; } } int result = fileChooser.showOpenDialog(this); if (result == JFileChooser.APPROVE_OPTION) { try { File file = fileChooser.getSelectedFile(); fileName = file.getAbsolutePath(); BufferedReader reader = new BufferedReader(new FileReader(file)); String line = null; StringBuilder sb = new StringBuilder(); while ((line = reader.readLine()) != null) { sb.append(line); sb.append(System.lineSeparator()); } reader.close(); textArea.setText(sb.toString()); } catch (Exception e) { e.printStackTrace(); } } } // 保存文件 private void saveFile() { if (fileName == null) { saveAsFile(); } else { try { BufferedWriter writer = new BufferedWriter(new FileWriter(fileName)); writer.write(textArea.getText()); writer.close(); } catch (Exception e) { e.printStackTrace(); } } } // 另存为文件 private void saveAsFile() { int result = fileChooser.showSaveDialog(this); if (result == JFileChooser.APPROVE_OPTION) { try { File file = fileChooser.getSelectedFile(); if (!file.getName().endsWith(".txt")) { file = new File(file.getAbsolutePath() + ".txt"); } fileName = file.getAbsolutePath(); BufferedWriter writer = new BufferedWriter(new FileWriter(file)); writer.write(textArea.getText()); writer.close(); } catch (Exception e) { e.printStackTrace(); } } } // 退出程序 private void exit() { if (textArea.getText().length() > 0) { int option = JOptionPane.showConfirmDialog(this, "是否保存更改?", "记事本", JOptionPane.YES_NO_CANCEL_OPTION); if (option == JOptionPane.YES_OPTION) { saveFile(); } else if (option == JOptionPane.CANCEL_OPTION) { return; } } System.exit(0); } } ``` 该记事本实现新建打开保存另存为退出功能,可以选择文本文件进行编辑。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值