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);
    }
}