2013-03-04 46 views
8

Mục tiêu của tôi là triển khai màu xanh của từ khóa được người dùng viết vào JTextPane. Đây là cách mã nhìn tôi như:Ngoại lệ 'Cố gắng thay đổi thông báo' ngoại lệ

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); 
       } 
      } 
     } 
    } 

Sau khi gõ bất cứ điều gì vào cửa sổ tôi nhận được:

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) 

Làm thế nào để giải quyết vấn đề của tôi? Có lẽ tôi nên sử dụng một cái gì đó khác hơn là DocumentListener?

Trả lời

14

Bạn cần phải gọi các thay đổi đối với tài liệu từ Chủ đề người điều phối sự kiện.

Hãy thử điều này:

private void highlight() { 

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

Issue không phải là 'điểm nhấn() 'được thực hiện từ chủ đề sai. Thay vào đó, 'invokeLater (Runnable)' sửa chữa vấn đề vì nó trì hoãn việc thực hiện cho đến khi khóa Document được giải phóng. –

0

tôi đã cùng một vấn đề, tôi giải quyết nó bằng cách sử dụng này:

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"); 
       } 
      }); 
Các vấn đề liên quan