2016-01-31 108 views
0

我已經創建了Java彈跳球應用程序。一切都如假想般運作,但球在移動時凍結。當我將光標移動到窗口時,球順利移動。當我停止移動光標時,它又一次凍結。JAVA彈跳球凍結

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(); 
     } 

    } 
} 
} 
+0

您的代碼爲我工作。 –

+0

它也適用於我:/ –

+0

我測試了代碼,沒有任何東西凍結。 (操作系統:WIN10 JDK:8),所以它必須是Fedora的東西。 – osanger

回答

2

代碼工作,但在這樣的搖擺使用線程是不是最好的方式Concurrency in Swing

在你的情況揮杆Timer會更合適。

javax.swing.Timer timer = new javax.swing.Timer(17, new ActionListener() { 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     ball1.runMe(); 
    } 
}); 
timer.start(); 

runMe方法將類似於當前的run方法只是刪除whileThread.sleep

public void runMe() { 
    moveBall(); 
    repaint(); 
} 

當然你Ball將不執行Runnable了,所以刪除了所有的線程代碼

+0

謝謝@peter這是非常有用的文章,我必須讀這個。 –

+0

@DadashMemmedli歡迎您,我在哪裏使用不正確的線程在擺動環境中,這會產生意想不到的行爲。 –