6

I have written a simple Java animation program in Ubuntu 14.4.1. A ball moving inside a JPanel. But at execution, the ball moves quite jerky in the JPanel. This problem continues until I move the mouse inside the JPanel. At the time of moving the mouse inside the JPanel the ball movement is quite smooth. It should be said that I've run this program in Windows 10, and no problem occurred. The code for my program is as follows:

import java.awt.*;
import javax.swing.*;

public class BouncingBall extends JPanel {
    Ball ball = new Ball();

    void startAnimation() {
        while( true ) {
            try {
                Thread.sleep( 25 );
                ball.go();
                repaint();
            } catch( InterruptedException e ) {}
        } // end while( true )
    } // end method startAnimation()

    protected void paintComponent( Graphics g ) {
        super.paintComponent( g );
        ball.draw( g );
    } // end method paintComponent


    // inner class Ball
    class Ball {
        int x;
        int y;
        int diameter = 10;
        int xSpeed = 100;
        int ySpeed = 70;

        void go() {
            x = x + (xSpeed*25)/1000;
            y = y + (ySpeed*25)/1000;

            int maxX = getWidth() - diameter;
            int maxY = getHeight() - diameter;
            if( x < 0 ) {
                // bounce at the left side
                x = 0;
                xSpeed = -xSpeed;
            } else if( x > maxX ) {
                // bounce at the right side
                x = maxX;
                xSpeed = -xSpeed;
            } else if( y < 0 ) {
                // bounce at the top side
                y = 0;
                ySpeed = -ySpeed;
            } else if( y > maxY ) {
                // bounce at the bottom size
                y = maxY;
                ySpeed = -ySpeed;
            } // end if-else block
        } // end method go()

        void draw( Graphics g ) {
            g.fillOval( x , y , diameter , diameter );
        } // end method draw
    } // end inner class Ball


    public static void main( String[] args ) {
        JFrame window = new JFrame();
        window.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        BouncingBall animation = new BouncingBall();
        animation.setPreferredSize( new Dimension( 500 , 500 ) );
        animation.setBackground( Color.white );
        window.add( animation );
        window.pack();
        window.setVisible( true );

        animation.startAnimation();
    } // end method main
} // end class BouncingBall

What is the problem? Do I have to change some settings in my Ubuntu? I've also put some test code inside the paintComponent method as follows:

protected void paintComponent( Graphics g ) {
    System.out.println( "paintComponent call number: " + counter );
    ++counter;
    super.printComponent( g );
    ball.draw( g );
}  

with variable counter initial value of 0 declared in class MovingBall. I observed that the number of paintComponent's calls per second is much more than the actual refresh rate of the JPanel as it appears.

  • the println within your paintComponent method will slow it down and may have a noticeable effect. You will want to it out of there. – Hovercraft Full Of Eels Dec 06 '16 at 17:50
  • The main problem emerged before adding println. The println statement is just a testing statement to find out more about that problem. – Hedayat Mahdipour Dec 06 '16 at 17:52
  • I would also obtain real time increments within your animation method, and calculate the best position of the sprite based on real time increments. This way the ball moves the same distance if the animation is fast or slow. – Hovercraft Full Of Eels Dec 06 '16 at 17:53
  • Have you executed the code I've written in linux? – Hedayat Mahdipour Dec 06 '16 at 17:56
  • No. I'm at work and I don't have Linux. – Hovercraft Full Of Eels Dec 06 '16 at 18:04
  • If you do so, you will understand what I'm talking about. the problem is not about decreasing performance of the program because of a println statement or another. The problem is about why the program executes normally in Windows, while it does not in my Ubuntu. Java programs are intended to be platform independent, but this may be a counterexample to this. – Hedayat Mahdipour Dec 06 '16 at 18:10
  • Confirmed, animation is pretty choppy in Linux, using Java 1.8.0_111 64-bit, on a modern video card in both Linux and Windows. – VGR Dec 06 '16 at 18:29
  • maybe this will help out. https://stackoverflow.com/questions/19480076/java-animation-stutters-when-not-moving-mouse-cursor – phil294 Jan 27 '18 at 21:14

1 Answers1

10

Video acceleration is enabled by default in Windows, but is not enabled by default in Linux. (This has been true for many years now; I could have sworn this default was changed for recent Java releases, but evidently I was wrong.)

You can enable OpenGL to get accelerated performance:

public static void main( String[] args ) {
    System.setProperty("sun.java2d.opengl", "true");

    JFrame window = new JFrame();

Alternatively, you can set the property on the command line:

java -Dsun.java2d.opengl=true BouncingBall
VGR
  • 40,506
  • 4
  • 48
  • 63
  • Thank you for your answer. I tried both ways you told. But none of them did fix the problem. The animation is still jerky, just like before. – Hedayat Mahdipour Dec 06 '16 at 21:08
  • That property made a huge difference for me. What is your Linux system’s graphics card? Do you know if it provides OpenGL acceleration? – VGR Dec 06 '16 at 21:13
  • I don't know about both the graphics card and supporting OpenGL. How can I understand about them? – Hedayat Mahdipour Dec 06 '16 at 21:14
  • Wait a minute. It did work for me. I made a mistake writing openg1 instead of opengl. You're right. But now there remains another question: If I want my programs to be platform independent, do I have to place this statement at the beginning of all my animation or graphics programs? – Hedayat Mahdipour Dec 06 '16 at 21:20
  • Yes. You may also want to look into learning JavaFX, which has better performance and does not need that property. – VGR Dec 06 '16 at 21:24
  • Is there any way to enable OpenGL in Linux forever? – Hedayat Mahdipour Dec 06 '16 at 21:26
  • Thank you vary much for your answer dear VGR. You solved my problem. – Hedayat Mahdipour Dec 06 '16 at 21:43
  • Not that I’m aware of. Think of the property as standard setup, like setting a look-and-feel for normal GUIs. – VGR Dec 06 '16 at 21:43