Search on the blog

2013年7月27日土曜日

Swingで繰り返しRepaintするときはTimerを使う

Swingで定期的に画面を再描画するような処理を書いていてはまったので、メモを残しておきます。
結論から言うと、javax.swing.Timerを使うとやりたいことができました。


ソースコード

ダメな例
最初処理を書いたときは、
  1. Thread.sleep()でスレッドを一時停止する
  2. repaintを呼んで再描画する
をSTOPボタンが押されるまで繰り返すという書き方(参考URL[2]にあるような書き方)をしていたのですが、これだと思った動作ができませんでした。

調べてみると、

Thread.sleep()は、実行中のスレッドをスリープさせる。このときスリープするスレッドは保持しているロックを開放しない[1]。

ということでした。

その結果、
  1. repaintリクエストは実行されることなくキューに溜まっていく。
  2. STOPボタン押下時にはじめてキューにたまったrepaintが実行可能となる。
  3. 実行されてないrepaintリクエストが複数個ある場合は、一つにまとめられて最後のrepaintメソッドだけが実行される。(もしくは設定によってはキューに溜まったrepaintがすべて間隔をあけることなく一瞬で実行される。)
  4. 思った動作にはならない。
ということが起きていました。

参考URL
[1] Difference between wait() and sleep()
[2] Java - repaint component every second?
[3] Combining repaint() with Thread.Sleep()

0 件のコメント:

コメントを投稿