Подтвердить что ты не робот

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

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

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

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

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

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

4b9b3361

Ответ 1

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

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

Это требует, чтобы мой 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() );

Ответ 2

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

Ответ 3

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

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

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

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

Ответ 4

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

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