java 获取“尝试改变通知”异常
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15206586/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Getting 'Attempt to mutate notification' exception
提问by user2102972
My goal is to implement blue coloring of keywords written by user into JTextPane. This is how my code look like:
我的目标是在 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);
}
}
}
}
After typing anything into pane I get:
在窗格中输入任何内容后,我得到:
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)
How to solve my problem? Maybe I should use something other than DocumentListener?
如何解决我的问题?也许我应该使用 DocumentListener 以外的东西?
回答by moeTi
You need to invoke changes to the document from the Event Dispatcher Thread.
您需要从 Event Dispatcher Thread 调用对文档的更改。
Try this:
试试这个:
private void highlight() {
Runnable doHighlight = new Runnable() {
@Override
public void run() {
// your highlight code
}
};
SwingUtilities.invokeLater(doHighlight);
}
回答by user2845064
I had the same problem, I solved it by using this:
我有同样的问题,我用这个解决了它:
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");
}
});