GridBagLayout: равномерно распределенные ячейки - PullRequest
12 голосов
/ 12 сентября 2010

Можно ли полностью эмулировать поведение GridLayout с помощью менеджера GridBagLayout?

По сути, у меня есть сетка 8x8, в которой каждая ячейка должна иметь одинаковую ширину и высоту.GridLayout автоматически сделал это.Но я хочу добавить еще одну строку и столбец в сетку, размер которой не совпадает с другими.Эта строка / столбец должна занимать все оставшееся пространство, которое может быть оставлено (поскольку доступный размер не может быть равномерно распределен на 8 ячеек).Это вообще возможно, или мне опять нужно использовать другой менеджер макетов?

edit

Вот простой график того, чего я хочу достичь, упрощенный до 4 ячеек:Problem graphic

Цветные ячейки - это те, которые я добавил к фактической сетке (серой), в которой есть ячейки с одинаковой высотой и шириной x.Таким образом, высота и ширина сетки 4*x.Теперь я хочу, чтобы дополнительные ячейки имели необходимую ширину / высоту (минимальный размер) плюс оставшуюся доступную ширину / высоту от полного размера.

Если размер всей панели изменяется, ячейки серой сетки должны сновазанять как можно больше места.

Ответы [ 5 ]

3 голосов
/ 14 сентября 2010

установите weightx и weighty из GridBagConstraints фиксированных ячеек на 0 и fill на NONE. Для плавающих ячеек установите fill на BOTH, для плавающих ячеек, которые должны расширяться только по горизонтали, установите weightx на 1, а для вертикально расширяющихся ячеек установите weighty на 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);
    }
}
1 голос
/ 01 октября 2010

Если вы не привязаны к GridBagLayout обязательно, вам следует заглянуть в библиотеку MigLayout . Вы можете сделать что-то вроде:

MigLayout layout = new MigLayout(
        "",         // Layout Constraints
        "[10][10][10][10]", // Column constraints
        "[10][10][10][10]");  // Row constraints
0 голосов
/ 02 октября 2010

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

edit

didxga напомнил мне в комментариях, что я хотел опубликовать свое решение.Тем не менее, после того, как я выкопал проект из того времени и посмотрел его, я фактически не могу опубликовать свое решение, потому что оказывается, что я так и не смог его создать!

Это был универ-проект, который официально завершился в середине сентября 2010На самом деле мы хотели продолжить работу над этим позже, поэтому, вероятно, я сказал, что я опубликую это (так как это было одно, что я хотел улучшить), но мы так и не удосужились сделать это - к сожалению.Вместо этого я просто пропустил эти лишние столбцы и строки (что означало метку для строк / столбцов между прочим).

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

0 голосов
/ 02 октября 2010

Есть ли причина, по которой вы не делаете это в JTable?Похоже, именно для этого он создан.С помощью соответствующего средства визуализации ячеек вы можете поместить в ячейки все, что захотите.

http://www.java2s.com/Code/Java/Swing-Components/TableRowHeaderExample.htm

0 голосов
/ 12 сентября 2010

Все значения установлены в GridBagConstraints.

Если вы хотите, чтобы ваша сетка 8x8 была фиксированной, вы можете установить значения ipadx и ipady.

Затем установите значения weightx и weighty для новой строки / столбца на 1.0 и установите fill на FULL.

Ваша дополнительная строка / столбец расширится с оставшимся пробелом.

Если вы хотите, чтобы сетка 8x8 также расширялась, это более сложно. Вы можете настроить значения ipadx и ipady в дополнение к значениям weightx и weighty. Или создайте панель для сетки 8x8 и используйте GridLayout там. Используйте GridBagLayout на панели и дополнительную строку / столбец.

...