【问题标题】:From Grid Layout to GridBag Layout从网格布局到 GridBagLayout
【发布时间】:2013-12-10 05:43:56
【问题描述】:

我对 Java Swing 比较陌生,我在理解网格布局如何做某些事情时遇到了一些困难,如果不能,那么据说更强大的 gridbag 布局可以做到这一点。

这是我尝试使用网格布局的程序

import javax.swing.*;
import java.awt.*;
//import java.awt.event.*;
public class Swing24
{
public static void main(String[] args)
{
JFrame f1= new JFrame("Grid Layout Test");

f1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f1.setResizable(true);
f1.setLocation(500,200);
f1.setSize(600,600);

JPanel p1 = new JPanel();
p1.setBackground(Color.black);
f1.add(p1);


JButton b1= new JButton("Button 1");
b1.setBackground(Color.white);

JButton b2= new JButton("Button 2");
b2.setBackground(Color.white);

JButton b3= new JButton("Button 3");
b3.setBackground(Color.white);

JLabel lb1=new JLabel(" Label 1");
lb1.setForeground(Color.orange);
//lb1.setOpaque(true);
lb1.setBackground(Color.yellow);

JLabel lb2=new JLabel(" Label 2");
lb2.setBackground(Color.orange);
lb2.setOpaque(true);


GridLayout glm1=new GridLayout(2,3,0,0); 
p1.setLayout(glm1);

p1.add(b1);
p1.add(b2);
p1.add(b3);
p1.add(lb1);
p1.add(lb2);


f1.setVisible(true);

}
}

上面的程序允许我将容器分成 2 行和 3 列。基本上我可以用网格布局将一个容器分成 m 行和 n 列。但它会连续添加组件(按钮和标签)。

问题1:如何在大小为(10,10)的网格中直接向单元格(4,3)添加按钮? 问题2:一个按钮可以在网格布局中占据多个单元格吗?

如果以上任何一个问题的答案都不可能,那么 gridbag 布局如何帮助解决问题。 我尝试使用带有按钮的网格包布局。但它被放置在中心!比如说,我怎样才能把它放在一个容器中的单元格(4,3)中,该容器可以分为大小(10,10)

【问题讨论】:

    标签: java swing layout


    【解决方案1】:

    1) 你不能将组件添加到特定的单元格,但是在that question 你可以找到一些技巧。

    2)这是另一个trick,在单元格内嵌套了 lyout,用于合并。

    您可以在GridBagLayout 的帮助下做所有您想做的事。观看GridBagConstraints 它可以帮助您正确布局组件。

    查看GridBagConstraints的属性:

    gridwidthgridheightgridxgridyanchor

    但是,如果您只想向容器中添加一个组件,则需要在 cell(4,3) 周围留出一些空格。

    另请阅读GridBagLayout 的教程。

    编辑:你可以尝试这样的事情

    public class Form extends JFrame {
    
        public Form() {
            getContentPane().setLayout(new GridBagLayout());
            GridBagConstraints c = new GridBagConstraints();
            c.gridx = 0;
            c.gridy = 0;
            c.weightx = 1;
            c.weighty = 1;
            for(int i =0;i<10;i++){
                c.gridx = i;
                for(int j =0;j<10;j++){
                    c.gridy = j;
                    if(i == 3 && j == 2){
                        c.fill = GridBagConstraints.NONE;
                        getContentPane().add(new JButton("btn"),c);
                    } else {
                        c.fill = GridBagConstraints.BOTH;
                        JPanel p = new JPanel();
                        p.setBorder(BorderFactory.createLineBorder(Color.red));
                        getContentPane().add(p,c);
                    }
                }
            }
    
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            pack();
            setLocationRelativeTo(null);
        }
    
    
        public static void main(String[] args) throws Exception {
            SwingUtilities.invokeLater(new Runnable() {
    
                public void run() {
                    new Form().setVisible(true);
                }
            });
        }   
    }
    

    EDIT2:它不是真正的单元格(4,3),而是相同的比例

    public Form() {
        getContentPane().setLayout(new GridBagLayout());
        GridBagConstraints c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = 0;
        c.weightx = 0.2;
        c.weighty = 0.3;
        c.fill = GridBagConstraints.BOTH;
        getContentPane().add(new JLabel(" "),c);
    
        c.gridx++;
        c.gridy++;
        c.fill = GridBagConstraints.NONE;
        getContentPane().add(new JButton("btn"),c);
    
        c.weightx = 0.7;
        c.weighty = 0.6;
        c.gridx++;
        c.gridy++;
        c.fill = GridBagConstraints.BOTH;
        getContentPane().add(new JLabel(" "),c);
    
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        pack();
        setLocationRelativeTo(null);
    }
    

    或真正的单元格(4,3),但超过 3 个组件且少于 100 个:

    public Form() {
        getContentPane().setLayout(new GridBagLayout());
        GridBagConstraints c = new GridBagConstraints();
        c.gridx = 0;
        c.gridy = 0;
        c.weightx = 1;
        c.weighty = 1;
        for(int i =0;i<2;i++){
            getContentPane().add(new JLabel(" "),c);
            c.gridx++;
        }
    
        for(int i =0;i<3;i++){
            getContentPane().add(new JLabel(" "),c);
            c.gridy++;
        }
    
        c.gridx = 3;
        c.gridy = 4;
        getContentPane().add(new JButton("btn"),c);
    
        for(int i =0;i<7;i++){
            getContentPane().add(new JLabel(" "),c);
            c.gridx++;
        }
    
        for(int i =0;i<6;i++){
            getContentPane().add(new JLabel(" "),c);
            c.gridy++;
        }
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        pack();
        setLocationRelativeTo(null);
    }
    

    【讨论】:

    • 非常感谢您的回答。稍后我会回到网格布局,但是您能更详细地解释一下网格包布局吗?我确实阅读了 oracle 网站教程。我只是问,因为这对我来说不是很清楚。也许以对话的形式提供一点反馈会更好。
    • 也许是在网格包布局中仅使用一个按钮并将按钮放置在网格大小 (10,10) 的单元格 (4,3) 中的代码示例?
    • 非常感谢您的编辑。我认为这个程序创建了一个 100 个面板,然后在 (4,3) 的面板上放置一个按钮。但是有没有办法只使用一个或两个组件?你提到了一些关于间距技巧的事情。我想使用少量组件并直接操作它们的原因是因为我想从 JVM 的角度思考并了解 c.gridx、c.gridy、c.weightx 等的工作原理。为什么他们都被放在中心位置。为什么你的 panel(0,0) 可以放在左上角,而我的即使 gridx=0 也能放在中间?
    • 后面我给你举个例子,有3个组件,你可以自己试试,你需要使用weightx和weighty属性。我的手机上没有 IDE:)
    • 好的,谢谢,我会等。到那时,我会继续尝试。我无法理解 weightx 和 weighty 的含义。
    猜你喜欢
    • 2013-04-30
    • 2011-10-28
    • 2013-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-29
    • 2023-03-10
    • 1970-01-01
    相关资源
    最近更新 更多