Explain Codes LogoExplain Codes Logo

Java Swing revalidate() vs repaint()

java
layout-management
swing-components
repaint-method
Alex KataevbyAlex Kataev·Feb 27, 2025
TLDR

When modifying the Swing component hierarchy, use revalidate() for changes that impact layout, such as adding or removing components. To simply refresh the display without effecting layout - when changing a component's appearance - use repaint().

// For layout changes: myPanel.add(newComponent); myPanel.revalidate(); // Hey layout manager, mind the gap! myPanel.repaint(); // Aaand, drum roll please! Refresh! // For appearance updates only: myComponent.setText("New text"); myComponent.repaint(); // Presto chango! Just a new look.

Just remember: Layout changes? revalidate() then repaint(). Only a visual update? repaint() to the rescue.

Getting to grips with layout & painting

Working with revalidate

Use revalidate() when your component hierarchy is modified, such as when components are added, removed, or altered. revalidate() enlists the layout manager to reorganize the container's subcomponents. It’s your go-to when:

  • You've cleaned house with removeAll() and added fresh components to a JPanel.
  • Component changes could affect their dimensions or shape within the layout.

Understanding repaint

In contrast, repaint() is called upon to refresh the visuals when a component changes appearance but not position or size. It's the makeup artist for your Swing components, vital when:

  • A component's state changes such that it would be drawn differently.
  • Cleared components' visual remnants need cleaning up.

Repainting: The children aren't alright

While revalidate() also triggers a repaint for 'dirty regions' - the UI's own little messes needing refresh - you may need to manually call repaint() for child components in case their bounds have changed post-revalidate.

The swap team

Instead of modifying components on a JPanel, consider swapping the entire panel. It's like replacing the engine, not just the spark plugs - cleaner, more efficient, and distinctly more satisfying.

// Swapping panels like a boss: parentPanel.remove(oldPanel); parentPanel.add(newPanel); parentPanel.revalidate(); // Layout, do your thing parentPanel.repaint(); // That's showbiz, baby

Tried-and-true tips and curve-balls

Debugging: Solving puzzles like a pro

Complex UIs can go astray - knowing the process empowers you to identify and deal with issues.

  • Layout gone haywire after modification? Make sure you're calling revalidate().
  • Seeing ghost images? Your fresh repaint() call might have missed cleaning up some remnants.

Heavyweight components: Treat with care

Mixing lightweight (Swing) with heavyweight (AWT) components can result in interference with repainting. This is due to z-order issues. Let's juggle with care, shall we?

Thread safety: Better safe than sorry

Most Swing component modifications need to be made on the Event Dispatch Thread (EDT). 'Cause who likes concurrency issues in their UI, right? Use SwingUtilities.invokeLater() to ensure UI updates are thread-safe.

SwingUtilities.invokeLater(new Runnable() { public void run() { // Modifying UI, all OK, nothing to see here... myPanel.add(newComponent); myPanel.revalidate(); // Please hold while we update the layout myPanel.repaint(); // Ta-da, all new! } });