終わったらもう1回

もう一回

クリア後、押せなくしたstartのボタンを元に戻してもう一度できるようにします。。

to replay

run()メソッドからrbtnが見えない

ボタンを無効にするのは

rbtn.setEnabled(false);

でしたから、有効にするには

rbtn.setEnabled(true);

です。

ところがこれを実行しようとすると、困難にぶつかります。run()メソッドからrbtnが見えないからです。

class ABalln //クラス
JButton rbtn;
MyPanel mypnl;
void actionPerformed()
  new MoveDisk(mypnl);
void main()
class MyPanel //クラス
void paintComponent()
class MoveDisk //クラス
void run()
class Target //クラス

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)の書き換えが必要です

ファイル名 ABall6.java の一部

(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です。

ファイル名 ABall6.java の一部

thg.drawString("Time "+((time1-time0)/1000),sx,sy+ymax/8*3); 
btn.setEnabled(true);
btn.setText("replay");
mypnl.repaint();

初期画面クリア

前回の表示が残っています。(1)-(2)の2ヶ所直す必要があります。

ファイル名 ABall6.java の一部

(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 に初期化されるようになっていますから必要ありません。

課題

1.

上記の様に働くようにし、動作を確認しなさい。

ファイル名 ABall6.java

rbtn enabled


Javaプログラミング
聖愛中学高等学校
http://www.seiai.ed.jp/
Dec.2003
Oct.2010
Nov.2012