I have created bouncing ball app in Java. Everything is working as supposed but ball is freezing when it's moving. When I move the cursor to the window the ball is moving smoothly. When I stop moving the cursor it's again freezing.
OS: Fedora 23 JDK: 8
public class Main {
public static void main(String[] args) {
Game game = new Game();
}
}
class Game extends JFrame {
public Game(){
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
Ball ball1 = new Ball();
add(ball1);
setSize(400,300);
setTitle("Bubbles");
setVisible(true);
}
}
class Ball extends JPanel implements Runnable{
int radius = 50;
int x = 5 ;
int y = 5;
int dx = 2;
int dy = 2;
public Ball (){
Thread thread = new Thread(this);
thread.start();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.red);
g.fillOval(x,y,radius,radius);
}
public void moveBall (){
if (x + dx > 400 - radius){
x = 400 - radius;
dx = -dx;
} if (x + dx < 0){
x = 0;
dx = -dx;
}
else {
x += dx;
}
if (y + dy > this.getHeight() - radius){
y = this.getHeight() - radius;
dy = -dy;
} if (y + dy < 0){
y = 0;
dy = -dy;
}
else {
y += dy;
}
}
@Override
public void run() {
while (true){
moveBall();
repaint();
try {
Thread.sleep(17);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
The code works, but using Thread in Swing like this is not the best way Concurrency in Swing
In your case a swing Timer would be more appropriate.
Example
javax.swing.Timer timer = new javax.swing.Timer(17, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
ball1.runMe();
}
});
timer.start();
The runMe
method will be similar to your current run
method just remove the while
and Thread.sleep
.
public void runMe() {
moveBall();
repaint();
}
Naturally your Ball
will not implement the Runnable
anymore so you remove all Threading code
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.