• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:スレッドを動かすには?)

スレッドを動かす方法とプログラムのアニメーション化

このQ&Aのポイント
  • プログラムをアニメーション化する方法とスレッドの動かし方について教えてください。
  • プログラムの動きがうまくいかない場合の対処法について知りたいです。
  • 提供されたプログラムの要点を把握し、スレッドを正しく動かす方法を教えてください。

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

  • ベストアンサー
  • _ranco_
  • ベストアンサー率58% (126/214)
回答No.5

アニメスレッドの作り方と動かし方の例として、以下をダウンロードし、コンパイルし、動かしてみてください: http://homepage1.nifty.com/algafield/SatelliteOrbittSwing3.java 動かし方は、 appletviewer SatelliteOrbittSwing3.java です。または適当なhtmlから動かしてください。

kasegun
質問者

お礼

回答ありがとうございます。 こういう風にプログラミングすれば良かったのですね。 まだ、JAVAに関して知識が足りないみたいなので、勉強しておきます。 色々とありがとうございました。

その他の回答 (4)

  • _ranco_
  • ベストアンサー率58% (126/214)
回答No.4

> KeplerCuクラスのsolveZahyouメソッド内で計算された(Xg,Yg)を > 中心とするときちんと描画されるのですが、同じメソッド内で計算された > (kdo,ido)や(xp,yp)を中心とすると、うまく描画されません。 > (Plotボタンをクリックしても、座標(0,0)の位置から動かない) > solveZahyouメソッドで計算した(xp,yp)を座標の中心にしたいと > 思うのですが、この結果は使えないということでしょうか。それとも他 > に計算が必要なんでしょうか? あなたのスレッドのrun()メソッド内では、paintComponent()が使う描画用パラメータを更新せずに、ただrepaint()を呼んでいるだけですね。これは、根本的な間違いです。アニメスレッドのrun()メソッドは、 (1)描画パラメータの値の更新 (2)repaint() (3)Thread.sleep() の繰り返しです。値を更新してrepaint()するから、動きが実現するのです。現状のあなたのコードのように、なにもせずにrepaint()を呼んでも無意味です。 なお、描画パラメータがほかの現動スレッド上で刻々更新されているのなら、repaint()とsleep()だけでもいいですが、その場合は、それらのパラメータがパネルのpaintComponent()からアクセス可能でなければなりません。そのためには、描画パラメータ用の変数をメインクラスのフィールドにするのがよいでしょう。 SatelliteCanvasクラスのxp, ypと、KeplerクラスのsolveZahyou()メソッドのxp, ypは、全然別物ですよ!(後者は単なるローカル変数)。そのことが、分かりますか?。

  • _ranco_
  • ベストアンサー率58% (126/214)
回答No.3

人工衛星に関する計算についてはまったく無知なので、以下の3点のみお答えします。 (1)drawOval()/fillOval()の引数のx, yは、円や楕円を収める矩形の左上隅の座標です。円の中心の座標から、それらを計算して求めてください。 (2)アニメスレッドをactionPerformedの中でnew()してstart()してください(しかしアニメは、javax.swing.Timerを使うほうが楽です)。単軌道描画なら、そのあと、PlotボタンをsetEnabled(false)して不活性にしてください。 (3)solveZahyou()内の長大な if if if ... は、 if (.....){  ... } else if (.....){  ... } else if (.....){  ... } ... にしてください。現状では、毎回すべてのifを調べてしまいます。

kasegun
質問者

お礼

回答ありがとうございます。 >drawOval()/fillOval()の引数のx, yは、円や楕円を収める矩形の左上隅の座標です。 >円の中心の座標から、それらを計算して求めてください。 KeplerCuクラスのsolveZahyouメソッド内で計算された(Xg,Yg)を中心とす るときちんと描画されるのですが、同じメソッド内で計算された(kdo,ido) や(xp,yp)を中心とすると、うまく描画されません。(Plotボタンをクリッ クしても、座標(0,0)の位置から動かない) solveZahyouメソッドで計算した(xp,yp)を座標の中心にしたいと思うので すが、この結果は使えないということでしょうか。それとも他に計算が必 要なんでしょうか?

  • _ranco_
  • ベストアンサー率58% (126/214)
回答No.2

