0

I want to create a program that when a button is clicked, a panel may or may not change it's color. I have an array of panels that will turn red if a wrong combination is chosen. But I just want to make it red for about 1-2 seconds. After that I will change again the panel background to null. I want every panel to have it's own timer when it goes red. So far here is my code:

javax.swing.Timer timer = new javax.swing.Timer (250, new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {
        pnlArray [count - 2][count2].setBackground (Color.RED);
    };
});

pnlArray [count - 2][count2].setBackground (null);

This code generates an error: local variables referenced from an inner class must be final or effectively final. Obviously, pnlArray[][] is not a final panel. Thread.sleep() method however, freezes the whole program. How can I achieve this?

Bryan James
  • 65
  • 1
  • 11
  • 2
    (1) `local variables referenced from an inner class must be final or effectively final` Search this site on this error. (2) `Thread.sleep()` - then don't use it, you have a Swing `Timer` instead. (3) `setBackground (null)` This can be problematic. Conclusion: post an [MCVE](http://stackoverflow.com/help/mcve). Be sure to copy-paste your code to a *new project* and make sure it compiles and runs before posting it here. – user1803551 Feb 24 '16 at 03:40
  • Possible duplicate of [*How do I fade an image in swing?*](http://stackoverflow.com/q/2228735/230513) – trashgod Feb 24 '16 at 12:07

1 Answers1

0

I found a solution to my question using java.util.Timer package. Since the Timer() class needs final to run the run() method, I assigned the JPanel to a final variable. Then I canceled the timer once the first delay is over.

final JPanel pnlChange = pnlArray [count - 2][count2];
pnlChange.setBackground (Color.RED);

java.util.Timer timer = new java.util.Timer ();
TimerTask task = new TimerTask () {
    int seconds = 4;
    int divisor = 0;

    @Override
    public void run() {

            divisor++;

            if (divisor % seconds == 0) {
                timer.cancel ();
                pnlChange.setBackground (null);
            }
    }
};

timer.schedule(task, 0, 1000);
Bryan James
  • 65
  • 1
  • 11
  • 2
    You are changing UI from another thread than the [Event Dispatching Thread](https://docs.oracle.com/javase/tutorial/uiswing/concurrency/dispatch.html). Events from `java.util.Timer` are not posted in the event dispatching queue. That will result in undefined behaviour. Use `javax.swing.Timer` instead, or do UI interaction using [`SwingUtilities.invokeLater`](https://docs.oracle.com/javase/7/docs/api/javax/swing/SwingUtilities.html). – TT. Feb 24 '16 at 07:26