2017-04-21 9 views
0

私は自分のバージョンのSnakeを学習目的で作成しようとしています。フレームが再描画されるようにするには、手動でウィンドウのサイズを変更する必要があります。私のコードは次のとおりです:JFrameはウィンドウのサイズ変更時にのみ更新されます

package snake; 

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

public class PlayGame extends JPanel implements Runnable{ 

    public boolean animate = false;   
    public final int FRAME_DELAY = 750; 

    PickupBall b = new PickupBall(); 
    Snake bob = new Snake(); 


    public synchronized void start() { 
     animate = true; 
    } 

    public synchronized void stop() { 
     animate = false; 
    } 
    private synchronized boolean animationEnabled() { 
     return animate; 
    } 

    @Override 
    public void run(){    
     while(true){  
      if (animationEnabled()){      
       repaint();      
      } 
      try { 
       Thread.sleep(FRAME_DELAY); 
      } 
      catch (InterruptedException e) { 
       throw new RuntimeException(e); 
      } 
     } 
    }   

    @Override 
    public void paintComponent(Graphics g){    
     super.paintComponent(g); 

     b.draw(g); 
     bob.draw(g);    
    }   

    public static void main(String[] args) {  
     JFrame jfr = new JFrame("Snake"); 
     jfr.setSize(640,640); 
     jfr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);    
     jfr.setResizable(true); 

     PlayGame p = new PlayGame(); 

     jfr.setContentPane(p); 

     p.setBackground(Color.WHITE);    

     p.start();    

     new Thread(p).start();    
     jfr.setVisible(true);  

    } 


} 

フレームサイズを変更せずにrepaint()がトリガーされないのはなぜですか?私は相関を得ていますが、とにかくwhile(true)ループに入っているときに、なぜそれがなぜこのようなトリガーを必要とするのかは私には意味がありません。

私はここで何が欠けていますか? p.startと 削除スレッドオブジェクト 置き換えt.start()()

編集2:

編集1 追加new Thread(p).start();、今それは働きます!ありがとう。

編集3:revalidate();

+0

PlayGame p = new PlayGame(); スレッドt =新しいスレッド(p)。 t.start(); –

+1

't.start()'ですが、 'p.start()'は決して使わないので、 'animate'は常に' false'です。 – kiheru

+0

さて、これはスレッドオブジェクトが無意味であることを意味しますか? –

答えて

0

はまだ見当がつかない方法や、なぜこれが Thread t = new Thread(p); t.start();

に異なっている。しかし、それが働きました。

+0

これらは違いはありませんが、問題はありません。問題はあなたが 'Thread'クラスから' start'を呼び出しましたが、あなたの 'PlayGame'クラスから' start'を呼び出さなかったことでした。それらは全く異なる方法であり、両方を呼び出す必要があります。 'Playgame'の' start'はあなたが望む任意の名前を持つことができました。それは 'Thread'のメソッドと同じ名前だったと誤解していました。 – Berger

0

削除 あなたは、実際に画面上に描画するだけですイベントディスパッチトレッド(EDT)でのワーカースレッドでrepaint()ずに実行されています。

あなたはエンSwingUtilities静的メソッドinvokeLater()またはinvokeAndWait()を使用しEDTにrepaint()にコールをキューイングしなければなりません。追加new Thread(p).start();

+0

私を見せてください。私はそれをどこに置くべきか分からず、Googleは助けにはならない。 –

+0

'repaint'はスレッドセーフです。処理するEDTに実際のペイントイベントを投稿します。 – MadProgrammer

関連する問題