0

I'm trying to flash a Java graphic object by changing the color and calling the repaint() method. The color is only updating with the final change color call. Here is my code:

public void start() {
    try {
        Color origColor = node.getColor();
        for (int i=0; i<noOfFlashes; i++) {
            Manager.gui.getDrawGraph().changeNodeColor(node, Color.WHITE);
            Thread.sleep(500);
            Manager.gui.getDrawGraph().changeNodeColor(node, origColor);
            Thread.sleep(500);
        }
        Manager.gui.getDrawGraph().changeNodeColor(node, Graph.VISITED_NODE);       
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

and the change node color method is:

public void changeNodeColor(Node node, Color c) {
    node.setColor(c);
    repaint();
}

The change node color is in the same class as the paint component.

Any help would be much appreciated.

Alberto Solano
  • 7,972
  • 3
  • 38
  • 61
Josh
  • 818
  • 2
  • 16
  • 27

3 Answers3

1

Based on what i understand from your code, I will probably recommend the use of SwingWorker.

I know you do not have any cost expensive code but you using SwingWorker, you will be able to update your GUI more easily.

VirtualTroll
  • 3,077
  • 1
  • 30
  • 47
1

You need to use separate thread to manage your GUI event. You can do this, using a SwingWorker, as suggested by Amine, or implement the Runnable interface, or extend the Thread class, developing the run() method, that is the task of your thread.

You can read this old question of SO : How do I use SwingWorker in Java?

A tutorial for SwingWorker : http://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html

A tutorial to make a Thread : http://docs.oracle.com/javase/tutorial/essential/concurrency/

The color is only updating with the final change color call.

If you don't use a separate thread, your gui will freezing until the method is completely executed, and you won't see the color change separated by Thread.sleep(500);.

UPDATE

In this link, in the paragraph Why does a Swing GUI freeze or lock up?, you can understand why a Java Swing GUI freezes, with the use of a single thread.

Check also this official link, in the paragraph Creating Threads, and this page, that returns:

Swing's single-thread rule says that Swing components can only be accessed by a single thread. This rule applies to both gets and sets, and the single thread is known as the event-dispatch thread.

The single-thread rule is a good match for UI components because they tend to be used in a single-threaded way anyway, with most actions being initiated by the user. Furthermore, building thread safe components is difficult and tedious: it's a good thing not to be doing if it can be avoided. But for all its benefits, the single-thread rule has far-reaching implications.

Swing components will generally not comply with the single-thread rule unless all their events are sent and received on the event-dispatch thread. For example, property-change events should be sent on the event-dispatch thread, and model-change events should be received on the event-dispatch thread.

For model-based components such as JTable and JTree, the single-thread rule implies that the model itself can only be accessed by the event-dispatch thread. For this reason, the model's methods must execute quickly and should never block, or the entire user interface will be unresponsive.

I think that the sentences above are very useful to understand better the Swing package.

I report the suggestion of trashgod.

You can use the Timer class, from the javax.swing.Timer package. That is also a good alternative.

In this question, trashgod reports some examples of Timer.

Check here for a tutorial about Timer.

Community
  • 1
  • 1
Alberto Solano
  • 7,972
  • 3
  • 38
  • 61
  • 1
    +1 [`javax.swing.Timer`](http://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html), mentioned [here](http://stackoverflow.com/q/8237370/230513), is another alternative. – trashgod Nov 24 '11 at 17:30
  • @trashgod Thanks for the vote, the suggestion, and the link to your question. Your questions, are always very useful and nice. ;-) The Timer is also a good alternative. I edit my answer to insert the link to your question. – Alberto Solano Nov 25 '11 at 08:35
0

I am not sure which framework you're using here... but you may need a repaint() just before the Thread.sleep(). Is there a Manager.gui.repaint() perhaps? (Sorry, complete guesswork here...)

Jaco Van Niekerk
  • 4,180
  • 2
  • 21
  • 48