diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 48e0ef63..1382260f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -105,11 +105,11 @@ jobs: distribution: temurin # pre-installed on ubuntu-latest cache: gradle - - name: Publish snapshot to oss.sonatype.org + - name: Publish snapshot to Sonatype Central run: ./gradlew publish -PskipFonts -Dorg.gradle.internal.publish.checksums.insecure=true -Dorg.gradle.parallel=false env: - OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }} - OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }} + SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} + SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} release: @@ -131,10 +131,10 @@ jobs: cache: gradle - name: Release a new stable version to Maven Central - run: ./gradlew publish :flatlaf-demo:build :flatlaf-theme-editor:build -PskipFonts -Prelease -Dorg.gradle.parallel=false + run: ./gradlew publishToSonatype closeSonatypeStagingRepository :flatlaf-demo:build :flatlaf-theme-editor:build -PskipFonts -Prelease -Dorg.gradle.parallel=false env: - OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }} - OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }} + SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} + SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} SIGNING_KEY: ${{ secrets.SIGNING_KEY }} SIGNING_PASSWORD: ${{ secrets.SIGNING_PASSWORD }} diff --git a/.github/workflows/fonts.yml b/.github/workflows/fonts.yml index e6a04226..9654f503 100644 --- a/.github/workflows/fonts.yml +++ b/.github/workflows/fonts.yml @@ -45,18 +45,18 @@ jobs: run: ./gradlew :flatlaf-fonts-${{ matrix.font }}:build if: startsWith( github.ref, format( 'refs/tags/fonts/{0}-', matrix.font ) ) != true - - name: Publish snapshot to oss.sonatype.org + - name: Publish snapshot to Sonatype Central run: ./gradlew :flatlaf-fonts-${{ matrix.font }}:publish -Dorg.gradle.internal.publish.checksums.insecure=true env: - OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }} - OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }} + SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} + SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} if: github.ref == 'refs/heads/main' || startsWith( github.ref, 'refs/heads/develop-' ) - name: Release a new stable version to Maven Central run: ./gradlew :flatlaf-fonts-${{ matrix.font }}:build :flatlaf-fonts-${{ matrix.font }}:publish -Prelease env: - OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }} - OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }} + SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} + SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} SIGNING_KEY: ${{ secrets.SIGNING_KEY }} SIGNING_PASSWORD: ${{ secrets.SIGNING_PASSWORD }} if: startsWith( github.ref, format( 'refs/tags/fonts/{0}-', matrix.font ) ) diff --git a/.github/workflows/pr-snapshots.yml b/.github/workflows/pr-snapshots.yml index bd09587e..207bae20 100644 --- a/.github/workflows/pr-snapshots.yml +++ b/.github/workflows/pr-snapshots.yml @@ -28,10 +28,10 @@ jobs: distribution: temurin # pre-installed on ubuntu-latest cache: gradle - - name: Publish PR snapshot to oss.sonatype.org + - name: Publish PR snapshot to Sonatype Central run: > ./gradlew publish -PskipFonts -Dorg.gradle.internal.publish.checksums.insecure=true -Dorg.gradle.parallel=false -Pgithub.event.pull_request.number=${{ github.event.pull_request.number }} env: - OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }} - OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }} + SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} + SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} diff --git a/CHANGELOG.md b/CHANGELOG.md index 3501db20..3af9602e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,18 @@ FlatLaf Change Log ================== -## 3.6-SNAPSHOT +## 3.7-SNAPSHOT + +- Extras: Support JSVG 2.0.0. Minimum JSVG version is now 1.6.0. (issue #997) +- JideSplitButton: Fixed updating popup when switching theme. (issue #1000) +- IntelliJ Themes: Fixed logging false errors when loading 3rd party + `.theme.json` files. (issue #990) +- Linux: Popups appeared in wrong position on multi-screen setup if primary + display is located below or right to secondary display. (see + [NetBeans issue #8532](https://github.com/apache/netbeans/issues/8532)) + + +## 3.6 #### New features and improvements @@ -21,6 +32,8 @@ FlatLaf Change Log - List: Support for alternate row highlighting. (PR #939) - Tree: Support for alternate row highlighting. (PR #903) - Tree: Support wide cell renderer. (issue #922) +- ScrollBar: Use rounded thumb also on Windows (as on macOS and Linux) and made + thumb slightly darker/lighter. (issue #918) - Extras: `FlatSVGIcon` color filters now can access painting component to implement component state based color mappings. (issue #906) - Linux: @@ -70,6 +83,21 @@ FlatLaf Change Log application where multiple class loaders are involved. E.g. in Eclipse plugin or in LibreOffice extension. (issues #955 and #851) - HTML: Fixed rendering of `
` in dark themes. (issue #932) +- TextComponents: `selectAllOnFocusPolicy` related changes: + - No longer select all text if selection (or caret position) was changed by + application and `selectAllOnFocusPolicy` is `once` (the default). (issue + #983) + - FormattedTextField and Spinner: `selectAllOnFocusPolicy = once` behaves now + as `always` (was `never` before), which means that all text is selected when + component gains focus. This is because of special behavior of + `JFormattedTextField` that did not allow implementation of `once`. + - Client property `JTextField.selectAllOnFocusPolicy` now also works on + (editable) `JComboBox` and on `JSpinner`. + - Added client property `JTextField.selectAllOnMouseClick` to override UI + property `TextComponent.selectAllOnMouseClick`. (issue #961) + - For `selectAllOnMouseClick = true`, clicking with the mouse into the text + field, to focus it, now always selects all text, even if + `selectAllOnFocusPolicy` is `once`. #### Incompatibilities diff --git a/README.md b/README.md index 2ab9ce61..11a719b3 100644 --- a/README.md +++ b/README.md @@ -83,10 +83,10 @@ application. ### Snapshots FlatLaf snapshot binaries are available on -[Sonatype OSSRH](https://oss.sonatype.org/content/repositories/snapshots/com/formdev/flatlaf/). +[Sonatype Central](https://central.sonatype.com/service/rest/repository/browse/maven-snapshots/com/formdev/flatlaf/). To access the latest snapshot, change the FlatLaf version in your dependencies -to `-SNAPSHOT` (e.g. `0.27-SNAPSHOT`) and add the repository -`https://oss.sonatype.org/content/repositories/snapshots/` to your build (see +to `-SNAPSHOT` (e.g. `3.7-SNAPSHOT`) and add the repository +`https://central.sonatype.com/repository/maven-snapshots/` to your build (see [Maven](https://maven.apache.org/guides/mini/guide-multiple-repositories.html) and [Gradle](https://docs.gradle.org/current/userguide/declaring_repositories.html#sec:declaring_custom_repository) @@ -184,11 +184,16 @@ Applications using FlatLaf relational data browsing tool - ![Hot](images/hot.svg) [MagicPlot](https://magicplot.com/) (**commercial**) - Software for nonlinear fitting, plotting and data analysis -- ![New](images/new.svg) [Constellation](https://www.constellation-app.com/) - - Data Visualization and Analytics (based on NetBeans platform) -- ![New](images/new.svg) - [Kafka Visualizer](https://github.com/kumait/kafkavisualizer) - Kafka GUI +- [Constellation](https://www.constellation-app.com/) - Data Visualization and + Analytics (based on NetBeans platform) +- [Kafka Visualizer](https://github.com/kumait/kafkavisualizer) - Kafka GUI client +- ![New](images/new.svg) + [RedisFront](https://github.com/dromara/RedisFront/blob/master/README_EN.md) - + Cross-platform redis GUI +- ![New](images/new.svg) + [Zettelkasten](https://github.com/Zettelkasten-Team/Zettelkasten) - knowledge + management tool ### Security @@ -197,11 +202,9 @@ Applications using FlatLaf - ![Hot](images/hot.svg) [Burp Suite Professional and Community Edition](https://portswigger.net/burp/pro) (**commercial**) - the leading software for web security testing -- ![New](images/new.svg) - [Ghidra](https://github.com/NationalSecurityAgency/ghidra) - a software +- [Ghidra](https://github.com/NationalSecurityAgency/ghidra) - a software reverse engineering (SRE) framework -- ![New](images/new.svg) [jadx](https://github.com/skylot/jadx) - Dex to Java - decompiler +- [jadx](https://github.com/skylot/jadx) - Dex to Java decompiler - [BurpCustomizer](https://github.com/CoreyD97/BurpCustomizer) - adds more FlatLaf themes to Burp Suite - [Total Validator](https://www.totalvalidator.com/) (**commercial**) - checks @@ -213,13 +216,12 @@ Applications using FlatLaf - [jclasslib bytecode viewer](https://github.com/ingokegel/jclasslib) - [KeyStore Explorer](https://keystore-explorer.org/) -- ![New](images/new.svg) - [muCommander](https://github.com/mucommander/mucommander) - lightweight +- [muCommander](https://github.com/mucommander/mucommander) - lightweight cross-platform file manager -- ![New](images/new.svg) [Guiffy](https://www.guiffy.com/) (**commercial**) - - advanced cross-platform Diff/Merge -- ![New](images/new.svg) [HashGarten](https://github.com/jonelo/HashGarten) - - cross-platform Swing GUI for Jacksum +- [Guiffy](https://www.guiffy.com/) (**commercial**) - advanced cross-platform + Diff/Merge +- [HashGarten](https://github.com/jonelo/HashGarten) - cross-platform Swing GUI + for Jacksum - [Pseudo Assembler IDE](https://github.com/tomasz-herman/PseudoAssemblerIDE) - IDE for Pseudo-Assembler - [Linotte](https://github.com/cpc6128/LangageLinotte) - French programming @@ -228,6 +230,10 @@ Applications using FlatLaf systems development platform - ![New](images/new.svg) [Consulo](https://github.com/consulo/consulo) - open source cross-platform multi-language IDE (Java, .NET, JS, etc) +- [Convertigo](https://github.com/convertigo/convertigo) - low code & no code + mobile & web platform +- ![New](images/new.svg) [EduMIPS64](https://github.com/EduMIPS64/edumips64) - + visual MIPS64 CPU simulator ### Electrical @@ -235,6 +241,11 @@ Applications using FlatLaf designing, simulating and explaining digital circuits - [Logisim-evolution](https://github.com/logisim-evolution/logisim-evolution) - Digital logic design tool and simulator +- ![New](images/new.svg) [OpenPnP](https://github.com/openpnp/openpnp) - SMT + Pick and Place Hardware and Software +- ![New](images/new.svg) + [TrainControl](https://github.com/bob123456678/TrainControl) - control Marklin + / Trix / DCC digital model train layout - [Makelangelo Software](https://github.com/MarginallyClever/Makelangelo-software) - for plotters, especially the wall-hanging polargraph - [GUIslice Builder](https://github.com/ImpulseAdventure/GUIslice-Builder) - GUI @@ -249,8 +260,10 @@ Applications using FlatLaf - ![Hot](images/hot.svg) [jAlbum](https://jalbum.net/) (**commercial**) - creates photo album websites -- ![New](images/new.svg) [MediathekView](https://mediathekview.de/) - search in - media libraries of various German broadcasters +- [MediathekView](https://mediathekview.de/) - search in media libraries of + various German broadcasters +- ![New](images/new.svg) [Pixelitor](https://github.com/lbalazscs/Pixelitor) - + image editor - [Cinecred](https://loadingbyte.com/cinecred/) - create beautiful film credit sequences - [tinyMediaManager](https://www.tinymediamanager.org/) (**commercial**) - a @@ -267,18 +280,23 @@ Applications using FlatLaf - [lectureStudio](https://www.lecturestudio.org/) - digitize your lectures with ease -### Modelling +### Modelling / Planning -- ![New](images/new.svg) [Astah](https://astah.net/) (**commercial**) - create - UML, ER Diagram, Flowchart, Data Flow Diagram, Requirement Diagram, SysML - diagrams and more +- ![New](images/new.svg) [Gephi](https://github.com/gephi/gephi) - the Open + Graph Viz Platform +- [Astah](https://astah.net/) (**commercial**) - create UML, ER Diagram, + Flowchart, Data Flow Diagram, Requirement Diagram, SysML diagrams and more - [IGMAS+](https://www.gfz-potsdam.de/igmas) - Interactive Gravity and Magnetic Application System +- ![New](images/new.svg) [StarPlan](https://www.progotec.de/) (**commercial**) - + die Stundenplan Software für Bildungseinrichtungen +- ![New](images/new.svg) [SSPlot](https://github.com/babaissarkar/ssplot) - + plotting utility for plotting CSV data ### Documents -- ![New](images/new.svg) [Big Faceless (BFO) PDF Viewer](https://bfo.com/) - (**commercial**) - Swing PDF Viewer +- [Big Faceless (BFO) PDF Viewer](https://bfo.com/) (**commercial**) - Swing PDF + Viewer - [PDF Studio](https://www.qoppa.com/pdfstudio/) (**commercial**) - create, review and edit PDF documents - [XMLmind XML Editor](https://www.xmlmind.com/xmleditor/) (**commercial**) @@ -296,6 +314,9 @@ Applications using FlatLaf ### Business / Legal +- ![New](images/new.svg) ![Sponsor](images/sponsor.svg) + [Lisheane ERP](https://www.lisheane.ch/) (**commercial**) - backoffice + applikation - ![Sponsor](images/sponsor.svg) [j-lawyer](https://github.com/jlawyerorg/j-lawyer-org) - Kanzleisoftware - ![Sponsor](images/sponsor.svg) [Jeyla Studio](https://www.jeylastudio.com/) - @@ -312,20 +333,20 @@ Applications using FlatLaf ### Messaging -- ![New](images/new.svg) [Spark](https://github.com/igniterealtime/Spark) - - cross-platform IM client optimized for businesses and organizations -- ![New](images/new.svg) [Chatty](https://github.com/chatty/chatty) - Twitch - Chat Client +- [Spark](https://github.com/igniterealtime/Spark) - cross-platform IM client + optimized for businesses and organizations +- [Chatty](https://github.com/chatty/chatty) - Twitch Chat Client ### Gaming -- ![New](images/new.svg) ![Sponsor](images/sponsor.svg) - [BGBlitz](https://www.bgblitz.com/) (**commercial**) - professional Backgammon -- ![New](images/new.svg) [MCreator](https://github.com/MCreator/MCreator) - - software used to make Minecraft Java Edition mods, Minecraft Bedrock Edition Add-Ons, - and data packs without programming knowledge -- ![New](images/new.svg) [MapTool](https://github.com/RPTools/maptool) - virtual - Tabletop for playing role-playing games +- ![Sponsor](images/sponsor.svg) [BGBlitz](https://www.bgblitz.com/) + (**commercial**) - professional Backgammon +- ![New](images/new.svg) [josé](https://peteschaefer.github.io/jose/) - a + graphical chess tool +- ![New](images/new.svg) [MCreator](https://github.com/MCreator/MCreator) - make + Minecraft Java Edition mods, Minecraft Bedrock Edition Add-Ons, and data packs +- [MapTool](https://github.com/RPTools/maptool) - virtual Tabletop for playing + role-playing games - [MegaMek](https://github.com/MegaMek/megamek), [MegaMekLab](https://github.com/MegaMek/megameklab) and [MekHQ](https://github.com/MegaMek/mekhq) - a sci-fi tabletop BattleTech @@ -337,8 +358,7 @@ Applications using FlatLaf - [MooInfo](https://github.com/rememberber/MooInfo) - visual implementation of OSHI, to view information about the system and hardware -- ![New](images/new.svg) - [Linux Task Manager (LTM)](https://github.com/ajee10x/LTM-LinuxTaskManager) - +- [Linux Task Manager (LTM)](https://github.com/ajee10x/LTM-LinuxTaskManager) - GUI for monitoring and managing various aspects of a Linux system - [Rest Suite](https://github.com/supanadit/restsuite) - Rest API testing - [SpringRemote](https://github.com/HaleyWang/SpringRemote) - remote Linux SSH @@ -347,6 +367,8 @@ Applications using FlatLaf easy - [Android Tool](https://github.com/fast-geek/Android-Tool) - makes popular adb and fastboot commands easier to use +- ![New](images/new.svg) [Termora](https://github.com/TermoraDev/termora) - + Terminal emulator and SSH client ### Miscellaneous diff --git a/build.gradle.kts b/build.gradle.kts index 424fd54e..67b55aac 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -16,6 +16,7 @@ import net.ltgt.gradle.errorprone.errorprone +group = "com.formdev" version = property( if( hasProperty( "release" ) ) "flatlaf.releaseVersion" else "flatlaf.developmentVersion" ) as String // for PR snapshots change version to 'PR--SNAPSHOT' @@ -49,6 +50,7 @@ println() plugins { + alias( libs.plugins.gradle.nexus.publish.plugin ) alias( libs.plugins.errorprone ) apply false } @@ -143,3 +145,20 @@ allprojects { } } } + +nexusPublishing { + repositories { + sonatype { + // see https://central.sonatype.org/publish/publish-portal-ossrh-staging-api/ + nexusUrl = uri( "https://ossrh-staging-api.central.sonatype.com/service/local/" ) + snapshotRepositoryUrl = uri( "https://central.sonatype.com/repository/maven-snapshots/" ) + + // 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 + } + } +} diff --git a/buildSrc/src/main/kotlin/flatlaf-publish.gradle.kts b/buildSrc/src/main/kotlin/flatlaf-publish.gradle.kts index f7575003..0a547c20 100644 --- a/buildSrc/src/main/kotlin/flatlaf-publish.gradle.kts +++ b/buildSrc/src/main/kotlin/flatlaf-publish.gradle.kts @@ -86,24 +86,26 @@ publishing { } } +/* repositories { maven { - name = "OSSRH" + name = "MavenCentral" - val releasesRepoUrl = "https://oss.sonatype.org/service/local/staging/deploy/maven2/" - val snapshotsRepoUrl = "https://oss.sonatype.org/content/repositories/snapshots/" + 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 ossrhUsername: String? by project - val ossrhPassword: String? by project + val sonatypeUsername: String? by project + val sonatypePassword: String? by project - username = System.getenv( "OSSRH_USERNAME" ) ?: ossrhUsername - password = System.getenv( "OSSRH_PASSWORD" ) ?: ossrhPassword + username = System.getenv( "SONATYPE_USERNAME" ) ?: sonatypeUsername + password = System.getenv( "SONATYPE_PASSWORD" ) ?: sonatypePassword } } } +*/ } signing { diff --git a/flatlaf-core/build.gradle.kts b/flatlaf-core/build.gradle.kts index f02a413d..f1de6233 100644 --- a/flatlaf-core/build.gradle.kts +++ b/flatlaf-core/build.gradle.kts @@ -158,4 +158,8 @@ flatlafPublish { NativeArtifact( "${natives}/libflatlaf-linux-x86_64.so", "linux-x86_64", "so" ), NativeArtifact( "${natives}/libflatlaf-linux-arm64.so", "linux-arm64", "so" ), ) + + // Maven Central Snapshots repo currently does not accept .dylib files + if( version.toString().endsWith( "-SNAPSHOT" ) ) + nativeArtifacts = nativeArtifacts?.filter { it.type != "dylib" } } diff --git a/flatlaf-core/flatlaf-core-sigtest.txt b/flatlaf-core/flatlaf-core-sigtest.txt index 1378b2c7..ca3f4737 100644 --- a/flatlaf-core/flatlaf-core-sigtest.txt +++ b/flatlaf-core/flatlaf-core-sigtest.txt @@ -1,5 +1,5 @@ #Signature file v4.1 -#Version 3.5.2 +#Version 3.6 CLSS public abstract interface com.formdev.flatlaf.FlatClientProperties fld public final static java.lang.String BUTTON_TYPE = "JButton.buttonType" @@ -24,6 +24,7 @@ fld public final static java.lang.String MINIMUM_HEIGHT = "JComponent.minimumHei fld public final static java.lang.String MINIMUM_WIDTH = "JComponent.minimumWidth" fld public final static java.lang.String OUTLINE = "JComponent.outline" fld public final static java.lang.String OUTLINE_ERROR = "error" +fld public final static java.lang.String OUTLINE_SUCCESS = "success" fld public final static java.lang.String OUTLINE_WARNING = "warning" fld public final static java.lang.String PLACEHOLDER_TEXT = "JTextField.placeholderText" fld public final static java.lang.String POPUP_BORDER_CORNER_RADIUS = "Popup.borderCornerRadius" @@ -40,6 +41,7 @@ fld public final static java.lang.String SELECT_ALL_ON_FOCUS_POLICY = "JTextFiel fld public final static java.lang.String SELECT_ALL_ON_FOCUS_POLICY_ALWAYS = "always" fld public final static java.lang.String SELECT_ALL_ON_FOCUS_POLICY_NEVER = "never" fld public final static java.lang.String SELECT_ALL_ON_FOCUS_POLICY_ONCE = "once" +fld public final static java.lang.String SELECT_ALL_ON_MOUSE_CLICK = "JTextField.selectAllOnMouseClick" fld public final static java.lang.String SPLIT_PANE_EXPANDABLE_SIDE = "JSplitPane.expandableSide" fld public final static java.lang.String SPLIT_PANE_EXPANDABLE_SIDE_LEFT = "left" fld public final static java.lang.String SPLIT_PANE_EXPANDABLE_SIDE_RIGHT = "right" @@ -107,6 +109,7 @@ fld public final static java.lang.String TITLE_BAR_SHOW_ICONIFFY = "JRootPane.ti fld public final static java.lang.String TITLE_BAR_SHOW_MAXIMIZE = "JRootPane.titleBarShowMaximize" fld public final static java.lang.String TITLE_BAR_SHOW_TITLE = "JRootPane.titleBarShowTitle" fld public final static java.lang.String TREE_PAINT_SELECTION = "JTree.paintSelection" +fld public final static java.lang.String TREE_WIDE_CELL_RENDERER = "JTree.wideCellRenderer" fld public final static java.lang.String TREE_WIDE_SELECTION = "JTree.wideSelection" fld public final static java.lang.String USE_WINDOW_DECORATIONS = "JRootPane.useWindowDecorations" fld public final static java.lang.String WINDOW_STYLE = "Window.style" @@ -220,8 +223,11 @@ meth public static java.lang.String getPreferredFontFamily() meth public static java.lang.String getPreferredLightFontFamily() meth public static java.lang.String getPreferredMonospacedFontFamily() meth public static java.lang.String getPreferredSemiboldFontFamily() +meth public static java.lang.String getUIKeyLightOrDarkPrefix(boolean) meth public static java.util.Map> getStyleableInfos(javax.swing.JComponent) meth public static java.util.Map getGlobalExtraDefaults() +meth public static java.util.Set getUIKeyPlatformPrefixes() +meth public static java.util.Set getUIKeySpecialPrefixes() meth public static java.util.function.Function getSystemColorGetter() meth public static javax.swing.UIDefaults$ActiveValue createActiveFontValue(float) meth public static void disableWindowsD3Donscreen() @@ -255,7 +261,7 @@ meth public void setExtraDefaults(java.util.Map) supr javax.swing.plaf.basic.BasicLookAndFeel -hfds DESKTOPFONTHINTS,aquaLoaded,customDefaultsSources,desktopPropertyListener,desktopPropertyName,desktopPropertyName2,extraDefaults,globalExtraDefaults,mnemonicHandler,oldPopupFactory,postInitialization,preferredFontFamily,preferredLightFontFamily,preferredMonospacedFontFamily,preferredSemiboldFontFamily,subMenuUsabilityHelperInstalled,systemColorGetter,uiDefaultsGetters,updateUIPending +hfds DESKTOPFONTHINTS,aquaLoaded,customDefaultsSources,desktopPropertyListener,desktopPropertyName,desktopPropertyName2,extraDefaults,globalExtraDefaults,linuxPopupMenuCanceler,mnemonicHandler,oldPopupFactory,postInitialization,preferredFontFamily,preferredLightFontFamily,preferredMonospacedFontFamily,preferredSemiboldFontFamily,subMenuUsabilityHelperInstalled,systemColorGetter,uiDefaultsGetters,uiKeyPlatformPrefixes,uiKeySpecialPrefixes,updateUIPending hcls ActiveFont,FlatUIDefaults,ImageIconUIResource CLSS public abstract interface static com.formdev.flatlaf.FlatLaf$DisabledIconProvider @@ -318,7 +324,7 @@ meth public static boolean setup(java.io.InputStream) meth public static com.formdev.flatlaf.FlatLaf createLaf(com.formdev.flatlaf.IntelliJTheme) meth public static com.formdev.flatlaf.FlatLaf createLaf(java.io.InputStream) throws java.io.IOException supr java.lang.Object -hfds checkboxDuplicateColors,checkboxKeyMapping,colors,icons,isMaterialUILite,namedColors,ui,uiKeyCopying,uiKeyDoNotOverride,uiKeyExcludes,uiKeyInverseMapping,uiKeyMapping +hfds checkboxDuplicateColors,checkboxKeyMapping,jsonColors,jsonIcons,jsonUI,namedColors,uiKeyCopying,uiKeyDoNotOverride,uiKeyExcludes,uiKeyInverseMapping,uiKeyMapping CLSS public static com.formdev.flatlaf.IntelliJTheme$ThemeLaf outer com.formdev.flatlaf.IntelliJTheme @@ -413,6 +419,7 @@ innr public static Fade innr public static HSLChange innr public static HSLIncreaseDecrease innr public static Mix +innr public static Mix2 meth public !varargs static java.awt.Color applyFunctions(java.awt.Color,com.formdev.flatlaf.util.ColorFunctions$ColorFunction[]) meth public static float clamp(float) meth public static float luma(java.awt.Color) @@ -474,6 +481,16 @@ meth public java.lang.String toString() meth public void apply(float[]) supr java.lang.Object +CLSS public static com.formdev.flatlaf.util.ColorFunctions$Mix2 + outer com.formdev.flatlaf.util.ColorFunctions +cons public init(java.awt.Color,float) +fld public final float weight +fld public final java.awt.Color color1 +intf com.formdev.flatlaf.util.ColorFunctions$ColorFunction +meth public java.lang.String toString() +meth public void apply(float[]) +supr java.lang.Object + CLSS public com.formdev.flatlaf.util.CubicBezierEasing cons public init(float,float,float,float) fld public final static com.formdev.flatlaf.util.CubicBezierEasing EASE @@ -755,6 +772,7 @@ supr java.lang.Object CLSS public com.formdev.flatlaf.util.SystemInfo cons public init() fld public final static boolean isAARCH64 +fld public final static boolean isGNOME fld public final static boolean isJava_11_orLater fld public final static boolean isJava_12_orLater fld public final static boolean isJava_15_orLater @@ -771,6 +789,7 @@ fld public final static boolean isMacOS_10_11_ElCapitan_orLater fld public final static boolean isMacOS_10_14_Mojave_orLater fld public final static boolean isMacOS_10_15_Catalina_orLater fld public final static boolean isProjector +fld public final static boolean isUnknownOS fld public final static boolean isWebswing fld public final static boolean isWinPE fld public final static boolean isWindows diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java index 2625294f..e26b7ec3 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java @@ -21,6 +21,8 @@ import java.awt.IllegalComponentStateException; import java.awt.Window; import java.util.Objects; import javax.swing.JComponent; +import javax.swing.JFormattedTextField; +import javax.swing.JSpinner; import javax.swing.SwingConstants; /** @@ -1209,12 +1211,15 @@ public interface FlatClientProperties /** * Specifies whether all text is selected when the text component gains focus. *

