简体   繁体   English

即使我使用了 doubleBuffer,我的 jframe 也会闪烁

[英]flickering my jframe even i used doubleBuffer

when I call a repaint method its flickering, I was searching on the internet about doubleBuffered but its stil flickering all of objects on the same time,当我将重绘方法称为闪烁时,我在互联网上搜索了有关 doubleBuffered 的信息,但它仍然同时闪烁所有对象,


import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.ArrayList;
import java.util.Random;


public class GuiGame extends JFrame implements ActionListener {
  
    private final Flower flower;
    private final ArrayList<MyObjects> objekty;

    private Image dbImage;
    private Graphics dbGraphics;


    public GuiGame() {
        this.setFocusable(true);
        Timer timer = new Timer(40, this);
        timer.start();
        this.setVisible(true);
/*

    public void paint(Graphics g) {
         this.dbImage = this.createImage(this.getWidth(), this.getHeight());
        this.dbGraphics = this.dbImage.getGraphics();
        this.paintComponents(g);
        g.drawImage(this.dbImage, 0 ,0, this);
    }

*/
    public void paint(Graphics g) {
  //when i use doubleBuffering this method was called paintComponents
       
        g.drawImage(background.getImage(), 0, 0, this);
        g.drawImage(flower.getImage(), flower.getPozX(), flower.getPozY(), this);
        String skore = "Score: " + player.getScore() ;
        g.drawString(skore, 20, 50);
        this.paintObjects(g);
    }

    public void paintObjects(Graphics g) {
        if (this.objekty != null) {
            for (objekty o : this.objekty) {
                o.move();
                g.drawImage(o.getImage(), o.getPozX(), o.getPozY(), this);
            }
        }
    }

when I used doubleBuffering I tried to slow down a timer eg to 1000, it was blank page for most of the time and my objects was there only for moment.当我使用 doubleBuffering 时,我试图将计时器减慢到 1000,大部分时间它都是空白页,而我的对象只是暂时存在。

when I do not used it, only last objects which i draw were flickering.当我不使用它时,只有我画的最后一个对象在闪烁。 how can I avoid?我该如何避免?

I would recommend you start by taking a look at Painting in AWT and Swing and Performing Custom Painting .我建议您先看看在 AWT 和 Swing 中的绘画执行自定义绘画

Swing components, when used correctly, are double buffered by default.如果正确使用 Swing 组件,默认情况下是双缓冲的。

Painting is very complex, there's a lot of work that goes into a paint pass.绘画非常复杂,绘画过程中有很多工作要做。 When you override a "paint" method, you either need to honour the existing workflow (ie, call the super.paintXxx method) or be prepared to take over the full responsibility of the method.当您覆盖“paint”方法时,您要么需要遵守现有的工作流程(即调用super.paintXxx方法),要么准备好接管该方法的全部责任。 Your code has circumvented whole sections of the paint workflow, this is never a good idea.您的代码已经绕过了绘制工作流程的整个部分,这绝不是一个好主意。

It's not generally recommend that you extend from top level containers like JFrame , you're not adding any new functionality and they are generally complex components to start with.通常不建议您从JFrame之类的顶级容器扩展,您不会添加任何新功能,而且它们通常是开始时的复杂组件。 JFrame for example, is actually a composite component, that is, it has a number of child components added to it that form it's core functionality例如, JFrame实际上是一个复合组件,也就是说,它添加了许多子组件,形成了它的核心功能

在此处输入图像描述

By overriding paint (of JFrame ), you start competing with these components, and because a child component can be painted without the parent been involved, this can lead to any number of issues.通过覆盖( JFrame的) paint ,您开始与这些组件竞争,并且由于可以在不涉及父组件的情况下绘制子组件,这可能会导致任何数量的问题。

Instead, start with a JPanel and override it's paintComponent method, this guarantees that you will be operating in a double buffered workflow.相反,从JPanel开始并覆盖它的paintComponent方法,这可以保证您将在双缓冲工作流中进行操作。

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

public class Main {
    public static void main(String[] args) {
        new Main();
    }

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    JFrame frame = new JFrame();
                    frame.add(new MainPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                } catch (IOException ex) {
                    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });
    }

    public class MainPane extends JPanel {

        private int xDelta = 1;
        private int xPos = 0;
        private BufferedImage ufo;

        public MainPane() throws IOException {
            ufo = ImageIO.read(getClass().getResource("/images/ufo.png"));

            Timer timer = new Timer(5, new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    xPos += xDelta;
                    if (xPos + ufo.getWidth() > getWidth()) {
                        xPos = getWidth() - ufo.getWidth();
                        xDelta *= -1;
                    } else if (xPos < 0) {
                        xPos = 0;
                        xDelta *= -1;
                    }
                    repaint();
                }
            });
            timer.start();
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(400, 400);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            paintUFO(g2d);
            g2d.dispose();
        }

        protected void paintUFO(Graphics2D g2d) {
            int y = (getHeight() - ufo.getHeight()) / 2;
            g2d.drawImage(ufo, xPos, y, this);
        }

    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM