使用GridBagLayout如何让组件跨多列?Java Swing计算器布局问题
问题根因
该问题由GridBagLayout的权重分配规则导致:
你给所有组件设置了相同的weightx值,跨2列的文本框权重会被拆分到它覆盖的后两列,最终三列实际权重比例不相等,加上文本框本身首选宽度远大于按钮,初始列宽计算就会出现偏差,拉伸时第一列就会出现异常的尺寸变动。
修复方案
仅需调整weightx的配置,保证三列权重完全相等即可:
- 所有单列组件的
weightx统一设为1(权重为相对比例,不需要设置过大的数值) - 跨2列的文本框单独设置
weightx=2,这样它覆盖的两列各分到1的权重,和第一列权重完全相等
修改后完整代码
import java.awt.Font; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import javax.swing.*; public class Calculator extends JFrame{ JButton but1, but2, but3, but4, but5, but6, but7, but8, but9, but0, butPlus, butMinus, clearAll; JTextField textResult; int num1, num2; public static void main(String[] args){ new Calculator(); } public Calculator(){ this.setSize(400,400); this.setLocationRelativeTo(null); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setTitle("Calculator"); JPanel thePanel = new JPanel(); thePanel.setLayout(new GridBagLayout()); GridBagConstraints gridConstraints = new GridBagConstraints(); gridConstraints.gridx = 0; gridConstraints.gridy = 0; gridConstraints.gridwidth = 1; gridConstraints.gridheight = 1; // 调整weightx和weighty为相对比例值 gridConstraints.weightx = 1; gridConstraints.weighty = 1; gridConstraints.insets = new Insets(5, 5, 5, 5); gridConstraints.anchor = GridBagConstraints.CENTER; gridConstraints.fill = GridBagConstraints.BOTH; textResult = new JTextField("0", 20); Font font = new Font("Helvetica", Font.PLAIN, 18); textResult.setFont(font); // 可选优化:文本右对齐,禁止直接编辑,更符合计算器使用习惯 textResult.setHorizontalAlignment(JTextField.RIGHT); textResult.setEditable(false); but1 = new JButton("1"); but2 = new JButton("2"); but3 = new JButton("3"); but4 = new JButton("4"); but5 = new JButton("5"); but6 = new JButton("6"); but7 = new JButton("7"); but8 = new JButton("8"); but9 = new JButton("9"); butPlus = new JButton("+"); but0 = new JButton("0"); butMinus = new JButton("-"); clearAll = new JButton("C"); thePanel.add(clearAll, gridConstraints); gridConstraints.gridx = 1; gridConstraints.gridwidth = 2; // 跨2列的文本框单独设置weightx为2,保证覆盖的两列各分1权重 gridConstraints.weightx = 2; thePanel.add(textResult, gridConstraints); gridConstraints.gridwidth = 1; // 恢复单列组件的weightx为1 gridConstraints.weightx = 1; gridConstraints.gridx = 0; gridConstraints.gridy = 1; thePanel.add(but1, gridConstraints); gridConstraints.gridx = 1; thePanel.add(but2, gridConstraints); gridConstraints.gridx = 2; thePanel.add(but3, gridConstraints); gridConstraints.gridx = 0; gridConstraints.gridy = 2; thePanel.add(but4, gridConstraints); gridConstraints.gridx = 1; thePanel.add(but5, gridConstraints); gridConstraints.gridx = 2; thePanel.add(but6, gridConstraints); gridConstraints.gridx = 0; gridConstraints.gridy = 3; thePanel.add(but7, gridConstraints); gridConstraints.gridx = 1; thePanel.add(but8, gridConstraints); gridConstraints.gridx = 2; thePanel.add(but9, gridConstraints); gridConstraints.gridx = 0; gridConstraints.gridy = 4; thePanel.add(butPlus, gridConstraints); gridConstraints.gridx = 1; thePanel.add(but0, gridConstraints); gridConstraints.gridx = 2; thePanel.add(butMinus, gridConstraints); this.add(thePanel); this.setVisible(true); } }
修改后无论怎么拉伸窗口,三列都会保持1:1:1的等宽比例,第一列组件不会再出现异常尺寸变动,文本框也会正常跨2列展示。
内容的提问来源于stack exchange,提问作者Zare
相关产品推荐
相关产品推荐

