Как получить высоту введенного текста в JTextArea, когда он вводится пользователем?

Я понимаю, что это может звучать как дубликат Как получить высоту введенного текста в JTextPane?, но это не так.

Я пытаюсь определить предпочтительную высоту JTextArea, пока пользователь вводит текст в поле. Для этого, следуя советам, найденным в другом месте, я использую следующий код

import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.awt.*;

public class Main {
    public static void main(String[] args) {
        final JFrame frame = new JFrame();

        frame.setLayout(new BorderLayout());

        final JTextArea text = new JTextArea();
        text.setLineWrap(true);
        text.setWrapStyleWord(true);
        text.setColumns(10);

        text.getDocument().addDocumentListener(
                new DocumentListener() {
                    @Override
                    public void insertUpdate(DocumentEvent inDocumentEvent) {
                        System.out.println("new preferred: " + text.getPreferredSize());
                    }

                    @Override
                    public void removeUpdate(DocumentEvent inDocumentEvent) {
                        System.out.println("new preferred: " + text.getPreferredSize());
                    }

                    @Override
                    public void changedUpdate(DocumentEvent inDocumentEvent) {

                    }
                }
        );

        frame.add(text, BorderLayout.CENTER);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

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

Чтобы воспроизвести:

  • Запустите вышеуказанную программу
  • Вводите символы до тех пор, пока курсор не окажется рядом с правым краем, так что следующее нажатие клавиши приведет к переносу строки
  • Нажмите другой символ.
  • В этот момент строка будет перенесена, и высота напечатанного PreferredSize должна быть больше, чем раньше, поскольку в JTextArea есть две строки, но это не так.
  • Нажмите другой символ. Сейчас PreferredSize обновляется, чтобы отразить тот факт, что есть две строки.
  • То же самое происходит при удалении символов.

Это ошибка? Что тут происходит?

"Как получить высоту введенного текста в JTextArea"Почему (сделать это вместо того, чтобы устанавливать количество строк и помещать текстовую область в область прокрутки)?
Andrew Thompson 12.04.2019 16:28

JTextArea используется как часть графического приложения, где оно используется как текстовое поле, плавающее поверх другого дисплея. Когда пользователь создает «текстовое поле», оно должно расширяться по мере того, как пользователь вводит текст.

wakjah 12.04.2019 16:30
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
2
29
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это работает с помощью простого трюка, называемого SwingUtilities.invokeLater

Просто измените строку:

System.out.println("new preferred: " + text.getPreferredSize());

по линии

SwingUtilities.invokeLater(() -> System.out.println("new preferred: " + text.getPreferredSize()));

И это работает! Вероятно, TextArea обеспечивает обновление размера после обработки ключевого события.

Конечно! Теперь, почему я не подумал об этом? :D Спасибо

wakjah 12.04.2019 16:43

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