Подтвердить что ты не робот

GridBagLayout: равномерно распределенные ячейки

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

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

изменить

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

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

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

4b9b3361

Ответ 1

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

изменить

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

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

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

Ответ 2

установите weightx и weighty из GridBagConstraints фиксированных ячеек на 0 и fill на NONE. Для плавающих ячеек установите fill на BOTH, для плавающих ячеек, которые должны расширяться только горизонтально, установите weightx в 1, а для вертикально расширяющихся установите weighty на 1.

Ячейки расширяются только в том случае, если у них есть контент, поэтому вам нужно что-то заполнить. Я выбрал JLabel и установил фиксированные размеры для меток в фиксированных ячейках. При изменении размера вам необходимо пересчитать размеры и вызвать 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);
    }
}

Ответ 3

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

MigLayout layout = new MigLayout(
        "",         // Layout Constraints
        "[10][10][10][10]", // Column constraints
        "[10][10][10][10]");  // Row constraints

Ответ 4

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

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

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

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

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

Ответ 5

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

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