プロが教えるわが家の防犯対策術!

今晩は。

車輪が回転するコードを作成しました。
エラ-は出ていませんが、車輪は回転しません。

宜しくご教示お願い致します。

このコードは、「Util.Timer」を使って周期的に動かそうとしていますが、
「Swing.Timer」を使って書き換えると問題なく動きました。

問題は「TimerTask」、「Timer」の箇所に原因がある
と考えていますが、どこをどのように修正すればよいのか分かりません。

詳しい方宜しくお願い致します。
//----------------------------------------------------

public class Kanran_Frame extends JFrame
{
public Kanran_Frame( )
{
Container cnt = this.getContentPane() ;
cnt.setBackground( Color.black ) ;

this.setSize( 800 , 600 ) ;
this.setLayout( null ) ;

Kanran_Panel1 k_can1 = new Kanran_Panel1() ;
k_can1.setLayout( null ) ;
k_can1.setSize( 350 , 350 ) ;

cnt.add( k_can1 ) ;

Timer timer = new Timer() ;
timer.schedule( ( new MyTimer() ) , 500 , 1000 ) ;
}

public static void main( String[] args )
{
Toolkit.getDefaultToolkit().setDynamicLayout( true ) ;
new Kanran_Frame() ;
( new Kanran_Frame() ).setVisible( true ) ;
}
}

//---------------------------------------------------------

public class Kanran_Panel1 extends JPanel
{
int x , y ;
int xc = 200 ;
int yc = 200 ;
double hankei = 100.0 ;
double kakudo ;

int rr = 0 ;
Graphics2D g2 ;

public Kanran_Panel1( )
{
this.setLocation( 300 , 0 ) ;
this.setBackground( Color.black ) ;
}

public void paintComponent( Graphics g )
{
super.paintComponent( g ) ;
g2 = (Graphics2D) g ;

System.out.println( "rr_00 =" + rr ) ;
g2.rotate( rr * Math.PI / 180 , xc , yc ) ;

//Outer CicleLine
g2.setColor( Color.GREEN ) ;
g2.drawOval( 100 , 100 , 200 , 200 ) ;

//Frame
for( kakudo = 0.0 ; kakudo < 360 ; kakudo += 20.0 )
{
x = xc + (int)( hankei * Math.cos( Math.toRadians( kakudo ) ) ) ;
y = yc + (int)( hankei * Math.sin( Math.toRadians( kakudo ) ) ) ;

g2.drawLine( xc , yc , x , y ) ;
}
}

public void move()
{
rr = ++rr % 360 ;

System.out.println( "rr_11 =" + rr ) ;

}
}

//-----------------------------------------------------------------

public class MyTimer extends TimerTask
{
Kanran_Panel1 kp1 ;

public MyTimer()
{
kp1 = new Kanran_Panel1() ;
}

@Override
public void run( )
{
kp1.move() ;
kp1.repaint() ;
}
}

//----------------------------------------------------------------

A 回答 (2件)

質問から何日か経っていますが解決したでしょうか?



念のため、気がついたところを指摘しておきます。

まず、回転しない原因ですが、これは、Kanran_Panel1のインスタンスが2つ作られ、一つが回転しないで表示され、もう一つが表示されずに回転しているせいです。

new Kanran_Panel1() が2か所にあります。
public Kanran_Frame( )の中で作られたものが表示されて、public MyTimer()の中で作られたものが表示されずに回転しています。

修正案としては、Kanran_Frame( )で作ったKanran_Panel1のインスタンスをMyTimer()に渡すやり方があります。

public Kanran_Frame( )の中の
timer.schedule( ( new MyTimer() ) , 500 , 1000 ) ;

timer.schedule( ( new MyTimer(k_can1) ) , 500 , 1000 ) ;
に変更し、さらに、
public MyTimer()
{
kp1 = new Kanran_Panel1() ;
}

