简体   繁体   English

Java GridBagLayout对齐按钮

[英]Java GridBagLayout Aligning buttons

I have a problem with GridbagLayout; 我对GridbagLayout有问题; I've 5 buttons and I want to have them in this way: 我有5个按钮,我想以这种方式使用它们: 目标按钮的位置

I've already tried different approaches but no one works in the correct way. 我已经尝试了不同的方法,但是没有人以正确的方式工作。

For example: 例如:

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

Appears: 显示: 错误的按钮对齐 I'm not interested in other approaches (such as GridLayout), I'd like to know what I'm missing. 我对其他方法(例如GridLayout)不感兴趣,我想知道自己缺少什么。

GridbagLayout seems to require a row where a component occupies all of the columns in the row. GridbagLayout似乎需要一行,其中组件占据该行中的所有列。 See: Why does this GridBagLayout not appear as planned? 请参阅: 为什么此GridBagLayout不能按计划显示? for the basis of this solution. 作为该解决方案的基础。

Note the that horizontal strut size was choosen to be half the size of the "Logout" button so that two cells with span the width of the logout button to give the centering of components that you desire. 请注意,水平支柱的大小选择为“注销”按钮的大小的一半,以便两个单元格具有“注销”按钮的宽度,以使所需组件居中。

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

GridBagLayout can be a strange animal in some cases. 在某些情况下,GridBagLayout可能是一种奇怪的动物。 But anyway, gridwidth is something that works, only if there is an actual component that requires some width within the "spanned" column (for example, if you say gridx=0 and gridwidth=2, column 0 has a component and the "spanned" column is column 1). 但是无论如何,只有在“ spanned”列中有一个实际组件需要一定宽度的情况下,gridwidth才起作用(例如,如果您说gridx = 0且gridwidth = 2,则列0具有一个组件,而“ spanned” “列是第1列)。

In your case, column 2, 4 & 7 have no components, so their width is set to 0. Additionnaly, column 5 also gets a width of 0, because column 6 provides enough witdth to the exit room button, so in the end you get the result you see. 在您的情况下,第2列,第4列和第7列没有组件,因此它们的宽度设置为0。此外,第5列的宽度也为0,因为第6列为退出房间按钮提供了足够的技巧,所以最终得到您看到的结果。

Now, not sure of the kind of layout you are trying to achieve (I saw your screenshot, but how should it behave when the panel collapses/expands in width?). 现在,不确定要尝试实现的布局类型(我看到了您的屏幕截图,但是当面板折叠/扩展宽度时应该如何表现?)。 So find below, an example that comes a bit closer to what you describe (although I don't find it very nice) 因此,请在下面找到一个与您描述的内容更接近的示例(尽管我觉得它不是很好)

例

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM