GridBagLayout: равномерно распределенные ячейки
можно ли полностью эмулировать поведение GridLayout с менеджером GridBagLayout?
в принципе, у меня есть сетка 8x8, в которой каждая ячейка должна иметь одинаковую ширину и высоту. GridLayout автоматически сделал это. Но я хочу добавить еще одну строку и столбец в сетку, размер которой не то же самое как и другие. Эта строка / столбец должна занимать все оставшееся пространство ,которое может быть оставлено (потому что доступный размер не может быть одинаковым разделены на 8 клеток). Это вообще возможно, или мне снова придется использовать другой менеджер компоновки?
редактировать
вот простая графика того, что я хочу достичь, упрощенная до всего 4 ячеек:
цветные ячейки-это те, которые я добавил в фактическую сетку (серый), которая имеет ячейки с одинаковой высотой и шириной x
. Таким образом, высота и ширина сетки 4*x
. Теперь я хочу, чтобы дополнительные ячейки имели необходимую ширину / высоту (minimumSize) плюс остальная часть доступной ширины/высоты от полного размера.
Если размер всей панели изменен, ячейки серой сетки должны снова занять как можно больше места.
5 ответов
set weightx
и weighty
of GridBagConstraints
из фиксированных ячеек в 0
и fill
to NONE
. Для плавающих ячеек set fill
to BOTH
, для плавающих ячеек, которые должны расширяться только горизонтально, установите weightx
to 1
и для вертикально расширяющихся наборов weighty
to 1
.
ячейки расширяются, только если они имеют какой-либо контент, поэтому вам нужно заполнить его чем-то. Я выбрал JLabel
s и установите фиксированные размеры для меток в фиксированных ячейках. На размеры нужно пересчитать размеры и вызов invalidate()
для пересчета макета.
вот пример w
x h
решетки:
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class GridBag {
public static void main(String[] args) {
final JFrame f = new JFrame("Gridbag Test");
final Container c = f.getContentPane();
c.setLayout(new GridBagLayout());
final Dimension dim = new Dimension(70, 70);
final int w = 4;
final int h = 4;
final JLabel[] yfloating = new JLabel[w];
final JLabel[] xfloating = new JLabel[h];
final JLabel[][] fixed = new JLabel[w][h];
// adding the vertically floating cells
final GridBagConstraints gc = new GridBagConstraints();
gc.fill = GridBagConstraints.BOTH;
gc.weightx = 0.0;
gc.weighty = 1.0;
for(int i = 0; i < w; ++i) {
yfloating[i] = new JLabel("floating " + i);
yfloating[i].setBorder(BorderFactory.createLineBorder(Color.BLACK));
yfloating[i].setHorizontalTextPosition(JLabel.CENTER);
yfloating[i].setVerticalTextPosition(JLabel.CENTER);
gc.gridy = 0;
gc.gridx = i+1;
c.add(yfloating[i], gc);
}
// adding the horizontally floating cells
gc.fill = GridBagConstraints.BOTH;
gc.weightx = 1.0;
gc.weighty = 0.0;
for(int i = 0; i < w; ++i) {
xfloating[i] = new JLabel("floating " + i);
xfloating[i].setBorder(BorderFactory.createLineBorder(Color.BLACK));
xfloating[i].setHorizontalTextPosition(JLabel.CENTER);
xfloating[i].setVerticalTextPosition(JLabel.CENTER);
gc.gridy = i+1;
gc.gridx = 0;
c.add(xfloating[i], gc);
}
// adding the fixed cells
gc.fill = GridBagConstraints.NONE;
gc.weightx = 0.0;
gc.weighty = 0.0;
for(int i = 0; i < w; ++i) {
for(int j = 0; j < h; ++j) {
fixed[i][j] = new JLabel("fixed " + i);
fixed[i][j].setBorder(BorderFactory.createLineBorder(Color.BLACK));
fixed[i][j].setMaximumSize(dim);
fixed[i][j].setMinimumSize(dim);
fixed[i][j].setPreferredSize(dim);
gc.gridx = i+1;
gc.gridy = j+1;
c.add(fixed[i][j], gc);
}
}
c.addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
final Component comp = e.getComponent();
final int newSize = Math.min(comp.getHeight() / h, comp.getWidth() / w);
final Dimension newDim = new Dimension(newSize, newSize);
for(int i = 0; i < w; ++i) {
for(int j = 0; j < h; ++j) {
fixed[i][j].setMaximumSize(newDim);
fixed[i][j].setMinimumSize(newDim);
fixed[i][j].setPreferredSize(newDim);
}
}
comp.invalidate();
}
});
f.pack();
f.setVisible(true);
}
}
Если вы не привязаны к GridBagLayout обязательно, вы должны посмотреть в MigLayout библиотека. Вы можете сделать что-то вроде:
MigLayout layout = new MigLayout(
"", // Layout Constraints
"[10][10][10][10]", // Column constraints
"[10][10][10][10]"); // Row constraints
все значения устанавливаются в GridBagConstraints
.
если вы хотите, чтобы ваша сетка 8x8 исправлена, вы можете установить ipadx
и ipady
значения.
затем выберите weightx
и weighty
значения вашей новой строки / столбца в 1.0
и set fill
to FULL
.
ваша дополнительная строка / столбец будет расширяться с оставшимся пространством.
если вы хотите, чтобы сетка 8x8 также расширялась, это сложнее. Вы можете настроить ipadx
и ipady
значения в дополнение к weightx
и weighty
значения. Или сделайте панель для сетки 8x8 и используйте GridLayout
там. Использовать GridBagLayout
на панели и дополнительной строке / столбце.
есть ли причина, по которой вы не делаете это в JTable? Похоже, именно для этого он и создан. С помощью соответствующего визуализатора ячеек вы можете поместить все, что хотите, в ячейки.
http://www.java2s.com/Code/Java/Swing-Components/TableRowHeaderExample.htm
попробовав много разных вещей со встроенными менеджерами макетов, я решил создать пользовательский менеджер макетов для этой проблемы. Я еще не сделал этого, так как у меня не было времени продолжить этот проект, но когда я это сделаю, я обязательно опубликую код менеджера макетов здесь, чтобы любой, кто заинтересован в подобном решении, мог его использовать.
редактировать
didxga напомнил мне в комментариях, что я хотел опубликовать свое решение. Однако, после того, как я выкопал проект и посмотрел на него, я на самом деле не могу опубликовать свое решение, потому что оказывается, что я никогда не создавал его!
Это был проект uni, который закончился официально в середине сентября 2010 года. Мы на самом деле хотели продолжить работу над ним после этого, и, вероятно, поэтому я сказал, что опубликую его (поскольку это была одна вещь, которую я хотел улучшить), но мы никогда не делали этого – к сожалению. Вместо этого я просто оставил эти дополнительные столбец и строку (которая была подразумевается как метка для строк / столбцов btw).
Так что да, мне ужасно жаль, что я не могу опубликовать макет, который делает то, что я изначально хотел...: (может быть, если есть достаточно запроса такого макета, я бы его создал, но на данный момент я не очень хочу снова погружаться в Java layouting ;)