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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With