【问题标题】:stacked JPanel repaint not correctly堆叠的 JPanel 重绘不正确
【发布时间】:2015-11-14 19:30:57
【问题描述】:

我尝试用 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);
    }

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

我得到了什么 |我想要什么

主要

@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);
    }
}

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

【问题讨论】:

  • 请不要在标题中添加 [SOLVED] 之类的标签。而是发布一个答案(就像你做的那样),然后接受它。

标签: java swing canvas jpanel


【解决方案1】:

[已解决] 使用 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);
    }
}

【讨论】:

    猜你喜欢
    • 2018-05-23
    • 2019-07-25
    • 1970-01-01
    • 2012-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多