实现一个简易记事本

效果:记事本界面,实现用户编辑内容,文本字体设置,文件保存,文件打开,记事本退出

先来看看最后运行的一个结果界面:(代码在最后)

java 制作记事本的程序 java简易记事本_java 制作记事本的程序


分析上图,第一个观察简易记事本的主要构成

1.菜单栏

2.文本域

3.给文本域添加的滚动条

java 制作记事本的程序 java简易记事本_java_02

第二个考虑窗体布局,明显的使用方位布局–BorderLayout。菜单栏添加到窗体的上方,文本域添加到窗体的中间。

第三个考虑使用到的组件:面板JPanel,菜单栏JMenuBar,菜单JMenu,文本域JTextArea,文本域的滚动条JScrollPane,
还有三个菜单JMenu:file 、edit 、view

第四个,代码的实现思路
1.定义要用到的变量
2.创建主要方法分别实现:变量初始化、组件往窗体上添加、组件事件监听,保存文件,打开文件,记事本退出等功能

代码有一些细节要注意,菜单有哪些都可以自己定义,如下,每俩功能之间都有一条下划线,当然这个不添加也可以。

java 制作记事本的程序 java简易记事本_1024程序员节_03

代码实现

package test2;
//简易记事本,里面的this是调用成员变量,解决局部变量名称冲突问题
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.*;

//继承JFrame的这个父类,实现监听器的接口
public class EasyTXT extends JFrame implements ActionListener {
    //观察布局,有菜单栏和文本域两个上下组成,所以用方位布局
    //先定义要用到的变量

    JPanel jp;//窗体主面板
    JTextArea jta;//文本域
    JScrollPane jsp;//文本域的滚动条
    JMenuBar jmb;//菜单栏组件
    JMenu file,edit,view;//菜单内容
    File currentFile=null;//当前打开的文件
    boolean wasSaved=true;//当前文件是否保存

    public  void TextEditor(){ //该方法实现对组件的初始化
        jp=new JPanel();//初始化面板
        jmb=new JMenuBar();//初始化菜单栏组件
        jta=new JTextArea(50,50);//初始化文本域
        jta.getDocument().addDocumentListener( 
        //给文本域注册监听器,用来监听文档是否发生更改,DocumentListener()接口中有三个方法      
                new DocumentListener() {  
                       
                    @Override//表示继承,以下三个方法是对父类方法的一个重写
                    public void insertUpdate(DocumentEvent e) {
                        wasSaved=false;//表示编辑框有修改操作
                        //当监听到有这三种操作时就代表着文本将重新保存,这时文本状态是未保存的,所以用false,true是文件已保存
                    }

                    @Override
                    public void removeUpdate(DocumentEvent e) {

                        wasSaved=false;//表示对编辑框有插入操作
                    }

                    @Override
                    public void changedUpdate(DocumentEvent e) {

                        wasSaved=false;//表示对编辑框内容有删除的操作
                    }
                }
        );
        jsp=new JScrollPane(jta);// 给文本域添加滚动条

        //下面对三个菜单按钮进行定义
        file=new JMenu("File");//第一个,file菜单
        JMenuItem item;//定义菜单项
        file.add(item=new JMenuItem("New"));//给file添加以下功能
        item.addActionListener(this);
        file.add(item=new JMenuItem("Open..."));
        item.addActionListener(this);
        file.addSeparator();//调用该方法,在这两个功能下添加一条下划线
        file.add(item=new JMenuItem("Save"));
        item.addActionListener(this);
        file.add(item=new JMenuItem("Save As..."));
        item.addActionListener( this);
        file.addSeparator();//调用该方法,添加一条下划线
        file.add(item=new JMenuItem("Quit"));
        item.addActionListener( this);
  		//给edit菜单添加以下功能
        edit=new JMenu("Edit");
        edit.add(item=new JMenuItem("Find..."));
        item.addActionListener( this);
        edit.add(item=new JMenuItem("Replace..."));
        item.addActionListener(this);
		//给view菜单添加以下功能
        view=new JMenu("View");
        view.add(item=new JMenuItem("Font..."));
        item.addActionListener(this);
        view.add(item=new JMenuItem("Color..."));
        item.addActionListener(this);


    }

    public void init(){  //菜单栏和窗体的添加
    
        jmb.add(file);//把三个菜单都添加到菜单栏组件上去
        jmb.add(edit);
        jmb.add(view);
        this.setJMenuBar(jmb);//再设置jmb 为窗体的菜单栏,这个this指的是jp
        this.add(jsp, BorderLayout.CENTER);//把带有滚动条的文本域添加到面板中间,这个this也是指jp
        
        setSize(800,600);//窗体大小设置
        jta.setFont(new Font("宋体",Font.PLAIN,18));//字体设置
        setVisible(true);//窗口可见
    }


