From 2a494b1d6077748dc2f869ade263955fb6f5c6a4 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Thu, 13 Jun 2024 11:15:55 +0200 Subject: [PATCH] Testing: easier testing of various system scale factors using `Alt+Shift+F1`...`F12` --- .../com/formdev/flatlaf/demo/ControlBar.java | 5 +- .../com/formdev/flatlaf/demo/DemoPrefs.java | 68 +++++++++++++++ .../com/formdev/flatlaf/demo/FlatLafDemo.java | 5 +- .../testing/FlatNativeWindowBorderTest.java | 6 +- .../testing/FlatSingleComponentTest.java | 86 +++++++++---------- .../flatlaf/testing/FlatTestFrame.java | 48 ++++------- 6 files changed, 138 insertions(+), 80 deletions(-) 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 13e6daeb..338cee55 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 @@ -140,8 +140,8 @@ class ControlBar registerSwitchToLookAndFeel( KeyEvent.VK_F9, "com.apple.laf.AquaLookAndFeel" ); else if( SystemInfo.isLinux ) registerSwitchToLookAndFeel( KeyEvent.VK_F9, "com.sun.java.swing.plaf.gtk.GTKLookAndFeel" ); - registerSwitchToLookAndFeel( KeyEvent.VK_F12, MetalLookAndFeel.class.getName() ); registerSwitchToLookAndFeel( KeyEvent.VK_F11, NimbusLookAndFeel.class.getName() ); + registerSwitchToLookAndFeel( KeyEvent.VK_F12, MetalLookAndFeel.class.getName() ); // register Alt+UP and Alt+DOWN to switch to previous/next theme ((JComponent)frame.getContentPane()).registerKeyboardAction( @@ -153,6 +153,9 @@ class ControlBar KeyStroke.getKeyStroke( KeyEvent.VK_DOWN, KeyEvent.ALT_DOWN_MASK ), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT ); + // register Alt+Shift+F1, F2, ... keys to change system scale factor + DemoPrefs.registerSystemScaleFactors( frame ); + // register ESC key to close frame ((JComponent)frame.getContentPane()).registerKeyboardAction( e -> { diff --git a/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/DemoPrefs.java b/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/DemoPrefs.java index 52626d16..4af1d1ec 100644 --- a/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/DemoPrefs.java +++ b/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/DemoPrefs.java @@ -19,6 +19,10 @@ package com.formdev.flatlaf.demo; import java.io.File; import java.io.FileInputStream; import java.util.prefs.Preferences; +import javax.swing.JComponent; +import javax.swing.JFrame; +import javax.swing.JOptionPane; +import javax.swing.KeyStroke; import javax.swing.UIManager; import com.formdev.flatlaf.FlatLaf; import com.formdev.flatlaf.FlatLightLaf; @@ -27,6 +31,7 @@ import com.formdev.flatlaf.IntelliJTheme; import com.formdev.flatlaf.demo.intellijthemes.IJThemesPanel; import com.formdev.flatlaf.util.LoggingFacade; import com.formdev.flatlaf.util.StringUtils; +import com.formdev.flatlaf.util.SystemInfo; /** * @author Karl Tauber @@ -35,6 +40,7 @@ public class DemoPrefs { public static final String KEY_LAF = "laf"; public static final String KEY_LAF_THEME = "lafTheme"; + public static final String KEY_SYSTEM_SCALE_FACTOR = "systemScaleFactor"; public static final String RESOURCE_PREFIX = "res:"; public static final String FILE_PREFIX = "file:"; @@ -96,4 +102,66 @@ public class DemoPrefs state.put( KEY_LAF, UIManager.getLookAndFeel().getClass().getName() ); } ); } + + public static void initSystemScale() { + if( System.getProperty( "sun.java2d.uiScale" ) == null ) { + String scaleFactor = getState().get( KEY_SYSTEM_SCALE_FACTOR, null ); + if( scaleFactor != null ) + System.setProperty( "sun.java2d.uiScale", scaleFactor ); + } + } + + /** + * register Alt+Shift+F1, F2, ... F12 keys to change system scale factor + */ + public static void registerSystemScaleFactors( JFrame frame ) { + registerSystemScaleFactor( frame, "alt shift F1", null ); + registerSystemScaleFactor( frame, "alt shift F2", "1" ); + + if( SystemInfo.isWindows ) { + registerSystemScaleFactor( frame, "alt shift F3", "1.25" ); + registerSystemScaleFactor( frame, "alt shift F4", "1.5" ); + registerSystemScaleFactor( frame, "alt shift F5", "1.75" ); + registerSystemScaleFactor( frame, "alt shift F6", "2" ); + registerSystemScaleFactor( frame, "alt shift F7", "2.25" ); + registerSystemScaleFactor( frame, "alt shift F8", "2.5" ); + registerSystemScaleFactor( frame, "alt shift F9", "2.75" ); + registerSystemScaleFactor( frame, "alt shift F10", "3" ); + registerSystemScaleFactor( frame, "alt shift F11", "3.5" ); + registerSystemScaleFactor( frame, "alt shift F12", "4" ); + } else { + // Java on macOS and Linux supports only integer scale factors + registerSystemScaleFactor( frame, "alt shift F3", "2" ); + registerSystemScaleFactor( frame, "alt shift F4", "3" ); + registerSystemScaleFactor( frame, "alt shift F5", "4" ); + + } + } + + private static void registerSystemScaleFactor( JFrame frame, String keyStrokeStr, String scaleFactor ) { + KeyStroke keyStroke = KeyStroke.getKeyStroke( keyStrokeStr ); + if( keyStroke == null ) + throw new IllegalArgumentException( "Invalid key stroke '" + keyStrokeStr + "'" ); + + ((JComponent)frame.getContentPane()).registerKeyboardAction( + e -> applySystemScaleFactor( frame, scaleFactor ), + keyStroke, + JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT ); + } + + private static void applySystemScaleFactor( JFrame frame, String scaleFactor ) { + if( JOptionPane.showConfirmDialog( frame, + "Change system scale factor to " + + (scaleFactor != null ? scaleFactor : "default") + + " and exit?", + frame.getTitle(), JOptionPane.YES_NO_OPTION ) != JOptionPane.YES_OPTION ) + return; + + if( scaleFactor != null ) + DemoPrefs.getState().put( KEY_SYSTEM_SCALE_FACTOR, scaleFactor ); + else + DemoPrefs.getState().remove( KEY_SYSTEM_SCALE_FACTOR ); + + System.exit( 0 ); + } } diff --git a/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/FlatLafDemo.java b/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/FlatLafDemo.java index 4a55f459..dd8b6666 100644 --- a/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/FlatLafDemo.java +++ b/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/FlatLafDemo.java @@ -70,9 +70,10 @@ public class FlatLafDemo if( FlatLafDemo.screenshotsMode && !SystemInfo.isJava_9_orLater && System.getProperty( "flatlaf.uiScale" ) == null ) System.setProperty( "flatlaf.uiScale", "2x" ); - SwingUtilities.invokeLater( () -> { - DemoPrefs.init( PREFS_ROOT_PATH ); + DemoPrefs.init( PREFS_ROOT_PATH ); + DemoPrefs.initSystemScale(); + SwingUtilities.invokeLater( () -> { // install fonts for lazy loading FlatInterFont.installLazy(); FlatJetBrainsMonoFont.installLazy(); diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatNativeWindowBorderTest.java b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatNativeWindowBorderTest.java index e59784fd..b6d610bd 100644 --- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatNativeWindowBorderTest.java +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatNativeWindowBorderTest.java @@ -36,6 +36,8 @@ import com.formdev.flatlaf.FlatLaf; import com.formdev.flatlaf.FlatLightLaf; import com.formdev.flatlaf.extras.FlatInspector; import com.formdev.flatlaf.extras.components.FlatTriStateCheckBox; +import com.formdev.flatlaf.themes.FlatMacDarkLaf; +import com.formdev.flatlaf.themes.FlatMacLightLaf; import com.formdev.flatlaf.ui.FlatLineBorder; import com.formdev.flatlaf.util.SystemInfo; import net.miginfocom.swing.*; @@ -161,6 +163,8 @@ public class FlatNativeWindowBorderTest registerSwitchToLookAndFeel( "F2", FlatDarkLaf.class.getName() ); registerSwitchToLookAndFeel( "F3", FlatIntelliJLaf.class.getName() ); registerSwitchToLookAndFeel( "F4", FlatDarculaLaf.class.getName() ); + registerSwitchToLookAndFeel( "F5", FlatMacLightLaf.class.getName() ); + registerSwitchToLookAndFeel( "F6", FlatMacDarkLaf.class.getName() ); registerSwitchToLookAndFeel( "F8", FlatTestLaf.class.getName() ); @@ -170,8 +174,8 @@ public class FlatNativeWindowBorderTest registerSwitchToLookAndFeel( "F9", "com.apple.laf.AquaLookAndFeel" ); else if( SystemInfo.isLinux ) registerSwitchToLookAndFeel( "F9", "com.sun.java.swing.plaf.gtk.GTKLookAndFeel" ); - registerSwitchToLookAndFeel( "F12", MetalLookAndFeel.class.getName() ); registerSwitchToLookAndFeel( "F11", NimbusLookAndFeel.class.getName() ); + registerSwitchToLookAndFeel( "F12", MetalLookAndFeel.class.getName() ); } private void updateInfo() { diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatSingleComponentTest.java b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatSingleComponentTest.java index 050a15be..fefaca0f 100644 --- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatSingleComponentTest.java +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatSingleComponentTest.java @@ -22,13 +22,13 @@ import java.awt.Dimension; import java.awt.EventQueue; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; -import java.awt.event.KeyEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JFrame; import javax.swing.JLabel; +import javax.swing.JScrollPane; import javax.swing.KeyStroke; import javax.swing.UIManager; import javax.swing.plaf.metal.MetalLookAndFeel; @@ -42,6 +42,8 @@ import com.formdev.flatlaf.FlatSystemProperties; import com.formdev.flatlaf.demo.DemoPrefs; import com.formdev.flatlaf.extras.FlatInspector; import com.formdev.flatlaf.extras.FlatUIDefaultsInspector; +import com.formdev.flatlaf.themes.FlatMacDarkLaf; +import com.formdev.flatlaf.themes.FlatMacLightLaf; import com.formdev.flatlaf.util.SystemInfo; import com.formdev.flatlaf.util.UIScale; import net.miginfocom.swing.MigLayout; @@ -63,8 +65,9 @@ public class FlatSingleComponentTest public static void main( String[] args ) { DemoPrefs.init( PREFS_ROOT_PATH ); + DemoPrefs.initSystemScale(); - // set scale factor + // set user scale factor if( System.getProperty( FlatSystemProperties.UI_SCALE ) == null ) { String scaleFactor = DemoPrefs.getState().get( KEY_SCALE_FACTOR, null ); if( scaleFactor != null ) @@ -95,7 +98,8 @@ public class FlatSingleComponentTest JComponent c = createSingleComponent(); Container contentPane = getContentPane(); - contentPane.setLayout( new MigLayout( null, null, "[][grow]") ); + contentPane.setLayout( new MigLayout( null, null, + c instanceof JScrollPane ? "[grow,fill][]" : "[][grow]" ) ); contentPane.add( c ); infoLabel = new JLabel(); @@ -107,6 +111,8 @@ public class FlatSingleComponentTest registerSwitchToLookAndFeel( "F2", FlatDarkLaf.class.getName() ); registerSwitchToLookAndFeel( "F3", FlatIntelliJLaf.class.getName() ); registerSwitchToLookAndFeel( "F4", FlatDarculaLaf.class.getName() ); + registerSwitchToLookAndFeel( "F5", FlatMacLightLaf.class.getName() ); + registerSwitchToLookAndFeel( "F6", FlatMacDarkLaf.class.getName() ); registerSwitchToLookAndFeel( "F8", FlatTestLaf.class.getName() ); @@ -116,42 +122,37 @@ public class FlatSingleComponentTest registerSwitchToLookAndFeel( "F9", "com.apple.laf.AquaLookAndFeel" ); else if( SystemInfo.isLinux ) registerSwitchToLookAndFeel( "F9", "com.sun.java.swing.plaf.gtk.GTKLookAndFeel" ); - registerSwitchToLookAndFeel( "F12", MetalLookAndFeel.class.getName() ); registerSwitchToLookAndFeel( "F11", NimbusLookAndFeel.class.getName() ); + registerSwitchToLookAndFeel( "F12", MetalLookAndFeel.class.getName() ); - // register Alt+F1, F2, ... keys to change scale factor - registerScaleFactor( "alt F1", "1" ); - registerScaleFactor( "alt F2", "1.25" ); - registerScaleFactor( "alt F3", "1.5" ); - registerScaleFactor( "alt F4", "1.75" ); - registerScaleFactor( "alt F5", "2" ); - registerScaleFactor( "alt F6", "2.5" ); - registerScaleFactor( "alt F7", "3" ); - registerScaleFactor( "alt F8", "3.5" ); - registerScaleFactor( "alt F9", "4" ); - registerScaleFactor( "alt F10", "5" ); - registerScaleFactor( "alt F11", "6" ); - registerScaleFactor( "alt F12", null ); + // register Alt+F1, F2, ... keys to change user scale factor + registerScaleFactor( "alt F1", null ); + registerScaleFactor( "alt F2", "1" ); + registerScaleFactor( "alt F3", "1.25" ); + registerScaleFactor( "alt F4", "1.5" ); + registerScaleFactor( "alt F5", "1.75" ); + registerScaleFactor( "alt F6", "2" ); + registerScaleFactor( "alt F7", "2.5" ); + registerScaleFactor( "alt F8", "3" ); + registerScaleFactor( "alt F9", "3.5" ); + registerScaleFactor( "alt F10", "4" ); + registerScaleFactor( "alt F11", "5" ); + registerScaleFactor( "alt F12", "6" ); + + // register Alt+Shift+F1, F2, ... keys to change system scale factor + DemoPrefs.registerSystemScaleFactors( this ); // register Alt+R key to toggle component orientation - ((JComponent)getContentPane()).registerKeyboardAction( - e -> { - applyComponentOrientation( getComponentOrientation().isLeftToRight() - ? ComponentOrientation.RIGHT_TO_LEFT - : ComponentOrientation.LEFT_TO_RIGHT ); - revalidate(); - repaint(); - }, - KeyStroke.getKeyStroke( "alt R" ), - JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT ); + registerKey( "alt R", () -> { + applyComponentOrientation( getComponentOrientation().isLeftToRight() + ? ComponentOrientation.RIGHT_TO_LEFT + : ComponentOrientation.LEFT_TO_RIGHT ); + revalidate(); + repaint(); + } ); // register ESC key to close frame - ((JComponent)getContentPane()).registerKeyboardAction( - e -> { - dispose(); - }, - KeyStroke.getKeyStroke( KeyEvent.VK_ESCAPE, 0, false ), - JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT ); + registerKey( "ESCAPE", () -> dispose() ); // update info addWindowListener( new WindowAdapter() { @@ -199,19 +200,23 @@ public class FlatSingleComponentTest + ")" ); } - private void registerSwitchToLookAndFeel( String keyStrokeStr, String lafClassName ) { + private void registerKey( String keyStrokeStr, Runnable runnable ) { KeyStroke keyStroke = KeyStroke.getKeyStroke( keyStrokeStr ); if( keyStroke == null ) throw new IllegalArgumentException( "Invalid key stroke '" + keyStrokeStr + "'" ); ((JComponent)getContentPane()).registerKeyboardAction( e -> { - applyLookAndFeel( lafClassName ); + runnable.run(); }, keyStroke, JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT ); } + private void registerSwitchToLookAndFeel( String keyStrokeStr, String lafClassName ) { + registerKey( keyStrokeStr, () -> applyLookAndFeel( lafClassName ) ); + } + private void applyLookAndFeel( String lafClassName ) { try { UIManager.setLookAndFeel( lafClassName ); @@ -222,16 +227,7 @@ public class FlatSingleComponentTest } private void registerScaleFactor( String keyStrokeStr, String scaleFactor ) { - KeyStroke keyStroke = KeyStroke.getKeyStroke( keyStrokeStr ); - if( keyStroke == null ) - throw new IllegalArgumentException( "Invalid key stroke '" + keyStrokeStr + "'" ); - - ((JComponent)getContentPane()).registerKeyboardAction( - e -> { - applyScaleFactor( scaleFactor ); - }, - keyStroke, - JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT ); + registerKey( keyStrokeStr, () -> applyScaleFactor( scaleFactor ) ); } private void applyScaleFactor( String scaleFactor ) { diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatTestFrame.java b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatTestFrame.java index e516f6d0..e7f1bc5c 100644 --- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatTestFrame.java +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatTestFrame.java @@ -19,7 +19,6 @@ package com.formdev.flatlaf.testing; import java.awt.*; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; -import java.awt.event.KeyEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.FileInputStream; @@ -81,6 +80,7 @@ public class FlatTestFrame // System.setProperty( "awt.useSystemAAFontSettings", "off" ); DemoPrefs.init( PREFS_ROOT_PATH ); + DemoPrefs.initSystemScale(); // set scale factor if( System.getProperty( FlatSystemProperties.UI_SCALE ) == null ) { @@ -169,41 +169,23 @@ public class FlatTestFrame registerSwitchToLookAndFeel( "F9", "com.apple.laf.AquaLookAndFeel" ); else if( SystemInfo.isLinux ) registerSwitchToLookAndFeel( "F9", "com.sun.java.swing.plaf.gtk.GTKLookAndFeel" ); - registerSwitchToLookAndFeel( "F12", MetalLookAndFeel.class.getName() ); registerSwitchToLookAndFeel( "F11", NimbusLookAndFeel.class.getName() ); + registerSwitchToLookAndFeel( "F12", MetalLookAndFeel.class.getName() ); + + // register Alt+Shift+F1, F2, ... keys to change system scale factor + DemoPrefs.registerSystemScaleFactors( this ); // register Ctrl+0, Ctrl++ and Ctrl+- to change font size - int menuShortcutKeyMask = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(); - ((JComponent)getContentPane()).registerKeyboardAction( - e -> restoreFont(), - KeyStroke.getKeyStroke( KeyEvent.VK_0, menuShortcutKeyMask ), - JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT ); - ((JComponent)getContentPane()).registerKeyboardAction( - e -> incrFont(), - KeyStroke.getKeyStroke( KeyEvent.VK_PLUS, menuShortcutKeyMask ), - JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT ); - ((JComponent)getContentPane()).registerKeyboardAction( - e -> decrFont(), - KeyStroke.getKeyStroke( KeyEvent.VK_MINUS, menuShortcutKeyMask ), - JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT ); + registerKey( SystemInfo.isMacOS ? "meta 0" : "ctrl 0", () -> restoreFont() ); + registerKey( SystemInfo.isMacOS ? "meta PLUS" : "ctrl PLUS", () -> incrFont() ); + registerKey( SystemInfo.isMacOS ? "meta MINUS" : "ctrl MINUS", () -> decrFont() ); // register Alt+UP and Alt+DOWN to switch to previous/next theme - ((JComponent)getContentPane()).registerKeyboardAction( - e -> themesPanel.selectPreviousTheme(), - KeyStroke.getKeyStroke( KeyEvent.VK_UP, KeyEvent.ALT_DOWN_MASK ), - JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT ); - ((JComponent)getContentPane()).registerKeyboardAction( - e -> themesPanel.selectNextTheme(), - KeyStroke.getKeyStroke( KeyEvent.VK_DOWN, KeyEvent.ALT_DOWN_MASK ), - JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT ); + registerKey( "alt UP", () -> themesPanel.selectPreviousTheme() ); + registerKey( "alt DOWN", () -> themesPanel.selectNextTheme() ); // register ESC key to close frame - ((JComponent)getContentPane()).registerKeyboardAction( - e -> { - dispose(); - }, - KeyStroke.getKeyStroke( KeyEvent.VK_ESCAPE, 0, false ), - JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT ); + registerKey( "ESCAPE", () -> dispose() ); // make the "close" button the default button getRootPane().setDefaultButton( closeButton ); @@ -274,19 +256,23 @@ public class FlatTestFrame setTitle( newTitle ); } - private void registerSwitchToLookAndFeel( String keyStrokeStr, String lafClassName ) { + private void registerKey( String keyStrokeStr, Runnable runnable ) { KeyStroke keyStroke = KeyStroke.getKeyStroke( keyStrokeStr ); if( keyStroke == null ) throw new IllegalArgumentException( "Invalid key stroke '" + keyStrokeStr + "'" ); ((JComponent)getContentPane()).registerKeyboardAction( e -> { - selectLookAndFeel( lafClassName ); + runnable.run(); }, keyStroke, JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT ); } + private void registerSwitchToLookAndFeel( String keyStrokeStr, String lafClassName ) { + registerKey( keyStrokeStr, () -> selectLookAndFeel( lafClassName ) ); + } + private void loadLafs( DefaultComboBoxModel lafModel ) { Properties properties = new Properties(); try( InputStream in = new FileInputStream( "lafs.properties" ) ) {