Javax.swing timer repeats fine, but ActionListener doesn’t do anything

This example continually varies the saturation of a panel’s background color:

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

Leave a Comment