2013-03-04 83 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"); 
       } 
      });