如何在彼此下方对齐多个元素?

Posted

技术标签:

【中文标题】如何在彼此下方对齐多个元素?【英文标题】:How to align multiple elements below each other? 【发布时间】:2021-03-09 20:48:31 【问题描述】:

我很难将 Swing 元素流对齐到彼此下方。使用GridLayout 对我没有帮助,因为它将屏幕划分为大小相等的行。我需要在每一行放置一个组件,下一个组件应该在最后一个组件的最底部。

我的问题是,如果问题的选择多于一行,这种布局将它们挤压到行中,图片和问题“3+3?”之间存在巨大差距?

【问题讨论】:

您能否添加您当前拥有的 UI 的屏幕截图并解释问题所在? i.stack.imgur.com/nGrlF.png 1) 为了尽快获得更好的帮助,请发帖 minimal reproducible example 或 Short, Self Contained, Correct Example。 2) 要将单个列GridLayout 压缩到容器顶部或底部所需的最小值,请将具有网格布局的面板放入PAGE_STARTPAGE_END 约束BorderLayout ..跨度> 【参考方案1】:

您可以为此使用GridBagLayout。这是非常容易使用。这是一个示例实现。

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRadioButton;

class MyFrame extends JFrame 

    public MyFrame() 
        JPanel panel = new JPanel(new GridBagLayout());

        JLabel image = new JLabel();
        image.setIcon(new ImageIcon(getClass().getResource("/image.png")));

        JLabel question = new JLabel("3 + 3 = ?");

        JRadioButton rb1 = new JRadioButton("5");
        JRadioButton rb2 = new JRadioButton("3");
        JRadioButton rb3 = new JRadioButton("6");
        JRadioButton rb4 = new JRadioButton("9");
        JRadioButton rb5 = new JRadioButton("23");

        GridBagConstraints c = new GridBagConstraints();

        c.gridx = 0;//set the x location of the grid for the next component
        c.gridy = 0;//set the y location of the grid for the next component
        panel.add(image,c);

        c.gridy = 1;//change the y location
        c.anchor=GridBagConstraints.WEST;//left align components after this point
        panel.add(question,c);

        c.gridy = 2;//change the y location
        panel.add(rb1,c);

        c.gridy = 3;//change the y location
        panel.add(rb2,c);

        c.gridy = 4;//change the y location
        panel.add(rb3,c);

        c.gridy = 5;//change the y location
        panel.add(rb4,c);

        c.gridy =6;//change the y location
        panel.add(rb5,c);

        this.getContentPane().add(panel);

        this.setDefaultCloseOperation(EXIT_ON_CLOSE);
        this.pack();
    

    public static void main(String[] args) 
        MyFrame myFrame = new MyFrame();
        myFrame.setVisible(true);
    


参考:https://docs.oracle.com/javase/tutorial/uiswing/layout/gridbag.html

【讨论】:

它可以工作,但问题总是在图片之后的组件居中。图片后的组件应该保持对齐。我做不到 c.anchor 应设置为对齐。 'c.achor' 不起作用。如果您执行代码,当您调整 frame 的大小时,此布局会将组件置于框架的中心。 GridBagConstraints c = new GridBagConstraints(); 行之后添加c.weightx = 1;。然后RadioButtons 将粘在框架的左侧。 PS:我忘了在最后的评论中告诉你。 c.anchor 只对齐panel 内的元素。如果你想在frame 内对齐RadioButtons,那么当框架调整大小时,你必须调整panel 的大小,就像我在上一条评论中所做的那样或者将frame的布局设置为GridBagLayout后,将imageRadioButtons分别添加到frame中。【参考方案2】:

有许多可能的解决方案,但可能最有用的是GridBagLayout,虽然复杂,但非常灵活。

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test 

    public static void main(String[] args) 
        new Test();
    

    public Test() 
        EventQueue.invokeLater(new Runnable() 
            @Override
            public void run() 
                try 
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                 catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) 
                    ex.printStackTrace();
                

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            
        );
    

    public class TestPane extends JPanel 

        public TestPane() 
            setLayout(new GridBagLayout());

            JLabel label = new JLabel("Cool");
            label.setFont(label.getFont().deriveFont(Font.BOLD, 48f));
            label.setOpaque(true);
            label.setBackground(Color.WHITE);

            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridwidth = GridBagConstraints.REMAINDER;

            add(label, gbc);
            add(new JLabel("3+5="), gbc);
            add(new JCheckBox("5"), gbc);
            add(new JCheckBox("3"), gbc);
            add(new JCheckBox("6"), gbc);
            add(new JCheckBox("9"), gbc);
            add(new JCheckBox("23"), gbc);
        

    


您甚至可以使用anchor 将组件移动到单元格内的不同位置...

gbc.anchor = GridBagConstraints.WEST;

显然,这些也可以应用于单个组件,因此每个组件都可以有自己的一组约束

查看How to Use GridBagLayout了解更多详情

【讨论】:

如果正确答案是其中一个选项,它也会很有用。 这绝对应该是公认的答案。我在我的应用程序中使用了相同的方法,我需要在块中的JPanel 中显示我的元素。也许只有一个问题:我可以,为每个元素定义不同的GridBagConstraints,或者我可以接受一个。提前谢谢你。 @rchrd 取决于您的需要。 GridBagLayout 为每个组件复制约束本身

以上是关于如何在彼此下方对齐多个元素?的主要内容,如果未能解决你的问题,请参考以下文章

如何在表格下方居中对齐按钮?

在整个屏幕上垂直对齐元素[重复]

如何在不使用 Flexbox 的情况下水平对齐元素?

如何使元素响应式在左侧对齐

如何使用 HTML 和 CSS 让多个元素在顶部相互对齐?

如何使用自动布局将图像彼此水平对齐