【问题标题】:Java, GridBagLayout. How add components right to other componentJava,网格包布局。如何将组件添加到其他组件
【发布时间】:2021-08-02 18:33:03
【问题描述】:

我正在学习 JSwing,我发现了 GridBagLayout。

我正在尝试创建一个简单的计算器,我通过添加多个 JPanel 设置每个preferedSize 来做到这一点,但是当我调整窗口框架的大小时,面板也不会调整大小。 然后我发现了 GridBagLayout。

但这就是我得到的:Wrong calculator with GridBagLayout

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

public class Calc extends JFrame {

private final int  WIDTH = 300;
private final int  HEIGHT = 450;

public Calc(){

    setSize(WIDTH, HEIGHT);

    JPanel mainPanel = new JPanel();
    mainPanel.setLayout(new BorderLayout());




    mainPanel.add(createButtons(), BorderLayout.SOUTH);


    add(mainPanel);


}

private  JPanel createButtons(){

    JPanel panel = new JPanel();

    GridBagLayout layout = new GridBagLayout();

    panel.setLayout(layout);


    GridBagConstraints g = new GridBagConstraints();

    g.gridx = 0;
    g.gridy = 0;

    for(int i = 0; i < 9; i++){

        panel.add(new JButton(""+i), g);
        g.gridx++;
        if(g.gridx == 3) {
            g.gridx = 0;
            g.gridy++;
        }

    }


    return panel;



}


public static void main(String... args){

    Calc calc = new Calc();
    calc.setVisible(true);

}

}

应该是这样的: Right calculator

我试过了:

  • 设置锚点...但它不起作用,
  • 创建多个 JPanel(一个带有 GridLayout)但不起作用

如果你不想用勺子编码,没关系.. 但我应该从哪里开始呢?

编辑: 我弄清楚如何排列按钮......但我无法将标题设置为填充所有 x 轴: 代码:

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

public class ButtonPanel extends JPanel {

JPanel top;
JPanel left;
JPanel right;


private class CButton extends JButton{

    private Operation operation;

    public CButton(){

    }



}

public ButtonPanel(){

    initComponent();
    initLayout();
}

private void initLayout() {

    GridBagLayout layout = new GridBagLayout();
    this.setLayout(layout);

    layout.columnWeights = new double[] {3,1};
    layout.rowWeights = new double[] {1, 1};

    GridBagConstraints c = new GridBagConstraints();
    c.gridx = 0;
    c.gridy = 0;
    c.fill = GridBagConstraints.BOTH;

    c.weightx = 5;
    this.add(top, c);
    c.gridy++;
    c.weighty=1;
    this.add(left, c);
    c.gridx++;
    this.add(right, c);




}

private void initComponent() {

    top = new JPanel();

    top.setLayout(new GridLayout(1, 3));

    for(int i = 0; i < 3; i++){
        top.add(new JButton("bbb"));
    }



    left = new JPanel();

    left.setLayout(new GridLayout(3,3));
    for(int i = 0; i < 9; i++){

        left.add(new JButton(""+i));

    }

    right = new JPanel();
    right.setLayout(new GridLayout(3,1));
    for(int i = 0; i < 3; i++){
        JButton btn = new JButton("aa");
        right.add(btn);

    }

}

public static void main(String[] args) {
    JFrame frame = new JFrame("test");
    frame.setLayout(new BorderLayout());
    frame.add(new ButtonPanel(), BorderLayout.SOUTH);
    frame.setSize(300, 450);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);
}

}

应该是:Image

【问题讨论】:

    标签: java swing layout-manager gridbaglayout


    【解决方案1】:

    您可能可以在一个面板中完成所有操作,其中一些按钮跨越多个列。

    所以我给你一个不同的例子来使用单个 GridBagLayout 布局按钮,在这里你可以将你的按钮排列定义为一个值数组,检查它是否可以成为你项目的一个很好的起点。

    package test;
    
    import static test.Calculator.Buttons.*;
    
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.util.HashMap;
    import java.util.Map;
    
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    
    public class Calculator extends JPanel {
        //Here define all possible buttons with labels
        public enum Buttons {
            PERCENT("%"), CE("CE"), CLEAR("C"),
            ONE("1"), TWO("2"), THREE("3"), FOUR("4"), FIVE("5"), SIX("6"), SEVEN("7"), EIGHT("8"), NINE("9"), ZERO("0"),
            ADD("+"), SUB("-"), MULT("x"), DIV("/"), RESULT("="), DECPOINT(".");
            
            protected String text;
            
            Buttons(String txt) {
                this.text=txt;
            }
            
            public String getText() {
                return text;
            }
        };
        
        //This array contains your keypad layout, contiguous repeated elements will span across multiple columns (e.g. ZERO). 
        protected Buttons[][] keyPad = {
            {PERCENT, CE, CLEAR, DIV},
            {SEVEN, EIGHT, NINE, MULT},
            {FOUR, FIVE, SIX, ADD},
            {ONE, TWO, THREE, SUB},
            {ZERO, ZERO, DECPOINT, RESULT}
        };
        
        Map<JButton, Buttons> sourceMap=new HashMap<>();
        
        ActionListener padListener=new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                onKeyPadPressed(sourceMap.get(e.getSource()));
            }
        };
        
        public Calculator() {
            setLayout(new GridBagLayout());
            GridBagConstraints c=new GridBagConstraints();
            c.weightx=1.0;
            c.weighty=1.0;
            c.fill=GridBagConstraints.BOTH;
            
            for (int y=0;y<keyPad.length;y++) {
                for (int x=0;x<keyPad[y].length;) {
                    Buttons b=keyPad[y][x];
                    if (b==null) {
                        continue;
                    }
                    JButton btn=new JButton(b.getText());
                    c.gridx=x;
                    c.gridy=y;
    
                    c.gridwidth=0;
                    while(x<keyPad[y].length&&keyPad[y][x]==b) {
                        c.gridwidth++;
                        x++;
                    }
                    add(btn,c);
                    
                    sourceMap.put(btn,b);
                    btn.addActionListener(padListener);
                }
            }
            
        }
        
        //Callback method, whenever a button is clicked you get the associated enum value here
        protected void onKeyPadPressed(Buttons b) {
            System.out.println("Pressed "+b);
            switch (b) {
    //          case ZERO:
    //          .... here your logic
            }
        }
        
        public static void main(String[] args) {
            JFrame frame=new JFrame("Calculator");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setContentPane(new Calculator());
            frame.pack();
            frame.setVisible(true);
        }
    }
    

    上面的代码产生了这个结果,但是添加/删除按钮和更改布局真的很容易。

    【讨论】:

    • 但是以更抽象的方式...您能给我一些建议或使用 GridBagLayout 的“入门工具包”吗?我对布局管理器有一些疑问。喜欢:1)我应该将主容器的布局管理器设置为gridbaglayout,这样我可以设置权重。 2) 权重就像整个空间的一小部分,对吧?
    • @andre 官方的Java教程很详细:docs.oracle.com/javase/tutorial/uiswing/layout/gridbag.html;使用此布局,您可以使用网格,其中每个组件也可以跨越多个列/行(gridwidth, gridheight 属性)。列/行的基本宽度/高度由组件的首选大小决定,但是通过计算使用 weightx/weighty,您可以在列/行成比例。
    • @andre 要理解的另一点是,这些属性定义了组件所在的“单元格”的大小,但是要将组件定位在单元格内,您可以使用锚点和/或填充属性(在我的示例中填充为 BOTH,因此无需锚定,因为组件将填充所有可用空间)
    • 好,tysm,我去看看官方教程,ty又来了!
    猜你喜欢
    • 2016-08-09
    • 2017-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-17
    • 2023-03-14
    • 2015-08-05
    相关资源
    最近更新 更多