简体   繁体   中英

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,


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.

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 .

Swing components, when used correctly, are double buffered by default.

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. 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 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

在此处输入图像描述

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.

Instead, start with a JPanel and override it's paintComponent method, this guarantees that you will be operating in a double buffered workflow.

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

    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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