Изменение цвета не работает, когда я открываю файл

Я работаю над программой блокнота, и у меня есть ее, где, когда пользователь печатает, если набрано определенное слово (например, public, void, private, protected, static), цвет меняется на темно-красный (как в eclipse), но если пользователь открывает файл, он не меняет цвет и даже при вводе пользователем ничего не происходит. Работает только при вводе в "новый" документ. Это краткая версия моего проекта всего, что необходимо:

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 ответ

read(...) метод создает новый PlainDocument когда он читает текстовый файл.

Вместо создания анонимного внутреннего класса создайте пользовательский класс для вашего документа, возможно, "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 );
Другие вопросы по тегам