diff --git a/CHANGELOG.md b/CHANGELOG.md index 622fd9c8..438996c6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ FlatLaf Change Log ## Unreleased -#### New features +#### New features and improvements - Added API to register packages or folders where FlatLaf searches for application specific properties files with custom UI defaults (see @@ -12,6 +12,8 @@ FlatLaf Change Log application. - Extras: `FlatSVGIcon` now allows specifying `ClassLoader` that is used to load SVG file. (issue #163) +- Smoother transition from old to new theme, independent of UI complexity, when + using animated theme change (see [FlatLaf Extras](flatlaf-extras)). #### Fixed bugs 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 f30dd1e3..f66cefe1 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 @@ -56,8 +56,10 @@ public class FlatAnimatedLafChange public static int resolution = 40; private static Animator animator; - private static final Map map = new WeakHashMap<>(); + private static final Map oldUIsnapshots = new WeakHashMap<>(); + private static final Map newUIsnapshots = new WeakHashMap<>(); private static float alpha; + private static boolean inShowSnapshot; /** * Create a snapshot of the old UI and shows it on top of the UI. @@ -73,6 +75,13 @@ public class FlatAnimatedLafChange alpha = 1; + // show snapshot of old UI + showSnapshot( true, oldUIsnapshots ); + } + + private static void showSnapshot( boolean useAlpha, Map map ) { + inShowSnapshot = true; + // create snapshots for all shown windows Window[] windows = Window.getWindows(); for( Window window : windows ) { @@ -94,10 +103,11 @@ public class FlatAnimatedLafChange JComponent snapshotLayer = new JComponent() { @Override public void paint( Graphics g ) { - if( snapshot.contentsLost() ) + if( inShowSnapshot || snapshot.contentsLost() ) return; - ((Graphics2D)g).setComposite( AlphaComposite.getInstance( AlphaComposite.SRC_OVER, alpha ) ); + if( useAlpha ) + ((Graphics2D)g).setComposite( AlphaComposite.getInstance( AlphaComposite.SRC_OVER, alpha ) ); g.drawImage( snapshot, 0, 0, null ); } @@ -109,12 +119,16 @@ public class FlatAnimatedLafChange snapshot.flush(); } }; + if( !useAlpha ) + snapshotLayer.setOpaque( true ); snapshotLayer.setSize( layeredPane.getSize() ); // add image layer to layered pane - layeredPane.add( snapshotLayer, JLayeredPane.DRAG_LAYER ); + layeredPane.add( snapshotLayer, Integer.valueOf( JLayeredPane.DRAG_LAYER + (useAlpha ? 2 : 1) ) ); map.put( layeredPane, snapshotLayer ); } + + inShowSnapshot = false; } /** @@ -126,9 +140,12 @@ public class FlatAnimatedLafChange if( !FlatSystemProperties.getBoolean( "flatlaf.animatedLafChange", true ) ) return; - if( map.isEmpty() ) + if( oldUIsnapshots.isEmpty() ) return; + // show snapshot of new UI + showSnapshot( false, newUIsnapshots ); + // create animator animator = new Animator( duration, fraction -> { if( fraction < 0.1 || fraction > 0.9 ) @@ -137,7 +154,7 @@ public class FlatAnimatedLafChange alpha = 1f - fraction; // repaint snapshots - for( Map.Entry e : map.entrySet() ) { + for( Map.Entry e : oldUIsnapshots.entrySet() ) { if( e.getKey().isShowing() ) e.getValue().repaint(); } @@ -151,6 +168,11 @@ public class FlatAnimatedLafChange } private static void hideSnapshot() { + hideSnapshot( oldUIsnapshots ); + hideSnapshot( newUIsnapshots ); + } + + private static void hideSnapshot( Map map ) { // remove snapshots for( Map.Entry e : map.entrySet() ) { e.getKey().remove( e.getValue() );