• ベストアンサー

描画処理が実行されない

while(gameflag==true){ (数値設定)    repaint(); long start = System.currentTimeMillis(); while(System.currentTimeMillis()<start+1000){ } } 上記のようにwhileループの中で数値などの設定を行い、描画をし、遅延をしているのですが他の処理はちゃんと実行されるのになぜか描画処理だけが行われません。また、whileループ外でも描画を行っていますがその時点ではきちんと描画されます。描画されない原因はどのようなことが考えられるでしょうか?描画はpaintComponent(Graphics g) メソッドで描画しています。

質問者が選んだベストアンサー

  • ベストアンサー
noname#49664
noname#49664
回答No.2

>描画されない原因はどのようなことが考えられるでしょうか? Swingの描画はダブルバッファを使っている関係上、描画メソッドを呼び出したときではなく、その後、もっとも早く再描画できるタイミングで表示を更新します。このため、while内で描画を行っている場合には、そのwhileを抜け、処理が終了した頃で表示が更新されるため、while中で行っている描画処理は見えません。(途中の描画は見えず、最終的に描画された状態だけが表示される) この処理は、別スレッドを使って実行していますか? メインスレッドでは、上のような理由で途中の更新は見えませんから、マルチスレッドで実行し、描画ごとに強制的にrepaintするなどしてみてはいかがでしょう。

sakusha
質問者

お礼

無事解決できました、ありがとうございます。以前マルチスレッドを使った方法で失敗したのでこの方法を使ったのですがSwingの描画では逆効果だったのですね。以後マルチスレッドや描画処理の呼び出しには気をつけます。

sakusha
質問者

補足

なるほど、Swingの描画にそのような落とし穴があったのですね。 whileループは別のスレッドで行っていますがそれでもwhileループではなくマルチスレッドを使ったほうがよろしいのでしょうか?

その他の回答 (3)

  • bgbg
  • ベストアンサー率53% (94/175)
回答No.4

repaint()はイベントキュースレッドに処理を投げますので、メインメソッド系のスレッドが占有状態でもマシンパワーが十分なら適切に再描画されるはずです。 しかしイベントキュースレッドが占有状態だとrepaint()の処理も回らないので再描画が行われない、または後回しになる可能性があります。 repaint()と同時に別のイベントが発生していないでしょうか。あるいは再描画の処理自体が重いというのもあるかもしれません(画像を一回一回読み込んでいるようですし) とりあえずは、Thread#sleepで様子を見ることをお勧めします。

sakusha
質問者

お礼

無事解決できました、ありがとうございます。whileループが原因というのもありましたが処理手順にばかり気をとられ、無駄なスレッドが増えて複雑になっているのもありました。今後はプログラムを定期的に整理するように気をつけます。

  • isle
  • ベストアンサー率51% (77/150)
回答No.3

ループの中に Thread.yield(); を入れてみたらどうでしょう? タイミングクリティカルな処理でなければ Thread.sleep(n); //要例外キャッチ を適切に呼び出すのがよろしいかと。

  • bgbg
  • ベストアンサー率53% (94/175)
回答No.1

Swingを使用していると思われますが、paintComponentをオーバーライドしているクラスを補足してください。(特にどのクラスからの継承なのか)

sakusha
質問者

補足

public class Syori_out extends JPanel implements MouseListener{ public Syori_out() {//コンストラクタ setPreferredSize(new Dimension(WIDTH, HEIGHT)); addMouseListener(this); } public void gameImage(int tensu){ if(start==false) { for(int i=0;i<4;i++){ gameimage[i] =get.MakeImage(data.gazoudata[i]); } kasokuimage=get.MakeImage("../g_data/risu2.gif"); start=true; } else { for(int i=0;i<4;i++){ System.out.println(data.gazoudata[1]); gameimage[i] =get.MakeImage(data.gazoudata[i]); } System.out.println(data.datastate); } repaint(); timer(); } } private static void timer(){ long start = System.currentTimeMillis(); while(System.currentTimeMillis()<start+1000){ } } プログラムの問題となっている部分を抜き出しました。whileループは Game_mainというクラスにあり、そこで数値の設定を行った後、上記の gameImage()が呼び出されます。get.MakeImage()では画像を取得しています。また、フレームはSyori_mainというクラスで生成し、上記の Syori_outクラスをインスタンス化したものをパネルに貼り付けています。

関連するQ&A