Wrapping JTextArea не получает достаточно места / крадет пространство - PullRequest
1 голос
/ 28 апреля 2019

Кажется, что упаковка (setLineWrap(true)) JTextArea не получает достаточно места и поэтому обрезается:
JTextArea cut off

Создание родительского макета из его дочерних элементов дважды, кажется, решает эту проблему:
JTextArea proper size

import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.Collections;
import java.util.stream.Collectors;

import javax.swing.JFrame;
import javax.swing.JTextArea;

public class JTextAreaTest {
    public static void main(String[] args) throws InvocationTargetException, InterruptedException {
        SwingUtilities.invokeAndWait(() -> {
            Arrays.asList(true, false).forEach(packTwice -> {
                testWrappingCutOff(packTwice);
            });
        });
    }

    private static void testWrappingCutOff(boolean packTwice) {
        JFrame frame = new JFrame("packTwice: " + packTwice);
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        JTextArea wrapping = new JTextArea();
        wrapping.setLineWrap(true);
        wrapping.setText(Collections.nCopies(10, "wrapping").stream().collect(Collectors.joining(" ")));
        frame.add(wrapping);

        frame.pack();
        // Second call to pack() solves the problem
        if (packTwice) {
            frame.pack();
        }

        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }
}

Кроме того, когда он используется вместе с другими компонентами, он «крадет» у них пространство. То есть когда другие компоненты находятся внутри JScrollPane, они получают полосы прокрутки, даже если их общий родительский компонент может быть просто увеличен для соответствия обоим компонентам:
JTextArea stealing space

Вызов pack() дважды решает эту проблему снова:
Both components properly layed out

Размещать родителей дважды довольно неудобно и не всегда возможно.

  • Я неправильно использую класс?
  • Является ли это известным ограничением, потому что перенос может произойти только после того, как станет известно, сколько места доступно?
  • Это (пока не сообщается) ошибка с Swing?
  • Или что-то еще не так?

1 Ответ

1 голос
/ 28 апреля 2019

Компоненты Swing определяют свой собственный предпочтительный размер.Обычно это делается следующим образом:

JTextArea textArea = new JTextArea(5, 20);

, поэтому текстовая область может иметь размер, отображающий 5 строк данных и 20 символов "W".Обычно JTextArea затем добавляется в JScrollPane, чтобы при необходимости появлялись полосы прокрутки.

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

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

Вы можете предотвратить необходимость второго пакета (), предоставив подсказку для текстовой области, используя что-то вроде:

wrapping.setSize(200, 1);

Теперь текстовая область имеет размер после первого пакета ().

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...