クリア後、押せなくしたstartのボタンを元に戻してもう一度できるようにします。。
ボタンを無効にするのは
rbtn.setEnabled(false);
でしたから、有効にするには
rbtn.setEnabled(true);
です。
ところがこれを実行しようとすると、困難にぶつかります。run()メソッドからrbtnが見えないからです。
run()メソッドのwhile内で障害物がクリアされると、成績などが表示されrun()メソッドは終わります。ここでrbtn.setEnabled(true)も実行すればよいのですが、rbtnにアクセスできません。コンパイラから「シンボルが見つかりません」と言われます。rbtnはABallクラスの変数ですから MoveDisk()クラスのインスタンスからは見えないのです。
run()メソッドが終了すると、このスレッドはなくなります。他のスレッドとは独立に動いていたものなので、このスレッドが終了したことを他に知らせる方法がありません。ASallプログラムで残っているのはgbtn,bbtnのボタンを押したらカウンタを増やすという部分と、mypnlのpaintComponent()がパネルの書き換えをすべく待機している部分です。この部分にMoveDiskが終了したことを察知してrbtnの有効化をさせるのは無理でしょう。
mypnlのフィールドにある変数(インスタンス)は mypnl.buffimg mypnl.bgcolor mypnl.greenct mypnl.bluect というようにアクセスできます。これはMoveDisk()クラスのインスタンスをnewで作るときに、mypnlが引数になっているからです。
そこでrbtnも引数としてよぶことにします。(1)-(2)の書き換えが必要です
(1)rbtnも引数にする。
public void actionPerformed(ActionEvent e) { if (e.getSource() == rbtn) { rbtn.setEnabled(false); rbtn.setText("busy"); MoveDisk disk = new MoveDisk(mypnl,rbtn); //for 6 disk.start();
(2)MoveDiskのフィールドとコンストラクタも対応させる。
MyPanel mypnl; ... 略 ... Target[] ts = new Target[tmax]; JButton btn; public MoveDisk(MyPanel mypnl , JButton btn) { this.mypnl = mypnl; this.buffimg = mypnl.buffimg; this.btn = btn; thg = buffimg.createGraphics();
フィールドに JButton btn を宣言したのは、run()メソッドの中でbtnを有効化するためです。
run()メソッドの最後に次のように書きます。ボタンの有効化はsetEnabled(true)、ボタンの文字はreplayです。
thg.drawString("Time "+((time1-time0)/1000),sx,sy+ymax/8*3); btn.setEnabled(true); btn.setText("replay"); mypnl.repaint();
前回の表示が残っています。(1)-(2)の2ヶ所直す必要があります。
(1)MyPanelのコンストラクタでやっていたパネル全面を背景色に塗る作業はMoveDiskのコンストラクタに移す必要があります。
xmax = buffimg.getWidth(); ymax = buffimg.getHeight(); thg.setColor(mypnl.bgcolor); thg.fillRect(0, 0, xmax, ymax); x = (int)(xmax*Math.random()); y = (int)(ymax*Math.random());
(2)クリック回数もリセットする必要があります。
mypnl.greenct = 0; mypnl.bluect = 0; this.greenct = mypnl.greenct; this.bluect = mypnl.bluect;
clearct と bouncect はフィールドですでに 0 に初期化されるようになっていますから必要ありません。
上記の様に働くようにし、動作を確認しなさい。