Java Swing GUI添加多个gameTile仅显示最后一个问题求助
问题根因
你遇到的只显示最后一个瓦片的问题由两个Swing基础使用错误导致:
- JFrame默认使用
BorderLayout布局,直接调用frame.add()且不指定布局位置时,所有组件都会被放到BorderLayout.CENTER位置,该位置同一时间只能展示一个组件,最后添加的组件会覆盖之前所有组件,因此只有最后一个橙色瓦片可见 - 你自定义的
gameTile继承JPanel属于Swing组件,组件自身的位置由父容器的布局管理器控制,但你在paintComponent方法中用传入的绝对坐标绘制,同时没有给组件设置正确的首选尺寸,就算解决了布局覆盖问题,也会出现绘制错位。

修复步骤
- 不要直接往JFrame上添加瓦片,使用你代码中已经声明但未使用的JPanel作为瓦片容器,JPanel默认使用
FlowLayout布局,会自动按水平顺序排列子组件,刚好匹配你一行展示4个瓦片的需求 - 给
gameTile类重写getPreferredSize()方法,返回瓦片的实际尺寸,让布局管理器能正确计算组件占位大小 - 组件的绘制坐标是相对于自身左上角的,不需要传入父容器绝对坐标,把
paintComponent里的绘制起点改为组件自身的(0,0)即可,组件在父容器中的位置由布局管理器自动处理 - 调用
frame.pack()代替手动写死窗口尺寸,让窗口自动根据内容计算合适大小,同时给容器加空边框实现你原本想要的10px边距。
修复后的gameTile类代码:
import javax.swing.*; import java.awt.*; public class gameTile extends JPanel { private Color color; private int size; // 不再需要传入父容器绝对坐标x/y,位置由布局管理器控制 public gameTile (int size_, Color color_) { size = size_; color = color_; // 设置组件首选尺寸,供布局管理器计算占位 setPreferredSize(new Dimension(size, size)); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2 = (Graphics2D) g; g2.setStroke(new BasicStroke(2)); g.setColor(color); // 从组件自身左上角(0,0)开始绘制 g.fillRect(0, 0, size, size); g2.setColor(Color.BLACK); g2.drawRect(0, 0, size, size); } }
修复后的主类代码:
import java.awt.*; import javax.swing.*; public class testGameTileClass { gameTile tile1; gameTile tile2; gameTile tile3; gameTile tile4; public testGameTileClass() { JFrame frame = new JFrame("Game Tiles"); JPanel panel = new JPanel(); // 加空边框实现10px的外围边距 panel.setBorder(BorderFactory.createEmptyBorder(10,10,10,10)); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setResizable(false); testConstructor1(panel); frame.add(panel); // 自动根据内容计算窗口大小 frame.pack(); frame.setVisible(true); } public void testConstructor1(JPanel panel) { tile1 = new gameTile(64, Color.RED.darker()); panel.add(tile1); tile2 = new gameTile(64, Color.GREEN); panel.add(tile2); tile3 = new gameTile(64, Color.BLUE); panel.add(tile3); tile4 = new gameTile(64, Color.ORANGE); panel.add(tile4); } public static void main(String[] args) { new testGameTileClass(); } }
补充说明
如果需要精确控制瓦片位置和间距,可以将JPanel的布局设置为null启用绝对定位,但不推荐这种写法:Swing的布局管理器本身就是为了适配不同系统分辨率、不同UI主题的显示差异,使用布局管理器的代码兼容性更强,不会出现跨环境显示错位的问题。
内容的提问来源于stack exchange,提问作者ilovepalydota
相关产品推荐
相关产品推荐

