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

BorderLayout布局JFrame中GridLayout面板大小调整方法

问题根因

你的setPreferredSize()不生效完全是布局配置的问题,和Swing本身无关:

  • BorderLayout的PAGE_START/PAGE_END位置的组件,只会遵循自身设置的首选高度,水平方向会强制铺满容器宽度,且当窗口空间不足时会优先挤压这两个位置的组件到最小尺寸
  • 你把JTextField放在BorderLayout.CENTER位置,这个位置的组件会抢占所有剩余的容器空间,直接把上下两个棋盘面板挤到了最小高度
  • 棋盘里的JButton没有设置尺寸,默认Swing按钮的首选尺寸非常小,GridLayout会按子组件的最小尺寸来计算面板整体大小,最终棋盘就缩成了极小的方块。

修复方案

调整布局层级+给棋盘格子设置固定尺寸即可,修改后可直接运行的完整代码如下:

package testeborderlayout;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JTextField;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;

public class TesteBorderLayout extends JFrame {
    private JButton[][] tabuleiro1 = new JButton[10][10];
    private JButton[][] tabuleiro2 = new JButton[10][10];
    private JPanel jPanel1;
    private JPanel jPanel2;
    private JPanel boardContainer;
    private JTextField jTextField1; 
    // 单个棋盘格子边长,修改这个值就能自由调整棋盘整体大小
    private static final int CELL_SIZE = 45;
    private static final int BOARD_BORDER_GAP = 20;
    
    public TesteBorderLayout() {
        initComponents();
    }
                       
    private void initComponents() {
        jPanel1 = new JPanel();
        jPanel2 = new JPanel();
        // 新增棋盘容器,统一管理两个棋盘的布局
        boardContainer = new JPanel(new GridLayout(1, 2, BOARD_BORDER_GAP, 0));
        jTextField1 = new JTextField();
        
        // 初始化棋盘按钮,给每个格子设置固定首选尺寸
        for(int i=0;i<10;i++){
            for(int j=0; j<10;j++){
                tabuleiro1[i][j]=new JButton();
                tabuleiro2[i][j]=new JButton();
                tabuleiro1[i][j].setPreferredSize(new Dimension(CELL_SIZE, CELL_SIZE));
                tabuleiro2[i][j].setPreferredSize(new Dimension(CELL_SIZE, CELL_SIZE));
            }
        }
        
        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jPanel1.setBackground(new Color(255, 102, 102));
        jPanel1.setLayout(new GridLayout(10,10));

        jPanel2.setBackground(new Color(51, 102, 255));
        jPanel2.setLayout(new GridLayout(10,10));
        
        // 两个棋盘加入容器,放在CENTER区域避免被挤压
        boardContainer.add(jPanel1);
        boardContainer.add(jPanel2);
        getContentPane().add(boardContainer, BorderLayout.CENTER);
        
        // 填充棋盘格子
        for(int i=0;i<10;i++){
            for(int j=0;j<10;j++){
                jPanel1.add(tabuleiro1[i][j]);
                jPanel2.add(tabuleiro2[i][j]);
            }
        }
        
        jTextField1.setBackground(new Color(255,255,255));
        jTextField1.setText("Comandos para o usuário");
        // 文本框移到底部,只占用自身需要的高度
        getContentPane().add(jTextField1, BorderLayout.PAGE_END);
        setTitle("Batalha Naval");
        pack();
        // 禁止随意拉伸窗口避免棋盘变形,窗口启动居中
        setResizable(false);
        setLocationRelativeTo(null);
    }                

    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(() -> new TesteBorderLayout().setVisible(true));
    }
}

调整说明

  • 两个红蓝棋盘默认左右并排,符合海战棋双阵营棋盘的常规布局,如果需要保留上下排列的效果,只需要把boardContainer的布局改为new GridLayout(2, 1, 0, BOARD_BORDER_GAP)即可
  • 修改代码里的CELL_SIZE常量就能等比例缩放棋盘,数值越大棋盘尺寸越大
  • 棋盘容器放在BorderLayout.CENTER区域会获得最高的空间优先级,不会再被其他组件挤压变形

内容的提问来源于stack exchange,提问作者Mathguy on CS

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 11:48:26