Java swing计时器可以正常重复,但ActionListener不会';我什么也不做

Java swing计时器可以正常重复,但ActionListener不会';我什么也不做,java,swing,javax.swing.timer,Java,Swing,Javax.swing.timer,我试图在文本字段中闪烁背景色。我的计时器设置如下所示: Flash flash = new Flash(); //set up timer tmr = new javax.swing.Timer(1000, new Flash()); tmr.addActionListener(flash); tmr.setInitialDelay(0); tmr.setRepeats(true); tmr.start();

我试图在文本字段中闪烁背景色。我的计时器设置如下所示:

 Flash flash = new Flash();                      //set up timer
 tmr = new javax.swing.Timer(1000, new Flash());
 tmr.addActionListener(flash);
 tmr.setInitialDelay(0);
 tmr.setRepeats(true);
 tmr.start();                 
 static class Flash implements ActionListener
 {
    public void actionPerformed(ActionEvent evt)
    {
        if (flasher)
        {
            SpreademPanel.historyPnl.NameTxt.setBackground(Color.white);
        }
        else
        {
            SpreademPanel.historyPnl.NameTxt.setBackground(Color.pink);
        }
        flasher = !flasher;
    } //actionPerformed
} //Flash
我的actionListener如下所示:

 Flash flash = new Flash();                      //set up timer
 tmr = new javax.swing.Timer(1000, new Flash());
 tmr.addActionListener(flash);
 tmr.setInitialDelay(0);
 tmr.setRepeats(true);
 tmr.start();                 
 static class Flash implements ActionListener
 {
    public void actionPerformed(ActionEvent evt)
    {
        if (flasher)
        {
            SpreademPanel.historyPnl.NameTxt.setBackground(Color.white);
        }
        else
        {
            SpreademPanel.historyPnl.NameTxt.setBackground(Color.pink);
        }
        flasher = !flasher;
    } //actionPerformed
} //Flash
现在,当我将其放入调试并遵循操作时,程序会重复通过flash并在两个选项之间切换。但在屏幕上,只有第一个切换 发生。之后,尽管flash仍在运行,但没有任何动作

这里怎么了


提前感谢您的帮助。

我尝试了您的代码,效果很好

tmr = new javax.swing.Timer(1000, flash);
为什么对
SpreademPanel.historyPnl.NameTxt
使用静态上下文

编辑

您可能需要重新设计类以在构造函数中传递组件

private class Flash implements ActionListener
{
    private boolean flasher = false;
    private JComponent component;

    public Flash(JComponent component) {
        this.component = component;
    }

    public void actionPerformed(ActionEvent evt)
    {
        if (flasher)
        {
            component.setBackground(Color.white);
        }
        else
        {
            component.setBackground(Color.pink);
        }
        flasher = !flasher;
    } //actionPerformed
} //Flash
然后用

 Flash flash = new Flash(SpreademPanel.historyPnl.NameTxt);
 Timer tmr = new javax.swing.Timer(1000, flash);
 tmr.start();

这里有几个问题

第一件显而易见的事情是,您似乎正在使用可变静态。这是一个非常糟糕的想法,表明(并导致!)混乱。在这种特殊情况下,导致的问题之一是共享
闪光器
静态

Flash flash = new Flash();                      //set up timer
tmr = new javax.swing.Timer(1000, new Flash());
tmr.addActionListener(flash);
我们正在添加两个
Flash
操作。通常这会很糟糕,但只会产生一个无法检测的“bug”。颜色将设置两次

把这两件事放在一起,我们有两个不间断的动作,它们执行相同的切换。两个开关。状态不会更改(尽管存在重绘、属性更改事件等)


因此,不要使用可变静态,并保持代码干净。

此示例不断改变面板背景颜色:

import java.awt.*;
import java.awt.event.*;
import java.awt.event.ActionListener;
import java.util.LinkedList;
import java.util.Queue;
import javax.swing.*;

public class FlashTest extends JPanel {

    private static final Font font = new Font("Serif", Font.PLAIN, 32);
    private static final String s = "Godzilla alert!";

    FlashTest() {
        this.setPreferredSize(new Dimension(256, 96));
        this.setBackground(Color.red);
        Timer t = new Timer(50, new Flash(this));
        t.start();
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.setFont(font);
        int xx = this.getWidth();
        int yy = this.getHeight();
        int w2 = g.getFontMetrics().stringWidth(s) / 2;
        int h2 = g.getFontMetrics().getDescent();
        g.setColor(Color.black);
        g.drawString(s, xx / 2 - w2, yy / 2 + h2);
    }

    private static class Flash implements ActionListener {

        private final float N = 32;
        private final JComponent component;
        private final Queue<Color> clut = new LinkedList<Color>();

        public Flash(JComponent component) {
            this.component = component;
            for (int i = 0; i < N; i++) {
                clut.add(Color.getHSBColor(1, 1 - (i / N), 1));
            }
            for (int i = 0; i < N; i++) {
                clut.add(Color.getHSBColor(1, i / N, 1));
            }
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            component.setBackground(clut.peek());
            clut.add(clut.remove());
        }
    }

    static public void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                JFrame f = new JFrame();
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                f.add(new FlashTest());
                f.pack();
                f.setVisible(true);
            }
        });
    }
}

import java.awt.*;
导入java.awt.event.*;
导入java.awt.event.ActionListener;
导入java.util.LinkedList;
导入java.util.Queue;
导入javax.swing.*;
公共类FlashTest扩展了JPanel{
私有静态最终字体字体=新字体(“衬线”,Font.PLAIN,32);
私有静态最终字符串s=“哥斯拉警报!”;
FlashTest(){
此.setPreferredSize(新维度(256,96));
这个.挫折背景(颜色.红色);
定时器t=新定时器(50,新闪光灯(本));
t、 start();
}
@凌驾
受保护组件(图形g){
超级组件(g);
g、 setFont(字体);
int xx=this.getWidth();
int yy=this.getHeight();
int w2=g.getFontMetrics().stringWidth(s)/2;
int h2=g.getFontMetrics().getDescent();
g、 设置颜色(颜色为黑色);
g、 抽绳(s,xx/2-w2,yy/2+h2);
}
私有静态类Flash实现ActionListener{
私人最终浮动N=32;
私有最终组件;
private final Queue clut=new LinkedList();
公共闪存(JComponent组件){
这个组件=组件;
对于(int i=0;i
关于混淆,您是完全正确的,我是Java新手,以前在我使用的语言中没有遇到过“静态”的概念,但我正在慢慢地了解它的所有含义:这是一个新的概念,感谢您指出这个案例的复杂性。我把计时器从主程序中移到了SpreadTempanel中,它显然属于这里,现在它工作正常了。