Я не очень знаком с GroupLayout, это то, что я наблюдал, просматривая документы и размышляя об этом. Надеюсь, это полезно. Мой ответ был довольно длинным, поэтому я подведу итог:
Почему это происходит? Сочетание 3 вещей.
- GroupLayout учитывает предпочтительный размер ваших компонентов. (именно поэтому вы выбрали его, судя по вашим комментариям).
- Ваша вертикальная группа является последовательной. Он выкладывает по одному компоненту за раз - в их предпочтительном размере или больше, если есть место.
- Ваш JScrollPane имеет неограниченный предпочтительный размер. Он увеличивается до любого предпочтительного размера JTextArea ... не оставляя места для компонента под ним, когда его предпочтительный размер становится больше, чем у вашего фрейма.
Объединение менеджера компоновки, который учитывает предпочтительный размер, с компонентом с очень большим предпочтительным размером, как правило, всегда вызывает эту проблему. Я не тестировал подробно, но я знаю, что это также происходит в FormLayout (если вы скажете, чтобы он использовал предпочтительный размер).
Более длительная попытка объяснения / мыслительного процесса:
Это как если бы текстовая область спрашивала
контейнер, сколько места в
контейнер, а затем взять 100% его,
независимо от других компонентов.
Текстовая область не спрашивает контейнер, насколько он может быть увеличен - напротив, он сообщает контейнеру, какой он хочет быть. В этом случае textArea непосредственно содержится в области прокрутки. Предпочтительный размер текстовой области будет увеличиваться с размером текста в текстовой области. Предпочтительный размер области прокрутки будет увеличиваться с предпочтительным размером текстовой области, если вы не установите предпочтительный размер на панели прокрутки. Оттуда менеджер по макетам решит, как все устроить.
В этом случае вы используете GroupLayout с SequentialGroup для вертикального макета. Это позволит расположить компоненты по порядку, исходя из их размеров min / pref / max. Если вы измените положение textPane как последнего элемента в группе, он не будет воровать пространство у других ваших компонентов ... поэтому я предполагаю, что для очень больших размеров GroupLayout не волнует, отображаются ли все компоненты - если после последнего компонента не осталось места, они не отображаются до тех пор, пока контейнер не будет увеличен. Для небольших размеров пользователи могут регулировать размер рамки ... но для больших размеров, как в вашем примере, это невозможно.
Отдельно от упущения - похоже, что это просто сочетание огромной области прокрутки, а GroupLayout не знает, когда остановиться ... поэтому нижняя часть панели прокрутки обрезается. Этого можно избежать, просто установив разумный предпочтительный размер на JScrollPane, хотя, как предложил @camickr.
Другая странная вещь в том, что она появляется
произойти только тогда, когда JTextArea (не
JScrollPane) размер плюс другие
высота компонентов внутри контейнера
достичь Short.MAX_VALUE.
Если вы зарегистрируете размеры каждого компонента, вы увидите, что если вы не укажете предпочтительный размер для JScrollPane, он всегда будет иметь предпочтительный размер больше, чем у textArea, поэтому я не думаю, что выше утверждение верно. Размер области прокрутки плюс другие компоненты в контейнере все равно будут превышать Short.MAX_VALUE и, по-видимому, вызывают проблемы в GroupLayout, что очень верно.
Смысл JScrollPane, который я вижу, заключается в размещении компонента с большим (или потенциально большим) предпочтительным размером в отдельной меньшей области (с соответствующими полосами прокрутки).Затем вы всегда можете позволить полосе прокрутки увеличиваться до размера, превышающего ее предпочтительный размер ... но она начинается с указания панели прокрутки, насколько большой она должна быть.Фактически, установка предпочтительного размера эффективно сообщает JScrollPane, когда ему нужны полосы прокрутки.Например, если предпочтительный размер области прокрутки равен 400 300, то всякий раз, когда предпочтительная ширина содержащегося компонента превышает 400 (или размер области прокрутки, если она находится в контейнере, который позволяет ей расти больше, чем ее предпочтительный размер), показать горизонтальные полосы прокрутки.Точно так же и по высоте.В противном случае он всегда будет увеличиваться до размера, который у вас есть, и ему не понадобятся полосы прокрутки, устранение точки или, в некоторых случаях, предотвращение отображения других компонентов.
Документы для GroupLayoutОтметим, что он обычно используется другими инструментами компоновщика, а не разработчиками (хотя вы все еще можете).Я хотел бы рассмотреть возможность использования другого макета, чем тот, который обычно требует от вас использовать специальные максимальные значения для правильной работы.Мой личный фаворит - FormLayout , бесплатный менеджер макетов сторонних производителей с лицензией BSD.Я не думаю, что вам когда-либо нужно указывать фиксированные размеры для обычных компонентов, но в случае панелей прокрутки вы действительно хотите задать предпочтительный размер в макетах, которые соответствуют предпочтительному размеру.
Я хочу, чтобы всемои макеты учитывают DPI, растут там, где это необходимо, и прекрасно работают с интернационализацией (где длина текста может сильно отличаться) ... поэтому я не хотел бы использовать что-либо, что требует указания фиксированных размеров для всего.Я думаю, что в большинстве макетов установка фиксированного предпочтительного размера на панели прокрутки не является плохой вещью.Это делается для кнопки, текстового поля или другого компонента, который явно имеет очевидный предпочтительный размер, не так уж много.
Вот как это будет выглядеть в FormLayout (он также имеет компоновщики, но в этом случае яиспользуя ограничения ячеек, чтобы легко охватить столбец):
FormLayout layout = new FormLayout(
"pref,fill:pref:grow", // cols
"pref,3dlu,fill:pref:grow,3dlu,pref" // rows
);
JPanel panel = new JPanel(layout);
CellConstraints cc = new CellConstraints();
panel.add(redrawBtn, cc.xy(1, 1));
panel.add(textPane, cc.xyw(1, 3, 2)); // span 2 columns
panel.add(addBtn, cc.xy(1, 5));
frame.setContentPane(panel);