チョコミントアイス

今日は、スレッドがうまく動作しません、宜しくお願いします。

パネルに車輪を描画し、その車輪を回転させ、フレームに貼付けます。
パネルの車輪を回転させながら、更にそのパネルを下に移動させる
スレッドを書きましたが、うまく動作しません。

車輪の回転、パネルの移動のそれぞれの単独なら、どちらも正常に
動作しますが、両方を同時に動かそうとすると、パネルが移動するだけです。

2本のスレッドをうまくコントロール出来ていないのが原因だろうと考えて
いますが、複数のスレッドをどのようにコントロールするのか分かりません。

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

//---------------------------------------------------------------------
//フレーム
public class Kanran_Frame extends JFrame
{
Kanran_Panel1 k_can1 ;
Timer timer = new Timer() ;

public Kanran_Frame( )
{
this.setDefaultCloseOperation( EXIT_ON_CLOSE ) ;

Container cnt = this.getContentPane() ;

this.setSize( 1000 , 900 ) ;
this.setLayout( null ) ;

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

//上下移動
timer.schedule( new MyRunnable( k_can1 ) , 0 , 10 ) ;
//回転
// timer.schedule( new MyTimer( k_can1 ) , 0 , 10 ) ;
}

public static void main( String[] args )
{
Toolkit.getDefaultToolkit().setDynamicLayout( true ) ;
Kanran_Frame kf = new Kanran_Frame() ;
kf.setVisible( true ) ;
}
}
//-------------------------------------------------
//描画用パネル
class Kanran_Panel1 extends JPanel
{
int x , y ;
int xc = 200 ;
int yc = 200 ;
double hankei = 100.0 ;
double kakudo ;

int rr ;
Graphics2D g2 ;

public Kanran_Panel1( )
{
this.setBackground( Color.magenta ) ;
}

public void paintComponent( Graphics g )
{
super.paintComponent( g ) ;
g2 = (Graphics2D)g ;
// rotatetion Panel
g2.rotate( rr * Math.PI / 180 , xc , yc ) ;

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

g2.setColor( Color.magenta ) ;
g2.drawOval( 101 , 101 , 198 , 198 ) ;

g2.setColor( Color.orange ) ;
g2.drawOval( 102 , 102 , 196 , 196 ) ;

//Scue Arm Line //Backets
for( kakudo = 0.0 ; kakudo < 360 ; kakudo += 20.0 )
{
//Scue Aim Line
x = xc + (int)( hankei * Math.cos( Math.toRadians( kakudo ) ) ) ;
y = yc + (int)( hankei * Math.sin( Math.toRadians( kakudo ) ) ) ;
g2.drawLine( xc , yc , x , y ) ;

//Backets
g2.fillRect( x - 5 , y - 2 , 11 , 11 ) ;
}
}
}
//-------------------------------------------------
//updown
class MyRunnable extends TimerTask
{
Kanran_Panel1 kp1 ;
int updown = 0 ;
int x0 = 600 ;

MyRunnable( Kanran_Panel1 thr )
{
kp1 = thr ;
}

public void run( )
{
while( updown <= 500 )
{
updown = updown += 1 ;
kp1.setLocation( x0 , updown ) ;

try
{
Thread.sleep( 10 ) ;
}
catch( InterruptedException e ) {}
}
}
}
//-------------------------------------------------
//回転
class MyTimer extends TimerTask
{
Kanran_Panel1 kp1 ;

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

public void run( )
{
kp1.rr = ++ kp1.rr % 360 ;
kp1.repaint() ;
}
}
//-------------------------------------------------

質問者からの補足コメント

  • tknakamuriさん、回答有難う御座います。

    >Timerのインスタンスを複数作れば済む話では?

    # Timerのインスタンスを複数作るとは、
     具体的には、
     「timer.schedule( new MyRunnable( k_can1 ) , 0 , 10 ) ;
     timer.schedule( new MyTimer( k_can1 ) , 0 , 10 ) ;」
     をどのように、書き換えてやればいいのでしょうか。

     宜しくお願い致します。

    No.3の回答に寄せられた補足コメントです。 補足日時:2016/10/06 14:18

A 回答 (4件)

># Timerのインスタンスを複数作るとは、


> 具体的には、
> 「timer.schedule( new MyRunnable( k_can1 ) , 0 , 10 ) ;
> timer.schedule( new MyTimer( k_can1 ) , 0 , 10 ) ;」

そのまんまですよ。

Timer timer1 = new Timer(true);
Timer timer2 = new Timer(true);

// 上下移動
timer1.schedule(new MyRunnable(k_can1), 0, 10);
// 回転
timer2.schedule( new MyTimer( k_can1 ) , 0 , 10 ) ;

こんなかんじ。試してないけど多分動きます。
    • good
    • 0
この回答へのお礼

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

正常に動きました。
本当に有難う御座いました。
今後とも宜しくお願いします。

お礼日時:2016/10/06 16:20

>#Timerで2個のスレッドを走らせることは出来ないのでしょうか。



TimerのJavadocに

>各 Timer オブジェクトと対応するのは、
>タイマーのタスクをすべて連続して実行するために使用される、
>単一のバックグラウンドスレッドです。

と書いてあるので無理でしょう。

Timerのインスタンスを複数作れば済む話では?
この回答への補足あり
    • good
    • 0

>他に思い当たる原因はあるのでしょうか。



そもそも Timer ってスレッド1個しか作らないからかな。

一個のTimer だと順番に登録されたタスクを
実行するだけだと思います。

いずれにしれも GUI の操作をバックグラウンドスレッドから
行うのは厳禁。
    • good
    • 0
この回答へのお礼

tknakamuriさん、回答ありがとうございます。

>そもそも Timer ってスレッド1個しか作らないからかな。

#Timerで2個のスレッドを走らせることは出来ないのでしょうか。
 web等のサイトを参考にしましたが、複数のスレッドを走らせているよう に見えるのですが、私の勘違いなのでしょうか。

Threadクラスを使って書き換えてやる必要があるということでしょうか。

宜しくお願いします。

お礼日時:2016/10/06 12:28

Swingが素人なんですが(javaFXや .NET や AndroidやWindowsしか


しらない)、
一般的にGraphicsの描画処理に複数のスレッドを使うのは非常識では?

他のライブラリでは、スレッドを使うにしても、最終的な描画処理は
描画専用スレッドにイベントを引き渡すのが普通だと思います。
そのためのユーティリティクラスやメソッドが用意されているのが
普通です。

Swingにもそういうのがあるのでは?

SwingUtilities.invokeLater

あたりそれっぽいと思います。あくまで素人のあてずっぽうですが。。。
    • good
    • 0
この回答へのお礼

tknakamuriさん、回答有難う御座います。
コードを変更してみましたが、結果は同じでした。
他に思い当たる原因はあるのでしょうか。
(文字数オーバのため、一部省略しています。)

宜しくお願いします。
---------------------------------------------------------------
public class Kanran_Frame extends JFrame
{
static Kanran_Panel1 k_can1 ;
static Timer timer = new Timer() ;

public Kanran_Frame( ) 
   {
    ・
    ・
    ・
   }

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

SwingUtilities.invokeLater
(
new Runnable()
{
public void run()
{
Kanran_Frame kf = new Kanran_Frame() ;
kf.setVisible( true ) ;

//上下移動
timer.schedule( new MyRunnable( k_can1 ) , 0 , 10 ) ;
//回転
timer.schedule( new MyTimer( k_can1 ) , 0 , 10 ) ;
}
}
) ;
}
}

お礼日時:2016/10/05 22:19

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