Compare commits

...

30 Commits

Author SHA1 Message Date
Karl Tauber
97988e90b4 release 3.6.1 2025-07-12 16:44:32 +02:00
Karl Tauber
f71dbb2647 Linux: ensure that old LinuxPopupMenuCanceler window listener is removed before adding a new one (issue #962)
(did not yet happen...)
2025-07-12 16:28:49 +02:00
Karl Tauber
04ad21b5b6 Button: added unit tests for foreground and background colors (issue #1017) 2025-07-12 15:59:56 +02:00
Karl Tauber
ff722c0b34 Popup:
- macOS: Fixed popup flickering after theme change. (issue #1009)
- macOS with JetBrains Runtime: Fixed sometimes empty popups. (issue #1019)
2025-07-07 18:33:49 +02:00
Karl Tauber
34b19f00e4 Window decorations (Windows 10/11 only):
- improved diagonal window resizing on top-left and top-right window corners
- top window resize area now also covers iconify/maximize/close buttons
(issue #1015)
2025-07-03 20:08:40 +02:00
Karl Tauber
286ce15146 ToggleButton: styling selectedForeground did not work if foreground is also styled (issue #1017) 2025-07-02 20:08:55 +02:00
Karl Tauber
abfaf86cd5 change snapshot version from 3.7-SNAPSHOT to 3.6.1-SNAPSHOT 2025-07-02 19:50:51 +02:00
Karl Tauber
bc4c7b25d3 snapshots: publish macOS .dylib native libraries to Maven Central Snapshots (disabled in commit 5575854e68) 2025-06-23 16:56:38 +02:00
Karl Tauber
0863e289a1 Table: add disabled icon for boolean renderer (issue #1008) 2025-06-20 19:56:24 +02:00
Karl Tauber
4945378dd3 macOS themes: fixed rendering of menu bar separator if unified background is disabled (issue #1003) 2025-06-12 10:45:57 +02:00
Karl Tauber
b178450e81 README.md: new applications using FlatLaf:
- SSPlot (issue #1002)
2025-06-12 10:28:24 +02:00
Karl Tauber
e3ffdd3b7c UIDefaultsLoader: improved error reporting and added more unit tests 2025-05-28 00:32:35 +02:00
Karl Tauber
5326971287 Linux: popups appeared in wrong position on multi-screen setup if primary display is located below or right to secondary display (issue https://github.com/apache/netbeans/issues/8532)) 2025-05-27 20:01:04 +02:00
Karl Tauber
cd34c08dc9 README.md: new applications using FlatLaf:
- Zettelkasten
- Convertigo
- EduMIPS64
- OpenPnP
- TrainControl
- Pixelitor
- Gephi
- StarPlan
- Lisheane ERP
- jose
2025-05-24 14:38:31 +02:00
Karl Tauber
edee73e0ea README.md: removed "new" badge from applications added in 2023 (and before) 2025-05-24 13:06:27 +02:00
Karl Tauber
54a53fb527 IntelliJ Themes: fixed logging false errors when loading 3rd party .theme.json files (issue #990) 2025-05-24 13:02:29 +02:00
Karl Tauber
62b96fbccd JideSplitButton: fixed updating popup when switching theme (issue #1000) 2025-05-23 19:31:42 +02:00
Karl Tauber
42cbb0666d README.md: added RedisFront (issue #989) 2025-05-23 01:17:14 +02:00
Karl Tauber
1465fbaabc Merge PR #992: Add Termora to Utilities list 2025-05-23 01:11:48 +02:00
Karl Tauber
5575854e68 migrate from legacy OSSRH to Central Portal
https://central.sonatype.org/faq/what-is-different-between-central-portal-and-legacy-ossrh/

using Portal OSSRH Staging API
https://central.sonatype.org/publish/publish-portal-ossrh-staging-api/
2025-05-23 00:59:32 +02:00
Karl Tauber
640f2ba9a2 update to Gradle 8.14.1 2025-05-23 00:49:02 +02:00
Karl Tauber
b221fd1894 Extras: Support JSVG 2.0.0. Minimum JSVG version is now 1.6.0. (issue #997) 2025-04-30 19:39:25 +02:00
hstyi
b64ab09b88 Add Termora to Utilities list 2025-04-14 15:39:25 +08:00
Karl Tauber
2870ee5c51 release 3.6 2025-04-11 12:00:51 +02:00
Karl Tauber
23f8ce867b Demo on Linux: support toggling FlatLaf window decorations (menu "Options > Window decorations") 2025-03-23 13:58:02 +01:00
Karl Tauber
835a1f155b ScrollBar: use rounded thumb also on Windows (as on macOS and Linux) and made thumb slightly darker/lighter (issue #918) 2025-03-23 13:01:15 +01:00
Karl Tauber
3925f198d9 Demo and Theme Editor: added Enable-Native-Access: ALL-UNNAMED to MANIFEST.MF to avoid warning when lauchned with Java 24 2025-03-22 18:13:10 +01:00
Karl Tauber
d8e59f2cf3 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`.
2025-03-16 11:24:01 +01:00
Karl Tauber
666b99971d Merge PR #971: Linux: rounded iconify/maximize/close buttons if using FlatLaf window decorations 2025-03-09 16:41:51 +01:00
Karl Tauber
ae4037ee82 Linux: rounded iconify/maximize/close buttons if using FlatLaf window decorations (issue #821) 2025-02-18 13:33:02 +01:00
67 changed files with 2397 additions and 383 deletions

View File

@@ -105,11 +105,11 @@ jobs:
distribution: temurin # pre-installed on ubuntu-latest distribution: temurin # pre-installed on ubuntu-latest
cache: gradle 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 run: ./gradlew publish -PskipFonts -Dorg.gradle.internal.publish.checksums.insecure=true -Dorg.gradle.parallel=false
env: env:
OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }} SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }}
OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }} SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }}
release: release:
@@ -131,10 +131,10 @@ jobs:
cache: gradle cache: gradle
- name: Release a new stable version to Maven Central - 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: env:
OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }} SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }}
OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }} SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }}
SIGNING_KEY: ${{ secrets.SIGNING_KEY }} SIGNING_KEY: ${{ secrets.SIGNING_KEY }}
SIGNING_PASSWORD: ${{ secrets.SIGNING_PASSWORD }} SIGNING_PASSWORD: ${{ secrets.SIGNING_PASSWORD }}

View File

@@ -45,18 +45,18 @@ jobs:
run: ./gradlew :flatlaf-fonts-${{ matrix.font }}:build run: ./gradlew :flatlaf-fonts-${{ matrix.font }}:build
if: startsWith( github.ref, format( 'refs/tags/fonts/{0}-', matrix.font ) ) != true 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 run: ./gradlew :flatlaf-fonts-${{ matrix.font }}:publish -Dorg.gradle.internal.publish.checksums.insecure=true
env: env:
OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }} SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }}
OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }} SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }}
if: github.ref == 'refs/heads/main' || startsWith( github.ref, 'refs/heads/develop-' ) if: github.ref == 'refs/heads/main' || startsWith( github.ref, 'refs/heads/develop-' )
- name: Release a new stable version to Maven Central - name: Release a new stable version to Maven Central
run: ./gradlew :flatlaf-fonts-${{ matrix.font }}:build :flatlaf-fonts-${{ matrix.font }}:publish -Prelease run: ./gradlew :flatlaf-fonts-${{ matrix.font }}:build :flatlaf-fonts-${{ matrix.font }}:publish -Prelease
env: env:
OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }} SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }}
OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }} SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }}
SIGNING_KEY: ${{ secrets.SIGNING_KEY }} SIGNING_KEY: ${{ secrets.SIGNING_KEY }}
SIGNING_PASSWORD: ${{ secrets.SIGNING_PASSWORD }} SIGNING_PASSWORD: ${{ secrets.SIGNING_PASSWORD }}
if: startsWith( github.ref, format( 'refs/tags/fonts/{0}-', matrix.font ) ) if: startsWith( github.ref, format( 'refs/tags/fonts/{0}-', matrix.font ) )

View File

@@ -28,10 +28,10 @@ jobs:
distribution: temurin # pre-installed on ubuntu-latest distribution: temurin # pre-installed on ubuntu-latest
cache: gradle cache: gradle
- name: Publish PR snapshot to oss.sonatype.org - name: Publish PR snapshot to Sonatype Central
run: > run: >
./gradlew publish -PskipFonts -Dorg.gradle.internal.publish.checksums.insecure=true -Dorg.gradle.parallel=false ./gradlew publish -PskipFonts -Dorg.gradle.internal.publish.checksums.insecure=true -Dorg.gradle.parallel=false
-Pgithub.event.pull_request.number=${{ github.event.pull_request.number }} -Pgithub.event.pull_request.number=${{ github.event.pull_request.number }}
env: env:
OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }} SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }}
OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }} SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }}

View File

@@ -1,7 +1,25 @@
FlatLaf Change Log FlatLaf Change Log
================== ==================
## 3.6-SNAPSHOT ## 3.6.1
- Extras: Support JSVG 2.0.0. Minimum JSVG version is now 1.6.0. (issue #997)
- FlatLaf window decorations (Windows 10/11 only): Improved diagonal window
resizing on top-left and top-right window corners. Top window resize area now
also covers iconify/maximize/close buttons. (issue #1015)
- ToggleButton: Styling `selectedForeground` did not work if `foreground` is
also styled. (issue #1017)
- 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))
- macOS: Fixed popup flickering after theme change. (issue #1009)
- macOS with JetBrains Runtime: Fixed sometimes empty popups. (issue #1019)
## 3.6
#### New features and improvements #### New features and improvements
@@ -21,12 +39,17 @@ FlatLaf Change Log
- List: Support for alternate row highlighting. (PR #939) - List: Support for alternate row highlighting. (PR #939)
- Tree: Support for alternate row highlighting. (PR #903) - Tree: Support for alternate row highlighting. (PR #903)
- Tree: Support wide cell renderer. (issue #922) - 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 - Extras: `FlatSVGIcon` color filters now can access painting component to
implement component state based color mappings. (issue #906) implement component state based color mappings. (issue #906)
- Linux: Added `libflatlaf-linux-arm64.so` for Linux on ARM64. (issue #899) - Linux:
- Linux: Use X11 window manager events to resize window, if FlatLaf window - Rounded iconify/maximize/close buttons if using FlatLaf window decorations.
decorations are enabled. This gives FlatLaf windows a more "native" feeling. (PR #971)
(issue #866) - Added `libflatlaf-linux-arm64.so` for Linux on ARM64. (issue #899)
- Use X11 window manager events to resize window, if FlatLaf window
decorations are enabled. This gives FlatLaf windows a more "native" feeling.
(issue #866)
- IntelliJ Themes: - IntelliJ Themes:
- Updated to latest versions and fixed various issues. - Updated to latest versions and fixed various issues.
- Support customizing through properties files. (issue #824) - Support customizing through properties files. (issue #824)
@@ -67,6 +90,21 @@ FlatLaf Change Log
application where multiple class loaders are involved. E.g. in Eclipse plugin application where multiple class loaders are involved. E.g. in Eclipse plugin
or in LibreOffice extension. (issues #955 and #851) or in LibreOffice extension. (issues #955 and #851)
- HTML: Fixed rendering of `<hr noshade>` in dark themes. (issue #932) - HTML: Fixed rendering of `<hr noshade>` 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 #### Incompatibilities

View File

@@ -83,10 +83,10 @@ application.
### Snapshots ### Snapshots
FlatLaf snapshot binaries are available on 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 access the latest snapshot, change the FlatLaf version in your dependencies
to `<version>-SNAPSHOT` (e.g. `0.27-SNAPSHOT`) and add the repository to `<version>-SNAPSHOT` (e.g. `3.7-SNAPSHOT`) and add the repository
`https://oss.sonatype.org/content/repositories/snapshots/` to your build (see `https://central.sonatype.com/repository/maven-snapshots/` to your build (see
[Maven](https://maven.apache.org/guides/mini/guide-multiple-repositories.html) [Maven](https://maven.apache.org/guides/mini/guide-multiple-repositories.html)
and and
[Gradle](https://docs.gradle.org/current/userguide/declaring_repositories.html#sec:declaring_custom_repository) [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 relational data browsing tool
- ![Hot](images/hot.svg) [MagicPlot](https://magicplot.com/) (**commercial**) - - ![Hot](images/hot.svg) [MagicPlot](https://magicplot.com/) (**commercial**) -
Software for nonlinear fitting, plotting and data analysis Software for nonlinear fitting, plotting and data analysis
- ![New](images/new.svg) [Constellation](https://www.constellation-app.com/) - - [Constellation](https://www.constellation-app.com/) - Data Visualization and
Data Visualization and Analytics (based on NetBeans platform) Analytics (based on NetBeans platform)
- ![New](images/new.svg) - [Kafka Visualizer](https://github.com/kumait/kafkavisualizer) - Kafka GUI
[Kafka Visualizer](https://github.com/kumait/kafkavisualizer) - Kafka GUI
client 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 ### Security
@@ -197,11 +202,9 @@ Applications using FlatLaf
- ![Hot](images/hot.svg) - ![Hot](images/hot.svg)
[Burp Suite Professional and Community Edition](https://portswigger.net/burp/pro) [Burp Suite Professional and Community Edition](https://portswigger.net/burp/pro)
(**commercial**) - the leading software for web security testing (**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 reverse engineering (SRE) framework
- ![New](images/new.svg) [jadx](https://github.com/skylot/jadx) - Dex to Java - [jadx](https://github.com/skylot/jadx) - Dex to Java decompiler
decompiler
- [BurpCustomizer](https://github.com/CoreyD97/BurpCustomizer) - adds more - [BurpCustomizer](https://github.com/CoreyD97/BurpCustomizer) - adds more
FlatLaf themes to Burp Suite FlatLaf themes to Burp Suite
- [Total Validator](https://www.totalvalidator.com/) (**commercial**) - checks - [Total Validator](https://www.totalvalidator.com/) (**commercial**) - checks
@@ -213,13 +216,12 @@ Applications using FlatLaf
- [jclasslib bytecode viewer](https://github.com/ingokegel/jclasslib) - [jclasslib bytecode viewer](https://github.com/ingokegel/jclasslib)
- [KeyStore Explorer](https://keystore-explorer.org/) - [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 cross-platform file manager
- ![New](images/new.svg) [Guiffy](https://www.guiffy.com/) (**commercial**) - - [Guiffy](https://www.guiffy.com/) (**commercial**) - advanced cross-platform
advanced cross-platform Diff/Merge Diff/Merge
- ![New](images/new.svg) [HashGarten](https://github.com/jonelo/HashGarten) - - [HashGarten](https://github.com/jonelo/HashGarten) - cross-platform Swing GUI
cross-platform Swing GUI for Jacksum for Jacksum
- [Pseudo Assembler IDE](https://github.com/tomasz-herman/PseudoAssemblerIDE) - - [Pseudo Assembler IDE](https://github.com/tomasz-herman/PseudoAssemblerIDE) -
IDE for Pseudo-Assembler IDE for Pseudo-Assembler
- [Linotte](https://github.com/cpc6128/LangageLinotte) - French programming - [Linotte](https://github.com/cpc6128/LangageLinotte) - French programming
@@ -228,6 +230,10 @@ Applications using FlatLaf
systems development platform systems development platform
- ![New](images/new.svg) [Consulo](https://github.com/consulo/consulo) - open - ![New](images/new.svg) [Consulo](https://github.com/consulo/consulo) - open
source cross-platform multi-language IDE (Java, .NET, JS, etc) 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 ### Electrical
@@ -235,6 +241,11 @@ Applications using FlatLaf
designing, simulating and explaining digital circuits designing, simulating and explaining digital circuits
- [Logisim-evolution](https://github.com/logisim-evolution/logisim-evolution) - - [Logisim-evolution](https://github.com/logisim-evolution/logisim-evolution) -
Digital logic design tool and simulator 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) - - [Makelangelo Software](https://github.com/MarginallyClever/Makelangelo-software) -
for plotters, especially the wall-hanging polargraph for plotters, especially the wall-hanging polargraph
- [GUIslice Builder](https://github.com/ImpulseAdventure/GUIslice-Builder) - GUI - [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**) - - ![Hot](images/hot.svg) [jAlbum](https://jalbum.net/) (**commercial**) -
creates photo album websites creates photo album websites
- ![New](images/new.svg) [MediathekView](https://mediathekview.de/) - search in - [MediathekView](https://mediathekview.de/) - search in media libraries of
media libraries of various German broadcasters various German broadcasters
- ![New](images/new.svg) [Pixelitor](https://github.com/lbalazscs/Pixelitor) -
image editor
- [Cinecred](https://loadingbyte.com/cinecred/) - create beautiful film credit - [Cinecred](https://loadingbyte.com/cinecred/) - create beautiful film credit
sequences sequences
- [tinyMediaManager](https://www.tinymediamanager.org/) (**commercial**) - a - [tinyMediaManager](https://www.tinymediamanager.org/) (**commercial**) - a
@@ -267,18 +280,23 @@ Applications using FlatLaf
- [lectureStudio](https://www.lecturestudio.org/) - digitize your lectures with - [lectureStudio](https://www.lecturestudio.org/) - digitize your lectures with
ease ease
### Modelling ### Modelling / Planning
- ![New](images/new.svg) [Astah](https://astah.net/) (**commercial**) - create - ![New](images/new.svg) [Gephi](https://github.com/gephi/gephi) - the Open
UML, ER Diagram, Flowchart, Data Flow Diagram, Requirement Diagram, SysML Graph Viz Platform
diagrams and more - [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 - [IGMAS+](https://www.gfz-potsdam.de/igmas) - Interactive Gravity and Magnetic
Application System 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 ### Documents
- ![New](images/new.svg) [Big Faceless (BFO) PDF Viewer](https://bfo.com/) - [Big Faceless (BFO) PDF Viewer](https://bfo.com/) (**commercial**) - Swing PDF
(**commercial**) - Swing PDF Viewer Viewer
- [PDF Studio](https://www.qoppa.com/pdfstudio/) (**commercial**) - create, - [PDF Studio](https://www.qoppa.com/pdfstudio/) (**commercial**) - create,
review and edit PDF documents review and edit PDF documents
- [XMLmind XML Editor](https://www.xmlmind.com/xmleditor/) (**commercial**) - [XMLmind XML Editor](https://www.xmlmind.com/xmleditor/) (**commercial**)
@@ -296,6 +314,9 @@ Applications using FlatLaf
### Business / Legal ### Business / Legal
- ![New](images/new.svg) ![Sponsor](images/sponsor.svg)
[Lisheane ERP](https://www.lisheane.ch/) (**commercial**) - backoffice
applikation
- ![Sponsor](images/sponsor.svg) - ![Sponsor](images/sponsor.svg)
[j-lawyer](https://github.com/jlawyerorg/j-lawyer-org) - Kanzleisoftware [j-lawyer](https://github.com/jlawyerorg/j-lawyer-org) - Kanzleisoftware
- ![Sponsor](images/sponsor.svg) [Jeyla Studio](https://www.jeylastudio.com/) - - ![Sponsor](images/sponsor.svg) [Jeyla Studio](https://www.jeylastudio.com/) -
@@ -312,20 +333,20 @@ Applications using FlatLaf
### Messaging ### Messaging
- ![New](images/new.svg) [Spark](https://github.com/igniterealtime/Spark) - - [Spark](https://github.com/igniterealtime/Spark) - cross-platform IM client
cross-platform IM client optimized for businesses and organizations optimized for businesses and organizations
- ![New](images/new.svg) [Chatty](https://github.com/chatty/chatty) - Twitch - [Chatty](https://github.com/chatty/chatty) - Twitch Chat Client
Chat Client
### Gaming ### Gaming
- ![New](images/new.svg) ![Sponsor](images/sponsor.svg) - ![Sponsor](images/sponsor.svg) [BGBlitz](https://www.bgblitz.com/)
[BGBlitz](https://www.bgblitz.com/) (**commercial**) - professional Backgammon (**commercial**) - professional Backgammon
- ![New](images/new.svg) [MCreator](https://github.com/MCreator/MCreator) - - ![New](images/new.svg) [josé](https://peteschaefer.github.io/jose/) - a
software used to make Minecraft Java Edition mods, Minecraft Bedrock Edition Add-Ons, graphical chess tool
and data packs without programming knowledge - ![New](images/new.svg) [MCreator](https://github.com/MCreator/MCreator) - make
- ![New](images/new.svg) [MapTool](https://github.com/RPTools/maptool) - virtual Minecraft Java Edition mods, Minecraft Bedrock Edition Add-Ons, and data packs
Tabletop for playing role-playing games - [MapTool](https://github.com/RPTools/maptool) - virtual Tabletop for playing
role-playing games
- [MegaMek](https://github.com/MegaMek/megamek), - [MegaMek](https://github.com/MegaMek/megamek),
[MegaMekLab](https://github.com/MegaMek/megameklab) and [MegaMekLab](https://github.com/MegaMek/megameklab) and
[MekHQ](https://github.com/MegaMek/mekhq) - a sci-fi tabletop BattleTech [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 - [MooInfo](https://github.com/rememberber/MooInfo) - visual implementation of
OSHI, to view information about the system and hardware 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 GUI for monitoring and managing various aspects of a Linux system
- [Rest Suite](https://github.com/supanadit/restsuite) - Rest API testing - [Rest Suite](https://github.com/supanadit/restsuite) - Rest API testing
- [SpringRemote](https://github.com/HaleyWang/SpringRemote) - remote Linux SSH - [SpringRemote](https://github.com/HaleyWang/SpringRemote) - remote Linux SSH
@@ -347,6 +367,8 @@ Applications using FlatLaf
easy easy
- [Android Tool](https://github.com/fast-geek/Android-Tool) - makes popular adb - [Android Tool](https://github.com/fast-geek/Android-Tool) - makes popular adb
and fastboot commands easier to use and fastboot commands easier to use
- ![New](images/new.svg) [Termora](https://github.com/TermoraDev/termora) -
Terminal emulator and SSH client
### Miscellaneous ### Miscellaneous

View File

@@ -16,6 +16,7 @@
import net.ltgt.gradle.errorprone.errorprone import net.ltgt.gradle.errorprone.errorprone
group = "com.formdev"
version = property( if( hasProperty( "release" ) ) "flatlaf.releaseVersion" else "flatlaf.developmentVersion" ) as String version = property( if( hasProperty( "release" ) ) "flatlaf.releaseVersion" else "flatlaf.developmentVersion" ) as String
// for PR snapshots change version to 'PR-<pr_number>-SNAPSHOT' // for PR snapshots change version to 'PR-<pr_number>-SNAPSHOT'
@@ -49,6 +50,7 @@ println()
plugins { plugins {
alias( libs.plugins.gradle.nexus.publish.plugin )
alias( libs.plugins.errorprone ) apply false 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
}
}
}

View File

@@ -86,24 +86,26 @@ publishing {
} }
} }
/*
repositories { repositories {
maven { maven {
name = "OSSRH" name = "MavenCentral"
val releasesRepoUrl = "https://oss.sonatype.org/service/local/staging/deploy/maven2/" val releasesRepoUrl = "https://ossrh-staging-api.central.sonatype.com/service/local/staging/deploy/maven2/"
val snapshotsRepoUrl = "https://oss.sonatype.org/content/repositories/snapshots/" val snapshotsRepoUrl = "https://central.sonatype.com/repository/maven-snapshots/"
url = uri( if( rootProject.hasProperty( "release" ) ) releasesRepoUrl else snapshotsRepoUrl ) url = uri( if( rootProject.hasProperty( "release" ) ) releasesRepoUrl else snapshotsRepoUrl )
credentials { credentials {
// get from gradle.properties // get from gradle.properties
val ossrhUsername: String? by project val sonatypeUsername: String? by project
val ossrhPassword: String? by project val sonatypePassword: String? by project
username = System.getenv( "OSSRH_USERNAME" ) ?: ossrhUsername username = System.getenv( "SONATYPE_USERNAME" ) ?: sonatypeUsername
password = System.getenv( "OSSRH_PASSWORD" ) ?: ossrhPassword password = System.getenv( "SONATYPE_PASSWORD" ) ?: sonatypePassword
} }
} }
} }
*/
} }
signing { signing {

View File

@@ -1,5 +1,5 @@
#Signature file v4.1 #Signature file v4.1
#Version 3.5.2 #Version 3.6.1
CLSS public abstract interface com.formdev.flatlaf.FlatClientProperties CLSS public abstract interface com.formdev.flatlaf.FlatClientProperties
fld public final static java.lang.String BUTTON_TYPE = "JButton.buttonType" 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 MINIMUM_WIDTH = "JComponent.minimumWidth"
fld public final static java.lang.String OUTLINE = "JComponent.outline" 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_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 OUTLINE_WARNING = "warning"
fld public final static java.lang.String PLACEHOLDER_TEXT = "JTextField.placeholderText" fld public final static java.lang.String PLACEHOLDER_TEXT = "JTextField.placeholderText"
fld public final static java.lang.String POPUP_BORDER_CORNER_RADIUS = "Popup.borderCornerRadius" 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_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_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_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 = "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_LEFT = "left"
fld public final static java.lang.String SPLIT_PANE_EXPANDABLE_SIDE_RIGHT = "right" 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_MAXIMIZE = "JRootPane.titleBarShowMaximize"
fld public final static java.lang.String TITLE_BAR_SHOW_TITLE = "JRootPane.titleBarShowTitle" 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_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 TREE_WIDE_SELECTION = "JTree.wideSelection"
fld public final static java.lang.String USE_WINDOW_DECORATIONS = "JRootPane.useWindowDecorations" fld public final static java.lang.String USE_WINDOW_DECORATIONS = "JRootPane.useWindowDecorations"
fld public final static java.lang.String WINDOW_STYLE = "Window.style" 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 getPreferredLightFontFamily()
meth public static java.lang.String getPreferredMonospacedFontFamily() meth public static java.lang.String getPreferredMonospacedFontFamily()
meth public static java.lang.String getPreferredSemiboldFontFamily() meth public static java.lang.String getPreferredSemiboldFontFamily()
meth public static java.lang.String getUIKeyLightOrDarkPrefix(boolean)
meth public static java.util.Map<java.lang.String,java.lang.Class<?>> getStyleableInfos(javax.swing.JComponent) meth public static java.util.Map<java.lang.String,java.lang.Class<?>> getStyleableInfos(javax.swing.JComponent)
meth public static java.util.Map<java.lang.String,java.lang.String> getGlobalExtraDefaults() meth public static java.util.Map<java.lang.String,java.lang.String> getGlobalExtraDefaults()
meth public static java.util.Set<java.lang.String> getUIKeyPlatformPrefixes()
meth public static java.util.Set<java.lang.String> getUIKeySpecialPrefixes()
meth public static java.util.function.Function<java.lang.String,java.awt.Color> getSystemColorGetter() meth public static java.util.function.Function<java.lang.String,java.awt.Color> getSystemColorGetter()
meth public static javax.swing.UIDefaults$ActiveValue createActiveFontValue(float) meth public static javax.swing.UIDefaults$ActiveValue createActiveFontValue(float)
meth public static void disableWindowsD3Donscreen() meth public static void disableWindowsD3Donscreen()
@@ -255,7 +261,7 @@ meth public void setExtraDefaults(java.util.Map<java.lang.String,java.lang.Strin
meth public void uninitialize() meth public void uninitialize()
meth public void unregisterUIDefaultsGetter(java.util.function.Function<java.lang.Object,java.lang.Object>) meth public void unregisterUIDefaultsGetter(java.util.function.Function<java.lang.Object,java.lang.Object>)
supr javax.swing.plaf.basic.BasicLookAndFeel 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 hcls ActiveFont,FlatUIDefaults,ImageIconUIResource
CLSS public abstract interface static com.formdev.flatlaf.FlatLaf$DisabledIconProvider 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(com.formdev.flatlaf.IntelliJTheme)
meth public static com.formdev.flatlaf.FlatLaf createLaf(java.io.InputStream) throws java.io.IOException meth public static com.formdev.flatlaf.FlatLaf createLaf(java.io.InputStream) throws java.io.IOException
supr java.lang.Object 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,uiKeyExcludesContains,uiKeyExcludesStartsWith,uiKeyInverseMapping,uiKeyMapping
CLSS public static com.formdev.flatlaf.IntelliJTheme$ThemeLaf CLSS public static com.formdev.flatlaf.IntelliJTheme$ThemeLaf
outer com.formdev.flatlaf.IntelliJTheme outer com.formdev.flatlaf.IntelliJTheme
@@ -413,6 +419,7 @@ innr public static Fade
innr public static HSLChange innr public static HSLChange
innr public static HSLIncreaseDecrease innr public static HSLIncreaseDecrease
innr public static Mix 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 !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 clamp(float)
meth public static float luma(java.awt.Color) meth public static float luma(java.awt.Color)
@@ -474,6 +481,16 @@ meth public java.lang.String toString()
meth public void apply(float[]) meth public void apply(float[])
supr java.lang.Object 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 CLSS public com.formdev.flatlaf.util.CubicBezierEasing
cons public init(float,float,float,float) cons public init(float,float,float,float)
fld public final static com.formdev.flatlaf.util.CubicBezierEasing EASE 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 CLSS public com.formdev.flatlaf.util.SystemInfo
cons public init() cons public init()
fld public final static boolean isAARCH64 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_11_orLater
fld public final static boolean isJava_12_orLater fld public final static boolean isJava_12_orLater
fld public final static boolean isJava_15_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_14_Mojave_orLater
fld public final static boolean isMacOS_10_15_Catalina_orLater fld public final static boolean isMacOS_10_15_Catalina_orLater
fld public final static boolean isProjector fld public final static boolean isProjector
fld public final static boolean isUnknownOS
fld public final static boolean isWebswing fld public final static boolean isWebswing
fld public final static boolean isWinPE fld public final static boolean isWinPE
fld public final static boolean isWindows fld public final static boolean isWindows

View File

@@ -21,6 +21,8 @@ import java.awt.IllegalComponentStateException;
import java.awt.Window; import java.awt.Window;
import java.util.Objects; import java.util.Objects;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.JFormattedTextField;
import javax.swing.JSpinner;
import javax.swing.SwingConstants; import javax.swing.SwingConstants;
/** /**
@@ -1209,12 +1211,15 @@ public interface FlatClientProperties
/** /**
* Specifies whether all text is selected when the text component gains focus. * Specifies whether all text is selected when the text component gains focus.
* <p> * <p>
* <strong>Component</strong> {@link javax.swing.JTextField} (and subclasses)<br> * <strong>Components</strong> {@link javax.swing.text.JTextComponent} (and subclasses),
* {@link javax.swing.JComboBox} (since 3.6) and {@link javax.swing.JSpinner} (since 3.6)<br>
* <strong>Value type</strong> {@link java.lang.String}<br> * <strong>Value type</strong> {@link java.lang.String}<br>
* <strong>Allowed Values</strong> * <strong>Allowed Values</strong>
* {@link #SELECT_ALL_ON_FOCUS_POLICY_NEVER}, * {@link #SELECT_ALL_ON_FOCUS_POLICY_NEVER},
* {@link #SELECT_ALL_ON_FOCUS_POLICY_ONCE} (default) or * {@link #SELECT_ALL_ON_FOCUS_POLICY_ONCE} (default) or
* {@link #SELECT_ALL_ON_FOCUS_POLICY_ALWAYS} * {@link #SELECT_ALL_ON_FOCUS_POLICY_ALWAYS}
*
* @see #SELECT_ALL_ON_MOUSE_CLICK
*/ */
String SELECT_ALL_ON_FOCUS_POLICY = "JTextField.selectAllOnFocusPolicy"; 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 * Select all text when the text component gains focus for the first time
* and selection was not modified (is at end of text). * and selection was not modified (is at end of text).
* This is the default. * This is the default.
* <p>
* <b>Limitations:</b>
* 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 * @see #SELECT_ALL_ON_FOCUS_POLICY
*/ */
@@ -1241,6 +1252,19 @@ public interface FlatClientProperties
*/ */
String SELECT_ALL_ON_FOCUS_POLICY_ALWAYS = "always"; 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).
* <p>
* <strong>Components</strong> {@link javax.swing.text.JTextComponent} (and subclasses),
* {@link javax.swing.JComboBox} and {@link javax.swing.JSpinner}<br>
* <strong>Value type</strong> {@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. * Placeholder text that is only painted if the text field is empty.
* <p> * <p>

View File

@@ -413,22 +413,37 @@ public class IntelliJTheme
key.equals( "Tree.rightChildIndent" ) ) key.equals( "Tree.rightChildIndent" ) )
return; // ignore return; // ignore
// ignore icons
if( key.endsWith( "Icon" ) )
return; // ignore
// map keys // map keys
key = uiKeyMapping.getOrDefault( key, key ); key = uiKeyMapping.getOrDefault( key, key );
if( key.isEmpty() ) if( key.isEmpty() )
return; // ignore key return; // ignore key
// exclude properties // exclude properties (1st level)
int dot = key.indexOf( '.' ); 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; 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 ) ) if( uiKeyDoNotOverride.contains( key ) && jsonUIKeys.contains( key ) )
return; return;
jsonUIKeys.add( key ); jsonUIKeys.add( key );
String valueStr = value.toString(); String valueStr = value.toString().trim();
// map named colors // map named colors
String uiValue = namedColors.get( valueStr ); String uiValue = namedColors.get( valueStr );
@@ -657,7 +672,8 @@ public class IntelliJTheme
} }
} }
private static final Set<String> uiKeyExcludes; private static final Set<String> uiKeyExcludesStartsWith;
private static final String[] uiKeyExcludesContains;
private static final Set<String> uiKeyDoNotOverride; private static final Set<String> uiKeyDoNotOverride;
/** Rename UI default keys (key --> value). */ /** Rename UI default keys (key --> value). */
private static final Map<String, String> uiKeyMapping = new HashMap<>(); private static final Map<String, String> uiKeyMapping = new HashMap<>();
@@ -669,7 +685,7 @@ public class IntelliJTheme
static { static {
// IntelliJ UI properties that are not used in FlatLaf // 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.", "ActionButton.", "ActionToolbar.", "ActionsList.", "AppInspector.", "AssignedMnemonic.", "Autocomplete.",
"AvailableMnemonic.", "AvailableMnemonic.",
"Badge.", "Banner.", "BigSpinner.", "Bookmark.", "BookmarkIcon.", "BookmarkMnemonicAssigned.", "BookmarkMnemonicAvailable.", "Badge.", "Banner.", "BigSpinner.", "Bookmark.", "BookmarkIcon.", "BookmarkMnemonicAssigned.", "BookmarkMnemonicAvailable.",
@@ -703,14 +719,24 @@ public class IntelliJTheme
// possible typos in .theme.json files // possible typos in .theme.json files
"Checkbox.", "Toolbar.", "Tooltip.", "UiDesigner.", "link." "Checkbox.", "Toolbar.", "Tooltip.", "UiDesigner.", "link."
) ); ) );
uiKeyExcludesContains = new String[] {
".darcula."
};
uiKeyDoNotOverride = new HashSet<>( Arrays.asList( uiKeyDoNotOverride = new HashSet<>( Arrays.asList(
"TabbedPane.selectedForeground" "TabbedPane.selectedForeground"
) ); ) );
// "*."
uiKeyMapping.put( "*.fontFace", "" ); // ignore (used in OnePauintxi themes)
uiKeyMapping.put( "*.fontSize", "" ); // ignore (used in OnePauintxi themes)
// Button // Button
uiKeyMapping.put( "Button.minimumSize", "" ); // ignore (used in Material Theme UI Lite) uiKeyMapping.put( "Button.minimumSize", "" ); // ignore (used in Material Theme UI Lite)
// CheckBox.iconSize
uiKeyMapping.put( "CheckBox.iconSize", "" ); // ignore (used in Rider themes)
// ComboBox // ComboBox
uiKeyMapping.put( "ComboBox.background", "" ); // ignore uiKeyMapping.put( "ComboBox.background", "" ); // ignore
uiKeyMapping.put( "ComboBox.buttonBackground", "" ); // ignore uiKeyMapping.put( "ComboBox.buttonBackground", "" ); // ignore
@@ -751,6 +777,9 @@ public class IntelliJTheme
uiKeyMapping.put( "ProgressBar.trackColor", "ProgressBar.background" ); uiKeyMapping.put( "ProgressBar.trackColor", "ProgressBar.background" );
uiKeyMapping.put( "ProgressBar.progressColor", "ProgressBar.foreground" ); uiKeyMapping.put( "ProgressBar.progressColor", "ProgressBar.foreground" );
// RadioButton
uiKeyMapping.put( "RadioButton.iconSize", "" ); // ignore (used in Rider themes)
// ScrollBar // ScrollBar
uiKeyMapping.put( "ScrollBar.trackColor", "ScrollBar.track" ); uiKeyMapping.put( "ScrollBar.trackColor", "ScrollBar.track" );
uiKeyMapping.put( "ScrollBar.thumbColor", "ScrollBar.thumb" ); uiKeyMapping.put( "ScrollBar.thumbColor", "ScrollBar.thumb" );

View File

@@ -70,6 +70,8 @@ class LinuxPopupMenuCanceler
} }
private void addWindowListeners( MenuElement selected ) { private void addWindowListeners( MenuElement selected ) {
removeWindowListeners();
// see BasicPopupMenuUI.MouseGrabber.grabWindow() // see BasicPopupMenuUI.MouseGrabber.grabWindow()
Component invoker = selected.getComponent(); Component invoker = selected.getComponent();
if( invoker instanceof JPopupMenu ) if( invoker instanceof JPopupMenu )

View File

@@ -649,22 +649,26 @@ class UIDefaultsLoader
if( value.indexOf( ',' ) >= 0 ) { if( value.indexOf( ',' ) >= 0 ) {
// Syntax: top,left,bottom,right[,lineColor[,lineThickness[,arc]]] // Syntax: top,left,bottom,right[,lineColor[,lineThickness[,arc]]]
List<String> parts = splitFunctionParams( value, ',' ); List<String> parts = splitFunctionParams( value, ',' );
Insets insets = parseInsets( value ); try {
ColorUIResource lineColor = (parts.size() >= 5 && !parts.get( 4 ).isEmpty()) Insets insets = parseInsets( value );
? (ColorUIResource) parseColorOrFunction( resolver.apply( parts.get( 4 ) ), resolver ) ColorUIResource lineColor = (parts.size() >= 5 && !parts.get( 4 ).isEmpty())
: null; ? (ColorUIResource) parseColorOrFunction( resolver.apply( parts.get( 4 ) ), resolver )
float lineThickness = (parts.size() >= 6 && !parts.get( 5 ).isEmpty()) : null;
? parseFloat( parts.get( 5 ) ) float lineThickness = (parts.size() >= 6 && !parts.get( 5 ).isEmpty())
: 1f; ? parseFloat( parts.get( 5 ) )
int arc = (parts.size() >= 7) && !parts.get( 6 ).isEmpty() : 1f;
? parseInteger( parts.get( 6 ) ) int arc = (parts.size() >= 7) && !parts.get( 6 ).isEmpty()
: -1; ? parseInteger( parts.get( 6 ) )
: -1;
return (LazyValue) t -> { return (LazyValue) t -> {
return (lineColor != null || arc > 0) return (lineColor != null || arc > 0)
? new FlatLineBorder( insets, lineColor, lineThickness, arc ) ? new FlatLineBorder( insets, lineColor, lineThickness, arc )
: new FlatEmptyBorder( insets ); : new FlatEmptyBorder( insets );
}; };
} catch( RuntimeException ex ) {
throw new IllegalArgumentException( "invalid border '" + value + "' (" + ex.getMessage() + ")" );
}
} else } else
return parseInstance( value, resolver, addonClassLoaders ); return parseInstance( value, resolver, addonClassLoaders );
} }
@@ -735,7 +739,7 @@ class UIDefaultsLoader
Integer.parseInt( numbers.get( 1 ) ), Integer.parseInt( numbers.get( 1 ) ),
Integer.parseInt( numbers.get( 2 ) ), Integer.parseInt( numbers.get( 2 ) ),
Integer.parseInt( numbers.get( 3 ) ) ); Integer.parseInt( numbers.get( 3 ) ) );
} catch( NumberFormatException ex ) { } catch( NumberFormatException | IndexOutOfBoundsException ex ) {
throw new IllegalArgumentException( "invalid insets '" + value + "'" ); throw new IllegalArgumentException( "invalid insets '" + value + "'" );
} }
} }
@@ -748,7 +752,7 @@ class UIDefaultsLoader
return new DimensionUIResource( return new DimensionUIResource(
Integer.parseInt( numbers.get( 0 ) ), Integer.parseInt( numbers.get( 0 ) ),
Integer.parseInt( numbers.get( 1 ) ) ); Integer.parseInt( numbers.get( 1 ) ) );
} catch( NumberFormatException ex ) { } catch( NumberFormatException | IndexOutOfBoundsException ex ) {
throw new IllegalArgumentException( "invalid size '" + value + "'" ); throw new IllegalArgumentException( "invalid size '" + value + "'" );
} }
} }
@@ -1379,17 +1383,17 @@ class UIDefaultsLoader
break; break;
} }
} }
} catch( IOException ex ) { } catch( RuntimeException | IOException ex ) {
throw new IllegalArgumentException( ex ); throw new IllegalArgumentException( "invalid font '" + value + "' (" + ex.getMessage() + ")" );
} }
if( style != -1 && styleChange != 0 ) 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 != 0 ) {
if( (styleChange & Font.BOLD) != 0 && (styleChange & (Font.BOLD << 16)) != 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 ) 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 ); font = new FlatLaf.ActiveFont( baseFontKey, families, style, styleChange, absoluteSize, relativeSize, scaleSize );
@@ -1529,7 +1533,7 @@ class UIDefaultsLoader
return (LazyValue) t -> { return (LazyValue) t -> {
return new GrayFilter( brightness, contrast, alpha ); return new GrayFilter( brightness, contrast, alpha );
}; };
} catch( NumberFormatException ex ) { } catch( NumberFormatException | IndexOutOfBoundsException ex ) {
throw new IllegalArgumentException( "invalid gray filter '" + value + "'" ); throw new IllegalArgumentException( "invalid gray filter '" + value + "'" );
} }
} }

View File

@@ -18,44 +18,95 @@ package com.formdev.flatlaf.icons;
import java.awt.Color; import java.awt.Color;
import java.awt.Component; import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.awt.RenderingHints; import java.awt.Insets;
import java.awt.Window;
import javax.swing.SwingUtilities;
import com.formdev.flatlaf.ui.FlatButtonUI; import com.formdev.flatlaf.ui.FlatButtonUI;
import com.formdev.flatlaf.ui.FlatTitlePane;
import com.formdev.flatlaf.ui.FlatUIUtils; import com.formdev.flatlaf.ui.FlatUIUtils;
import com.formdev.flatlaf.util.DerivedColor;
import com.formdev.flatlaf.util.HiDPIUtils; import com.formdev.flatlaf.util.HiDPIUtils;
import com.formdev.flatlaf.util.UIScale;
/** /**
* Base class for window icons. * Base class for window icons.
* *
* @uiDefault TitlePane.buttonSize Dimension * @uiDefault TitlePane.buttonSize Dimension
* @uiDefault TitlePane.buttonInsets Insets optional
* @uiDefault TitlePane.buttonArc int optional
* @uiDefault TitlePane.buttonSymbolHeight int * @uiDefault TitlePane.buttonSymbolHeight int
* @uiDefault TitlePane.buttonHoverBackground Color * @uiDefault TitlePane.buttonBackground Color optional
* @uiDefault TitlePane.buttonPressedBackground Color * @uiDefault TitlePane.buttonForeground Color optional
* @uiDefault TitlePane.buttonInactiveBackground Color optional
* @uiDefault TitlePane.buttonInactiveForeground Color optional
* @uiDefault TitlePane.buttonHoverBackground Color optional
* @uiDefault TitlePane.buttonHoverForeground Color optional
* @uiDefault TitlePane.buttonPressedBackground Color optional
* @uiDefault TitlePane.buttonPressedForeground Color optional
* *
* @author Karl Tauber * @author Karl Tauber
*/ */
public abstract class FlatWindowAbstractIcon public abstract class FlatWindowAbstractIcon
extends FlatAbstractIcon extends FlatAbstractIcon
{ {
private final int symbolHeight; /** @since 3.6 */ protected final Insets insets;
private final Color hoverBackground; /** @since 3.6 */ protected final int arc;
private final Color pressedBackground; /** @since 3.6 */ protected final int symbolHeight;
/** @since 3.6 */ protected final Color background;
/** @since 3.6 */ protected final Color foreground;
/** @since 3.6 */ protected final Color inactiveBackground;
/** @since 3.6 */ protected final Color inactiveForeground;
protected final Color hoverBackground;
/** @since 3.6 */ protected final Color hoverForeground;
protected final Color pressedBackground;
/** @since 3.6 */ protected final Color pressedForeground;
/** @since 3.2 */ /** @since 3.2 */
protected FlatWindowAbstractIcon( String windowStyle ) { protected FlatWindowAbstractIcon( String windowStyle ) {
this( FlatUIUtils.getSubUIDimension( "TitlePane.buttonSize", windowStyle ), this( windowStyle, null, null, null, null, null, null, null, null );
FlatUIUtils.getSubUIInt( "TitlePane.buttonSymbolHeight", windowStyle, 10 ),
FlatUIUtils.getSubUIColor( "TitlePane.buttonHoverBackground", windowStyle ),
FlatUIUtils.getSubUIColor( "TitlePane.buttonPressedBackground", windowStyle ) );
} }
/** @since 3.2 */ /** @since 3.6 */
protected FlatWindowAbstractIcon( Dimension size, int symbolHeight, Color hoverBackground, Color pressedBackground ) { protected FlatWindowAbstractIcon( String windowStyle,
Color background, Color foreground, Color inactiveBackground, Color inactiveForeground,
Color hoverBackground, Color hoverForeground, Color pressedBackground, Color pressedForeground )
{
this( FlatUIUtils.getSubUIDimension( "TitlePane.buttonSize", windowStyle ),
FlatUIUtils.getSubUIInsets( "TitlePane.buttonInsets", windowStyle ),
FlatUIUtils.getSubUIInt( "TitlePane.buttonArc", windowStyle, 0 ),
FlatUIUtils.getSubUIInt( "TitlePane.buttonSymbolHeight", windowStyle, 10 ),
(background != null) ? background : FlatUIUtils.getSubUIColor( "TitlePane.buttonBackground", windowStyle ),
(foreground != null) ? foreground : FlatUIUtils.getSubUIColor( "TitlePane.buttonForeground", windowStyle ),
(inactiveBackground != null) ? inactiveBackground : FlatUIUtils.getSubUIColor( "TitlePane.buttonInactiveBackground", windowStyle ),
(inactiveForeground != null) ? inactiveForeground : FlatUIUtils.getSubUIColor( "TitlePane.buttonInactiveForeground", windowStyle ),
(hoverBackground != null) ? hoverBackground : FlatUIUtils.getSubUIColor( "TitlePane.buttonHoverBackground", windowStyle ),
(hoverForeground != null) ? hoverForeground : FlatUIUtils.getSubUIColor( "TitlePane.buttonHoverForeground", windowStyle ),
(pressedBackground != null) ? pressedBackground : FlatUIUtils.getSubUIColor( "TitlePane.buttonPressedBackground", windowStyle ),
(pressedForeground != null) ? pressedForeground : FlatUIUtils.getSubUIColor( "TitlePane.buttonPressedForeground", windowStyle ) );
}
/** @since 3.6 */
protected FlatWindowAbstractIcon( Dimension size, Insets insets, int arc, int symbolHeight,
Color background, Color foreground, Color inactiveBackground, Color inactiveForeground,
Color hoverBackground, Color hoverForeground, Color pressedBackground, Color pressedForeground )
{
super( size.width, size.height, null ); super( size.width, size.height, null );
this.insets = (insets != null) ? insets : new Insets( 0, 0, 0, 0 );
this.arc = arc;
this.symbolHeight = symbolHeight; this.symbolHeight = symbolHeight;
this.background = background;
this.foreground = foreground;
this.inactiveBackground = inactiveBackground;
this.inactiveForeground = inactiveForeground;
this.hoverBackground = hoverBackground; this.hoverBackground = hoverBackground;
this.hoverForeground = hoverForeground;
this.pressedBackground = pressedBackground; this.pressedBackground = pressedBackground;
this.pressedForeground = pressedForeground;
} }
@Override @Override
@@ -69,26 +120,39 @@ public abstract class FlatWindowAbstractIcon
/** @since 3.5.2 */ /** @since 3.5.2 */
@Override @Override
protected void paintBackground( Component c, Graphics2D g, int x, int y ) { protected void paintBackground( Component c, Graphics2D g, int x, int y ) {
Color background = FlatButtonUI.buttonStateColor( c, null, null, null, hoverBackground, pressedBackground ); Color bg = null;
if( background != null || inactiveBackground != null ) {
Window window = SwingUtilities.windowForComponent( c );
bg = (window == null || window.isActive()) ? background : inactiveBackground;
}
Color background = FlatButtonUI.buttonStateColor( c, bg, null, null, hoverBackground, pressedBackground );
if( background != null ) { if( background != null ) {
// disable antialiasing for background rectangle painting to avoid blurry edges when scaled (e.g. at 125% or 175%) Insets insets = UIScale.scale( this.insets );
Object oldHint = g.getRenderingHint( RenderingHints.KEY_ANTIALIASING ); float arc = UIScale.scale( (float) this.arc );
g.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF );
// fill background of whole component // derive color from title pane background
g.setColor( FlatUIUtils.deriveColor( background, c.getBackground() ) ); if( background instanceof DerivedColor ) {
g.fillRect( 0, 0, c.getWidth(), c.getHeight() ); Container titlePane = SwingUtilities.getAncestorOfClass( FlatTitlePane.class, c );
Component baseComp = (titlePane != null) ? titlePane : c;
background = FlatUIUtils.deriveColor( background, baseComp.getBackground() );
}
g.setRenderingHint( RenderingHints.KEY_ANTIALIASING, oldHint ); g.setColor( background );
FlatUIUtils.paintComponentBackground( g, insets.left, insets.top,
c.getWidth() - insets.left - insets.right,
c.getHeight() - insets.top - insets.bottom,
0, arc );
} }
} }
protected Color getForeground( Component c ) { protected Color getForeground( Component c ) {
return c.getForeground(); Color fg = null;
} if( foreground != null || inactiveForeground != null ) {
Window window = SwingUtilities.windowForComponent( c );
/** @since 3.2 */ fg = (window == null || window.isActive()) ? foreground : inactiveForeground;
protected int getSymbolHeight() { }
return symbolHeight; return FlatButtonUI.buttonStateColor( c, (fg != null) ? fg : c.getForeground(),
null, null, hoverForeground, pressedForeground );
} }
} }

View File

@@ -17,53 +17,54 @@
package com.formdev.flatlaf.icons; package com.formdev.flatlaf.icons;
import java.awt.BasicStroke; import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.awt.geom.Path2D; import java.awt.geom.Path2D;
import com.formdev.flatlaf.ui.FlatButtonUI;
import com.formdev.flatlaf.ui.FlatUIUtils; import com.formdev.flatlaf.ui.FlatUIUtils;
import com.formdev.flatlaf.util.SystemInfo; import com.formdev.flatlaf.util.SystemInfo;
/** /**
* "close" icon for windows (frames and dialogs). * "close" icon for windows (frames and dialogs).
* *
* @uiDefault TitlePane.closeHoverBackground Color * @uiDefault TitlePane.closeBackground Color optional
* @uiDefault TitlePane.closePressedBackground Color * @uiDefault TitlePane.closeForeground Color optional
* @uiDefault TitlePane.closeHoverForeground Color * @uiDefault TitlePane.closeInactiveBackground Color optional
* @uiDefault TitlePane.closePressedForeground Color * @uiDefault TitlePane.closeInactiveForeground Color optional
* @uiDefault TitlePane.closeHoverBackground Color optional
* @uiDefault TitlePane.closeHoverForeground Color optional
* @uiDefault TitlePane.closePressedBackground Color optional
* @uiDefault TitlePane.closePressedForeground Color optional
* *
* @author Karl Tauber * @author Karl Tauber
*/ */
public class FlatWindowCloseIcon public class FlatWindowCloseIcon
extends FlatWindowAbstractIcon extends FlatWindowAbstractIcon
{ {
private final Color hoverForeground;
private final Color pressedForeground;
public FlatWindowCloseIcon() { public FlatWindowCloseIcon() {
this( null ); this( null );
} }
/** @since 3.2 */ /** @since 3.2 */
public FlatWindowCloseIcon( String windowStyle ) { public FlatWindowCloseIcon( String windowStyle ) {
super( FlatUIUtils.getSubUIDimension( "TitlePane.buttonSize", windowStyle ), super( windowStyle,
FlatUIUtils.getSubUIInt( "TitlePane.buttonSymbolHeight", windowStyle, 10 ), FlatUIUtils.getSubUIColor( "TitlePane.closeBackground", windowStyle ),
FlatUIUtils.getSubUIColor( "TitlePane.closeForeground", windowStyle ),
FlatUIUtils.getSubUIColor( "TitlePane.closeInactiveBackground", windowStyle ),
FlatUIUtils.getSubUIColor( "TitlePane.closeInactiveForeground", windowStyle ),
FlatUIUtils.getSubUIColor( "TitlePane.closeHoverBackground", windowStyle ), FlatUIUtils.getSubUIColor( "TitlePane.closeHoverBackground", windowStyle ),
FlatUIUtils.getSubUIColor( "TitlePane.closePressedBackground", windowStyle ) ); FlatUIUtils.getSubUIColor( "TitlePane.closeHoverForeground", windowStyle ),
FlatUIUtils.getSubUIColor( "TitlePane.closePressedBackground", windowStyle ),
hoverForeground = FlatUIUtils.getSubUIColor( "TitlePane.closeHoverForeground", windowStyle ); FlatUIUtils.getSubUIColor( "TitlePane.closePressedForeground", windowStyle ) );
pressedForeground = FlatUIUtils.getSubUIColor( "TitlePane.closePressedForeground", windowStyle );
} }
@Override @Override
protected void paintIconAt1x( Graphics2D g, int x, int y, int width, int height, double scaleFactor ) { protected void paintIconAt1x( Graphics2D g, int x, int y, int width, int height, double scaleFactor ) {
int iwh = (int) (getSymbolHeight() * scaleFactor); int iwh = (int) (symbolHeight * scaleFactor);
int ix = x + ((width - iwh) / 2); int ix = x + ((width - iwh) / 2);
int iy = y + ((height - iwh) / 2); int iy = y + ((height - iwh) / 2);
int ix2 = ix + iwh - 1; int ix2 = ix + iwh - 1;
int iy2 = iy + iwh - 1; int iy2 = iy + iwh - 1;
float thickness = Math.max( SystemInfo.isWindows_11_orLater ? (float) scaleFactor : (int) scaleFactor, 1 ); boolean isWindows10 = SystemInfo.isWindows_10_orLater && !SystemInfo.isWindows_11_orLater;
float thickness = Math.max( isWindows10 ? (int) scaleFactor : (float) scaleFactor, 1 );
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD, 4 ); Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD, 4 );
path.moveTo( ix, iy ); path.moveTo( ix, iy );
@@ -73,9 +74,4 @@ public class FlatWindowCloseIcon
g.setStroke( new BasicStroke( thickness ) ); g.setStroke( new BasicStroke( thickness ) );
g.draw( path ); g.draw( path );
} }
@Override
protected Color getForeground( Component c ) {
return FlatButtonUI.buttonStateColor( c, c.getForeground(), null, null, hoverForeground, pressedForeground );
}
} }

View File

@@ -37,7 +37,7 @@ public class FlatWindowIconifyIcon
@Override @Override
protected void paintIconAt1x( Graphics2D g, int x, int y, int width, int height, double scaleFactor ) { protected void paintIconAt1x( Graphics2D g, int x, int y, int width, int height, double scaleFactor ) {
int iw = (int) (getSymbolHeight() * scaleFactor); int iw = (int) (symbolHeight * scaleFactor);
int ih = Math.max( (int) scaleFactor, 1 ); int ih = Math.max( (int) scaleFactor, 1 );
int ix = x + ((width - iw) / 2); int ix = x + ((width - iw) / 2);
int iy = y + ((height - ih) / 2); int iy = y + ((height - ih) / 2);

View File

@@ -39,10 +39,11 @@ public class FlatWindowMaximizeIcon
@Override @Override
protected void paintIconAt1x( Graphics2D g, int x, int y, int width, int height, double scaleFactor ) { protected void paintIconAt1x( Graphics2D g, int x, int y, int width, int height, double scaleFactor ) {
int iwh = (int) (getSymbolHeight() * scaleFactor); int iwh = (int) (symbolHeight * scaleFactor);
int ix = x + ((width - iwh) / 2); int ix = x + ((width - iwh) / 2);
int iy = y + ((height - iwh) / 2); int iy = y + ((height - iwh) / 2);
float thickness = Math.max( SystemInfo.isWindows_11_orLater ? (float) scaleFactor : (int) scaleFactor, 1 ); boolean isWindows10 = SystemInfo.isWindows_10_orLater && !SystemInfo.isWindows_11_orLater;
float thickness = Math.max( isWindows10 ? (int) scaleFactor : (float) scaleFactor, 1 );
int arc = Math.max( (int) (1.5 * scaleFactor), 2 ); int arc = Math.max( (int) (1.5 * scaleFactor), 2 );
g.fill( SystemInfo.isWindows_11_orLater g.fill( SystemInfo.isWindows_11_orLater

View File

@@ -42,14 +42,15 @@ public class FlatWindowRestoreIcon
@Override @Override
protected void paintIconAt1x( Graphics2D g, int x, int y, int width, int height, double scaleFactor ) { protected void paintIconAt1x( Graphics2D g, int x, int y, int width, int height, double scaleFactor ) {
int iwh = (int) (getSymbolHeight() * scaleFactor); int iwh = (int) (symbolHeight * scaleFactor);
int ix = x + ((width - iwh) / 2); int ix = x + ((width - iwh) / 2);
int iy = y + ((height - iwh) / 2); int iy = y + ((height - iwh) / 2);
float thickness = Math.max( SystemInfo.isWindows_11_orLater ? (float) scaleFactor : (int) scaleFactor, 1 ); boolean isWindows10 = SystemInfo.isWindows_10_orLater && !SystemInfo.isWindows_11_orLater;
float thickness = Math.max( isWindows10 ? (int) scaleFactor : (float) scaleFactor, 1 );
int arc = Math.max( (int) (1.5 * scaleFactor), 2 ); int arc = Math.max( (int) (1.5 * scaleFactor), 2 );
int arcOuter = (int) (arc + (1.5 * scaleFactor)); int arcOuter = (int) (arc + (1.5 * scaleFactor));
int rwh = (int) ((getSymbolHeight() - 2) * scaleFactor); int rwh = (int) ((symbolHeight - 2) * scaleFactor);
int ro2 = iwh - rwh; int ro2 = iwh - rwh;
// upper-right rectangle // upper-right rectangle

View File

@@ -381,6 +381,12 @@ public class FlatButtonUI
return ((FlatHelpButtonIcon)helpButtonIcon).applyStyleProperty( key, value ); return ((FlatHelpButtonIcon)helpButtonIcon).applyStyleProperty( key, value );
} }
// update internal values; otherwise isCustomBackground() and isCustomForeground() would return wrong results
switch( key ) {
case "background": background = (Color) value; break;
case "foreground": foreground = (Color) value; break;
}
if( "iconTextGap".equals( key ) && value instanceof Integer ) if( "iconTextGap".equals( key ) && value instanceof Integer )
value = UIScale.scale( (Integer) value ); value = UIScale.scale( (Integer) value );

View File

@@ -17,6 +17,7 @@
package com.formdev.flatlaf.ui; package com.formdev.flatlaf.ui;
import static com.formdev.flatlaf.FlatClientProperties.*; import static com.formdev.flatlaf.FlatClientProperties.*;
import java.awt.Container;
import java.awt.EventQueue; import java.awt.EventQueue;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
@@ -24,7 +25,9 @@ import java.awt.event.FocusEvent;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import javax.swing.Action; import javax.swing.Action;
import javax.swing.ActionMap; import javax.swing.ActionMap;
import javax.swing.JComboBox;
import javax.swing.JFormattedTextField; import javax.swing.JFormattedTextField;
import javax.swing.JSpinner;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import javax.swing.UIManager; import javax.swing.UIManager;
import javax.swing.plaf.UIResource; import javax.swing.plaf.UIResource;
@@ -33,6 +36,7 @@ import javax.swing.text.DefaultCaret;
import javax.swing.text.DefaultEditorKit; import javax.swing.text.DefaultEditorKit;
import javax.swing.text.Document; import javax.swing.text.Document;
import javax.swing.text.JTextComponent; import javax.swing.text.JTextComponent;
import javax.swing.text.Position;
import javax.swing.text.Utilities; import javax.swing.text.Utilities;
/** /**
@@ -48,12 +52,15 @@ public class FlatCaret
{ {
private static final String KEY_CARET_INFO = "FlatLaf.internal.caretInfo"; 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 String selectAllOnFocusPolicy;
private final boolean selectAllOnMouseClick; private final boolean selectAllOnMouseClick;
private boolean inInstall; private boolean inInstall;
private boolean wasFocused; private boolean wasFocused;
private boolean wasTemporaryLost; private boolean wasFocusTemporaryLost;
private boolean isMousePressed; private boolean isMousePressed;
private boolean isWordSelection; private boolean isWordSelection;
private boolean isLineSelection; private boolean isLineSelection;
@@ -94,6 +101,9 @@ public class FlatCaret
// restore selection // restore selection
select( (int) ci[1], (int) ci[0] ); select( (int) ci[1], (int) ci[0] );
if( ci[4] != 0 )
wasFocused = true;
// if text component is focused, then caret and selection are visible, // if text component is focused, then caret and selection are visible,
// but when switching theme, the component does not yet have // but when switching theme, the component does not yet have
// a highlighter and the selection is not painted // a highlighter and the selection is not painted
@@ -121,6 +131,7 @@ public class FlatCaret
getMark(), getMark(),
getBlinkRate(), getBlinkRate(),
System.currentTimeMillis(), System.currentTimeMillis(),
wasFocused ? 1 : 0,
} ); } );
super.deinstall( c ); super.deinstall( c );
@@ -140,11 +151,36 @@ public class FlatCaret
super.adjustVisibility( nloc ); 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 @Override
public void focusGained( FocusEvent e ) { public void focusGained( FocusEvent e ) {
if( !inInstall && !wasTemporaryLost && (!isMousePressed || selectAllOnMouseClick) ) if( !inInstall && !wasFocusTemporaryLost && (!isMousePressed || isSelectAllOnMouseClick()) )
selectAllOnFocusGained(); selectAllOnFocusGained();
wasTemporaryLost = false;
wasFocusTemporaryLost = false;
wasFocused = true; wasFocused = true;
super.focusGained( e ); super.focusGained( e );
@@ -152,7 +188,7 @@ public class FlatCaret
@Override @Override
public void focusLost( FocusEvent e ) { public void focusLost( FocusEvent e ) {
wasTemporaryLost = e.isTemporary(); wasFocusTemporaryLost = e.isTemporary();
super.focusLost( e ); super.focusLost( e );
} }
@@ -232,24 +268,13 @@ public class FlatCaret
if( doc == null || !c.isEnabled() || !c.isEditable() || FlatUIUtils.isCellEditor( c ) ) if( doc == null || !c.isEnabled() || !c.isEditable() || FlatUIUtils.isCellEditor( c ) )
return; return;
Object selectAllOnFocusPolicy = c.getClientProperty( SELECT_ALL_ON_FOCUS_POLICY ); int selectAllOnFocusPolicy = getSelectAllOnFocusPolicy();
if( selectAllOnFocusPolicy == null ) if( selectAllOnFocusPolicy == NEVER )
selectAllOnFocusPolicy = this.selectAllOnFocusPolicy;
if( selectAllOnFocusPolicy == null || SELECT_ALL_ON_FOCUS_POLICY_NEVER.equals( selectAllOnFocusPolicy ) )
return; return;
if( !SELECT_ALL_ON_FOCUS_POLICY_ALWAYS.equals( selectAllOnFocusPolicy ) ) { if( selectAllOnFocusPolicy == ONCE && !isMousePressed ) {
// policy is "once" (or null or unknown)
// was already focused? // was already focused?
if( wasFocused ) if( wasFocused && !(c instanceof JFormattedTextField) )
return;
// check whether selection was modified before gaining focus
int dot = getDot();
int mark = getMark();
if( dot != mark || dot != doc.getLength() )
return; return;
} }
@@ -265,16 +290,51 @@ public class FlatCaret
select( 0, c2.getDocument().getLength() ); select( 0, c2.getDocument().getLength() );
} ); } );
} else { } else
select( 0, doc.getLength() ); select( 0, doc.getLength() );
}
} }
private void select( int mark, int dot ) { private void select( int mark, int dot ) {
if( mark != getMark() ) if( mark != getMark() )
setDot( mark ); setDot( mark, Position.Bias.Forward );
if( dot != getDot() ) 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 */ /** @since 1.4 */

View File

@@ -882,7 +882,7 @@ public class FlatComboBoxUI
GraphicsConfiguration gc = comboBox.getGraphicsConfiguration(); GraphicsConfiguration gc = comboBox.getGraphicsConfiguration();
if( gc != null ) { if( gc != null ) {
Rectangle screenBounds = gc.getBounds(); 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 ); displayWidth = Math.min( displayWidth, screenBounds.width - screenInsets.left - screenInsets.right );
} else { } else {
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();

View File

@@ -32,7 +32,6 @@ import java.awt.Panel;
import java.awt.Point; import java.awt.Point;
import java.awt.PointerInfo; import java.awt.PointerInfo;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.Window; import java.awt.Window;
import java.awt.event.ComponentEvent; import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener; import java.awt.event.ComponentListener;
@@ -312,7 +311,7 @@ public class FlatPopupFactory
return null; return null;
Rectangle screenBounds = gc.getBounds(); Rectangle screenBounds = gc.getBounds();
Insets screenInsets = Toolkit.getDefaultToolkit().getScreenInsets( gc ); Insets screenInsets = FlatUIUtils.getScreenInsets( gc );
int screenTop = screenBounds.y + screenInsets.top; int screenTop = screenBounds.y + screenInsets.top;
// place tooltip above mouse location if there is enough space // place tooltip above mouse location if there is enough space
@@ -619,7 +618,30 @@ public class FlatPopupFactory
void showImpl() { void showImpl() {
if( delegate != null ) { if( delegate != null ) {
showPopupAndFixLocation( delegate, popupWindow ); // On macOS and Linux, the empty popup window is shown in popup.show()
// (in peer.setVisible(true) invoked from Component.show()),
// but the popup content is painted later via repaint manager.
// This may cause some flicker, especially during JVM warm-up or
// when running JVM in interpreter mode (option -Xint).
// To reduce flicker, immediately paint popup content as soon as popup window becomes visible.
// This also fixes a problem with JetBrainsRuntime JVM, where sometimes the popups were empty.
if( (SystemInfo.isMacOS || SystemInfo.isLinux) && popupWindow instanceof JWindow ) {
HierarchyListener l = e -> {
if( e.getID() == HierarchyEvent.HIERARCHY_CHANGED &&
(e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0 )
{
((JWindow)popupWindow).getRootPane().paintImmediately(
0, 0, popupWindow.getWidth(), popupWindow.getHeight() );
}
};
popupWindow.addHierarchyListener( l );
try {
showPopupAndFixLocation( delegate, popupWindow );
} finally {
popupWindow.removeHierarchyListener( l );
}
} else
showPopupAndFixLocation( delegate, popupWindow );
// increase tooltip size if necessary because it may be too small on HiDPI screens // increase tooltip size if necessary because it may be too small on HiDPI screens
// https://bugs.openjdk.java.net/browse/JDK-8213535 // https://bugs.openjdk.java.net/browse/JDK-8213535
@@ -678,6 +700,21 @@ public class FlatPopupFactory
// restore background so that it can not affect other LaFs (when switching) // restore background so that it can not affect other LaFs (when switching)
// because popup windows are cached and reused // because popup windows are cached and reused
popupWindow.setBackground( oldPopupWindowBackground ); popupWindow.setBackground( oldPopupWindowBackground );
// On macOS, popupWindow.setBackground(...) invoked from constructor,
// has no affect if the popup window peer (a NSWindow) is already created,
// which is the case when reusing a cached popup window
// (see class PopupFactory.HeavyWeightPopup).
// This may result in flicker when e.g. showing a popup in a light theme,
// then switching to a dark theme and again showing a popup,
// because the underling NSWindow still has a light background,
// which may be shown shortly before the actual dark popup content is shown.
// To fix this, dispose the popup window, which disposes the NSWindow.
// The AWT popup window stays in the popup cache, but when reusing it later,
// a new peer and a new NSWindow is created and gets the correct background.
if( SystemInfo.isMacOS )
popupWindow.dispose();
popupWindow = null; popupWindow = null;
} }
} }

View File

@@ -246,7 +246,7 @@ public class FlatPopupMenuUI
// (always subtract screen insets because there is no API to detect whether // (always subtract screen insets because there is no API to detect whether
// the popup can overlap the taskbar; see JPopupMenu.canPopupOverlapTaskBar()) // the popup can overlap the taskbar; see JPopupMenu.canPopupOverlapTaskBar())
Rectangle screenBounds = gc.getBounds(); Rectangle screenBounds = gc.getBounds();
Insets screenInsets = Toolkit.getDefaultToolkit().getScreenInsets( gc ); Insets screenInsets = FlatUIUtils.getScreenInsets( gc );
return FlatUIUtils.subtractInsets( screenBounds, screenInsets ); return FlatUIUtils.subtractInsets( screenBounds, screenInsets );
} }

View File

@@ -31,6 +31,7 @@ import java.awt.Window;
import java.awt.event.ComponentListener; import java.awt.event.ComponentListener;
import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener; import java.beans.PropertyChangeListener;
import java.util.Objects;
import java.util.function.Function; import java.util.function.Function;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.JDialog; import javax.swing.JDialog;
@@ -485,8 +486,12 @@ public class FlatRootPaneUI
break; break;
case "ancestor": case "ancestor":
if( e.getNewValue() instanceof Window ) if( e.getNewValue() instanceof Window ) {
if( titlePane != null && !Objects.equals( titlePane.windowStyle, FlatTitlePane.getWindowStyle( rootPane ) ) )
setTitlePane( createTitlePane() );
macClearBackgroundForTranslucentWindow( rootPane ); macClearBackgroundForTranslucentWindow( rootPane );
}
macUninstallWindowBackgroundListener( rootPane ); macUninstallWindowBackgroundListener( rootPane );
macInstallWindowBackgroundListener( rootPane ); macInstallWindowBackgroundListener( rootPane );

View File

@@ -39,6 +39,7 @@ import java.beans.PropertyChangeListener;
import java.util.Map; import java.util.Map;
import javax.swing.Action; import javax.swing.Action;
import javax.swing.ActionMap; import javax.swing.ActionMap;
import javax.swing.Icon;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.JScrollPane; import javax.swing.JScrollPane;
import javax.swing.JTable; import javax.swing.JTable;
@@ -989,12 +990,14 @@ public class FlatTableUI
FlatBooleanRenderer() { FlatBooleanRenderer() {
setHorizontalAlignment( SwingConstants.CENTER ); setHorizontalAlignment( SwingConstants.CENTER );
setIcon( new FlatCheckBoxIcon() { Icon icon = new FlatCheckBoxIcon() {
@Override @Override
protected boolean isSelected( Component c ) { protected boolean isSelected( Component c ) {
return selected; return selected;
} }
} ); };
setIcon( icon );
setDisabledIcon( icon );
} }
@Override @Override

View File

@@ -89,13 +89,16 @@ import com.formdev.flatlaf.util.UIScale;
* @uiDefault TitlePane.iconSize Dimension * @uiDefault TitlePane.iconSize Dimension
* @uiDefault TitlePane.iconMargins Insets * @uiDefault TitlePane.iconMargins Insets
* @uiDefault TitlePane.titleMargins Insets * @uiDefault TitlePane.titleMargins Insets
* @uiDefault TitlePane.menuBarEmbedded boolean
* @uiDefault TitlePane.titleMinimumWidth int * @uiDefault TitlePane.titleMinimumWidth int
* @uiDefault TitlePane.buttonMinimumWidth int * @uiDefault TitlePane.buttonMinimumWidth int
* @uiDefault TitlePane.buttonMaximizedHeight int * @uiDefault TitlePane.buttonMaximizedHeight int
* @uiDefault TitlePane.buttonsGap int
* @uiDefault TitlePane.buttonsMargins Insets
* @uiDefault TitlePane.buttonsFillVertically boolean
* @uiDefault TitlePane.centerTitle boolean * @uiDefault TitlePane.centerTitle boolean
* @uiDefault TitlePane.centerTitleIfMenuBarEmbedded boolean * @uiDefault TitlePane.centerTitleIfMenuBarEmbedded boolean
* @uiDefault TitlePane.showIconBesideTitle boolean * @uiDefault TitlePane.showIconBesideTitle boolean
* @uiDefault TitlePane.menuBarEmbedded boolean
* @uiDefault TitlePane.menuBarTitleGap int * @uiDefault TitlePane.menuBarTitleGap int
* @uiDefault TitlePane.menuBarTitleMinimumGap int * @uiDefault TitlePane.menuBarTitleMinimumGap int
* @uiDefault TitlePane.closeIcon Icon * @uiDefault TitlePane.closeIcon Icon
@@ -123,9 +126,14 @@ public class FlatTitlePane
/** @since 2.5 */ protected final boolean showIconInDialogs; /** @since 2.5 */ protected final boolean showIconInDialogs;
/** @since 2 */ protected final int noIconLeftGap; /** @since 2 */ protected final int noIconLeftGap;
protected final Dimension iconSize; protected final Dimension iconSize;
/** @since 3.6 */ protected final Insets iconMargins;
/** @since 3.6 */ protected final Insets titleMargins;
/** @since 2.4 */ protected final int titleMinimumWidth; /** @since 2.4 */ protected final int titleMinimumWidth;
/** @since 2.4 */ protected final int buttonMinimumWidth; /** @since 2.4 */ protected final int buttonMinimumWidth;
protected final int buttonMaximizedHeight; protected final int buttonMaximizedHeight;
/** @since 3.6 */ protected final int buttonsGap;
/** @since 3.6 */ protected final Insets buttonsMargins;
/** @since 3.6 */ protected final boolean buttonsFillVertically;
protected final boolean centerTitle; protected final boolean centerTitle;
protected final boolean centerTitleIfMenuBarEmbedded; protected final boolean centerTitleIfMenuBarEmbedded;
/** @since 2.4 */ protected final boolean showIconBesideTitle; /** @since 2.4 */ protected final boolean showIconBesideTitle;
@@ -145,6 +153,9 @@ public class FlatTitlePane
protected JButton restoreButton; protected JButton restoreButton;
protected JButton closeButton; protected JButton closeButton;
private JComponent iconifyMaximizeGapComp;
private JComponent maximizeCloseGapComp;
protected Window window; protected Window window;
private final Handler handler; private final Handler handler;
@@ -179,9 +190,7 @@ public class FlatTitlePane
public FlatTitlePane( JRootPane rootPane ) { public FlatTitlePane( JRootPane rootPane ) {
this.rootPane = rootPane; this.rootPane = rootPane;
Window w = SwingUtilities.getWindowAncestor( rootPane ); windowStyle = getWindowStyle( rootPane );
String defaultWindowStyle = (w != null && w.getType() == Window.Type.UTILITY) ? WINDOW_STYLE_SMALL : null;
windowStyle = clientProperty( rootPane, WINDOW_STYLE, defaultWindowStyle, String.class );
titleFont = FlatUIUtils.getSubUIFont( "TitlePane.font", windowStyle ); titleFont = FlatUIUtils.getSubUIFont( "TitlePane.font", windowStyle );
activeBackground = FlatUIUtils.getSubUIColor( "TitlePane.background", windowStyle ); activeBackground = FlatUIUtils.getSubUIColor( "TitlePane.background", windowStyle );
@@ -196,9 +205,14 @@ public class FlatTitlePane
showIconInDialogs = FlatUIUtils.getSubUIBoolean( "TitlePane.showIconInDialogs", windowStyle, true ); showIconInDialogs = FlatUIUtils.getSubUIBoolean( "TitlePane.showIconInDialogs", windowStyle, true );
noIconLeftGap = FlatUIUtils.getSubUIInt( "TitlePane.noIconLeftGap", windowStyle, 8 ); noIconLeftGap = FlatUIUtils.getSubUIInt( "TitlePane.noIconLeftGap", windowStyle, 8 );
iconSize = FlatUIUtils.getSubUIDimension( "TitlePane.iconSize", windowStyle ); iconSize = FlatUIUtils.getSubUIDimension( "TitlePane.iconSize", windowStyle );
iconMargins = FlatUIUtils.getSubUIInsets( "TitlePane.iconMargins", windowStyle );
titleMargins = FlatUIUtils.getSubUIInsets( "TitlePane.titleMargins", windowStyle );
titleMinimumWidth = FlatUIUtils.getSubUIInt( "TitlePane.titleMinimumWidth", windowStyle, 60 ); titleMinimumWidth = FlatUIUtils.getSubUIInt( "TitlePane.titleMinimumWidth", windowStyle, 60 );
buttonMinimumWidth = FlatUIUtils.getSubUIInt( "TitlePane.buttonMinimumWidth", windowStyle, 30 ); buttonMinimumWidth = FlatUIUtils.getSubUIInt( "TitlePane.buttonMinimumWidth", windowStyle, 30 );
buttonMaximizedHeight = FlatUIUtils.getSubUIInt( "TitlePane.buttonMaximizedHeight", windowStyle, 0 ); buttonMaximizedHeight = FlatUIUtils.getSubUIInt( "TitlePane.buttonMaximizedHeight", windowStyle, 0 );
buttonsGap = FlatUIUtils.getSubUIInt( "TitlePane.buttonsGap", windowStyle, 0 );
buttonsMargins = FlatUIUtils.getSubUIInsets( "TitlePane.buttonsMargins", windowStyle );
buttonsFillVertically = FlatUIUtils.getSubUIBoolean( "TitlePane.buttonsFillVertically", windowStyle, true );
centerTitle = FlatUIUtils.getSubUIBoolean( "TitlePane.centerTitle", windowStyle, false ); centerTitle = FlatUIUtils.getSubUIBoolean( "TitlePane.centerTitle", windowStyle, false );
centerTitleIfMenuBarEmbedded = FlatUIUtils.getSubUIBoolean( "TitlePane.centerTitleIfMenuBarEmbedded", windowStyle, true ); centerTitleIfMenuBarEmbedded = FlatUIUtils.getSubUIBoolean( "TitlePane.centerTitleIfMenuBarEmbedded", windowStyle, true );
showIconBesideTitle = FlatUIUtils.getSubUIBoolean( "TitlePane.showIconBesideTitle", windowStyle, false ); showIconBesideTitle = FlatUIUtils.getSubUIBoolean( "TitlePane.showIconBesideTitle", windowStyle, false );
@@ -228,6 +242,12 @@ public class FlatTitlePane
applyComponentOrientation( rootPane.getComponentOrientation() ); applyComponentOrientation( rootPane.getComponentOrientation() );
} }
static String getWindowStyle( JRootPane rootPane ) {
Window w = SwingUtilities.getWindowAncestor( rootPane );
String defaultWindowStyle = (w != null && w.getType() == Window.Type.UTILITY) ? WINDOW_STYLE_SMALL : null;
return clientProperty( rootPane, WINDOW_STYLE, defaultWindowStyle, String.class );
}
protected FlatTitlePaneBorder createTitlePaneBorder() { protected FlatTitlePaneBorder createTitlePaneBorder() {
return new FlatTitlePaneBorder(); return new FlatTitlePaneBorder();
} }
@@ -245,8 +265,8 @@ public class FlatTitlePane
setUI( new FlatTitleLabelUI() ); setUI( new FlatTitleLabelUI() );
} }
}; };
iconLabel.setBorder( new FlatEmptyBorder( FlatUIUtils.getSubUIInsets( "TitlePane.iconMargins", windowStyle ) ) ); iconLabel.setBorder( new FlatEmptyBorder( iconMargins ) );
titleLabel.setBorder( new FlatEmptyBorder( FlatUIUtils.getSubUIInsets( "TitlePane.titleMargins", windowStyle ) ) ); titleLabel.setBorder( new FlatEmptyBorder( titleMargins ) );
leftPanel.setLayout( new BoxLayout( leftPanel, BoxLayout.LINE_AXIS ) ); leftPanel.setLayout( new BoxLayout( leftPanel, BoxLayout.LINE_AXIS ) );
leftPanel.setOpaque( false ); leftPanel.setOpaque( false );
@@ -349,10 +369,15 @@ public class FlatTitlePane
restoreButton = createButton( "TitlePane.restoreIcon", "Restore", e -> restore() ); restoreButton = createButton( "TitlePane.restoreIcon", "Restore", e -> restore() );
closeButton = createButton( "TitlePane.closeIcon", "Close", e -> close() ); closeButton = createButton( "TitlePane.closeIcon", "Close", e -> close() );
iconifyMaximizeGapComp = createButtonsGapComp();
maximizeCloseGapComp = createButtonsGapComp();
// initially hide buttons that are only supported in frames // initially hide buttons that are only supported in frames
iconifyButton.setVisible( false ); iconifyButton.setVisible( false );
maximizeButton.setVisible( false ); maximizeButton.setVisible( false );
restoreButton.setVisible( false ); restoreButton.setVisible( false );
iconifyMaximizeGapComp.setVisible( false );
maximizeCloseGapComp.setVisible( false );
buttonPanel = new JPanel() { buttonPanel = new JPanel() {
@Override @Override
@@ -364,12 +389,13 @@ public class FlatTitlePane
if( buttonMaximizedHeight > 0 && isWindowMaximized() && !hasVisibleEmbeddedMenuBar( rootPane.getJMenuBar() ) ) { if( buttonMaximizedHeight > 0 && isWindowMaximized() && !hasVisibleEmbeddedMenuBar( rootPane.getJMenuBar() ) ) {
// make title pane height smaller when frame is maximized // make title pane height smaller when frame is maximized
size = new Dimension( size.width, Math.min( size.height, UIScale.scale( buttonMaximizedHeight ) ) ); size = new Dimension( size.width, Math.min( size.height, UIScale.scale( buttonMaximizedHeight + buttonsMargins.top + buttonsMargins.bottom ) ) );
} }
return size; return size;
} }
}; };
buttonPanel.setOpaque( false ); buttonPanel.setOpaque( false );
buttonPanel.setBorder( FlatUIUtils.nonUIResource( new FlatEmptyBorder( buttonsMargins ) ) );
buttonPanel.setLayout( new BoxLayout( buttonPanel, BoxLayout.LINE_AXIS ) ); buttonPanel.setLayout( new BoxLayout( buttonPanel, BoxLayout.LINE_AXIS ) );
if( rootPane.getWindowDecorationStyle() == JRootPane.FRAME ) { if( rootPane.getWindowDecorationStyle() == JRootPane.FRAME ) {
// JRootPane.FRAME works only for frames (and not for dialogs) // JRootPane.FRAME works only for frames (and not for dialogs)
@@ -378,8 +404,10 @@ public class FlatTitlePane
// later in frameStateChanged(), which is invoked from addNotify() // later in frameStateChanged(), which is invoked from addNotify()
buttonPanel.add( iconifyButton ); buttonPanel.add( iconifyButton );
buttonPanel.add( iconifyMaximizeGapComp );
buttonPanel.add( maximizeButton ); buttonPanel.add( maximizeButton );
buttonPanel.add( restoreButton ); buttonPanel.add( restoreButton );
buttonPanel.add( maximizeCloseGapComp );
} }
buttonPanel.add( closeButton ); buttonPanel.add( closeButton );
@@ -396,13 +424,17 @@ public class FlatTitlePane
@Override @Override
public Dimension getMinimumSize() { public Dimension getMinimumSize() {
// allow the button to shrink if space is rare // allow the button to shrink if space is rare
return new Dimension( UIScale.scale( buttonMinimumWidth ), super.getMinimumSize().height ); return new Dimension(
Math.min( UIScale.scale( buttonMinimumWidth ), super.getPreferredSize().width ),
super.getMinimumSize().height );
} }
@Override @Override
public Dimension getMaximumSize() { public Dimension getMaximumSize() {
// allow the button to fill whole button area height // allow the button to fill whole button area height
// see also BasicMenuUI.getMaximumSize() // see also BasicMenuUI.getMaximumSize()
return new Dimension( super.getMaximumSize().width, Short.MAX_VALUE ); return buttonsFillVertically
? new Dimension( super.getMaximumSize().width, Short.MAX_VALUE )
: super.getMaximumSize();
} }
}; };
button.setFocusable( false ); button.setFocusable( false );
@@ -413,6 +445,14 @@ public class FlatTitlePane
return button; return button;
} }
private JComponent createButtonsGapComp() {
JComponent gapComp = new JPanel();
gapComp.setOpaque( false );
gapComp.setMinimumSize( new Dimension( 0, 0 ) );
gapComp.setPreferredSize( new Dimension( UIScale.scale( buttonsGap ), 0 ) );
return gapComp;
}
protected void activeChanged( boolean active ) { protected void activeChanged( boolean active ) {
Color background = clientPropertyColor( rootPane, TITLE_BAR_BACKGROUND, null ); Color background = clientPropertyColor( rootPane, TITLE_BAR_BACKGROUND, null );
Color foreground = clientPropertyColor( rootPane, TITLE_BAR_FOREGROUND, null ); Color foreground = clientPropertyColor( rootPane, TITLE_BAR_FOREGROUND, null );
@@ -434,6 +474,9 @@ public class FlatTitlePane
closeButton.setForeground( foreground ); closeButton.setForeground( foreground );
// this is necessary because hover/pressed colors are derived from background color // this is necessary because hover/pressed colors are derived from background color
// (since FlatWindowAbstractIcon now invokes FlatTitlePane.getBackground()
// to get base color, this is no longer necessary, but keep it for compatibility;
// e.g. for custom window icons)
iconifyButton.setBackground( background ); iconifyButton.setBackground( background );
maximizeButton.setBackground( background ); maximizeButton.setBackground( background );
restoreButton.setBackground( background ); restoreButton.setBackground( background );
@@ -493,6 +536,13 @@ public class FlatTitlePane
maximizeButton.setVisible( false ); maximizeButton.setVisible( false );
restoreButton.setVisible( false ); restoreButton.setVisible( false );
} }
boolean iconifyVisible = iconifyButton.isVisible();
boolean maximizeVisible = maximizeButton.isVisible();
boolean restoreVisible = restoreButton.isVisible();
boolean closeVisible = closeButton.isVisible();
iconifyMaximizeGapComp.setVisible( iconifyVisible && (maximizeVisible || restoreVisible || closeVisible) );
maximizeCloseGapComp.setVisible( closeVisible && (maximizeVisible || restoreVisible) );
} }
protected void updateIcon() { protected void updateIcon() {
@@ -746,12 +796,17 @@ public class FlatTitlePane
if( isFullWindowContent() ) if( isFullWindowContent() )
return; return;
g.setColor( getBackground() );
g.fillRect( 0, 0, getWidth(), getHeight() );
}
@Override
public Color getBackground() {
// not storing value of "TitlePane.unifiedBackground" in class to allow changing at runtime // not storing value of "TitlePane.unifiedBackground" in class to allow changing at runtime
g.setColor( (UIManager.getBoolean( "TitlePane.unifiedBackground" ) && return (UIManager.getBoolean( "TitlePane.unifiedBackground" ) &&
clientPropertyColor( rootPane, TITLE_BAR_BACKGROUND, null ) == null) clientPropertyColor( rootPane, TITLE_BAR_BACKGROUND, null ) == null)
? FlatUIUtils.getParentBackground( this ) ? FlatUIUtils.getParentBackground( this )
: getBackground() ); : super.getBackground();
g.fillRect( 0, 0, getWidth(), getHeight() );
} }
/** /**
@@ -859,7 +914,7 @@ public class FlatTitlePane
// screen insets are in physical size, except for Java 15+ // screen insets are in physical size, except for Java 15+
// (see https://bugs.openjdk.java.net/browse/JDK-8243925) // (see https://bugs.openjdk.java.net/browse/JDK-8243925)
// and except for Java 8 on secondary screens where primary screen is scaled // 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+ // maximized bounds are required in physical size, except for Java 15+
// (see https://bugs.openjdk.java.net/browse/JDK-8231564 and // (see https://bugs.openjdk.java.net/browse/JDK-8231564 and
@@ -1093,6 +1148,7 @@ public class FlatTitlePane
if( !c.isDisplayable() || !c.isVisible() || !contains( c, x, y ) || c == mouseLayer ) if( !c.isDisplayable() || !c.isVisible() || !contains( c, x, y ) || c == mouseLayer )
return true; // continue checking with next component return true; // continue checking with next component
// check enabled component that has mouse listeners
if( c.isEnabled() && if( c.isEnabled() &&
(c.getMouseListeners().length > 0 || (c.getMouseListeners().length > 0 ||
c.getMouseMotionListeners().length > 0) ) c.getMouseMotionListeners().length > 0) )

View File

@@ -26,6 +26,7 @@ import java.awt.Graphics;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration; import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice; import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Insets; import java.awt.Insets;
import java.awt.KeyboardFocusManager; import java.awt.KeyboardFocusManager;
import java.awt.Paint; import java.awt.Paint;
@@ -34,6 +35,7 @@ import java.awt.RenderingHints;
import java.awt.Shape; import java.awt.Shape;
import java.awt.Stroke; import java.awt.Stroke;
import java.awt.SystemColor; import java.awt.SystemColor;
import java.awt.Toolkit;
import java.awt.Window; import java.awt.Window;
import java.awt.event.FocusEvent; import java.awt.event.FocusEvent;
import java.awt.event.FocusListener; import java.awt.event.FocusListener;
@@ -414,6 +416,17 @@ public class FlatUIUtils
return (fullScreenWindow != null && fullScreenWindow == SwingUtilities.windowForComponent( c )); return (fullScreenWindow != null && fullScreenWindow == SwingUtilities.windowForComponent( c ));
} }
/** @since 3.6.1 */
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 ) { public static Boolean isRoundRect( Component c ) {
return (c instanceof JComponent) return (c instanceof JComponent)
? FlatClientProperties.clientPropertyBooleanStrict( ? FlatClientProperties.clientPropertyBooleanStrict(

View File

@@ -331,7 +331,7 @@ public abstract class FlatWindowResizer
protected Rectangle getParentBounds() { protected Rectangle getParentBounds() {
GraphicsConfiguration gc = window.getGraphicsConfiguration(); GraphicsConfiguration gc = window.getGraphicsConfiguration();
Rectangle bounds = gc.getBounds(); 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, return new Rectangle( bounds.x + insets.left, bounds.y + insets.top,
bounds.width - insets.left - insets.right, bounds.width - insets.left - insets.right,
bounds.height - insets.top - insets.bottom ); bounds.height - insets.top - insets.bottom );

View File

@@ -21,6 +21,7 @@ import java.awt.Dialog;
import java.awt.EventQueue; import java.awt.EventQueue;
import java.awt.Frame; import java.awt.Frame;
import java.awt.GraphicsConfiguration; import java.awt.GraphicsConfiguration;
import java.awt.Insets;
import java.awt.Point; import java.awt.Point;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.awt.Window; import java.awt.Window;
@@ -39,6 +40,7 @@ import javax.swing.event.ChangeListener;
import javax.swing.event.EventListenerList; import javax.swing.event.EventListenerList;
import com.formdev.flatlaf.util.LoggingFacade; import com.formdev.flatlaf.util.LoggingFacade;
import com.formdev.flatlaf.util.SystemInfo; import com.formdev.flatlaf.util.SystemInfo;
import com.formdev.flatlaf.util.UIScale;
// //
// Interesting resources: // Interesting resources:
@@ -282,6 +284,8 @@ class FlatWindowsNativeWindowBorder
HTMINBUTTON = 8, HTMINBUTTON = 8,
HTMAXBUTTON = 9, HTMAXBUTTON = 9,
HTTOP = 12, HTTOP = 12,
HTTOPLEFT = 13,
HTTOPRIGHT = 14,
HTCLOSE = 20; HTCLOSE = 20;
private Window window; private Window window;
@@ -341,6 +345,31 @@ class FlatWindowsNativeWindowBorder
// scale-down mouse x/y because Swing coordinates/values may be scaled on a HiDPI screen // scale-down mouse x/y because Swing coordinates/values may be scaled on a HiDPI screen
Point pt = scaleDown( x, y ); Point pt = scaleDown( x, y );
// limit top resize border to 4px, which seems to be standard for modern WinUI apps
if( isOnResizeBorder && pt.y > UIScale.scale( 4 ) )
isOnResizeBorder = false;
if( isOnResizeBorder ) {
Insets insets = window.getInsets();
// return HTTOPLEFT if mouse is over top resize border on left side
// - hovering mouse shows top-left resize cursor
// - left-click-and-drag resizes window
if( pt.x <= insets.left + UIScale.scale( 12 ) )
return HTTOPLEFT;
// return HTTOPRIGHT if mouse is over top resize border on right side
// - hovering mouse shows top-right resize cursor
// - left-click-and-drag resizes window
if( pt.x >= window.getWidth() - insets.right - UIScale.scale( 12 ) )
return HTTOPRIGHT;
// return HTTOP if mouse is over top resize border
// - hovering mouse shows vertical resize cursor
// - left-click-and-drag vertically resizes window
return HTTOP;
}
// return HTSYSMENU if mouse is over application icon // return HTSYSMENU if mouse is over application icon
// - left-click on HTSYSMENU area shows system menu // - left-click on HTSYSMENU area shows system menu
// - double-left-click sends WM_CLOSE // - double-left-click sends WM_CLOSE
@@ -364,12 +393,6 @@ class FlatWindowsNativeWindowBorder
if( contains( closeButtonBounds, pt ) ) if( contains( closeButtonBounds, pt ) )
return HTCLOSE; return HTCLOSE;
// return HTTOP if mouse is over top resize border
// - hovering mouse shows vertical resize cursor
// - left-click and drag vertically resizes window
if( isOnResizeBorder )
return HTTOP;
boolean isOnTitleBar = (pt.y < titleBarHeight); boolean isOnTitleBar = (pt.y < titleBarHeight);
if( isOnTitleBar ) { if( isOnTitleBar ) {
// return HTCLIENT if mouse is over any Swing component in title bar // return HTCLIENT if mouse is over any Swing component in title bar

View File

@@ -276,7 +276,7 @@ RootPane.inactiveBorderColor = lighten(@background,5%,derived)
#---- ScrollBar ---- #---- ScrollBar ----
ScrollBar.track = lighten(@background,1%,derived noAutoInverse) 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.hoverTrackColor = lighten($ScrollBar.track,4%,derived noAutoInverse)
ScrollBar.hoverThumbColor = lighten($ScrollBar.thumb,10%,derived noAutoInverse) ScrollBar.hoverThumbColor = lighten($ScrollBar.thumb,10%,derived noAutoInverse)
ScrollBar.pressedThumbColor = lighten($ScrollBar.thumb,15%,derived noAutoInverse) ScrollBar.pressedThumbColor = lighten($ScrollBar.thumb,15%,derived noAutoInverse)
@@ -343,8 +343,13 @@ TableHeader.bottomSeparatorColor = $TableHeader.separatorColor
#---- TitlePane ---- #---- TitlePane ----
TitlePane.embeddedForeground = darken($TitlePane.foreground,15%) TitlePane.embeddedForeground = darken($TitlePane.foreground,15%)
TitlePane.buttonHoverBackground = lighten($TitlePane.background,15%,derived) TitlePane.buttonHoverBackground = lighten($TitlePane.background,10%,derived)
TitlePane.buttonPressedBackground = lighten($TitlePane.background,10%,derived) TitlePane.buttonPressedBackground = lighten($TitlePane.background,6%,derived)
# Linux
[linux]TitlePane.buttonBackground = lighten($TitlePane.background,5%,derived)
[linux]TitlePane.buttonHoverBackground = lighten($TitlePane.background,10%,derived)
[linux]TitlePane.buttonPressedBackground = lighten($TitlePane.background,15%,derived)
#---- ToggleButton ---- #---- ToggleButton ----

View File

@@ -574,12 +574,12 @@ RootPane.honorDialogMinimumSizeOnResize = true
ScrollBar.width = 10 ScrollBar.width = 10
ScrollBar.minimumButtonSize = 12,12 ScrollBar.minimumButtonSize = 12,12
ScrollBar.minimumThumbSize = 10,10 ScrollBar.minimumThumbSize = 18,18
ScrollBar.maximumThumbSize = 100000,100000 ScrollBar.maximumThumbSize = 100000,100000
ScrollBar.trackInsets = 0,0,0,0 ScrollBar.trackInsets = 0,0,0,0
ScrollBar.thumbInsets = 0,0,0,0 ScrollBar.thumbInsets = 2,2,2,2
ScrollBar.trackArc = 0 ScrollBar.trackArc = 0
ScrollBar.thumbArc = 0 ScrollBar.thumbArc = 999
ScrollBar.hoverThumbWithTrack = false ScrollBar.hoverThumbWithTrack = false
ScrollBar.pressedThumbWithTrack = false ScrollBar.pressedThumbWithTrack = false
ScrollBar.showButtons = false ScrollBar.showButtons = false
@@ -588,15 +588,8 @@ ScrollBar.buttonArrowColor = @buttonArrowColor
ScrollBar.buttonDisabledArrowColor = @buttonDisabledArrowColor ScrollBar.buttonDisabledArrowColor = @buttonDisabledArrowColor
ScrollBar.allowsAbsolutePositioning = true ScrollBar.allowsAbsolutePositioning = true
[mac]ScrollBar.minimumThumbSize = 18,18
[mac]ScrollBar.thumbInsets = 2,2,2,2
[mac]ScrollBar.thumbArc = 999
[mac]ScrollBar.hoverThumbWithTrack = true [mac]ScrollBar.hoverThumbWithTrack = true
[linux]ScrollBar.minimumThumbSize = 18,18
[linux]ScrollBar.thumbInsets = 2,2,2,2
[linux]ScrollBar.thumbArc = 999
#---- ScrollPane ---- #---- ScrollPane ----
@@ -823,9 +816,14 @@ TitlePane.iconMargins = 3,8,3,8
TitlePane.titleMargins = 3,0,3,0 TitlePane.titleMargins = 3,0,3,0
TitlePane.titleMinimumWidth = 60 TitlePane.titleMinimumWidth = 60
TitlePane.buttonSize = 44,30 TitlePane.buttonSize = 44,30
TitlePane.buttonInsets = 0,0,0,0
TitlePane.buttonArc = 0
TitlePane.buttonMinimumWidth = 30 TitlePane.buttonMinimumWidth = 30
TitlePane.buttonMaximizedHeight = 22 TitlePane.buttonMaximizedHeight = 22
TitlePane.buttonSymbolHeight = 10 TitlePane.buttonSymbolHeight = 10
TitlePane.buttonsGap = 0
TitlePane.buttonsMargins = 0,0,0,0
TitlePane.buttonsFillVertically = true
TitlePane.centerTitle = false TitlePane.centerTitle = false
TitlePane.centerTitleIfMenuBarEmbedded = true TitlePane.centerTitleIfMenuBarEmbedded = true
TitlePane.showIconBesideTitle = false TitlePane.showIconBesideTitle = false
@@ -856,6 +854,27 @@ TitlePane.small.iconifyIcon = com.formdev.flatlaf.icons.FlatWindowIconifyIcon, s
TitlePane.small.maximizeIcon = com.formdev.flatlaf.icons.FlatWindowMaximizeIcon, small TitlePane.small.maximizeIcon = com.formdev.flatlaf.icons.FlatWindowMaximizeIcon, small
TitlePane.small.restoreIcon = com.formdev.flatlaf.icons.FlatWindowRestoreIcon, small TitlePane.small.restoreIcon = com.formdev.flatlaf.icons.FlatWindowRestoreIcon, small
# Linux
[linux]TitlePane.buttonSize = 26,26
[linux]TitlePane.buttonInsets = 2,2,2,2
[linux]TitlePane.buttonArc = 999
[linux]TitlePane.buttonMaximizedHeight = -1
[linux]TitlePane.buttonSymbolHeight = 8
[linux]TitlePane.buttonsGap = 8
[linux]TitlePane.buttonsMargins = 4,4,4,4
[linux]TitlePane.buttonsFillVertically = false
[linux]TitlePane.small.buttonSize = 20,20
[linux]TitlePane.small.buttonInsets = 1,1,1,1
[linux]TitlePane.small.buttonSymbolHeight = 6
[linux]TitlePane.small.buttonsGap = 4
[linux]TitlePane.small.buttonsMargins = 2,2,2,2
[linux]TitlePane.closeBackground = $?TitlePane.buttonBackground
[linux]TitlePane.closeInactiveBackground = $?TitlePane.buttonInactiveBackground
[linux]TitlePane.closeHoverBackground = $?TitlePane.buttonHoverBackground
[linux]TitlePane.closePressedBackground = $?TitlePane.buttonPressedBackground
[linux]TitlePane.closeHoverForeground = $?TitlePane.foreground
[linux]TitlePane.closePressedForeground = $?TitlePane.foreground
#---- ToggleButton ---- #---- ToggleButton ----

View File

@@ -282,7 +282,7 @@ RootPane.inactiveBorderColor = darken(@background,30%,derived)
#---- ScrollBar ---- #---- ScrollBar ----
ScrollBar.track = lighten(@background,1%,derived noAutoInverse) 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.hoverTrackColor = darken($ScrollBar.track,3%,derived noAutoInverse)
ScrollBar.hoverThumbColor = darken($ScrollBar.thumb,10%,derived noAutoInverse) ScrollBar.hoverThumbColor = darken($ScrollBar.thumb,10%,derived noAutoInverse)
ScrollBar.pressedThumbColor = darken($ScrollBar.thumb,20%,derived noAutoInverse) ScrollBar.pressedThumbColor = darken($ScrollBar.thumb,20%,derived noAutoInverse)
@@ -349,8 +349,13 @@ TableHeader.bottomSeparatorColor = $TableHeader.separatorColor
#---- TitlePane ---- #---- TitlePane ----
TitlePane.embeddedForeground = lighten($TitlePane.foreground,35%) TitlePane.embeddedForeground = lighten($TitlePane.foreground,35%)
TitlePane.buttonHoverBackground = darken($TitlePane.background,10%,derived) TitlePane.buttonHoverBackground = darken($TitlePane.background,5%,derived)
TitlePane.buttonPressedBackground = darken($TitlePane.background,8%,derived) TitlePane.buttonPressedBackground = darken($TitlePane.background,3%,derived)
# Linux
[linux]TitlePane.buttonBackground = darken($TitlePane.background,5%,derived)
[linux]TitlePane.buttonHoverBackground = darken($TitlePane.background,10%,derived)
[linux]TitlePane.buttonPressedBackground = darken($TitlePane.background,15%,derived)
#---- ToggleButton ---- #---- ToggleButton ----

View File

@@ -184,6 +184,7 @@ MenuBar.selectionEmbeddedInsets = 3,0,3,0
MenuBar.selectionArc = 8 MenuBar.selectionArc = 8
MenuBar.selectionBackground = lighten(@menuBackground,15%,derived) MenuBar.selectionBackground = lighten(@menuBackground,15%,derived)
MenuBar.selectionForeground = @foreground MenuBar.selectionForeground = @foreground
MenuBar.borderColor = over($Separator.foreground,$MenuBar.background)
#---- MenuItem ---- #---- MenuItem ----

View File

@@ -184,6 +184,7 @@ MenuBar.selectionEmbeddedInsets = 3,0,3,0
MenuBar.selectionArc = 8 MenuBar.selectionArc = 8
MenuBar.selectionBackground = darken(@menuBackground,15%,derived) MenuBar.selectionBackground = darken(@menuBackground,15%,derived)
MenuBar.selectionForeground = @foreground MenuBar.selectionForeground = @foreground
MenuBar.borderColor = over($Separator.foreground,$MenuBar.background)
#---- MenuItem ---- #---- MenuItem ----

View File

@@ -18,6 +18,7 @@ package com.formdev.flatlaf;
import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertInstanceOf; 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 static org.junit.jupiter.api.Assertions.assertTrue;
import java.awt.Color; import java.awt.Color;
import java.awt.Dimension; import java.awt.Dimension;
@@ -29,6 +30,7 @@ import javax.swing.border.Border;
import javax.swing.UIDefaults.ActiveValue; import javax.swing.UIDefaults.ActiveValue;
import javax.swing.UIDefaults.LazyValue; import javax.swing.UIDefaults.LazyValue;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.function.Executable;
import com.formdev.flatlaf.ui.FlatEmptyBorder; import com.formdev.flatlaf.ui.FlatEmptyBorder;
import com.formdev.flatlaf.ui.FlatLineBorder; import com.formdev.flatlaf.ui.FlatLineBorder;
import com.formdev.flatlaf.util.DerivedColor; import com.formdev.flatlaf.util.DerivedColor;
@@ -452,6 +454,73 @@ public class TestUIDefaultsLoader
return ((LazyValue)v).createValue( null ); 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 ------------------------------------------------- //---- class TestInstance -------------------------------------------------
@SuppressWarnings( "EqualsHashCode" ) // Error Prone @SuppressWarnings( "EqualsHashCode" ) // Error Prone

View File

@@ -0,0 +1,404 @@
/*
* 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.ui;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.awt.Color;
import java.util.HashMap;
import java.util.function.Function;
import java.util.function.Predicate;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JRootPane;
import javax.swing.UIManager;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.FlatLaf;
/**
* @author Karl Tauber
*/
public class TestFlatButton
{
@BeforeAll
static void setup() {
String[] defs = {
"Button.background", "#000001",
"Button.foreground", "#000002",
"Button.focusedBackground", "#000003",
"Button.focusedForeground", "#000004",
"Button.hoverBackground", "#000005",
"Button.hoverForeground", "#000006",
"Button.pressedBackground", "#000007",
"Button.pressedForeground", "#000008",
"Button.selectedBackground", "#000009",
"Button.selectedForeground", "#00000a",
"Button.disabledBackground", "#00000b",
"Button.disabledText", "#00000c",
"Button.disabledSelectedBackground", "#00000d",
"Button.disabledSelectedForeground", "#00000e",
"Button.default.background", "#000101",
"Button.default.foreground", "#000102",
"Button.default.focusedBackground", "#000103",
"Button.default.focusedForeground", "#000104",
"Button.default.hoverBackground", "#000105",
"Button.default.hoverForeground", "#000106",
"Button.default.pressedBackground", "#000107",
"Button.default.pressedForeground", "#000108",
"Button.toolbar.hoverBackground", "#000201",
"Button.toolbar.hoverForeground", "#000202",
"Button.toolbar.pressedBackground", "#000203",
"Button.toolbar.pressedForeground", "#000204",
"Button.toolbar.selectedBackground", "#000205",
"Button.toolbar.selectedForeground", "#000206",
"Button.toolbar.disabledSelectedBackground", "#000207",
"Button.toolbar.disabledSelectedForeground", "#000208",
};
HashMap<String, String> globalExtraDefaults = new HashMap<>();
for( int i = 0; i < defs.length; i += 2 )
globalExtraDefaults.put( defs[i], defs[i+1] );
FlatLaf.setGlobalExtraDefaults( globalExtraDefaults );
TestUtils.setup( false );
}
@AfterAll
static void cleanup() {
TestUtils.cleanup();
}
@Test
void background() {
JButton b = new JButton();
testButtonColors( b, b2 -> ((FlatButtonUI)b2.getUI()).getBackground( b2 ),
UIManager.getColor( "Button.background" ),
UIManager.getColor( "Button.disabledBackground" ),
UIManager.getColor( "Button.focusedBackground" ),
UIManager.getColor( "Button.hoverBackground" ),
UIManager.getColor( "Button.pressedBackground" ) );
// selected
b.setSelected( true );
testButtonColors( b, b2 -> ((FlatButtonUI)b2.getUI()).getBackground( b2 ),
UIManager.getColor( "Button.selectedBackground" ),
UIManager.getColor( "Button.disabledSelectedBackground" ),
null,
null,
UIManager.getColor( "Button.pressedBackground" ) );
b.setSelected( false );
// default
JRootPane rootPane = new JRootPane();
rootPane.getContentPane().add( b );
rootPane.setDefaultButton( b );
testButtonColors( b, b2 -> ((FlatButtonUI)b2.getUI()).getBackground( b2 ),
UIManager.getColor( "Button.default.background" ),
UIManager.getColor( "Button.disabledBackground" ),
UIManager.getColor( "Button.default.focusedBackground" ),
UIManager.getColor( "Button.default.hoverBackground" ),
UIManager.getColor( "Button.default.pressedBackground" ) );
rootPane.getContentPane().remove( b );
}
@Test
void foreground() {
JButton b = new JButton();
testButtonColors( b, b2 -> ((FlatButtonUI)b2.getUI()).getForeground( b2 ),
UIManager.getColor( "Button.foreground" ),
UIManager.getColor( "Button.disabledText" ),
UIManager.getColor( "Button.focusedForeground" ),
UIManager.getColor( "Button.hoverForeground" ),
UIManager.getColor( "Button.pressedForeground" ) );
// selected
b.setSelected( true );
testButtonColors( b, b2 -> ((FlatButtonUI)b2.getUI()).getForeground( b2 ),
UIManager.getColor( "Button.selectedForeground" ),
FlatUIUtils.getUIColor( "Button.disabledSelectedForeground", "Button.disabledText" ),
null,
null,
UIManager.getColor( "Button.pressedForeground" ) );
b.setSelected( false );
// default
JRootPane rootPane = new JRootPane();
rootPane.getContentPane().add( b );
rootPane.setDefaultButton( b );
testButtonColors( b, b2 -> ((FlatButtonUI)b2.getUI()).getForeground( b2 ),
UIManager.getColor( "Button.default.foreground" ),
UIManager.getColor( "Button.disabledText" ),
UIManager.getColor( "Button.default.focusedForeground" ),
UIManager.getColor( "Button.default.hoverForeground" ),
UIManager.getColor( "Button.default.pressedForeground" ) );
rootPane.getContentPane().remove( b );
}
@Test
void backgroundExplicit() {
JButton b = new JButton();
Color c = new Color( 0x020001 );
b.setBackground( c );
testButtonColors( b, b2 -> ((FlatButtonUI)b2.getUI()).getBackground( b2 ),
c,
UIManager.getColor( "Button.disabledBackground" ),
null,
UIManager.getColor( "Button.hoverBackground" ),
UIManager.getColor( "Button.pressedBackground" ) );
// selected
b.setSelected( true );
testButtonColors( b, b2 -> ((FlatButtonUI)b2.getUI()).getBackground( b2 ),
UIManager.getColor( "Button.selectedBackground" ),
UIManager.getColor( "Button.disabledSelectedBackground" ),
null,
null,
UIManager.getColor( "Button.pressedBackground" ) );
b.setSelected( false );
// default
JRootPane rootPane = new JRootPane();
rootPane.getContentPane().add( b );
rootPane.setDefaultButton( b );
testButtonColors( b, b2 -> ((FlatButtonUI)b2.getUI()).getBackground( b2 ),
c,
UIManager.getColor( "Button.disabledBackground" ),
null,
UIManager.getColor( "Button.default.hoverBackground" ),
UIManager.getColor( "Button.default.pressedBackground" ) );
rootPane.getContentPane().remove( b );
}
@Test
void foregroundExplicit() {
JButton b = new JButton();
Color c = new Color( 0x020001 );
b.setForeground( c );
testButtonColors( b, b2 -> ((FlatButtonUI)b2.getUI()).getForeground( b2 ),
c,
UIManager.getColor( "Button.disabledText" ),
null,
UIManager.getColor( "Button.hoverForeground" ),
UIManager.getColor( "Button.pressedForeground" ) );
// selected
b.setSelected( true );
testButtonColors( b, b2 -> ((FlatButtonUI)b2.getUI()).getForeground( b2 ),
c,
FlatUIUtils.getUIColor( "Button.disabledSelectedForeground", "Button.disabledText" ),
null,
null,
UIManager.getColor( "Button.pressedForeground" ) );
b.setSelected( false );
// default
JRootPane rootPane = new JRootPane();
rootPane.getContentPane().add( b );
rootPane.setDefaultButton( b );
testButtonColors( b, b2 -> ((FlatButtonUI)b2.getUI()).getForeground( b2 ),
c,
UIManager.getColor( "Button.disabledText" ),
null,
UIManager.getColor( "Button.default.hoverForeground" ),
UIManager.getColor( "Button.default.pressedForeground" ) );
rootPane.getContentPane().remove( b );
}
@Test
void backgroundStyled() {
JButton b = new JButton();
b.putClientProperty( FlatClientProperties.STYLE,
"background: #020001;" +
"disabledBackground: #020002;" +
"focusedBackground: #020003;" +
"hoverBackground: #020004;" +
"pressedBackground: #020005;" +
"selectedBackground: #020006;" +
"disabledSelectedBackground: #020007;" );
testButtonColors( b, b2 -> ((FlatButtonUI)b2.getUI()).getBackground( b2 ),
new Color( 0x020001 ),
new Color( 0x020002 ),
new Color( 0x020003 ),
new Color( 0x020004 ),
new Color( 0x020005 ) );
// selected
b.setSelected( true );
testButtonColors( b, b2 -> ((FlatButtonUI)b2.getUI()).getBackground( b2 ),
new Color( 0x020006 ),
new Color( 0x020007 ),
null,
null,
new Color( 0x020005 ) );
b.setSelected( false );
Color c = new Color( 0x0a0001 );
b.setBackground( c );
testButtonColors( b, b2 -> ((FlatButtonUI)b2.getUI()).getBackground( b2 ),
c,
new Color( 0x020002 ),
c,
new Color( 0x020004 ),
new Color( 0x020005 ) );
b.setSelected( true );
testButtonColors( b, b2 -> ((FlatButtonUI)b2.getUI()).getBackground( b2 ),
new Color( 0x020006 ),
new Color( 0x020007 ),
null,
null,
new Color( 0x020005 ) );
b.setSelected( false );
b = new JButton();
b.putClientProperty( FlatClientProperties.STYLE,
"default.background: #020101;" +
"disabledBackground: #020102;" +
"default.focusedBackground: #020103;" +
"default.hoverBackground: #020104;" +
"default.pressedBackground: #020105;" );
// default
JRootPane rootPane = new JRootPane();
rootPane.getContentPane().add( b );
rootPane.setDefaultButton( b );
testButtonColors( b, b2 -> ((FlatButtonUI)b2.getUI()).getBackground( b2 ),
new Color( 0x020101 ),
new Color( 0x020102 ),
new Color( 0x020103 ),
new Color( 0x020104 ),
new Color( 0x020105 ) );
rootPane.getContentPane().remove( b );
}
@Test
void foregroundStyled() {
JButton b = new JButton();
b.putClientProperty( FlatClientProperties.STYLE,
"foreground: #020001;" +
"disabledText: #020002;" +
"focusedForeground: #020003;" +
"hoverForeground: #020004;" +
"pressedForeground: #020005;" +
"selectedForeground: #020006;" +
"disabledSelectedForeground: #020007;" );
testButtonColors( b, b2 -> ((FlatButtonUI)b2.getUI()).getForeground( b2 ),
new Color( 0x020001 ),
new Color( 0x020002 ),
new Color( 0x020003 ),
new Color( 0x020004 ),
new Color( 0x020005 ) );
// selected
b.setSelected( true );
testButtonColors( b, b2 -> ((FlatButtonUI)b2.getUI()).getForeground( b2 ),
new Color( 0x020006 ),
new Color( 0x020007 ),
null,
null,
new Color( 0x020005 ) );
b.setSelected( false );
Color c = new Color( 0x0a0001 );
b.setForeground( c );
testButtonColors( b, b2 -> ((FlatButtonUI)b2.getUI()).getForeground( b2 ),
c,
new Color( 0x020002 ),
c,
new Color( 0x020004 ),
new Color( 0x020005 ) );
b.setSelected( true );
testButtonColors( b, b2 -> ((FlatButtonUI)b2.getUI()).getForeground( b2 ),
c,
new Color( 0x020007 ),
null,
null,
new Color( 0x020005 ) );
b.setSelected( false );
b = new JButton();
b.putClientProperty( FlatClientProperties.STYLE,
"default.foreground: #020101;" +
"disabledText: #020102;" +
"default.focusedForeground: #020103;" +
"default.hoverForeground: #020104;" +
"default.pressedForeground: #020105;" );
// default
JRootPane rootPane = new JRootPane();
rootPane.getContentPane().add( b );
rootPane.setDefaultButton( b );
testButtonColors( b, b2 -> ((FlatButtonUI)b2.getUI()).getForeground( b2 ),
new Color( 0x020101 ),
new Color( 0x020102 ),
new Color( 0x020103 ),
new Color( 0x020104 ),
new Color( 0x020105 ) );
rootPane.getContentPane().remove( b );
}
private void testButtonColors( JButton b, Function<JButton, Color> f,
Color expectedEnabled, Color expectedDisabled, Color expectedFocused,
Color expectedHover, Color expectedPressed
)
{
assertEquals( expectedEnabled, f.apply( b ) );
// disabled
b.setEnabled( false );
assertEquals( expectedDisabled, f.apply( b ) );
b.setEnabled( true );
// focused
if( expectedFocused != null ) {
b.putClientProperty( FlatClientProperties.COMPONENT_FOCUS_OWNER, (Predicate<JComponent>) c -> true );
assertEquals( expectedFocused, f.apply( b ) );
b.putClientProperty( FlatClientProperties.COMPONENT_FOCUS_OWNER, null );
}
// hover
if( expectedHover != null ) {
b.getModel().setRollover( true );
assertEquals( expectedHover, f.apply( b ) );
b.getModel().setRollover( false );
}
// pressed
if( expectedPressed != null ) {
b.getModel().setPressed( true );
assertEquals( expectedPressed, f.apply( b ) );
b.getModel().setPressed( false );
}
}
}

View File

@@ -48,6 +48,9 @@ tasks {
if( JavaVersion.current() >= JavaVersion.VERSION_1_9 ) if( JavaVersion.current() >= JavaVersion.VERSION_1_9 )
attributes( "Multi-Release" to "true" ) 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" ) exclude( "module-info.class" )

View File

@@ -228,8 +228,20 @@ class DemoFrame
private void windowDecorationsChanged() { private void windowDecorationsChanged() {
boolean windowDecorations = windowDecorationsCheckBoxMenuItem.isSelected(); boolean windowDecorations = windowDecorationsCheckBoxMenuItem.isSelected();
// change window decoration of all frames and dialogs if( SystemInfo.isLinux ) {
FlatLaf.setUseNativeWindowDecorations( windowDecorations ); // 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 ); menuBarEmbeddedCheckBoxMenuItem.setEnabled( windowDecorations );
unifiedTitleBarMenuItem.setEnabled( windowDecorations ); unifiedTitleBarMenuItem.setEnabled( windowDecorations );
@@ -486,7 +498,7 @@ class DemoFrame
} }
private boolean supportsFlatLafWindowDecorations() { private boolean supportsFlatLafWindowDecorations() {
return FlatLaf.supportsNativeWindowDecorations() || (SystemInfo.isLinux && JFrame.isDefaultLookAndFeelDecorated()); return FlatLaf.supportsNativeWindowDecorations() || SystemInfo.isLinux;
} }
private void initComponents() { private void initComponents() {
@@ -979,10 +991,9 @@ class DemoFrame
scrollingPopupMenu.add( "Item " + i ); scrollingPopupMenu.add( "Item " + i );
if( supportsFlatLafWindowDecorations() ) { if( supportsFlatLafWindowDecorations() ) {
if( SystemInfo.isLinux ) windowDecorationsCheckBoxMenuItem.setSelected( SystemInfo.isLinux
unsupported( windowDecorationsCheckBoxMenuItem ); ? JFrame.isDefaultLookAndFeelDecorated()
else : FlatLaf.isUseNativeWindowDecorations() );
windowDecorationsCheckBoxMenuItem.setSelected( FlatLaf.isUseNativeWindowDecorations() );
menuBarEmbeddedCheckBoxMenuItem.setSelected( UIManager.getBoolean( "TitlePane.menuBarEmbedded" ) ); menuBarEmbeddedCheckBoxMenuItem.setSelected( UIManager.getBoolean( "TitlePane.menuBarEmbedded" ) );
unifiedTitleBarMenuItem.setSelected( UIManager.getBoolean( "TitlePane.unifiedBackground" ) ); unifiedTitleBarMenuItem.setSelected( UIManager.getBoolean( "TitlePane.unifiedBackground" ) );
showTitleBarIconMenuItem.setSelected( UIManager.getBoolean( "TitlePane.showIcon" ) ); showTitleBarIconMenuItem.setSelected( UIManager.getBoolean( "TitlePane.showIcon" ) );
@@ -1026,7 +1037,7 @@ class DemoFrame
private void unsupported( JCheckBoxMenuItem menuItem ) { private void unsupported( JCheckBoxMenuItem menuItem ) {
menuItem.setEnabled( false ); menuItem.setEnabled( false );
menuItem.setSelected( 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 // JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables

View File

@@ -41,6 +41,11 @@ If SVG classes are used, `jsvg-<version>.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) [![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.6.1+ supports JSVG 1.6.0 and later.
- FlatLaf 3.6- supports only JSVG 1.x (but not 2.x).
Tools Tools
----- -----

View File

@@ -25,6 +25,7 @@ import java.awt.Image;
import java.awt.Paint; import java.awt.Paint;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.awt.RenderingHints; import java.awt.RenderingHints;
import java.awt.geom.Dimension2D;
import java.awt.LinearGradientPaint; import java.awt.LinearGradientPaint;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.awt.image.RGBImageFilter; 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.SoftCache;
import com.formdev.flatlaf.util.UIScale; import com.formdev.flatlaf.util.UIScale;
import com.github.weisj.jsvg.SVGDocument; 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; import com.github.weisj.jsvg.parser.SVGLoader;
/** /**
@@ -271,7 +272,7 @@ public class FlatSVGIcon
this( null, -1, -1, 1, false, null, null ); this( null, -1, -1, 1, false, null, null );
try( InputStream in2 = in ) { try( InputStream in2 = in ) {
document = svgLoader.load( in2 ); document = svgLoader.load( in2, null, LoaderContext.createDefault() );
if( document == null ) { if( document == null ) {
loadFailed = true; loadFailed = true;
@@ -620,9 +621,9 @@ public class FlatSVGIcon
UIScale.scaleGraphics( g ); UIScale.scaleGraphics( g );
if( width > 0 || height > 0 ) { if( width > 0 || height > 0 ) {
FloatSize svgSize = document.size(); Dimension2D svgSize = document.size();
double sx = (width > 0) ? width / svgSize.width : 1; double sx = (width > 0) ? width / svgSize.getWidth() : 1;
double sy = (height > 0) ? height / svgSize.height : 1; double sy = (height > 0) ? height / svgSize.getHeight() : 1;
if( sx != 1 || sy != 1 ) if( sx != 1 || sy != 1 )
g.scale( sx, sy ); g.scale( sx, sy );
} }

View File

@@ -19,6 +19,7 @@ package com.formdev.flatlaf.extras;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.awt.Image; import java.awt.Image;
import java.awt.geom.Dimension2D;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.net.URL; import java.net.URL;
import java.util.Arrays; import java.util.Arrays;
@@ -28,7 +29,6 @@ import javax.swing.JWindow;
import com.formdev.flatlaf.util.MultiResolutionImageSupport; import com.formdev.flatlaf.util.MultiResolutionImageSupport;
import com.formdev.flatlaf.util.SystemInfo; import com.formdev.flatlaf.util.SystemInfo;
import com.github.weisj.jsvg.SVGDocument; import com.github.weisj.jsvg.SVGDocument;
import com.github.weisj.jsvg.geometry.size.FloatSize;
/** /**
* Utility methods for SVG. * Utility methods for SVG.
@@ -180,9 +180,9 @@ public class FlatSVGUtils
*/ */
public static BufferedImage svg2image( URL svgUrl, float scaleFactor ) { public static BufferedImage svg2image( URL svgUrl, float scaleFactor ) {
SVGDocument document = FlatSVGIcon.loadSVG( svgUrl ); SVGDocument document = FlatSVGIcon.loadSVG( svgUrl );
FloatSize size = document.size(); Dimension2D size = document.size();
int width = (int) (size.width * scaleFactor); int width = (int) (size.getWidth() * scaleFactor);
int height = (int) (size.height * scaleFactor); int height = (int) (size.getHeight() * scaleFactor);
return svg2image( document, width, height ); return svg2image( document, width, height );
} }
@@ -202,9 +202,9 @@ public class FlatSVGUtils
try { try {
FlatSVGIcon.setRenderingHints( g ); FlatSVGIcon.setRenderingHints( g );
FloatSize size = document.size(); Dimension2D size = document.size();
double sx = width / size.width; double sx = width / size.getWidth();
double sy = height / size.height; double sy = height / size.getHeight();
if( sx != 1 || sy != 1 ) if( sx != 1 || sy != 1 )
g.scale( sx, sy ); g.scale( sx, sy );

View File

@@ -215,8 +215,14 @@ TableHeader.pressedForeground = TableHeader.foreground
#---- TitlePane ---- #---- TitlePane ----
TitlePane.buttonBackground = TitlePane.background
TitlePane.buttonInactiveBackground = TitlePane.background
TitlePane.buttonHoverBackground = TitlePane.background TitlePane.buttonHoverBackground = TitlePane.background
TitlePane.buttonPressedBackground = TitlePane.background TitlePane.buttonPressedBackground = TitlePane.background
TitlePane.closeBackground = TitlePane.background
TitlePane.closeInactiveBackground = TitlePane.background
TitlePane.closeHoverBackground = TitlePane.background
TitlePane.closePressedBackground = TitlePane.background
#---- ToggleButton ---- #---- ToggleButton ----

View File

@@ -25,9 +25,11 @@ import java.awt.geom.Rectangle2D;
import javax.swing.ButtonModel; import javax.swing.ButtonModel;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.JMenuItem; import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.SwingConstants; import javax.swing.SwingConstants;
import javax.swing.UIManager; import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI; import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.PopupMenuUI;
import com.formdev.flatlaf.ui.FlatUIUtils; import com.formdev.flatlaf.ui.FlatUIUtils;
import com.formdev.flatlaf.util.UIScale; import com.formdev.flatlaf.util.UIScale;
import com.jidesoft.plaf.LookAndFeelFactory; 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 // but it does not because FlatLaf already has added the UI class to the UI defaults
LookAndFeelFactory.installJideExtension(); 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(); return new FlatJideSplitButtonUI();
} }

View File

@@ -24,6 +24,7 @@ import java.awt.Dialog;
import java.awt.EventQueue; import java.awt.EventQueue;
import java.awt.Frame; import java.awt.Frame;
import java.awt.GraphicsConfiguration; import java.awt.GraphicsConfiguration;
import java.awt.Insets;
import java.awt.Point; import java.awt.Point;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.awt.Window; import java.awt.Window;
@@ -42,6 +43,7 @@ import javax.swing.event.ChangeListener;
import javax.swing.event.EventListenerList; import javax.swing.event.EventListenerList;
import com.formdev.flatlaf.ui.FlatNativeWindowBorder; import com.formdev.flatlaf.ui.FlatNativeWindowBorder;
import com.formdev.flatlaf.util.SystemInfo; import com.formdev.flatlaf.util.SystemInfo;
import com.formdev.flatlaf.util.UIScale;
import com.sun.jna.Native; import com.sun.jna.Native;
import com.sun.jna.Pointer; import com.sun.jna.Pointer;
import com.sun.jna.Structure; import com.sun.jna.Structure;
@@ -326,6 +328,8 @@ public class FlatWindowsNativeWindowBorder
HTMINBUTTON = 8, HTMINBUTTON = 8,
HTMAXBUTTON = 9, HTMAXBUTTON = 9,
HTTOP = 12, HTTOP = 12,
HTTOPLEFT = 13,
HTTOPRIGHT = 14,
HTCLOSE = 20; HTCLOSE = 20;
private static final int ABS_AUTOHIDE = 0x0000001; private static final int ABS_AUTOHIDE = 0x0000001;
@@ -674,6 +678,35 @@ public class FlatWindowsNativeWindowBorder
// scale-down mouse x/y because Swing coordinates/values may be scaled on a HiDPI screen // scale-down mouse x/y because Swing coordinates/values may be scaled on a HiDPI screen
Point pt = scaleDown( x, y ); Point pt = scaleDown( x, y );
int resizeBorderHeight = getResizeHandleHeight();
boolean isOnResizeBorder = (y < resizeBorderHeight) &&
(User32.INSTANCE.GetWindowLong( hwnd, GWL_STYLE ) & WS_THICKFRAME) != 0;
// limit top resize border to 4px, which seems to be standard for modern WinUI apps
if( isOnResizeBorder && pt.y > UIScale.scale( 4 ) )
isOnResizeBorder = false;
if( isOnResizeBorder ) {
Insets insets = window.getInsets();
// return HTTOPLEFT if mouse is over top resize border on left side
// - hovering mouse shows top-left resize cursor
// - left-click-and-drag resizes window
if( pt.x <= insets.left + UIScale.scale( 12 ) )
return new LRESULT( HTTOPLEFT );
// return HTTOPRIGHT if mouse is over top resize border on right side
// - hovering mouse shows top-right resize cursor
// - left-click-and-drag resizes window
if( pt.x >= window.getWidth() - insets.right - UIScale.scale( 12 ) )
return new LRESULT( HTTOPRIGHT );
// return HTTOP if mouse is over top resize border
// - hovering mouse shows vertical resize cursor
// - left-click-and-drag vertically resizes window
return new LRESULT( HTTOP );
}
// return HTSYSMENU if mouse is over application icon // return HTSYSMENU if mouse is over application icon
// - left-click on HTSYSMENU area shows system menu // - left-click on HTSYSMENU area shows system menu
// - double-left-click sends WM_CLOSE // - double-left-click sends WM_CLOSE
@@ -697,16 +730,6 @@ public class FlatWindowsNativeWindowBorder
if( contains( closeButtonBounds, pt ) ) if( contains( closeButtonBounds, pt ) )
return new LRESULT( HTCLOSE ); return new LRESULT( HTCLOSE );
int resizeBorderHeight = getResizeHandleHeight();
boolean isOnResizeBorder = (y < resizeBorderHeight) &&
(User32.INSTANCE.GetWindowLong( hwnd, GWL_STYLE ) & WS_THICKFRAME) != 0;
// return HTTOP if mouse is over top resize border
// - hovering mouse shows vertical resize cursor
// - left-click and drag vertically resizes window
if( isOnResizeBorder )
return new LRESULT( HTTOP );
boolean isOnTitleBar = (pt.y < titleBarHeight); boolean isOnTitleBar = (pt.y < titleBarHeight);
if( isOnTitleBar ) { if( isOnTitleBar ) {
// return HTCLIENT if mouse is over any Swing component in title bar // return HTCLIENT if mouse is over any Swing component in title bar

View File

@@ -25,18 +25,6 @@
+ ProgressBar.font [active] Liberation Sans plain 13 javax.swing.plaf.FontUIResource [UI] + 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 ----
- TaskPane.font [active] Segoe UI bold 12 javax.swing.plaf.FontUIResource [UI] - TaskPane.font [active] Segoe UI bold 12 javax.swing.plaf.FontUIResource [UI]
@@ -45,8 +33,86 @@
#---- TitlePane ---- #---- TitlePane ----
- TitlePane.buttonArc 0
+ TitlePane.buttonArc 999
+ TitlePane.buttonBackground #3c3f41 HSL 204 4 25 com.formdev.flatlaf.util.DerivedColor [UI] lighten(5% autoInverse)
- TitlePane.buttonInsets 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI]
+ TitlePane.buttonInsets 2,2,2,2 javax.swing.plaf.InsetsUIResource [UI]
- TitlePane.buttonMaximizedHeight 22
+ TitlePane.buttonMaximizedHeight -1
- TitlePane.buttonPressedBackground #3f4144 HSL 216 4 26 com.formdev.flatlaf.util.DerivedColor [UI] lighten(6% autoInverse)
+ TitlePane.buttonPressedBackground #55585c HSL 214 4 35 com.formdev.flatlaf.util.DerivedColor [UI] lighten(15% autoInverse)
- TitlePane.buttonSize 44,30 javax.swing.plaf.DimensionUIResource [UI]
+ TitlePane.buttonSize 26,26 javax.swing.plaf.DimensionUIResource [UI]
- TitlePane.buttonSymbolHeight 10
+ TitlePane.buttonSymbolHeight 8
- TitlePane.buttonsFillVertically true
+ TitlePane.buttonsFillVertically false
- TitlePane.buttonsGap 0
+ TitlePane.buttonsGap 8
- TitlePane.buttonsMargins 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI]
+ TitlePane.buttonsMargins 4,4,4,4 javax.swing.plaf.InsetsUIResource [UI]
+ TitlePane.closeBackground #3c3f41 HSL 204 4 25 com.formdev.flatlaf.util.DerivedColor [UI] lighten(5% autoInverse)
- TitlePane.closeHoverBackground #c42b1c HSL 5 75 44 javax.swing.plaf.ColorUIResource [UI]
+ TitlePane.closeHoverBackground #484c4f HSL 206 5 30 com.formdev.flatlaf.util.DerivedColor [UI] lighten(10% autoInverse)
- TitlePane.closeHoverForeground #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI]
+ TitlePane.closeHoverForeground #dddddd HSL 0 0 87 javax.swing.plaf.ColorUIResource [UI]
- TitlePane.closeIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowCloseIcon [UI]
+ TitlePane.closeIcon [lazy] 26,26 com.formdev.flatlaf.icons.FlatWindowCloseIcon [UI]
- TitlePane.closePressedBackground #c42b1ce6 90% HSLA 5 75 44 90 javax.swing.plaf.ColorUIResource [UI]
+ TitlePane.closePressedBackground #55585c HSL 214 4 35 com.formdev.flatlaf.util.DerivedColor [UI] lighten(15% autoInverse)
- TitlePane.closePressedForeground #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI]
+ TitlePane.closePressedForeground #dddddd HSL 0 0 87 javax.swing.plaf.ColorUIResource [UI]
- TitlePane.iconifyIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowIconifyIcon [UI]
+ TitlePane.iconifyIcon [lazy] 26,26 com.formdev.flatlaf.icons.FlatWindowIconifyIcon [UI]
- TitlePane.maximizeIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowMaximizeIcon [UI]
+ TitlePane.maximizeIcon [lazy] 26,26 com.formdev.flatlaf.icons.FlatWindowMaximizeIcon [UI]
- TitlePane.restoreIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowRestoreIcon [UI]
+ TitlePane.restoreIcon [lazy] 26,26 com.formdev.flatlaf.icons.FlatWindowRestoreIcon [UI]
+ TitlePane.small.buttonInsets 1,1,1,1 javax.swing.plaf.InsetsUIResource [UI]
- TitlePane.small.buttonSize 30,20 javax.swing.plaf.DimensionUIResource [UI]
+ TitlePane.small.buttonSize 20,20 javax.swing.plaf.DimensionUIResource [UI]
- TitlePane.small.buttonSymbolHeight 8
+ TitlePane.small.buttonSymbolHeight 6
+ TitlePane.small.buttonsGap 4
+ TitlePane.small.buttonsMargins 2,2,2,2 javax.swing.plaf.InsetsUIResource [UI]
- TitlePane.small.closeIcon [lazy] 30,20 com.formdev.flatlaf.icons.FlatWindowCloseIcon [UI]
+ TitlePane.small.closeIcon [lazy] 20,20 com.formdev.flatlaf.icons.FlatWindowCloseIcon [UI]
- TitlePane.small.font [active] Segoe UI plain 11 javax.swing.plaf.FontUIResource [UI] - TitlePane.small.font [active] Segoe UI plain 11 javax.swing.plaf.FontUIResource [UI]
+ TitlePane.small.font [active] Liberation Sans plain 14 javax.swing.plaf.FontUIResource [UI] + TitlePane.small.font [active] Liberation Sans plain 14 javax.swing.plaf.FontUIResource [UI]
- TitlePane.small.iconifyIcon [lazy] 30,20 com.formdev.flatlaf.icons.FlatWindowIconifyIcon [UI]
+ TitlePane.small.iconifyIcon [lazy] 20,20 com.formdev.flatlaf.icons.FlatWindowIconifyIcon [UI]
- TitlePane.small.maximizeIcon [lazy] 30,20 com.formdev.flatlaf.icons.FlatWindowMaximizeIcon [UI]
+ TitlePane.small.maximizeIcon [lazy] 20,20 com.formdev.flatlaf.icons.FlatWindowMaximizeIcon [UI]
- TitlePane.small.restoreIcon [lazy] 30,20 com.formdev.flatlaf.icons.FlatWindowRestoreIcon [UI]
+ TitlePane.small.restoreIcon [lazy] 20,20 com.formdev.flatlaf.icons.FlatWindowRestoreIcon [UI]
- defaultFont Segoe UI plain 12 javax.swing.plaf.FontUIResource [UI] - defaultFont Segoe UI plain 12 javax.swing.plaf.FontUIResource [UI]
+ defaultFont Liberation Sans plain 15 javax.swing.plaf.FontUIResource [UI] + defaultFont Liberation Sans plain 15 javax.swing.plaf.FontUIResource [UI]

View File

@@ -68,15 +68,6 @@
- ScrollBar.hoverThumbWithTrack false - ScrollBar.hoverThumbWithTrack false
+ ScrollBar.hoverThumbWithTrack true + 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 ---- #---- TaskPane ----

View File

@@ -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.buttonDisabledArrowColor #777777 HSL 0 0 47 javax.swing.plaf.ColorUIResource [UI]
ScrollBar.foreground #dddddd HSL 0 0 87 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.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.hoverThumbWithTrack false
ScrollBar.hoverTrackColor #484c4f HSL 206 5 30 com.formdev.flatlaf.util.DerivedColor [UI] lighten(4%) 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.maximumThumbSize 100000,100000 javax.swing.plaf.DimensionUIResource [UI]
ScrollBar.minimumButtonSize 12,12 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.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.pressedThumbWithTrack false
ScrollBar.showButtons false ScrollBar.showButtons false
ScrollBar.squareButtons false ScrollBar.squareButtons false
ScrollBar.thumb #565c5f HSL 200 5 35 com.formdev.flatlaf.util.DerivedColor [UI] lighten(10%) ScrollBar.thumb #62696c HSL 198 5 40 com.formdev.flatlaf.util.DerivedColor [UI] lighten(15%)
ScrollBar.thumbArc 0 ScrollBar.thumbArc 999
ScrollBar.thumbDarkShadow #7a7d7f HSL 204 2 49 javax.swing.plaf.ColorUIResource [UI] 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.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.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.track #3e4244 HSL 200 5 25 com.formdev.flatlaf.util.DerivedColor [UI] lighten(1%)
ScrollBar.trackArc 0 ScrollBar.trackArc 0
@@ -1255,12 +1255,17 @@ TipOfTheDay.tipAreaInsets 4,16,4,16 javax.swing.plaf.InsetsUIResource [U
#---- TitlePane ---- #---- TitlePane ----
TitlePane.background #303234 HSL 210 4 20 javax.swing.plaf.ColorUIResource [UI] TitlePane.background #303234 HSL 210 4 20 javax.swing.plaf.ColorUIResource [UI]
TitlePane.buttonHoverBackground #55585c HSL 214 4 35 com.formdev.flatlaf.util.DerivedColor [UI] lighten(15% autoInverse) TitlePane.buttonArc 0
TitlePane.buttonHoverBackground #484c4f HSL 206 5 30 com.formdev.flatlaf.util.DerivedColor [UI] lighten(10% autoInverse)
TitlePane.buttonInsets 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI]
TitlePane.buttonMaximizedHeight 22 TitlePane.buttonMaximizedHeight 22
TitlePane.buttonMinimumWidth 30 TitlePane.buttonMinimumWidth 30
TitlePane.buttonPressedBackground #484c4f HSL 206 5 30 com.formdev.flatlaf.util.DerivedColor [UI] lighten(10% autoInverse) TitlePane.buttonPressedBackground #3f4144 HSL 216 4 26 com.formdev.flatlaf.util.DerivedColor [UI] lighten(6% autoInverse)
TitlePane.buttonSize 44,30 javax.swing.plaf.DimensionUIResource [UI] TitlePane.buttonSize 44,30 javax.swing.plaf.DimensionUIResource [UI]
TitlePane.buttonSymbolHeight 10 TitlePane.buttonSymbolHeight 10
TitlePane.buttonsFillVertically true
TitlePane.buttonsGap 0
TitlePane.buttonsMargins 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI]
TitlePane.centerTitle false TitlePane.centerTitle false
TitlePane.centerTitleIfMenuBarEmbedded true TitlePane.centerTitleIfMenuBarEmbedded true
TitlePane.closeHoverBackground #c42b1c HSL 5 75 44 javax.swing.plaf.ColorUIResource [UI] TitlePane.closeHoverBackground #c42b1c HSL 5 75 44 javax.swing.plaf.ColorUIResource [UI]

View File

@@ -25,18 +25,6 @@
+ ProgressBar.font [active] Liberation Sans plain 13 javax.swing.plaf.FontUIResource [UI] + 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 ----
- TaskPane.font [active] Segoe UI bold 12 javax.swing.plaf.FontUIResource [UI] - TaskPane.font [active] Segoe UI bold 12 javax.swing.plaf.FontUIResource [UI]
@@ -45,8 +33,89 @@
#---- TitlePane ---- #---- TitlePane ----
- TitlePane.buttonArc 0
+ TitlePane.buttonArc 999
+ TitlePane.buttonBackground #f2f2f2 HSL 0 0 95 com.formdev.flatlaf.util.DerivedColor [UI] darken(5% autoInverse)
- TitlePane.buttonHoverBackground #f2f2f2 HSL 0 0 95 com.formdev.flatlaf.util.DerivedColor [UI] darken(5% autoInverse)
+ TitlePane.buttonHoverBackground #e6e6e6 HSL 0 0 90 com.formdev.flatlaf.util.DerivedColor [UI] darken(10% autoInverse)
- TitlePane.buttonInsets 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI]
+ TitlePane.buttonInsets 2,2,2,2 javax.swing.plaf.InsetsUIResource [UI]
- TitlePane.buttonMaximizedHeight 22
+ TitlePane.buttonMaximizedHeight -1
- TitlePane.buttonPressedBackground #f7f7f7 HSL 0 0 97 com.formdev.flatlaf.util.DerivedColor [UI] darken(3% autoInverse)
+ TitlePane.buttonPressedBackground #d9d9d9 HSL 0 0 85 com.formdev.flatlaf.util.DerivedColor [UI] darken(15% autoInverse)
- TitlePane.buttonSize 44,30 javax.swing.plaf.DimensionUIResource [UI]
+ TitlePane.buttonSize 26,26 javax.swing.plaf.DimensionUIResource [UI]
- TitlePane.buttonSymbolHeight 10
+ TitlePane.buttonSymbolHeight 8
- TitlePane.buttonsFillVertically true
+ TitlePane.buttonsFillVertically false
- TitlePane.buttonsGap 0
+ TitlePane.buttonsGap 8
- TitlePane.buttonsMargins 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI]
+ TitlePane.buttonsMargins 4,4,4,4 javax.swing.plaf.InsetsUIResource [UI]
+ TitlePane.closeBackground #f2f2f2 HSL 0 0 95 com.formdev.flatlaf.util.DerivedColor [UI] darken(5% autoInverse)
- TitlePane.closeHoverBackground #c42b1c HSL 5 75 44 javax.swing.plaf.ColorUIResource [UI]
+ TitlePane.closeHoverBackground #e6e6e6 HSL 0 0 90 com.formdev.flatlaf.util.DerivedColor [UI] darken(10% autoInverse)
- TitlePane.closeHoverForeground #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI]
+ TitlePane.closeHoverForeground #000000 HSL 0 0 0 javax.swing.plaf.ColorUIResource [UI]
- TitlePane.closeIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowCloseIcon [UI]
+ TitlePane.closeIcon [lazy] 26,26 com.formdev.flatlaf.icons.FlatWindowCloseIcon [UI]
- TitlePane.closePressedBackground #c42b1ce6 90% HSLA 5 75 44 90 javax.swing.plaf.ColorUIResource [UI]
+ TitlePane.closePressedBackground #d9d9d9 HSL 0 0 85 com.formdev.flatlaf.util.DerivedColor [UI] darken(15% autoInverse)
- TitlePane.closePressedForeground #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI]
+ TitlePane.closePressedForeground #000000 HSL 0 0 0 javax.swing.plaf.ColorUIResource [UI]
- TitlePane.iconifyIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowIconifyIcon [UI]
+ TitlePane.iconifyIcon [lazy] 26,26 com.formdev.flatlaf.icons.FlatWindowIconifyIcon [UI]
- TitlePane.maximizeIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowMaximizeIcon [UI]
+ TitlePane.maximizeIcon [lazy] 26,26 com.formdev.flatlaf.icons.FlatWindowMaximizeIcon [UI]
- TitlePane.restoreIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowRestoreIcon [UI]
+ TitlePane.restoreIcon [lazy] 26,26 com.formdev.flatlaf.icons.FlatWindowRestoreIcon [UI]
+ TitlePane.small.buttonInsets 1,1,1,1 javax.swing.plaf.InsetsUIResource [UI]
- TitlePane.small.buttonSize 30,20 javax.swing.plaf.DimensionUIResource [UI]
+ TitlePane.small.buttonSize 20,20 javax.swing.plaf.DimensionUIResource [UI]
- TitlePane.small.buttonSymbolHeight 8
+ TitlePane.small.buttonSymbolHeight 6
+ TitlePane.small.buttonsGap 4
+ TitlePane.small.buttonsMargins 2,2,2,2 javax.swing.plaf.InsetsUIResource [UI]
- TitlePane.small.closeIcon [lazy] 30,20 com.formdev.flatlaf.icons.FlatWindowCloseIcon [UI]
+ TitlePane.small.closeIcon [lazy] 20,20 com.formdev.flatlaf.icons.FlatWindowCloseIcon [UI]
- TitlePane.small.font [active] Segoe UI plain 11 javax.swing.plaf.FontUIResource [UI] - TitlePane.small.font [active] Segoe UI plain 11 javax.swing.plaf.FontUIResource [UI]
+ TitlePane.small.font [active] Liberation Sans plain 14 javax.swing.plaf.FontUIResource [UI] + TitlePane.small.font [active] Liberation Sans plain 14 javax.swing.plaf.FontUIResource [UI]
- TitlePane.small.iconifyIcon [lazy] 30,20 com.formdev.flatlaf.icons.FlatWindowIconifyIcon [UI]
+ TitlePane.small.iconifyIcon [lazy] 20,20 com.formdev.flatlaf.icons.FlatWindowIconifyIcon [UI]
- TitlePane.small.maximizeIcon [lazy] 30,20 com.formdev.flatlaf.icons.FlatWindowMaximizeIcon [UI]
+ TitlePane.small.maximizeIcon [lazy] 20,20 com.formdev.flatlaf.icons.FlatWindowMaximizeIcon [UI]
- TitlePane.small.restoreIcon [lazy] 30,20 com.formdev.flatlaf.icons.FlatWindowRestoreIcon [UI]
+ TitlePane.small.restoreIcon [lazy] 20,20 com.formdev.flatlaf.icons.FlatWindowRestoreIcon [UI]
- defaultFont Segoe UI plain 12 javax.swing.plaf.FontUIResource [UI] - defaultFont Segoe UI plain 12 javax.swing.plaf.FontUIResource [UI]
+ defaultFont Liberation Sans plain 15 javax.swing.plaf.FontUIResource [UI] + defaultFont Liberation Sans plain 15 javax.swing.plaf.FontUIResource [UI]

View File

@@ -68,15 +68,6 @@
- ScrollBar.hoverThumbWithTrack false - ScrollBar.hoverThumbWithTrack false
+ ScrollBar.hoverThumbWithTrack true + 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 ---- #---- TaskPane ----

View File

@@ -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.buttonDisabledArrowColor #a6a6a6 HSL 0 0 65 javax.swing.plaf.ColorUIResource [UI]
ScrollBar.foreground #000000 HSL 0 0 0 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.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.hoverThumbWithTrack false
ScrollBar.hoverTrackColor #ededed HSL 0 0 93 com.formdev.flatlaf.util.DerivedColor [UI] darken(3%) 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.maximumThumbSize 100000,100000 javax.swing.plaf.DimensionUIResource [UI]
ScrollBar.minimumButtonSize 12,12 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.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.pressedThumbWithTrack false
ScrollBar.showButtons false ScrollBar.showButtons false
ScrollBar.squareButtons false ScrollBar.squareButtons false
ScrollBar.thumb #dcdcdc HSL 0 0 86 com.formdev.flatlaf.util.DerivedColor [UI] darken(10%) ScrollBar.thumb #cfcfcf HSL 0 0 81 com.formdev.flatlaf.util.DerivedColor [UI] darken(15%)
ScrollBar.thumbArc 0 ScrollBar.thumbArc 999
ScrollBar.thumbDarkShadow #9c9c9c HSL 0 0 61 javax.swing.plaf.ColorUIResource [UI] 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.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.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.track #f5f5f5 HSL 0 0 96 com.formdev.flatlaf.util.DerivedColor [UI] lighten(1%)
ScrollBar.trackArc 0 ScrollBar.trackArc 0
@@ -1260,12 +1260,17 @@ TipOfTheDay.tipAreaInsets 4,16,4,16 javax.swing.plaf.InsetsUIResource [U
#---- TitlePane ---- #---- TitlePane ----
TitlePane.background #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI] TitlePane.background #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI]
TitlePane.buttonHoverBackground #e6e6e6 HSL 0 0 90 com.formdev.flatlaf.util.DerivedColor [UI] darken(10% autoInverse) TitlePane.buttonArc 0
TitlePane.buttonHoverBackground #f2f2f2 HSL 0 0 95 com.formdev.flatlaf.util.DerivedColor [UI] darken(5% autoInverse)
TitlePane.buttonInsets 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI]
TitlePane.buttonMaximizedHeight 22 TitlePane.buttonMaximizedHeight 22
TitlePane.buttonMinimumWidth 30 TitlePane.buttonMinimumWidth 30
TitlePane.buttonPressedBackground #ebebeb HSL 0 0 92 com.formdev.flatlaf.util.DerivedColor [UI] darken(8% autoInverse) TitlePane.buttonPressedBackground #f7f7f7 HSL 0 0 97 com.formdev.flatlaf.util.DerivedColor [UI] darken(3% autoInverse)
TitlePane.buttonSize 44,30 javax.swing.plaf.DimensionUIResource [UI] TitlePane.buttonSize 44,30 javax.swing.plaf.DimensionUIResource [UI]
TitlePane.buttonSymbolHeight 10 TitlePane.buttonSymbolHeight 10
TitlePane.buttonsFillVertically true
TitlePane.buttonsGap 0
TitlePane.buttonsMargins 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI]
TitlePane.centerTitle false TitlePane.centerTitle false
TitlePane.centerTitleIfMenuBarEmbedded true TitlePane.centerTitleIfMenuBarEmbedded true
TitlePane.closeHoverBackground #c42b1c HSL 5 75 44 javax.swing.plaf.ColorUIResource [UI] TitlePane.closeHoverBackground #c42b1c HSL 5 75 44 javax.swing.plaf.ColorUIResource [UI]

View File

@@ -1265,12 +1265,17 @@ TipOfTheDay.tipAreaInsets 4,16,4,16 javax.swing.plaf.InsetsUIResource [U
#---- TitlePane ---- #---- TitlePane ----
TitlePane.background #323232 HSL 0 0 20 javax.swing.plaf.ColorUIResource [UI] TitlePane.background #323232 HSL 0 0 20 javax.swing.plaf.ColorUIResource [UI]
TitlePane.buttonHoverBackground #585858 HSL 0 0 35 com.formdev.flatlaf.util.DerivedColor [UI] lighten(15% autoInverse) TitlePane.buttonArc 0
TitlePane.buttonHoverBackground #4c4c4c HSL 0 0 30 com.formdev.flatlaf.util.DerivedColor [UI] lighten(10% autoInverse)
TitlePane.buttonInsets 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI]
TitlePane.buttonMaximizedHeight 22 TitlePane.buttonMaximizedHeight 22
TitlePane.buttonMinimumWidth 30 TitlePane.buttonMinimumWidth 30
TitlePane.buttonPressedBackground #4c4c4c HSL 0 0 30 com.formdev.flatlaf.util.DerivedColor [UI] lighten(10% autoInverse) TitlePane.buttonPressedBackground #414141 HSL 0 0 25 com.formdev.flatlaf.util.DerivedColor [UI] lighten(6% autoInverse)
TitlePane.buttonSize 44,30 javax.swing.plaf.DimensionUIResource [UI] TitlePane.buttonSize 44,30 javax.swing.plaf.DimensionUIResource [UI]
TitlePane.buttonSymbolHeight 10 TitlePane.buttonSymbolHeight 10
TitlePane.buttonsFillVertically true
TitlePane.buttonsGap 0
TitlePane.buttonsMargins 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI]
TitlePane.centerTitle false TitlePane.centerTitle false
TitlePane.centerTitleIfMenuBarEmbedded true TitlePane.centerTitleIfMenuBarEmbedded true
TitlePane.closeHoverBackground #c42b1c HSL 5 75 44 javax.swing.plaf.ColorUIResource [UI] TitlePane.closeHoverBackground #c42b1c HSL 5 75 44 javax.swing.plaf.ColorUIResource [UI]

View File

@@ -1269,12 +1269,17 @@ TipOfTheDay.tipAreaInsets 4,16,4,16 javax.swing.plaf.InsetsUIResource [U
#---- TitlePane ---- #---- TitlePane ----
TitlePane.background #ececec HSL 0 0 93 javax.swing.plaf.ColorUIResource [UI] TitlePane.background #ececec HSL 0 0 93 javax.swing.plaf.ColorUIResource [UI]
TitlePane.buttonHoverBackground #d3d3d3 HSL 0 0 83 com.formdev.flatlaf.util.DerivedColor [UI] darken(10% autoInverse) TitlePane.buttonArc 0
TitlePane.buttonHoverBackground #dfdfdf HSL 0 0 87 com.formdev.flatlaf.util.DerivedColor [UI] darken(5% autoInverse)
TitlePane.buttonInsets 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI]
TitlePane.buttonMaximizedHeight 22 TitlePane.buttonMaximizedHeight 22
TitlePane.buttonMinimumWidth 30 TitlePane.buttonMinimumWidth 30
TitlePane.buttonPressedBackground #d8d8d8 HSL 0 0 85 com.formdev.flatlaf.util.DerivedColor [UI] darken(8% autoInverse) TitlePane.buttonPressedBackground #e4e4e4 HSL 0 0 89 com.formdev.flatlaf.util.DerivedColor [UI] darken(3% autoInverse)
TitlePane.buttonSize 44,30 javax.swing.plaf.DimensionUIResource [UI] TitlePane.buttonSize 44,30 javax.swing.plaf.DimensionUIResource [UI]
TitlePane.buttonSymbolHeight 10 TitlePane.buttonSymbolHeight 10
TitlePane.buttonsFillVertically true
TitlePane.buttonsGap 0
TitlePane.buttonsMargins 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI]
TitlePane.centerTitle false TitlePane.centerTitle false
TitlePane.centerTitleIfMenuBarEmbedded true TitlePane.centerTitleIfMenuBarEmbedded true
TitlePane.closeHoverBackground #c42b1c HSL 5 75 44 javax.swing.plaf.ColorUIResource [UI] TitlePane.closeHoverBackground #c42b1c HSL 5 75 44 javax.swing.plaf.ColorUIResource [UI]

View File

@@ -919,15 +919,15 @@ ScrollBar.hoverThumbWithTrack false
ScrollBar.hoverTrackColor #00ff00 HSL 120 100 50 javax.swing.plaf.ColorUIResource [UI] ScrollBar.hoverTrackColor #00ff00 HSL 120 100 50 javax.swing.plaf.ColorUIResource [UI]
ScrollBar.maximumThumbSize 100000,100000 javax.swing.plaf.DimensionUIResource [UI] ScrollBar.maximumThumbSize 100000,100000 javax.swing.plaf.DimensionUIResource [UI]
ScrollBar.minimumButtonSize 12,12 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.pressedThumbWithTrack false
ScrollBar.showButtons false ScrollBar.showButtons false
ScrollBar.squareButtons false ScrollBar.squareButtons false
ScrollBar.thumb #73737333 20% HSLA 0 0 45 20 javax.swing.plaf.ColorUIResource [UI] 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.thumbDarkShadow #696969 HSL 0 0 41 javax.swing.plaf.ColorUIResource [UI]
ScrollBar.thumbHighlight #ffffff HSL 0 0 100 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.thumbShadow #a0a0a0 HSL 0 0 63 javax.swing.plaf.ColorUIResource [UI]
ScrollBar.track #88ff88 HSL 120 100 77 javax.swing.plaf.ColorUIResource [UI] ScrollBar.track #88ff88 HSL 120 100 77 javax.swing.plaf.ColorUIResource [UI]
ScrollBar.trackArc 0 ScrollBar.trackArc 0
@@ -1302,17 +1302,34 @@ TipOfTheDay.tipAreaInsets 4,16,4,16 javax.swing.plaf.InsetsUIResource [U
TitlePane.background #00ff00 HSL 120 100 50 javax.swing.plaf.ColorUIResource [UI] TitlePane.background #00ff00 HSL 120 100 50 javax.swing.plaf.ColorUIResource [UI]
TitlePane.borderColor #ff0000 HSL 0 100 50 javax.swing.plaf.ColorUIResource [UI] TitlePane.borderColor #ff0000 HSL 0 100 50 javax.swing.plaf.ColorUIResource [UI]
TitlePane.buttonArc 0
TitlePane.buttonBackground #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI]
TitlePane.buttonForeground #000000 HSL 0 0 0 javax.swing.plaf.ColorUIResource [UI]
TitlePane.buttonHoverBackground #bbbbbb HSL 0 0 73 javax.swing.plaf.ColorUIResource [UI]
TitlePane.buttonHoverForeground #00ff00 HSL 120 100 50 javax.swing.plaf.ColorUIResource [UI]
TitlePane.buttonInactiveBackground #dddddd HSL 0 0 87 javax.swing.plaf.ColorUIResource [UI]
TitlePane.buttonInactiveForeground #0000ff HSL 240 100 50 javax.swing.plaf.ColorUIResource [UI]
TitlePane.buttonInsets 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI]
TitlePane.buttonMaximizedHeight 22 TitlePane.buttonMaximizedHeight 22
TitlePane.buttonMinimumWidth 30 TitlePane.buttonMinimumWidth 30
TitlePane.buttonPressedBackground #999999 HSL 0 0 60 javax.swing.plaf.ColorUIResource [UI]
TitlePane.buttonPressedForeground #ff0000 HSL 0 100 50 javax.swing.plaf.ColorUIResource [UI]
TitlePane.buttonSize 44,30 javax.swing.plaf.DimensionUIResource [UI] TitlePane.buttonSize 44,30 javax.swing.plaf.DimensionUIResource [UI]
TitlePane.buttonSymbolHeight 10 TitlePane.buttonSymbolHeight 10
TitlePane.buttonsFillVertically true
TitlePane.buttonsGap 0
TitlePane.buttonsMargins 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI]
TitlePane.centerTitle false TitlePane.centerTitle false
TitlePane.centerTitleIfMenuBarEmbedded true TitlePane.centerTitleIfMenuBarEmbedded true
TitlePane.closeHoverBackground #c42b1c HSL 5 75 44 javax.swing.plaf.ColorUIResource [UI] TitlePane.closeBackground #ff0000 HSL 0 100 50 javax.swing.plaf.ColorUIResource [UI]
TitlePane.closeHoverForeground #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI] TitlePane.closeForeground #000000 HSL 0 0 0 javax.swing.plaf.ColorUIResource [UI]
TitlePane.closeHoverBackground #bb0000 HSL 0 100 37 javax.swing.plaf.ColorUIResource [UI]
TitlePane.closeHoverForeground #ff00ff HSL 300 100 50 javax.swing.plaf.ColorUIResource [UI]
TitlePane.closeIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowCloseIcon [UI] TitlePane.closeIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowCloseIcon [UI]
TitlePane.closePressedBackground #c42b1ce6 90% HSLA 5 75 44 90 javax.swing.plaf.ColorUIResource [UI] TitlePane.closeInactiveBackground #dd0000 HSL 0 100 43 javax.swing.plaf.ColorUIResource [UI]
TitlePane.closePressedForeground #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI] TitlePane.closeInactiveForeground #00ffff HSL 180 100 50 javax.swing.plaf.ColorUIResource [UI]
TitlePane.closePressedBackground #990000 HSL 0 100 30 javax.swing.plaf.ColorUIResource [UI]
TitlePane.closePressedForeground #00ff00 HSL 120 100 50 javax.swing.plaf.ColorUIResource [UI]
TitlePane.font [active] $defaultFont [UI] TitlePane.font [active] $defaultFont [UI]
TitlePane.foreground #0000ff HSL 240 100 50 javax.swing.plaf.ColorUIResource [UI] TitlePane.foreground #0000ff HSL 240 100 50 javax.swing.plaf.ColorUIResource [UI]
TitlePane.icon [lazy] 16,16 sun.swing.ImageIconUIResource [UI] (sun.awt.image.ToolkitImage) TitlePane.icon [lazy] 16,16 sun.swing.ImageIconUIResource [UI] (sun.awt.image.ToolkitImage)
@@ -1714,6 +1731,24 @@ windowText #ff0000 HSL 0 100 50 javax.swing.plaf.Colo
#-- activeTitleForeground -- #-- activeTitleForeground --
InternalFrame.activeTitleForeground #ffaaaa #880000 5.7 !! InternalFrame.activeTitleForeground #ffaaaa #880000 5.7 !!
#-- buttonForeground --
TitlePane.buttonForeground #000000 #ffffff 21.0
#-- buttonHoverForeground --
TitlePane.buttonHoverForeground #00ff00 #bbbbbb 1.4 !!!!!!
#-- buttonInactiveForeground --
TitlePane.buttonInactiveForeground #0000ff #dddddd 6.3 !
#-- buttonPressedForeground --
TitlePane.buttonPressedForeground #ff0000 #999999 1.4 !!!!!!
#-- closeForeground --
TitlePane.closeForeground #000000 #ff0000 5.3 !!
#-- closeInactiveForeground --
TitlePane.closeInactiveForeground #00ffff #dd0000 4.1 !!!
#-- disabledForeground -- #-- disabledForeground --
ComboBox.disabledForeground #000088 #e0e0e0 11.7 ComboBox.disabledForeground #000088 #e0e0e0 11.7
Label.disabledForeground #000088 #ccffcc 13.8 Label.disabledForeground #000088 #ccffcc 13.8

View File

@@ -24,13 +24,8 @@ import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent; import java.awt.event.ComponentEvent;
import java.awt.event.WindowAdapter; import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent; import java.awt.event.WindowEvent;
import javax.swing.JButton; import java.util.function.Supplier;
import javax.swing.JComponent; import javax.swing.*;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.plaf.metal.MetalLookAndFeel; import javax.swing.plaf.metal.MetalLookAndFeel;
import javax.swing.plaf.nimbus.NimbusLookAndFeel; import javax.swing.plaf.nimbus.NimbusLookAndFeel;
import com.formdev.flatlaf.FlatDarculaLaf; import com.formdev.flatlaf.FlatDarculaLaf;
@@ -59,11 +54,18 @@ public class FlatSingleComponentTest
private final JLabel infoLabel; private final JLabel infoLabel;
private JComponent createSingleComponent() { protected JComponent createSingleComponent() {
return new JButton( "hello" ); return new JButton( "hello" );
} }
public static void main( String[] args ) { public static void main( String[] args ) {
EventQueue.invokeLater( () -> {
launch( FlatSingleComponentTest::new, args );
} );
}
@SuppressWarnings( "ReturnValueIgnored" ) // Error Prone
protected static void launch( Supplier<FlatSingleComponentTest> factory, String[] args ) {
DemoPrefs.init( PREFS_ROOT_PATH ); DemoPrefs.init( PREFS_ROOT_PATH );
DemoPrefs.initSystemScale(); DemoPrefs.initSystemScale();
@@ -88,10 +90,10 @@ public class FlatSingleComponentTest
DemoPrefs.setupLaf( args ); DemoPrefs.setupLaf( args );
// create and show frame // create and show frame
new FlatSingleComponentTest(); factory.get();
} }
private FlatSingleComponentTest() { protected FlatSingleComponentTest() {
super( "FlatSingleComponentTest" ); super( "FlatSingleComponentTest" );
setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );

View File

@@ -18,7 +18,9 @@ package com.formdev.flatlaf.testing;
import java.awt.Color; import java.awt.Color;
import java.awt.Component; import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.FocusTraversalPolicy;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.Insets; import java.awt.Insets;
import java.util.function.Supplier; import java.util.function.Supplier;
@@ -47,6 +49,12 @@ public class FlatTextComponentsTest
FlatTextComponentsTest() { FlatTextComponentsTest() {
initComponents(); initComponents();
updatePreferredSizes(); updatePreferredSizes();
// exclude from tab focus traversal
controlPanel.setFocusTraversalPolicyProvider( true );
controlPanel.setFocusTraversalPolicy( new NotFocusableTraversalPolicy() );
placeholderPanel.setFocusTraversalPolicyProvider( true );
placeholderPanel.setFocusTraversalPolicy( new NotFocusableTraversalPolicy() );
} }
@Override @Override
@@ -196,7 +204,7 @@ public class FlatTextComponentsTest
JLabel formattedTextFieldLabel = new JLabel(); JLabel formattedTextFieldLabel = new JLabel();
JFormattedTextField formattedTextField1 = new JFormattedTextField(); JFormattedTextField formattedTextField1 = new JFormattedTextField();
JFormattedTextField formattedTextField3 = new JFormattedTextField(); JFormattedTextField formattedTextField3 = new JFormattedTextField();
JPanel panel1 = new JPanel(); controlPanel = new JPanel();
editableCheckBox = new JCheckBox(); editableCheckBox = new JCheckBox();
JButton button1 = new JButton(); JButton button1 = new JButton();
JLabel leftPaddingLabel = new JLabel(); JLabel leftPaddingLabel = new JLabel();
@@ -215,7 +223,7 @@ public class FlatTextComponentsTest
trailingComponentVisibleCheckBox = new JCheckBox(); trailingComponentVisibleCheckBox = new JCheckBox();
showClearButtonCheckBox = new JCheckBox(); showClearButtonCheckBox = new JCheckBox();
showRevealButtonCheckBox = new JCheckBox(); showRevealButtonCheckBox = new JCheckBox();
JPanel panel2 = new JPanel(); placeholderPanel = new JPanel();
JLabel label7 = new JLabel(); JLabel label7 = new JLabel();
FlatTextField flatTextField1 = new FlatTextField(); FlatTextField flatTextField1 = new FlatTextField();
JLabel label8 = new JLabel(); JLabel label8 = new JLabel();
@@ -351,11 +359,11 @@ public class FlatTextComponentsTest
formattedTextField3.putClientProperty(FlatClientProperties.PLACEHOLDER_TEXT, "place"); formattedTextField3.putClientProperty(FlatClientProperties.PLACEHOLDER_TEXT, "place");
add(formattedTextField3, "cell 2 1,growx"); add(formattedTextField3, "cell 2 1,growx");
//======== panel1 ======== //======== controlPanel ========
{ {
panel1.setBorder(new TitledBorder("Control")); controlPanel.setBorder(new TitledBorder("Control"));
panel1.putClientProperty("FlatLaf.internal.testing.ignore", true); controlPanel.putClientProperty("FlatLaf.internal.testing.ignore", true);
panel1.setLayout(new MigLayout( controlPanel.setLayout(new MigLayout(
"hidemode 3", "hidemode 3",
// columns // columns
"[fill]" + "[fill]" +
@@ -379,94 +387,104 @@ public class FlatTextComponentsTest
//---- editableCheckBox ---- //---- editableCheckBox ----
editableCheckBox.setText("editable"); editableCheckBox.setText("editable");
editableCheckBox.setSelected(true); editableCheckBox.setSelected(true);
editableCheckBox.setFocusable(false);
editableCheckBox.addActionListener(e -> editableChanged()); 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 ----
button1.setText("change text"); button1.setText("change text");
button1.setFocusable(false);
button1.addActionListener(e -> changeText()); 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 ----
leftPaddingLabel.setText("Left padding:"); leftPaddingLabel.setText("Left padding:");
panel1.add(leftPaddingLabel, "cell 0 2"); controlPanel.add(leftPaddingLabel, "cell 0 2");
//---- leftPaddingField ---- //---- leftPaddingField ----
leftPaddingField.addChangeListener(e -> paddingChanged()); leftPaddingField.addChangeListener(e -> paddingChanged());
panel1.add(leftPaddingField, "cell 1 2"); controlPanel.add(leftPaddingField, "cell 1 2");
//---- rightPaddingLabel ---- //---- rightPaddingLabel ----
rightPaddingLabel.setText("Right padding:"); rightPaddingLabel.setText("Right padding:");
panel1.add(rightPaddingLabel, "cell 0 3"); controlPanel.add(rightPaddingLabel, "cell 0 3");
//---- rightPaddingField ---- //---- rightPaddingField ----
rightPaddingField.addChangeListener(e -> paddingChanged()); rightPaddingField.addChangeListener(e -> paddingChanged());
panel1.add(rightPaddingField, "cell 1 3"); controlPanel.add(rightPaddingField, "cell 1 3");
//---- topPaddingLabel ---- //---- topPaddingLabel ----
topPaddingLabel.setText("Top padding:"); topPaddingLabel.setText("Top padding:");
panel1.add(topPaddingLabel, "cell 0 4"); controlPanel.add(topPaddingLabel, "cell 0 4");
//---- topPaddingField ---- //---- topPaddingField ----
topPaddingField.addChangeListener(e -> paddingChanged()); topPaddingField.addChangeListener(e -> paddingChanged());
panel1.add(topPaddingField, "cell 1 4"); controlPanel.add(topPaddingField, "cell 1 4");
//---- bottomPaddingLabel ---- //---- bottomPaddingLabel ----
bottomPaddingLabel.setText("Bottom padding:"); bottomPaddingLabel.setText("Bottom padding:");
panel1.add(bottomPaddingLabel, "cell 0 5"); controlPanel.add(bottomPaddingLabel, "cell 0 5");
//---- bottomPaddingField ---- //---- bottomPaddingField ----
bottomPaddingField.addChangeListener(e -> paddingChanged()); bottomPaddingField.addChangeListener(e -> paddingChanged());
panel1.add(bottomPaddingField, "cell 1 5"); controlPanel.add(bottomPaddingField, "cell 1 5");
//---- leadingIconCheckBox ---- //---- leadingIconCheckBox ----
leadingIconCheckBox.setText("leading icon"); leadingIconCheckBox.setText("leading icon");
leadingIconCheckBox.setFocusable(false);
leadingIconCheckBox.addActionListener(e -> leadingIcon()); 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 ----
trailingIconCheckBox.setText("trailing icon"); trailingIconCheckBox.setText("trailing icon");
trailingIconCheckBox.setFocusable(false);
trailingIconCheckBox.addActionListener(e -> trailingIcon()); 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 ----
leadingComponentCheckBox.setText("leading component"); leadingComponentCheckBox.setText("leading component");
leadingComponentCheckBox.setFocusable(false);
leadingComponentCheckBox.addActionListener(e -> leadingComponent()); 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 ----
trailingComponentCheckBox.setText("trailing component"); trailingComponentCheckBox.setText("trailing component");
trailingComponentCheckBox.setFocusable(false);
trailingComponentCheckBox.addActionListener(e -> trailingComponent()); 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 ----
leadingComponentVisibleCheckBox.setText("leading component visible"); leadingComponentVisibleCheckBox.setText("leading component visible");
leadingComponentVisibleCheckBox.setSelected(true); leadingComponentVisibleCheckBox.setSelected(true);
leadingComponentVisibleCheckBox.setFocusable(false);
leadingComponentVisibleCheckBox.addActionListener(e -> leadingComponentVisible()); 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 ----
trailingComponentVisibleCheckBox.setText("trailing component visible"); trailingComponentVisibleCheckBox.setText("trailing component visible");
trailingComponentVisibleCheckBox.setSelected(true); trailingComponentVisibleCheckBox.setSelected(true);
trailingComponentVisibleCheckBox.setFocusable(false);
trailingComponentVisibleCheckBox.addActionListener(e -> trailingComponentVisible()); 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 ----
showClearButtonCheckBox.setText("clear button"); showClearButtonCheckBox.setText("clear button");
showClearButtonCheckBox.setFocusable(false);
showClearButtonCheckBox.addActionListener(e -> showClearButton()); 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 ----
showRevealButtonCheckBox.setText("password reveal button"); showRevealButtonCheckBox.setText("password reveal button");
showRevealButtonCheckBox.setFocusable(false);
showRevealButtonCheckBox.addActionListener(e -> showRevealButton()); 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")); placeholderPanel.setBorder(new TitledBorder("Placeholder"));
panel2.setLayout(new MigLayout( placeholderPanel.setLayout(new MigLayout(
"hidemode 3", "hidemode 3",
// columns // columns
"[fill]" + "[fill]" +
@@ -480,55 +498,55 @@ public class FlatTextComponentsTest
//---- label7 ---- //---- label7 ----
label7.setText("leading"); label7.setText("leading");
panel2.add(label7, "cell 0 0"); placeholderPanel.add(label7, "cell 0 0");
//---- flatTextField1 ---- //---- flatTextField1 ----
flatTextField1.setHorizontalAlignment(SwingConstants.LEADING); flatTextField1.setHorizontalAlignment(SwingConstants.LEADING);
flatTextField1.setPlaceholderText("text"); flatTextField1.setPlaceholderText("text");
flatTextField1.setColumns(10); flatTextField1.setColumns(10);
panel2.add(flatTextField1, "cell 1 0"); placeholderPanel.add(flatTextField1, "cell 1 0");
//---- label8 ---- //---- label8 ----
label8.setText("left"); label8.setText("left");
panel2.add(label8, "cell 0 1"); placeholderPanel.add(label8, "cell 0 1");
//---- flatTextField2 ---- //---- flatTextField2 ----
flatTextField2.setHorizontalAlignment(SwingConstants.LEFT); flatTextField2.setHorizontalAlignment(SwingConstants.LEFT);
flatTextField2.setPlaceholderText("text"); flatTextField2.setPlaceholderText("text");
flatTextField2.setColumns(10); flatTextField2.setColumns(10);
panel2.add(flatTextField2, "cell 1 1"); placeholderPanel.add(flatTextField2, "cell 1 1");
//---- label9 ---- //---- label9 ----
label9.setText("center"); label9.setText("center");
panel2.add(label9, "cell 0 2"); placeholderPanel.add(label9, "cell 0 2");
//---- flatTextField3 ---- //---- flatTextField3 ----
flatTextField3.setHorizontalAlignment(SwingConstants.CENTER); flatTextField3.setHorizontalAlignment(SwingConstants.CENTER);
flatTextField3.setPlaceholderText("text"); flatTextField3.setPlaceholderText("text");
flatTextField3.setColumns(10); flatTextField3.setColumns(10);
panel2.add(flatTextField3, "cell 1 2"); placeholderPanel.add(flatTextField3, "cell 1 2");
//---- label10 ---- //---- label10 ----
label10.setText("right"); label10.setText("right");
panel2.add(label10, "cell 0 3"); placeholderPanel.add(label10, "cell 0 3");
//---- flatTextField4 ---- //---- flatTextField4 ----
flatTextField4.setHorizontalAlignment(SwingConstants.RIGHT); flatTextField4.setHorizontalAlignment(SwingConstants.RIGHT);
flatTextField4.setPlaceholderText("text"); flatTextField4.setPlaceholderText("text");
flatTextField4.setColumns(10); flatTextField4.setColumns(10);
panel2.add(flatTextField4, "cell 1 3"); placeholderPanel.add(flatTextField4, "cell 1 3");
//---- label11 ---- //---- label11 ----
label11.setText("trailing"); label11.setText("trailing");
panel2.add(label11, "cell 0 4"); placeholderPanel.add(label11, "cell 0 4");
//---- flatTextField5 ---- //---- flatTextField5 ----
flatTextField5.setHorizontalAlignment(SwingConstants.TRAILING); flatTextField5.setHorizontalAlignment(SwingConstants.TRAILING);
flatTextField5.setPlaceholderText("text"); flatTextField5.setPlaceholderText("text");
flatTextField5.setColumns(10); 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 ----
passwordFieldLabel.setText("JPasswordField:"); passwordFieldLabel.setText("JPasswordField:");
@@ -783,6 +801,7 @@ public class FlatTextComponentsTest
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables // JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
private JTextField textField1; private JTextField textField1;
private JPanel controlPanel;
private JCheckBox editableCheckBox; private JCheckBox editableCheckBox;
private JSpinner leftPaddingField; private JSpinner leftPaddingField;
private JSpinner rightPaddingField; private JSpinner rightPaddingField;
@@ -796,6 +815,7 @@ public class FlatTextComponentsTest
private JCheckBox trailingComponentVisibleCheckBox; private JCheckBox trailingComponentVisibleCheckBox;
private JCheckBox showClearButtonCheckBox; private JCheckBox showClearButtonCheckBox;
private JCheckBox showRevealButtonCheckBox; private JCheckBox showRevealButtonCheckBox;
private JPanel placeholderPanel;
private JComboBox<String> comboBox5; private JComboBox<String> comboBox5;
private JSpinner spinner4; private JSpinner spinner4;
private JComboBox<String> comboBox6; private JComboBox<String> comboBox6;
@@ -807,6 +827,18 @@ public class FlatTextComponentsTest
private JEditorPane editorPane; private JEditorPane editorPane;
// JFormDesigner - End of variables declaration //GEN-END:variables // 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 ----------------------------------------------------------- //---- TestIcon -----------------------------------------------------------
private static class TestIcon private static class TestIcon

View File

@@ -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 { new FormModel {
contentType: "form/swing" contentType: "form/swing"
@@ -78,13 +78,17 @@ new FormModel {
"$columnConstraints": "[fill][fill]" "$columnConstraints": "[fill][fill]"
"$rowConstraints": "[][][][][][][]0[][]0[][]0[][][]" "$rowConstraints": "[][][][][][][]0[][]0[][]0[][][]"
} ) { } ) {
name: "panel1" name: "controlPanel"
"border": new javax.swing.border.TitledBorder( "Control" ) "border": new javax.swing.border.TitledBorder( "Control" )
"$client.FlatLaf.internal.testing.ignore": true "$client.FlatLaf.internal.testing.ignore": true
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
add( new FormComponent( "javax.swing.JCheckBox" ) { add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "editableCheckBox" name: "editableCheckBox"
"text": "editable" "text": "editable"
"selected": true "selected": true
"focusable": false
auxiliary() { auxiliary() {
"JavaCodeGenerator.variableLocal": false "JavaCodeGenerator.variableLocal": false
} }
@@ -95,6 +99,7 @@ new FormModel {
add( new FormComponent( "javax.swing.JButton" ) { add( new FormComponent( "javax.swing.JButton" ) {
name: "button1" name: "button1"
"text": "change text" "text": "change text"
"focusable": false
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "changeText", false ) ) addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "changeText", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 1 2 1,alignx left,growx 0" "value": "cell 0 1 2 1,alignx left,growx 0"
@@ -162,6 +167,7 @@ new FormModel {
add( new FormComponent( "javax.swing.JCheckBox" ) { add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "leadingIconCheckBox" name: "leadingIconCheckBox"
"text": "leading icon" "text": "leading icon"
"focusable": false
auxiliary() { auxiliary() {
"JavaCodeGenerator.variableLocal": false "JavaCodeGenerator.variableLocal": false
} }
@@ -172,6 +178,7 @@ new FormModel {
add( new FormComponent( "javax.swing.JCheckBox" ) { add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "trailingIconCheckBox" name: "trailingIconCheckBox"
"text": "trailing icon" "text": "trailing icon"
"focusable": false
auxiliary() { auxiliary() {
"JavaCodeGenerator.variableLocal": false "JavaCodeGenerator.variableLocal": false
} }
@@ -182,6 +189,7 @@ new FormModel {
add( new FormComponent( "javax.swing.JCheckBox" ) { add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "leadingComponentCheckBox" name: "leadingComponentCheckBox"
"text": "leading component" "text": "leading component"
"focusable": false
auxiliary() { auxiliary() {
"JavaCodeGenerator.variableLocal": false "JavaCodeGenerator.variableLocal": false
} }
@@ -192,6 +200,7 @@ new FormModel {
add( new FormComponent( "javax.swing.JCheckBox" ) { add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "trailingComponentCheckBox" name: "trailingComponentCheckBox"
"text": "trailing component" "text": "trailing component"
"focusable": false
auxiliary() { auxiliary() {
"JavaCodeGenerator.variableLocal": false "JavaCodeGenerator.variableLocal": false
} }
@@ -203,6 +212,7 @@ new FormModel {
name: "leadingComponentVisibleCheckBox" name: "leadingComponentVisibleCheckBox"
"text": "leading component visible" "text": "leading component visible"
"selected": true "selected": true
"focusable": false
auxiliary() { auxiliary() {
"JavaCodeGenerator.variableLocal": false "JavaCodeGenerator.variableLocal": false
} }
@@ -214,6 +224,7 @@ new FormModel {
name: "trailingComponentVisibleCheckBox" name: "trailingComponentVisibleCheckBox"
"text": "trailing component visible" "text": "trailing component visible"
"selected": true "selected": true
"focusable": false
auxiliary() { auxiliary() {
"JavaCodeGenerator.variableLocal": false "JavaCodeGenerator.variableLocal": false
} }
@@ -224,6 +235,7 @@ new FormModel {
add( new FormComponent( "javax.swing.JCheckBox" ) { add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "showClearButtonCheckBox" name: "showClearButtonCheckBox"
"text": "clear button" "text": "clear button"
"focusable": false
auxiliary() { auxiliary() {
"JavaCodeGenerator.variableLocal": false "JavaCodeGenerator.variableLocal": false
} }
@@ -234,6 +246,7 @@ new FormModel {
add( new FormComponent( "javax.swing.JCheckBox" ) { add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "showRevealButtonCheckBox" name: "showRevealButtonCheckBox"
"text": "password reveal button" "text": "password reveal button"
"focusable": false
auxiliary() { auxiliary() {
"JavaCodeGenerator.variableLocal": false "JavaCodeGenerator.variableLocal": false
} }
@@ -249,8 +262,11 @@ new FormModel {
"$columnConstraints": "[fill][fill]" "$columnConstraints": "[fill][fill]"
"$rowConstraints": "[][][][][]" "$rowConstraints": "[][][][][]"
} ) { } ) {
name: "panel2" name: "placeholderPanel"
"border": new javax.swing.border.TitledBorder( "Placeholder" ) "border": new javax.swing.border.TitledBorder( "Placeholder" )
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
add( new FormComponent( "javax.swing.JLabel" ) { add( new FormComponent( "javax.swing.JLabel" ) {
name: "label7" name: "label7"
"text": "leading" "text": "leading"
@@ -325,7 +341,7 @@ new FormModel {
"value": "cell 1 4" "value": "cell 1 4"
} ) } )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, 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" ) { add( new FormComponent( "javax.swing.JLabel" ) {
name: "passwordFieldLabel" name: "passwordFieldLabel"

View File

@@ -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<String> comboBox1;
private JComboBox<String> comboBox2;
private JComboBox<String> comboBox3;
private JComboBox<String> comboBox4;
private JComboBox<String> comboBox5;
private JComboBox<String> comboBox6;
private JComboBox<String> 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
}

View File

@@ -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 )
} )
}
}

View File

@@ -106,9 +106,9 @@ public class UIDefaultsDump
dump( FlatMacLightLaf.class.getName(), dir, false ); dump( FlatMacLightLaf.class.getName(), dir, false );
dump( FlatMacDarkLaf.class.getName(), dir, false ); dump( FlatMacDarkLaf.class.getName(), dir, false );
}
dump( FlatTestLaf.class.getName(), dir, false ); dump( FlatTestLaf.class.getName(), dir, false );
}
// dump( MyBasicLookAndFeel.class.getName(), dir, false ); // dump( MyBasicLookAndFeel.class.getName(), dir, false );
// dump( MetalLookAndFeel.class.getName(), dir, false ); // dump( MetalLookAndFeel.class.getName(), dir, false );
@@ -192,8 +192,11 @@ public class UIDefaultsDump
dump( dir, "", lookAndFeel, defaults, key -> !key.contains( "InputMap" ), true ); dump( dir, "", lookAndFeel, defaults, key -> !key.contains( "InputMap" ), true );
if( lookAndFeel.getClass() == FlatLightLaf.class || !(lookAndFeel instanceof FlatLaf) ) { if( lookAndFeel.getClass() == FlatLightLaf.class || !(lookAndFeel instanceof FlatLaf) ) {
dump( dir, "_InputMap", lookAndFeel, defaults, key -> key.contains( "InputMap" ), false ); if( SystemInfo.isWindows || SystemInfo.isMacOS )
dumpActionMaps( dir, "_ActionMap", lookAndFeel, defaults ); dump( dir, "_InputMap", lookAndFeel, defaults, key -> key.contains( "InputMap" ), false );
if( SystemInfo.isWindows )
dumpActionMaps( dir, "_ActionMap", lookAndFeel, defaults );
} }
if( lookAndFeel instanceof IntelliJTheme.ThemeLaf ) { if( lookAndFeel instanceof IntelliJTheme.ThemeLaf ) {

View File

@@ -463,6 +463,24 @@ TitlePane.foreground = #00f
TitlePane.inactiveForeground = #fff TitlePane.inactiveForeground = #fff
TitlePane.borderColor = #f00 TitlePane.borderColor = #f00
TitlePane.buttonBackground = #fff
TitlePane.buttonForeground = #000
TitlePane.buttonInactiveBackground = #ddd
TitlePane.buttonInactiveForeground = #00f
TitlePane.buttonHoverBackground = #bbb
TitlePane.buttonHoverForeground = #0f0
TitlePane.buttonPressedBackground = #999
TitlePane.buttonPressedForeground = #f00
TitlePane.closeBackground = #f00
TitlePane.closeForeground = #000
TitlePane.closeInactiveBackground = #d00
TitlePane.closeInactiveForeground = #0ff
TitlePane.closeHoverBackground = #b00
TitlePane.closeHoverForeground = #f0f
TitlePane.closePressedBackground = #900
TitlePane.closePressedForeground = #0f0
#---- ToggleButton ---- #---- ToggleButton ----

View File

@@ -46,6 +46,9 @@ tasks {
if( JavaVersion.current() >= JavaVersion.VERSION_1_9 ) if( JavaVersion.current() >= JavaVersion.VERSION_1_9 )
attributes( "Multi-Release" to "true" ) 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" ) exclude( "module-info.class" )

View File

@@ -1066,17 +1066,32 @@ TipOfTheDay.icon.socketColor
TipOfTheDay.tipAreaInsets TipOfTheDay.tipAreaInsets
TitlePane.background TitlePane.background
TitlePane.borderColor TitlePane.borderColor
TitlePane.buttonArc
TitlePane.buttonBackground
TitlePane.buttonForeground
TitlePane.buttonHoverBackground TitlePane.buttonHoverBackground
TitlePane.buttonHoverForeground
TitlePane.buttonInactiveBackground
TitlePane.buttonInactiveForeground
TitlePane.buttonInsets
TitlePane.buttonMaximizedHeight TitlePane.buttonMaximizedHeight
TitlePane.buttonMinimumWidth TitlePane.buttonMinimumWidth
TitlePane.buttonPressedBackground TitlePane.buttonPressedBackground
TitlePane.buttonPressedForeground
TitlePane.buttonSize TitlePane.buttonSize
TitlePane.buttonSymbolHeight TitlePane.buttonSymbolHeight
TitlePane.buttonsFillVertically
TitlePane.buttonsGap
TitlePane.buttonsMargins
TitlePane.centerTitle TitlePane.centerTitle
TitlePane.centerTitleIfMenuBarEmbedded TitlePane.centerTitleIfMenuBarEmbedded
TitlePane.closeBackground
TitlePane.closeForeground
TitlePane.closeHoverBackground TitlePane.closeHoverBackground
TitlePane.closeHoverForeground TitlePane.closeHoverForeground
TitlePane.closeIcon TitlePane.closeIcon
TitlePane.closeInactiveBackground
TitlePane.closeInactiveForeground
TitlePane.closePressedBackground TitlePane.closePressedBackground
TitlePane.closePressedForeground TitlePane.closePressedForeground
TitlePane.embeddedForeground TitlePane.embeddedForeground
@@ -1098,17 +1113,32 @@ TitlePane.showIcon
TitlePane.showIconBesideTitle TitlePane.showIconBesideTitle
TitlePane.showIconInDialogs TitlePane.showIconInDialogs
TitlePane.small.background TitlePane.small.background
TitlePane.small.buttonArc
TitlePane.small.buttonBackground
TitlePane.small.buttonForeground
TitlePane.small.buttonHoverBackground TitlePane.small.buttonHoverBackground
TitlePane.small.buttonHoverForeground
TitlePane.small.buttonInactiveBackground
TitlePane.small.buttonInactiveForeground
TitlePane.small.buttonInsets
TitlePane.small.buttonMaximizedHeight TitlePane.small.buttonMaximizedHeight
TitlePane.small.buttonMinimumWidth TitlePane.small.buttonMinimumWidth
TitlePane.small.buttonPressedBackground TitlePane.small.buttonPressedBackground
TitlePane.small.buttonPressedForeground
TitlePane.small.buttonSize TitlePane.small.buttonSize
TitlePane.small.buttonSymbolHeight TitlePane.small.buttonSymbolHeight
TitlePane.small.buttonsFillVertically
TitlePane.small.buttonsGap
TitlePane.small.buttonsMargins
TitlePane.small.centerTitle TitlePane.small.centerTitle
TitlePane.small.centerTitleIfMenuBarEmbedded TitlePane.small.centerTitleIfMenuBarEmbedded
TitlePane.small.closeBackground
TitlePane.small.closeForeground
TitlePane.small.closeHoverBackground TitlePane.small.closeHoverBackground
TitlePane.small.closeHoverForeground TitlePane.small.closeHoverForeground
TitlePane.small.closeIcon TitlePane.small.closeIcon
TitlePane.small.closeInactiveBackground
TitlePane.small.closeInactiveForeground
TitlePane.small.closePressedBackground TitlePane.small.closePressedBackground
TitlePane.small.closePressedForeground TitlePane.small.closePressedForeground
TitlePane.small.embeddedForeground TitlePane.small.embeddedForeground

View File

@@ -14,8 +14,8 @@
# limitations under the License. # limitations under the License.
# #
flatlaf.releaseVersion = 3.5.4 flatlaf.releaseVersion = 3.6.1
flatlaf.developmentVersion = 3.6-SNAPSHOT flatlaf.developmentVersion = 3.7-SNAPSHOT
org.gradle.parallel = true org.gradle.parallel = true
# org.gradle.warning.mode = all # org.gradle.warning.mode = all

View File

@@ -24,7 +24,7 @@ junit = "5.10.2"
sigtest = "org.netbeans.tools:sigtest-maven-plugin:1.7" sigtest = "org.netbeans.tools:sigtest-maven-plugin:1.7"
# flatlaf-extras # flatlaf-extras
jsvg = "com.github.weisj:jsvg:1.4.0" jsvg = "com.github.weisj:jsvg:2.0.0"
# flatlaf-jide-oss # flatlaf-jide-oss
jide-oss = "com.formdev:jide-oss:3.7.15" jide-oss = "com.formdev:jide-oss:3.7.15"
@@ -58,4 +58,5 @@ errorprone = "com.google.errorprone:error_prone_core:2.20.0"
[plugins] [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" } errorprone = { id = "net.ltgt.errorprone", version = "3.1.0" }

Binary file not shown.

View File

@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.1-bin.zip
networkTimeout=10000 networkTimeout=10000
validateDistributionUrl=true validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME

6
gradlew vendored
View File

@@ -114,7 +114,7 @@ case "$( uname )" in #(
NONSTOP* ) nonstop=true ;; NONSTOP* ) nonstop=true ;;
esac esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar CLASSPATH="\\\"\\\""
# Determine the Java command to use to start the JVM. # Determine the Java command to use to start the JVM.
@@ -205,7 +205,7 @@ fi
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Collect all arguments for the java command: # 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. # 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 # * 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. # treated as '${Hostname}' itself on the command line.
@@ -213,7 +213,7 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
set -- \ set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \ "-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \ -classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \ -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
"$@" "$@"
# Stop when "xargs" is not available. # Stop when "xargs" is not available.

4
gradlew.bat vendored
View File

@@ -70,11 +70,11 @@ goto fail
:execute :execute
@rem Setup the command line @rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar set CLASSPATH=
@rem Execute Gradle @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 :end
@rem End local scope for the variables with windows NT shell @rem End local scope for the variables with windows NT shell