Является ли это поведение Swing ошибкой? Загадочное выравнивание BoxLayout

Я экспериментировал с WindowBuilder Pro для макетов Java Swing и столкнулся с каким-то странным поведением, которое мне в итоге удалось свести к SSCCE. Рассмотрим исходный код ниже:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FlowLayout;

import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class WBPTest2 {
    private JFrame frame;
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    WBPTest2 window = new WBPTest2();
                    window.frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
    public WBPTest2() {
        initialize();
    }
    private void initialize() {
        frame = new JFrame();
        frame.setBounds(100, 100, 450, 300);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel panel = new JPanel();
        panel.setBackground(Color.RED);
        frame.getContentPane().add(panel, BorderLayout.CENTER);
        panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));

        JPanel panel_1 = new JPanel();
        panel_1.setBackground(Color.GREEN);
        panel_1.setMaximumSize(new Dimension(32767, 100));
        panel.add(panel_1);
        panel_1.setLayout(new BoxLayout(panel_1, BoxLayout.Y_AXIS));

        JPanel panel_2 = new JPanel();
        panel_2.setBackground(Color.BLUE);
        panel_2.setMaximumSize(new Dimension(32767, 100));
        panel.add(panel_2);
        panel_2.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
    }
}

Это дает следующий макет:

введите здесь описание изображения

По какой-то причине panel_1, зеленый, плывет вправо. Играя с некоторыми параметрами в коде, я могу найти только два способа полностью убить пробел слева от зеленой панели:

  • измените hgap и vgap в конструкторе panel_2 на 0.

OR

  • измените minimumSize из panel_2 на (0,0).

Выполните любое из этих действий, и мы получим следующее:

введите здесь описание изображения

Теперь возникает вопрос, с какой стати minimumSize или hgap для FlowLayout в panel_2 имеют какое-то отношение к предотвращению заполнения panel_1 полностью слева от родителя? Что, если я захочу minimumSize больше нуля и hgap больше нуля для моих FlowLayout в panel_2? Как тогда мне устранить пробел слева от моего BoxLayout в panel_1?

Независимо от того, что я делаю с panel_1, я не могу заставить его заполнить всю ширину своего родительского контейнера (если я не отредактирую panel_2, как описано выше). По иронии судьбы, если я установлю alignmentX для panel_1 на RIGHT_ALIGNMENT, он фактически сдвинется влево. Но щель все равно есть (только сейчас справа). По мере того, как я заполняю panel_1 контентом и увеличиваю его размер, зазор справа от него становится все меньше и меньше, но, к сожалению, никогда полностью не исчезает.

Это происходит не только тогда, когда panel_2 является FlowLayout... это также происходит с JScrollPane и многими другими типами... типами, которые обычно не имеют параметра hgap, что означает единственный способ исправить пробел слева от panel_1 заключается в том, чтобы изменить minimumSize нового контейнера на 0, что снова кажется глупым и не связанным, и, что наиболее важно, может не соответствовать моим намерениям.


person The111    schedule 17.01.2013    source источник
comment
Чтобы быстрее получить помощь, опубликуйте SSCCE. которое я в конечном итоге смог сократить до SSCCE. Ммм... хорошо. Вы в конечном итоге поделитесь этим SSCCE?   -  person Andrew Thompson    schedule 17.01.2013
comment
@AndrewThompson Извините, наверное, я неправильно понял SSCCE и подумал, что основного метода достаточно. Вот весь исходный код, прикрепленный сейчас. Спасибо.   -  person The111    schedule 17.01.2013
comment
@AndrewThompson Что вы подразумеваете под макетом null? учебники Oracle say Каждая панель содержимого инициализируется для использования Пограничный макет. Итак, я считаю, что мой макет frame не нулевой? Просто для усмешки я попытался явно изменить его на BorderLayout с помощью конструктора, и он по-прежнему работает так же. Кроме того, я не уверен, что понимаю, что вы предлагаете с BufferedImage, извините.   -  person The111    schedule 17.01.2013
comment
Я устанавливаю выравнивание X на панелях 1 и 2, и оно заполняет экран.   -  person BevynQ    schedule 17.01.2013
comment
@BevynQ Спасибо, похоже, это решает проблему. Опубликуйте это как ответ, и я приму его. :-) Не знаю, как я это пропустил. Тем не менее, кажется странным, что два выравнивания по центру в сумме дают один из элементов, выровненный по правому краю, но неважно.   -  person The111    schedule 17.01.2013
comment
@ The111 Плохо. Я неправильно понял вопрос. :П   -  person Andrew Thompson    schedule 17.01.2013


Ответы (1)


Установите выравнивание X на панелях 1 и 2, и оно заполнит экран.

Похоже, что два разных менеджера компоновки заставляют панель устанавливать разные значения выравнивания по умолчанию.

person BevynQ    schedule 17.01.2013