Java Swing revalidate vs repaint
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
revalidate() tells the layout manager to recalculate component sizes and positions. repaint() schedules the component for visual redrawing on screen. When you add, remove, or resize components, you typically need both: revalidate() to fix the layout, then repaint() to render the updated result. Calling only one of them is the most common source of "invisible component" or "stale display" bugs in Swing applications.
What revalidate() Does
revalidate() marks a component as needing layout recalculation. It walks up the containment hierarchy to find the nearest "validate root" (usually a JRootPane), then schedules a validate() call on the Event Dispatch Thread (EDT). During validation, the layout manager calls getPreferredSize(), getMinimumSize(), and getMaximumSize() on each child component and assigns new bounds via setBounds().
Internally, revalidate() calls RepaintManager.addInvalidComponent(this), which coalesces multiple layout requests into a single layout pass. This means calling revalidate() ten times in a row does not produce ten layout passes.
When to Call revalidate()
- After calling
add()orremove()on a container - After changing a component's preferred/minimum/maximum size
- After modifying a border that affects insets
- After swapping a layout manager on a container
- After changing properties that affect a component's size (e.g., text on a JLabel that uses its preferred size)
What repaint() Does
repaint() schedules a paint request. It does not paint immediately. Instead, it posts a request to the EDT's paint queue, which the RepaintManager coalesces into a single paintComponent() call. The actual painting sequence for a JComponent is:
paintComponent(Graphics g)- draws the component itselfpaintBorder(Graphics g)- draws the borderpaintChildren(Graphics g)- recursively paints child components
When to Call repaint()
- After changing a visual property (color, font, icon) that does not affect layout
- After updating custom painting state (animation frames, selection highlighting)
- After
revalidate()when components have been structurally modified - When a model change should be reflected visually (e.g., table data changed)
Why You Usually Need Both
When the component hierarchy changes, the layout must be recalculated (revalidate()) and then the new layout must be rendered (repaint()). Calling only revalidate() can leave stale pixels on screen because the repaint region may not cover the old component locations. Calling only repaint() without revalidate() will redraw components at their old positions and sizes.
Comparison Table
| Aspect | revalidate() | repaint() |
| Purpose | Recalculate layout (sizes, positions) | Redraw visual appearance (pixels) |
| Triggers | Component add/remove, size changes | Color, font, icon, or painting state changes |
| Defined in | JComponent (overrides Component.invalidate()) | Component |
| What it schedules | validate() on the nearest validate root | paintComponent(), paintBorder(), paintChildren() |
| Coalescing | Yes, via RepaintManager.addInvalidComponent() | Yes, via RepaintManager.addDirtyRegion() |
| Thread safety | Must be called on EDT (or it posts to EDT) | Can be called from any thread (posts to EDT internally) |
| Effect without the other | Layout updates but old pixels may remain | Redraws at old positions/sizes |
The RepaintManager Under the Hood
Both methods are managed by javax.swing.RepaintManager, which batches and optimizes UI updates. Understanding this helps explain why Swing remains responsive even when code calls revalidate() and repaint() frequently.
The RepaintManager also handles double buffering. When repaint() fires, Swing paints to an off-screen buffer first, then copies the buffer to the screen in a single operation. This prevents flickering, which was a major problem with AWT's immediate-mode painting.
Thread Safety Rules
Swing is single-threaded by design. All UI modifications must happen on the Event Dispatch Thread.
Note that repaint() is one of the few Swing methods that is safe to call from any thread, because it only posts a request to the EDT queue. However, revalidate() should still be called from the EDT.
Common Pitfalls
- Calling only
revalidate()after adding components. The new components get correct bounds but old pixels from the previous layout may remain visible, creating ghost artifacts. Always pair withrepaint(). - Calling only
repaint()after adding components. The paint cycle renders components at their old (or zero) bounds. The new component will be invisible or drawn at (0,0) with zero size. - Calling
revalidate()andrepaint()inside a tight loop. WhileRepaintManagercoalesces these calls, the overhead of posting hundreds of requests is wasteful. Make all structural changes first, then call both methods once. - Calling
repaint()insidepaintComponent(). This creates an infinite repaint loop that pegs the CPU at 100%. Use ajavax.swing.Timerfor animations instead. - Modifying the UI from a non-EDT thread. This causes race conditions that produce intermittent rendering glitches, exceptions, or deadlocks. Use
SwingUtilities.invokeLater()orSwingWorker. - Forgetting to call
super.paintComponent(g)in custom painting. Without this call, the background is not cleared, leading to visual smearing as old content bleeds through.
Summary
revalidate() handles layout: it tells the layout manager to recompute where everything goes. repaint() handles rendering: it schedules the component to be redrawn on screen. After any structural change to the component tree (adding, removing, or resizing children), call revalidate() followed by repaint(). For purely visual changes that do not affect layout (color, custom painting), repaint() alone is sufficient. Both methods are coalesced by RepaintManager to avoid redundant work, and both must be invoked on the Event Dispatch Thread (with repaint() being the exception that can safely be called from any thread). Getting this pair right eliminates the most common category of Swing rendering bugs.
Related reading
- Java switch statement Constant expression required, but it IS constant
- Java Synchronized Block for .class
- Java synchronized method
- Java synchronized method lock on object, or method?
- Java synchronized method lock on object, or method?
- Java system properties and environment variables
- Java System.currentTimeMillis equivalent in C
- Java text classification problem

OOD Fundamentals
Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.