tags:

views:

575

answers:

3

I have a Java Swing UI that isn't updating/repainting as I thought it should. The app sends an XMPP message and receives a response on a different thread. That response is processed and the UI is updated to reflect information contained in the message.

When the response is received, I update a JPanel component using

javax.swing.SwingUtilities.invokeLater(new Runnable() {
    public void run() { /* execute logic to update panel */ }
});

It's been quite sometime since I've developed in Java, but based on my research online invokeLater queues the runnable up for execution on the GUI thread. However, my GUI doesn't update until I do something else in the app that causes a repaint - such as resizing the window. What am I missing? After the logic for updating the panel, I've tried various combinations of invalidate() and repaint(), but the result is still the same - the GUI does not update until I, say, resize the window.

EDIT: When I say updating the panel, I am, specifically, doing a removeAll() and then adding a handful of JLabels.

+1  A: 

If you mean by "update the panel" that you are adding or removing components, then you better use invalidate() or revalidate() so that the layout manager catches the changes.

See here for a similar problem.

Stroboskop
+1  A: 

If you are adding or removing components from a panel during the GUI event handling (such as action listeners) calling doLayout() should hopefully fix your problem. I've found when the GUI doesn't update, calling validate(), doLayout(), and repaint() tends to fix things.

Peter Nix
actually you are not supposed to call doLayout() directly and should call revalidate() instead.
Stroboskop
@Stroboskop though you're not supposed to, the documentation says "This is usually called when the component is validated." and my experiences suggest that when adding and removing components from a container during event handling, this method isn't called by revalidate().
Peter Nix
Right. Since all this happens in the EventQueue, there's a good chance that the revalidate flag will not be looked at until you're done. But i would have guessed a call to repaint() would trigger both painting and layout later on...
Stroboskop
+5  A: 

After adding/removing components from a panel you should use:

panel.revalidate(); // this works 99% of the time
panel.repaint(); // sometimes needed.

Other stuff like validate(), invalidate() etc., is left over from AWT days I believe and revalidate() does a better job and was added specifically for Swing.

camickr