Таймер Javax.swing повторяет штраф, но 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();                 

My actionListener выглядит следующим образом:

 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 и переключает между двумя альтернативами. Но на экране, только первый переключатель имеет место. После этого никаких действий, хотя вспышка все еще функционирует.

Что здесь не так?

Заранее благодарим за помощь.

Ответ 1

Здесь есть пара проблем.

Первое очевидное, что вы, кажется, используете изменчивую статику. Это действительно плохая идея и указывает (и вызывает!) Путаницу. В этом конкретном случае одна из проблем вызвана тем, что статический файл flasher является общим.

Flash flash = new Flash();                      //set up timer
tmr = new javax.swing.Timer(1000, new Flash());
tmr.addActionListener(flash);

Мы добавляем два действия Flash. Обычно это было бы плохо, но просто создавайте неопределяемую "ошибку". Цвет будет установлен дважды.

Объедините эти две вещи, и у нас есть два действия без перерыва, которые выполняют один и тот же переключатель. Два переключателя. Состояние не изменяется (хотя есть перерисовка, события изменения свойств и т.д.).

Итак, не используйте изменчивую статику и сохраняйте код чистым.

Ответ 2

Этот пример постоянно меняет цвет фона saturation:

FlashTest

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);
            }
        });
    }
}

Ответ 3

tmr = new javax.swing.Timer(1000, flash);

Ответ 4

Я пробовал ваш код, и он отлично работает.

Почему вы используете статический контекст для 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();