- * Component {@link javax.swing.JTextField} (and subclasses)
+ * Components {@link javax.swing.text.JTextComponent} (and subclasses), + * {@link javax.swing.JComboBox} (since 3.6) and {@link javax.swing.JSpinner} (since 3.6)
* Value type {@link java.lang.String}
* Allowed Values * {@link #SELECT_ALL_ON_FOCUS_POLICY_NEVER}, * {@link #SELECT_ALL_ON_FOCUS_POLICY_ONCE} (default) or * {@link #SELECT_ALL_ON_FOCUS_POLICY_ALWAYS} + * + * @see #SELECT_ALL_ON_MOUSE_CLICK */ String SELECT_ALL_ON_FOCUS_POLICY = "JTextField.selectAllOnFocusPolicy"; @@ -1229,6 +1234,12 @@ public interface FlatClientProperties * Select all text when the text component gains focus for the first time * and selection was not modified (is at end of text). * This is the default. + *

+ * Limitations: + * For {@link JFormattedTextField} and {@link JSpinner} this behaves + * as {@link #SELECT_ALL_ON_FOCUS_POLICY_ALWAYS}. + * This is because of special behavior of {@link JFormattedTextField} + * that did not allow implementation of {@code "once"}. * * @see #SELECT_ALL_ON_FOCUS_POLICY */ @@ -1241,6 +1252,19 @@ public interface FlatClientProperties */ String SELECT_ALL_ON_FOCUS_POLICY_ALWAYS = "always"; + /** + * Specifies whether all text is selected when when clicking with the mouse + * into the text field (and if "select all on focus" policy is enabled). + *

+ * Components {@link javax.swing.text.JTextComponent} (and subclasses), + * {@link javax.swing.JComboBox} and {@link javax.swing.JSpinner}
+ * Value type {@link java.lang.Boolean} + * + * @see #SELECT_ALL_ON_FOCUS_POLICY + * @since 3.6 + */ + String SELECT_ALL_ON_MOUSE_CLICK = "JTextField.selectAllOnMouseClick"; + /** * Placeholder text that is only painted if the text field is empty. *

diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/IntelliJTheme.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/IntelliJTheme.java index 8992328d..21874425 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/IntelliJTheme.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/IntelliJTheme.java @@ -413,22 +413,37 @@ public class IntelliJTheme key.equals( "Tree.rightChildIndent" ) ) return; // ignore + // ignore icons + if( key.endsWith( "Icon" ) ) + return; // ignore + // map keys key = uiKeyMapping.getOrDefault( key, key ); if( key.isEmpty() ) return; // ignore key - // exclude properties + // exclude properties (1st level) int dot = key.indexOf( '.' ); - if( dot > 0 && uiKeyExcludes.contains( key.substring( 0, dot + 1 ) ) ) + if( dot > 0 && uiKeyExcludesStartsWith.contains( key.substring( 0, dot + 1 ) ) ) return; + // exclude properties (2st level) + int dot2 = (dot > 0) ? key.indexOf( '.', dot + 1 ) : -1; + if( dot2 > 0 && uiKeyExcludesStartsWith.contains( key.substring( 0, dot2 + 1 ) ) ) + return; + + // exclude properties (contains) + for( String s : uiKeyExcludesContains ) { + if( key.contains( s ) ) + return; + } + if( uiKeyDoNotOverride.contains( key ) && jsonUIKeys.contains( key ) ) return; jsonUIKeys.add( key ); - String valueStr = value.toString(); + String valueStr = value.toString().trim(); // map named colors String uiValue = namedColors.get( valueStr ); @@ -657,7 +672,8 @@ public class IntelliJTheme } } - private static final Set uiKeyExcludes; + private static final Set uiKeyExcludesStartsWith; + private static final String[] uiKeyExcludesContains; private static final Set uiKeyDoNotOverride; /** Rename UI default keys (key --> value). */ private static final Map uiKeyMapping = new HashMap<>(); @@ -669,7 +685,7 @@ public class IntelliJTheme static { // IntelliJ UI properties that are not used in FlatLaf - uiKeyExcludes = new HashSet<>( Arrays.asList( + uiKeyExcludesStartsWith = new HashSet<>( Arrays.asList( "ActionButton.", "ActionToolbar.", "ActionsList.", "AppInspector.", "AssignedMnemonic.", "Autocomplete.", "AvailableMnemonic.", "Badge.", "Banner.", "BigSpinner.", "Bookmark.", "BookmarkIcon.", "BookmarkMnemonicAssigned.", "BookmarkMnemonicAvailable.", @@ -703,14 +719,24 @@ public class IntelliJTheme // possible typos in .theme.json files "Checkbox.", "Toolbar.", "Tooltip.", "UiDesigner.", "link." ) ); + uiKeyExcludesContains = new String[] { + ".darcula." + }; uiKeyDoNotOverride = new HashSet<>( Arrays.asList( "TabbedPane.selectedForeground" ) ); + // "*." + uiKeyMapping.put( "*.fontFace", "" ); // ignore (used in OnePauintxi themes) + uiKeyMapping.put( "*.fontSize", "" ); // ignore (used in OnePauintxi themes) + // Button uiKeyMapping.put( "Button.minimumSize", "" ); // ignore (used in Material Theme UI Lite) + // CheckBox.iconSize + uiKeyMapping.put( "CheckBox.iconSize", "" ); // ignore (used in Rider themes) + // ComboBox uiKeyMapping.put( "ComboBox.background", "" ); // ignore uiKeyMapping.put( "ComboBox.buttonBackground", "" ); // ignore @@ -751,6 +777,9 @@ public class IntelliJTheme uiKeyMapping.put( "ProgressBar.trackColor", "ProgressBar.background" ); uiKeyMapping.put( "ProgressBar.progressColor", "ProgressBar.foreground" ); + // RadioButton + uiKeyMapping.put( "RadioButton.iconSize", "" ); // ignore (used in Rider themes) + // ScrollBar uiKeyMapping.put( "ScrollBar.trackColor", "ScrollBar.track" ); uiKeyMapping.put( "ScrollBar.thumbColor", "ScrollBar.thumb" ); diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/UIDefaultsLoader.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/UIDefaultsLoader.java index 81a58196..a2e614ec 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/UIDefaultsLoader.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/UIDefaultsLoader.java @@ -649,22 +649,26 @@ class UIDefaultsLoader if( value.indexOf( ',' ) >= 0 ) { // Syntax: top,left,bottom,right[,lineColor[,lineThickness[,arc]]] List parts = splitFunctionParams( value, ',' ); - Insets insets = parseInsets( value ); - ColorUIResource lineColor = (parts.size() >= 5 && !parts.get( 4 ).isEmpty()) - ? (ColorUIResource) parseColorOrFunction( resolver.apply( parts.get( 4 ) ), resolver ) - : null; - float lineThickness = (parts.size() >= 6 && !parts.get( 5 ).isEmpty()) - ? parseFloat( parts.get( 5 ) ) - : 1f; - int arc = (parts.size() >= 7) && !parts.get( 6 ).isEmpty() - ? parseInteger( parts.get( 6 ) ) - : -1; + try { + Insets insets = parseInsets( value ); + ColorUIResource lineColor = (parts.size() >= 5 && !parts.get( 4 ).isEmpty()) + ? (ColorUIResource) parseColorOrFunction( resolver.apply( parts.get( 4 ) ), resolver ) + : null; + float lineThickness = (parts.size() >= 6 && !parts.get( 5 ).isEmpty()) + ? parseFloat( parts.get( 5 ) ) + : 1f; + int arc = (parts.size() >= 7) && !parts.get( 6 ).isEmpty() + ? parseInteger( parts.get( 6 ) ) + : -1; - return (LazyValue) t -> { - return (lineColor != null || arc > 0) - ? new FlatLineBorder( insets, lineColor, lineThickness, arc ) - : new FlatEmptyBorder( insets ); - }; + return (LazyValue) t -> { + return (lineColor != null || arc > 0) + ? new FlatLineBorder( insets, lineColor, lineThickness, arc ) + : new FlatEmptyBorder( insets ); + }; + } catch( RuntimeException ex ) { + throw new IllegalArgumentException( "invalid border '" + value + "' (" + ex.getMessage() + ")" ); + } } else return parseInstance( value, resolver, addonClassLoaders ); } @@ -735,7 +739,7 @@ class UIDefaultsLoader Integer.parseInt( numbers.get( 1 ) ), Integer.parseInt( numbers.get( 2 ) ), Integer.parseInt( numbers.get( 3 ) ) ); - } catch( NumberFormatException ex ) { + } catch( NumberFormatException | IndexOutOfBoundsException ex ) { throw new IllegalArgumentException( "invalid insets '" + value + "'" ); } } @@ -748,7 +752,7 @@ class UIDefaultsLoader return new DimensionUIResource( Integer.parseInt( numbers.get( 0 ) ), Integer.parseInt( numbers.get( 1 ) ) ); - } catch( NumberFormatException ex ) { + } catch( NumberFormatException | IndexOutOfBoundsException ex ) { throw new IllegalArgumentException( "invalid size '" + value + "'" ); } } @@ -1379,17 +1383,17 @@ class UIDefaultsLoader break; } } - } catch( IOException ex ) { - throw new IllegalArgumentException( ex ); + } catch( RuntimeException | IOException ex ) { + throw new IllegalArgumentException( "invalid font '" + value + "' (" + ex.getMessage() + ")" ); } if( style != -1 && styleChange != 0 ) - throw new IllegalArgumentException( "can not mix absolute style (e.g. 'bold') with derived style (e.g. '+italic') in '" + value + "'" ); + throw new IllegalArgumentException( "invalid font '" + value + "': can not mix absolute style (e.g. 'bold') with derived style (e.g. '+italic')" ); if( styleChange != 0 ) { if( (styleChange & Font.BOLD) != 0 && (styleChange & (Font.BOLD << 16)) != 0 ) - throw new IllegalArgumentException( "can not use '+bold' and '-bold' in '" + value + "'" ); + throw new IllegalArgumentException( "invalid font '" + value + "': can not use '+bold' and '-bold'" ); if( (styleChange & Font.ITALIC) != 0 && (styleChange & (Font.ITALIC << 16)) != 0 ) - throw new IllegalArgumentException( "can not use '+italic' and '-italic' in '" + value + "'" ); + throw new IllegalArgumentException( "invalid font '" + value + "': can not use '+italic' and '-italic'" ); } font = new FlatLaf.ActiveFont( baseFontKey, families, style, styleChange, absoluteSize, relativeSize, scaleSize ); @@ -1529,7 +1533,7 @@ class UIDefaultsLoader return (LazyValue) t -> { return new GrayFilter( brightness, contrast, alpha ); }; - } catch( NumberFormatException ex ) { + } catch( NumberFormatException | IndexOutOfBoundsException ex ) { throw new IllegalArgumentException( "invalid gray filter '" + value + "'" ); } } diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatCaret.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatCaret.java index e301961e..0edf010b 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatCaret.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatCaret.java @@ -17,6 +17,7 @@ package com.formdev.flatlaf.ui; import static com.formdev.flatlaf.FlatClientProperties.*; +import java.awt.Container; import java.awt.EventQueue; import java.awt.Rectangle; import java.awt.event.ActionEvent; @@ -24,7 +25,9 @@ import java.awt.event.FocusEvent; import java.awt.event.MouseEvent; import javax.swing.Action; import javax.swing.ActionMap; +import javax.swing.JComboBox; import javax.swing.JFormattedTextField; +import javax.swing.JSpinner; import javax.swing.SwingUtilities; import javax.swing.UIManager; import javax.swing.plaf.UIResource; @@ -33,6 +36,7 @@ import javax.swing.text.DefaultCaret; import javax.swing.text.DefaultEditorKit; import javax.swing.text.Document; import javax.swing.text.JTextComponent; +import javax.swing.text.Position; import javax.swing.text.Utilities; /** @@ -48,12 +52,15 @@ public class FlatCaret { private static final String KEY_CARET_INFO = "FlatLaf.internal.caretInfo"; + // selectAllOnFocusPolicy + private static final int NEVER = 0, ONCE = 1, ALWAYS = 2; + private final String selectAllOnFocusPolicy; private final boolean selectAllOnMouseClick; private boolean inInstall; private boolean wasFocused; - private boolean wasTemporaryLost; + private boolean wasFocusTemporaryLost; private boolean isMousePressed; private boolean isWordSelection; private boolean isLineSelection; @@ -94,6 +101,9 @@ public class FlatCaret // restore selection select( (int) ci[1], (int) ci[0] ); + if( ci[4] != 0 ) + wasFocused = true; + // if text component is focused, then caret and selection are visible, // but when switching theme, the component does not yet have // a highlighter and the selection is not painted @@ -121,6 +131,7 @@ public class FlatCaret getMark(), getBlinkRate(), System.currentTimeMillis(), + wasFocused ? 1 : 0, } ); super.deinstall( c ); @@ -140,11 +151,36 @@ public class FlatCaret super.adjustVisibility( nloc ); } + @Override + public void setDot( int dot ) { + super.setDot( dot ); + + // mark as focused if invoked from JTextComponent.setCaretPosition() + // to disable SELECT_ALL_ON_FOCUS_POLICY_ONCE if application explicitly changes selection + if( !wasFocused && + getSelectAllOnFocusPolicy() == ONCE && + StackUtils.wasInvokedFrom( JTextComponent.class.getName(), "setCaretPosition", 6 ) ) + wasFocused = true; + } + + @Override + public void moveDot( int dot ) { + super.moveDot( dot ); + + // mark as focused if invoked from JTextComponent.moveCaretPosition() + // to disable SELECT_ALL_ON_FOCUS_POLICY_ONCE if application explicitly changes selection + if( !wasFocused && + getSelectAllOnFocusPolicy() == ONCE && + StackUtils.wasInvokedFrom( JTextComponent.class.getName(), "moveCaretPosition", 6 ) ) + wasFocused = true; + } + @Override public void focusGained( FocusEvent e ) { - if( !inInstall && !wasTemporaryLost && (!isMousePressed || selectAllOnMouseClick) ) + if( !inInstall && !wasFocusTemporaryLost && (!isMousePressed || isSelectAllOnMouseClick()) ) selectAllOnFocusGained(); - wasTemporaryLost = false; + + wasFocusTemporaryLost = false; wasFocused = true; super.focusGained( e ); @@ -152,7 +188,7 @@ public class FlatCaret @Override public void focusLost( FocusEvent e ) { - wasTemporaryLost = e.isTemporary(); + wasFocusTemporaryLost = e.isTemporary(); super.focusLost( e ); } @@ -232,24 +268,13 @@ public class FlatCaret if( doc == null || !c.isEnabled() || !c.isEditable() || FlatUIUtils.isCellEditor( c ) ) return; - Object selectAllOnFocusPolicy = c.getClientProperty( SELECT_ALL_ON_FOCUS_POLICY ); - if( selectAllOnFocusPolicy == null ) - selectAllOnFocusPolicy = this.selectAllOnFocusPolicy; - - if( selectAllOnFocusPolicy == null || SELECT_ALL_ON_FOCUS_POLICY_NEVER.equals( selectAllOnFocusPolicy ) ) + int selectAllOnFocusPolicy = getSelectAllOnFocusPolicy(); + if( selectAllOnFocusPolicy == NEVER ) return; - if( !SELECT_ALL_ON_FOCUS_POLICY_ALWAYS.equals( selectAllOnFocusPolicy ) ) { - // policy is "once" (or null or unknown) - + if( selectAllOnFocusPolicy == ONCE && !isMousePressed ) { // was already focused? - if( wasFocused ) - return; - - // check whether selection was modified before gaining focus - int dot = getDot(); - int mark = getMark(); - if( dot != mark || dot != doc.getLength() ) + if( wasFocused && !(c instanceof JFormattedTextField) ) return; } @@ -265,16 +290,51 @@ public class FlatCaret select( 0, c2.getDocument().getLength() ); } ); - } else { + } else select( 0, doc.getLength() ); - } } private void select( int mark, int dot ) { if( mark != getMark() ) - setDot( mark ); + setDot( mark, Position.Bias.Forward ); if( dot != getDot() ) - moveDot( dot ); + moveDot( dot, Position.Bias.Forward ); + } + + private int getSelectAllOnFocusPolicy() { + Object value = getClientProperty( SELECT_ALL_ON_FOCUS_POLICY ); + // Note: using String.valueOf() because selectAllOnFocusPolicy may be null + switch( String.valueOf( value instanceof String ? value : selectAllOnFocusPolicy ) ) { + default: + case SELECT_ALL_ON_FOCUS_POLICY_NEVER: return NEVER; + case SELECT_ALL_ON_FOCUS_POLICY_ONCE: return ONCE; + case SELECT_ALL_ON_FOCUS_POLICY_ALWAYS: return ALWAYS; + } + } + + private boolean isSelectAllOnMouseClick() { + Object value = getClientProperty( SELECT_ALL_ON_MOUSE_CLICK ); + return (value instanceof Boolean) ? (boolean) value : selectAllOnMouseClick; + } + + private Object getClientProperty( String key ) { + JTextComponent c = getComponent(); + if( c == null ) + return null; + + Object value = c.getClientProperty( key ); + if( value != null ) + return value; + + Container parent = c.getParent(); + if( parent instanceof JComboBox ) + return ((JComboBox)parent).getClientProperty( key ); + if( parent instanceof JSpinner.DefaultEditor ) { + parent = parent.getParent(); + if( parent instanceof JSpinner ) + return ((JSpinner)parent).getClientProperty( key ); + } + return null; } /** @since 1.4 */ diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatComboBoxUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatComboBoxUI.java index 05a4973a..2f135bca 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatComboBoxUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatComboBoxUI.java @@ -882,7 +882,7 @@ public class FlatComboBoxUI GraphicsConfiguration gc = comboBox.getGraphicsConfiguration(); if( gc != null ) { Rectangle screenBounds = gc.getBounds(); - Insets screenInsets = Toolkit.getDefaultToolkit().getScreenInsets( gc ); + Insets screenInsets = FlatUIUtils.getScreenInsets( gc ); displayWidth = Math.min( displayWidth, screenBounds.width - screenInsets.left - screenInsets.right ); } else { Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatPopupFactory.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatPopupFactory.java index 553695d8..a1fdaa6f 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatPopupFactory.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatPopupFactory.java @@ -32,7 +32,6 @@ import java.awt.Panel; import java.awt.Point; import java.awt.PointerInfo; import java.awt.Rectangle; -import java.awt.Toolkit; import java.awt.Window; import java.awt.event.ComponentEvent; import java.awt.event.ComponentListener; @@ -312,7 +311,7 @@ public class FlatPopupFactory return null; Rectangle screenBounds = gc.getBounds(); - Insets screenInsets = Toolkit.getDefaultToolkit().getScreenInsets( gc ); + Insets screenInsets = FlatUIUtils.getScreenInsets( gc ); int screenTop = screenBounds.y + screenInsets.top; // place tooltip above mouse location if there is enough space diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatPopupMenuUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatPopupMenuUI.java index 69fc6ec4..42e0670a 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatPopupMenuUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatPopupMenuUI.java @@ -246,7 +246,7 @@ public class FlatPopupMenuUI // (always subtract screen insets because there is no API to detect whether // the popup can overlap the taskbar; see JPopupMenu.canPopupOverlapTaskBar()) Rectangle screenBounds = gc.getBounds(); - Insets screenInsets = Toolkit.getDefaultToolkit().getScreenInsets( gc ); + Insets screenInsets = FlatUIUtils.getScreenInsets( gc ); return FlatUIUtils.subtractInsets( screenBounds, screenInsets ); } diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTitlePane.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTitlePane.java index 369332e7..9d689991 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTitlePane.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTitlePane.java @@ -914,7 +914,7 @@ public class FlatTitlePane // screen insets are in physical size, except for Java 15+ // (see https://bugs.openjdk.java.net/browse/JDK-8243925) // and except for Java 8 on secondary screens where primary screen is scaled - Insets screenInsets = window.getToolkit().getScreenInsets( gc ); + Insets screenInsets = FlatUIUtils.getScreenInsets( gc ); // maximized bounds are required in physical size, except for Java 15+ // (see https://bugs.openjdk.java.net/browse/JDK-8231564 and diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatUIUtils.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatUIUtils.java index 706e4546..08c74d19 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatUIUtils.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatUIUtils.java @@ -26,6 +26,7 @@ import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; import java.awt.Insets; import java.awt.KeyboardFocusManager; import java.awt.Paint; @@ -34,6 +35,7 @@ import java.awt.RenderingHints; import java.awt.Shape; import java.awt.Stroke; import java.awt.SystemColor; +import java.awt.Toolkit; import java.awt.Window; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; @@ -414,6 +416,17 @@ public class FlatUIUtils return (fullScreenWindow != null && fullScreenWindow == SwingUtilities.windowForComponent( c )); } + /** @since 3.7 */ + public static Insets getScreenInsets( GraphicsConfiguration gc ) { + // on Linux, getScreenInsets() may report wrong values in multi-screen setups + // see https://github.com/apache/netbeans/issues/8532#issuecomment-2909687016 + if( SystemInfo.isLinux && + GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices().length > 1 ) + return new Insets( 0, 0, 0, 0 ); + + return Toolkit.getDefaultToolkit().getScreenInsets( gc ); + } + public static Boolean isRoundRect( Component c ) { return (c instanceof JComponent) ? FlatClientProperties.clientPropertyBooleanStrict( diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatWindowResizer.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatWindowResizer.java index c63ac409..42e9d96e 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatWindowResizer.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatWindowResizer.java @@ -331,7 +331,7 @@ public abstract class FlatWindowResizer protected Rectangle getParentBounds() { GraphicsConfiguration gc = window.getGraphicsConfiguration(); Rectangle bounds = gc.getBounds(); - Insets insets = window.getToolkit().getScreenInsets( gc ); + Insets insets = FlatUIUtils.getScreenInsets( gc ); return new Rectangle( bounds.x + insets.left, bounds.y + insets.top, bounds.width - insets.left - insets.right, bounds.height - insets.top - insets.bottom ); diff --git a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatDarkLaf.properties b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatDarkLaf.properties index 1eda0de3..04f5db56 100644 --- a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatDarkLaf.properties +++ b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatDarkLaf.properties @@ -276,7 +276,7 @@ RootPane.inactiveBorderColor = lighten(@background,5%,derived) #---- ScrollBar ---- ScrollBar.track = lighten(@background,1%,derived noAutoInverse) -ScrollBar.thumb = lighten($ScrollBar.track,10%,derived noAutoInverse) +ScrollBar.thumb = lighten($ScrollBar.track,15%,derived noAutoInverse) ScrollBar.hoverTrackColor = lighten($ScrollBar.track,4%,derived noAutoInverse) ScrollBar.hoverThumbColor = lighten($ScrollBar.thumb,10%,derived noAutoInverse) ScrollBar.pressedThumbColor = lighten($ScrollBar.thumb,15%,derived noAutoInverse) diff --git a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties index ec2dbdaa..368562b1 100644 --- a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties +++ b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties @@ -574,12 +574,12 @@ RootPane.honorDialogMinimumSizeOnResize = true ScrollBar.width = 10 ScrollBar.minimumButtonSize = 12,12 -ScrollBar.minimumThumbSize = 10,10 +ScrollBar.minimumThumbSize = 18,18 ScrollBar.maximumThumbSize = 100000,100000 ScrollBar.trackInsets = 0,0,0,0 -ScrollBar.thumbInsets = 0,0,0,0 +ScrollBar.thumbInsets = 2,2,2,2 ScrollBar.trackArc = 0 -ScrollBar.thumbArc = 0 +ScrollBar.thumbArc = 999 ScrollBar.hoverThumbWithTrack = false ScrollBar.pressedThumbWithTrack = false ScrollBar.showButtons = false @@ -588,15 +588,8 @@ ScrollBar.buttonArrowColor = @buttonArrowColor ScrollBar.buttonDisabledArrowColor = @buttonDisabledArrowColor ScrollBar.allowsAbsolutePositioning = true -[mac]ScrollBar.minimumThumbSize = 18,18 -[mac]ScrollBar.thumbInsets = 2,2,2,2 -[mac]ScrollBar.thumbArc = 999 [mac]ScrollBar.hoverThumbWithTrack = true -[linux]ScrollBar.minimumThumbSize = 18,18 -[linux]ScrollBar.thumbInsets = 2,2,2,2 -[linux]ScrollBar.thumbArc = 999 - #---- ScrollPane ---- diff --git a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLightLaf.properties b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLightLaf.properties index a9165856..f6223208 100644 --- a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLightLaf.properties +++ b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLightLaf.properties @@ -282,7 +282,7 @@ RootPane.inactiveBorderColor = darken(@background,30%,derived) #---- ScrollBar ---- ScrollBar.track = lighten(@background,1%,derived noAutoInverse) -ScrollBar.thumb = darken($ScrollBar.track,10%,derived noAutoInverse) +ScrollBar.thumb = darken($ScrollBar.track,15%,derived noAutoInverse) ScrollBar.hoverTrackColor = darken($ScrollBar.track,3%,derived noAutoInverse) ScrollBar.hoverThumbColor = darken($ScrollBar.thumb,10%,derived noAutoInverse) ScrollBar.pressedThumbColor = darken($ScrollBar.thumb,20%,derived noAutoInverse) diff --git a/flatlaf-core/src/main/resources/com/formdev/flatlaf/themes/FlatMacDarkLaf.properties b/flatlaf-core/src/main/resources/com/formdev/flatlaf/themes/FlatMacDarkLaf.properties index 02ed6b34..226fecd1 100644 --- a/flatlaf-core/src/main/resources/com/formdev/flatlaf/themes/FlatMacDarkLaf.properties +++ b/flatlaf-core/src/main/resources/com/formdev/flatlaf/themes/FlatMacDarkLaf.properties @@ -184,6 +184,7 @@ MenuBar.selectionEmbeddedInsets = 3,0,3,0 MenuBar.selectionArc = 8 MenuBar.selectionBackground = lighten(@menuBackground,15%,derived) MenuBar.selectionForeground = @foreground +MenuBar.borderColor = over($Separator.foreground,$MenuBar.background) #---- MenuItem ---- diff --git a/flatlaf-core/src/main/resources/com/formdev/flatlaf/themes/FlatMacLightLaf.properties b/flatlaf-core/src/main/resources/com/formdev/flatlaf/themes/FlatMacLightLaf.properties index d18eb106..b37d2131 100644 --- a/flatlaf-core/src/main/resources/com/formdev/flatlaf/themes/FlatMacLightLaf.properties +++ b/flatlaf-core/src/main/resources/com/formdev/flatlaf/themes/FlatMacLightLaf.properties @@ -184,6 +184,7 @@ MenuBar.selectionEmbeddedInsets = 3,0,3,0 MenuBar.selectionArc = 8 MenuBar.selectionBackground = darken(@menuBackground,15%,derived) MenuBar.selectionForeground = @foreground +MenuBar.borderColor = over($Separator.foreground,$MenuBar.background) #---- MenuItem ---- diff --git a/flatlaf-core/src/test/java/com/formdev/flatlaf/TestUIDefaultsLoader.java b/flatlaf-core/src/test/java/com/formdev/flatlaf/TestUIDefaultsLoader.java index 28c36c89..da9f52e9 100644 --- a/flatlaf-core/src/test/java/com/formdev/flatlaf/TestUIDefaultsLoader.java +++ b/flatlaf-core/src/test/java/com/formdev/flatlaf/TestUIDefaultsLoader.java @@ -18,6 +18,7 @@ package com.formdev.flatlaf; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.junit.jupiter.api.Assertions.assertThrowsExactly; import static org.junit.jupiter.api.Assertions.assertTrue; import java.awt.Color; import java.awt.Dimension; @@ -29,6 +30,7 @@ import javax.swing.border.Border; import javax.swing.UIDefaults.ActiveValue; import javax.swing.UIDefaults.LazyValue; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.function.Executable; import com.formdev.flatlaf.ui.FlatEmptyBorder; import com.formdev.flatlaf.ui.FlatLineBorder; import com.formdev.flatlaf.util.DerivedColor; @@ -452,6 +454,73 @@ public class TestUIDefaultsLoader return ((LazyValue)v).createValue( null ); } + //---- invalid values ----------------------------------------------------- + + @Test + void parseInvalidValue() { + assertThrows( new IllegalArgumentException( "invalid character 'abc'" ), () -> UIDefaultsLoader.parseValue( "dummyChar", "abc", null ) ); + assertThrows( new NumberFormatException( "invalid integer or float '123abc'" ), () -> UIDefaultsLoader.parseValue( "dummyWidth", "123abc", null ) ); + assertThrows( new NumberFormatException( "invalid integer or float '1.23abc'" ), () -> UIDefaultsLoader.parseValue( "dummyWidth", "1.23abc", null ) ); + + assertThrows( new IllegalArgumentException( "invalid insets '1,abc,3,4'" ), () -> UIDefaultsLoader.parseValue( "dummyInsets", "1,abc,3,4", null ) ); + assertThrows( new IllegalArgumentException( "invalid insets '1,2,3'" ), () -> UIDefaultsLoader.parseValue( "dummyInsets", "1,2,3", null ) ); + assertThrows( new IllegalArgumentException( "invalid size '1abc'" ), () -> UIDefaultsLoader.parseValue( "dummySize", "1abc", null ) ); + assertThrows( new IllegalArgumentException( "invalid size '1'" ), () -> UIDefaultsLoader.parseValue( "dummySize", "1", null ) ); + assertThrows( new IllegalArgumentException( "invalid color '#f0'" ), () -> UIDefaultsLoader.parseValue( "dummy", "#f0", null ) ); + assertThrows( new IllegalArgumentException( "invalid color '#f0'" ), () -> UIDefaultsLoader.parseValue( "dummyColor", "#f0", null ) ); + } + + @Test + void parseInvalidValueWithJavaType() { + assertThrows( new IllegalArgumentException( "invalid boolean 'falseyy'" ), () -> UIDefaultsLoader.parseValue( "dummy", "falseyy", boolean.class ) ); + assertThrows( new IllegalArgumentException( "invalid boolean 'falseyy'" ), () -> UIDefaultsLoader.parseValue( "dummy", "falseyy", Boolean.class ) ); + + assertThrows( new IllegalArgumentException( "invalid character 'abc'" ), () -> UIDefaultsLoader.parseValue( "dummyChar", "abc", char.class ) ); + assertThrows( new IllegalArgumentException( "invalid character 'abc'" ), () -> UIDefaultsLoader.parseValue( "dummyChar", "abc", Character.class ) ); + assertThrows( new NumberFormatException( "invalid integer '123abc'" ), () -> UIDefaultsLoader.parseValue( "dummyWidth", "123abc", int.class ) ); + assertThrows( new NumberFormatException( "invalid integer '123abc'" ), () -> UIDefaultsLoader.parseValue( "dummyWidth", "123abc", Integer.class ) ); + assertThrows( new NumberFormatException( "invalid float '1.23abc'" ), () -> UIDefaultsLoader.parseValue( "dummyWidth", "1.23abc", float.class ) ); + assertThrows( new NumberFormatException( "invalid float '1.23abc'" ), () -> UIDefaultsLoader.parseValue( "dummyWidth", "1.23abc", Float.class ) ); + + assertThrows( new IllegalArgumentException( "invalid insets '1,abc,3'" ), () -> UIDefaultsLoader.parseValue( "dummyInsets", "1,abc,3", Insets.class ) ); + assertThrows( new IllegalArgumentException( "invalid insets '1,2,3'" ), () -> UIDefaultsLoader.parseValue( "dummyInsets", "1,2,3", Insets.class ) ); + assertThrows( new IllegalArgumentException( "invalid size '1abc'" ), () -> UIDefaultsLoader.parseValue( "dummySize", "1abc", Dimension.class ) ); + assertThrows( new IllegalArgumentException( "invalid size '1'" ), () -> UIDefaultsLoader.parseValue( "dummySize", "1", Dimension.class ) ); + assertThrows( new IllegalArgumentException( "invalid color '#f0'" ), () -> UIDefaultsLoader.parseValue( "dummy", "#f0", Color.class ) ); + assertThrows( new IllegalArgumentException( "invalid color '#f0'" ), () -> UIDefaultsLoader.parseValue( "dummyColor", "#f0", Color.class ) ); + } + + @Test + void parseInvalidBorders() { + assertThrows( new IllegalArgumentException( "invalid border '1,abc,3,4' (invalid insets '1,abc,3,4')" ), () -> UIDefaultsLoader.parseValue( "dummyBorder", "1,abc,3,4", null ) ); + assertThrows( new IllegalArgumentException( "invalid border '1,2,3' (invalid insets '1,2,3')" ), () -> UIDefaultsLoader.parseValue( "dummyBorder", "1,2,3", null ) ); + assertThrows( new IllegalArgumentException( "invalid border '1,2,3,,,' (invalid insets '1,2,3,,,')" ), () -> UIDefaultsLoader.parseValue( "dummyBorder", "1,2,3,,,", null ) ); + assertThrows( new IllegalArgumentException( "invalid border '1,2,3,4,#f0' (invalid color '#f0')" ), () -> UIDefaultsLoader.parseValue( "dummyBorder", "1,2,3,4,#f0", null ) ); + assertThrows( new IllegalArgumentException( "invalid border '1,2,3,4,#f00,2.5abc' (invalid float '2.5abc')" ), () -> UIDefaultsLoader.parseValue( "dummyBorder", "1,2,3,4,#f00,2.5abc", null ) ); + assertThrows( new IllegalArgumentException( "invalid border '1,2,3,4,#f00,2.5,6abc' (invalid integer '6abc')" ), () -> UIDefaultsLoader.parseValue( "dummyBorder", "1,2,3,4,#f00,2.5,6abc", null ) ); + } + + @Test + void parseInvalidFonts() { + // size + assertThrows( new IllegalArgumentException( "invalid font '12abc' (invalid integer '12abc')" ), () -> UIDefaultsLoader.parseValue( "dummyFont", "12abc", null ) ); + assertThrows( new IllegalArgumentException( "invalid font '+12abc' (invalid integer '+12abc')" ), () -> UIDefaultsLoader.parseValue( "dummyFont", "+12abc", null ) ); + assertThrows( new IllegalArgumentException( "invalid font '+3abc' (invalid integer '+3abc')" ), () -> UIDefaultsLoader.parseValue( "dummyFont", "+3abc", null ) ); + assertThrows( new IllegalArgumentException( "invalid font '-4abc' (invalid integer '-4abc')" ), () -> UIDefaultsLoader.parseValue( "dummyFont", "-4abc", null ) ); + assertThrows( new IllegalArgumentException( "invalid font '150abc%' (invalid integer '150abc')" ), () -> UIDefaultsLoader.parseValue( "dummyFont", "150abc%", null ) ); + assertThrows( new IllegalArgumentException( "invalid font 'bold 13abc Monospaced' (invalid integer '13abc')" ), () -> UIDefaultsLoader.parseValue( "dummyFont", "bold 13abc Monospaced", null ) ); + + // invalid combinations of styles + assertThrows( new IllegalArgumentException( "invalid font 'bold +italic': can not mix absolute style (e.g. 'bold') with derived style (e.g. '+italic')" ), () -> UIDefaultsLoader.parseValue( "dummyFont", "bold +italic", null ) ); + assertThrows( new IllegalArgumentException( "invalid font '+bold -bold': can not use '+bold' and '-bold'" ), () -> UIDefaultsLoader.parseValue( "dummyFont", "+bold -bold", null ) ); + assertThrows( new IllegalArgumentException( "invalid font '+italic -italic': can not use '+italic' and '-italic'" ), () -> UIDefaultsLoader.parseValue( "dummyFont", "+italic -italic", null ) ); + } + + private void assertThrows( Throwable expected, Executable executable ) { + Throwable actual = assertThrowsExactly( expected.getClass(), executable ); + assertEquals( expected.getMessage(), actual.getMessage() ); + } + //---- class TestInstance ------------------------------------------------- @SuppressWarnings( "EqualsHashCode" ) // Error Prone diff --git a/flatlaf-demo/build.gradle.kts b/flatlaf-demo/build.gradle.kts index 55d7e2ef..beb241db 100644 --- a/flatlaf-demo/build.gradle.kts +++ b/flatlaf-demo/build.gradle.kts @@ -48,6 +48,9 @@ tasks { if( JavaVersion.current() >= JavaVersion.VERSION_1_9 ) attributes( "Multi-Release" to "true" ) + + // allow loading FlatLaf native library in Java 24+ (see https://openjdk.org/jeps/472) + attributes( "Enable-Native-Access" to "ALL-UNNAMED" ) } exclude( "module-info.class" ) diff --git a/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/DemoFrame.java b/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/DemoFrame.java index 08b0a202..e3711254 100644 --- a/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/DemoFrame.java +++ b/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/DemoFrame.java @@ -272,8 +272,20 @@ class DemoFrame private void windowDecorationsChanged() { boolean windowDecorations = windowDecorationsCheckBoxMenuItem.isSelected(); - // change window decoration of all frames and dialogs - FlatLaf.setUseNativeWindowDecorations( windowDecorations ); + if( SystemInfo.isLinux ) { + // enable/disable custom window decorations + JFrame.setDefaultLookAndFeelDecorated( windowDecorations ); + JDialog.setDefaultLookAndFeelDecorated( windowDecorations ); + + // dispose frame, update decoration and re-show frame + dispose(); + setUndecorated( windowDecorations ); + getRootPane().setWindowDecorationStyle( windowDecorations ? JRootPane.FRAME : JRootPane.NONE ); + setVisible( true ); + } else { + // change window decoration of all frames and dialogs + FlatLaf.setUseNativeWindowDecorations( windowDecorations ); + } menuBarEmbeddedCheckBoxMenuItem.setEnabled( windowDecorations ); unifiedTitleBarMenuItem.setEnabled( windowDecorations ); @@ -530,7 +542,7 @@ class DemoFrame } private boolean supportsFlatLafWindowDecorations() { - return FlatLaf.supportsNativeWindowDecorations() || (SystemInfo.isLinux && JFrame.isDefaultLookAndFeelDecorated()); + return FlatLaf.supportsNativeWindowDecorations() || SystemInfo.isLinux; } private void initComponents() { @@ -1045,10 +1057,9 @@ class DemoFrame scrollingPopupMenu.add( "Item " + i ); if( supportsFlatLafWindowDecorations() ) { - if( SystemInfo.isLinux ) - unsupported( windowDecorationsCheckBoxMenuItem ); - else - windowDecorationsCheckBoxMenuItem.setSelected( FlatLaf.isUseNativeWindowDecorations() ); + windowDecorationsCheckBoxMenuItem.setSelected( SystemInfo.isLinux + ? JFrame.isDefaultLookAndFeelDecorated() + : FlatLaf.isUseNativeWindowDecorations() ); menuBarEmbeddedCheckBoxMenuItem.setSelected( UIManager.getBoolean( "TitlePane.menuBarEmbedded" ) ); unifiedTitleBarMenuItem.setSelected( UIManager.getBoolean( "TitlePane.unifiedBackground" ) ); showTitleBarIconMenuItem.setSelected( UIManager.getBoolean( "TitlePane.showIcon" ) ); @@ -1092,7 +1103,7 @@ class DemoFrame private void unsupported( JCheckBoxMenuItem menuItem ) { menuItem.setEnabled( false ); menuItem.setSelected( false ); - menuItem.setToolTipText( "Not supported on your system." ); + menuItem.setToolTipText( "Not supported on this platform." ); } // JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables diff --git a/flatlaf-extras/README.md b/flatlaf-extras/README.md index ef66e83d..314f24ae 100644 --- a/flatlaf-extras/README.md +++ b/flatlaf-extras/README.md @@ -41,6 +41,11 @@ If SVG classes are used, `jsvg-.jar` is also required: [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.github.weisj/jsvg/badge.svg?style=flat-square&color=007ec6)](https://maven-badges.herokuapp.com/maven-central/com.github.weisj/jsvg) +Supported JSVG versions: + +- FlatLaf 3.7+ supports JSVG 1.6.0 and later. +- FlatLaf 3.6- supports only JSVG 1.x (but not 2.x). + Tools ----- diff --git a/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/FlatSVGIcon.java b/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/FlatSVGIcon.java index 046c4ca8..f615a48f 100644 --- a/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/FlatSVGIcon.java +++ b/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/FlatSVGIcon.java @@ -25,6 +25,7 @@ import java.awt.Image; import java.awt.Paint; import java.awt.Rectangle; import java.awt.RenderingHints; +import java.awt.geom.Dimension2D; import java.awt.LinearGradientPaint; import java.awt.image.BufferedImage; import java.awt.image.RGBImageFilter; @@ -52,7 +53,7 @@ import com.formdev.flatlaf.util.MultiResolutionImageSupport; import com.formdev.flatlaf.util.SoftCache; import com.formdev.flatlaf.util.UIScale; import com.github.weisj.jsvg.SVGDocument; -import com.github.weisj.jsvg.geometry.size.FloatSize; +import com.github.weisj.jsvg.parser.LoaderContext; import com.github.weisj.jsvg.parser.SVGLoader; /** @@ -271,7 +272,7 @@ public class FlatSVGIcon this( null, -1, -1, 1, false, null, null ); try( InputStream in2 = in ) { - document = svgLoader.load( in2 ); + document = svgLoader.load( in2, null, LoaderContext.createDefault() ); if( document == null ) { loadFailed = true; @@ -620,9 +621,9 @@ public class FlatSVGIcon UIScale.scaleGraphics( g ); if( width > 0 || height > 0 ) { - FloatSize svgSize = document.size(); - double sx = (width > 0) ? width / svgSize.width : 1; - double sy = (height > 0) ? height / svgSize.height : 1; + Dimension2D svgSize = document.size(); + double sx = (width > 0) ? width / svgSize.getWidth() : 1; + double sy = (height > 0) ? height / svgSize.getHeight() : 1; if( sx != 1 || sy != 1 ) g.scale( sx, sy ); } diff --git a/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/FlatSVGUtils.java b/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/FlatSVGUtils.java index bf09fbc9..c76d5fda 100644 --- a/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/FlatSVGUtils.java +++ b/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/FlatSVGUtils.java @@ -19,6 +19,7 @@ package com.formdev.flatlaf.extras; import java.awt.Dimension; import java.awt.Graphics2D; import java.awt.Image; +import java.awt.geom.Dimension2D; import java.awt.image.BufferedImage; import java.net.URL; import java.util.Arrays; @@ -28,7 +29,6 @@ import javax.swing.JWindow; import com.formdev.flatlaf.util.MultiResolutionImageSupport; import com.formdev.flatlaf.util.SystemInfo; import com.github.weisj.jsvg.SVGDocument; -import com.github.weisj.jsvg.geometry.size.FloatSize; /** * Utility methods for SVG. @@ -180,9 +180,9 @@ public class FlatSVGUtils */ public static BufferedImage svg2image( URL svgUrl, float scaleFactor ) { SVGDocument document = FlatSVGIcon.loadSVG( svgUrl ); - FloatSize size = document.size(); - int width = (int) (size.width * scaleFactor); - int height = (int) (size.height * scaleFactor); + Dimension2D size = document.size(); + int width = (int) (size.getWidth() * scaleFactor); + int height = (int) (size.getHeight() * scaleFactor); return svg2image( document, width, height ); } @@ -202,9 +202,9 @@ public class FlatSVGUtils try { FlatSVGIcon.setRenderingHints( g ); - FloatSize size = document.size(); - double sx = width / size.width; - double sy = height / size.height; + Dimension2D size = document.size(); + double sx = width / size.getWidth(); + double sy = height / size.getHeight(); if( sx != 1 || sy != 1 ) g.scale( sx, sy ); diff --git a/flatlaf-jide-oss/src/main/java/com/formdev/flatlaf/jideoss/ui/FlatJideSplitButtonUI.java b/flatlaf-jide-oss/src/main/java/com/formdev/flatlaf/jideoss/ui/FlatJideSplitButtonUI.java index 080cf1fb..25ca30f4 100644 --- a/flatlaf-jide-oss/src/main/java/com/formdev/flatlaf/jideoss/ui/FlatJideSplitButtonUI.java +++ b/flatlaf-jide-oss/src/main/java/com/formdev/flatlaf/jideoss/ui/FlatJideSplitButtonUI.java @@ -25,9 +25,11 @@ import java.awt.geom.Rectangle2D; import javax.swing.ButtonModel; import javax.swing.JComponent; import javax.swing.JMenuItem; +import javax.swing.JPopupMenu; import javax.swing.SwingConstants; import javax.swing.UIManager; import javax.swing.plaf.ComponentUI; +import javax.swing.plaf.PopupMenuUI; import com.formdev.flatlaf.ui.FlatUIUtils; import com.formdev.flatlaf.util.UIScale; import com.jidesoft.plaf.LookAndFeelFactory; @@ -54,6 +56,14 @@ public class FlatJideSplitButtonUI // but it does not because FlatLaf already has added the UI class to the UI defaults LookAndFeelFactory.installJideExtension(); + // workaround for bug in JideSplitButton, which overrides JMenu.updateUI(), + // but does not invoke super.updateUI() to update UI of JMenu.popupMenu field + if( c instanceof JideSplitButton ) { + JPopupMenu popupMenu = ((JideSplitButton)c).getPopupMenu(); + if( popupMenu != null ) + popupMenu.setUI( (PopupMenuUI) UIManager.getUI( popupMenu ) ); + } + return new FlatJideSplitButtonUI(); } diff --git a/flatlaf-testing/dumps/uidefaults/FlatDarkLaf_1.8.0-linux.txt b/flatlaf-testing/dumps/uidefaults/FlatDarkLaf_1.8.0-linux.txt index f70ad825..5259e6e9 100644 --- a/flatlaf-testing/dumps/uidefaults/FlatDarkLaf_1.8.0-linux.txt +++ b/flatlaf-testing/dumps/uidefaults/FlatDarkLaf_1.8.0-linux.txt @@ -25,18 +25,6 @@ + ProgressBar.font [active] Liberation Sans plain 13 javax.swing.plaf.FontUIResource [UI] -#---- ScrollBar ---- - -- ScrollBar.minimumThumbSize 10,10 javax.swing.plaf.DimensionUIResource [UI] -+ ScrollBar.minimumThumbSize 18,18 javax.swing.plaf.DimensionUIResource [UI] - -- ScrollBar.thumbArc 0 -+ ScrollBar.thumbArc 999 - -- ScrollBar.thumbInsets 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI] -+ ScrollBar.thumbInsets 2,2,2,2 javax.swing.plaf.InsetsUIResource [UI] - - #---- TaskPane ---- - TaskPane.font [active] Segoe UI bold 12 javax.swing.plaf.FontUIResource [UI] diff --git a/flatlaf-testing/dumps/uidefaults/FlatDarkLaf_1.8.0-mac.txt b/flatlaf-testing/dumps/uidefaults/FlatDarkLaf_1.8.0-mac.txt index 7f0d7d07..eb458058 100644 --- a/flatlaf-testing/dumps/uidefaults/FlatDarkLaf_1.8.0-mac.txt +++ b/flatlaf-testing/dumps/uidefaults/FlatDarkLaf_1.8.0-mac.txt @@ -68,15 +68,6 @@ - ScrollBar.hoverThumbWithTrack false + ScrollBar.hoverThumbWithTrack true -- ScrollBar.minimumThumbSize 10,10 javax.swing.plaf.DimensionUIResource [UI] -+ ScrollBar.minimumThumbSize 18,18 javax.swing.plaf.DimensionUIResource [UI] - -- ScrollBar.thumbArc 0 -+ ScrollBar.thumbArc 999 - -- ScrollBar.thumbInsets 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI] -+ ScrollBar.thumbInsets 2,2,2,2 javax.swing.plaf.InsetsUIResource [UI] - #---- TaskPane ---- diff --git a/flatlaf-testing/dumps/uidefaults/FlatDarkLaf_1.8.0.txt b/flatlaf-testing/dumps/uidefaults/FlatDarkLaf_1.8.0.txt index ce1fec24..a96d5114 100644 --- a/flatlaf-testing/dumps/uidefaults/FlatDarkLaf_1.8.0.txt +++ b/flatlaf-testing/dumps/uidefaults/FlatDarkLaf_1.8.0.txt @@ -881,22 +881,22 @@ ScrollBar.buttonArrowColor #b7b7b7 HSL 0 0 72 javax.swing.plaf.Colo ScrollBar.buttonDisabledArrowColor #777777 HSL 0 0 47 javax.swing.plaf.ColorUIResource [UI] ScrollBar.foreground #dddddd HSL 0 0 87 javax.swing.plaf.ColorUIResource [UI] ScrollBar.hoverButtonBackground #484c4e HSL 200 4 29 com.formdev.flatlaf.util.DerivedColor [UI] lighten(5%) -ScrollBar.hoverThumbColor #6e767a HSL 200 5 45 com.formdev.flatlaf.util.DerivedColor [UI] lighten(10%) +ScrollBar.hoverThumbColor #7a8387 HSL 198 5 50 com.formdev.flatlaf.util.DerivedColor [UI] lighten(10%) ScrollBar.hoverThumbWithTrack false ScrollBar.hoverTrackColor #484c4f HSL 206 5 30 com.formdev.flatlaf.util.DerivedColor [UI] lighten(4%) ScrollBar.maximumThumbSize 100000,100000 javax.swing.plaf.DimensionUIResource [UI] ScrollBar.minimumButtonSize 12,12 javax.swing.plaf.DimensionUIResource [UI] -ScrollBar.minimumThumbSize 10,10 javax.swing.plaf.DimensionUIResource [UI] +ScrollBar.minimumThumbSize 18,18 javax.swing.plaf.DimensionUIResource [UI] ScrollBar.pressedButtonBackground #54595c HSL 203 5 35 com.formdev.flatlaf.util.DerivedColor [UI] lighten(10%) -ScrollBar.pressedThumbColor #7a8387 HSL 198 5 50 com.formdev.flatlaf.util.DerivedColor [UI] lighten(15%) +ScrollBar.pressedThumbColor #888f93 HSL 202 5 55 com.formdev.flatlaf.util.DerivedColor [UI] lighten(15%) ScrollBar.pressedThumbWithTrack false ScrollBar.showButtons false ScrollBar.squareButtons false -ScrollBar.thumb #565c5f HSL 200 5 35 com.formdev.flatlaf.util.DerivedColor [UI] lighten(10%) -ScrollBar.thumbArc 0 +ScrollBar.thumb #62696c HSL 198 5 40 com.formdev.flatlaf.util.DerivedColor [UI] lighten(15%) +ScrollBar.thumbArc 999 ScrollBar.thumbDarkShadow #7a7d7f HSL 204 2 49 javax.swing.plaf.ColorUIResource [UI] ScrollBar.thumbHighlight #232324 HSL 240 1 14 javax.swing.plaf.ColorUIResource [UI] -ScrollBar.thumbInsets 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI] +ScrollBar.thumbInsets 2,2,2,2 javax.swing.plaf.InsetsUIResource [UI] ScrollBar.thumbShadow #616365 HSL 210 2 39 javax.swing.plaf.ColorUIResource [UI] ScrollBar.track #3e4244 HSL 200 5 25 com.formdev.flatlaf.util.DerivedColor [UI] lighten(1%) ScrollBar.trackArc 0 diff --git a/flatlaf-testing/dumps/uidefaults/FlatLightLaf_1.8.0-linux.txt b/flatlaf-testing/dumps/uidefaults/FlatLightLaf_1.8.0-linux.txt index d8837b5a..b3a9f77e 100644 --- a/flatlaf-testing/dumps/uidefaults/FlatLightLaf_1.8.0-linux.txt +++ b/flatlaf-testing/dumps/uidefaults/FlatLightLaf_1.8.0-linux.txt @@ -25,18 +25,6 @@ + ProgressBar.font [active] Liberation Sans plain 13 javax.swing.plaf.FontUIResource [UI] -#---- ScrollBar ---- - -- ScrollBar.minimumThumbSize 10,10 javax.swing.plaf.DimensionUIResource [UI] -+ ScrollBar.minimumThumbSize 18,18 javax.swing.plaf.DimensionUIResource [UI] - -- ScrollBar.thumbArc 0 -+ ScrollBar.thumbArc 999 - -- ScrollBar.thumbInsets 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI] -+ ScrollBar.thumbInsets 2,2,2,2 javax.swing.plaf.InsetsUIResource [UI] - - #---- TaskPane ---- - TaskPane.font [active] Segoe UI bold 12 javax.swing.plaf.FontUIResource [UI] diff --git a/flatlaf-testing/dumps/uidefaults/FlatLightLaf_1.8.0-mac.txt b/flatlaf-testing/dumps/uidefaults/FlatLightLaf_1.8.0-mac.txt index 46d779b2..f79062bb 100644 --- a/flatlaf-testing/dumps/uidefaults/FlatLightLaf_1.8.0-mac.txt +++ b/flatlaf-testing/dumps/uidefaults/FlatLightLaf_1.8.0-mac.txt @@ -68,15 +68,6 @@ - ScrollBar.hoverThumbWithTrack false + ScrollBar.hoverThumbWithTrack true -- ScrollBar.minimumThumbSize 10,10 javax.swing.plaf.DimensionUIResource [UI] -+ ScrollBar.minimumThumbSize 18,18 javax.swing.plaf.DimensionUIResource [UI] - -- ScrollBar.thumbArc 0 -+ ScrollBar.thumbArc 999 - -- ScrollBar.thumbInsets 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI] -+ ScrollBar.thumbInsets 2,2,2,2 javax.swing.plaf.InsetsUIResource [UI] - #---- TaskPane ---- diff --git a/flatlaf-testing/dumps/uidefaults/FlatLightLaf_1.8.0.txt b/flatlaf-testing/dumps/uidefaults/FlatLightLaf_1.8.0.txt index 47a09ec5..2d18f745 100644 --- a/flatlaf-testing/dumps/uidefaults/FlatLightLaf_1.8.0.txt +++ b/flatlaf-testing/dumps/uidefaults/FlatLightLaf_1.8.0.txt @@ -886,22 +886,22 @@ ScrollBar.buttonArrowColor #666666 HSL 0 0 40 javax.swing.plaf.Colo ScrollBar.buttonDisabledArrowColor #a6a6a6 HSL 0 0 65 javax.swing.plaf.ColorUIResource [UI] ScrollBar.foreground #000000 HSL 0 0 0 javax.swing.plaf.ColorUIResource [UI] ScrollBar.hoverButtonBackground #e5e5e5 HSL 0 0 90 com.formdev.flatlaf.util.DerivedColor [UI] darken(5%) -ScrollBar.hoverThumbColor #c3c3c3 HSL 0 0 76 com.formdev.flatlaf.util.DerivedColor [UI] darken(10%) +ScrollBar.hoverThumbColor #b6b6b6 HSL 0 0 71 com.formdev.flatlaf.util.DerivedColor [UI] darken(10%) ScrollBar.hoverThumbWithTrack false ScrollBar.hoverTrackColor #ededed HSL 0 0 93 com.formdev.flatlaf.util.DerivedColor [UI] darken(3%) ScrollBar.maximumThumbSize 100000,100000 javax.swing.plaf.DimensionUIResource [UI] ScrollBar.minimumButtonSize 12,12 javax.swing.plaf.DimensionUIResource [UI] -ScrollBar.minimumThumbSize 10,10 javax.swing.plaf.DimensionUIResource [UI] +ScrollBar.minimumThumbSize 18,18 javax.swing.plaf.DimensionUIResource [UI] ScrollBar.pressedButtonBackground #d9d9d9 HSL 0 0 85 com.formdev.flatlaf.util.DerivedColor [UI] darken(10%) -ScrollBar.pressedThumbColor #a9a9a9 HSL 0 0 66 com.formdev.flatlaf.util.DerivedColor [UI] darken(20%) +ScrollBar.pressedThumbColor #9c9c9c HSL 0 0 61 com.formdev.flatlaf.util.DerivedColor [UI] darken(20%) ScrollBar.pressedThumbWithTrack false ScrollBar.showButtons false ScrollBar.squareButtons false -ScrollBar.thumb #dcdcdc HSL 0 0 86 com.formdev.flatlaf.util.DerivedColor [UI] darken(10%) -ScrollBar.thumbArc 0 +ScrollBar.thumb #cfcfcf HSL 0 0 81 com.formdev.flatlaf.util.DerivedColor [UI] darken(15%) +ScrollBar.thumbArc 999 ScrollBar.thumbDarkShadow #9c9c9c HSL 0 0 61 javax.swing.plaf.ColorUIResource [UI] ScrollBar.thumbHighlight #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI] -ScrollBar.thumbInsets 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI] +ScrollBar.thumbInsets 2,2,2,2 javax.swing.plaf.InsetsUIResource [UI] ScrollBar.thumbShadow #c2c2c2 HSL 0 0 76 javax.swing.plaf.ColorUIResource [UI] ScrollBar.track #f5f5f5 HSL 0 0 96 com.formdev.flatlaf.util.DerivedColor [UI] lighten(1%) ScrollBar.trackArc 0 diff --git a/flatlaf-testing/dumps/uidefaults/FlatTestLaf_1.8.0.txt b/flatlaf-testing/dumps/uidefaults/FlatTestLaf_1.8.0.txt index 572dc92e..a7392ccb 100644 --- a/flatlaf-testing/dumps/uidefaults/FlatTestLaf_1.8.0.txt +++ b/flatlaf-testing/dumps/uidefaults/FlatTestLaf_1.8.0.txt @@ -919,15 +919,15 @@ ScrollBar.hoverThumbWithTrack false ScrollBar.hoverTrackColor #00ff00 HSL 120 100 50 javax.swing.plaf.ColorUIResource [UI] ScrollBar.maximumThumbSize 100000,100000 javax.swing.plaf.DimensionUIResource [UI] ScrollBar.minimumButtonSize 12,12 javax.swing.plaf.DimensionUIResource [UI] -ScrollBar.minimumThumbSize 10,10 javax.swing.plaf.DimensionUIResource [UI] +ScrollBar.minimumThumbSize 18,18 javax.swing.plaf.DimensionUIResource [UI] ScrollBar.pressedThumbWithTrack false ScrollBar.showButtons false ScrollBar.squareButtons false ScrollBar.thumb #73737333 20% HSLA 0 0 45 20 javax.swing.plaf.ColorUIResource [UI] -ScrollBar.thumbArc 0 +ScrollBar.thumbArc 999 ScrollBar.thumbDarkShadow #696969 HSL 0 0 41 javax.swing.plaf.ColorUIResource [UI] ScrollBar.thumbHighlight #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI] -ScrollBar.thumbInsets 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI] +ScrollBar.thumbInsets 2,2,2,2 javax.swing.plaf.InsetsUIResource [UI] ScrollBar.thumbShadow #a0a0a0 HSL 0 0 63 javax.swing.plaf.ColorUIResource [UI] ScrollBar.track #88ff88 HSL 120 100 77 javax.swing.plaf.ColorUIResource [UI] ScrollBar.trackArc 0 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 6c40eb87..a2b51e5f 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 @@ -24,13 +24,8 @@ import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; 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 java.util.function.Supplier; +import javax.swing.*; import javax.swing.plaf.metal.MetalLookAndFeel; import javax.swing.plaf.nimbus.NimbusLookAndFeel; import com.formdev.flatlaf.FlatDarculaLaf; @@ -59,11 +54,18 @@ public class FlatSingleComponentTest private final JLabel infoLabel; - private JComponent createSingleComponent() { + protected JComponent createSingleComponent() { return new JButton( "hello" ); } public static void main( String[] args ) { + EventQueue.invokeLater( () -> { + launch( FlatSingleComponentTest::new, args ); + } ); + } + + @SuppressWarnings( "ReturnValueIgnored" ) // Error Prone + protected static void launch( Supplier factory, String[] args ) { DemoPrefs.init( PREFS_ROOT_PATH ); DemoPrefs.initSystemScale(); @@ -88,10 +90,10 @@ public class FlatSingleComponentTest DemoPrefs.setupLaf( args ); // create and show frame - new FlatSingleComponentTest(); + factory.get(); } - private FlatSingleComponentTest() { + protected FlatSingleComponentTest() { super( "FlatSingleComponentTest" ); setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatTextComponentsTest.java b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatTextComponentsTest.java index 8b74098e..da05be2c 100644 --- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatTextComponentsTest.java +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatTextComponentsTest.java @@ -18,7 +18,9 @@ package com.formdev.flatlaf.testing; import java.awt.Color; import java.awt.Component; +import java.awt.Container; import java.awt.Dimension; +import java.awt.FocusTraversalPolicy; import java.awt.Graphics; import java.awt.Insets; import java.util.function.Supplier; @@ -47,6 +49,12 @@ public class FlatTextComponentsTest FlatTextComponentsTest() { initComponents(); updatePreferredSizes(); + + // exclude from tab focus traversal + controlPanel.setFocusTraversalPolicyProvider( true ); + controlPanel.setFocusTraversalPolicy( new NotFocusableTraversalPolicy() ); + placeholderPanel.setFocusTraversalPolicyProvider( true ); + placeholderPanel.setFocusTraversalPolicy( new NotFocusableTraversalPolicy() ); } @Override @@ -196,7 +204,7 @@ public class FlatTextComponentsTest JLabel formattedTextFieldLabel = new JLabel(); JFormattedTextField formattedTextField1 = new JFormattedTextField(); JFormattedTextField formattedTextField3 = new JFormattedTextField(); - JPanel panel1 = new JPanel(); + controlPanel = new JPanel(); editableCheckBox = new JCheckBox(); JButton button1 = new JButton(); JLabel leftPaddingLabel = new JLabel(); @@ -215,7 +223,7 @@ public class FlatTextComponentsTest trailingComponentVisibleCheckBox = new JCheckBox(); showClearButtonCheckBox = new JCheckBox(); showRevealButtonCheckBox = new JCheckBox(); - JPanel panel2 = new JPanel(); + placeholderPanel = new JPanel(); JLabel label7 = new JLabel(); FlatTextField flatTextField1 = new FlatTextField(); JLabel label8 = new JLabel(); @@ -351,11 +359,11 @@ public class FlatTextComponentsTest formattedTextField3.putClientProperty(FlatClientProperties.PLACEHOLDER_TEXT, "place"); add(formattedTextField3, "cell 2 1,growx"); - //======== panel1 ======== + //======== controlPanel ======== { - panel1.setBorder(new TitledBorder("Control")); - panel1.putClientProperty("FlatLaf.internal.testing.ignore", true); - panel1.setLayout(new MigLayout( + controlPanel.setBorder(new TitledBorder("Control")); + controlPanel.putClientProperty("FlatLaf.internal.testing.ignore", true); + controlPanel.setLayout(new MigLayout( "hidemode 3", // columns "[fill]" + @@ -379,94 +387,104 @@ public class FlatTextComponentsTest //---- editableCheckBox ---- editableCheckBox.setText("editable"); editableCheckBox.setSelected(true); + editableCheckBox.setFocusable(false); editableCheckBox.addActionListener(e -> editableChanged()); - panel1.add(editableCheckBox, "cell 0 0 2 1,alignx left,growx 0"); + controlPanel.add(editableCheckBox, "cell 0 0 2 1,alignx left,growx 0"); //---- button1 ---- button1.setText("change text"); + button1.setFocusable(false); button1.addActionListener(e -> changeText()); - panel1.add(button1, "cell 0 1 2 1,alignx left,growx 0"); + controlPanel.add(button1, "cell 0 1 2 1,alignx left,growx 0"); //---- leftPaddingLabel ---- leftPaddingLabel.setText("Left padding:"); - panel1.add(leftPaddingLabel, "cell 0 2"); + controlPanel.add(leftPaddingLabel, "cell 0 2"); //---- leftPaddingField ---- leftPaddingField.addChangeListener(e -> paddingChanged()); - panel1.add(leftPaddingField, "cell 1 2"); + controlPanel.add(leftPaddingField, "cell 1 2"); //---- rightPaddingLabel ---- rightPaddingLabel.setText("Right padding:"); - panel1.add(rightPaddingLabel, "cell 0 3"); + controlPanel.add(rightPaddingLabel, "cell 0 3"); //---- rightPaddingField ---- rightPaddingField.addChangeListener(e -> paddingChanged()); - panel1.add(rightPaddingField, "cell 1 3"); + controlPanel.add(rightPaddingField, "cell 1 3"); //---- topPaddingLabel ---- topPaddingLabel.setText("Top padding:"); - panel1.add(topPaddingLabel, "cell 0 4"); + controlPanel.add(topPaddingLabel, "cell 0 4"); //---- topPaddingField ---- topPaddingField.addChangeListener(e -> paddingChanged()); - panel1.add(topPaddingField, "cell 1 4"); + controlPanel.add(topPaddingField, "cell 1 4"); //---- bottomPaddingLabel ---- bottomPaddingLabel.setText("Bottom padding:"); - panel1.add(bottomPaddingLabel, "cell 0 5"); + controlPanel.add(bottomPaddingLabel, "cell 0 5"); //---- bottomPaddingField ---- bottomPaddingField.addChangeListener(e -> paddingChanged()); - panel1.add(bottomPaddingField, "cell 1 5"); + controlPanel.add(bottomPaddingField, "cell 1 5"); //---- leadingIconCheckBox ---- leadingIconCheckBox.setText("leading icon"); + leadingIconCheckBox.setFocusable(false); leadingIconCheckBox.addActionListener(e -> leadingIcon()); - panel1.add(leadingIconCheckBox, "cell 0 6 2 1,alignx left,growx 0"); + controlPanel.add(leadingIconCheckBox, "cell 0 6 2 1,alignx left,growx 0"); //---- trailingIconCheckBox ---- trailingIconCheckBox.setText("trailing icon"); + trailingIconCheckBox.setFocusable(false); trailingIconCheckBox.addActionListener(e -> trailingIcon()); - panel1.add(trailingIconCheckBox, "cell 0 7 2 1,alignx left,growx 0"); + controlPanel.add(trailingIconCheckBox, "cell 0 7 2 1,alignx left,growx 0"); //---- leadingComponentCheckBox ---- leadingComponentCheckBox.setText("leading component"); + leadingComponentCheckBox.setFocusable(false); leadingComponentCheckBox.addActionListener(e -> leadingComponent()); - panel1.add(leadingComponentCheckBox, "cell 0 8 2 1,alignx left,growx 0"); + controlPanel.add(leadingComponentCheckBox, "cell 0 8 2 1,alignx left,growx 0"); //---- trailingComponentCheckBox ---- trailingComponentCheckBox.setText("trailing component"); + trailingComponentCheckBox.setFocusable(false); trailingComponentCheckBox.addActionListener(e -> trailingComponent()); - panel1.add(trailingComponentCheckBox, "cell 0 9 2 1,alignx left,growx 0"); + controlPanel.add(trailingComponentCheckBox, "cell 0 9 2 1,alignx left,growx 0"); //---- leadingComponentVisibleCheckBox ---- leadingComponentVisibleCheckBox.setText("leading component visible"); leadingComponentVisibleCheckBox.setSelected(true); + leadingComponentVisibleCheckBox.setFocusable(false); leadingComponentVisibleCheckBox.addActionListener(e -> leadingComponentVisible()); - panel1.add(leadingComponentVisibleCheckBox, "cell 0 10 2 1,alignx left,growx 0"); + controlPanel.add(leadingComponentVisibleCheckBox, "cell 0 10 2 1,alignx left,growx 0"); //---- trailingComponentVisibleCheckBox ---- trailingComponentVisibleCheckBox.setText("trailing component visible"); trailingComponentVisibleCheckBox.setSelected(true); + trailingComponentVisibleCheckBox.setFocusable(false); trailingComponentVisibleCheckBox.addActionListener(e -> trailingComponentVisible()); - panel1.add(trailingComponentVisibleCheckBox, "cell 0 11 2 1,alignx left,growx 0"); + controlPanel.add(trailingComponentVisibleCheckBox, "cell 0 11 2 1,alignx left,growx 0"); //---- showClearButtonCheckBox ---- showClearButtonCheckBox.setText("clear button"); + showClearButtonCheckBox.setFocusable(false); showClearButtonCheckBox.addActionListener(e -> showClearButton()); - panel1.add(showClearButtonCheckBox, "cell 0 12 2 1,alignx left,growx 0"); + controlPanel.add(showClearButtonCheckBox, "cell 0 12 2 1,alignx left,growx 0"); //---- showRevealButtonCheckBox ---- showRevealButtonCheckBox.setText("password reveal button"); + showRevealButtonCheckBox.setFocusable(false); showRevealButtonCheckBox.addActionListener(e -> showRevealButton()); - panel1.add(showRevealButtonCheckBox, "cell 0 13 2 1,alignx left,growx 0"); + controlPanel.add(showRevealButtonCheckBox, "cell 0 13 2 1,alignx left,growx 0"); } - add(panel1, "cell 4 0 1 10,aligny top,growy 0"); + add(controlPanel, "cell 4 0 1 10,aligny top,growy 0"); - //======== panel2 ======== + //======== placeholderPanel ======== { - panel2.setBorder(new TitledBorder("Placeholder")); - panel2.setLayout(new MigLayout( + placeholderPanel.setBorder(new TitledBorder("Placeholder")); + placeholderPanel.setLayout(new MigLayout( "hidemode 3", // columns "[fill]" + @@ -480,55 +498,55 @@ public class FlatTextComponentsTest //---- label7 ---- label7.setText("leading"); - panel2.add(label7, "cell 0 0"); + placeholderPanel.add(label7, "cell 0 0"); //---- flatTextField1 ---- flatTextField1.setHorizontalAlignment(SwingConstants.LEADING); flatTextField1.setPlaceholderText("text"); flatTextField1.setColumns(10); - panel2.add(flatTextField1, "cell 1 0"); + placeholderPanel.add(flatTextField1, "cell 1 0"); //---- label8 ---- label8.setText("left"); - panel2.add(label8, "cell 0 1"); + placeholderPanel.add(label8, "cell 0 1"); //---- flatTextField2 ---- flatTextField2.setHorizontalAlignment(SwingConstants.LEFT); flatTextField2.setPlaceholderText("text"); flatTextField2.setColumns(10); - panel2.add(flatTextField2, "cell 1 1"); + placeholderPanel.add(flatTextField2, "cell 1 1"); //---- label9 ---- label9.setText("center"); - panel2.add(label9, "cell 0 2"); + placeholderPanel.add(label9, "cell 0 2"); //---- flatTextField3 ---- flatTextField3.setHorizontalAlignment(SwingConstants.CENTER); flatTextField3.setPlaceholderText("text"); flatTextField3.setColumns(10); - panel2.add(flatTextField3, "cell 1 2"); + placeholderPanel.add(flatTextField3, "cell 1 2"); //---- label10 ---- label10.setText("right"); - panel2.add(label10, "cell 0 3"); + placeholderPanel.add(label10, "cell 0 3"); //---- flatTextField4 ---- flatTextField4.setHorizontalAlignment(SwingConstants.RIGHT); flatTextField4.setPlaceholderText("text"); flatTextField4.setColumns(10); - panel2.add(flatTextField4, "cell 1 3"); + placeholderPanel.add(flatTextField4, "cell 1 3"); //---- label11 ---- label11.setText("trailing"); - panel2.add(label11, "cell 0 4"); + placeholderPanel.add(label11, "cell 0 4"); //---- flatTextField5 ---- flatTextField5.setHorizontalAlignment(SwingConstants.TRAILING); flatTextField5.setPlaceholderText("text"); flatTextField5.setColumns(10); - panel2.add(flatTextField5, "cell 1 4"); + placeholderPanel.add(flatTextField5, "cell 1 4"); } - add(panel2, "cell 5 0 1 9,aligny top,growy 0"); + add(placeholderPanel, "cell 5 0 1 10,aligny top,growy 0"); //---- passwordFieldLabel ---- passwordFieldLabel.setText("JPasswordField:"); @@ -783,6 +801,7 @@ public class FlatTextComponentsTest // JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables private JTextField textField1; + private JPanel controlPanel; private JCheckBox editableCheckBox; private JSpinner leftPaddingField; private JSpinner rightPaddingField; @@ -796,6 +815,7 @@ public class FlatTextComponentsTest private JCheckBox trailingComponentVisibleCheckBox; private JCheckBox showClearButtonCheckBox; private JCheckBox showRevealButtonCheckBox; + private JPanel placeholderPanel; private JComboBox comboBox5; private JSpinner spinner4; private JComboBox comboBox6; @@ -807,6 +827,18 @@ public class FlatTextComponentsTest private JEditorPane editorPane; // JFormDesigner - End of variables declaration //GEN-END:variables + //---- NotFocusableTraversalPolicy ---------------------------------------- + + private static class NotFocusableTraversalPolicy + extends FocusTraversalPolicy + { + @Override public Component getComponentAfter( Container aContainer, Component aComponent ) { return null; } + @Override public Component getComponentBefore( Container aContainer, Component aComponent ) { return null; } + @Override public Component getFirstComponent( Container aContainer ) { return null; } + @Override public Component getLastComponent( Container aContainer ) { return null; } + @Override public Component getDefaultComponent( Container aContainer ) { return null; } + } + //---- TestIcon ----------------------------------------------------------- private static class TestIcon diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatTextComponentsTest.jfd b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatTextComponentsTest.jfd index 73b5c705..8484ae6f 100644 --- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatTextComponentsTest.jfd +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatTextComponentsTest.jfd @@ -1,4 +1,4 @@ -JFDML JFormDesigner: "8.1.0.0.283" Java: "19.0.2" encoding: "UTF-8" +JFDML JFormDesigner: "8.3" encoding: "UTF-8" new FormModel { contentType: "form/swing" @@ -78,13 +78,17 @@ new FormModel { "$columnConstraints": "[fill][fill]" "$rowConstraints": "[][][][][][][]0[][]0[][]0[][][]" } ) { - name: "panel1" + name: "controlPanel" "border": new javax.swing.border.TitledBorder( "Control" ) "$client.FlatLaf.internal.testing.ignore": true + auxiliary() { + "JavaCodeGenerator.variableLocal": false + } add( new FormComponent( "javax.swing.JCheckBox" ) { name: "editableCheckBox" "text": "editable" "selected": true + "focusable": false auxiliary() { "JavaCodeGenerator.variableLocal": false } @@ -95,6 +99,7 @@ new FormModel { add( new FormComponent( "javax.swing.JButton" ) { name: "button1" "text": "change text" + "focusable": false addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "changeText", false ) ) }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 0 1 2 1,alignx left,growx 0" @@ -162,6 +167,7 @@ new FormModel { add( new FormComponent( "javax.swing.JCheckBox" ) { name: "leadingIconCheckBox" "text": "leading icon" + "focusable": false auxiliary() { "JavaCodeGenerator.variableLocal": false } @@ -172,6 +178,7 @@ new FormModel { add( new FormComponent( "javax.swing.JCheckBox" ) { name: "trailingIconCheckBox" "text": "trailing icon" + "focusable": false auxiliary() { "JavaCodeGenerator.variableLocal": false } @@ -182,6 +189,7 @@ new FormModel { add( new FormComponent( "javax.swing.JCheckBox" ) { name: "leadingComponentCheckBox" "text": "leading component" + "focusable": false auxiliary() { "JavaCodeGenerator.variableLocal": false } @@ -192,6 +200,7 @@ new FormModel { add( new FormComponent( "javax.swing.JCheckBox" ) { name: "trailingComponentCheckBox" "text": "trailing component" + "focusable": false auxiliary() { "JavaCodeGenerator.variableLocal": false } @@ -203,6 +212,7 @@ new FormModel { name: "leadingComponentVisibleCheckBox" "text": "leading component visible" "selected": true + "focusable": false auxiliary() { "JavaCodeGenerator.variableLocal": false } @@ -214,6 +224,7 @@ new FormModel { name: "trailingComponentVisibleCheckBox" "text": "trailing component visible" "selected": true + "focusable": false auxiliary() { "JavaCodeGenerator.variableLocal": false } @@ -224,6 +235,7 @@ new FormModel { add( new FormComponent( "javax.swing.JCheckBox" ) { name: "showClearButtonCheckBox" "text": "clear button" + "focusable": false auxiliary() { "JavaCodeGenerator.variableLocal": false } @@ -234,6 +246,7 @@ new FormModel { add( new FormComponent( "javax.swing.JCheckBox" ) { name: "showRevealButtonCheckBox" "text": "password reveal button" + "focusable": false auxiliary() { "JavaCodeGenerator.variableLocal": false } @@ -249,8 +262,11 @@ new FormModel { "$columnConstraints": "[fill][fill]" "$rowConstraints": "[][][][][]" } ) { - name: "panel2" + name: "placeholderPanel" "border": new javax.swing.border.TitledBorder( "Placeholder" ) + auxiliary() { + "JavaCodeGenerator.variableLocal": false + } add( new FormComponent( "javax.swing.JLabel" ) { name: "label7" "text": "leading" @@ -325,7 +341,7 @@ new FormModel { "value": "cell 1 4" } ) }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 5 0 1 9,aligny top,growy 0" + "value": "cell 5 0 1 10,aligny top,growy 0" } ) add( new FormComponent( "javax.swing.JLabel" ) { name: "passwordFieldLabel" diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatTextSelectAllOnFocusTest.java b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatTextSelectAllOnFocusTest.java new file mode 100644 index 00000000..9a27b069 --- /dev/null +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatTextSelectAllOnFocusTest.java @@ -0,0 +1,423 @@ +/* + * 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.testing; + +import static com.formdev.flatlaf.FlatClientProperties.*; +import java.awt.EventQueue; +import java.text.ParseException; +import javax.swing.*; +import javax.swing.text.DefaultFormatterFactory; +import javax.swing.text.MaskFormatter; +import net.miginfocom.swing.*; + +/** + * @author Karl Tauber + */ +public class FlatTextSelectAllOnFocusTest + extends FlatSingleComponentTest +{ + public static void main( String[] args ) { + EventQueue.invokeLater( () -> { + launch( FlatTextSelectAllOnFocusTest::new, args ); + } ); + } + + @Override + protected JComponent createSingleComponent() { + initComponents(); + + try { + MaskFormatter formatter = new MaskFormatter( "###-####-###" ); + formatter.setPlaceholderCharacter( '_' ); + DefaultFormatterFactory factory = new DefaultFormatterFactory( formatter ); + + formattedTextField1.setFormatterFactory( factory ); + formattedTextField2.setFormatterFactory( factory ); + formattedTextField3.setFormatterFactory( factory ); + formattedTextField4.setFormatterFactory( factory ); + formattedTextField5.setFormatterFactory( factory ); + formattedTextField6.setFormatterFactory( factory ); + + formattedTextField1.setValue( "123-4567-890" ); + formattedTextField2.setValue( "123-4567-890" ); + formattedTextField3.setValue( "123-4567-890" ); + formattedTextField4.setValue( "123-4567-890" ); + formattedTextField5.setValue( "123-4567-890" ); + formattedTextField6.setValue( "123-4567-890" ); + } catch( ParseException ex ) { + ex.printStackTrace(); + } + + textField2.putClientProperty( SELECT_ALL_ON_FOCUS_POLICY, SELECT_ALL_ON_FOCUS_POLICY_NEVER ); + textField3.putClientProperty( SELECT_ALL_ON_FOCUS_POLICY, SELECT_ALL_ON_FOCUS_POLICY_ONCE ); + textField4.putClientProperty( SELECT_ALL_ON_FOCUS_POLICY, SELECT_ALL_ON_FOCUS_POLICY_ALWAYS ); + textField5.putClientProperty( SELECT_ALL_ON_FOCUS_POLICY, SELECT_ALL_ON_FOCUS_POLICY_ONCE ); + textField5.putClientProperty( SELECT_ALL_ON_MOUSE_CLICK, true ); + textField6.putClientProperty( SELECT_ALL_ON_FOCUS_POLICY, SELECT_ALL_ON_FOCUS_POLICY_ALWAYS ); + textField6.putClientProperty( SELECT_ALL_ON_MOUSE_CLICK, true ); + textField7.select( 5, 7 ); + + formattedTextField2.putClientProperty( SELECT_ALL_ON_FOCUS_POLICY, SELECT_ALL_ON_FOCUS_POLICY_NEVER ); + formattedTextField3.putClientProperty( SELECT_ALL_ON_FOCUS_POLICY, SELECT_ALL_ON_FOCUS_POLICY_ONCE ); + formattedTextField4.putClientProperty( SELECT_ALL_ON_FOCUS_POLICY, SELECT_ALL_ON_FOCUS_POLICY_ALWAYS ); + formattedTextField5.putClientProperty( SELECT_ALL_ON_FOCUS_POLICY, SELECT_ALL_ON_FOCUS_POLICY_ONCE ); + formattedTextField5.putClientProperty( SELECT_ALL_ON_MOUSE_CLICK, true ); + formattedTextField6.putClientProperty( SELECT_ALL_ON_FOCUS_POLICY, SELECT_ALL_ON_FOCUS_POLICY_ALWAYS ); + formattedTextField6.putClientProperty( SELECT_ALL_ON_MOUSE_CLICK, true ); + + comboBox2.putClientProperty( SELECT_ALL_ON_FOCUS_POLICY, SELECT_ALL_ON_FOCUS_POLICY_NEVER ); + comboBox3.putClientProperty( SELECT_ALL_ON_FOCUS_POLICY, SELECT_ALL_ON_FOCUS_POLICY_ONCE ); + comboBox4.putClientProperty( SELECT_ALL_ON_FOCUS_POLICY, SELECT_ALL_ON_FOCUS_POLICY_ALWAYS ); + comboBox5.putClientProperty( SELECT_ALL_ON_FOCUS_POLICY, SELECT_ALL_ON_FOCUS_POLICY_ONCE ); + comboBox5.putClientProperty( SELECT_ALL_ON_MOUSE_CLICK, true ); + comboBox6.putClientProperty( SELECT_ALL_ON_FOCUS_POLICY, SELECT_ALL_ON_FOCUS_POLICY_ALWAYS ); + comboBox6.putClientProperty( SELECT_ALL_ON_MOUSE_CLICK, true ); + ((JTextField)comboBox7.getEditor().getEditorComponent()).select( 5, 7 ); + + spinner2.putClientProperty( SELECT_ALL_ON_FOCUS_POLICY, SELECT_ALL_ON_FOCUS_POLICY_NEVER ); + spinner3.putClientProperty( SELECT_ALL_ON_FOCUS_POLICY, SELECT_ALL_ON_FOCUS_POLICY_ONCE ); + spinner4.putClientProperty( SELECT_ALL_ON_FOCUS_POLICY, SELECT_ALL_ON_FOCUS_POLICY_ALWAYS ); + spinner5.putClientProperty( SELECT_ALL_ON_FOCUS_POLICY, SELECT_ALL_ON_FOCUS_POLICY_ONCE ); + spinner5.putClientProperty( SELECT_ALL_ON_MOUSE_CLICK, true ); + spinner6.putClientProperty( SELECT_ALL_ON_FOCUS_POLICY, SELECT_ALL_ON_FOCUS_POLICY_ALWAYS ); + spinner6.putClientProperty( SELECT_ALL_ON_MOUSE_CLICK, true ); + +// textArea1.putClientProperty( SELECT_ALL_ON_FOCUS_POLICY, SELECT_ALL_ON_FOCUS_POLICY_ALWAYS ); +// textPane1.putClientProperty( SELECT_ALL_ON_FOCUS_POLICY, SELECT_ALL_ON_FOCUS_POLICY_ALWAYS ); +// editorPane1.putClientProperty( SELECT_ALL_ON_FOCUS_POLICY, SELECT_ALL_ON_FOCUS_POLICY_ALWAYS ); +// +// textArea1.putClientProperty( SELECT_ALL_ON_FOCUS_POLICY, SELECT_ALL_ON_FOCUS_POLICY_ONCE ); +// textPane1.putClientProperty( SELECT_ALL_ON_FOCUS_POLICY, SELECT_ALL_ON_FOCUS_POLICY_ONCE ); +// editorPane1.putClientProperty( SELECT_ALL_ON_FOCUS_POLICY, SELECT_ALL_ON_FOCUS_POLICY_ONCE ); +// +// textArea1.putClientProperty( SELECT_ALL_ON_MOUSE_CLICK, true ); +// textPane1.putClientProperty( SELECT_ALL_ON_MOUSE_CLICK, true ); +// editorPane1.putClientProperty( SELECT_ALL_ON_MOUSE_CLICK, true ); +// +// textArea1.select( 5, 7 ); +// textPane1.select( 5, 7 ); +// editorPane1.select( 5, 7 ); + + return panel; + } + + private void initComponents() { + // JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents + panel = new FlatTestPanel(); + label1 = new JLabel(); + label2 = new JLabel(); + label3 = new JLabel(); + label4 = new JLabel(); + label5 = new JLabel(); + label6 = new JLabel(); + label7 = new JLabel(); + textFieldLabel = new JLabel(); + textField1 = new JTextField(); + textField2 = new JTextField(); + textField3 = new JTextField(); + textField4 = new JTextField(); + textField5 = new JTextField(); + textField6 = new JTextField(); + textField7 = new JTextField(); + formattedTextFieldLabel = new JLabel(); + formattedTextField1 = new JFormattedTextField(); + formattedTextField2 = new JFormattedTextField(); + formattedTextField3 = new JFormattedTextField(); + formattedTextField4 = new JFormattedTextField(); + formattedTextField5 = new JFormattedTextField(); + formattedTextField6 = new JFormattedTextField(); + comboBoxLabel = new JLabel(); + comboBox1 = new JComboBox<>(); + comboBox2 = new JComboBox<>(); + comboBox3 = new JComboBox<>(); + comboBox4 = new JComboBox<>(); + comboBox5 = new JComboBox<>(); + comboBox6 = new JComboBox<>(); + comboBox7 = new JComboBox<>(); + spinnerLabel = new JLabel(); + spinner1 = new JSpinner(); + spinner2 = new JSpinner(); + spinner3 = new JSpinner(); + spinner4 = new JSpinner(); + spinner5 = new JSpinner(); + spinner6 = new JSpinner(); + scrollPane1 = new JScrollPane(); + textArea1 = new JTextArea(); + scrollPane2 = new JScrollPane(); + textPane1 = new JTextPane(); + scrollPane3 = new JScrollPane(); + editorPane1 = new JEditorPane(); + + //======== panel ======== + { + panel.setLayout(new MigLayout( + "ltr,insets dialog,hidemode 3", + // columns + "[]" + + "[100,sizegroup 1,fill]" + + "[sizegroup 1,fill]" + + "[sizegroup 1,fill]" + + "[sizegroup 1,fill]" + + "[sizegroup 1,fill]" + + "[fill]" + + "[fill]", + // rows + "[]" + + "[]" + + "[]" + + "[]" + + "[]" + + "[fill]" + + "[30]")); + + //---- label1 ---- + label1.setText("default"); + panel.add(label1, "cell 1 0"); + + //---- label2 ---- + label2.setText("never"); + panel.add(label2, "cell 2 0"); + + //---- label3 ---- + label3.setText("once"); + panel.add(label3, "cell 3 0"); + + //---- label4 ---- + label4.setText("always"); + panel.add(label4, "cell 4 0"); + + //---- label5 ---- + label5.setText("once on click"); + panel.add(label5, "cell 5 0"); + + //---- label6 ---- + label6.setText("always on click"); + panel.add(label6, "cell 6 0"); + + //---- label7 ---- + label7.setText("custom selection"); + panel.add(label7, "cell 7 0"); + + //---- textFieldLabel ---- + textFieldLabel.setText("JTextField:"); + textFieldLabel.setDisplayedMnemonic('T'); + textFieldLabel.setLabelFor(textField1); + panel.add(textFieldLabel, "cell 0 1"); + + //---- textField1 ---- + textField1.setText("1234567890"); + panel.add(textField1, "cell 1 1"); + + //---- textField2 ---- + textField2.setText("1234567890"); + panel.add(textField2, "cell 2 1"); + + //---- textField3 ---- + textField3.setText("1234567890"); + panel.add(textField3, "cell 3 1"); + + //---- textField4 ---- + textField4.setText("1234567890"); + panel.add(textField4, "cell 4 1"); + + //---- textField5 ---- + textField5.setText("1234567890"); + panel.add(textField5, "cell 5 1"); + + //---- textField6 ---- + textField6.setText("1234567890"); + panel.add(textField6, "cell 6 1"); + + //---- textField7 ---- + textField7.setText("1234567890"); + panel.add(textField7, "cell 7 1"); + + //---- formattedTextFieldLabel ---- + formattedTextFieldLabel.setText("JFormattedTextField:"); + formattedTextFieldLabel.setDisplayedMnemonic('F'); + formattedTextFieldLabel.setLabelFor(formattedTextField1); + panel.add(formattedTextFieldLabel, "cell 0 2"); + panel.add(formattedTextField1, "cell 1 2"); + panel.add(formattedTextField2, "cell 2 2"); + panel.add(formattedTextField3, "cell 3 2"); + panel.add(formattedTextField4, "cell 4 2"); + panel.add(formattedTextField5, "cell 5 2"); + panel.add(formattedTextField6, "cell 6 2"); + + //---- comboBoxLabel ---- + comboBoxLabel.setText("JComboBox:"); + comboBoxLabel.setDisplayedMnemonic('C'); + comboBoxLabel.setLabelFor(comboBox1); + panel.add(comboBoxLabel, "cell 0 3"); + + //---- comboBox1 ---- + comboBox1.setEditable(true); + comboBox1.setModel(new DefaultComboBoxModel<>(new String[] { + "1234567890" + })); + panel.add(comboBox1, "cell 1 3"); + + //---- comboBox2 ---- + comboBox2.setEditable(true); + comboBox2.setModel(new DefaultComboBoxModel<>(new String[] { + "1234567890" + })); + panel.add(comboBox2, "cell 2 3"); + + //---- comboBox3 ---- + comboBox3.setEditable(true); + comboBox3.setModel(new DefaultComboBoxModel<>(new String[] { + "1234567890" + })); + panel.add(comboBox3, "cell 3 3"); + + //---- comboBox4 ---- + comboBox4.setEditable(true); + comboBox4.setModel(new DefaultComboBoxModel<>(new String[] { + "1234567890" + })); + panel.add(comboBox4, "cell 4 3"); + + //---- comboBox5 ---- + comboBox5.setEditable(true); + comboBox5.setModel(new DefaultComboBoxModel<>(new String[] { + "1234567890" + })); + panel.add(comboBox5, "cell 5 3"); + + //---- comboBox6 ---- + comboBox6.setEditable(true); + comboBox6.setModel(new DefaultComboBoxModel<>(new String[] { + "1234567890" + })); + panel.add(comboBox6, "cell 6 3"); + + //---- comboBox7 ---- + comboBox7.setEditable(true); + comboBox7.setModel(new DefaultComboBoxModel<>(new String[] { + "1234567890" + })); + panel.add(comboBox7, "cell 7 3"); + + //---- spinnerLabel ---- + spinnerLabel.setText("JSpinner:"); + spinnerLabel.setDisplayedMnemonic('S'); + spinnerLabel.setLabelFor(spinner1); + panel.add(spinnerLabel, "cell 0 4"); + + //---- spinner1 ---- + spinner1.setModel(new SpinnerNumberModel(1234, null, null, 100)); + panel.add(spinner1, "cell 1 4"); + + //---- spinner2 ---- + spinner2.setModel(new SpinnerNumberModel(1234, null, null, 100)); + panel.add(spinner2, "cell 2 4"); + + //---- spinner3 ---- + spinner3.setModel(new SpinnerNumberModel(1234, null, null, 100)); + panel.add(spinner3, "cell 3 4"); + + //---- spinner4 ---- + spinner4.setModel(new SpinnerNumberModel(1234, null, null, 100)); + panel.add(spinner4, "cell 4 4"); + + //---- spinner5 ---- + spinner5.setModel(new SpinnerNumberModel(1234, null, null, 100)); + panel.add(spinner5, "cell 5 4"); + + //---- spinner6 ---- + spinner6.setModel(new SpinnerNumberModel(1234, null, null, 100)); + panel.add(spinner6, "cell 6 4"); + + //======== scrollPane1 ======== + { + + //---- textArea1 ---- + textArea1.setRows(3); + textArea1.setText("1234567890\nabc"); + scrollPane1.setViewportView(textArea1); + } + panel.add(scrollPane1, "cell 1 5"); + + //======== scrollPane2 ======== + { + + //---- textPane1 ---- + textPane1.setText("1234567890\nabc"); + scrollPane2.setViewportView(textPane1); + } + panel.add(scrollPane2, "cell 2 5"); + + //======== scrollPane3 ======== + { + + //---- editorPane1 ---- + editorPane1.setText("1234567890\nabc"); + scrollPane3.setViewportView(editorPane1); + } + panel.add(scrollPane3, "cell 3 5 2 1"); + } + // JFormDesigner - End of component initialization //GEN-END:initComponents + } + + // JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables + private FlatTestPanel panel; + private JLabel label1; + private JLabel label2; + private JLabel label3; + private JLabel label4; + private JLabel label5; + private JLabel label6; + private JLabel label7; + private JLabel textFieldLabel; + private JTextField textField1; + private JTextField textField2; + private JTextField textField3; + private JTextField textField4; + private JTextField textField5; + private JTextField textField6; + private JTextField textField7; + private JLabel formattedTextFieldLabel; + private JFormattedTextField formattedTextField1; + private JFormattedTextField formattedTextField2; + private JFormattedTextField formattedTextField3; + private JFormattedTextField formattedTextField4; + private JFormattedTextField formattedTextField5; + private JFormattedTextField formattedTextField6; + private JLabel comboBoxLabel; + private JComboBox comboBox1; + private JComboBox comboBox2; + private JComboBox comboBox3; + private JComboBox comboBox4; + private JComboBox comboBox5; + private JComboBox comboBox6; + private JComboBox comboBox7; + private JLabel spinnerLabel; + private JSpinner spinner1; + private JSpinner spinner2; + private JSpinner spinner3; + private JSpinner spinner4; + private JSpinner spinner5; + private JSpinner spinner6; + private JScrollPane scrollPane1; + private JTextArea textArea1; + private JScrollPane scrollPane2; + private JTextPane textPane1; + private JScrollPane scrollPane3; + private JEditorPane editorPane1; + // JFormDesigner - End of variables declaration //GEN-END:variables +} diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatTextSelectAllOnFocusTest.jfd b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatTextSelectAllOnFocusTest.jfd new file mode 100644 index 00000000..d2a327e6 --- /dev/null +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatTextSelectAllOnFocusTest.jfd @@ -0,0 +1,327 @@ +JFDML JFormDesigner: "8.3" encoding: "UTF-8" + +new FormModel { + contentType: "form/swing" + root: new FormRoot { + add( new FormContainer( "com.formdev.flatlaf.testing.FlatTestPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { + "$layoutConstraints": "ltr,insets dialog,hidemode 3" + "$columnConstraints": "[][100,sizegroup 1,fill][sizegroup 1,fill][sizegroup 1,fill][sizegroup 1,fill][sizegroup 1,fill][fill][fill]" + "$rowConstraints": "[][][][][][fill][30]" + } ) { + name: "panel" + add( new FormComponent( "javax.swing.JLabel" ) { + name: "label1" + "text": "default" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 1 0" + } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "label2" + "text": "never" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 2 0" + } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "label3" + "text": "once" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 3 0" + } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "label4" + "text": "always" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 4 0" + } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "label5" + "text": "once on click" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 5 0" + } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "label6" + "text": "always on click" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 6 0" + } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "label7" + "text": "custom selection" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 7 0" + } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "textFieldLabel" + "text": "JTextField:" + "displayedMnemonic": 84 + "labelFor": new FormReference( "textField1" ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 1" + } ) + add( new FormComponent( "javax.swing.JTextField" ) { + name: "textField1" + "text": "1234567890" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 1 1" + } ) + add( new FormComponent( "javax.swing.JTextField" ) { + name: "textField2" + "text": "1234567890" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 2 1" + } ) + add( new FormComponent( "javax.swing.JTextField" ) { + name: "textField3" + "text": "1234567890" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 3 1" + } ) + add( new FormComponent( "javax.swing.JTextField" ) { + name: "textField4" + "text": "1234567890" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 4 1" + } ) + add( new FormComponent( "javax.swing.JTextField" ) { + name: "textField5" + "text": "1234567890" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 5 1" + } ) + add( new FormComponent( "javax.swing.JTextField" ) { + name: "textField6" + "text": "1234567890" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 6 1" + } ) + add( new FormComponent( "javax.swing.JTextField" ) { + name: "textField7" + "text": "1234567890" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 7 1" + } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "formattedTextFieldLabel" + "text": "JFormattedTextField:" + "displayedMnemonic": 70 + "labelFor": new FormReference( "formattedTextField1" ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 2" + } ) + add( new FormComponent( "javax.swing.JFormattedTextField" ) { + name: "formattedTextField1" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 1 2" + } ) + add( new FormComponent( "javax.swing.JFormattedTextField" ) { + name: "formattedTextField2" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 2 2" + } ) + add( new FormComponent( "javax.swing.JFormattedTextField" ) { + name: "formattedTextField3" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 3 2" + } ) + add( new FormComponent( "javax.swing.JFormattedTextField" ) { + name: "formattedTextField4" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 4 2" + } ) + add( new FormComponent( "javax.swing.JFormattedTextField" ) { + name: "formattedTextField5" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 5 2" + } ) + add( new FormComponent( "javax.swing.JFormattedTextField" ) { + name: "formattedTextField6" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 6 2" + } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "comboBoxLabel" + "text": "JComboBox:" + "displayedMnemonic": 67 + "labelFor": new FormReference( "comboBox1" ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 3" + } ) + add( new FormComponent( "javax.swing.JComboBox" ) { + name: "comboBox1" + "editable": true + "model": new javax.swing.DefaultComboBoxModel { + selectedItem: "1234567890" + addElement( "1234567890" ) + } + auxiliary() { + "JavaCodeGenerator.typeParameters": "String" + } + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 1 3" + } ) + add( new FormComponent( "javax.swing.JComboBox" ) { + name: "comboBox2" + "editable": true + "model": new javax.swing.DefaultComboBoxModel { + selectedItem: "1234567890" + addElement( "1234567890" ) + } + auxiliary() { + "JavaCodeGenerator.typeParameters": "String" + } + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 2 3" + } ) + add( new FormComponent( "javax.swing.JComboBox" ) { + name: "comboBox3" + "editable": true + "model": new javax.swing.DefaultComboBoxModel { + selectedItem: "1234567890" + addElement( "1234567890" ) + } + auxiliary() { + "JavaCodeGenerator.typeParameters": "String" + } + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 3 3" + } ) + add( new FormComponent( "javax.swing.JComboBox" ) { + name: "comboBox4" + "editable": true + "model": new javax.swing.DefaultComboBoxModel { + selectedItem: "1234567890" + addElement( "1234567890" ) + } + auxiliary() { + "JavaCodeGenerator.typeParameters": "String" + } + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 4 3" + } ) + add( new FormComponent( "javax.swing.JComboBox" ) { + name: "comboBox5" + "editable": true + "model": &DefaultComboBoxModel0 new javax.swing.DefaultComboBoxModel { + selectedItem: "1234567890" + addElement( "1234567890" ) + } + auxiliary() { + "JavaCodeGenerator.typeParameters": "String" + } + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 5 3" + } ) + add( new FormComponent( "javax.swing.JComboBox" ) { + name: "comboBox6" + "editable": true + "model": #DefaultComboBoxModel0 + auxiliary() { + "JavaCodeGenerator.typeParameters": "String" + } + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 6 3" + } ) + add( new FormComponent( "javax.swing.JComboBox" ) { + name: "comboBox7" + "editable": true + "model": #DefaultComboBoxModel0 + auxiliary() { + "JavaCodeGenerator.typeParameters": "String" + } + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 7 3" + } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "spinnerLabel" + "text": "JSpinner:" + "displayedMnemonic": 83 + "labelFor": new FormReference( "spinner1" ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 4" + } ) + add( new FormComponent( "javax.swing.JSpinner" ) { + name: "spinner1" + "model": new javax.swing.SpinnerNumberModel { + stepSize: 100 + value: 1234 + } + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 1 4" + } ) + add( new FormComponent( "javax.swing.JSpinner" ) { + name: "spinner2" + "model": new javax.swing.SpinnerNumberModel { + stepSize: 100 + value: 1234 + } + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 2 4" + } ) + add( new FormComponent( "javax.swing.JSpinner" ) { + name: "spinner3" + "model": new javax.swing.SpinnerNumberModel { + stepSize: 100 + value: 1234 + } + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 3 4" + } ) + add( new FormComponent( "javax.swing.JSpinner" ) { + name: "spinner4" + "model": new javax.swing.SpinnerNumberModel { + stepSize: 100 + value: 1234 + } + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 4 4" + } ) + add( new FormComponent( "javax.swing.JSpinner" ) { + name: "spinner5" + "model": &SpinnerNumberModel0 new javax.swing.SpinnerNumberModel { + stepSize: 100 + value: 1234 + } + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 5 4" + } ) + add( new FormComponent( "javax.swing.JSpinner" ) { + name: "spinner6" + "model": #SpinnerNumberModel0 + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 6 4" + } ) + add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) { + name: "scrollPane1" + add( new FormComponent( "javax.swing.JTextArea" ) { + name: "textArea1" + "rows": 3 + "text": "1234567890\nabc" + } ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 1 5" + } ) + add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) { + name: "scrollPane2" + add( new FormComponent( "javax.swing.JTextPane" ) { + name: "textPane1" + "text": "1234567890\nabc" + } ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 2 5" + } ) + add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) { + name: "scrollPane3" + add( new FormComponent( "javax.swing.JEditorPane" ) { + name: "editorPane1" + "text": "1234567890\nabc" + } ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 3 5 2 1" + } ) + }, new FormLayoutConstraints( null ) { + "location": new java.awt.Point( 0, 0 ) + "size": new java.awt.Dimension( 995, 285 ) + } ) + } +} diff --git a/flatlaf-theme-editor/build.gradle.kts b/flatlaf-theme-editor/build.gradle.kts index ffbd4982..d334d2e8 100644 --- a/flatlaf-theme-editor/build.gradle.kts +++ b/flatlaf-theme-editor/build.gradle.kts @@ -46,6 +46,9 @@ tasks { if( JavaVersion.current() >= JavaVersion.VERSION_1_9 ) attributes( "Multi-Release" to "true" ) + + // allow loading FlatLaf native library in Java 24+ (see https://openjdk.org/jeps/472) + attributes( "Enable-Native-Access" to "ALL-UNNAMED" ) } exclude( "module-info.class" ) diff --git a/gradle.properties b/gradle.properties index 6902d50c..2d00cb10 100644 --- a/gradle.properties +++ b/gradle.properties @@ -14,8 +14,8 @@ # limitations under the License. # -flatlaf.releaseVersion = 3.5.4 -flatlaf.developmentVersion = 3.6-SNAPSHOT +flatlaf.releaseVersion = 3.6 +flatlaf.developmentVersion = 3.7-SNAPSHOT org.gradle.parallel = true # org.gradle.warning.mode = all diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 6bd75ca2..ee8ec1ab 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -24,7 +24,7 @@ junit = "5.10.2" sigtest = "org.netbeans.tools:sigtest-maven-plugin:1.7" # flatlaf-extras -jsvg = "com.github.weisj:jsvg:1.4.0" +jsvg = "com.github.weisj:jsvg:2.0.0" # flatlaf-jide-oss jide-oss = "com.formdev:jide-oss:3.7.15" @@ -59,4 +59,5 @@ errorprone = "com.google.errorprone:error_prone_core:2.20.0" [plugins] +gradle-nexus-publish-plugin = { id = "io.github.gradle-nexus.publish-plugin", version = "2.0.0" } errorprone = { id = "net.ltgt.errorprone", version = "3.1.0" } diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index a4b76b95..1b33c55b 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e18bc253..002b867c 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.12.1-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.1-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index f3b75f3b..23d15a93 100755 --- a/gradlew +++ b/gradlew @@ -114,7 +114,7 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar +CLASSPATH="\\\"\\\"" # Determine the Java command to use to start the JVM. @@ -205,7 +205,7 @@ fi DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Collect all arguments for the java command: -# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, # and any embedded shellness will be escaped. # * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be # treated as '${Hostname}' itself on the command line. @@ -213,7 +213,7 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ -classpath "$CLASSPATH" \ - org.gradle.wrapper.GradleWrapperMain \ + -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" # Stop when "xargs" is not available. diff --git a/gradlew.bat b/gradlew.bat index 9d21a218..db3a6ac2 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -70,11 +70,11 @@ goto fail :execute @rem Setup the command line -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar +set CLASSPATH= @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell