Swing JPanel won't repaint
java, repaint, swing, user-interface
Solution
It depends on what you want to happen and what layout managers are in use, but the basic rules are:
Make sure `update` is called on the EDT. If it's not (`SwingUtilities.isEventDispatchThread()`returns false) you will need to use `SwingUtilities.invokeLater` to schedule the update on the EDT. For example:
SwingUtilities.invokeLater(new Runnable() {
public void run() {
update();
}});
Call `invalidate()`. Most things that change a component will do this for you. So you only need to call this if the following does not work on its own.
Call `validate()` on the highest affected component. This is probably the muddiest bit of Java's rendering cycle. The call to `invalidate` marks the component and all of its ancestors as needing layout. The call to `validate` performs the layout of the component and all of its descendants. One works "up" and the other works "down". You need to call `validate` on the highest component in the tree that will be affected by your change.
Also, calling validate on a top-level component (JWindow, JDialog, JFrame) will not necessarily resize that component. To make that happen, you'll need to call `pack()` or `setSize()`.
If your changes alter the size or position of containers, The resized containers will repaint, but they will not erase the space the used to occupy. Calling `repaint()` on the parent of the container will cause it to repaint the background, correcting the damage.
Problem
I have a simple object which extends `JPanel`, when the `update()` method is called on this object it it meant to add some labels to the panel and then repaint. However the labels do not show up after the update method is called, below is the code for update: ``` public void update(){ GridBagConstraints constraints = new GridBagConstraints(); if(cardsHidden){ for(int i = 0; i < 2; i++){ constraints.gridx = i; constraints.gridy = 0; JLabel card = new JLabel(PlayingCards.cardImages[PlayingCards.CARD_BACK_INDEX]); add(card, constraints); } } else{ Card[] holeCards = player.getHoleCards(); for(int i = 0; i < holeCards.length; i++){ constraints.gridx = i; constraints.gridy = 0; JLabel card = new JLabel(holeCards[i].getImageIcon()); add(card, constraints); } } validate(); repaint(); } ``` any ideas? Thanks EDIT solved: It turns out that the `HoleCardsPanel` wasn't adding to its parent frame properly. Once that was fixed the adding of new `JLabel`s works fine. I also: - added the call to the `update()` method to the event dispatch thread using `SwingUtillities.invokeLater` - had to call `validate()` from the uppermost component (in this case the `JFrame`) as Devon_C_Miller suggests in his answer.