Java GridBagLayout Выравнивание кнопок

У меня проблема с GridbagLayout; У меня есть 5 кнопок, и я хочу, чтобы они были такими: Target ButtonDisposition

Я уже пробовал разные подходы, но никто не работает правильно.

Например:

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TestGridBagLayout {

    protected void initUI() {
        JFrame frame = new JFrame("Test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JPanel southPanel = new JPanel(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();

        gbc.gridwidth = 2;
        gbc.gridy = 0;
        JButton enterRoom = new JButton("Enter room");
        JButton exitRoom = new JButton("Exit room");
        JButton login = new JButton("Login");
        JButton logout = new JButton("Logout");
        JButton whoIsIn = new JButton("Who is in");

        gbc.gridx = 1;
        southPanel.add(enterRoom, gbc);

        gbc.gridx = 5;
        southPanel.add(exitRoom, gbc);

        gbc.gridy = 1;

        gbc.gridx = 0;
        southPanel.add(login, gbc);

        gbc.gridx = 3;
        southPanel.add(logout, gbc);

        gbc.gridx = 6;
        southPanel.add(whoIsIn, gbc);

        frame.add(southPanel);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException,
            UnsupportedLookAndFeelException {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new TestGridBagLayout().initUI();
            }
        });
    }
}

Появляется: неправильное выравнивание кнопокМеня не интересуют другие подходы (например, GridLayout), я хотел бы знаю, что мне не хватает.


person Jacopo    schedule 14.04.2015    source источник
comment
Чтобы быстрее получить помощь, опубликуйте MCVE (минимальный полный проверяемый пример) или SSCCE (краткий, автономный, правильный пример).   -  person Andrew Thompson    schedule 14.04.2015
comment
@AndrewThompson Я поставил mcve, который я сделал, на свою сторону. Я думаю, что это воспроизводит проблему, которую видит ОП. Скорее всего, проблема просто в том, что ширина сетки применяется только в том случае, если в другой строке для составного столбца есть другой компонент.   -  person Guillaume Polet    schedule 14.04.2015


Ответы (2)


В некоторых случаях GridBagLayout может быть странным животным. Но в любом случае, gridwidth — это то, что работает, только если есть фактический компонент, требующий некоторой ширины в «составном» столбце (например, если вы говорите, что gridx=0 и gridwidth=2, в столбце 0 есть компонент, а «составной» столбец "столбец - это столбец 1).

В вашем случае столбцы 2, 4 и 7 не имеют компонентов, поэтому их ширина равна 0. Кроме того, столбец 5 также получает ширину 0, потому что столбец 6 обеспечивает достаточную ширину для кнопки выхода из комнаты, поэтому в конце вы получить результат, который вы видите.

Теперь не уверен, какой макет вы пытаетесь достичь (я видел ваш скриншот, но как он должен вести себя, когда панель сворачивается/расширяется по ширине?). Итак, найдите ниже пример, который немного ближе к тому, что вы описываете (хотя я не нахожу его очень хорошим)

Пример

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TestGridBagLayout2 {

    protected void initUI() {
        JFrame frame = new JFrame("Test");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JPanel southPanel = new JPanel(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();

        gbc.gridy = 0;
        JButton enterRoom = new JButton("Enter room");
        JButton exitRoom = new JButton("Exit room");
        JButton login = new JButton("Login");
        JButton logout = new JButton("Logout");
        JButton whoIsIn = new JButton("Who is in");

        gbc.gridx = 0;
        gbc.weightx = 1.0;
        gbc.anchor = GridBagConstraints.EAST;
        southPanel.add(enterRoom, gbc);

        gbc.anchor = GridBagConstraints.WEST;
        gbc.gridx = 2;
        southPanel.add(exitRoom, gbc);

        gbc.gridy = 1;

        gbc.gridx = 0;
        southPanel.add(login, gbc);

        gbc.weightx = 0;
        gbc.gridx = 1;
        southPanel.add(logout, gbc);

        gbc.weightx = 1.0;
        gbc.anchor = GridBagConstraints.EAST;
        gbc.gridx = 2;
        southPanel.add(whoIsIn, gbc);

        frame.add(southPanel);
        frame.pack();
        frame.setSize(frame.getWidth() * 4 / 3, frame.getHeight());
        frame.setMinimumSize(frame.getSize());
        frame.setVisible(true);
    }

    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException,
            UnsupportedLookAndFeelException {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new TestGridBagLayout().initUI();
            }
        });
    }
}
person Guillaume Polet    schedule 14.04.2015

GridbagLayout, по-видимому, требует строки, в которой компонент занимает все столбцы в строке. См.: Почему этот GridBagLayout не отображается, как планировалось? для основу этого решения.

Обратите внимание, что размер горизонтальной стойки был выбран равным половине размера кнопки «Выход», так что две ячейки с охватом ширины кнопки выхода обеспечивают центрирование компонентов, которое вы хотите.

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

public class SSCCE extends JPanel
{
    public SSCCE()
    {
        JButton enterRoom = new JButton("Enter room");
        JButton exitRoom = new JButton("Exit room");
        JButton login = new JButton("Login");
        JButton logout = new JButton("Logout");
        JButton whoIsIn = new JButton("Who is in");

        setLayout( new GridBagLayout() );
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.insets = new Insets(5, 0,5, 0);

        gbc.gridwidth = 2;

        gbc.gridx = 1;
        gbc.gridy = 0;
        add(enterRoom, gbc);

        gbc.gridx = 5;
        gbc.gridy = 0;
        add(exitRoom, gbc);

        gbc.gridx = 0;
        gbc.gridy = 1;
        add(login, gbc);

        gbc.gridx = 3;
        gbc.gridy = 1;
        add(logout, gbc);

        gbc.gridx = 6;
        gbc.gridy = 1;
        add(whoIsIn, gbc);

        //  Add dummy components so every cell has a component.

        gbc.insets = new Insets(0, 0, 0, 0);
        gbc.gridwidth = 1;
        gbc.gridy = 2;
        int strutWidth = logout.getPreferredSize().width / 2;

        for (int i = 0; i < 8; i++)
        {
            gbc.gridx = i;
            add(Box.createHorizontalStrut(strutWidth), gbc);
        }
    }

    private static void createAndShowGUI()
    {
        JFrame frame = new JFrame("SSCCE");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new SSCCE(), BorderLayout.NORTH);
        frame.setLocationByPlatform( true );
        frame.pack();
        frame.setVisible( true );
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowGUI();
            }
        });
    }
}
person camickr    schedule 14.04.2015