0

パラメータに渡される制御のバックグラウンドを変更できる静的クラスを作成しようとしています。だから私はこれを達成しました:

public static void wrong(final Component component) {

        component.setBackground(Color.RED);
        Timer   timer = new Timer(2, wrongAction);

        wrongAction = new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {

                int green = component.getBackground().getGreen();
                int blue = component.getBackground().getBlue();
                component.setBackground(new Color(255, green + 1, blue + 1));
                if (component.getBackground() == Color.WHITE) {
                    timer.stop();
                }
            }
        };

        timer.start();

    }  

そして、私はエラーがあります:

Cannot refer to a non-final variable timer inside an inner class defined in a different method

もちろん、タイマーをfinalに変更することはできますが、それを行うとメソッドは機能しなくなります。
私はそれをグーグルで検索し、他のスタックオーバーフローのトピックで答えを見つけようとしましたが、何も役に立ちませんでした。

よろしくお願いします!

4

4 に答える 4

4

問題は、別の wrongAction 参照を使用していることです。

public static void wrong(final Component component) {

    component.setBackground(Color.RED);
    Timer   timer = new Timer(2, wrongAction);// <-- Here wrongAction is not the one you
                                              // define on the next line

    wrongAction = new ActionListener() { // <-- This is a new ActionListener but Timer
                                         // has no knowledge about it.
        @Override
        public void actionPerformed(ActionEvent e) {

            int green = component.getBackground().getGreen();
            int blue = component.getBackground().getBlue();
            component.setBackground(new Color(255, green + 1, blue + 1));
            if (component.getBackground() == Color.WHITE) {
                timer.stop();
            }
        }
    };

    timer.start();

}

次のコードはすぐに機能します (ただし、あまりクリーンではありません。Timer をクラスの変数にして、リスナーが参照できるように、これらすべてを専用のオブジェクトにカプセル化する方がよいでしょう):

public static void wrong(final Component component) {
        class MyActionListener implements ActionListener {
            private Timer timer;

            public void setTimer(Timer timer) {
                this.timer = timer;
            }

            @Override
            public void actionPerformed(ActionEvent e) {

                int green = component.getBackground().getGreen();
                int blue = component.getBackground().getBlue();
                component.setBackground(new Color(255, green + 1, blue + 1));
                if (component.getBackground().equals(Color.WHITE)) {
                    if (timer == null) {
                        System.err.println("This sucks, I got no timer");
                    } else {
                        timer.stop();
                    }
                }

            }
        }
        MyActionListener wrongAction = new MyActionListener();
        component.setBackground(Color.RED);
        Timer timer = new Timer(2, wrongAction);
        wrongAction.setTimer(timer);


        timer.start();

    }
于 2012-05-14T16:43:38.233 に答える
1

wrongAction は内部クラスであり、Java では外部で定義されるローカル変数が内部クラスで使用されるために final である必要があります。

final Timer   timer = new Timer(2, wrongAction);

wrongAction = new ActionListener() {
    //...
}
于 2012-05-14T16:34:34.273 に答える
1

wrongAction をタイマーコンストラクターに渡してから、実際に初期化しているようです!!!

コードであってはならない

wrongAction = new ActionListener() {...
        };

上にいる

Timer   timer = new Timer(2, wrongAction);

???

もちろん、Timer timer =null; が必要です。頂点で

EDITED:間違ったアクションを完全に削除して、このようにシンプルに保つのはどうですか-

final Timer   timer = new Timer(2, new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {

                int green = component.getBackground().getGreen();
                int blue = component.getBackground().getBlue();
                component.setBackground(new Color(255, green + 1, blue + 1));
                if (component.getBackground() == Color.WHITE) {
                    timer.stop();
                }
            }
        });

;

于 2012-05-14T16:40:12.073 に答える
0

コンストラクターに null を渡してから、ActionListener

final Timer timer = new Timer(2,null);

timer.addActionListener(new ActionListener(){
//...
});
timer.start();
于 2012-05-14T16:49:37.680 に答える