Java GridBagLayout对齐按钮

时间:2015-04-14 17:34:18

标签: java swing button layout-manager 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();
            }
        });
    }
}

显示: wrong buttons aligning 我对其他方法(例如GridLayout)不感兴趣,我想知道我错过了什么。

2 个答案:

答案 0 :(得分:2)

GridbagLayout似乎需要一行,其中一个组件占据该行中的所有列。请参阅:Why does this GridBagLayout not appear as planned?了解此解决方案的基础。

请注意,水平支柱尺寸选择为“Logout”按钮大小的一半,以便两个单元格跨越注销按钮的宽度,以提供所需组件的居中。

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();
            }
        });
    }
}

答案 1 :(得分:2)

在某些情况下,GridBagLayout可能是一种奇怪的动物。但无论如何,只有在“跨越”列中存在需要一定宽度的实际组件时,网格宽度才有效(例如,如果您说gridx = 0且gridwidth = 2,则列0具有组件并且“跨越” “列是第1列。”

在您的情况下,第2,4和2列7没有组件,所以它们的宽度设置为0.另外,第5列的宽度也是0,因为第6列为出口房间按钮提供了足够的宽度,所以最后你会得到你看到的结果。

现在,不确定你想要实现的那种布局(我看到了你的截图,但是当面板在宽度上折叠/展开时它应该如何表现?)。所以在下面找到一个更接近你所描述的例子(虽然我觉得它不太好)

Example

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();
            }
        });
    }
}