new ComponentFlasher().flashNow(myTextField); // works on buttons too
Sometimes people need help finding messages on screen, or seeing data that has changed. The above code will change the color of the text in the text field myTextField to red, then quickly fade it back to black.
 
ComponentFlasher.java :
import java.awt.Color; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.LinkedList; import java.util.List; import javax.swing.JComponent; import javax.swing.SwingUtilities; import javax.swing.Timer; // Please feel free to reuse, modify and distribute. // Please add your own url or email address to this list: // // - http://javajon.blogspot.com/ // /** * Class to make it easy to flash a component. */ public class ComponentFlasher { private final ListflashQueue = new LinkedList (); private final Object FLASH_LOCK = new Object(); private volatile JComponent flashCurrent = null; private final FlashTimer flashTimer = new FlashTimer(); private final int maxQueueSize = 3; public void flashQueue(JComponent componentToAddToQueue) { synchronized (FLASH_LOCK) { if (flashCurrent == componentToAddToQueue) { flashReset(componentToAddToQueue); } else { final boolean restartTimer = flashQueue.isEmpty() && (flashCurrent == null); flashQueue.remove(componentToAddToQueue); flashQueue.add(componentToAddToQueue); if (restartTimer) { flashTimer.start(); } } } } public void flashNow(final JComponent componentToFlashNow) { synchronized (FLASH_LOCK) { if (flashCurrent != componentToFlashNow) { final boolean restartTimer; if (flashCurrent != null) { final JComponent componentToPutBackIntoTheQueue = flashCurrent; flashQueue.remove(componentToPutBackIntoTheQueue); flashQueue.add(0, componentToPutBackIntoTheQueue); SwingUtilities.invokeLater(new Runnable() { @Override public void run() { componentToPutBackIntoTheQueue.setForeground(Color.BLACK); } }); restartTimer = false; } else { restartTimer = flashQueue.isEmpty(); } flashCurrent = componentToFlashNow; if (restartTimer) { flashTimer.start(); } } flashReset(componentToFlashNow); } } private void flashReset(final JComponent componentToFlashNow) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { componentToFlashNow.setForeground(Color.RED); } }); } private void flashIteration(final JComponent componentToFlash) { // run this code on the UI thread SwingUtilities.invokeLater(new Runnable() { @Override public void run() { // find out how red we still are final int red = flashCurrent.getForeground().getRed() - 10; if (red > 0) { componentToFlash.setForeground(new Color(red, 0, 0)); } else { synchronized (FLASH_LOCK) { if (flashCurrent == componentToFlash) { flashCurrent = null; } } } } }); } private void checkQueue() { // no current component - check queue if (!flashQueue.isEmpty()) { synchronized (FLASH_LOCK) { // recheck the same flags we just checked // now that we have the lock we are sure they won't change. if (flashCurrent == null) { if (flashQueue.isEmpty()) { // stop the timer flashTimer.stop(); } else { // make the next item current while (flashQueue.size() > (maxQueueSize + 1)) { flashQueue.remove(0); } final JComponent next = flashQueue.remove(0); flashCurrent = next; flashReset(next); } } } } } private class FlashTimer extends Timer { public FlashTimer() { super(50, new FlashTimerAction()); } } private class FlashTimerAction implements ActionListener { public FlashTimerAction() { } @Override public void actionPerformed(ActionEvent e) { // is there a current component ? if (flashCurrent == null) { checkQueue(); } else { // current component - copy to send to anon-implementation Runnable flashIteration(flashCurrent); } } } }
No comments:
Post a Comment