public MyTimer(Kanran_Panel1 p)
{
kp1 = p;
}
に変更します。

これでとりあえず回転するようになると思います。


もう一つ問題になるのが、mainメソッドの中の、
new Kanran_Frame() ;
( new Kanran_Frame() ).setVisible( true ) ;
の部分です。
これでは、Kanran_Frameが2つ作られ1つが表示されていますので、
( new Kanran_Frame() ).setVisible( true ) ;
だけにしてください。

さらにもう一つ、このままでは、表示されたKanran_Frameの右上の閉じるボタンをクリックしても、フレームは閉じますが、タイマーは動いたまま残ります。
とりあえずこのアプリケーションを終了させてしまえばいいのであれば、Kanran_Frame( )の中の
this.setLayout(null);の次の行あたりに
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
を入れておきます。
    • good
    • 0
この回答へのお礼

takashi8842さん、回答有難う御座いました。

まさにご指摘の通りで、

====どのようにして「MyTimer」の 「run( )メソッドの内容」を
「timer.schedule」に渡してやるのか====

が理解出来ず、悩んでいました。
本当に有難う御座いました、今回の回答で少し理解することが出
来ました。

ところで実際に動かしてみると、その出力内容に疑問なのですが、
以下のようになります。

スレッドの内容が、
プログラム作成直後には、「rr_00」の出力をせずに

「rr_11」からの 出力となり、その後「rr_00」が出力されます。
しかし、「rr_00 =359」以降には、「rr_00」から(正常に?)
出力されます。

これがスレッド正常な動作でしょうか。
スレッドの正常な動作とはこのようなものなのでしょうか。
それとも何かの原因があるのでしょうか。

宜しくお願い致します。

=============================
rr_11 =1
rr_11 =2
rr_11 =3
rr_11 =4
rr_11 =5
rr_11 =6
rr_11 =7
rr_11 =8
rr_11 =9
rr_11 =10
rr_11 =11
rr_00 =11
rr_11 =12
rr_11 =13
rr_11 =14
rr_00 =14
rr_11 =15
rr_00 =15
rr_11 =16
rr_00 =16

//・・・・・・・・・・

rr_00 =354
rr_11 =355
rr_00 =355
rr_11 =356
rr_00 =356
rr_11 =357
rr_00 =357
rr_11 =358
rr_00 =358
rr_11 =359
rr_00 =359
rr_11 =0
rr_00 =0
rr_11 =1
rr_00 =1
rr_11 =2
rr_00 =2
rr_11 =3
rr_00 =3
rr_11 =4
rr_00 =4
rr_11 =5
rr_00 =5
rr_11 =6
rr_00 =6
rr_11 =7
rr_00 =7
rr_11 =8
rr_00 =8
rr_11 =9
rr_00 =9
rr_11 =10
rr_00 =10

お礼日時:2016/10/01 13:35

No.1です。



「rr_00」が抜けるということは、paintComponentが呼び出されていないということです。

kp1.repaint() を実行したからといって、必ずしもpaintComponentが呼び出されるとは限りません。

APIのドキュメントによると、
http://docs.oracle.com/javase/jp/8/docs/api/java …
「このメソッドはこのコンポーネントのpaintメソッドをできるだけ早く呼び出します。」
とあります。
repaint自体は、再描画のリクエストを出すだけで、実際の再描画は状況によっては遅延される可能性があります。

何かの処理が重くて、タイマーでrunを呼び出すタイミングに追い付かないときは、paintComponentが呼び出されず、何回かのrepaintがまとめられて1回のpaintComponent呼び出しになってしまうのでしょう。

多分、最初にフレーム等を生成・表示する処理に手間取って、最初だけ飛ばされてしまうのかもしれません。
    • good
    • 0
この回答へのお礼

takashi8842さん、回答有難う御座いました。

理解出来ました、今後とも宜しくお願いいたします。

お礼日時:2016/10/01 21:19

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!