Панель GridBagLayout расширяется, игнорируя вертикальный клей BoxLayout - PullRequest
2 голосов
/ 29 декабря 2011

В приведенном ниже примере у меня есть JPanel с BoxLayout, который содержит другой JPanel с GridBagLayout.

Добавляя вертикальный клей, я ожидаю, что содержимое внутренней панели будет «приклеено» к верхней части внешней панели.

Но я вижу метку "А" в центре. Если я удаляю GridBagLayout, A отображается вверху. Почему это происходит?

import javax.swing.*;
import java.awt.*;

public class Test {
    public static void main(String[] args) {
        JPanel contentPane = new JPanel();        

        JFrame frame = new JFrame();
        frame.setContentPane(contentPane);

        contentPane.setLayout(new BoxLayout(contentPane, BoxLayout.Y_AXIS));

        JPanel gridBagPanel = new JPanel();
        gridBagPanel.setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.fill = GridBagConstraints.NONE;

        gridBagPanel.add(new JLabel("A"), gbc);
        contentPane.add(gridBagPanel);
        contentPane.add(Box.createVerticalGlue());

        frame.setSize(800, 200);
        frame.setVisible(true);
    }
}

Ответы [ 3 ]

3 голосов
/ 29 декабря 2011

Поскольку значение по умолчанию для свойства anchor GridBagConstraints равно CENTER. Если на внутренней панели больше места, чем в предпочтительном размере JLabel, JLabel будет отцентрирован относительно доступного пространства на внутренней панели (поскольку вы установили заполнение на NONE).

Вы можете использовать значение привязки NORTHWEST, чтобы приклеить ярлык к верхней части панели:

GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.NONE;
gbc.anchor = GridBagConstraints.NORTHWEST;
gbc.weighty = 1;
gbc.weightx = 1;

Вам также нужно установить весовые коэффициенты для документации Java: «Если вы не укажете хотя бы одно ненулевое значение для weightx или weightty, все компоненты слипаются в центре своего контейнера. Это происходит потому, что когда вес равен 0.0 (по умолчанию), GridBagLayout помещает любое дополнительное пространство между сеткой ячеек и краями контейнера."

1 голос
/ 29 декабря 2011

Это, вероятно, потому что GridBagLayout - это боль в заднице, и вы должны рассмотреть возможность использования других менеджеров компоновки.Или может быть, что вам нужно установить горизонтальное и вертикальное выравнивание ваших компонентов.Взгляните на setAlignmentX и setAlignmentY из JComponent.Всякий раз, когда у меня были компоненты с неправильным поведением, это потому, что я не выровнял все то же самое.

0 голосов
/ 07 мая 2014

Хотя Ответ Кавки решает требование наличия А на верхней части панели с помощью якоря, я считаю, что объявленный вертикальный клей на панели BoxLayout фактически ничего не делает. Итак, я собираюсь остановиться на этом, чтобы внести вклад в то, что я выяснил, используя веса и вертикальный клей в GridBagLayouts.

Поскольку GridBagLayout является сложным, может быть несколько причин, но, как уже указала Кавка:

ключ weightx и weighty изменение от значения по умолчанию 0,0 до ненулевое значение является ключом.

Как указано в учебной документации по Java по GridBagConstraints , в разделе описания JavaDoc для GridBagLayout и в описании конкретного параметра в JavaDoc для GridBagConstraints .

Если все веса равны нулю, все дополнительное пространство появляется между сетками ячейки и

  • для weightx дополнительное пространство появляется дополнительно между левым и правым краями.
  • для весомый дополнительное пространство появляется дополнительно между верхним и нижним краями.

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

Взяв за исходный код исходный код и немного расширив его, чтобы продемонстрировать возможности вертикального склеивания в сочетании с весами. Этот код будет позиционировать A на 20% от верхней части панели, поддерживая это соотношение при изменении размера:

import javax.swing.*;
import java.awt.*;

public class Test {
    public static void main(String[] args) {   
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel gridBagPanel = new JPanel();
        gridBagPanel.setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();

        gbc.gridy = 0;
        gbc.weighty = 0.2;
        gridBagPanel.add(Box.createVerticalGlue(), gbc);
        gbc.gridy = 1;
        gbc.weighty = 0;
        gridBagPanel.add(new JLabel("A"), gbc);
        gbc.gridy = 2;
        gbc.weighty = 0.8;
        gridBagPanel.add(Box.createVerticalGlue(), gbc);

        frame.setContentPane(gridBagPanel);
        frame.setSize(800, 200);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

Подробнее о том, как работает клей, см. Учебное руководство по Java по использованию BoxLayout, раздел Filler

...