El temporizador Javax.swing se repite correctamente, pero ActionListener no hace nada

Estoy tratando de mostrar el color de fondo en un campo de texto. La configuración de mi temporizador es la siguiente:

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 es el siguiente:

  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 

Ahora, cuando pongo esto en depuración y sigo la acción, el progtwig pasa paso a paso por el flash y alternar entre las dos alternativas. Pero en pantalla, solo se produce el primer alternar. Después de eso, no hay acción, aunque el flash sigue funcionando.

¿Que esta mal aquí?

Gracias de antemano por cualquier ayuda.

Hay un par de problemas aquí.

La primera cosa obvia es que parece estar usando estática mutable. Esta es una idea realmente mala e indica (¡y causa!) Confusión. En este caso particular, uno de los problemas causados ​​es que la flasher estática flasher es compartida.

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

Estamos agregando dos acciones Flash . Por lo general, esto sería malo, pero solo produce un “error” indetectable. El color se establecerá dos veces.

Junte estas dos cosas, y tenemos dos acciones sin interrupción que realizan el mismo alternar. Dos conmutadores. El estado no cambia (aunque hay repintes, eventos de cambio de propiedad, etc.).

Por lo tanto, no use estadísticas estáticas mutables y mantenga el código limpio.

Este ejemplo varía continuamente la saturación del color de fondo de un panel:

Prueba Flash

 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 clut = new LinkedList(); 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); } }); } } 
 tmr = new javax.swing.Timer(1000, flash); 

Probé tu código y funciona bien.

¿Por qué usa un contexto estático para SpreademPanel.historyPnl.NameTxt ?

EDITAR

Es posible que desee rediseñar su clase para pasar el componente en el constructor.

 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 

y luego iniciarlo con

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