我想将颜色应用于java关键字。当我打开一个文件时,它会在通知异常中提升尝试突变,程序没有完全显示,颜色也没有应用。 这是我的代码,
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FileDialog;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JInternalFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Document;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
import javax.swing.text.StyledDocument;
public class JavaKeywordsColor extends javax.swing.JFrame {
private JTextPane textPane;
private Color color = Color.BLACK;
private int i = 0;
private JPanel noWrapPanel;
private JScrollPane scrollpane;
private JTextField status;
private StyledDocument d;
private String[] keywords = {"import ", "class ", "int ", "public ", "private"};
public JavaKeywordsColor() {
initComponents();
}
private void initComponents() {
tp = new javax.swing.JTabbedPane();
jMenuBar1 = new javax.swing.JMenuBar();
jMenu1 = new javax.swing.JMenu();
Open = new javax.swing.JMenuItem();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
jMenu1.setText("File");
Open.setText("Open");
Open.addActionListener(new java.awt.event.ActionListener() {
@Override
public void actionPerformed(java.awt.event.ActionEvent evt) {
OpenActionPerformed(evt);
}
});
jMenu1.add(Open);
jMenuBar1.add(jMenu1);
setJMenuBar(jMenuBar1);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(tp, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 400, Short.MAX_VALUE));
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(tp, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 279, Short.MAX_VALUE));
pack();
}// </editor-fold>
private void OpenActionPerformed(java.awt.event.ActionEvent evt) {
FileDialog fd = new FileDialog(JavaKeywordsColor.this, "Select File", FileDialog.LOAD);
fd.setVisible(true);
String title;
String sts;
if (fd.getFile() != null) {
sts = fd.getDirectory() + fd.getFile();
title = fd.getFile();
BufferedReader br = null;
StringBuffer str = new StringBuffer("");
try {
br = new BufferedReader(new FileReader(sts));
String line;
try {
while ((line = br.readLine()) != null) {
str.append(line + "\n");
}
} catch (IOException ex) {
Logger.getLogger(JavaKeywordsColor.class.getName()).log(Level.SEVERE, null, ex);
}
} catch (FileNotFoundException ex) {
Logger.getLogger(JavaKeywordsColor.class.getName()).log(Level.SEVERE, null, ex);
}
String t = str.toString();
final JInternalFrame internalFrame = new JInternalFrame("", true, true);
textPane = new JTextPane();
// textPane.setEditorKit(new WrapEditorKit());
d = textPane.getStyledDocument();
d.addDocumentListener(new DocumentListener() {
@Override
public void insertUpdate(DocumentEvent de) {
jColorActionPerformed(de);
}
@Override
public void removeUpdate(DocumentEvent de) {
jColorActionPerformed(de);
}
@Override
public void changedUpdate(DocumentEvent de) {
jColorActionPerformed(de);
}
});
Document doc = textPane.getDocument();
textPane.setFont(new java.awt.Font("Miriam Fixed", 0, 13));
internalFrame.add(textPane);
i += 1;
internalFrame.setName("Doc" + i);
this.add(new javax.swing.JScrollPane(textPane));
noWrapPanel = new JPanel(new BorderLayout());
noWrapPanel.add(textPane);
scrollpane = new JScrollPane(noWrapPanel);
internalFrame.add(scrollpane);
internalFrame.setTitle(title);
tp.add(internalFrame);
tp.setSelectedIndex(i - 1);
internalFrame.setVisible(true);
textPane.setText(t);
}
}
private void jColorActionPerformed(DocumentEvent evt) {
replace(textPane);
}
public void replace(javax.swing.JTextPane jp) {
int cur = jp.getCaretPosition();
StyleContext sc = StyleContext.getDefaultStyleContext();
AttributeSet aset = sc.addAttribute(SimpleAttributeSet.EMPTY, StyleConstants.Foreground, Color.BLUE);
for (int ii = 0; ii < keywords.length; ii++) {
int fromIndex = 0;
String msg = keywords[ii];
int nol = 0; //number of lines upto keyword
int len = 1;
while (len != -1) {
len = jp.getText().indexOf(msg, fromIndex);
jp.setSelectedTextColor(Color.RED);
if (len != -1) {
try {
nol = countLine(jp.getText(0, len + 1));
} catch (BadLocationException ex) {
break;
}
fromIndex = len + msg.length();
System.out.println("len = " + len + " nol=" + nol);
len -= nol;
jp.select(len, len + msg.length());
System.out.println("Selected Text = " + jp.getSelectedText());
jp.replaceSelection("");
jp.setCaretPosition(len);
jp.setCharacterAttributes(aset, false);
jp.replaceSelection(msg);
}
}
}
aset = sc.addAttribute(SimpleAttributeSet.EMPTY, StyleConstants.Foreground, Color.BLACK);
jp.setCharacterAttributes(aset, false);
jp.setCaretPosition(cur);
}
public int countLine(String str) {
int n = 0;
for (int ii = 0; ii < str.length(); ii++) {
if (str.charAt(ii) == '\n') {
n++;
}
}
return n;
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new JavaKeywordsColor().setVisible(true);
}
});
}
private javax.swing.JMenuItem Open;
private javax.swing.JMenu jMenu1;
private javax.swing.JMenuBar jMenuBar1;
private javax.swing.JTabbedPane tp;
}
答案 0 :(得分:2)
异常的消息非常清楚。在侦听器通知正在进行时,不允许您改变文档。原因很清楚:修改会触发新的通知,而在像你这样的程序中,会引发StackOverflowError
或无限循环。它还暗示,在其他听众尚未了解旧的修改时,可能会报告更新的修改。
您必须将修改安排到以后的时间,并保护您的代码不会对您自己的修改做出反应。将更新安排到以后的时间也可以帮助用户快速键入时的性能,因为您不想在每个插入的字符上解析整个文档。
因此,您应该替换添加DocumentListener
d.addDocumentListener(new DocumentListener() {
@Override
public void insertUpdate(DocumentEvent de) {
jColorActionPerformed(de);
}
@Override
public void removeUpdate(DocumentEvent de) {
jColorActionPerformed(de);
}
@Override
public void changedUpdate(DocumentEvent de) {
jColorActionPerformed(de);
}
});
这样的事情:
final class UpdateTrigger implements DocumentListener, ActionListener {
final Timer timer=new Timer(150, this);
boolean enabled=true;
UpdateTrigger() {
timer.setRepeats(false);
}
public void insertUpdate(DocumentEvent e) {
if(enabled) timer.restart();
}
public void removeUpdate(DocumentEvent e) {
if(enabled) timer.restart();
}
public void changedUpdate(DocumentEvent e) {
if(enabled) timer.restart();
}
public void actionPerformed(ActionEvent e) {
enabled=false;
try { jColorActionPerformed(null); }
finally { enabled=true; }
}
}
d.addDocumentListener(new UpdateTrigger());
您可能会发现您的代码有更多问题超出了您的问题范围。顺便说一句,只是突出显示关键字对于正确的语法突出显示是不够的。你需要一个能理解语法结构的解析器,特别是注释和String
文字,即使是最小的突出显示。
您应该学习Chapter 3 of the The Java® Language Specification以获得完整的图片。