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

当然,我们可以将 timer 更改为 final,但是在我们这样做之后方法会停止工作。
我试图用谷歌搜索它并在其他 stackoverflow 主题中找到答案,但没有任何帮助。

非常感谢大家提前!

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; 在顶部

已编辑:您如何完全删除 wrongAction 并像这样保持简单-

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

您可以在构造函数中传递一个空值,然后添加一个ActionListener

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

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