# Java Notes: Example - NanoEdit

This program is the simplest text editor you can imagine. It's used as an example of menus, JFileChooser, and reading and writing text files.

## NanoEdit source code

      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    // File   : nanoedit/NanoEdit.java
    // Purpose: Display file in text area.  Allow open/save file.
    //          Illustrates menus, JFileChooser, read/write text files.
    //          This combines everything into one class,
    //          main, the GUI, and the model.  There really
    //          isn't much model because it's only the string
    //          in the JTextArea.
    // Bugs   : Doesn't write system dependent newlines.
    //          Error handling is nonexistent.
    // Author : Fred Swartz
    // Date   : 2005-12-01

    package nanoedit;

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import java.io.*;
    import java.util.*;

    public class NanoEdit extends JFrame {
        //================================================= instance variables
        //... GUI variables references at runtime.
        private JTextArea    m_textTA      = new JTextArea(25, 80);
        private JFileChooser m_fileChooser = new JFileChooser();
        private JMenuItem    m_openItem    = new JMenuItem("Open...");
        private JMenuItem    m_saveItem    = new JMenuItem("Save...");
        private JMenuItem    m_quitItem    = new JMenuItem("Quit");

        //======================================================== constructor
        NanoEdit() {
            JButton openButton = new JButton("Open");
            JButton saveButton = new JButton("Save");

            //... Layout main content panel
            JPanel content = new JPanel();
            content.setLayout(new BorderLayout());
            content.add(new JScrollPane(m_textTA), BorderLayout.CENTER);

            //... Set window characteristics
            this.setTitle("Nano Editor");
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

            this.setJMenuBar(createMenubar());
            this.setContentPane(content);
            this.pack();
        }
        //==================================================== createMenubar
        // It's not uncommon to write a method that produces the menubar.
        // It gives a little better organization to the program
        // and doesn't mix content pane and menu construction, but
        // there is no real need to separate it.

        private JMenuBar createMenubar() {
            //... Menubar, menus, menu items.  Use indentation to show structure.
            JMenuBar menubar = new JMenuBar();     // declare and create new menu bar
                JMenu fileMenu = new JMenu("File");// declare and create new menu
                    menubar.add(fileMenu);         // add the menu to the menubar
                    fileMenu.add(m_openItem);      // add menu item to the menu
                    fileMenu.add(m_saveItem);      // add menu item to the menu
                    fileMenu.addSeparator();       // add separator line to menu
                    fileMenu.add(m_quitItem);

            //... Attach listeners.
            m_openItem.addActionListener(new OpenAction());
            m_saveItem.addActionListener(new SaveAction());
            m_quitItem.addActionListener(new QuitAction());

            return menubar;
        }

        //////////////////////////////////// inner listener class - OpenAction
        private class OpenAction implements ActionListener {
            public void actionPerformed(ActionEvent ae) {
                int retval = m_fileChooser.showOpenDialog(NanoEdit.this);
                if (retval == JFileChooser.APPROVE_OPTION) {
                    File textFile = m_fileChooser.getSelectedFile();
                    m_textTA.setText(readFile(textFile));
                }
            }
        }

        //////////////////////////////////// inner listener class - SaveAction
        private class SaveAction implements ActionListener {
            public void actionPerformed(ActionEvent ae) {
                int retval = m_fileChooser.showSaveDialog(NanoEdit.this);
                if (retval == JFileChooser.APPROVE_OPTION) {
                    File textFile = m_fileChooser.getSelectedFile();
                    writeFile(textFile, m_textTA.getText());
                }
            }
        }

        //////////////////////////////////// inner listener class - QuitAction
        private class QuitAction implements ActionListener {
            public void actionPerformed(ActionEvent e) {
                System.exit(0);      // Terminate the program
            }
        }

        //======================================================= readFile
        // This reads a file and returns the contents as a string,
        // with ends of lines uniformly marked with \n.
        // It would probably be faster to read directly with
        // BufferedReader, but I decided to test Scanner this
        // time.  Seems to work fine.
        private String readFile(File f) {
            StringBuilder text = new StringBuilder(4000);
            try {
                Scanner wordScanner = new Scanner(f);
                while (wordScanner.hasNextLine()) {
                    text.append(wordScanner.nextLine());
                    text.append('\n');
                }
            } catch (FileNotFoundException fnfex) {
                System.out.println("Impossible?\n" + fnfex);
            }

            return text.toString();
        }

        //====================================================== writeFile
        // Should be fixed to get the system end of line string.
        private void writeFile(File f, String txt) {
            try {
                //... Create writer for text files.
                BufferedWriter writer = new BufferedWriter(new FileWriter(f));
                writer.write(txt);
                writer.close();  // Close to unlock and flush to disk.

            } catch (IOException e) {
                System.err.println(e);
                System.exit(1);
            }
        }

        //=========================================================== main
        public static void main(String[] args) {
            JFrame window = new NanoEdit();
            window.setVisible(true);
        }
    }