2013-03-04 62 views
8

我的目标是实现用户写入JTextPane的关键字的蓝色着色。这是我的代码看起来怎么样:获取'尝试变异通知'异常

private class DocumentHandler implements DocumentListener { 

     @Override 
     public void changedUpdate(DocumentEvent ev) { 
     } 

     @Override 
     public void insertUpdate(DocumentEvent ev) { 
      highlight(); 
     } 

     @Override 
     public void removeUpdate(DocumentEvent ev) { 
      highlight(); 
     } 

     private void highlight() { 
      String code = codePane.getText(); 
      SimpleAttributeSet defSet = new SimpleAttributeSet(); 
      StyleConstants.setForeground(defSet, Color.BLACK); 
      doc.setCharacterAttributes(0, code.length(), defSet, true); 
      SimpleAttributeSet set = new SimpleAttributeSet(); 
      StyleConstants.setForeground(set, Color.BLUE); 
      for (String keyword : keywords) { 
       Pattern pattern = Pattern.compile(keyword + "(\\[\\])*"); 
       Matcher matcher = pattern.matcher(code); 
       while (matcher.find()) { 

        //Just for test 
        System.out.print("Start index: " + matcher.start()); 
        System.out.print(" End index: " + matcher.end()); 
        System.out.println(" Found: " + matcher.group()); 

        doc.setCharacterAttributes(matcher.start(), keyword.length(), set, true); 
       } 
      } 
     } 
    } 

输入任何内容到面板后,我得到:

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.DefaultStyledDocument.setCharacterAttributes(DefaultStyledDocument.java:500) 
    at jnotepad.MainPanel$DocumentHandler.highlight(MainPanel.java:121) 
    at jnotepad.MainPanel$DocumentHandler.insertUpdate(MainPanel.java:108) 
    at javax.swing.text.AbstractDocument.fireInsertUpdate(AbstractDocument.java:202) 
    at javax.swing.text.AbstractDocument.handleInsertString(AbstractDocument.java:749) 

如何解决我的问题?也许我应该使用DocumentListener以外的东西?

回答

14

您需要从Event Dispatcher线程调用文档的更改。

试试这个:

private void highlight() { 

    Runnable doHighlight = new Runnable() { 
     @Override 
     public void run() { 
      // your highlight code 
     } 
    };  
    SwingUtilities.invokeLater(doHighlight); 
} 
+4

问题不在于'亮点()'是从错误的线程执行。相反,'invokeLater(Runnable)'修复了问题,因为它会推迟执行,直到文档锁被释放。 – 2014-01-27 15:33:25

0

我有同样的问题,我解决它通过使用这样的:

expiration_timeTF.getDocument().addDocumentListener(
      new DocumentListener() { 
       @Override 
       public void removeUpdate(DocumentEvent e) { 
        System.out.println("remove"); 
       } 

       private void assistDateText() { 
        Runnable doAssist = new Runnable() { 
         @Override 
         public void run() { 
          // when input "2013",will add to "2013-";when 
          // input "2013-10",will add to "2013-10-" 
          String input = expiration_timeTF.getText(); 
          if (input.matches("^[0-9]{4}")) { 
           expiration_timeTF.setText(input + "-"); 
          } else if (input.matches("^[0-9]{4}-[0-9]{2}")) { 
           expiration_timeTF.setText(input + "-"); 
          } 
         } 
        }; 
        SwingUtilities.invokeLater(doAssist); 
       } 

       @Override 
       public void insertUpdate(DocumentEvent e) { 
        // System.out.println("insert"); 
        assistDateText(); 
       } 

       @Override 
       public void changedUpdate(DocumentEvent e) { 
        // System.out.println("change"); 
       } 
      });