Symptoms & Diagnosis
Developers transitioning to Java 21 have reported unexpected visual artifacts during GUI animations. These issues primarily affect applications built on Swing, AWT, or JavaFX frameworks.
The most common symptom is a rapid flashing or “tearing” effect. This occurs when the screen updates faster than the rendering pipeline can process the buffer, leading to incomplete frames being displayed.

Another diagnosis point is the hardware acceleration mismatch. Java 21 introduces updates to the 2D rendering pipeline, which may conflict with specific GPU drivers or legacy “Double Buffering” implementations.
To diagnose, check if the flickering persists when hardware acceleration is disabled. If the flickering stops, the issue lies within the Java2D pipeline interaction with your OS display server.
Troubleshooting Guide
Resolving flickering in Java 21 often requires adjusting system properties to stabilize the rendering engine. Start by testing common flags that control the Java2D pipeline.
| System Property | Recommended Value | Effect |
|---|---|---|
| sun.java2d.d3d | false | Disables Direct3D on Windows to prevent driver conflicts. |
| sun.java2d.opengl | true | Forces OpenGL rendering, which is often more stable in Java 21. |
| sun.java2d.doublebuffering | true | Ensures the back-buffer is fully drawn before being flipped. |
If you are running a JAR file via the command line, apply these fixes using the following syntax to bypass problematic hardware acceleration:
java -Dsun.java2d.d3d=false -Dsun.java2d.opengl=true -Dsun.java2d.noddraw=true -jar your-app.jar
For macOS users, ensure that the Metal pipeline is correctly configured. You can toggle it using -Dsun.java2d.metal=true or false depending on your specific hardware generation.
Updating Graphics Drivers
Because Java 21 leverages newer API calls, outdated drivers may fail to synchronize vertical refresh (V-Sync) signals. Always ensure your NVIDIA, AMD, or Intel drivers are updated to the latest stable release.
Prevention
To prevent flickering in future Java 21 projects, always use standard Swing components that support built-in double buffering. Avoid mixing heavyweight and lightweight components in the same container.
Implement all UI updates strictly on the Event Dispatch Thread (EDT). Using SwingUtilities.invokeLater() ensures that animation frames do not overlap or collide during the rendering cycle.
Finally, consider using the VolatileImage class for custom animations. This class provides a hardware-accelerated image surface that handles surface loss and restoration automatically, significantly reducing flickering in high-performance Java 21 applications.