1

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);
            }
        });
    }
}
  • 1
    1) `Thread.sleep(5);` Don't block the EDT (Event Dispatch Thread) - the GUI will 'freeze' when that happens. Instead of calling `Thread.sleep(n)` implement a Swing `Timer` for repeating tasks or a `SwingWorker` for long running tasks. See [Concurrency in Swing](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/) for more details. 2) For better help sooner, post an [SSCCE](http://sscce.org/). 3) Where is the `g` coming from? It has a 'bad code smell' to it. Will know more when I see an SSCCE. 4) `jp.setDoubleBuffered(true);` - `JComponent` objects are double buffered by default. – Andrew Thompson Dec 26 '12 at 08:31
  • @AndrewThompson Thanks for your reply. I have edited my code to be short and simple and I am still not sure about how to make it an "SSCCE" code.The 'g' is the graphics variable (I have added it to the code now).I tried giving another method timer() after move() the timer() consists of the same timer that i used in the main code.Still I am getting flickering in the animation. –  Dec 26 '12 at 09:06
  • *"I am still not sure about how to make it an "SSCCE" code."* Which part of S-SC-C-E are you having trouble understanding? – Andrew Thompson Dec 26 '12 at 09:08
  • `Graphics g; .. g.clearRect(` Since `g` has not been initialized anywhere in that code snippet, `g` should be `null` when the method is called. The latest edit is also not an SSCCE that would show things like where/how `g` is created. Follow the link, read the document, and if you don't understand anything you read, ask me - I am well placed to explain (as are many others). – Andrew Thompson Dec 26 '12 at 09:12
  • Perhaps an example of how my current "code" would look like in SSCCE would help.Thanks. –  Dec 26 '12 at 09:13
  • (shrugs) Maybe it would. So what? I am not about to make one, and I doubt anyone else is either. The major problem (besides the fact it is 'not our problem') is that by 'adding code' we might set it up in a way where those code snippets work! I recommend you stop dithering though and take up my offer to clarify things in the SSCCE you do not understand, since my patience is limited. – Andrew Thompson Dec 26 '12 at 09:18
  • the variable 'g' has been initialized after the "public class NewJFrame extends javax.swing.JFrame {".Then does that mean i have paste my entire code here?. –  Dec 26 '12 at 09:18
  • 2
    There are plenty of animation examples on SO, you could try [this example](http://stackoverflow.com/questions/13022754/java-bouncing-ball/13022788#13022788) – MadProgrammer Dec 26 '12 at 10:00
  • 1
    And [this](http://stackoverflow.com/questions/13540534/how-to-make-line-animation-smoother/13547895#13547895) one – MadProgrammer Dec 26 '12 at 10:09
  • @user1171616 Try to increase Java heap space.I think this can be the problem.If you are working on net beans, Goto your Project -->properties-->Run, and in side VM options copy paste ** `-Xms300m -Xmx340m`** . Try and let me know. – joey rohan Dec 26 '12 at 10:42
  • sorry i could not reply earlier because i had some work and couldn't access my computer.
    @Madprogrammer thanks for your reply. i saw those examples those were written in class files unlike an IDE that I am using which is easier.
    –  Dec 27 '12 at 05:34
  • @joeyryan I changed that run to the specific settings that you had said but it didn't seem to help that much. –  Dec 27 '12 at 05:37
  • I am pretty sure that @MadProgrammer used an IDE when writing the two SSCCEs to which they linked. No one hand types those multitude of `catch` clauses needed for the PLAF change if they can possibly help it! – Andrew Thompson Dec 27 '12 at 10:35
  • @AndrewThompson well i edited again.. is it Ok? or should it be more "SSCCE"?.. and please suggest a fix. I feel the clearRect() is working fine but still there is some flickering and i make all timers a Swing one. –  Dec 27 '12 at 11:49
  • @MadProgrammer those examples that you showed were excellent.I want to learn more.Can you suggest some tutorial on basic animation(like the examples that you referred) to get started? Thanks –  Dec 27 '12 at 13:01
  • @user1171616 I've posted an "extended" comment with regards to you question. The comments don't have enough room ;) – MadProgrammer Dec 27 '12 at 21:32

3 Answers3

3
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);
            }
        });
    }
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • still not clear about this.. I'm using netbeans IDE with swing components(the drag and drop types) and what you have posted is somewhat different from whats on my netbeans screen.I thank you for being patient answering my Question.
    Note:My entire code in the "Source" tab of the Netbeans - [link]http://www.beetxt.com/2lN in which I would like to know where exactly are the paintComponent() {} and most of the other stuff(not complaining here.. just asking) and why it isn't in the "auto" generated or any part of my code?)
    –  Dec 27 '12 at 18:25
  • Apart from that the other things that you mentioned like paintComponent() are not present anywhere in the code.Also another thing- i just changed the ActionEvent part of the code whre you had put the repaint() method to test it working of different methods but it keeps giving me " 'required: int,java.awt.event.ActionListener found: int,javaapplication8.ActionListner' " error.The format/everything is the same except the variable name (fff instead of al)and the code/function to be done inside the ActionEvent(). –  Dec 27 '12 at 18:52
  • Really sorry.. the answer turned out to be a silly spelling mistake which is usually notified by the IDE.I had written ActionListner instead of ActionListener.. the "e" was missing. –  Dec 28 '12 at 08:37
0

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

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
-1

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

  • umm where exactly should i implement it?.. is it right after the move() method or in a timer loop? if its the timer loop what should be the delay? –  Dec 27 '12 at 08:18
  • UpdateUIis used to inform the components that the look and feel has changed, this is inappropriate method for updating the screen, it's also way to slow. Invalidate, revalidate and repaint (and/or combinations of) are more than enough – MadProgrammer Dec 27 '12 at 20:41