> 回答ありがとうございます。直して頂いたコードを実行したら、 > 計算で出された数値を中心に円が表示されるようになりました。 最新バージョン(?!)を再ダウンロードしてください: http://homepage1.nifty.com/algafield/SatelliteOrbittSwing.java > 最終的には、plotをクリックすると計算で出された緯度・経度 > 上を円が運動するものを作りたいと思っています。 ではplotのリスナのメソッドから、アニメスレッドをnew()してstart()す ればいいですね。さまざまの色の円が、同時に地球上空を軌道すると、おも しろいでしょう(ただしプログラミングはちょっと面倒)。ただし、逆に 1個に限定するなら、リスナの無効化という処理が必要です。「すでに動 いていたら、なにもせずにリターンする」 > そこで、また質問させていただきたいのですが、paintComponent() > が読んで使う描画パラメータの値を更新してからrepaint()を呼ぶ > とあるのですが、ここは具体的にどのようにしたらいいのでしょうか? 描画パラメータがたとえばint xとyで、更新が++x; ++y;なら、この更新 を書いた直後にrapaint()を呼べば、新たなx/yの値による描画が行われ ます。あなたのプログラムでは、keplerのメソッドを一定順で全部呼ん でから、repaint()を呼ぶことになるのかな? > また、計算で出た緯度・経度をうまく地図の画像に対応させるのに何 > かいい方法はあるでしょうか?結構手こずっているので。 これは、中学校の数学でしょう。画面座標のx,yは大きさが事前に決まって いるし(ただし原点(0,0)は左上隅)、計算値をその範囲内の値に変換する だけです。いちいち計算せずに、最初に配列(またはjava.util.HashMap)で マップ(値の写像関係)を作っておくと、プログラミングは楽ですよ。 実計算値 n < x < m -> 画面座標値 xp 実計算値 p < y < q -> 画面座標値 yp

kasegun
質問者

お礼

度々すみません。結局、座標変換は、下のプログラムのような感じでとり あえずやってみました。しかし、円の中心を(xp,yp)にしたいのですが、 うまく、その座標に円が描画されません。数値は問題ないと思うのです が、どこを直したらいいでしょうか? http://aaaaaaassss.up.seesaa.net/image/SatelliteOrbittSwing.java あと、アニメーションがまだ出来ていないのですが、 >描画パラメータがたとえばint xとyで、更新が++x; ++y;なら、この更新 >を書いた直後にrapaint()を呼べば、新たなx/yの値による描画が行われ >ます。あなたのプログラムでは、keplerのメソッドを一定順で全部呼ん >でから、repaint()を呼ぶことになるのかな? これは、119行目の、 kepler = new KeplerCu(yoso); kepler.Heikin(); kepler.Kepler(x); kepler.linearIter(x0); kepler.solveKepler(); kepler.solveZahyou(); sc.repaint(); の部分で出来ているでしょうか?更新は、現在の時間を変数にしているの で、時間が進むにつれて値が更新されるようにはなっているのですが。 >ではplotのリスナのメソッドから、アニメスレッドをnew()してstart()す >ればいいですね。 これは、actionPerformedメソッド内にスレッドを作るということでしょうか。 ここがちょっとうまくいかないので、どういう感じのプログラムになるの か教えていただきたいのですが。 よろしくお願いします。

  • _ranco_
  • ベストアンサー率58% (126/214)
回答No.1

コードを拝見しましたが、あなたがおやりになりたいのは、アニメーションではなくて、plotがクリックされたときの円の描画ではありませんか?。もしそうなら、Xg等の値をより妥当な値(負でなく、もっと有意に変化する値)にすれば次のコードで可能です。 http://homepage1.nifty.com/algafield/SatelliteOrbittSwing.java アニメをするなら、init()の最後にsc.start();を書いてください。もちろん、run()メソッドの中で、paintComponent()が読んで使う描画パラメータの値を更新してからrepaint()を呼んでください。ただし、Thread.sleep(1)は厳しいので、Thread.sleep(100)ぐらいが適当でしょう。 動画の質はSwingのほうが良いので、JAppletやJPanelを使ってください。アニメーションは、javax.swing.Timerを使うとより簡単に書けます。

kasegun
質問者

お礼

回答ありがとうございます。直して頂いたコードを実行したら、計算で出された数値を中心に円が表示されるようになりました。 最終的には、plotをクリックすると計算で出された緯度・経度上を円が運動するものを作りたいと思っています。 そこで、また質問させていただきたいのですが、paintComponent()が読んで使う描画パラメータの値を更新してからrepaint()を呼ぶとあるのですが、ここは具体的にどのようにしたらいいのでしょうか? また、計算で出た緯度・経度をうまく地図の画像に対応させるのに何かいい方法はあるでしょうか?結構手こずっているので。 よろしければ教えてください。よろしくお願いします。

関連するQ&A