我正在尝试制作一个小编辑器,我需要在某些特定关键字上突出显示语法。我希望你有耐心去看看这个。我想突出显示JTextPane中.txt文件中的单词。我需要一种方法来解决这个问题,希望你能指出我正确的方向。
我开始制作这个.txt文件:
if
else
echo
return
global
for
在这里阅读.txt文件并进行一些检查:
import javax.swing.text.DefaultStyledDocument;
import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
/**
* Created by Ilhami on 22-11-2014.
*/
public class SyntaxHighlighter {
final static Charset ENCODING = StandardCharsets.UTF_8;
private List<String> lines;
public SyntaxHighlighter() {
try {
lines = readFile("keywords.txt");
} catch(IOException e) {
e.getStackTrace();
}
}
public boolean keywordMatch(List<String> lines, String word) throws IOException {
boolean isTrue = false;
for(String item : lines) {
if(!item.isEmpty() && !word.isEmpty()) {
if(item.equals(word)) {
return isTrue = true;
}
}
}
return isTrue;
}
public List<String> readFile(String file) throws IOException {
Path path = Paths.get(file);
return Files.readAllLines(path, ENCODING);
}
public List<String> getLines() {
return this.lines;
}
}
我尝试了一些东西,但是当我在JTextPane中输入内容时,我一直遇到异常(是的,我使用Swing,不确定这是不是一个好主意)。
Exception in thread "AWT-EventQueue-0" java.lang.IllegalStateException: Attempt to mutate in notification
at javax.swing.text.AbstractDocument.writeLock(AbstractDocument.java:1338)
at javax.swing.text.AbstractDocument.replace(AbstractDocument.java:658)
at javax.swing.JTextPane.replaceSelection(JTextPane.java:192)
at javax.swing.JTextPane.replaceSelection(JTextPane.java:175)
at Editor$MyDocumentListener.appendToPane(Editor.java:61)
at Editor$MyDocumentListener.setFont(Editor.java:70)
at Editor$MyDocumentListener.insertUpdate(Editor.java:81)
at javax.swing.text.AbstractDocument.fireInsertUpdate(AbstractDocument.java:201)
at javax.swing.text.AbstractDocument.handleInsertString(AbstractDocument.java:748)
at javax.swing.text.AbstractDocument.insertString(AbstractDocument.java:707)
at javax.swing.text.AbstractDocument.replace(AbstractDocument.java:669)
at javax.swing.JTextPane.replaceSelection(JTextPane.java:192)
at javax.swing.JTextPane.replaceSelection(JTextPane.java:175)
at javax.swing.text.DefaultEditorKit$DefaultKeyTypedAction.actionPerformed(DefaultEditorKit.java:884)
at javax.swing.SwingUtilities.notifyAction(SwingUtilities.java:1663)
at javax.swing.JComponent.processKeyBinding(JComponent.java:2879)
at javax.swing.JComponent.processKeyBindings(JComponent.java:2926)
at javax.swing.JComponent.processKeyEvent(JComponent.java:2842)
at java.awt.Component.processEvent(Component.java:6304)
at java.awt.Container.processEvent(Container.java:2234)
at java.awt.Component.dispatchEventImpl(Component.java:4883)
at java.awt.Container.dispatchEventImpl(Container.java:2292)
at java.awt.Component.dispatchEvent(Component.java:4705)
at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1954)
at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:806)
at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:1074)
at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:945)
at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:771)
at java.awt.Component.dispatchEventImpl(Component.java:4754)
at java.awt.Container.dispatchEventImpl(Container.java:2292)
at java.awt.Window.dispatchEventImpl(Window.java:2739)
at java.awt.Component.dispatchEvent(Component.java:4705)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:746)
at java.awt.EventQueue.access$400(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:697)
at java.awt.EventQueue$3.run(EventQueue.java:691)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:86)
at java.awt.EventQueue$4.run(EventQueue.java:719)
at java.awt.EventQueue$4.run(EventQueue.java:717)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:716)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
这是我的编辑类,我收到错误:
import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.*;
import java.awt.*;
import java.io.IOException;
import java.util.List;
/**
* Created by Ilhami on 22-11-2014.
*/
public class Editor {
private JFrame editor;
public JTextPane editorPane;
private SyntaxHighlighter syntaxHighlighter;
private List<String> lines;
private JScrollPane scrollPane;
public Editor() {
editor = new JFrame("Editor");
editorPane = new JTextPane();
editor.setLayout(new BorderLayout());
editor.setLocationRelativeTo(null);
scrollPane = new JScrollPane(editorPane);
syntaxHighlighter = new SyntaxHighlighter();
lines = syntaxHighlighter.getLines();
editorPane.getDocument().addDocumentListener(new MyDocumentListener());
}
public void showEditor() {
editor.add(scrollPane);
editor.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
editor.setPreferredSize(new Dimension(500, 500));
editor.setSize(new Dimension(500, 500));
editor.setVisible(true);
}
class MyDocumentListener implements DocumentListener {
private StyledDocument document;
Style style, style2;
public MyDocumentListener() {
document = editorPane.getStyledDocument();
editorPane.setDocument(document);
}
private void appendToPane(JTextPane tp, String msg, Color c, int len)
{
StyleContext sc = StyleContext.getDefaultStyleContext();
AttributeSet aset = sc.addAttribute(SimpleAttributeSet.EMPTY, StyleConstants.Foreground, c);
aset = sc.addAttribute(aset, StyleConstants.FontFamily, "Lucida Console");
aset = sc.addAttribute(aset, StyleConstants.Alignment, StyleConstants.ALIGN_JUSTIFIED);
len = tp.getDocument().getLength();
tp.setCaretPosition(len);
tp.setCharacterAttributes(aset, false);
tp.replaceSelection(msg);
}
public void setFont() {
try {
for (String string : editorPane.getText().split("\\s+")) {
if (syntaxHighlighter.keywordMatch(lines, string)) {
appendToPane(editorPane, string, new Color(12, 146, 20), 40);
} else {
appendToPane(editorPane, string, new Color(22, 22, 22), 40);
}
}
} catch (IOException ex) {
ex.getStackTrace();
}
}
@Override
public void insertUpdate(DocumentEvent e) {
setFont();
}
@Override
public void removeUpdate(DocumentEvent e) {
setFont();
}
@Override
public void changedUpdate(DocumentEvent e) {
//System.out.println("Hej");
}
}
}
最后但并非最不重要的是我的Main.java文件:
public class Main {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
Editor editor = new Editor();
editor.showEditor();
}
});
}
}