Если вы хотите, чтобы ячейка внутри GridBagLayout была фиксированной по ширине (или высоте), то для этого есть рабочее решение. Скажем, вы хотите, чтобы ячейка в точке (x, y) была фиксированной по ширине, но внутри JLabel есть переменное содержимое, которое необходимо изменить во время выполнения. Использование GridBagLayout затем переместит другие компоненты, если JLabel потребуется изменить размер, что приведет к изменению размера содержащейся ячейки. Чтобы противостоять этому, вы можете сделать одно из следующих действий:
- Вы можете добавить дополнительную строку (y + 1) к макету, в котором в x-й ячейке содержится фиктивная JPanel, а в этой JPanel вы вызываете
.setPreferredSize(new Dimension(desiredWidth, 0));
.
- То же самое, но вместо установки предпочитаемого размера вы устанавливаете вставки для объекта GridBagConstraints, используемого при добавлении этой фиктивной панели. Поэтому, если вам нужна фиксированная ширина, просто наберите
gbc.insets = new Insets(0,preferredWidth,0,0);
или gbc.insets = new Insets(0,0,0,preferredWidth);
. Таким образом, сама панель имеет размер (0,0), но содержащая ячейка будет вынуждена быть настолько широкой, насколько вы укажете (потому что вставки - это внешний отступ, видимый из компонента).
Первый требует, чтобы вы вызывали setPreferredSize (), и это всегда заставляет меня чувствовать себя неловко, потому что вы возитесь с задачей LayoutManager. Поэтому я предпочитаю последнее решение, но вы не сможете визуализировать вашу ячейку, так как ваша фиктивная панель не имеет размера. В первом решении вы можете сделать вашу ячейку видимой, придав панели цвет фона.
Преимущества этого подхода состоят в том, что вам не нужно беспокоиться о настройке размеров JLabel, особенно его высоты, которая неизвестна до ее отображения. Вы не можете установить предпочитаемый размер для JLabel, потому что вы не знаете, какую высоту он должен иметь (зависит от платформы, от шрифта и т. Д.). Вы просто добавляете его, и использование фиктивной строки с фиктивной панелью заставит ячейку, содержащую JLabel, иметь ширину desiredWidth
.
Это решение работает, учитывая, что ширина JLabel не будет превышать desiredWidth
, потому что в этом случае ячейка также будет расти. Чтобы решить эту проблему, вы всегда можете указать максимальный размер JLabel (здесь у вас нет проблемы неизвестных высот - для максимальной высоты вы можете использовать Integer.MAX_VALUE).
Та же история касается высоты, просто введите фиктивный столбец и добавьте фиктивную JPanel с размерностью = (0, предпочитаемый высотой) в ячейку в строке, где возникает проблема.
Недостаток этого подхода: вы должны использовать фиктивные компоненты, что никогда не было лучшим способом, но здесь он работает довольно хорошо.