尝试将undos添加到JTextPane时的java.lang.NullPointerException

时间:2014-07-04 17:21:24

标签: java jtextpane undo undo-redo

我使用this website尝试将undos和redos添加到我的JTextPane,但是我收到此错误:
Exception in thread "main" java.lang.NullPointerException at guiWithSwing.TextEditor.main(TextEditor.java:137)
在第137行,它显示menuEdit.add(menuItemUndo);,这是添加"撤消"按钮到菜单。我认为错误意味着该按钮没有属性,或者缺少某些东西,但我不知道它是什么,因为它有一个动作和文本。

package guiWithSwing;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Event;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.UndoableEditEvent;
import javax.swing.event.UndoableEditListener;
import javax.swing.filechooser.FileFilter;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.StyledDocument;
import javax.swing.undo.CannotRedoException;
import javax.swing.undo.CannotUndoException;
import javax.swing.undo.UndoManager;

@SuppressWarnings("serial")
public class TextEditor extends JPanel {

static Container pane;
static Container paneText;
static BasicFrame frame;
static JTextPane textArea;
static JScrollPane areaScrollPane;
static FileFilter textFile;
static FileFilter htmlFile;
static FileFilter javaFile;
static JLabel label1;
static {
    try {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (InstantiationException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (UnsupportedLookAndFeelException e) {
        e.printStackTrace();
    }
}
static JFileChooser save = new JFileChooser();
static JFileChooser open = new JFileChooser();
static JMenuBar menuBar;
static JMenu menuFile, menuEdit;
static JMenuItem menuItemNew, menuItemSave, menuItemOpen;
static JMenuItem menuItemUndo, menuItemRedo;
static UndoManager undoManager;
static String newLine = "\n";
static Document editorPaneDocument;
static UndoHandler undoHandler;
static UndoAction undoAction;
static RedoAction redoAction;

public static void main(String[] args) throws ClassNotFoundException,
        InstantiationException, IllegalAccessException,
        UnsupportedLookAndFeelException, IOException {
    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    frame = BasicFrame.getInstance();
    pane = frame.getContentPane();
    paneText = new JPanel();
    textArea = new JTextPane();
    label1 = new JLabel("          ");
    menuBar = new JMenuBar();
    menuFile = new JMenu("File");
    undoManager = new UndoManager();
    menuFile.setMnemonic(KeyEvent.VK_F);
    menuFile.getAccessibleContext().setAccessibleDescription("File");
    menuBar.add(menuFile);
    menuItemNew = new JMenuItem(
            "New",
            new ImageIcon("Images/new.png"));
    menuItemNew.setMnemonic(KeyEvent.VK_N);
    menuFile.add(menuItemNew);
    menuItemOpen = new JMenuItem(
            "Open",
            new ImageIcon("Images/folder.png"));
    menuItemOpen.setMnemonic(KeyEvent.VK_O);
    menuFile.add(menuItemOpen);
    menuItemSave = new JMenuItem(
            "Save",
            new ImageIcon("Images/save.png"));
    menuItemSave.setMnemonic(KeyEvent.VK_S);
    menuFile.add(menuItemSave);
    areaScrollPane = new JScrollPane(textArea);
    areaScrollPane
            .setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
    areaScrollPane.setPreferredSize(new Dimension(250, 250));
    pane.setLayout(new BorderLayout());
    textFile = new FileNameExtensionFilter("Text File (.txt)", "txt");
    htmlFile = new FileNameExtensionFilter(
            "HTML Document (.html, .htm, .shtml, .shtm, .xhtml, .hta)",
            "html", "htm", "shtml", "shtm", "xhtml", "hta");
    javaFile = new FileNameExtensionFilter("Java Source Code (.java)",
            "java");
    save.addChoosableFileFilter(textFile);
    save.addChoosableFileFilter(htmlFile);
    save.addChoosableFileFilter(javaFile);
    save.setAcceptAllFileFilterUsed(true);
    save.setFileFilter(textFile);
    open.addChoosableFileFilter(textFile);
    open.addChoosableFileFilter(htmlFile);
    open.addChoosableFileFilter(javaFile);
    open.setAcceptAllFileFilterUsed(true);
    open.setFileFilter(textFile);
    menuItemUndo = new JMenuItem(undoAction);
    menuItemRedo = new JMenuItem(redoAction);
    menuEdit.add(menuItemUndo);
    menuEdit.add(menuItemRedo);
    pane.add(areaScrollPane, BorderLayout.CENTER);
    pane.add(paneText, BorderLayout.SOUTH);
    paneText.setLayout(new BoxLayout(paneText, BoxLayout.Y_AXIS));
    paneText.add(label1);
    editorPaneDocument = textArea.getDocument();
    editorPaneDocument.addUndoableEditListener(undoHandler);
    KeyStroke undoKeystroke = KeyStroke.getKeyStroke(KeyEvent.VK_Z,
            Event.META_MASK);
    KeyStroke redoKeystroke = KeyStroke.getKeyStroke(KeyEvent.VK_Y,
            Event.META_MASK);
    undoAction = new UndoAction();
    textArea.getInputMap().put(undoKeystroke, "undoKeystroke");
    textArea.getActionMap().put("undoKeystroke", undoAction);
    redoAction = new RedoAction();
    textArea.getInputMap().put(redoKeystroke, "redoKeystroke");
    textArea.getActionMap().put("redoKeystroke", redoAction);

    menuItemNew.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            textArea.setText(null);
        }

    });

