Java Swing自定义StyledDocument配置DocumentFilter后高亮失效
问题原因
高亮失效和默认DocumentFilter被覆盖没有直接关系。核心逻辑是:给AbstractDocument设置自定义DocumentFilter后,所有文本的插入、删除、替换操作都会先经过过滤器的回调,不会直接调用你在HighlightStyledDocument中重写的insertString、remove方法,你之前绑定在这两个重写方法里的高亮触发逻辑自然不会执行。
修复方案
二选一即可:
方案1:将高亮触发逻辑迁移到DocumentFilter中
这是改造成本最低的方案:
- 把
HighlightStyledDocument里的highlight()方法改为public,删掉类中重写的insertString、remove方法——这两个方法在设置了DocumentFilter后不会被触发,留着没用。 - 在自定义
CustomDocumentFilter的三个重写方法中,完成文本变更、自动缩进、符号配对逻辑后,主动调用文档的高亮方法,参考代码:
public class CustomDocumentFilter extends DocumentFilter { @Override public void insertString(FilterBypass fb, int offset, String text, AttributeSet attr) throws BadLocationException { super.insertString(fb, offset, text, attr); // 这里写自动缩进、符号配对的自定义逻辑 ((HighlightStyledDocument) fb.getDocument()).highlight(); } @Override public void remove(FilterBypass fb, int offset, int length) throws BadLocationException { super.remove(fb, offset, length); ((HighlightStyledDocument) fb.getDocument()).highlight(); } @Override public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException { super.replace(fb, offset, length, text, attrs); // 这里写自动缩进、符号配对的自定义逻辑 ((HighlightStyledDocument) fb.getDocument()).highlight(); } }
方案2:实现可叠加的DocumentFilter链
如果后续要加的编辑功能比较多,不想把所有逻辑都塞到同一个Filter里,可以自己实现过滤器链:维护一个过滤器列表,自定义FilterBypass将操作依次传递给链上的每个过滤器,最后一个过滤器执行完再调用实际的文档变更方法,这样就能实现类似addDocumentFilter的叠加效果,高亮、自动缩进、符号配对都可以拆成独立的过滤器维护。
注意:你当前的高亮逻辑用了
SwingUtilities.invokeLater异步执行,写自动缩进、配对符号插入逻辑时要做好递归判断,避免文本变更触发过滤器反复调用导致死循环。
内容的提问来源于stack exchange,提问作者Abdo21
相关产品推荐
相关产品推荐

