mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2025-12-06 22:10:54 +03:00
animated Laf changing added to flatlaf-extras, used in Demo
This commit is contained in:
@@ -3,6 +3,7 @@ FlatLaf Change Log
|
|||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
|
- Animated theme change (see [FlatLaf Extras](flatlaf-extras)).
|
||||||
- Custom window decorations: Fixed maximized window bounds when programmatically
|
- Custom window decorations: Fixed maximized window bounds when programmatically
|
||||||
maximizing window. E.g. restoring window state at startup. (issue #129)
|
maximizing window. E.g. restoring window state at startup. (issue #129)
|
||||||
- InternalFrame: Title pane height was too small when iconify, maximize and close
|
- InternalFrame: Title pane height was too small when iconify, maximize and close
|
||||||
|
|||||||
@@ -92,6 +92,7 @@ public class Animator
|
|||||||
/**
|
/**
|
||||||
* Sets the resolution of the animation in milliseconds.
|
* Sets the resolution of the animation in milliseconds.
|
||||||
*
|
*
|
||||||
|
* @param resolution the resolution of the animation in milliseconds
|
||||||
* @throws IllegalStateException if animation is running
|
* @throws IllegalStateException if animation is running
|
||||||
* @throws IllegalArgumentException if resolution is <= zero
|
* @throws IllegalArgumentException if resolution is <= zero
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import javax.swing.UIManager.LookAndFeelInfo;
|
|||||||
import javax.swing.plaf.metal.MetalLookAndFeel;
|
import javax.swing.plaf.metal.MetalLookAndFeel;
|
||||||
import javax.swing.plaf.nimbus.NimbusLookAndFeel;
|
import javax.swing.plaf.nimbus.NimbusLookAndFeel;
|
||||||
import com.formdev.flatlaf.*;
|
import com.formdev.flatlaf.*;
|
||||||
|
import com.formdev.flatlaf.extras.FlatAnimatedLafChange;
|
||||||
import com.formdev.flatlaf.util.SystemInfo;
|
import com.formdev.flatlaf.util.SystemInfo;
|
||||||
import com.formdev.flatlaf.util.UIScale;
|
import com.formdev.flatlaf.util.UIScale;
|
||||||
import net.miginfocom.swing.*;
|
import net.miginfocom.swing.*;
|
||||||
@@ -193,6 +194,8 @@ class ControlBar
|
|||||||
|
|
||||||
EventQueue.invokeLater( () -> {
|
EventQueue.invokeLater( () -> {
|
||||||
try {
|
try {
|
||||||
|
FlatAnimatedLafChange.showSnapshot();
|
||||||
|
|
||||||
// change look and feel
|
// change look and feel
|
||||||
UIManager.setLookAndFeel( lafClassName );
|
UIManager.setLookAndFeel( lafClassName );
|
||||||
|
|
||||||
@@ -202,6 +205,7 @@ class ControlBar
|
|||||||
|
|
||||||
// update all components
|
// update all components
|
||||||
FlatLaf.updateUI();
|
FlatLaf.updateUI();
|
||||||
|
FlatAnimatedLafChange.hideSnapshotWithAnimation();
|
||||||
|
|
||||||
// increase size of frame if necessary
|
// increase size of frame if necessary
|
||||||
int width = frame.getWidth();
|
int width = frame.getWidth();
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import com.formdev.flatlaf.FlatClientProperties;
|
|||||||
import com.formdev.flatlaf.FlatLaf;
|
import com.formdev.flatlaf.FlatLaf;
|
||||||
import com.formdev.flatlaf.demo.extras.*;
|
import com.formdev.flatlaf.demo.extras.*;
|
||||||
import com.formdev.flatlaf.demo.intellijthemes.*;
|
import com.formdev.flatlaf.demo.intellijthemes.*;
|
||||||
|
import com.formdev.flatlaf.extras.FlatAnimatedLafChange;
|
||||||
import com.formdev.flatlaf.extras.FlatSVGIcon;
|
import com.formdev.flatlaf.extras.FlatSVGIcon;
|
||||||
import com.formdev.flatlaf.extras.SVGUtils;
|
import com.formdev.flatlaf.extras.SVGUtils;
|
||||||
import com.formdev.flatlaf.ui.JBRCustomDecorations;
|
import com.formdev.flatlaf.ui.JBRCustomDecorations;
|
||||||
@@ -105,14 +106,21 @@ class DemoFrame
|
|||||||
repaint();
|
repaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void animatedLafChangeChanged() {
|
||||||
|
System.setProperty( "flatlaf.animatedLafChange", String.valueOf( animatedLafChangeMenuItem.isSelected() ) );
|
||||||
|
}
|
||||||
|
|
||||||
private void fontFamilyChanged( ActionEvent e ) {
|
private void fontFamilyChanged( ActionEvent e ) {
|
||||||
String fontFamily = e.getActionCommand();
|
String fontFamily = e.getActionCommand();
|
||||||
|
|
||||||
|
FlatAnimatedLafChange.showSnapshot();
|
||||||
|
|
||||||
Font font = UIManager.getFont( "defaultFont" );
|
Font font = UIManager.getFont( "defaultFont" );
|
||||||
Font newFont = StyleContext.getDefaultStyleContext().getFont( fontFamily, font.getStyle(), font.getSize() );
|
Font newFont = StyleContext.getDefaultStyleContext().getFont( fontFamily, font.getStyle(), font.getSize() );
|
||||||
UIManager.put( "defaultFont", newFont );
|
UIManager.put( "defaultFont", newFont );
|
||||||
|
|
||||||
FlatLaf.updateUI();
|
FlatLaf.updateUI();
|
||||||
|
FlatAnimatedLafChange.hideSnapshotWithAnimation();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void fontSizeChanged( ActionEvent e ) {
|
private void fontSizeChanged( ActionEvent e ) {
|
||||||
@@ -248,6 +256,7 @@ class DemoFrame
|
|||||||
menuBarEmbeddedCheckBoxMenuItem = new JCheckBoxMenuItem();
|
menuBarEmbeddedCheckBoxMenuItem = new JCheckBoxMenuItem();
|
||||||
underlineMenuSelectionMenuItem = new JCheckBoxMenuItem();
|
underlineMenuSelectionMenuItem = new JCheckBoxMenuItem();
|
||||||
alwaysShowMnemonicsMenuItem = new JCheckBoxMenuItem();
|
alwaysShowMnemonicsMenuItem = new JCheckBoxMenuItem();
|
||||||
|
animatedLafChangeMenuItem = new JCheckBoxMenuItem();
|
||||||
JMenu helpMenu = new JMenu();
|
JMenu helpMenu = new JMenu();
|
||||||
JMenuItem aboutMenuItem = new JMenuItem();
|
JMenuItem aboutMenuItem = new JMenuItem();
|
||||||
JToolBar toolBar1 = new JToolBar();
|
JToolBar toolBar1 = new JToolBar();
|
||||||
@@ -501,6 +510,12 @@ class DemoFrame
|
|||||||
alwaysShowMnemonicsMenuItem.setText("Always show mnemonics");
|
alwaysShowMnemonicsMenuItem.setText("Always show mnemonics");
|
||||||
alwaysShowMnemonicsMenuItem.addActionListener(e -> alwaysShowMnemonics());
|
alwaysShowMnemonicsMenuItem.addActionListener(e -> alwaysShowMnemonics());
|
||||||
optionsMenu.add(alwaysShowMnemonicsMenuItem);
|
optionsMenu.add(alwaysShowMnemonicsMenuItem);
|
||||||
|
|
||||||
|
//---- animatedLafChangeMenuItem ----
|
||||||
|
animatedLafChangeMenuItem.setText("Animated Laf Change");
|
||||||
|
animatedLafChangeMenuItem.setSelected(true);
|
||||||
|
animatedLafChangeMenuItem.addActionListener(e -> animatedLafChangeChanged());
|
||||||
|
optionsMenu.add(animatedLafChangeMenuItem);
|
||||||
}
|
}
|
||||||
menuBar1.add(optionsMenu);
|
menuBar1.add(optionsMenu);
|
||||||
|
|
||||||
@@ -620,6 +635,7 @@ class DemoFrame
|
|||||||
private JCheckBoxMenuItem menuBarEmbeddedCheckBoxMenuItem;
|
private JCheckBoxMenuItem menuBarEmbeddedCheckBoxMenuItem;
|
||||||
private JCheckBoxMenuItem underlineMenuSelectionMenuItem;
|
private JCheckBoxMenuItem underlineMenuSelectionMenuItem;
|
||||||
private JCheckBoxMenuItem alwaysShowMnemonicsMenuItem;
|
private JCheckBoxMenuItem alwaysShowMnemonicsMenuItem;
|
||||||
|
private JCheckBoxMenuItem animatedLafChangeMenuItem;
|
||||||
private JTabbedPane tabbedPane;
|
private JTabbedPane tabbedPane;
|
||||||
private ControlBar controlBar;
|
private ControlBar controlBar;
|
||||||
// JFormDesigner - End of variables declaration //GEN-END:variables
|
// JFormDesigner - End of variables declaration //GEN-END:variables
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
JFDML JFormDesigner: "7.0.1.0.272" Java: "13.0.2" encoding: "UTF-8"
|
JFDML JFormDesigner: "7.0.2.0.298" Java: "14.0.2" encoding: "UTF-8"
|
||||||
|
|
||||||
new FormModel {
|
new FormModel {
|
||||||
contentType: "form/swing"
|
contentType: "form/swing"
|
||||||
@@ -356,6 +356,15 @@ new FormModel {
|
|||||||
}
|
}
|
||||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "alwaysShowMnemonics", false ) )
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "alwaysShowMnemonics", false ) )
|
||||||
} )
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JCheckBoxMenuItem" ) {
|
||||||
|
name: "animatedLafChangeMenuItem"
|
||||||
|
"text": "Animated Laf Change"
|
||||||
|
"selected": true
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "animatedLafChangeChanged", false ) )
|
||||||
|
} )
|
||||||
} )
|
} )
|
||||||
add( new FormContainer( "javax.swing.JMenu", new FormLayoutManager( class javax.swing.JMenu ) ) {
|
add( new FormContainer( "javax.swing.JMenu", new FormLayoutManager( class javax.swing.JMenu ) ) {
|
||||||
name: "helpMenu"
|
name: "helpMenu"
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ import com.formdev.flatlaf.FlatLightLaf;
|
|||||||
import com.formdev.flatlaf.FlatPropertiesLaf;
|
import com.formdev.flatlaf.FlatPropertiesLaf;
|
||||||
import com.formdev.flatlaf.IntelliJTheme;
|
import com.formdev.flatlaf.IntelliJTheme;
|
||||||
import com.formdev.flatlaf.demo.DemoPrefs;
|
import com.formdev.flatlaf.demo.DemoPrefs;
|
||||||
|
import com.formdev.flatlaf.extras.FlatAnimatedLafChange;
|
||||||
import com.formdev.flatlaf.extras.FlatSVGIcon;
|
import com.formdev.flatlaf.extras.FlatSVGIcon;
|
||||||
import com.formdev.flatlaf.util.StringUtils;
|
import com.formdev.flatlaf.util.StringUtils;
|
||||||
import net.miginfocom.swing.*;
|
import net.miginfocom.swing.*;
|
||||||
@@ -219,6 +220,8 @@ public class IJThemesPanel
|
|||||||
if( themeInfo.lafClassName.equals( UIManager.getLookAndFeel().getClass().getName() ) )
|
if( themeInfo.lafClassName.equals( UIManager.getLookAndFeel().getClass().getName() ) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
FlatAnimatedLafChange.showSnapshot();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
UIManager.setLookAndFeel( themeInfo.lafClassName );
|
UIManager.setLookAndFeel( themeInfo.lafClassName );
|
||||||
} catch( Exception ex ) {
|
} catch( Exception ex ) {
|
||||||
@@ -226,6 +229,8 @@ public class IJThemesPanel
|
|||||||
showInformationDialog( "Failed to create '" + themeInfo.lafClassName + "'.", ex );
|
showInformationDialog( "Failed to create '" + themeInfo.lafClassName + "'.", ex );
|
||||||
}
|
}
|
||||||
} else if( themeInfo.themeFile != null ) {
|
} else if( themeInfo.themeFile != null ) {
|
||||||
|
FlatAnimatedLafChange.showSnapshot();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if( themeInfo.themeFile.getName().endsWith( ".properties" ) ) {
|
if( themeInfo.themeFile.getName().endsWith( ".properties" ) ) {
|
||||||
FlatLaf.install( new FlatPropertiesLaf( themeInfo.name, themeInfo.themeFile ) );
|
FlatLaf.install( new FlatPropertiesLaf( themeInfo.name, themeInfo.themeFile ) );
|
||||||
@@ -238,12 +243,15 @@ public class IJThemesPanel
|
|||||||
showInformationDialog( "Failed to load '" + themeInfo.themeFile + "'.", ex );
|
showInformationDialog( "Failed to load '" + themeInfo.themeFile + "'.", ex );
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
FlatAnimatedLafChange.showSnapshot();
|
||||||
|
|
||||||
IntelliJTheme.install( getClass().getResourceAsStream( THEMES_PACKAGE + themeInfo.resourceName ) );
|
IntelliJTheme.install( getClass().getResourceAsStream( THEMES_PACKAGE + themeInfo.resourceName ) );
|
||||||
DemoPrefs.getState().put( DemoPrefs.KEY_LAF_THEME, DemoPrefs.RESOURCE_PREFIX + themeInfo.resourceName );
|
DemoPrefs.getState().put( DemoPrefs.KEY_LAF_THEME, DemoPrefs.RESOURCE_PREFIX + themeInfo.resourceName );
|
||||||
}
|
}
|
||||||
|
|
||||||
// update all components
|
// update all components
|
||||||
FlatLaf.updateUI();
|
FlatLaf.updateUI();
|
||||||
|
FlatAnimatedLafChange.hideSnapshotWithAnimation();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void saveTheme() {
|
private void saveTheme() {
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ FlatLaf Extras
|
|||||||
|
|
||||||
This sub-project provides some additional components and classes:
|
This sub-project provides some additional components and classes:
|
||||||
|
|
||||||
|
- [FlatAnimatedLafChange](src/main/java/com/formdev/flatlaf/extras/FlatAnimatedLafChange.java):
|
||||||
|
Animated Laf changing.
|
||||||
- [FlatInspector](src/main/java/com/formdev/flatlaf/extras/FlatInspector.java):
|
- [FlatInspector](src/main/java/com/formdev/flatlaf/extras/FlatInspector.java):
|
||||||
A simple UI inspector that shows information about UI component at mouse
|
A simple UI inspector that shows information about UI component at mouse
|
||||||
location in a tooltip.
|
location in a tooltip.
|
||||||
|
|||||||
@@ -0,0 +1,163 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 FormDev Software GmbH
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
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.util.Map;
|
||||||
|
import javax.swing.JComponent;
|
||||||
|
import javax.swing.JLayeredPane;
|
||||||
|
import javax.swing.RootPaneContainer;
|
||||||
|
import com.formdev.flatlaf.FlatSystemProperties;
|
||||||
|
import com.formdev.flatlaf.util.Animator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Animated look and feel changing.
|
||||||
|
* <p>
|
||||||
|
* Invoke {@link #showSnapshot()} before setting look and feel and
|
||||||
|
* {@link #hideSnapshotWithAnimation()} after updating UI. E.g.
|
||||||
|
* <pre>
|
||||||
|
* FlatAnimatedLafChange.showSnapshot();
|
||||||
|
* UIManager.setLookAndFeel( lafClassName );
|
||||||
|
* FlatLaf.updateUI();
|
||||||
|
* FlatAnimatedLafChange.hideSnapshotWithAnimation();
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @author Karl Tauber
|
||||||
|
*/
|
||||||
|
public class FlatAnimatedLafChange
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* The duration of the animation in milliseconds. Default is 160 ms.
|
||||||
|
*/
|
||||||
|
public static int duration = 160;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The resolution of the animation in milliseconds. Default is 40 ms.
|
||||||
|
*/
|
||||||
|
public static int resolution = 40;
|
||||||
|
|
||||||
|
private static Animator animator;
|
||||||
|
private static final Map<JLayeredPane, JComponent> map = new HashMap<>();
|
||||||
|
private static float alpha;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a snapshot of the old UI and shows it on top of the UI.
|
||||||
|
* Invoke before setting new look and feel.
|
||||||
|
*/
|
||||||
|
public static void showSnapshot() {
|
||||||
|
if( !FlatSystemProperties.getBoolean( "flatlaf.animatedLafChange", true ) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// stop already running animation
|
||||||
|
if( animator != null )
|
||||||
|
animator.stop();
|
||||||
|
|
||||||
|
alpha = 1;
|
||||||
|
|
||||||
|
// create snapshots for all shown windows
|
||||||
|
Window[] windows = Window.getWindows();
|
||||||
|
for( Window window : windows ) {
|
||||||
|
if( !(window instanceof RootPaneContainer) || !window.isShowing() )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
JLayeredPane layeredPane = ((RootPaneContainer)window).getLayeredPane();
|
||||||
|
|
||||||
|
// create snapshot image of layered pane
|
||||||
|
Image snapshot = window.createImage( window.getWidth(), window.getHeight() );
|
||||||
|
layeredPane.paint( snapshot.getGraphics() );
|
||||||
|
|
||||||
|
// create snapshot layer, which is added to layered pane and paints
|
||||||
|
// snapshot with animated alpha
|
||||||
|
JComponent snapshotLayer = new JComponent() {
|
||||||
|
@Override
|
||||||
|
public void paint( Graphics g ) {
|
||||||
|
((Graphics2D)g).setComposite( AlphaComposite.getInstance( AlphaComposite.SRC_OVER, alpha ) );
|
||||||
|
g.drawImage( snapshot, 0, 0, null );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
snapshotLayer.setSize( layeredPane.getSize() );
|
||||||
|
|
||||||
|
// add image layer to layered pane
|
||||||
|
layeredPane.add( snapshotLayer, JLayeredPane.DRAG_LAYER );
|
||||||
|
map.put( layeredPane, snapshotLayer );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts an animation that shows the snapshot (created by {@link #showSnapshot()}
|
||||||
|
* with an decreasing alpha. At the end, the snapshot is removed and the new UI is shown.
|
||||||
|
* Invoke after updating UI.
|
||||||
|
*/
|
||||||
|
public static void hideSnapshotWithAnimation() {
|
||||||
|
if( !FlatSystemProperties.getBoolean( "flatlaf.animatedLafChange", true ) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if( map.isEmpty() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// create animator
|
||||||
|
animator = new Animator( duration, new Animator.TimingTarget() {
|
||||||
|
@Override
|
||||||
|
public void timingEvent( float fraction ) {
|
||||||
|
if( fraction < 0.1 || fraction > 0.9 )
|
||||||
|
return; // ignore initial and last events
|
||||||
|
|
||||||
|
alpha = 1f - fraction;
|
||||||
|
|
||||||
|
// repaint snapshots
|
||||||
|
for( Map.Entry<JLayeredPane, JComponent> e : map.entrySet() ) {
|
||||||
|
if( e.getKey().isShowing() )
|
||||||
|
e.getValue().repaint();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void end() {
|
||||||
|
hideSnapshot();
|
||||||
|
animator = null;
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
|
||||||
|
animator.setResolution( resolution );
|
||||||
|
animator.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void hideSnapshot() {
|
||||||
|
// remove snapshots
|
||||||
|
for( Map.Entry<JLayeredPane, JComponent> e : map.entrySet() ) {
|
||||||
|
e.getKey().remove( e.getValue() );
|
||||||
|
e.getKey().repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
map.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stops a running animation (if any) and hides the snapshot.
|
||||||
|
*/
|
||||||
|
public static void stop() {
|
||||||
|
if( animator != null )
|
||||||
|
animator.stop();
|
||||||
|
else
|
||||||
|
hideSnapshot();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -73,6 +73,9 @@ public class FlatTestFrame
|
|||||||
System.setProperty( FlatSystemProperties.UI_SCALE, scaleFactor );
|
System.setProperty( FlatSystemProperties.UI_SCALE, scaleFactor );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// disable animated Laf change
|
||||||
|
System.setProperty( "flatlaf.animatedLafChange", "false" );
|
||||||
|
|
||||||
// set look and feel
|
// set look and feel
|
||||||
DemoPrefs.initLaf( args );
|
DemoPrefs.initLaf( args );
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user