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

Java Swing中JPanel叠加绘制图形内容消失的问题求助

问题原因

你遇到的问题根源在于BorderLayout的布局规则:当调用contentPane.add(component)时,默认是将组件添加到CENTER区域,而这个区域同一时间只能显示一个组件——后添加的组件会直接替换掉之前的,所以你只能看到最后添加的那个。

解决方案

下面提供两种最适合你需求的修复方式:

方式一:合并绘制逻辑(推荐)

既然背景和方块都是绘制类组件,直接把它们的绘制逻辑合并到同一个自定义JComponent中,彻底避免组件覆盖问题:

import java.awt.*;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;

public class App {
    public static void main(String[] args) throws Exception {
        MainFrame myFrame = new MainFrame();
        myFrame.init();
    }
}

class MainFrame extends JFrame{
    public void init(){
        try {
            Image logo = ImageIO.read(new File("Logo.jpg"));
            setIconImage(logo);
        } catch (IOException e) {
            e.printStackTrace();
        }

        setTitle("Sandsim");
        setSize(600, 600);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        
        // 使用合并了背景和方块的组件
        GamePanel gamePanel = new GamePanel();
        setContentPane(gamePanel);
        
        setVisible(true);
    }
}

// 合并背景和方块绘制的组件
class GamePanel extends JComponent {
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g); // 必须调用,确保组件绘制流程正确
        Graphics2D g2d = (Graphics2D) g;
        int gridSize = 10;

        // 绘制背景网格
        g2d.setColor(Color.BLACK);
        // 竖线
        for (int x = 0; x < getWidth(); x += gridSize) {
            g2d.drawLine(x, 0, x, getHeight());
        }
        // 横线
        for (int y = 0; y < getHeight(); y += gridSize) {
            g2d.drawLine(0, y, getWidth(), y);
        }

        // 绘制方块(后续可改为鼠标点击生成的坐标列表)
        g2d.setColor(Color.YELLOW);
        g2d.fillRect(10, 10, gridSize, gridSize);
    }
}

方式二:使用分层窗格(JLayeredPane)

如果想保留分开的组件类,可以用JLayeredPane分层放置,背景在底层,方块在顶层:

import java.awt.*;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;

public class App {
    public static void main(String[] args) throws Exception {
        MainFrame myFrame = new MainFrame();
        myFrame.init();
    }
}

class MainFrame extends JFrame{
    public void init(){
        try {
            Image logo = ImageIO.read(new File("Logo.jpg"));
            setIconImage(logo);
        } catch (IOException e) {
            e.printStackTrace();
        }

        setTitle("Sandsim");
        setSize(600, 600);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        
        JLayeredPane layeredPane = new JLayeredPane();
        layeredPane.setPreferredSize(new Dimension(600,600));
        setContentPane(layeredPane);

        Background background = new Background();
        background.setBounds(0,0,600,600);
        Sand sand = new Sand();
        sand.setBounds(0,0,600,600);
        sand.setOpaque(false); // 关键:让方块组件透明,不遮挡背景

        // 背景放在底层,方块放在顶层
        layeredPane.add(background, JLayeredPane.DEFAULT_LAYER);
        layeredPane.add(sand, JLayeredPane.PALETTE_LAYER);
        
        setVisible(true);
    }
}

class Background extends JComponent {
    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.setColor(Color.BLACK);

        int positionX = 0;
        int positionY = 0;
        for (int i = 0; i < getBounds().width / 10; i++) {
            g2d.drawLine(positionX, 0, positionX, getBounds().height);
            positionX += 10;
        }
        for (int i = 0; i < getBounds().height / 10; i++) {
            g2d.drawLine(0, positionY, getBounds().width, positionY);
            positionY += 10;
        }
    }
}

class Sand extends JComponent{
    @Override
    protected void paintComponent(Graphics g){
        super.paintComponent(g);
        Graphics2D g2d =(Graphics2D)g;
        g2d.setColor(Color.YELLOW);
        g2d.fillRect(10, 10, 10, 10);
    }
}
后续扩展建议

如果要实现鼠标点击生成方块,可以在主绘制组件中添加鼠标监听器:

  • 维护一个List<Point>存储所有方块的网格坐标
  • 在mouseClicked事件中计算鼠标所在的网格位置,添加到列表
  • 在paintComponent中遍历列表,批量绘制所有方块

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 09:00:07