質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Swing

SwingはJavaに標準で付属するグラフィック関連のクラスライブラリを指します。

Q&A

解決済

3回答

8268閲覧

repaint(); が実行されない

Launcher

総合スコア19

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Swing

SwingはJavaに標準で付属するグラフィック関連のクラスライブラリを指します。

0グッド

0クリップ

投稿2017/03/03 00:09

java

1 class AnimeThread extends Thread { 2 3 public void run() { 4 while(mode == 1){ 5 System.out.println("動作中・・・"); 6 for(double d=0;d<(angle-vAngle)/vAngle;d+=vAngle){ 7 Displace(); 8 repaint(); 9 10 } 11 mode=2; 12 repaint(); 13 } 14 try { 15 Thread.sleep(150); 16 } catch(Exception e) { 17 } 18 } 19 } 20

repaintで呼び出されるメソッドはPaintCompnentです。
Displaceは別のメソッドです。

repaintをループの中に入れて、Displaceとrepaintを11回繰り返したいのですが、
実行されるのはDisplaceだけで(それも11回のはずなのに尋常じゃない回数を実行する)repaintは最後の1回だけ。

ループを抜けた後のrepaintは実行されます。

modeはPaintCompnentを呼び出した時にどの処理をするかの判断をするものです。

一応PaintCompnentの中身も貼っておきます。

java

1 public void paintComponent(Graphics g) { 2 super.paintComponent(g); 3 Graphics2D g2 = (Graphics2D)g; 4 System.out.println("paintComponent"); 5 6 7 if(mode==1){ 8 //再描画 9 System.out.println("移動開始(再描画)"); 10 for(int p=0;p<size;p++){ 11 //button自身が持っているx座標とy座標を送って描画する 12 ImageIcon icon = RoundButton.drow(button.get(p).getCoordX(),button.get(p).getCoordY(),buttonSize[p], button.get(p),iconList.get(p)); 13 button.get(p).setIcon(icon); 14 } 15 System.out.println("移動完了(再描画)"); 16 17 18 19 }else if(mode==2){ 20 //最終的に決められた位置に合わせてずれないようにする 21 move(); 22 System.out.println("最終点に合わせる"); 23 for(int l=0;l<size;l++){ 24 ImageIcon icon = RoundButton.drow(xPoint[l],yPoint[l],buttonSize[l], button.get(l),iconList.get(l)); 25 button.get(l).setIcon(icon); 26 } 27 mode=0; 28 } 29 30 setOpaque(false); 31 } 32 33

どうか助言お願いします!

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

最初にAnimeThreadでrepaintを呼び出してますが多分ご自分で定義したComponentの派生クラスのinnerクラスにしているのだと思います。そう仮定してコメントします。

それも11回のはずなのに尋常じゃない回数を実行する

原因はコードからだけではわかりません。ループの中でdをデバッグプリントしてみれば原因を推測できると思います。

repaintは最後の1回だけ。

repaintを呼び出したとき、呼び出しの度にComponent#paintが実行されるというのが質問者さんの期待だと思いますが実際はそう動きません。repaintの効果は「このコンポーネントを後で再描画することを覚えておく」というもので、実際に再描画されるのはEDT(Event Dispatch Thread)で非同期に適当なタイミングで動くと考えた方がよいです。EDT以外のスレッドで連続的にrepaintを呼び出しても1回しか再描画されないというのは普通の動きなのです。

今のプログラムの構造を大きく変えないようにして望みの効果を得るためにはrepaintを呼び出した後sleepするとよいと思います。10msec程度sleepすればその間にEDT上で再描画処理が行われることが充分期待できます。例えば1回の再描画ごとに1度だけ角度をずらしながら線を描画するようにしてrepaintの度に10msecずつsleepしてやるとほぼ期待通りのフレームレートで再描画されることが観察できます。(つまり1秒あたり100度程度角度が変わることが観察できます。)

投稿2017/03/03 02:38

KSwordOfHaste

総合スコア18392

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Launcher

2017/03/08 04:25

sleepを使い、うまくrepaintが何回も実行されました! ありがとうございます!
guest

0

Swingは扱ったことがないので、資料を読んだだけの情報ですが、
JComponent#repaintメソッドの説明の中に、
コンポーネントの再描画をスケジュールすると記述されているので、
paintComponentの呼び出しは非同期で行われていると考えられます。

repaintが処理できないような間隔で実行された場合、
再描画を実行しても画面がチラつくだけになると思うので、
一番最後のrepaintしか処理されないような設計になっているのではないでしょうか。

for文中にwaitを挟んでみてはいかがでしょう。

(もっとも、どういった動作を期待しているかは分かりませんが・・・)

投稿2017/03/03 01:52

abs123

総合スコア1280

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Launcher

2017/03/08 04:23

回答ありがとうございます! そのようですね...。別の方法を探してみます。
guest

0

Displaceが何かわかりませんが、その中でmodeを1,2以外の何かにしていませんか?

投稿2017/03/03 00:47

swordone

総合スコア20649

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Launcher

2017/03/08 04:22

回答ありがとうございます! 特にやっていません。説明不足ですみませんでした。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問