0

I have a JTextField that is cleared if it has invalid content. I would like the background to flash red one or two times to indicate to the user that this has happened. I have tried:

field.setBackground(Color.RED);
field.setBackground(Color.WHITE);

But it is red for such a brief time that it cannot possibly be seen. Any tips?

rhombidodecahedron
  • 7,693
  • 11
  • 58
  • 91

2 Answers2

7

The correct solution, almost arrive at by just eric, is to use a Swing Timer, since all the code in the Timer's ActionListener will be called on the Swing event thread, and this can prevent intermittent and frustrating errors from occurring. For example:

public void flashMyField(final JTextField field, Color flashColor, 
     final int timerDelay, int totalTime) {
  final int totalCount = totalTime / timerDelay;
  javax.swing.Timer timer = new javax.swing.Timer(timerDelay, new ActionListener(){
    int count = 0;

    public void actionPerformed(ActionEvent evt) {
      if (count % 2 == 0) {
        field.setBackground(flashColor);
      } else {
        field.setBackground(null);
        if (count >= totalCount) { 
          ((Timer)evt.getSource()).stop();
        }
      }
      count++;
    }
  });
  timer.start();
}

And it would be called via flashMyField(someTextField, Color.RED, 500, 2000);

Caveat: code has been neither compiled nor tested.

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
  • And FYI: the reason why you should use a `Timer` and why you do not see the red color is more or less the same as what I described in [this answer](http://stackoverflow.com/questions/11088910/timing-with-swing-animation/11090056#11090056). – Robin Jun 21 '12 at 05:43
  • 2
    +1 Nice catch in this answer to not call `setBackground( Color.WHITE )` which is not the default background in some L&F's. – Robin Jun 21 '12 at 05:44
2

You need to extend public class Timer Do it like so:

private class FlashTask extends TimerTask{
    public void run(){
       // set colors here
    }
}

You can set Timer to execute in whatever intervals you prefer to create the flashing effect

From documentation:

public void scheduleAtFixedRate(TimerTask task, long delay, long period)

Schedules the specified task for repeated fixed-rate execution, beginning after the specified delay.

just eric
  • 927
  • 1
  • 11
  • 23
  • That's a decent solution, but I only want it to flash once. The problem lies more in the fact that the background isn't set for red for a long enough time. – rhombidodecahedron Jun 21 '12 at 00:43
  • By flash once do you mean change colors for a second, then change back and stay there? or just change colors and stay that color until a condition is met? – just eric Jun 21 '12 at 00:45
  • 1
    "isn't set for red for a long enough time" do you mean you need help editing the intervals for changing? – just eric Jun 21 '12 at 00:51
  • Your idea is right but your implementation is wrong. Since this is a Swing question, the original poster should most definitely not use a java.util.Timer but rather a javax.swing.Timer or Swing Timer. There's a big difference in how they respect the Swing event thread. – Hovercraft Full Of Eels Jun 21 '12 at 02:32
  • You can see the extra effort required in this [example](http://stackoverflow.com/a/11058263/230513). – trashgod Jun 21 '12 at 03:26
  • A ha! Now that I see the correct solution I have a better understanding. Nice work guys! – just eric Jun 21 '12 at 20:04