Подтвердить что ты не робот

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

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

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

4b9b3361

Ответ 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();