From 5e33182de3093fe898259f97f35b28c55171cbfb Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Sat, 12 Oct 2019 20:10:37 +0200 Subject: [PATCH] Windows: update fonts (and scaling) when user changes Windows text size --- CHANGELOG.md | 2 + .../java/com/formdev/flatlaf/FlatLaf.java | 56 +++++++++++++++++++ .../com/formdev/flatlaf/FlatTestFrame.java | 22 +++++--- .../com/formdev/flatlaf/demo/ControlBar.java | 14 +++-- 4 files changed, 83 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 92e807cb..ee3140f5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ FlatLaf Change Log - Added `Flat*Laf.install()` methods. - macOS: Use native screen menu bar if system property `apple.laf.useScreenMenuBar` is `true`. +- Windows: Update fonts (and scaling) when user changes Windows text size + (Settings > Ease of Access > Display > Make text bigger). ## 0.11 diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java index b6859842..3e99f945 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatLaf.java @@ -21,6 +21,7 @@ import java.awt.Color; import java.awt.Component; import java.awt.Container; import java.awt.Dimension; +import java.awt.EventQueue; import java.awt.Font; import java.awt.Insets; import java.awt.KeyboardFocusManager; @@ -28,6 +29,8 @@ import java.awt.Toolkit; import java.awt.Window; import java.awt.event.AWTEventListener; import java.awt.event.KeyEvent; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; @@ -43,6 +46,7 @@ import javax.swing.LookAndFeel; import javax.swing.SwingUtilities; import javax.swing.UIDefaults; import javax.swing.UIManager; +import javax.swing.UnsupportedLookAndFeelException; import javax.swing.UIDefaults.LazyValue; import javax.swing.plaf.ColorUIResource; import javax.swing.plaf.DimensionUIResource; @@ -71,6 +75,9 @@ public abstract class FlatLaf private BasicLookAndFeel base; + private String desktopPropertyName; + private PropertyChangeListener desktopPropertyListener; + private AWTEventListener mnemonicListener; private static boolean altKeyPressed; @@ -111,10 +118,30 @@ public abstract class FlatLaf altKeyChanged( e.getID() == KeyEvent.KEY_PRESSED ); }; Toolkit.getDefaultToolkit().addAWTEventListener( mnemonicListener, AWTEvent.KEY_EVENT_MASK ); + + // listen to desktop property changes to update UI if system font or scaling changes + if( SystemInfo.IS_WINDOWS ) { + // Windows 10 allows increasing font size independent of scaling: + // Settings > Ease of Access > Display > Make text bigger (100% - 225%) + desktopPropertyName = "win.messagebox.font"; + } + if( desktopPropertyName != null ) { + desktopPropertyListener = e -> { + reSetLookAndFeel(); + }; + Toolkit.getDefaultToolkit().addPropertyChangeListener( desktopPropertyName, desktopPropertyListener ); + } } @Override public void uninitialize() { + // remove desktop property listener + if( desktopPropertyListener != null ) { + Toolkit.getDefaultToolkit().removePropertyChangeListener( desktopPropertyName, desktopPropertyListener ); + desktopPropertyName = null; + desktopPropertyListener = null; + } + // remove mnemonic listener if( mnemonicListener != null ) { Toolkit.getDefaultToolkit().removeAWTEventListener( mnemonicListener ); @@ -478,6 +505,35 @@ public abstract class FlatLaf return strs; } + private static void reSetLookAndFeel() { + EventQueue.invokeLater( () -> { + try { + // re-set current LaF + LookAndFeel lookAndFeel = UIManager.getLookAndFeel(); + UIManager.setLookAndFeel( lookAndFeel ); + + // must fire property change events ourself because old and new LaF are the same + PropertyChangeEvent e = new PropertyChangeEvent( UIManager.class, "lookAndFeel", lookAndFeel, lookAndFeel ); + for( PropertyChangeListener l : UIManager.getPropertyChangeListeners() ) + l.propertyChange( e ); + + // update UI + updateUI(); + } catch( UnsupportedLookAndFeelException ex ) { + ex.printStackTrace(); + } + } ); + } + + /** + * Update UI of all application windows. + * Invoke after changing LaF. + */ + public static void updateUI() { + for( Window w : Window.getWindows() ) + SwingUtilities.updateComponentTreeUI( w ); + } + public static boolean isShowMnemonics() { return altKeyPressed || !UIManager.getBoolean( "Component.hideMnemonics" ); } diff --git a/flatlaf-core/src/test/java/com/formdev/flatlaf/FlatTestFrame.java b/flatlaf-core/src/test/java/com/formdev/flatlaf/FlatTestFrame.java index cfcafe79..698481d1 100644 --- a/flatlaf-core/src/test/java/com/formdev/flatlaf/FlatTestFrame.java +++ b/flatlaf-core/src/test/java/com/formdev/flatlaf/FlatTestFrame.java @@ -22,6 +22,8 @@ import java.awt.event.ComponentEvent; import java.awt.event.KeyEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; import java.util.prefs.Preferences; import javax.swing.*; import javax.swing.plaf.ColorUIResource; @@ -167,6 +169,18 @@ public class FlatTestFrame updateTitle(); } } ); + + UIManager.addPropertyChangeListener( e -> { + if( "lookAndFeel".equals( e.getPropertyName() ) ) { + EventQueue.invokeLater( () -> { + // update title because user scale factor may change + updateTitle(); + + // enable/disable scale factor combobox + updateScaleFactorComboBox(); + } ); + } + } ); } private void updateTitle() { @@ -233,14 +247,8 @@ public class FlatTestFrame // change look and feel UIManager.setLookAndFeel( lafClassName ); - // update title because user scale factor may change - updateTitle(); - - // enable/disable scale factor combobox - updateScaleFactorComboBox(); - // update all components - SwingUtilities.updateComponentTreeUI( this ); + FlatLaf.updateUI(); // increase size of frame if necessary if( pack ) diff --git a/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/ControlBar.java b/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/ControlBar.java index b4d09372..15486632 100644 --- a/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/ControlBar.java +++ b/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/ControlBar.java @@ -79,6 +79,15 @@ class ControlBar lafModel.setSelectedItem( lafModel.getElementAt( sel ) ); lookAndFeelComboBox.setModel( lafModel ); + + UIManager.addPropertyChangeListener( e -> { + if( "lookAndFeel".equals( e.getPropertyName() ) ) { + EventQueue.invokeLater( () -> { + // update info label because user scale factor may change + updateInfoLabel(); + } ); + } + } ); } void initialize( JFrame frame, JTabbedPane tabbedPane ) { @@ -173,11 +182,8 @@ class ControlBar // change look and feel UIManager.setLookAndFeel( newLaf.className ); - // update info label because user scale factor may change - updateInfoLabel(); - // update all components - SwingUtilities.updateComponentTreeUI( frame ); + FlatLaf.updateUI(); // increase size of frame if necessary int width = frame.getWidth();