From faffc9393dce63a2029246fff9dc8cb1aa88df2c Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Mon, 31 Aug 2020 16:20:20 +0200 Subject: [PATCH] fixed sub-pixel text rendering in animated theme change; use weak hash map for static map to avoid memory leak for the case that something went wrong --- CHANGELOG.md | 2 ++ .../flatlaf/extras/FlatAnimatedLafChange.java | 27 ++++++++++++++----- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 043eb143..622fd9c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,8 @@ FlatLaf Change Log window is inactive. - Custom window decorations: Fixed title pane background color in IntelliJ themes if window is inactive. +- Fixed sub-pixel text rendering in animated theme change (see + [FlatLaf Extras](flatlaf-extras)). #### Other Changes diff --git a/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/FlatAnimatedLafChange.java b/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/FlatAnimatedLafChange.java index b0010dea..f30dd1e3 100644 --- a/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/FlatAnimatedLafChange.java +++ b/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/FlatAnimatedLafChange.java @@ -19,10 +19,10 @@ package com.formdev.flatlaf.extras; import java.awt.AlphaComposite; import java.awt.Graphics; import java.awt.Graphics2D; -import java.awt.Image; import java.awt.Window; -import java.util.HashMap; +import java.awt.image.VolatileImage; import java.util.Map; +import java.util.WeakHashMap; import javax.swing.JComponent; import javax.swing.JLayeredPane; import javax.swing.RootPaneContainer; @@ -56,7 +56,7 @@ public class FlatAnimatedLafChange public static int resolution = 40; private static Animator animator; - private static final Map map = new HashMap<>(); + private static final Map map = new WeakHashMap<>(); private static float alpha; /** @@ -79,10 +79,14 @@ public class FlatAnimatedLafChange if( !(window instanceof RootPaneContainer) || !window.isShowing() ) continue; - JLayeredPane layeredPane = ((RootPaneContainer)window).getLayeredPane(); + // create snapshot image + // (using volatile image to have correct sub-pixel text rendering on Java 9+) + VolatileImage snapshot = window.createVolatileImage( window.getWidth(), window.getHeight() ); + if( snapshot == null ) + continue; - // create snapshot image of layered pane - Image snapshot = window.createImage( window.getWidth(), window.getHeight() ); + // paint window to snapshot image + JLayeredPane layeredPane = ((RootPaneContainer)window).getLayeredPane(); layeredPane.paint( snapshot.getGraphics() ); // create snapshot layer, which is added to layered pane and paints @@ -90,9 +94,20 @@ public class FlatAnimatedLafChange JComponent snapshotLayer = new JComponent() { @Override public void paint( Graphics g ) { + if( snapshot.contentsLost() ) + return; + ((Graphics2D)g).setComposite( AlphaComposite.getInstance( AlphaComposite.SRC_OVER, alpha ) ); g.drawImage( snapshot, 0, 0, null ); } + + @Override + public void removeNotify() { + super.removeNotify(); + + // release system resources used by volatile image + snapshot.flush(); + } }; snapshotLayer.setSize( layeredPane.getSize() );