Как создать JTextArea с заданной шириной и наименьшей возможной высотой, необходимой для отображения всего текста?

во всех примерах, которые я могу найти, используйте JTextArea, высота и ширина известны перед построением JTextArea, а если JTextArea потребовало бы больше высоты, тогда оно положено внутри JScrollPane. Очевидно, высота JTextArea зависит от ширины и содержание текста.

теперь моя ситуация требует, чтобы я не использовал JScrollPane, а что JTextArea быть достаточно высоким, чтобы отобразить весь текст. Когда я создаю JTextArea, Я знаю текст содержание и сколько ширины ему придется работать; я не знаю высоту - я хочу, чтобы это было как можно меньше, не отрезая ни одного текста. Кажется, это очень трудно сделать.

в качестве примечания,JTextArea будет добавлен в JPanel у которого нет менеджера макетов - он использует абсолютное позиционирование на основе предпочтительного размера добавленного компонента. Это требует, чтобы мой JTextArea вернет правильные размеры на getPreferredSize(). Правильные размеры должна быть ширина, которую я предоставил при его создании, и минимальная высота, необходимая для отображения всего текста с предоставленной шириной.

я нашел некоторые подобные темы, которые обсуждают странности / ошибки, связанные с JTextArea которые иногда решаются путем вызова pack() дважды на родительском контейнере. Это не вариант для меня. Я испытываю соблазн в основном создать свой собственный JTextArea который принимает ширину и строку и вычисляет необходимую минимальную высоту на основе настройки ширины и шрифта, но я решил, что сначала спрошу, прежде чем тратить время на это.

Надеюсь, мой вопрос понятен. Спасибо всем за помощь!

4 ответов


оно использует абсолютный располагать основанный на размере добавленного компонента предпочитаемом.

звучит как работа менеджера макета.

для этого требуется, чтобы мой JTextArea вернул правильные размеры в getPreferredSize().

JTextArea textArea = new JTextArea();
textArea.setLineWrap( true );
textArea.setWrapStyleWord( true );
textArea.setText("one two three four five six seven eight nine ten");
System.out.println("000: " + textArea.getPreferredSize());
textArea.setSize(100, 1);
System.out.println("100: " + textArea.getPreferredSize());
textArea.setSize( textArea.getPreferredSize() );

import java.awt.*;
import javax.swing.*;

class FixedWidthLabel {

    public static void main(String[] args) {

        Runnable r = new Runnable() {
            public void run() {
                String pt1 = "<html><body width='";
                String pt2 =
                    "px'><h1>Label Height</h1>" +
                    "<p>Many Swing components support HTML 3.2 &amp;" +
                    " (simple) CSS.  By setting a body width we can cause the " +
                    " component to find the natural height needed to display" +
                    " the component.<br><br>" +
                    "<p>The body width in this text is set to " +
                    "";
                String pt3 =
                    " pixels." +
                    "";

                JPanel p = new JPanel( new BorderLayout() );

                JLabel l1 = new JLabel( pt1 + "125" + pt2 + "125" + pt3 );
                p.add(l1, BorderLayout.WEST);

                JLabel l2 = new JLabel( pt1 + "200" + pt2 + "200" + pt3 );
                p.add(l2, BorderLayout.CENTER);

                JOptionPane.showMessageDialog(null, p);
            }
        };
        SwingUtilities.invokeLater(r);
    }
}

решение, описанное в FixedWidthLabel, с помощью <html><body width="..." потребуется, чтобы программист предоставил сообщение как часть строки html.

Если сообщение что-то вроде invalid integer: i<0 not allowed , тогда < должен быть экранирован (закодирован?), в противном случае неизвестно, как JLabel будет интерпретировать html.

Это добавляет сложности к этому решению.

только если вы знаете, что сообщение не содержит таких символов, вы будете хорошо.


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

скажем, ваш текст имеет 1000 символов, включая пробелы, а ширина символа эквивалентна 4пикселям, тогда вы можете работать, если ширина составляет 400, что 100 символы помещаются на каждой строке, впоследствии вам понадобится 10 строк. Теперь скажите, что высота 10 для размера шрифта, теперь вы знаете, что вам нужно 10 x 10 == 100 пикселей, поэтому ваш TextArea должен быть 400x100