尝试向 JTextPane 添加撤消时出现 java.lang.NullPointerException

标签 java jtextpane undo undo-redo

我用了this website尝试将撤消和重做添加到我的 JTextPane,但出现此错误:
guiWithSwing.TextEditor.main(TextEditor.java:137) 线程“main”中出现 java.lang.NullPointerException 异常
在第 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");
            }
        }
    }
}

最佳答案

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

menuEdit = new JMenu("Edit.");

当您收到 NullPointerException 时,很容易将方法/函数的参数视为问题的根源。重要的是要记住检查所引用的行上的所有对象实际上都有一个实例,否则您会发现自己陷入了白费力气!

关于尝试向 JTextPane 添加撤消时出现 java.lang.NullPointerException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24578741/

相关文章:

java - 如何使 Map 可选(无论其每个可选值是否存在)

vim - 跳过Vim中的撤消步骤

java - 获取 JTextPane 中的段落样式

java - StyleConstants.setBold 中 boolean 参数的含义是什么?

java - Artifact 显示了 JTextPane 背景颜色的自定义颜色的使用

git - 如何清理 Rebase 弄乱的 Git 提交

vim - 为什么当我尝试撤消时 vim 总是说 'Already at oldest change'?

java - 为什么 8099.99975f != 8100f?

java - Grails - 导入 jsch 结果为 "package com.jcraft.jsch does not exist"

java - 带有列表的树上的 BFS