打开文件时颜色变化不起作用

时间:2015-08-09 18:41:54

标签: java swing file jtextpane foreground

我正在处理记事本程序,并且我在用户输入的位置,如果键入某个单词(例如:public,void,private,protected,static),颜色会变为深红色颜色(如在eclipse中),但如果用户打开文件,它不会改变颜色,即使用户输入,也没有任何反应。它只适用于输入" new"文献。这是我项目的简短版本,包含了所有必要的内容:

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;

import javax.swing.*;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultStyledDocument;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;

public class Test {
    static JTabbedPane tabbedPane;
    static JTextPane txt;

    private static int findLastNonWordChar(String text, int index) {
        while (--index >= 0) {
            if (String.valueOf(text.charAt(index)).matches("\\W")) {
                break;
            }
        }
        return index;
    }

    private static int findFirstNonWordChar(String text, int index) {
        while (index < text.length()) {
            if (String.valueOf(text.charAt(index)).matches("\\W")) {
                break;
            }
            index++;
        }
        return index;
    }

    private static void makeBold(SimpleAttributeSet sas) {
        sas.addAttribute(StyleConstants.CharacterConstants.Bold, Boolean.TRUE);
    }

    private static void makeUnBold(SimpleAttributeSet sas) {
        sas.addAttribute(StyleConstants.CharacterConstants.Bold, Boolean.FALSE);
    }

    private static JTextPane createEmptyDocument() {
        final StyleContext cont = StyleContext.getDefaultStyleContext();
        final AttributeSet attrRed = cont.addAttribute(cont.getEmptySet(), StyleConstants.Foreground, new Color(127, 0, 85));
        final AttributeSet attrBlack = cont.addAttribute(cont.getEmptySet(), StyleConstants.Foreground, Color.BLACK);
        SimpleAttributeSet sas = new SimpleAttributeSet();

        DefaultStyledDocument document = new DefaultStyledDocument() {
            public void insertString(int offset, String str, AttributeSet a) throws BadLocationException {
                super.insertString(offset, str, a);

                String text = getText(0, getLength());
                int before = findLastNonWordChar(text, offset);
                if (before < 0) before = 0;
                int after = findFirstNonWordChar(text, offset + str.length());
                int wordL = before;
                int wordR = before;

                while (wordR <= after) {
                    if (wordR == after || String.valueOf(text.charAt(wordR)).matches("\\W")) {
                        if (text.substring(wordL, wordR).matches("(\\W)*(public|static|void|main|private|protected)")) {
                            setCharacterAttributes(wordL, wordR - wordL, attrRed, false);
                            makeBold(sas);
                            setCharacterAttributes(wordL, wordR - wordL, sas, false);
                        } else {
                            setCharacterAttributes(wordL, wordR - wordL, attrBlack, false);
                            makeUnBold(sas);
                            setCharacterAttributes(wordL, wordR - wordL, sas, false);
                        }
                        wordL = wordR;
                    }
                    wordR++;
                }
            }

            public void remove(int offs, int len) throws BadLocationException {
                super.remove(offs, len);

                String text = getText(0, getLength());
                int before = findLastNonWordChar(text, offs);
                if (before < 0) before = 0;
                int after = findFirstNonWordChar(text, offs);

                if (text.substring(before, after).matches("(\\W)*(public|static|void|private|protected)")) {
                    makeBold(sas);
                    setCharacterAttributes(before, after - before, attrRed, false);
                    setCharacterAttributes(before, after - before, sas, false);
                } else {
                    makeUnBold(sas);
                    setCharacterAttributes(before, after - before, attrBlack, false);
                    setCharacterAttributes(before, after - before, sas, false);
                }
            }
        };
        return new JTextPane(document);
    }

    private static void readInFile(File file, JTextPane txt) {
        try {
            FileReader r = new FileReader(file);
            txt.read(r, null);
            r.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static void createNewDocument(File file, JTabbedPane tabbedPane) {
        txt = createEmptyDocument();

        String fileName;
        String theFile;

        if (file == null) {
            fileName = "Untitled";
            theFile = "Untitled";
        } else {
            fileName = file.getName().toString();
            theFile = file.toString();

            readInFile(file, txt);
        }

        txt.setFont(new Font("Monospaced", Font.PLAIN, 14));

        JScrollPane scrollPane = new JScrollPane(txt);

        JPanel panel = new JPanel();
        panel.setLayout(new BorderLayout());
        panel.add(scrollPane);
        panel.setPreferredSize(new Dimension(800, 600));

        tabbedPane.addTab(fileName, null, panel, theFile);
        tabbedPane.setSelectedIndex(tabbedPane.getTabCount() - 1);

        tabbedPane.setFocusable(false);
        txt.grabFocus();
    }

    private static JTabbedPane setupForTabs(JFrame frame) {
        JPanel topPanel = new JPanel();
        topPanel.setLayout(new BorderLayout());

        tabbedPane = new JTabbedPane();

        topPanel.add(tabbedPane);
        frame.add(topPanel, BorderLayout.CENTER);

        return tabbedPane;
    }

    static Action New = new AbstractAction("New") {
        @Override
        public void actionPerformed(ActionEvent e) {
            createNewDocument(null, tabbedPane);
        }
    };

    static Action Open = new AbstractAction("Open") {
        @Override
        public void actionPerformed(ActionEvent e) {
            JFileChooser chooser = new JFileChooser();
            int result = chooser.showOpenDialog(tabbedPane);

            if (result == JFileChooser.APPROVE_OPTION) {
                File file = chooser.getSelectedFile();
                createNewDocument(file, tabbedPane);
            }
        }
    };

    private static JMenuBar createMenuBar(JTabbedPane tabbedPane) {
        JMenuBar menuBar = new JMenuBar();
        JMenu file = new JMenu("File");

        JMenuItem newDoc = new JMenuItem();
        JMenuItem open = new JMenuItem();

        New.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_N, KeyEvent.CTRL_DOWN_MASK));
        newDoc.setAction(New);

        Open.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_O, KeyEvent.CTRL_DOWN_MASK));
        open.setAction(Open);

        menuBar.add(file);

        file.add(newDoc);
        file.add(open);

        return menuBar;
    }

    private static void createAndShowGui() {
        JFrame frame = new JFrame("Notepad");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(800, 600);

        tabbedPane = setupForTabs(frame);

        createNewDocument(null, tabbedPane);

        JMenuBar menuBar = createMenuBar(tabbedPane);
        frame.setJMenuBar(menuBar);

        frame.pack();

        Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
        frame.setLocation(dim.width/2-frame.getSize().width/2, dim.height/2-frame.getSize().height/2);

        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                UIManager.put("swing.boldmetal", Boolean.FALSE);
                createAndShowGui();
            }
        });
    }
}

即使打开文件,我也需要更改颜色。现在我没有办法在文件打开后搜索单词,但是我担心用户在打开的文档中输入颜色会有变化。如果有人能给我一个关于如何搜索单词并在文件打开后更改颜色的提示,那也会很棒。 :)

1 个答案:

答案 0 :(得分:2)

read(...)方法在读取文本文件时会创建一个新的PlainDocument

而不是创建一个匿名内部类,为您的Document创建一个自定义类,可能是“ColoredDocument”。

然后您可以使用以下代码:

EditorKit editorKit = new StyledEditorKit()
{
    public Document createDefaultDocument()
    {
        return new ColoredDocument();
    }
};

JTextPane textPane = new JTextPane();
textPane.setEditorKit( editorKit );

FileReader fr = new FileReader( ... );
BufferedReader br = new BufferedReader( fr );
textPane.read( br, null );