简体   繁体   中英

JAVA bouncing ball is freezing

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM