mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2025-12-06 14:00:55 +03:00
Compare commits
4 Commits
d4827b6ddf
...
02636b260a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
02636b260a | ||
|
|
c8e2e78955 | ||
|
|
19c86cf1f7 | ||
|
|
0fb4c811f6 |
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@@ -107,7 +107,7 @@ jobs:
|
||||
- name: Cache Gradle
|
||||
uses: ./.github/actions/cache-gradle
|
||||
|
||||
- name: Release a new stable version to Maven Central
|
||||
- name: Release a new stable version to Maven Central and build demo and theme editor
|
||||
run: ./gradlew publishToSonatype closeSonatypeStagingRepository :flatlaf-demo:build :flatlaf-theme-editor:build -PskipFonts -Prelease -Dorg.gradle.parallel=false
|
||||
env:
|
||||
SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }}
|
||||
|
||||
@@ -7,6 +7,7 @@ FlatLaf Change Log
|
||||
|
||||
- System File Chooser allows using **operating system file dialogs** in Java
|
||||
Swing applications. (PR #988)
|
||||
- Zooming API. (PR #1051)
|
||||
|
||||
#### Fixed bugs
|
||||
|
||||
|
||||
@@ -14,7 +14,9 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import io.github.gradlenexus.publishplugin.CloseNexusStagingRepository
|
||||
import net.ltgt.gradle.errorprone.errorprone
|
||||
import org.gradle.kotlin.dsl.withType
|
||||
|
||||
|
||||
// initialize version
|
||||
@@ -103,6 +105,17 @@ allprojects {
|
||||
languageVersion.set( JavaLanguageVersion.of( 25 ) )
|
||||
} )
|
||||
}
|
||||
|
||||
// mark some publishing related tasks as not compatible with configuration cache
|
||||
withType<Sign>().configureEach {
|
||||
notCompatibleWithConfigurationCache( "not compatible" )
|
||||
}
|
||||
withType<PublishToMavenRepository>().configureEach {
|
||||
notCompatibleWithConfigurationCache( "not compatible" )
|
||||
}
|
||||
withType<CloseNexusStagingRepository>().configureEach {
|
||||
notCompatibleWithConfigurationCache( "not compatible" )
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import org.gradle.kotlin.dsl.support.serviceOf
|
||||
|
||||
plugins {
|
||||
`cpp-library`
|
||||
}
|
||||
@@ -37,6 +39,10 @@ tasks {
|
||||
doFirst {
|
||||
println( "Used Tool Chain:" )
|
||||
println( " - ${toolChain.get()}" )
|
||||
}
|
||||
|
||||
if( !project.gradle.serviceOf<BuildFeatures>().configurationCache.active.get() ) {
|
||||
doFirst {
|
||||
println( "Available Tool Chains:" )
|
||||
toolChains.forEach {
|
||||
println( " - $it" )
|
||||
@@ -44,3 +50,4 @@ tasks {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,10 +45,11 @@ if( !exclude ) {
|
||||
setSrcDirs( listOf( "src/main/module-info", "src/main/java", "src/main/java9" ) )
|
||||
|
||||
// exclude Java 8 source file if an equally named Java 9+ source file exists
|
||||
val projectDir = projectDir // necessary for configuration cache
|
||||
exclude {
|
||||
if( it.isDirectory )
|
||||
return@exclude false
|
||||
val java9file = file( "${projectDir}/src/main/java9/${it.path}" )
|
||||
val java9file = File( "${projectDir}/src/main/java9/${it.path}" )
|
||||
java9file.exists() && java9file != it.file
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,27 +85,6 @@ publishing {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
repositories {
|
||||
maven {
|
||||
name = "MavenCentral"
|
||||
|
||||
val releasesRepoUrl = "https://ossrh-staging-api.central.sonatype.com/service/local/staging/deploy/maven2/"
|
||||
val snapshotsRepoUrl = "https://central.sonatype.com/repository/maven-snapshots/"
|
||||
url = uri( if( rootProject.hasProperty( "release" ) ) releasesRepoUrl else snapshotsRepoUrl )
|
||||
|
||||
credentials {
|
||||
// get from gradle.properties
|
||||
val sonatypeUsername: String? by project
|
||||
val sonatypePassword: String? by project
|
||||
|
||||
username = System.getenv( "SONATYPE_USERNAME" ) ?: sonatypeUsername
|
||||
password = System.getenv( "SONATYPE_PASSWORD" ) ?: sonatypePassword
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
signing {
|
||||
@@ -125,10 +104,22 @@ tasks.withType<Sign>().configureEach {
|
||||
onlyIf { rootProject.hasProperty( "release" ) }
|
||||
}
|
||||
|
||||
tasks {
|
||||
// check whether parallel build is enabled
|
||||
tasks.withType<AbstractPublishToMaven>().configureEach {
|
||||
withType<AbstractPublishToMaven>().configureEach {
|
||||
doFirst {
|
||||
if( System.getProperty( "org.gradle.parallel" ) == "true" )
|
||||
throw RuntimeException( "Publishing does not work correctly with enabled parallel build. Disable parallel build with VM option '-Dorg.gradle.parallel=false'." )
|
||||
}
|
||||
}
|
||||
|
||||
register( "publishToSonatypeAndCloseStagingRepo" ) {
|
||||
group = "publishing"
|
||||
description = "Publish to Sonatype Maven Central and close staging repository"
|
||||
|
||||
dependsOn(
|
||||
"publishToSonatype",
|
||||
":closeSonatypeStagingRepository"
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,24 +98,30 @@ tasks {
|
||||
group = "verification"
|
||||
dependsOn( "jar" )
|
||||
|
||||
// necessary for configuration cache
|
||||
val classpath = sigtest.asPath
|
||||
val signatureFile = "${project.name}-sigtest.txt"
|
||||
val jarPath = jar.get().outputs.files.asPath
|
||||
val version = version
|
||||
|
||||
doLast {
|
||||
ant.withGroovyBuilder {
|
||||
"taskdef"(
|
||||
"name" to "sigtest",
|
||||
"classname" to "org.netbeans.apitest.Sigtest",
|
||||
"classpath" to sigtest.asPath )
|
||||
"classpath" to classpath )
|
||||
|
||||
"sigtest"(
|
||||
"action" to "generate",
|
||||
"fileName" to "${project.name}-sigtest.txt",
|
||||
"classpath" to jar.get().outputs.files.asPath,
|
||||
"fileName" to signatureFile,
|
||||
"classpath" to jarPath,
|
||||
"packages" to "com.formdev.flatlaf,com.formdev.flatlaf.themes,com.formdev.flatlaf.util",
|
||||
"version" to version,
|
||||
"release" to "1.8", // Java version
|
||||
"failonerror" to "true" )
|
||||
|
||||
"fixcrlf"(
|
||||
"file" to "${project.name}-sigtest.txt",
|
||||
"file" to signatureFile,
|
||||
"eol" to "lf" )
|
||||
}
|
||||
}
|
||||
@@ -125,17 +131,23 @@ tasks {
|
||||
group = "verification"
|
||||
dependsOn( "jar" )
|
||||
|
||||
// necessary for configuration cache
|
||||
val classpath = sigtest.asPath
|
||||
val signatureFile = "${project.name}-sigtest.txt"
|
||||
val jarPath = jar.get().outputs.files.asPath
|
||||
val version = version
|
||||
|
||||
doLast {
|
||||
ant.withGroovyBuilder {
|
||||
"taskdef"(
|
||||
"name" to "sigtest",
|
||||
"classname" to "org.netbeans.apitest.Sigtest",
|
||||
"classpath" to sigtest.asPath )
|
||||
"classpath" to classpath )
|
||||
|
||||
"sigtest"(
|
||||
"action" to "check",
|
||||
"fileName" to "${project.name}-sigtest.txt",
|
||||
"classpath" to jar.get().outputs.files.asPath,
|
||||
"fileName" to signatureFile,
|
||||
"classpath" to jarPath,
|
||||
"packages" to "com.formdev.flatlaf,com.formdev.flatlaf.util",
|
||||
"version" to version,
|
||||
"release" to "1.8", // Java version
|
||||
|
||||
@@ -368,6 +368,22 @@ public abstract class FlatLaf
|
||||
String.format( "a, address { color: #%06x; }", linkColor.getRGB() & 0xffffff ) );
|
||||
}
|
||||
};
|
||||
|
||||
// Initialize UIScale user scale factor immediately after FlatLaf was activated,
|
||||
// which is necessary to ensure that UIScale.setZoomFactor(float)
|
||||
// scales FlatLaf defaultDont correctly even if UIScale.scale() was not yet used.
|
||||
// In other words: Without this, UIScale.setZoomFactor(float) would
|
||||
// not work correctly if invoked between FlatLaf.setup() and crating UI.
|
||||
PropertyChangeListener listener = new PropertyChangeListener() {
|
||||
@Override
|
||||
public void propertyChange( PropertyChangeEvent e ) {
|
||||
if( "lookAndFeel".equals( e.getPropertyName() ) ) {
|
||||
UIManager.removePropertyChangeListener( this );
|
||||
UIScale.getUserScaleFactor();
|
||||
}
|
||||
}
|
||||
};
|
||||
UIManager.addPropertyChangeListener( listener );
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -707,11 +723,22 @@ public abstract class FlatLaf
|
||||
uiFont = ((ActiveFont)defaultFont).derive( baseFont, fontSize -> {
|
||||
return Math.round( fontSize * UIScale.computeFontScaleFactor( baseFont ) );
|
||||
} );
|
||||
}
|
||||
} else if( defaultFont instanceof LazyValue )
|
||||
uiFont = ActiveFont.toUIResource( (Font) ((LazyValue)defaultFont).createValue( defaults ) );
|
||||
|
||||
// increase font size if system property "flatlaf.uiScale" is set
|
||||
uiFont = UIScale.applyCustomScaleFactor( uiFont );
|
||||
|
||||
// apply zoom factor to font size
|
||||
float zoomFactor = UIScale.getZoomFactor();
|
||||
if( zoomFactor != 1 ) {
|
||||
// see also UIScale.setZoomFactor()
|
||||
int unzoomedFontSize = uiFont.getSize();
|
||||
defaults.put( "defaultFont.unzoomedSize", unzoomedFontSize );
|
||||
int newFontSize = Math.max( Math.round( unzoomedFontSize * zoomFactor ), 1 );
|
||||
uiFont = new FontUIResource( uiFont.deriveFont( (float) newFontSize ) );
|
||||
}
|
||||
|
||||
// set default font
|
||||
defaults.put( "defaultFont", uiFont );
|
||||
}
|
||||
@@ -1768,7 +1795,7 @@ public abstract class FlatLaf
|
||||
return toUIResource( baseFont );
|
||||
}
|
||||
|
||||
private FontUIResource toUIResource( Font font ) {
|
||||
private static FontUIResource toUIResource( Font font ) {
|
||||
// make sure that font is a UIResource for LaF switching
|
||||
return (font instanceof FontUIResource)
|
||||
? (FontUIResource) font
|
||||
|
||||
@@ -27,7 +27,9 @@ import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import javax.swing.LookAndFeel;
|
||||
import javax.swing.UIDefaults;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.plaf.DimensionUIResource;
|
||||
import javax.swing.plaf.FontUIResource;
|
||||
@@ -61,16 +63,28 @@ import com.formdev.flatlaf.FlatSystemProperties;
|
||||
* or if the default font is changed.
|
||||
* The user scale factor is computed based on the used font.
|
||||
* The JRE does not scale anything.
|
||||
* So we have to invoke {@link #scale(float)} where necessary.
|
||||
* So we have to invoke {@link #scale(int)} where necessary.
|
||||
* There is only one user scale factor for all displays.
|
||||
* The user scale factor may change if the active LaF, "defaultFont" or "Label.font" has changed.
|
||||
* If system scaling mode is available the user scale factor is usually 1,
|
||||
* but may be larger on Linux or if the default font is changed.
|
||||
*
|
||||
* <h2>Zooming</h2>
|
||||
*
|
||||
* Zooming allows appliations to easily zoom their UI, if FlatLaf is active Laf.
|
||||
* This is done by changing user scale factor and default font.
|
||||
* There are methods to increase, decrease and reset zoom factor.
|
||||
* <p>
|
||||
* Note: Only standard Swing components are zoomed.
|
||||
* Custom components need to use {@link #scale(int)} to zoom their UI.
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class UIScale
|
||||
{
|
||||
/** @since 3.7 */ public static final String PROP_USER_SCALE_FACTOR = "userScaleFactor";
|
||||
/** @since 3.7 */ public static final String PROP_ZOOM_FACTOR = "zoomFactor";
|
||||
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
private static PropertyChangeSupport changeSupport;
|
||||
@@ -87,7 +101,7 @@ public class UIScale
|
||||
changeSupport.removePropertyChangeListener( listener );
|
||||
}
|
||||
|
||||
//---- system scaling (Java 9) --------------------------------------------
|
||||
//---- system scaling (Java 9+) -------------------------------------------
|
||||
|
||||
private static Boolean jreHiDPI;
|
||||
|
||||
@@ -135,10 +149,13 @@ public class UIScale
|
||||
return (isSystemScalingEnabled() && gc != null) ? gc.getDefaultTransform().getScaleX() : 1;
|
||||
}
|
||||
|
||||
//---- user scaling (Java 8) ----------------------------------------------
|
||||
//---- user scaling (Java 8 / zooming) ------------------------------------
|
||||
|
||||
private static float unzoomedScaleFactor = 1;
|
||||
private static float scaleFactor = 1;
|
||||
private static boolean initialized;
|
||||
private static boolean listenerInitialized; // use extra flag for unit tests
|
||||
private static boolean ignoreFontChange;
|
||||
|
||||
private static void initialize() {
|
||||
if( initialized )
|
||||
@@ -148,33 +165,43 @@ public class UIScale
|
||||
if( !isUserScalingEnabled() )
|
||||
return;
|
||||
|
||||
initializeListener();
|
||||
|
||||
updateScaleFactor( true );
|
||||
}
|
||||
|
||||
private static void initializeListener() {
|
||||
if( listenerInitialized )
|
||||
return;
|
||||
listenerInitialized = true;
|
||||
|
||||
// listener to update scale factor if LaF changed, "defaultFont" or "Label.font" changed
|
||||
PropertyChangeListener listener = new PropertyChangeListener() {
|
||||
@Override
|
||||
public void propertyChange( PropertyChangeEvent e ) {
|
||||
switch( e.getPropertyName() ) {
|
||||
case "lookAndFeel":
|
||||
// it is not necessary (and possible) to remove listener of old LaF defaults
|
||||
// it is not possible (and necessary) to remove listener of old LaF defaults
|
||||
// because it is not possible to access the UIDefault object of the old LaF
|
||||
if( e.getNewValue() instanceof LookAndFeel )
|
||||
UIManager.getLookAndFeelDefaults().addPropertyChangeListener( this );
|
||||
updateScaleFactor();
|
||||
updateScaleFactor( true );
|
||||
break;
|
||||
|
||||
case "defaultFont":
|
||||
case "Label.font":
|
||||
updateScaleFactor();
|
||||
if( !ignoreFontChange )
|
||||
updateScaleFactor( false );
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
UIManager.addPropertyChangeListener( listener );
|
||||
UIManager.getDefaults().addPropertyChangeListener( listener );
|
||||
UIManager.getLookAndFeelDefaults().addPropertyChangeListener( listener );
|
||||
|
||||
updateScaleFactor();
|
||||
UIManager.addPropertyChangeListener( listener );
|
||||
}
|
||||
|
||||
private static void updateScaleFactor() {
|
||||
private static void updateScaleFactor( boolean lafChanged ) {
|
||||
if( !isUserScalingEnabled() )
|
||||
return;
|
||||
|
||||
@@ -185,17 +212,20 @@ public class UIScale
|
||||
return;
|
||||
}
|
||||
|
||||
// use font size to calculate scale factor (instead of DPI)
|
||||
// because even if we are on a HiDPI display it is not sure
|
||||
// that a larger font size is set by the current LaF
|
||||
// (e.g. can avoid large icons with small text)
|
||||
// get font that is used to calculate scale factor
|
||||
Font font = null;
|
||||
if( UIManager.getLookAndFeel() instanceof FlatLaf )
|
||||
font = UIManager.getFont( "defaultFont" );
|
||||
if( font == null )
|
||||
font = UIManager.getFont( "Label.font" );
|
||||
|
||||
setUserScaleFactor( computeFontScaleFactor( font ), true );
|
||||
float fontScaleFactor = computeFontScaleFactor( font );
|
||||
if( lafChanged && UIManager.getLookAndFeel() instanceof FlatLaf ) {
|
||||
// FlatLaf has applied zoom factor in FlatLaf.initDefaultFont() to defaultFont,
|
||||
// so we need to take it into account to get correct user scale factor
|
||||
fontScaleFactor /= zoomFactor;
|
||||
}
|
||||
setUserScaleFactor( fontScaleFactor, true );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -204,7 +234,7 @@ public class UIScale
|
||||
* @since 2
|
||||
*/
|
||||
public static float computeFontScaleFactor( Font font ) {
|
||||
if( SystemInfo.isWindows ) {
|
||||
if( SystemInfo.isWindows && !inUnitTests ) {
|
||||
// Special handling for Windows to be compatible with OS scaling,
|
||||
// which distinguish between "screen scaling" and "text scaling".
|
||||
// - Windows "screen scaling" scales everything (text, icon, gaps, etc.)
|
||||
@@ -335,7 +365,7 @@ public class UIScale
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the user scale factor.
|
||||
* Returns the user scale factor (including zoom factor).
|
||||
*/
|
||||
public static float getUserScaleFactor() {
|
||||
initialize();
|
||||
@@ -345,27 +375,49 @@ public class UIScale
|
||||
/**
|
||||
* Sets the user scale factor.
|
||||
*/
|
||||
private static void setUserScaleFactor( float scaleFactor, boolean normalize ) {
|
||||
if( normalize ) {
|
||||
if( scaleFactor < 1f ) {
|
||||
scaleFactor = FlatSystemProperties.getBoolean( FlatSystemProperties.UI_SCALE_ALLOW_SCALE_DOWN, false )
|
||||
? Math.round( scaleFactor * 10f ) / 10f // round small scale factor to 1/10
|
||||
: 1f;
|
||||
} else if( scaleFactor > 1f ) // round scale factor to 1/4
|
||||
scaleFactor = Math.round( scaleFactor * 4f ) / 4f;
|
||||
}
|
||||
private static void setUserScaleFactor( float unzoomedScaleFactor, boolean normalize ) {
|
||||
if( normalize )
|
||||
unzoomedScaleFactor = normalizeScaleFactor( unzoomedScaleFactor );
|
||||
|
||||
// minimum scale factor
|
||||
scaleFactor = Math.max( scaleFactor, 0.1f );
|
||||
unzoomedScaleFactor = Math.max( unzoomedScaleFactor, 0.1f );
|
||||
|
||||
if( unzoomedScaleFactor == UIScale.unzoomedScaleFactor )
|
||||
return;
|
||||
|
||||
if( DEBUG )
|
||||
System.out.println( "Unzoomed scale factor " + UIScale.unzoomedScaleFactor + " --> " + unzoomedScaleFactor );
|
||||
|
||||
UIScale.unzoomedScaleFactor = unzoomedScaleFactor;
|
||||
setScaleFactor( unzoomedScaleFactor * zoomFactor );
|
||||
}
|
||||
|
||||
private static void setScaleFactor( float scaleFactor ) {
|
||||
// round scale factor to 1/100
|
||||
scaleFactor = Math.round( scaleFactor * 100f ) / 100f;
|
||||
|
||||
if( scaleFactor == UIScale.scaleFactor )
|
||||
return;
|
||||
|
||||
float oldScaleFactor = UIScale.scaleFactor;
|
||||
UIScale.scaleFactor = scaleFactor;
|
||||
|
||||
if( DEBUG )
|
||||
System.out.println( "HiDPI scale factor " + scaleFactor );
|
||||
System.out.println( "Scale factor " + oldScaleFactor + " --> " + scaleFactor + " (unzoomed " + UIScale.unzoomedScaleFactor + ")" );
|
||||
|
||||
if( changeSupport != null )
|
||||
changeSupport.firePropertyChange( "userScaleFactor", oldScaleFactor, scaleFactor );
|
||||
changeSupport.firePropertyChange( PROP_USER_SCALE_FACTOR, oldScaleFactor, scaleFactor );
|
||||
}
|
||||
|
||||
private static float normalizeScaleFactor( float scaleFactor ) {
|
||||
if( scaleFactor < 1f ) {
|
||||
return FlatSystemProperties.getBoolean( FlatSystemProperties.UI_SCALE_ALLOW_SCALE_DOWN, false )
|
||||
? Math.round( scaleFactor * 10f ) / 10f // round small scale factor to 1/10
|
||||
: 1f;
|
||||
} else if( scaleFactor > 1f ) // round scale factor to 1/4
|
||||
return Math.round( scaleFactor * 4f ) / 4f;
|
||||
else
|
||||
return scaleFactor;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -451,4 +503,185 @@ public class UIScale
|
||||
? new InsetsUIResource( scale( insets.top ), scale( insets.left ), scale( insets.bottom ), scale( insets.right ) )
|
||||
: new Insets ( scale( insets.top ), scale( insets.left ), scale( insets.bottom ), scale( insets.right ) ));
|
||||
}
|
||||
|
||||
//---- zoom ---------------------------------------------------------------
|
||||
|
||||
private static float zoomFactor = 1;
|
||||
private static float[] supportedZoomFactors = { 1f, 1.1f, 1.25f, 1.5f, 1.75f, 2f };
|
||||
|
||||
/**
|
||||
* Returns the current zoom factor. Default is {@code 1}.
|
||||
*
|
||||
* @since 3.7
|
||||
*/
|
||||
public static float getZoomFactor() {
|
||||
return zoomFactor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the zoom factor.
|
||||
* Also updates user scale factor and default font (if FlatLaf is active Laf).
|
||||
* <p>
|
||||
* UI needs to be updated if zoom factor has changed. E.g.:
|
||||
* <pre>{@code
|
||||
* if( UIScale.setZoomFactor( newZoomFactor ) )
|
||||
* FlatLaf.updateUI();
|
||||
* }</pre>
|
||||
*
|
||||
* @param zoomFactor new zoom factor
|
||||
* @return {@code true} if zoom factor has changed
|
||||
* @since 3.7
|
||||
*/
|
||||
public static boolean setZoomFactor( float zoomFactor ) {
|
||||
// minimum zoom factor
|
||||
zoomFactor = Math.max( zoomFactor, 0.1f );
|
||||
|
||||
if( UIScale.zoomFactor == zoomFactor )
|
||||
return false;
|
||||
|
||||
float oldZoomFactor = UIScale.zoomFactor;
|
||||
UIScale.zoomFactor = zoomFactor;
|
||||
|
||||
if( DEBUG )
|
||||
System.out.println( "Zoom factor " + oldZoomFactor + " --> " + zoomFactor );
|
||||
|
||||
setScaleFactor( UIScale.unzoomedScaleFactor * zoomFactor );
|
||||
|
||||
if( initialized && UIManager.getLookAndFeel() instanceof FlatLaf ) {
|
||||
// see also FlatLaf.initDefaultFont()
|
||||
UIDefaults defaults = UIManager.getLookAndFeelDefaults();
|
||||
Font font = defaults.getFont( "defaultFont" );
|
||||
int unzoomedSize = defaults.getInt( "defaultFont.unzoomedSize" );
|
||||
if( unzoomedSize == 0 ) {
|
||||
unzoomedSize = font.getSize();
|
||||
defaults.put( "defaultFont.unzoomedSize", unzoomedSize );
|
||||
}
|
||||
|
||||
// update "defaultFont"
|
||||
ignoreFontChange = true;
|
||||
try {
|
||||
// get application default font before updating Laf default font
|
||||
Font appFont = UIManager.getFont( "defaultFont" );
|
||||
|
||||
// update Laf default font
|
||||
int newFontSize = Math.max( Math.round( unzoomedSize * zoomFactor ), 1 );
|
||||
defaults.put( "defaultFont", new FontUIResource( font.deriveFont( (float) newFontSize ) ) );
|
||||
|
||||
if( DEBUG )
|
||||
System.out.println( "Zoom Laf font " + font.getSize() + " --> " + newFontSize + " (unzoomed " + unzoomedSize + ")" );
|
||||
|
||||
// check whether application has changed default font
|
||||
if( appFont != font ) {
|
||||
// application has own default font --> also zoom it
|
||||
int newAppFontSize = Math.max( Math.round( (appFont.getSize() / oldZoomFactor) * zoomFactor ), 1 );
|
||||
UIManager.put( "defaultFont", appFont.deriveFont( (float) newAppFontSize ) );
|
||||
|
||||
if( DEBUG )
|
||||
System.out.println( "Zoom app font " + appFont.getSize() + " --> " + newAppFontSize );
|
||||
}
|
||||
} finally {
|
||||
ignoreFontChange = false;
|
||||
}
|
||||
}
|
||||
|
||||
if( changeSupport != null )
|
||||
changeSupport.firePropertyChange( PROP_ZOOM_FACTOR, oldZoomFactor, zoomFactor );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increases zoom factor using next greater factor in supported factors array.
|
||||
* <p>
|
||||
* UI needs to be updated if zoom factor has changed. E.g.:
|
||||
* <pre>{@code
|
||||
* if( UIScale.zoomIn() )
|
||||
* FlatLaf.updateUI();
|
||||
* }</pre>
|
||||
*
|
||||
* @return {@code true} if zoom factor has changed
|
||||
* @see #getSupportedZoomFactors()
|
||||
* @since 3.7
|
||||
*/
|
||||
public static boolean zoomIn() {
|
||||
int i = Arrays.binarySearch( supportedZoomFactors, zoomFactor );
|
||||
int next = (i >= 0) ? i + 1 : -i - 1;
|
||||
if( next >= supportedZoomFactors.length )
|
||||
return false;
|
||||
|
||||
return setZoomFactor( supportedZoomFactors[next] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Decreases zoom factor using next smaller factor in supported factors array.
|
||||
* <p>
|
||||
* UI needs to be updated if zoom factor has changed. E.g.:
|
||||
* <pre>{@code
|
||||
* if( UIScale.zoomOut() )
|
||||
* FlatLaf.updateUI();
|
||||
* }</pre>
|
||||
*
|
||||
* @return {@code true} if zoom factor has changed
|
||||
* @see #getSupportedZoomFactors()
|
||||
* @since 3.7
|
||||
*/
|
||||
public static boolean zoomOut() {
|
||||
int i = Arrays.binarySearch( supportedZoomFactors, zoomFactor );
|
||||
int prev = (i >= 0) ? i - 1 : -i - 2;
|
||||
if( prev < 0 )
|
||||
return false;
|
||||
|
||||
return setZoomFactor( supportedZoomFactors[prev] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets zoom factor to {@code 1}.
|
||||
* <p>
|
||||
* UI needs to be updated if zoom factor has changed. E.g.:
|
||||
* <pre>{@code
|
||||
* if( UIScale.zoomReset() )
|
||||
* FlatLaf.updateUI();
|
||||
* }</pre>
|
||||
*
|
||||
* @return {@code true} if zoom factor has changed
|
||||
* @since 3.7
|
||||
*/
|
||||
public static boolean zoomReset() {
|
||||
return setZoomFactor( 1 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the supported zoom factors used for {@link #zoomIn()} and {@link #zoomOut()}.
|
||||
* <p>
|
||||
* Default is {@code [ 1f, 1.1f, 1.25f, 1.5f, 1.75f, 2f ]}.
|
||||
*
|
||||
* @since 3.7
|
||||
*/
|
||||
public static float[] getSupportedZoomFactors() {
|
||||
return supportedZoomFactors.clone();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the supported zoom factors used for {@link #zoomIn()} and {@link #zoomOut()}.
|
||||
*
|
||||
* @since 3.7
|
||||
*/
|
||||
public static void setSupportedZoomFactors( float[] supportedZoomFactors ) {
|
||||
UIScale.supportedZoomFactors = supportedZoomFactors.clone();
|
||||
Arrays.sort( UIScale.supportedZoomFactors );
|
||||
|
||||
if( Arrays.binarySearch( UIScale.supportedZoomFactors, 1f ) < 0 )
|
||||
throw new IllegalArgumentException( "supportedZoomFactors array must contain value 1f" );
|
||||
}
|
||||
|
||||
//---- unit testing -------------------------------------------------------
|
||||
|
||||
static boolean inUnitTests;
|
||||
|
||||
static void tests_uninitialize() {
|
||||
initialized = false;
|
||||
unzoomedScaleFactor = 1;
|
||||
scaleFactor = 1;
|
||||
zoomFactor = 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,343 @@
|
||||
/*
|
||||
* Copyright 2025 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.util;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotEquals;
|
||||
import java.awt.Font;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.UnsupportedLookAndFeelException;
|
||||
import javax.swing.plaf.metal.MetalLookAndFeel;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import com.formdev.flatlaf.FlatDarkLaf;
|
||||
import com.formdev.flatlaf.FlatLaf;
|
||||
import com.formdev.flatlaf.FlatLightLaf;
|
||||
import com.formdev.flatlaf.FlatSystemProperties;
|
||||
|
||||
/**
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class TestUIScale
|
||||
{
|
||||
private static Map<String, String> FONT_EXTRA_DEFAULTS_1x = Collections.singletonMap(
|
||||
"defaultFont", "{instance}java.awt.Font,Dialog,0,12" );
|
||||
private static Map<String, String> FONT_EXTRA_DEFAULTS_1_5x = Collections.singletonMap(
|
||||
"defaultFont", "{instance}java.awt.Font,Dialog,0,18" );
|
||||
|
||||
@BeforeAll
|
||||
static void setup() {
|
||||
UIScale.inUnitTests = true;
|
||||
|
||||
// disable platform specific fonts
|
||||
System.setProperty( "flatlaf.uiScale.fontSizeDivider", "12" );
|
||||
FlatLaf.setGlobalExtraDefaults( FONT_EXTRA_DEFAULTS_1x );
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
static void cleanup() throws UnsupportedLookAndFeelException {
|
||||
System.clearProperty( "flatlaf.uiScale.fontSizeDivider" );
|
||||
FlatLaf.setGlobalExtraDefaults( null );
|
||||
|
||||
UIScale.inUnitTests = false;
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
void afterEach() throws UnsupportedLookAndFeelException {
|
||||
UIManager.setLookAndFeel( new MetalLookAndFeel() );
|
||||
UIManager.put( "defaultFont", null );
|
||||
UIManager.put( "Label.font", null );
|
||||
FlatLaf.setGlobalExtraDefaults( FONT_EXTRA_DEFAULTS_1x );
|
||||
|
||||
UIScale.tests_uninitialize();
|
||||
}
|
||||
|
||||
@Test
|
||||
void testCustomScaleFactor() {
|
||||
System.setProperty( FlatSystemProperties.UI_SCALE, "1.25x" );
|
||||
assertScaleFactor( 1.25f );
|
||||
|
||||
System.setProperty( FlatSystemProperties.UI_SCALE, "2x" );
|
||||
UIScale.tests_uninitialize();
|
||||
assertScaleFactor( 2f );
|
||||
|
||||
System.clearProperty( FlatSystemProperties.UI_SCALE );
|
||||
}
|
||||
|
||||
@Test
|
||||
void testLabelFontScaling() {
|
||||
assertInstanceOf( MetalLookAndFeel.class, UIManager.getLookAndFeel() );
|
||||
|
||||
testLabelFont( 8, 1f );
|
||||
testLabelFont( 9, 1f );
|
||||
testLabelFont( 10, 1f );
|
||||
testLabelFont( 11, 1f );
|
||||
testLabelFont( 12, 1f );
|
||||
testLabelFont( 13, 1f );
|
||||
testLabelFont( 14, 1.25f );
|
||||
testLabelFont( 15, 1.25f );
|
||||
testLabelFont( 16, 1.25f );
|
||||
testLabelFont( 17, 1.5f );
|
||||
testLabelFont( 18, 1.5f );
|
||||
testLabelFont( 19, 1.5f );
|
||||
testLabelFont( 20, 1.75f );
|
||||
testLabelFont( 21, 1.75f );
|
||||
testLabelFont( 22, 1.75f );
|
||||
testLabelFont( 23, 2f );
|
||||
testLabelFont( 24, 2f );
|
||||
testLabelFont( 25, 2f );
|
||||
testLabelFont( 26, 2.25f );
|
||||
}
|
||||
|
||||
private void testLabelFont( int fontSize, float expectedScaleFactor ) {
|
||||
UIManager.put( "Label.font", new Font( Font.DIALOG, Font.PLAIN, fontSize ) );
|
||||
assertScaleFactor( expectedScaleFactor );
|
||||
}
|
||||
|
||||
@Test
|
||||
void testDefaultFontScaling() {
|
||||
FlatLightLaf.setup();
|
||||
|
||||
testDefaultFont( 8, 1f );
|
||||
testDefaultFont( 9, 1f );
|
||||
testDefaultFont( 10, 1f );
|
||||
testDefaultFont( 11, 1f );
|
||||
testDefaultFont( 12, 1f );
|
||||
testDefaultFont( 13, 1f );
|
||||
testDefaultFont( 14, 1.25f );
|
||||
testDefaultFont( 15, 1.25f );
|
||||
testDefaultFont( 16, 1.25f );
|
||||
testDefaultFont( 17, 1.5f );
|
||||
testDefaultFont( 18, 1.5f );
|
||||
testDefaultFont( 19, 1.5f );
|
||||
testDefaultFont( 20, 1.75f );
|
||||
testDefaultFont( 21, 1.75f );
|
||||
testDefaultFont( 22, 1.75f );
|
||||
testDefaultFont( 23, 2f );
|
||||
testDefaultFont( 24, 2f );
|
||||
testDefaultFont( 25, 2f );
|
||||
testDefaultFont( 26, 2.25f );
|
||||
}
|
||||
|
||||
private void testDefaultFont( int fontSize, float expectedScaleFactor ) {
|
||||
UIManager.put( "defaultFont", new Font( Font.DIALOG, Font.PLAIN, fontSize ) );
|
||||
assertScaleFactor( expectedScaleFactor );
|
||||
}
|
||||
|
||||
@Test
|
||||
void testInitialScaleFactorAndFontSizes() {
|
||||
FlatLightLaf.setup();
|
||||
assertScaleFactorAndFontSizes( 1f, 12, -1 );
|
||||
|
||||
FlatLaf.setGlobalExtraDefaults( FONT_EXTRA_DEFAULTS_1_5x );
|
||||
FlatDarkLaf.setup();
|
||||
assertScaleFactorAndFontSizes( 1.5f, 18, -1 );
|
||||
}
|
||||
|
||||
@Test
|
||||
void zoom_Metal() {
|
||||
UIScale.setZoomFactor( 1.1f );
|
||||
assertScaleFactor( 1.1f );
|
||||
|
||||
UIScale.setZoomFactor( 1.3f );
|
||||
assertScaleFactor( 1.3f );
|
||||
|
||||
UIScale.setZoomFactor( 2.3f );
|
||||
assertScaleFactor( 2.3f );
|
||||
}
|
||||
|
||||
@Test
|
||||
void zoom_1x() {
|
||||
FlatLightLaf.setup();
|
||||
testZoom( 0.7f, 0.7f, 8, -1 );
|
||||
testZoom( 0.75f, 0.75f, 9, -1 );
|
||||
testZoom( 0.8f, 0.8f, 10, -1 );
|
||||
testZoom( 0.9f, 0.9f, 11, -1 );
|
||||
testZoom( 1f, 1f, 12, -1 );
|
||||
testZoom( 1.1f, 1.1f, 13, -1 );
|
||||
testZoom( 1.2f, 1.2f, 14, -1 );
|
||||
testZoom( 1.25f, 1.25f, 15, -1 );
|
||||
testZoom( 1.3f, 1.3f, 16, -1 );
|
||||
testZoom( 1.4f, 1.4f, 17, -1 );
|
||||
testZoom( 1.5f, 1.5f, 18, -1 );
|
||||
testZoom( 1.6f, 1.6f, 19, -1 );
|
||||
testZoom( 1.7f, 1.7f, 20, -1 );
|
||||
testZoom( 1.75f, 1.75f, 21, -1 );
|
||||
testZoom( 1.8f, 1.8f, 22, -1 );
|
||||
testZoom( 1.9f, 1.9f, 23, -1 );
|
||||
testZoom( 2f, 2f, 24, -1 );
|
||||
testZoom( 2.25f, 2.25f, 27, -1 );
|
||||
testZoom( 2.5f, 2.5f, 30, -1 );
|
||||
testZoom( 2.75f, 2.75f, 33, -1 );
|
||||
testZoom( 3f, 3f, 36, -1 );
|
||||
testZoom( 4f, 4f, 48, -1 );
|
||||
}
|
||||
|
||||
@Test
|
||||
void zoom_1_5x() {
|
||||
FlatLaf.setGlobalExtraDefaults( FONT_EXTRA_DEFAULTS_1_5x );
|
||||
FlatLightLaf.setup();
|
||||
|
||||
testZoom( 0.7f, 1.05f, 13, -1 );
|
||||
testZoom( 0.75f, 1.13f, 14, -1 );
|
||||
testZoom( 0.8f, 1.2f, 14, -1 );
|
||||
testZoom( 0.9f, 1.35f, 16, -1 );
|
||||
testZoom( 1f, 1.5f, 18, -1 );
|
||||
testZoom( 1.1f, 1.65f, 20, -1 );
|
||||
testZoom( 1.2f, 1.8f, 22, -1 );
|
||||
testZoom( 1.25f, 1.88f, 23, -1 );
|
||||
testZoom( 1.3f, 1.95f, 23, -1 );
|
||||
testZoom( 1.4f, 2.1f, 25, -1 );
|
||||
testZoom( 1.5f, 2.25f, 27, -1 );
|
||||
testZoom( 1.6f, 2.4f, 29, -1 );
|
||||
testZoom( 1.7f, 2.55f, 31, -1 );
|
||||
testZoom( 1.75f, 2.63f, 32, -1 );
|
||||
testZoom( 1.8f, 2.7f, 32, -1 );
|
||||
testZoom( 1.9f, 2.85f, 34, -1 );
|
||||
testZoom( 2f, 3f, 36, -1 );
|
||||
testZoom( 2.25f, 3.38f, 41, -1 );
|
||||
testZoom( 2.5f, 3.75f, 45, -1 );
|
||||
testZoom( 2.75f, 4.13f, 50, -1 );
|
||||
testZoom( 3f, 4.5f, 54, -1 );
|
||||
testZoom( 4f, 6f, 72, -1 );
|
||||
}
|
||||
|
||||
@Test
|
||||
void zoomAppFont_1x() {
|
||||
FlatLightLaf.setup();
|
||||
UIManager.put( "defaultFont", new Font( Font.DIALOG, Font.PLAIN, 14 ) );
|
||||
|
||||
testZoom( 1f, 1.25f, 12, 14 );
|
||||
testZoom( 1.1f, 1.38f, 13, 15 );
|
||||
testZoom( 1.25f, 1.56f, 15, 17 );
|
||||
testZoom( 1.5f, 1.88f, 18, 20 );
|
||||
testZoom( 1.75f, 2.19f, 21, 23 );
|
||||
testZoom( 2f, 2.5f, 24, 26 );
|
||||
testZoom( 1f, 1.25f, 12, 13 );
|
||||
testZoom( 2f, 2.5f, 24, 26 );
|
||||
}
|
||||
|
||||
@Test
|
||||
void zoomWithLafChange() {
|
||||
FlatLightLaf.setup();
|
||||
assertScaleFactorAndFontSizes( 1f, 12, -1 );
|
||||
testZoom( 1.1f, 1.1f, 13, -1 );
|
||||
|
||||
FlatDarkLaf.setup();
|
||||
assertScaleFactorAndFontSizes( 1.1f, 13, -1 );
|
||||
testZoom( 1.2f, 1.2f, 14, -1 );
|
||||
|
||||
FlatLightLaf.setup();
|
||||
assertScaleFactorAndFontSizes( 1.2f, 14, -1 );
|
||||
testZoom( 1.3f, 1.3f, 16, -1 );
|
||||
|
||||
FlatLaf.setGlobalExtraDefaults( FONT_EXTRA_DEFAULTS_1_5x );
|
||||
FlatDarkLaf.setup();
|
||||
assertScaleFactorAndFontSizes( 1.95f, 23, -1 );
|
||||
testZoom( 1.4f, 2.1f, 25, -1 );
|
||||
|
||||
FlatLightLaf.setup();
|
||||
assertScaleFactorAndFontSizes( 2.1f, 25, -1 );
|
||||
testZoom( 1.5f, 2.25f, 27, -1 );
|
||||
}
|
||||
|
||||
@Test
|
||||
void zoomWithDefaultFontChange() {
|
||||
FlatLightLaf.setup();
|
||||
assertScaleFactorAndFontSizes( 1f, 12, -1 );
|
||||
|
||||
float zoom1 = 1.4f;
|
||||
testZoom( zoom1, zoom1, 17, -1 );
|
||||
testDefaultFont( 8, z( zoom1, 1f ) );
|
||||
testDefaultFont( 9, z( zoom1, 1f ) );
|
||||
testDefaultFont( 10, z( zoom1, 1f ) );
|
||||
testDefaultFont( 11, z( zoom1, 1f ) );
|
||||
testDefaultFont( 12, z( zoom1, 1f ) );
|
||||
testDefaultFont( 13, z( zoom1, 1f ) );
|
||||
testDefaultFont( 14, z( zoom1, 1.25f ) );
|
||||
testDefaultFont( 15, z( zoom1, 1.25f ) );
|
||||
testDefaultFont( 16, z( zoom1, 1.25f ) );
|
||||
testDefaultFont( 17, z( zoom1, 1.5f ) );
|
||||
testDefaultFont( 18, z( zoom1, 1.5f ) );
|
||||
testDefaultFont( 19, z( zoom1, 1.5f ) );
|
||||
testDefaultFont( 20, z( zoom1, 1.75f ) );
|
||||
testDefaultFont( 21, z( zoom1, 1.75f ) );
|
||||
testDefaultFont( 22, z( zoom1, 1.75f ) );
|
||||
testDefaultFont( 23, z( zoom1, 2f ) );
|
||||
testDefaultFont( 24, z( zoom1, 2f ) );
|
||||
testDefaultFont( 25, z( zoom1, 2f ) );
|
||||
testDefaultFont( 26, z( zoom1, 2.25f ) );
|
||||
|
||||
float zoom2 = 1.8f;
|
||||
testZoom( zoom2, 4.05f, 22, 33 );
|
||||
testDefaultFont( 8, z( zoom2, 1f ) );
|
||||
testDefaultFont( 9, z( zoom2, 1f ) );
|
||||
testDefaultFont( 10, z( zoom2, 1f ) );
|
||||
testDefaultFont( 11, z( zoom2, 1f ) );
|
||||
testDefaultFont( 12, z( zoom2, 1f ) );
|
||||
testDefaultFont( 13, z( zoom2, 1f ) );
|
||||
testDefaultFont( 14, z( zoom2, 1.25f ) );
|
||||
testDefaultFont( 15, z( zoom2, 1.25f ) );
|
||||
testDefaultFont( 16, z( zoom2, 1.25f ) );
|
||||
testDefaultFont( 17, z( zoom2, 1.5f ) );
|
||||
testDefaultFont( 18, z( zoom2, 1.5f ) );
|
||||
testDefaultFont( 19, z( zoom2, 1.5f ) );
|
||||
testDefaultFont( 20, z( zoom2, 1.75f ) );
|
||||
testDefaultFont( 21, z( zoom2, 1.75f ) );
|
||||
testDefaultFont( 22, z( zoom2, 1.75f ) );
|
||||
testDefaultFont( 23, z( zoom2, 2f ) );
|
||||
testDefaultFont( 24, z( zoom2, 2f ) );
|
||||
testDefaultFont( 25, z( zoom2, 2f ) );
|
||||
testDefaultFont( 26, z( zoom2, 2.25f ) );
|
||||
}
|
||||
|
||||
private static float z( float zoom, float scale ) {
|
||||
// round scale factor to 1/100
|
||||
return Math.round( (zoom * scale) * 100f ) / 100f;
|
||||
}
|
||||
|
||||
private static void testZoom( float zoomFactor, float expectedScaleFactor,
|
||||
int expectedLafFontSize, int expectedAppFontSize )
|
||||
{
|
||||
UIScale.setZoomFactor( zoomFactor );
|
||||
assertScaleFactorAndFontSizes( expectedScaleFactor, expectedLafFontSize, expectedAppFontSize );
|
||||
}
|
||||
|
||||
private static void assertScaleFactorAndFontSizes( float expectedScaleFactor,
|
||||
int expectedLafFontSize, int expectedAppFontSize )
|
||||
{
|
||||
assertScaleFactor( expectedScaleFactor );
|
||||
|
||||
Font lafFont = UIManager.getLookAndFeelDefaults().getFont( "defaultFont" );
|
||||
Font appFont = UIManager.getFont( "defaultFont" );
|
||||
assertEquals( expectedLafFontSize, lafFont.getSize() );
|
||||
if( expectedAppFontSize > 0 ) {
|
||||
assertNotEquals( lafFont, appFont );
|
||||
assertEquals( expectedAppFontSize, appFont.getSize() );
|
||||
} else
|
||||
assertEquals( lafFont, appFont );
|
||||
}
|
||||
|
||||
private static void assertScaleFactor( float expectedScaleFactor ) {
|
||||
assertEquals( expectedScaleFactor, UIScale.getUserScaleFactor() );
|
||||
}
|
||||
}
|
||||
@@ -111,6 +111,10 @@ class ControlBar
|
||||
UIScale.addPropertyChangeListener( e -> {
|
||||
// update info label because user scale factor may change
|
||||
updateInfoLabel();
|
||||
|
||||
// update "Font" menu (e.g. if zoom factor changed)
|
||||
if( UIScale.PROP_ZOOM_FACTOR.equals( e.getPropertyName() ) )
|
||||
frame.updateFontMenuItems();
|
||||
} );
|
||||
}
|
||||
|
||||
@@ -192,13 +196,15 @@ class ControlBar
|
||||
String javaVendor = System.getProperty( "java.vendor" );
|
||||
if( "Oracle Corporation".equals( javaVendor ) )
|
||||
javaVendor = null;
|
||||
float zoomFactor = UIScale.getZoomFactor();
|
||||
double systemScaleFactor = UIScale.getSystemScaleFactor( getGraphicsConfiguration() );
|
||||
float userScaleFactor = UIScale.getUserScaleFactor();
|
||||
Font font = UIManager.getFont( "Label.font" );
|
||||
String newInfo = "(Java " + System.getProperty( "java.version" )
|
||||
+ (javaVendor != null ? ("; " + javaVendor) : "")
|
||||
+ (systemScaleFactor != 1 ? ("; system scale factor " + systemScaleFactor) : "")
|
||||
+ (userScaleFactor != 1 ? ("; user scale factor " + userScaleFactor) : "")
|
||||
+ (zoomFactor != 1 ? ("; zoom " + zoomFactor) : "")
|
||||
+ (systemScaleFactor != 1 ? ("; system scale " + systemScaleFactor) : "")
|
||||
+ (userScaleFactor != 1 ? ("; user scale " + userScaleFactor) : "")
|
||||
+ (systemScaleFactor == 1 && userScaleFactor == 1 ? "; no scaling" : "")
|
||||
+ "; " + font.getFamily() + " " + font.getSize()
|
||||
+ (font.isBold() ? " BOLD" : "")
|
||||
|
||||
@@ -25,6 +25,7 @@ import java.net.URISyntaxException;
|
||||
import java.time.Year;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.prefs.Preferences;
|
||||
import javax.swing.*;
|
||||
import javax.swing.text.DefaultEditorKit;
|
||||
@@ -46,12 +47,14 @@ import com.formdev.flatlaf.extras.components.FlatButton.ButtonType;
|
||||
import com.formdev.flatlaf.icons.FlatAbstractIcon;
|
||||
import com.formdev.flatlaf.themes.FlatMacDarkLaf;
|
||||
import com.formdev.flatlaf.themes.FlatMacLightLaf;
|
||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
import com.formdev.flatlaf.extras.FlatSVGUtils;
|
||||
import com.formdev.flatlaf.util.ColorFunctions;
|
||||
import com.formdev.flatlaf.util.FontUtils;
|
||||
import com.formdev.flatlaf.util.LoggingFacade;
|
||||
import com.formdev.flatlaf.util.SystemFileChooser;
|
||||
import com.formdev.flatlaf.util.SystemInfo;
|
||||
import com.formdev.flatlaf.util.UIScale;
|
||||
import net.miginfocom.layout.ConstraintParser;
|
||||
import net.miginfocom.layout.LC;
|
||||
import net.miginfocom.layout.UnitValue;
|
||||
@@ -73,6 +76,7 @@ class DemoFrame
|
||||
Arrays.sort( availableFontFamilyNames );
|
||||
|
||||
initComponents();
|
||||
initZommMenuItems();
|
||||
updateFontMenuItems();
|
||||
initAccentColors();
|
||||
initFullWindowContent();
|
||||
@@ -330,6 +334,92 @@ class DemoFrame
|
||||
showHints();
|
||||
}
|
||||
|
||||
private void initZommMenuItems() {
|
||||
float currentZoomFactor = UIScale.getZoomFactor();
|
||||
UIScale.setSupportedZoomFactors( new float[] { 0.7f, 0.8f, 0.9f, 1f, 1.1f, 1.2f, 1.3f, 1.4f, 1.5f, 1.75f, 2f } );
|
||||
|
||||
ButtonGroup group = new ButtonGroup();
|
||||
HashMap<Float, JCheckBoxMenuItem> items = new HashMap<>();
|
||||
|
||||
// add supported zoom factors to "Zoom" menu
|
||||
zoomMenu.addSeparator();
|
||||
for( float zoomFactor : UIScale.getSupportedZoomFactors() ) {
|
||||
JCheckBoxMenuItem item = new JCheckBoxMenuItem( (int)(zoomFactor * 100) + "%" );
|
||||
item.setSelected( zoomFactor == currentZoomFactor );
|
||||
item.addActionListener( this::zoomFactorChanged );
|
||||
zoomMenu.add( item );
|
||||
|
||||
group.add( item );
|
||||
items.put( zoomFactor, item );
|
||||
}
|
||||
|
||||
// update menu item selection if zoom factor changed
|
||||
UIScale.addPropertyChangeListener( e -> {
|
||||
if( UIScale.PROP_ZOOM_FACTOR.equals( e.getPropertyName() ) ) {
|
||||
float newZoomFactor = UIScale.getZoomFactor();
|
||||
JCheckBoxMenuItem item = items.get( newZoomFactor );
|
||||
if( item != null )
|
||||
item.setSelected( true );
|
||||
|
||||
zoomWindowBounds( this, (float) e.getOldValue(), (float) e.getNewValue() );
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
private static void zoomWindowBounds( Window window, float oldZoomFactor, float newZoomFactor ) {
|
||||
if( window instanceof Frame && ((Frame)window).getExtendedState() != Frame.NORMAL )
|
||||
return;
|
||||
|
||||
Rectangle oldBounds = window.getBounds();
|
||||
|
||||
// zoom window bounds
|
||||
float factor = (1f / oldZoomFactor) * newZoomFactor;
|
||||
int newWidth = (int) (oldBounds.width * factor);
|
||||
int newHeight = (int) (oldBounds.height * factor);
|
||||
int newX = oldBounds.x - ((newWidth - oldBounds.width) / 2);
|
||||
int newY = oldBounds.y - ((newHeight - oldBounds.height) / 2);
|
||||
|
||||
// get maximum window bounds (screen bounds minus screen insets)
|
||||
GraphicsConfiguration gc = window.getGraphicsConfiguration();
|
||||
Rectangle screenBounds = gc.getBounds();
|
||||
Insets screenInsets = FlatUIUtils.getScreenInsets( gc );
|
||||
Rectangle maxBounds = FlatUIUtils.subtractInsets( screenBounds, screenInsets );
|
||||
|
||||
// limit new window width/height
|
||||
newWidth = Math.min( newWidth, maxBounds.width );
|
||||
newHeight = Math.min( newHeight, maxBounds.height );
|
||||
|
||||
// move window into screen bounds
|
||||
newX = Math.max( Math.min( newX, maxBounds.width - newWidth ), maxBounds.x );
|
||||
newY = Math.max( Math.min( newY, maxBounds.height - newHeight ), maxBounds.y );
|
||||
|
||||
// set new window bounds
|
||||
window.setBounds( newX, newY, newWidth, newHeight );
|
||||
}
|
||||
|
||||
private void zoomFactorChanged( ActionEvent e ) {
|
||||
String zoomFactor = e.getActionCommand();
|
||||
float zoom = Integer.parseInt( zoomFactor.substring( 0, zoomFactor.length() - 1 ) ) / 100f;
|
||||
|
||||
if( UIScale.setZoomFactor( zoom ) )
|
||||
FlatLaf.updateUI();
|
||||
}
|
||||
|
||||
private void zoomReset() {
|
||||
if( UIScale.zoomReset() )
|
||||
FlatLaf.updateUI();
|
||||
}
|
||||
|
||||
private void zoomIn() {
|
||||
if( UIScale.zoomIn() )
|
||||
FlatLaf.updateUI();
|
||||
}
|
||||
|
||||
private void zoomOut() {
|
||||
if( UIScale.zoomOut() )
|
||||
FlatLaf.updateUI();
|
||||
}
|
||||
|
||||
private void fontFamilyChanged( ActionEvent e ) {
|
||||
String fontFamily = e.getActionCommand();
|
||||
|
||||
@@ -580,6 +670,10 @@ class DemoFrame
|
||||
JRadioButtonMenuItem radioButtonMenuItem1 = new JRadioButtonMenuItem();
|
||||
JRadioButtonMenuItem radioButtonMenuItem2 = new JRadioButtonMenuItem();
|
||||
JRadioButtonMenuItem radioButtonMenuItem3 = new JRadioButtonMenuItem();
|
||||
zoomMenu = new JMenu();
|
||||
JMenuItem resetZoomMenuItem = new JMenuItem();
|
||||
JMenuItem incrZoomMenuItem = new JMenuItem();
|
||||
JMenuItem decrZoomMenuItem = new JMenuItem();
|
||||
fontMenu = new JMenu();
|
||||
JMenuItem restoreFontMenuItem = new JMenuItem();
|
||||
JMenuItem incrFontMenuItem = new JMenuItem();
|
||||
@@ -844,25 +938,49 @@ class DemoFrame
|
||||
}
|
||||
menuBar.add(viewMenu);
|
||||
|
||||
//======== zoomMenu ========
|
||||
{
|
||||
zoomMenu.setText("Zoom");
|
||||
|
||||
//---- resetZoomMenuItem ----
|
||||
resetZoomMenuItem.setText("Reset Zoom");
|
||||
resetZoomMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_0, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
|
||||
resetZoomMenuItem.addActionListener(e -> zoomReset());
|
||||
zoomMenu.add(resetZoomMenuItem);
|
||||
|
||||
//---- incrZoomMenuItem ----
|
||||
incrZoomMenuItem.setText("Zoom In");
|
||||
incrZoomMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_PLUS, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
|
||||
incrZoomMenuItem.addActionListener(e -> zoomIn());
|
||||
zoomMenu.add(incrZoomMenuItem);
|
||||
|
||||
//---- decrZoomMenuItem ----
|
||||
decrZoomMenuItem.setText("Zoom Out");
|
||||
decrZoomMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_MINUS, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
|
||||
decrZoomMenuItem.addActionListener(e -> zoomOut());
|
||||
zoomMenu.add(decrZoomMenuItem);
|
||||
}
|
||||
menuBar.add(zoomMenu);
|
||||
|
||||
//======== fontMenu ========
|
||||
{
|
||||
fontMenu.setText("Font");
|
||||
|
||||
//---- restoreFontMenuItem ----
|
||||
restoreFontMenuItem.setText("Restore Font");
|
||||
restoreFontMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_0, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
|
||||
restoreFontMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_0, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()|KeyEvent.ALT_DOWN_MASK));
|
||||
restoreFontMenuItem.addActionListener(e -> restoreFont());
|
||||
fontMenu.add(restoreFontMenuItem);
|
||||
|
||||
//---- incrFontMenuItem ----
|
||||
incrFontMenuItem.setText("Increase Font Size");
|
||||
incrFontMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_PLUS, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
|
||||
incrFontMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_PLUS, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()|KeyEvent.ALT_DOWN_MASK));
|
||||
incrFontMenuItem.addActionListener(e -> incrFont());
|
||||
fontMenu.add(incrFontMenuItem);
|
||||
|
||||
//---- decrFontMenuItem ----
|
||||
decrFontMenuItem.setText("Decrease Font Size");
|
||||
decrFontMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_MINUS, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
|
||||
decrFontMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_MINUS, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()|KeyEvent.ALT_DOWN_MASK));
|
||||
decrFontMenuItem.addActionListener(e -> decrFont());
|
||||
fontMenu.add(decrFontMenuItem);
|
||||
}
|
||||
@@ -1111,6 +1229,7 @@ class DemoFrame
|
||||
private JMenuItem exitMenuItem;
|
||||
private JMenu scrollingPopupMenu;
|
||||
private JMenuItem htmlMenuItem;
|
||||
private JMenu zoomMenu;
|
||||
private JMenu fontMenu;
|
||||
private JMenu optionsMenu;
|
||||
private JCheckBoxMenuItem windowDecorationsCheckBoxMenuItem;
|
||||
|
||||
@@ -383,6 +383,31 @@ new FormModel {
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) )
|
||||
} )
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JMenu", new FormLayoutManager( class javax.swing.JMenu ) ) {
|
||||
name: "zoomMenu"
|
||||
"text": "Zoom"
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
}
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "resetZoomMenuItem"
|
||||
"text": "Reset Zoom"
|
||||
"accelerator": static javax.swing.KeyStroke getKeyStroke( 48, 4226, false )
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "zoomReset", false ) )
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "incrZoomMenuItem"
|
||||
"text": "Zoom In"
|
||||
"accelerator": static javax.swing.KeyStroke getKeyStroke( 521, 4226, false )
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "zoomIn", false ) )
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "decrZoomMenuItem"
|
||||
"text": "Zoom Out"
|
||||
"accelerator": static javax.swing.KeyStroke getKeyStroke( 45, 4226, false )
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "zoomOut", false ) )
|
||||
} )
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JMenu", new FormLayoutManager( class javax.swing.JMenu ) ) {
|
||||
name: "fontMenu"
|
||||
"text": "Font"
|
||||
@@ -392,19 +417,19 @@ new FormModel {
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "restoreFontMenuItem"
|
||||
"text": "Restore Font"
|
||||
"accelerator": static javax.swing.KeyStroke getKeyStroke( 48, 4226, false )
|
||||
"accelerator": static javax.swing.KeyStroke getKeyStroke( 48, 4746, false )
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "restoreFont", false ) )
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "incrFontMenuItem"
|
||||
"text": "Increase Font Size"
|
||||
"accelerator": static javax.swing.KeyStroke getKeyStroke( 521, 4226, false )
|
||||
"accelerator": static javax.swing.KeyStroke getKeyStroke( 521, 4746, false )
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "incrFont", false ) )
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||
name: "decrFontMenuItem"
|
||||
"text": "Decrease Font Size"
|
||||
"accelerator": static javax.swing.KeyStroke getKeyStroke( 45, 4226, false )
|
||||
"accelerator": static javax.swing.KeyStroke getKeyStroke( 45, 4746, false )
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "decrFont", false ) )
|
||||
} )
|
||||
} )
|
||||
|
||||
@@ -40,6 +40,11 @@ var javaHome = System.getProperty( "java.home" )
|
||||
if( javaHome.endsWith( "jre" ) && !file( "${javaHome}/include" ).exists() )
|
||||
javaHome += "/.."
|
||||
|
||||
interface InjectedOps {
|
||||
@get:Inject val fs: FileSystemOperations
|
||||
@get:Inject val e: ExecOperations
|
||||
}
|
||||
|
||||
tasks {
|
||||
register( "build-natives" ) {
|
||||
group = "build"
|
||||
@@ -115,16 +120,18 @@ tasks {
|
||||
}
|
||||
} )
|
||||
|
||||
val injectedOps = project.objects.newInstance<InjectedOps>()
|
||||
|
||||
doLast {
|
||||
// copy shared library to flatlaf-core resources
|
||||
copy {
|
||||
injectedOps.fs.copy {
|
||||
from( linkedFile )
|
||||
into( nativesDir )
|
||||
rename( linkedFile.get().asFile.name, libraryName )
|
||||
}
|
||||
|
||||
// dump( linkedFile.asFile.get(), true )
|
||||
}
|
||||
|
||||
// dump( linkedFile, true, injectedOps )
|
||||
}
|
||||
|
||||
if( org.gradle.internal.os.OperatingSystem.current().isLinux &&
|
||||
@@ -198,28 +205,28 @@ tasks {
|
||||
"-lgtk-3",
|
||||
)
|
||||
|
||||
val injectedOps = project.objects.newInstance<InjectedOps>()
|
||||
|
||||
doLast {
|
||||
// copy shared library to flatlaf-core resources
|
||||
copy {
|
||||
injectedOps.fs.copy {
|
||||
from( "$outDir/$libraryName" )
|
||||
into( nativesDir )
|
||||
}
|
||||
|
||||
// dump( file( "$outDir/$libraryName" ), false )
|
||||
}
|
||||
|
||||
// dump( file( "$outDir/$libraryName" ), false, injectedOps )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*dump
|
||||
interface InjectedExecOps { @get:Inject val execOps: ExecOperations }
|
||||
val injected = project.objects.newInstance<InjectedExecOps>()
|
||||
|
||||
fun dump( dylib: File, disassemble: Boolean ) {
|
||||
|
||||
fun Task.dump( f: Any, disassemble: Boolean, injectedOps: InjectedOps ) {
|
||||
doLast {
|
||||
val dylib = if( f is RegularFileProperty) f.get().asFile else f as File
|
||||
val dylibDir = dylib.parent
|
||||
injected.execOps.exec { commandLine( "size", dylib ); standardOutput = FileOutputStream( "$dylibDir/size.txt" ) }
|
||||
injected.execOps.exec {
|
||||
injectedOps.e.exec { commandLine( "size", dylib ); standardOutput = FileOutputStream( "$dylibDir/size.txt" ) }
|
||||
injectedOps.e.exec {
|
||||
commandLine( "objdump",
|
||||
// commands
|
||||
"--archive-headers",
|
||||
@@ -233,8 +240,9 @@ fun dump( dylib: File, disassemble: Boolean ) {
|
||||
standardOutput = FileOutputStream( "$dylibDir/objdump.txt" )
|
||||
}
|
||||
if( disassemble )
|
||||
injected.execOps.exec { commandLine( "objdump", "--disassemble-all", dylib ); standardOutput = FileOutputStream( "$dylibDir/disassemble.txt" ) }
|
||||
injected.execOps.exec { commandLine( "objdump", "--full-contents", dylib ); standardOutput = FileOutputStream( "$dylibDir/full-contents.txt" ) }
|
||||
injected.execOps.exec { commandLine( "hexdump", dylib ); standardOutput = FileOutputStream( "$dylibDir/hexdump.txt" ) }
|
||||
injectedOps.e.exec { commandLine( "objdump", "--disassemble-all", dylib ); standardOutput = FileOutputStream( "$dylibDir/disassemble.txt" ) }
|
||||
injectedOps.e.exec { commandLine( "objdump", "--full-contents", dylib ); standardOutput = FileOutputStream( "$dylibDir/full-contents.txt" ) }
|
||||
injectedOps.e.exec { commandLine( "hexdump", dylib ); standardOutput = FileOutputStream( "$dylibDir/hexdump.txt" ) }
|
||||
}
|
||||
}
|
||||
dump*/
|
||||
|
||||
@@ -43,8 +43,10 @@ var javaHome = System.getProperty( "java.home" )
|
||||
if( javaHome.endsWith( "jre" ) )
|
||||
javaHome += "/.."
|
||||
|
||||
interface InjectedExecOps { @get:Inject val execOps: ExecOperations }
|
||||
val injected = project.objects.newInstance<InjectedExecOps>()
|
||||
interface InjectedOps {
|
||||
@get:Inject val fs: FileSystemOperations
|
||||
@get:Inject val e: ExecOperations
|
||||
}
|
||||
|
||||
tasks {
|
||||
register( "build-natives" ) {
|
||||
@@ -96,12 +98,14 @@ tasks {
|
||||
}
|
||||
} )
|
||||
|
||||
val injectedOps = project.objects.newInstance<InjectedOps>()
|
||||
|
||||
doLast {
|
||||
// sign shared library
|
||||
// injected.execOps.exec { commandLine( "codesign", "-s", "FormDev Software GmbH", "--timestamp", "${linkedFile.asFile.get()}" ) }
|
||||
// injectedOps.e.exec { commandLine( "codesign", "-s", "FormDev Software GmbH", "--timestamp", "${linkedFile.asFile.get()}" ) }
|
||||
|
||||
// copy shared library to flatlaf-core resources
|
||||
copy {
|
||||
injectedOps.fs.copy {
|
||||
from( linkedFile )
|
||||
into( nativesDir )
|
||||
rename( linkedFile.get().asFile.name, libraryName )
|
||||
@@ -110,9 +114,9 @@ tasks {
|
||||
/*dump
|
||||
val dylib = linkedFile.asFile.get()
|
||||
val dylibDir = dylib.parent
|
||||
injected.execOps.exec { commandLine( "size", dylib ); standardOutput = FileOutputStream( "$dylibDir/size.txt" ) }
|
||||
injected.execOps.exec { commandLine( "size", "-m", dylib ); standardOutput = FileOutputStream( "$dylibDir/size-m.txt" ) }
|
||||
injected.execOps.exec {
|
||||
injectedOps.e.exec { commandLine( "size", dylib ); standardOutput = FileOutputStream( "$dylibDir/size.txt" ) }
|
||||
injectedOps.e.exec { commandLine( "size", "-m", dylib ); standardOutput = FileOutputStream( "$dylibDir/size-m.txt" ) }
|
||||
injectedOps.e.exec {
|
||||
commandLine( "objdump",
|
||||
// commands
|
||||
"--archive-headers",
|
||||
@@ -130,8 +134,8 @@ tasks {
|
||||
dylib )
|
||||
standardOutput = FileOutputStream( "$dylibDir/objdump.txt" )
|
||||
}
|
||||
injected.execOps.exec { commandLine( "objdump", "--disassemble-all", dylib ); standardOutput = FileOutputStream( "$dylibDir/disassemble.txt" ) }
|
||||
injected.execOps.exec { commandLine( "objdump", "--full-contents", dylib ); standardOutput = FileOutputStream( "$dylibDir/full-contents.txt" ) }
|
||||
injectedOps.e.exec { commandLine( "objdump", "--disassemble-all", dylib ); standardOutput = FileOutputStream( "$dylibDir/disassemble.txt" ) }
|
||||
injectedOps.e.exec { commandLine( "objdump", "--full-contents", dylib ); standardOutput = FileOutputStream( "$dylibDir/full-contents.txt" ) }
|
||||
dump*/
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,8 +41,10 @@ var javaHome = System.getProperty( "java.home" )
|
||||
if( javaHome.endsWith( "jre" ) )
|
||||
javaHome += "/.."
|
||||
|
||||
interface InjectedExecOps { @get:Inject val execOps: ExecOperations }
|
||||
val injected = project.objects.newInstance<InjectedExecOps>()
|
||||
interface InjectedOps {
|
||||
@get:Inject val fs: FileSystemOperations
|
||||
@get:Inject val e: ExecOperations
|
||||
}
|
||||
|
||||
tasks {
|
||||
register( "build-natives" ) {
|
||||
@@ -89,9 +91,11 @@ tasks {
|
||||
}
|
||||
} )
|
||||
|
||||
val injectedOps = project.objects.newInstance<InjectedOps>()
|
||||
|
||||
doLast {
|
||||
// copy shared library to flatlaf-core resources
|
||||
copy {
|
||||
injectedOps.fs.copy {
|
||||
from( linkedFile )
|
||||
into( nativesDir )
|
||||
rename( linkedFile.get().asFile.name, libraryName )
|
||||
@@ -101,9 +105,9 @@ tasks {
|
||||
val dumpbin = "C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/MSVC/14.42.34433/bin/Hostx64/x64/dumpbin.exe"
|
||||
val dll = linkedFile.asFile.get()
|
||||
val dllDir = dll.parent
|
||||
injected.execOps.exec { commandLine( dumpbin, "/all", "/rawdata:none", "/out:$dllDir/objdump.txt", dll ) }
|
||||
injected.execOps.exec { commandLine( dumpbin, "/all", "/out:$dllDir/full-contents.txt", dll ) }
|
||||
injected.execOps.exec { commandLine( dumpbin, "/disasm", "/out:$dllDir/disassemble.txt", dll ) }
|
||||
injectedOps.e.exec { commandLine( dumpbin, "/all", "/rawdata:none", "/out:$dllDir/objdump.txt", dll ) }
|
||||
injectedOps.e.exec { commandLine( dumpbin, "/all", "/out:$dllDir/full-contents.txt", dll ) }
|
||||
injectedOps.e.exec { commandLine( dumpbin, "/disasm", "/out:$dllDir/disassemble.txt", dll ) }
|
||||
dump*/
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,16 +32,25 @@ flatlafModuleInfo {
|
||||
dependsOn( ":flatlaf-fonts-inter:jar" )
|
||||
}
|
||||
|
||||
interface InjectedOps {
|
||||
@get:Inject val fs: FileSystemOperations
|
||||
}
|
||||
|
||||
tasks {
|
||||
register( "build-for-debugging" ) {
|
||||
group = "build"
|
||||
|
||||
dependsOn( "build" )
|
||||
|
||||
// necessary for configuration cache
|
||||
val jar = project.tasks["jar"].outputs.files
|
||||
val runtimeJars = configurations.runtimeClasspath.get().files
|
||||
val injectedOps = project.objects.newInstance<InjectedOps>()
|
||||
|
||||
doLast {
|
||||
copy {
|
||||
from( project.tasks["jar"].outputs )
|
||||
from( configurations.runtimeClasspath )
|
||||
injectedOps.fs.copy {
|
||||
from( jar )
|
||||
from( runtimeJars )
|
||||
into( "run" )
|
||||
rename( "-[0-9][0-9.]*[0-9]", "-999" )
|
||||
}
|
||||
|
||||
@@ -17,5 +17,5 @@
|
||||
flatlaf.releaseVersion = 3.6.2
|
||||
flatlaf.developmentVersion = 3.7-SNAPSHOT
|
||||
|
||||
org.gradle.parallel = true
|
||||
org.gradle.configuration-cache = true
|
||||
# org.gradle.warning.mode = all
|
||||
|
||||
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,6 +1,6 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.0-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
||||
Reference in New Issue
Block a user