java - 更新单词的属性集时,它会在 JTextPane 中抛出 IllegalStateException

标签 java swing jtextpane illegalstateexception

在我的程序中,我有文本 Pane 。其中,当我在文本 Pane 中输入文本时,它仅将 java 关键字的颜色更改为蓝色。我的程序正确选择了单词,但是当我尝试设置单词的属性时,它抛出 IllegalStateException 我该如何解决它?

package event;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextPane;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;

import javax.swing.text.StyledDocument;

public class SourceCodeWriter implements DocumentListener, KeyListener{
  JTextPane pane;
  public static JPanel contentPane;
  public static JFrame frame;
  int poistion = 0;
  int start = 0;
  int set = 0;
  int lock = 0;
  int count = 0;
  int endPos = 0;
  char key;
  String word =  "";
  List<String> keywordList = new ArrayList<String>();
  public SourceCodeWriter() {
  }
  public JPanel createContentPane() {
    JPanel panel = new JPanel(new BorderLayout());
    pane = new JTextPane();

    pane.addKeyListener(this);
    pane.getStyledDocument().addDocumentListener(this);
    pane.setFont(new Font("Lucida Console",Font.BOLD,20));

    panel.add(pane);
    return panel;
  }
  @Override
  public void changedUpdate(DocumentEvent e) {

  }
  @Override
  public void insertUpdate(DocumentEvent e) {
    if(key != '\n') {
      word = word + key;
    }
    if(key == ' ' || (int)key == 10) {
      set = 0;
      lock = 0;
      word = "";
    }
    if(lock == 1) {
      endPos = e.getDocument().getLength();
    }
    if(keywordList.contains(word.trim())){
      System.out.println("contains :"+word);
      update(poistion,endPos-poistion,e);
    }
    if(lock == 0) {
      poistion = count ;
      lock = 1;
    }
    count++;
  }
  /**
   * This method update the attribute set of java keyword word 
   * @param start starting position of the word
   * @param length length of the word
   * @param event document event on document where we change the attribute set
   */
  public void update(int start,int length,DocumentEvent event) {
    try {
      System.out.println("Word : "+event.getDocument().getText(start, length)+ " #Position : Start : "+start+" end : "+(start+length));;
    }
    catch(Exception e) {
      e.printStackTrace();
    }
    SimpleAttributeSet set = new SimpleAttributeSet();
    StyleConstants.setForeground(set, Color.blue);
    StyledDocument style = pane.getStyledDocument();
    style.setCharacterAttributes(start, length, set, true);
  }
  @Override
  public void removeUpdate(DocumentEvent e) {
    // TODO Auto-generated method stub

  }
  public static void createAndShowGUI() {
    JFrame.setDefaultLookAndFeelDecorated(true);
    frame =  new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    SourceCodeWriter obj = new SourceCodeWriter();
    obj.loadKeywordList();

    contentPane = obj.createContentPane();
    frame.setContentPane(contentPane);

    frame.setVisible(true);
    frame.setSize(400,400);
  }
  public static void main(String[] args) {
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
      public void run() {
          createAndShowGUI();
      }
    });
  }
  @Override
  public void keyPressed(KeyEvent e) {
    // TODO Auto-generated method stub

  }
  @Override
  public void keyReleased(KeyEvent e) {
    // TODO Auto-generated method stub

  }
  @Override
  public void keyTyped(KeyEvent e) {
    key = e.getKeyChar();

  }
  /** 
   * This method is used to load all Keyword in java in list from a txt file. 
   */
  public void loadKeywordList() {
    File keywordFile = new File("D:/JavaKeywordList.txt");
    String line ="";
    try {
      BufferedReader reader = new BufferedReader(new FileReader(keywordFile));
      while((line = reader.readLine()) != null) {
        keywordList.add(line.trim());
      }
    }
    catch(IOException e) {
      e.printStackTrace();
    }
  }
}

和异常日志:

Exception in thread "AWT-EventQueue-0" Word : int #Position : Start : 0 end : 3
java.lang.IllegalStateException: Attempt to mutate in notification
    at javax.swing.text.AbstractDocument.writeLock(Unknown Source)
    at javax.swing.text.DefaultStyledDocument.setCharacterAttributes(Unknown Source)
    at event.SourceCodeWriter.update(SourceCodeWriter.java:96)
    at event.SourceCodeWriter.insertUpdate(SourceCodeWriter.java:72)
    at javax.swing.text.AbstractDocument.fireInsertUpdate(Unknown Source)
    at javax.swing.text.AbstractDocument.handleInsertString(Unknown Source)
    at javax.swing.text.AbstractDocument.insertString(Unknown Source)
    at javax.swing.text.AbstractDocument.replace(Unknown Source)
    at javax.swing.JTextPane.replaceSelection(Unknown Source)
    at javax.swing.JTextPane.replaceSelection(Unknown Source)
    at javax.swing.text.DefaultEditorKit$DefaultKeyTypedAction.actionPerformed(Unknown Source)
    at javax.swing.SwingUtilities.notifyAction(Unknown Source)
    at javax.swing.JComponent.processKeyBinding(Unknown Source)
    at javax.swing.JComponent.processKeyBindings(Unknown Source)
    at javax.swing.JComponent.processKeyEvent(Unknown Source)
    at java.awt.Component.processEvent(Unknown Source)
    at java.awt.Container.processEvent(Unknown Source)
    at java.awt.Component.dispatchEventImpl(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.KeyboardFocusManager.redispatchEvent(Unknown Source)
    at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(Unknown Source)
    at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(Unknown Source)
    at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(Unknown Source)
    at java.awt.DefaultKeyboardFocusManager.dispatchEvent(Unknown Source)
    at java.awt.Component.dispatchEventImpl(Unknown Source)
    at java.awt.Container.dispatchEventImpl(Unknown Source)
    at java.awt.Window.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
    at java.awt.EventQueue.access$500(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)

最佳答案

将 updateMethod() 中的代码更改为

StyledDocument style = pane.getStyledDocument();
Runnable runnable = new Runnable() {
        @Override
        public void run() {
            style.setCharacterAttributes(start, length, set, true);
        }
    };
    SwingUtilities.invokeLater(runnable);

关于java - 更新单词的属性集时,它会在 JTextPane 中抛出 IllegalStateException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45278665/

相关文章:

java - 使用 BorderLayout 时 JPanel 的间距不正确

java - 类的组合

java - 将图像插入 JTextPane 错误

java - 在java中停止输入JTextField后如何启动一个函数

java - 正在填充的 Graphics.drawRect

java - 如何清除JTextPane中的所有样式?

java - 使用 StyledDocument.insertString 将富文本附加到 JTextPane 不会保留字体

Windows 2003 Server 中的 java.io.IOException key 大小太大

java - Java 中的动态数组列表

java - 连接Java套接字时,为什么getInetAddress()返回/0 :0:0:0:0:0:0:1?