# Java: Example - Simple Editor

This very simple editor illustrates several things: the use of menus, JFileChooser, and Actions.

Actions. This simple text editor uses a `JTextArea` with Actions to implement the menu items. Actions are a good way to implement ActionListeners.

- Actions can be used with most buttons, including toolbox buttons and menu items, text fields, etc.
- They can be shared so that all components which do the same thing can share an Action.
- Actions can be dis-/enabled, and they will then dis-/enable all corresponding controls.
- They can be used to set icons, tooltip text, accelerator and mnemonic keys.

      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
    // File   : editor/NutPad.java -- A very simple text editor
    // Purpose: Illustrates use of AbstractActions for menus.
    //          It only uses a few Action features.  Many more are available.
    //          This program uses the obscure "read" and "write"
    //               text component methods.
    // Author : Fred Swartz - 2006-12-14 - Placed in public domain.

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

    ///////////////////////////////////////////////////////////////////////// NutPad
    public class NutPad extends JFrame {
        //... Components
        private JTextArea    _editArea;
        private JFileChooser _fileChooser = new JFileChooser();

        //... Create actions for menu items, buttons, ...
        private Action _openAction = new OpenAction();
        private Action _saveAction = new SaveAction();
        private Action _exitAction = new ExitAction();

        //===================================================================== main
        public static void main(String[] args) {
            new NutPad();
        }

        //============================================================== constructor
        public NutPad() {
            //... Create scrollable text area.
            _editArea = new JTextArea(15, 80);
            _editArea.setBorder(BorderFactory.createEmptyBorder(2,2,2,2));
            _editArea.setFont(new Font("monospaced", Font.PLAIN, 14));
            JScrollPane scrollingText = new JScrollPane(_editArea);

            //-- Create a content pane, set layout, add component.
            JPanel content = new JPanel();
            content.setLayout(new BorderLayout());
            content.add(scrollingText, BorderLayout.CENTER);

            //... Create menubar
            JMenuBar menuBar = new JMenuBar();
            JMenu fileMenu = menuBar.add(new JMenu("File"));
            fileMenu.setMnemonic('F');
            fileMenu.add(_openAction);       // Note use of actions, not text.
            fileMenu.add(_saveAction);
            fileMenu.addSeparator();
            fileMenu.add(_exitAction);

            //... Set window content and menu.
            setContentPane(content);
            setJMenuBar(menuBar);

            //... Set other window characteristics.
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            setTitle("NutPad");
            pack();
            setLocationRelativeTo(null);
            setVisible(true);
        }

        ////////////////////////////////////////////////// inner class OpenAction
        class OpenAction extends AbstractAction {
            //============================================= constructor
            public OpenAction() {
                super("Open...");
                putValue(MNEMONIC_KEY, new Integer('O'));
            }

            //========================================= actionPerformed
            public void actionPerformed(ActionEvent e) {
                int retval = _fileChooser.showOpenDialog(NutPad.this);
                if (retval == JFileChooser.APPROVE_OPTION) {
                    File f = _fileChooser.getSelectedFile();
                    try {
                        FileReader reader = new FileReader(f);
                        _editArea.read(reader, "");  // Use TextComponent read
                    } catch (IOException ioex) {
                        System.out.println(e);
                        System.exit(1);
                    }
                }
            }
        }

        //////////////////////////////////////////////////// inner class SaveAction
        class SaveAction extends AbstractAction {
            //============================================= constructor
            SaveAction() {
                super("Save...");
                putValue(MNEMONIC_KEY, new Integer('S'));
            }

            //========================================= actionPerformed
            public void actionPerformed(ActionEvent e) {
                int retval = _fileChooser.showSaveDialog(NutPad.this);
                if (retval == JFileChooser.APPROVE_OPTION) {
                    File f = _fileChooser.getSelectedFile();
                    try {
                        FileWriter writer = new FileWriter(f);
                        _editArea.write(writer);  // Use TextComponent write
                    } catch (IOException ioex) {
                        JOptionPane.showMessageDialog(NutPad.this, ioex);
                        System.exit(1);
                    }
                }
            }
        }

        ///////////////////////////////////////////////////// inner class ExitAction
        class ExitAction extends AbstractAction {

            //============================================= constructor
            public ExitAction() {
                super("Exit");
                putValue(MNEMONIC_KEY, new Integer('X'));
            }

            //========================================= actionPerformed
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        }
    }