Как уже упоминалось в комментариях к вопросу, вы смогли исправить это, переключившись на setMaximumSize()
. Однако, как вы заметили, setPreferredSize()
не работает. Итак, что с этим?
Во многих случаях Swing, свойства, используемые для определения фактического размера компонента при использовании BoxLayout
, являются несколько случайными (на мой взгляд). При определении способа рендеринга компонентов Swing вызывает layoutComponent()
в менеджере макета, который выясняет, где все расположить.
Реализация
BoxLayout
layoutComponent()
включает вызов метода, который создает SizeRequirements
объекты для ширины и высоты каждого из компонентов, которые вы добавляете к JPanel
, на основе по их getMinimum/Preferred/MaximumSize()
методам.
Позже он вызывает SizeRequirements.calculateAlignedPositions()
для определения правильных значений ширины для каждого компонента, поскольку ваша ориентация равна BoxLayout.Y_AXIS
(высоты рассчитываются с использованием другого метода). Принимая фрагменты из источника, соответствующая реализация этого метода выглядит следующим образом:
for (int i = 0; i < children.length; i++) {
SizeRequirements req = children[i];
//...
int maxAscent = (int)(req.maximum * alignment);
int maxDescent = req.maximum - maxAscent;
//...
int descent = Math.min(totalDescent, maxDescent);
//...
spans[i] = (int)Math.min((long) ascent + (long)descent, Integer.MAX_VALUE);
}
Обратите внимание, что totalDescent
- это доступная ширина, поэтому descent
всегда устанавливается на maxDescent
, что основано на SizeRequirements.maximum
, который был взят из JButton.getMaximumSize()
. Значение spans[i]
затем используется позже при вызове JButton.setBounds()
в качестве ширины. Как вы заметите, getPreferredSize()
здесь никогда не участвовал, поэтому его настройка в этом случае не имеет значения.