gpt4 book ai didi

java - 当我在 JTextpane 中打开文件时自动为 Java 关键字着色

转载 作者:行者123 更新时间:2023-12-02 05:35:19 25 4
gpt4 key购买 nike

我想将颜色应用于 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;
}

最佳答案

异常消息已经很清楚了。当监听器通知正在进行时,您不得更改文档。原因很明显:修改会触发新的通知,并且在像您这样的程序中,会引发 StackOverflowError 或无限循环。这还意味着,在其他听众尚未了解旧修改的情况下,可能会报告更新的修改。

您必须将修改安排在以后的时间,并防止您的代码对您自己的修改使用react。将更新安排在稍后的时间也有助于了解用户快速键入时的​​性能,因为您不想在每个插入的字符上解析整个文档。

所以你应该替换添加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以获得完整的图片。

关于java - 当我在 JTextpane 中打开文件时自动为 Java 关键字着色,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25031624/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com