简体   繁体   English

java在DocumentListener中更改文档

[英]java change the document in DocumentListener

I use a DocumentListener to handle any change in a JTextPane document. 我使用DocumentListener来处理JTextPane文档中的任何更改。 while the user types i want to delete the contents of JTextPane and insert a customized text instead. 而用户类型我想删除JTextPane的内容并改为插入自定义文本。 it is not possible to change the document in the DocumentListener ,instead a solution is said here: java.lang.IllegalStateException while using Document Listener in TextArea, Java ,but i don't understand that, at least i don't know what to do in my case? 不可能在DocumentListener更改DocumentListener ,而是在这里说一个解决方案: java.lang.IllegalStateException在TextArea,Java中使用Document Listener ,但我不明白,至少我不知道该怎么做做我的情况?

DocumentListener is really only good for notification of changes and should never be used to modify a text field/document. DocumentListener实际上只适用于更改通知,不应该用于修改文本字段/文档。

Instead, use a DocumentFilter 而是使用DocumentFilter

Check here for examples 点击这里查看示例

FYI FYI

The root course of your problem is that the DocumentListener is notified WHILE the document is been updated. 您的问题的根本过程是在DocumentListener更新时通知DocumentListener Attempts to modify the document (apart from risking a infinite loop) put the document into a invalid state, hence the exception 尝试修改文档(除了冒无限循环的风险)将文档置于无效状态,因此异常

Updated with an example 更新了一个示例

This is VERY basic example...It doesn't handle insert or remove, but my testing had remove working without doing anything anyway... 这是非常基本的例子......它不会处理插入或移除,但是我的测试已经删除了工作而没有做任何事情......

在此输入图像描述

public class TestHighlight {

    public static void main(String[] args) {
        new TestHighlight();
    }

    public TestHighlight() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JTextPane textPane = new JTextPane(new DefaultStyledDocument());
                ((AbstractDocument) textPane.getDocument()).setDocumentFilter(new HighlightDocumentFilter(textPane));
                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new JScrollPane(textPane));
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }

        });
    }

    public class HighlightDocumentFilter extends DocumentFilter {

        private DefaultHighlightPainter highlightPainter = new DefaultHighlightPainter(Color.YELLOW);
        private JTextPane textPane;
        private SimpleAttributeSet background;

        public HighlightDocumentFilter(JTextPane textPane) {
            this.textPane = textPane;
            background = new SimpleAttributeSet();
            StyleConstants.setBackground(background, Color.RED);
        }

        @Override
        public void insertString(FilterBypass fb, int offset, String text, AttributeSet attr) throws BadLocationException {
            System.out.println("insert");
            super.insertString(fb, offset, text, attr);
        }

        @Override
        public void remove(FilterBypass fb, int offset, int length) throws BadLocationException {
            System.out.println("remove");
            super.remove(fb, offset, length);
        }

        @Override
        public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException {

            String match = "test";

            super.replace(fb, offset, length, text, attrs);

            int startIndex = offset - match.length();
            if (startIndex >= 0) {

                String last = fb.getDocument().getText(startIndex, match.length()).trim();
                System.out.println(last);
                if (last.equalsIgnoreCase(match)) {

                    textPane.getHighlighter().addHighlight(startIndex, startIndex + match.length(), highlightPainter);

                }

            }
        }

    }

}

while the user types i want to delete the contents of JTextPane and insert a customized text instead. 而用户类型我想删除JTextPane的内容并改为插入自定义文本。

SwingUtilities.invokeLater()包装您调用的代码

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM