You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让Java计算器的JButton/JPanel随JFrame自适应调整大小?

实现Java计算器的自适应布局

你的计算器当前使用**绝对布局(null layout)**和固定坐标(setBounds),这是组件无法随窗口拉伸调整的核心原因。要实现自适应,需要替换为Java Swing提供的弹性布局管理器,以下是改造后的完整方案:

关键改造点

  • 移除frame.setLayout(null)和所有setBounds调用,改用BorderLayout作为窗口主布局,搭配GridLayout管理按钮面板
  • 使用BorderFactory.createEmptyBorder()设置整体边距,替代固定的坐标偏移
  • 用frame.pack()替代固定窗口尺寸,让窗口自动适配组件大小,同时设置最小尺寸避免窗口过小
  • 为按钮面板设置合适的行列数和间距,确保按钮均匀分配空间

改造后的完整代码

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class Calculator implements ActionListener {

    JFrame frame;
    JTextField textfield;
    JButton[] numberButtons = new JButton[10];
    JButton[] functionButtons = new JButton[14];
    JButton addButton, subButton, mulButton, divButton;
    JButton decButton, equButton, delButton, clrButton, negButton;
    JButton perButton, absButton, piButton, sqrButton, srootButton;

    // 补充原代码缺失的常量定义
    private final Color functionColor = new Color(255, 159, 67);
    private final Color numberColor = new Color(51, 51, 51);
    private final Color top = new Color(204, 204, 204);
    private final String add = "+", sub = "-", mul = "×", div = "÷", equ = "=", delete = "←";

    Font myFont = new Font("Helvetica", Font.BOLD, 30);

    double num1, num2, result = 0;
    char operator;

    Calculator() {
        frame = new JFrame("Calculator");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // 主布局改用BorderLayout,设置整体边距
        frame.setLayout(new BorderLayout(10, 10));
        frame.setBorder(BorderFactory.createEmptyBorder(25, 25, 25, 25));

        textfield = new JTextField();
        textfield.setFont(myFont);
        textfield.setEditable(false);
        textfield.setBorder(null);
        // 文本框放在顶部,自动填充水平空间
        frame.add(textfield, BorderLayout.NORTH);

        // 初始化功能按钮
        addButton = new JButton(add);
        addButton.setBackground(functionColor);
        subButton = new JButton(sub);
        subButton.setBackground(functionColor);
        mulButton = new JButton(mul);
        mulButton.setBackground(functionColor);
        divButton = new JButton(div);
        divButton.setBackground(functionColor);
        equButton = new JButton(equ);
        equButton.setBackground(functionColor);

        decButton = new JButton(".");
        decButton.setBackground(numberColor);
        decButton.setForeground(Color.WHITE);

        clrButton = new JButton("AC");
        clrButton.setBackground(top);
        clrButton.setForeground(Color.BLACK);
        negButton = new JButton("+/- ");
        negButton.setBackground(top);
        negButton.setForeground(Color.BLACK);
        delButton = new JButton(delete);
        delButton.setBackground(top);
        delButton.setForeground(Color.BLACK);

        perButton = new JButton("%");
        perButton.setBackground(top);
        perButton.setForeground(Color.BLACK);
        absButton = new JButton("|x|");
        absButton.setBackground(top);
        absButton.setForeground(Color.BLACK);
        piButton = new JButton("𝝅");
        piButton.setBackground(top);
        piButton.setForeground(Color.BLACK);
        sqrButton = new JButton("x²");
        sqrButton.setBackground(top);
        sqrButton.setForeground(Color.BLACK);
        srootButton = new JButton("√x");
        srootButton.setBackground(top);
        srootButton.setForeground(Color.BLACK);

        // 功能按钮数组赋值
        functionButtons[0] = addButton;
        functionButtons[1] = subButton;
        functionButtons[2] = mulButton;
        functionButtons[3] = divButton;
        functionButtons[4] = decButton;
        functionButtons[5] = equButton;
        functionButtons[6] = delButton;
        functionButtons[7] = clrButton;
        functionButtons[8] = negButton;
        functionButtons[9] = perButton;
        functionButtons[10] = piButton;
        functionButtons[11] = absButton;
        functionButtons[12] = sqrButton;
        functionButtons[13] = srootButton;

        // 为功能按钮添加监听和样式
        for (int i = 0; i < 14; i++) {
            functionButtons[i].addActionListener(this);
            functionButtons[i].setFont(myFont);
            functionButtons[i].setFocusable(false);
        }

        // 初始化数字按钮
        for (int i = 0; i < 10; i++) {
            numberButtons[i] = new JButton(String.valueOf(i));
            numberButtons[i].addActionListener(this);
            numberButtons[i].setFont(myFont);
            numberButtons[i].setFocusable(false);
            numberButtons[i].setBackground(numberColor);
            numberButtons[i].setForeground(Color.WHITE);
        }

        // 创建中间面板容器,用垂直BoxLayout管理三个按钮面板
        JPanel centerContainer = new JPanel();
        centerContainer.setLayout(new BoxLayout(centerContainer, BoxLayout.Y_AXIS));
        centerContainer.setBorder(BorderFactory.createEmptyBorder(20, 0, 0, 0));

        // 顶部功能按钮面板
        JPanel topPan = new JPanel();
        topPan.setLayout(new GridLayout(1, 4, 10, 10));
        topPan.add(negButton);
        topPan.add(absButton);
        topPan.add(clrButton);
        topPan.add(delButton);
        centerContainer.add(topPan);

        // 次级功能按钮面板
        JPanel secPan = new JPanel();
        secPan.setLayout(new GridLayout(1, 4, 10, 10));
        secPan.add(piButton);
        secPan.add(perButton);
        secPan.add(sqrButton);
        secPan.add(srootButton);
        secPan.setBorder(BorderFactory.createEmptyBorder(10, 0, 10, 0));
        centerContainer.add(secPan);

        // 数字与运算按钮面板
        JPanel panel = new JPanel();
        panel.setLayout(new GridLayout(4, 4, 10, 10));
        panel.add(numberButtons[7]);
        panel.add(numberButtons[8]);
        panel.add(numberButtons[9]);
        panel.add(mulButton);
        panel.add(numberButtons[4]);
        panel.add(numberButtons[5]);
        panel.add(numberButtons[6]);
        panel.add(subButton);
        panel.add(numberButtons[1]);
        panel.add(numberButtons[2]);
        panel.add(numberButtons[3]);
        panel.add(addButton);
        panel.add(numberButtons[0]);
        panel.add(decButton);
        panel.add(equButton);
        panel.add(divButton);
        centerContainer.add(panel);

        // 将中间容器添加到窗口中央
        frame.add(centerContainer, BorderLayout.CENTER);

        // 设置窗口最小尺寸,自动适配组件大小
        frame.setMinimumSize(new Dimension(400, 500));
        frame.pack();
        frame.setVisible(true);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        // 保留原有的事件处理逻辑,此处省略具体实现
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(Calculator::new);
    }
}

额外优化建议

  • 如果希望按钮字体随窗口大小动态调整,可以重写组件的paintComponent方法,结合FontMetrics计算适配字体
  • 无需为按钮设置固定尺寸,布局管理器会根据窗口大小自动分配空间

内容的提问来源于stack exchange,提问作者Sajal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 21:08:09