堆叠的JPanel重绘不正确

时间:2015-11-13 20:09:13

标签: java swing canvas jpanel

我尝试用2个面板堆栈互相制作游戏,第一个面板用于画布,其中所有瓷砖和所有游戏对象都在其上绘制,第二个面板用于顶层框架,其中我有png图像,透明度为背景,将包含JTextBoxJTabbedPanelJLabel

我的问题是当我重新绘制画布时,顶部框架的一部分被画布覆盖。

为什么?当我在画布上添加JButton时,JButton也会在我的顶部框架面板上绘制。

修改

我尝试过使用JLayeredPane,但仍然给我相同的结果。

    // initComponent from MyGame
    private void initComponent() {
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setTitle("My Game");
        this.setSize(320, 240);
        this.setLayout(null);
        this.setUndecorated(true);
        this.setResizable(false);

        JLayeredPane layered = this.getLayeredPane();
        layered.add(new Canvas(), 0);
        layered.add(new TopFrame(), 1);
    }

这个顶部框架和我的画布:

enter image description here

我得到了什么我想要的是什么

enter image description here

主要

@SuppressWarnings("serial")
public class MyGame extends JFrame {

    public MyGame() {
        this.initComponent();
    }

    private void initComponent() {
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setTitle("My Game");
        this.setSize(320, 240);
        this.setLayout(null);
        this.setUndecorated(true);
        this.setResizable(false);

        this.add(new TopFrame());       
        this.add(new Canvas());
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame game = new MyGame();
                game.setVisible(true);
            }
        });
    }
}

TopFrame

@SuppressWarnings("serial")
public class TopFrame extends JPanel {
    private static final int FRAME_WIDTH = 320;
    private static final int FRAME_HEIGHT = 240;

    private BufferedImage bgImage;

    public TopFrame() {
        this.initComponent();
    }

    private void initComponent() {
        this.setLayout(null);
        this.setBounds(0, 0, FRAME_WIDTH, FRAME_HEIGHT);

        bgImage = new BufferedImage(FRAME_WIDTH, FRAME_HEIGHT, BufferedImage.TYPE_4BYTE_ABGR_PRE);
        try {
            bgImage = ImageIO.read(new File("FRAME.png"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawImage(bgImage, 0, 0, this);
    }
}

帆布

@SuppressWarnings("serial")
public class Canvas extends JPanel {
    private static final int CANVAS_WIDTH = 227;
    private static final int CANVAS_HEIGHT = 240;

    BufferedImage image;
    BufferedImage imgBuffer;
    Graphics2D g2d;

    public Canvas() {
        this.initComponent();
    }

    private void initComponent() {
        Timer timer = new Timer();

        this.setBounds(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);
        imgBuffer = new BufferedImage(CANVAS_WIDTH, CANVAS_HEIGHT, BufferedImage.TYPE_4BYTE_ABGR_PRE);
        g2d = imgBuffer.createGraphics();

        try {
            image = ImageIO.read(new File("tile.png"));
        } catch (IOException e) {
            e.printStackTrace();
        }

        timer.schedule(new TimerTask(){
            @Override
            public void run() {
                drawComponent();
                repaint();
            }
        }, 0, 100);
    }

    public void drawComponent() {
        /* will do tile drawing */
        g2d.drawImage(image, 0, 0, this);
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawImage(imgBuffer, 0, 0, this);
    }
}

是否可以在底部绘制所有包含对象的画布?

1 个答案:

答案 0 :(得分:0)

[已解决] 使用JLayeredPane并制作TopFrame setOpaque(false);

尝试使用JLayeredPane时,我的代码错误。

我的最终代码正在运行代码:

主要

@SuppressWarnings("serial")
public class MyGame extends JFrame {

    public MyGame() {
        this.initComponent();
    }

    private void initComponent() {
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setTitle("My Game");
        this.setSize(320, 240);
        this.setLayout(null);
        this.setUndecorated(true);
        this.setResizable(false);

        JLayeredPane layered = this.getLayeredPane();
        layered.add(new Canvas(), new Integer(0));
        layered.add(new TopFrame(), new Integer(1));
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame game = new MyGame();
                game.setVisible(true);
            }
        });
    }
}

<强> TopFrame

@SuppressWarnings("serial")
public class TopFrame extends JPanel {
    private static final int FRAME_WIDTH = 320;
    private static final int FRAME_HEIGHT = 240;

    private BufferedImage bgImage;

    public TopFrame() {
        this.initComponent();
    }

    private void initComponent() {
        this.setLayout(null);
        this.setBounds(0, 0, FRAME_WIDTH, FRAME_HEIGHT);
        this.setOpaque(false);

        bgImage = new BufferedImage(FRAME_WIDTH, FRAME_HEIGHT, BufferedImage.TYPE_4BYTE_ABGR_PRE);
        try {
            bgImage = ImageIO.read(new File("FRAME.png"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void paintComponent(Graphics g) {
        // super.paintComponent(g);
        g.drawImage(bgImage, 0, 0, this);
    }
}

<强>帆布

@SuppressWarnings("serial")
public class Canvas extends JPanel {
    private static final int CANVAS_WIDTH = 227;
    private static final int CANVAS_HEIGHT = 240;

    BufferedImage image;
    BufferedImage imgBuffer;
    Graphics2D g2d;

    public Canvas() {
        this.initComponent();
    }

    private void initComponent() {
        Timer timer = new Timer();

        this.setBounds(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);
        imgBuffer = new BufferedImage(CANVAS_WIDTH, CANVAS_HEIGHT, BufferedImage.TYPE_4BYTE_ABGR_PRE);
        g2d = imgBuffer.createGraphics();

        try {
            image = ImageIO.read(new File("tile.png"));
        } catch (IOException e) {
            e.printStackTrace();
        }

        timer.schedule(new TimerTask(){
            @Override
            public void run() {
                drawComponent();
                repaint();
            }
        }, 0, 100);
    }

    public void drawComponent() {
        /* will do tile drawing */
        g2d.drawImage(image, 0, 0, this);
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawImage(imgBuffer, 0, 0, this);
    }
}