Java NetBeans IDE - Animation Flickering in JPanel

2019-06-12 16:49发布

I am currently learning Java Animation and graphics in NetBeans.

I decided to start off with a simple ball movement in JPanel.

I am having some problem with fixing the flickering a flickering problem. I have looked at many forums but most were for AWT using Double Buffering,but I came to know that SWING components don't need Double Buffering. I tried - using repaint() and .clearRect().

Out of the 2 I found that using .clearRect() gave me better results, but not seamless flicker-free animation all the time.So I wanted to know if there is a better way to eliminate flickering.

Here is my code:

public class NewJFrame extends javax.swing.JFrame {

int x;
int y;
int xspeed = 1;
int yspeed = 1;
int width;
int height;
Graphics g;

    /**
     * Creates new form NewJFrame
     */
    public NewJFrame() {
        initComponents();
    }                             

    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {                                         
g = jp.getGraphics();
width = jp.getWidth();
height = jp.getHeight();
final Timer timerCHK = new Timer();
timerCHK.schedule(new TimerTask() {
    public void run() {
        move();
        time();

    }
}, 1000, 10);

    }                                        
void time() {
    final Graphics g = jp.getGraphics();
    final Timer timerCHK = new Timer();
    timerCHK.schedule(new TimerTask() {
        public void run() {
            g.clearRect(0, 0, jp.getWidth() - 3, jp.getHeight() - 3);

        }
    }, 1000, 12);
}

void move() {
    x = x + xspeed;
    y = y + yspeed;
    Graphics mk = jp.getGraphics();
    if (x < 0) {
        x = 0;
        xspeed = -xspeed;
    } else if (x > width - 20) {
        x = width - 20;
        xspeed = -xspeed;
    }

    if (y < 0) {
        y = 0;
        yspeed = -yspeed;
    } else if (y == height - 20) {
        y = height - 20;
        yspeed = -yspeed;
    }

    mk.drawOval(x, y, 20, 20);

}
    public static void main(String args[]) {

        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new NewJFrame().setVisible(true);
            }
        });
    }
}

3条回答
在下西门庆
2楼-- · 2019-06-12 17:28
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class NewJFrame extends JFrame {

    private JPanel jp;
    private Timer timer;

    public NewJFrame() {
        initComponents();

        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.pack();
        this.setLocationByPlatform(true);
        timer.start();
    }

    public void initComponents() {
        ActionListener al = new ActionListener() {

            public void actionPerformed(ActionEvent evt) {
                jp.repaint();
            }
        };
        timer = new Timer(50,al);

        jp = new JPanel() {

            int x;
            int y;
            int xspeed = 1;
            int yspeed = 1;

            Dimension preferredSize = new Dimension(300, 100);

            @Override
            public Dimension getPreferredSize() {
                return preferredSize;
            }

            @Override
            public void paintComponent(Graphics g) {
                super.paintComponent(g);
                this.move();
                Graphics2D g2 = (Graphics2D)g;
                g2.setRenderingHint(
                        RenderingHints.KEY_ANTIALIASING, 
                        RenderingHints.VALUE_ANTIALIAS_ON);
                g.drawOval(x, y, 20, 20);
            }

            void move() {
                x = x + xspeed;
                y = y + yspeed;
                if (x < 0) {
                    x = 0;
                    xspeed = -xspeed;
                } else if (x > getWidth() - 20) {
                    x = getWidth() - 20;
                    xspeed = -xspeed;
                }

                if (y < 0) {
                    y = 0;
                    yspeed = -yspeed;
                } else if (y == getHeight() - 20) {
                    y = getHeight() - 20;
                    yspeed = -yspeed;
                }
            }
        };
        jp.setBackground(Color.ORANGE);

        this.add(jp);
    }

    public static void main(String args[]) {
        EventQueue.invokeLater(new Runnable() {

            public void run() {
                new NewJFrame().setVisible(true);
            }
        });
    }
}
查看更多
【Aperson】
3楼-- · 2019-06-12 17:32

This is not an answer (per se) but an extended comment - the comments didn't have enough room

I want to learn more.Can you suggest some tutorial on basic animation(like the examples that you referred) to get started?

Unfortunately, not. I did a short 3D animation course a few years ago and applied many of the basic principles from that to my programming. While many of the theories are superfluous to what we do, they are still important to understand.

The problem you will face is not only do you need to have a good understanding of the animation theories, but also a good understanding of Swing's inner workings and APIs.

There are a number of good APIs available to help you in this regards, but you will still need to have an understanding of the animation theories to put them into piratical use.

  • TimingFramwork - I've worked with this API since before version 1. I have built a reasonable library of code around it and have found it very flexible and useful. The latest version takes a little work to get running...
  • Trident - Similar to the TimingFramework but has a greater focus on component manipulation then TimingFramework.
  • Universal Tween Engine - I've not used this, but I'm greatly interested in having a look...

Kirill Grouchnikov has done some excellent post on his Pushing Pixels website (to support his Trident animation engine) which might be a suitable compromise between the two disciplines.

Kirill also highlight the following articals (which I have to admit, I've not read read ... yet ;))

Updated with Swing side

For the Swing side of things, you will need to have a good understanding of...

Painting in Swing - check out Painting in AWT and Swing and Performing Custom Painting.

This is REALLY, REALLY important. This is one of the most common misunderstandings that developers have when they first start trying to perform animation in Swing.

You'll also need to understand Concurrency in Java and in particular, how it applies to Swing

查看更多
Fickle 薄情
4楼-- · 2019-06-12 17:35

I had a very similar flickering problem, I used

contentPane.updateUI();

and solved all my problems let me know please if updateUI() solved your problem

查看更多
登录 后发表回答