wakjah
wakjah

Reputation: 4551

How to get the height of entered text in a JTextArea while it is being entered by the user?

I realise this may sound like a duplicate of How to get the height of the entered text in a JTextPane? but it is not.

I am trying to determine the preferred height of a JTextArea while the user is typing into the box. To do so, following advice found elsewhere, I am using the following code

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

This mostly works but not quite. The problem is that when the user enters enough characters to cause the line to wrap, the preferred size does not seem to be updated until the next character entry.

To reproduce:

Is this a bug? What's going on here?

Upvotes: 1

Views: 58

Answers (1)

Sergiy Medvynskyy
Sergiy Medvynskyy

Reputation: 11327

This works with a simple trick, called SwingUtilities.invokeLater

Simply change the line:

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

by the line

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

And it works! Probably the TextArea provide size update after the key event was processed.

Upvotes: 2

Related Questions