    public void actionPerformed(ActionEvent e){//该方法是对每个菜单事件的监听
        String command=e.getActionCommand();//获得点击按钮的字符串
        //getSource得到的组件的名称,而getActionCommand得到的是标签。
        if(command.equals("Open...")){

            File f=null;
            openFile(f);
            currentFile=f;
            return;
        }
        if(command.equals("Color...")){
            //Color菜单处理
            Color c=JColorChooser.showDialog(this,"选择文字颜色",Color.BLACK);
            jta.setForeground(c);//对文字进行颜色设置
            return;
        }
        if(command.equals("Quit")){
            this.dispose();  //关闭gui页面,关闭窗体并释放一部分窗体所占资源
        }
        if(command.equals("Save As...")){

            File f = null;
            saveFileAs(f);
            currentFile=f;

            return;
        }
        if(command.equals("Save")){

            File f=null;
            saveFile(f);
            currentFile = f;
            return;
        }

    }

//文件保存~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    public void saveFile(File f){
        // 从标题栏取得文件名称
        File file = new File(getTitle());

        // 若指定的文件不存在
        if(!file.exists()) {
            // 执行另存为
            saveFileAs(file);
        }
        else {
            try {
                // 开启指定的文件,创建一个字符输出缓冲流,让用户输入数据
                BufferedWriter buf = new BufferedWriter(new FileWriter(file));
                // 将文字编辑区的文字写入文件,
                buf.write(jta.getText());
                buf.close();//关闭缓冲流
            }
            catch(IOException e) {
                JOptionPane.showMessageDialog(null, e.toString(),
                        "写入文件失败", JOptionPane.ERROR_MESSAGE);
            }
        }
    }

    private void saveFileAs(File f) {
        // 显示文件对话框
        JFileChooser fileChooser = new JFileChooser();//创建文件选择器
        int option = fileChooser.showSaveDialog(null);//show‘’保存‘’
        //showSaveDialog(null);----show‘’保存‘’
        //showOpenDialog(null);----show“打开”
        // 如果确认选取文件
        if(option == JFileChooser.APPROVE_OPTION) {
            //JFileChooser.APPROVE_OPTION是个整型常量,代表0。就是说当返回0的值我们才执行相关操作,否则什么也不做。
            // 取得选择的文件
            File file = fileChooser.getSelectedFile();

            // 在标题栏上设定文件名称
            setTitle(file.toString());

            try {
                // 建立文件
                file.createNewFile();
                // 进行文件保存
                saveFile(file);
            }
            catch(IOException e) {
                JOptionPane.showMessageDialog(null, e.toString(),
                        "无法建立新文件", JOptionPane.ERROR_MESSAGE);
            }
        }
    }

//文件打开~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    public void openFile(File f){
        JFileChooser fileChooser = new JFileChooser();
        fileChooser.setDialogTitle("Open file");
        int option=fileChooser.showDialog(null, null);
        // 使用者按下确认键
        if(option == JFileChooser.APPROVE_OPTION) {
            try {
                // 开启选取的文件
                BufferedReader buf =new BufferedReader(new FileReader(fileChooser.getSelectedFile()));

                // 设定文件标题
                setTitle(fileChooser.getSelectedFile().toString());
                // 清除前一次文件
                clearjta();
                // 取得系统相依的换行字符
                String lineSeparator = System.getProperty("line.separator");//获取系统参数
                // 读取文件并附加至文字编辑区
                String text;//定义文本
                while((text = buf.readLine()) != null) {
                    jta.append(text);
                    jta.append(lineSeparator);
                }

                buf.close();
            }
            catch(IOException e) {
                JOptionPane.showMessageDialog(null, e.toString(),
                        "开启文件失败", JOptionPane.ERROR_MESSAGE);
            }
        }
    }

    private void clearjta() {
        jta.selectAll();
        jta.replaceSelection("");

    }


  
    public static void main(String[] args){
        EasyTXT tx=new EasyTXT();
        tx.TextEditor();
        tx.init();

    }
}

这里也顺便记录一下关于setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE)方法,上述代码没有用到:

java 制作记事本的程序 java简易记事本_文本域_04


没有设置的话,默认点关闭时只是隐藏窗体,在后台进程中还可以看到,如果有多个窗口,只是销毁调用dispose的窗口,其他窗口仍然存在,整个应用程序还是处于运行状态。