    menuItemSave.addActionListener(new ActionListener() {

        public void actionPerformed(ActionEvent e) {
            save.setFileHidingEnabled(false);
            save.setSelectedFile(new File("new 1"));
            save.setMultiSelectionEnabled(true);
            save.setCurrentDirectory(new File(System
                    .getProperty("user.home") + "/Desktop"));
            save.setDialogTitle("Where Would You Like to Save This File?");
            save.setDragEnabled(true);
            int actionDialog = save.showSaveDialog(null);
            if (actionDialog != JFileChooser.APPROVE_OPTION) {
                return;
            } else {
                log("Done!", true);
                String name = save.getSelectedFile().getAbsolutePath();
                if (!name.endsWith(".txt")
                        && save.getFileFilter() == textFile) {
                    name += ".txt";
                } else if (!name.endsWith(".java")
                        && save.getFileFilter() == javaFile) {
                    name += ".java";
                } else if ((!name.endsWith(".html") && save.getFileFilter() == htmlFile)
                        || (!name.endsWith(".htm") && save.getFileFilter() == htmlFile)
                        || (!name.endsWith(".shtml") && save
                                .getFileFilter() == htmlFile)
                        || (!name.endsWith(".shtm") && save.getFileFilter() == htmlFile)
                        || (!name.endsWith(".xhtml") && save
                                .getFileFilter() == htmlFile)
                        || (!name.endsWith(".hta") && save.getFileFilter() == htmlFile)) {
                    name += ".html";
                }
                BufferedWriter outFile = null;
                try {
                    outFile = new BufferedWriter(new FileWriter(name));
                    textArea.write(outFile);

                } catch (IOException ioe) {
                    ioe.printStackTrace();
                } finally {
                    if (outFile != null) {
                        try {
                            outFile.close();
                        } catch (IOException ioee) {
                        }
                    }
                }
            }

        }
    });

    menuItemOpen.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            open.setFileHidingEnabled(false);
            open.setMultiSelectionEnabled(true);
            open.setCurrentDirectory(new File(System
                    .getProperty("user.home") + "/Desktop"));
            open.setDialogTitle("Which File Would You Like to Open?");
            open.setDragEnabled(true);
            int actionDialog = open.showOpenDialog(null);
            if (actionDialog != JFileChooser.APPROVE_OPTION) {
                return;
            } else {
                log("Done!", true);
                String name = open.getSelectedFile().getAbsolutePath();
                try {
                    BufferedReader in = new BufferedReader(new FileReader(
                            name));
                    String line;
                    textArea.setText(null);
                    while ((line = in.readLine()) != null) {
                        appendString(line);
                        appendString(newLine);
                    }
                    in.close();

                } catch (IOException ioe) {
                    ioe.fillInStackTrace();
                } catch (BadLocationException e1) {
                }
            }

        }
    });

    frame.setSize(500, 320);
    frame.setJMenuBar(menuBar);
    frame.setVisible(true);
}

static public void appendString(String str) throws BadLocationException {
    StyledDocument document = (StyledDocument) textArea.getDocument();
    document.insertString(document.getLength(), str, null);
}

static private void log(String msg, boolean remove) {
    label1 = new JLabel(msg);
    if (remove) {
        paneText.removeAll();
    }
    paneText.add(label1);
    paneText.validate();
    pane.validate();
    new Thread() {
        public void run() {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException ie) {
                ie.printStackTrace();
            }
            paneText.removeAll();
            label1 = new JLabel("          ");
            paneText.add(label1);
            paneText.validate();
            pane.validate();
        }
    }.start();
}

class UndoHandler implements UndoableEditListener {

    public void undoableEditHappened(UndoableEditEvent e) {
        undoManager.addEdit(e.getEdit());
        undoAction.update();
        redoAction.update();
    }
}

static class UndoAction extends AbstractAction {
    public UndoAction() {
        super("Undo");
        setEnabled(false);
    }

    public void actionPerformed(ActionEvent e) {
        try {
            undoManager.undo();
        } catch (CannotUndoException ex) {
            // TODO deal with this
            // ex.printStackTrace();
        }
        update();
        redoAction.update();
    }

    protected void update() {
        if (undoManager.canUndo()) {
            setEnabled(true);
            putValue(Action.NAME, undoManager.getUndoPresentationName());
        } else {
            setEnabled(false);
            putValue(Action.NAME, "Undo");
        }
    }
}

static class RedoAction extends AbstractAction {
    public RedoAction() {
        super("Redo");
        setEnabled(false);
    }

    public void actionPerformed(ActionEvent e) {
        try {
            undoManager.redo();
        } catch (CannotRedoException ex) {
            // TODO deal with this
            ex.printStackTrace();
        }
        update();
        undoAction.update();
    }

    protected void update() {
        if (undoManager.canRedo()) {
            setEnabled(true);
            putValue(Action.NAME, undoManager.getRedoPresentationName());
        } else {
            setEnabled(false);
                putValue(Action.NAME, "Redo");
            }
        }
    }
}

3 个答案:

答案 0 :(得分:2)

您尚未实例化menuEdit,只是声明了它。在使用之前,您需要在此处添加此行:

menuEdit = new JMenu("Edit.");

当你得到NullPointerException它很容易被方法/函数的参数吸引作为问题的根源。重要的是要记住检查所有被引用的行上的对象实际上是否有一个实例,否则你会发现自己处于疯狂的追逐中!

答案 1 :(得分:1)

您永远不会在整个代码中实例化menuEdit。它是空的,你得到的是NullPointerException。将其初始化为:

menuEdit = new JMenu("Don't Dump Full Code on SO!");

答案 2 :(得分:1)

当你得到java.lang.NullPointerException时意味着一个对象没有被初始化, 在您的情况下,对象menuEdit未初始化,因此您无法使用它。 您可以将其初始化为:

 menuEdit = new JMenu("Any Thing");
祝你好运。