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
相关产品推荐
相关产品推荐

