tags:

views:

50

answers:

4

How do you refresh a JPanel on the panel change from container CardLayout?

+1  A: 

Use the show() method. From the Java API:

Flips to the component that was added to this layout with the specified name, using addLayoutComponent. If no such component exists, then nothing happens.

CardLayout#first(), next(), and previous() do something similar.

Sometimes, when I've made a panel swap like this (though not that I can remember on CardLayout, but it's been a while since I used it), I've also needed to pack the frame again. If that doesn't work, you can call revalidate(), which lets Swing know that the component needs to be redrawn.

You may also want to consider using a tabbed pane, as it does a lot of this for you; I started out a project trying to use CardLayout and decided to use a the tabbed pane instead. Depends on what you want to do, of course.

Feanor
A: 

The show() method does the trick of switching panels, but it doesn't "refresh" the data. Is there an actionlistener or something that I can have it reload/refresh my data on that screen?

cfans
When you say "refresh the data", are you referring to what you said above about refreshing the JPanel? Also, rather than adding another answer if you have additional questions, I'd recommend adding a comment to the answer to which you are referring. I've edited my answer to add another possible solution.
Feanor
+1  A: 

Is there an actionlistener or something that I can have it reload/refresh my data on that screen?

Assuming you have a model that supplies data to your view (panel), two approaches are common:

  1. Arrange for your model to extend Observable and your view to register as an Observer.

  2. Arrange for your model to manage an EventListenerList, in effect creating you own analog of ActionEvent.

In either approach, use the listener of the control that switches views tell the model to update its registered observers/listeners. The example in How to Use CardLayout uses a JComboBox and itemStateChanged(). There's additional discussion here.

trashgod
These also work very well, especially if you have a lot going on in the panel. I used the Observer approach in a Tetris-style game.
Feanor
@Feanor: Agreed; same here http://robotchase.sourceforge.net/
trashgod
great approach, the problem however I see is that the model doesn't contain the actual data displayed on that screen (the screen displays calculations based upon the model data). I'd think this could cause performance problems if I notified the observer on every change and redid the calculations after every update to the model.
cfans
@cfans: Only the model should know when the source data changes; I'd expect it to cache derived results for use by listeners.
trashgod
A: 

Is there an actionlistener or something that I can have it reload/refresh my data on that screen?

You can use an AncestorListener. It fires when a component is added to a Container. So when you swap cards the event is fired. You would need to add the listener to each panel you add to the CardLayout:

Another problem with the CardLayout is that the panel doesn't gain focus when it is swapped. I use this approach to set focus on the panel. Check out Card Layout Focus.

panel.addAncestorListener(...);
camickr