Ява изменить документ в DocumentListener

Я использую DocumentListener обрабатывать любые изменения в JTextPane документ. в то время как пользователь печатает, я хочу удалить содержимое JTextPane и вместо этого вставьте настроенный текст. невозможно изменить документ в DocumentListenerВместо этого здесь сказано решение: java.lang.IllegalStateException при использовании Document Listener в TextArea, Java, но я не понимаю этого, по крайней мере, я не знаю, что делать в моем случае?

3 ответа

Решение

DocumentListener действительно хорош только для уведомления об изменениях и никогда не должен использоваться для изменения текстового поля / документа.

Вместо этого используйте DocumentFilter

Проверьте здесь для примеров

FYI

Корень вашей проблемы в том, что DocumentListener В то время как документ обновляется. Попытки изменить документ (кроме риска бесконечного цикла) переводят документ в недопустимое состояние, отсюда исключение

Обновлено с примером

Это ОЧЕНЬ базовый пример... Он не обрабатывает вставку или удаление, но в моем тестировании было выполнено удаление без каких-либо действий...

введите описание изображения здесь

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

                }

            }
        }

    }

}

в то время как пользователь вводит, я хочу удалить содержимое JTextPane и вместо этого вставить настроенный текст.

  • это не работа для DocumentListener, в основном этот Listener предназначен для запуска событий из JTextComponent s в другой JComponent, в Swing GUI, реализованные методы в используемом Java

  • Посмотрите на DocumentFilter, это обеспечивает желаемые методы для изменения, модификации или обновления собственного документа (модель для JTextComponents) во время выполнения

Оберните код, по которому вы звоните SwingUtilities.invokeLater()

Другие вопросы по тегам