mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2026-02-12 15:07:11 -06:00
Compare commits
37 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
36d5685f4c | ||
|
|
ddc8d6e29c | ||
|
|
119b4a922d | ||
|
|
5e4f00f0c8 | ||
|
|
15cbf28a0d | ||
|
|
f8e53c9064 | ||
|
|
b3c9638e47 | ||
|
|
d079741f94 | ||
|
|
c051ad5f72 | ||
|
|
1ed7aeaa45 | ||
|
|
2ac7234c32 | ||
|
|
6f63982054 | ||
|
|
d388158de7 | ||
|
|
e7a766bf8f | ||
|
|
97988e90b4 | ||
|
|
f71dbb2647 | ||
|
|
04ad21b5b6 | ||
|
|
ff722c0b34 | ||
|
|
34b19f00e4 | ||
|
|
286ce15146 | ||
|
|
abfaf86cd5 | ||
|
|
bc4c7b25d3 | ||
|
|
0863e289a1 | ||
|
|
4945378dd3 | ||
|
|
b178450e81 | ||
|
|
e3ffdd3b7c | ||
|
|
5326971287 | ||
|
|
cd34c08dc9 | ||
|
|
edee73e0ea | ||
|
|
54a53fb527 | ||
|
|
62b96fbccd | ||
|
|
42cbb0666d | ||
|
|
1465fbaabc | ||
|
|
5575854e68 | ||
|
|
640f2ba9a2 | ||
|
|
b221fd1894 | ||
|
|
b64ab09b88 |
19
.github/workflows/ci.yml
vendored
19
.github/workflows/ci.yml
vendored
@@ -67,11 +67,10 @@ jobs:
|
|||||||
- 8
|
- 8
|
||||||
- 17 # LTS
|
- 17 # LTS
|
||||||
- 21 # LTS
|
- 21 # LTS
|
||||||
- 23 # latest
|
|
||||||
toolchain: [""]
|
toolchain: [""]
|
||||||
# include:
|
include:
|
||||||
# - java: 21
|
- java: 21
|
||||||
# toolchain: 22 # latest
|
toolchain: 25 # LTS
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
@@ -105,11 +104,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 +130,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 }}
|
||||||
|
|
||||||
|
|||||||
10
.github/workflows/fonts.yml
vendored
10
.github/workflows/fonts.yml
vendored
@@ -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 ) )
|
||||||
|
|||||||
6
.github/workflows/pr-snapshots.yml
vendored
6
.github/workflows/pr-snapshots.yml
vendored
@@ -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 }}
|
||||||
|
|||||||
48
CHANGELOG.md
48
CHANGELOG.md
@@ -1,6 +1,54 @@
|
|||||||
FlatLaf Change Log
|
FlatLaf Change Log
|
||||||
==================
|
==================
|
||||||
|
|
||||||
|
## 3.6.2
|
||||||
|
|
||||||
|
#### New features and improvements
|
||||||
|
|
||||||
|
- If using `FlatLaf.registerCustomDefaultsSource( "com.myapp.themes" )` and
|
||||||
|
named Java modules, it is no longer necessary to add `opens com.myapp.themes;`
|
||||||
|
to `module-info.java`. (issue #1026)
|
||||||
|
- Extras: Made animated theme change (class `FlatAnimatedLafChange`) smoother.
|
||||||
|
|
||||||
|
#### Fixed bugs
|
||||||
|
|
||||||
|
- Tree and List: Fixed painting of rounded drop backgrounds. (issue #1023)
|
||||||
|
- Popup: Showing tooltip in inactive window brought that window to front (made
|
||||||
|
it active) and potentially hid the previously active window. (issue #1037)
|
||||||
|
- Popup: No longer reuse popup windows for menus to avoid immediately closing
|
||||||
|
dialogs on ChromeOS. (issue #1029)
|
||||||
|
- macOS: Fixed window "flashing" when switching from a light to a dark theme (or
|
||||||
|
vice versa). Especially when using animated theme changer (see
|
||||||
|
[FlatLaf Extras](flatlaf-extras)).
|
||||||
|
|
||||||
|
#### Incompatibilities
|
||||||
|
|
||||||
|
- FlatLaf properties files are now loaded using the UTF-8 character encoding
|
||||||
|
instead of ISO 8859-1. In usual properties files you will not notice any
|
||||||
|
difference because they use only ASCII characters, but if you've put localized
|
||||||
|
(non-English) texts (e.g. German umlauts) into your properties files, you need
|
||||||
|
to convert them to UTF-8. Properties files created with the FlatLaf Theme
|
||||||
|
Editor already use UTF-8, including in older versions. (issue #1031)
|
||||||
|
|
||||||
|
|
||||||
|
## 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
|
## 3.6
|
||||||
|
|
||||||
#### New features and improvements
|
#### New features and improvements
|
||||||
|
|||||||
113
README.md
113
README.md
@@ -35,6 +35,8 @@ Sponsors
|
|||||||
|
|
||||||
### Current Sponsors
|
### Current Sponsors
|
||||||
|
|
||||||
|
<a href="https://www.soptim.de/"><img src="https://www.formdev.com/flatlaf/sponsor/soptim.svg" width="200" alt="SOPTIM" title="SOPTIM - your expert in software solutions for the energy industry"></a>
|
||||||
|
|
||||||
<a href="https://exocharts.com/"><img src="https://www.formdev.com/flatlaf/sponsor/Exocharts.png" width="200" alt="Exocharts" title="Exocharts - Professional Grade OrderFlow"></a>
|
<a href="https://exocharts.com/"><img src="https://www.formdev.com/flatlaf/sponsor/Exocharts.png" width="200" alt="Exocharts" title="Exocharts - Professional Grade OrderFlow"></a>
|
||||||
|
|
||||||
<!-- [](https://www.formdev.com/flatlaf/sponsor/) -->
|
<!-- [](https://www.formdev.com/flatlaf/sponsor/) -->
|
||||||
@@ -72,7 +74,7 @@ build script:
|
|||||||
|
|
||||||
Otherwise, download `flatlaf-<version>.jar` here:
|
Otherwise, download `flatlaf-<version>.jar` here:
|
||||||
|
|
||||||
[](https://maven-badges.herokuapp.com/maven-central/com.formdev/flatlaf)
|
[](https://central.sonatype.com/artifact/com.formdev/flatlaf)
|
||||||
|
|
||||||
See also
|
See also
|
||||||
[Native Libraries distribution](https://www.formdev.com/flatlaf/native-libraries/)
|
[Native Libraries distribution](https://www.formdev.com/flatlaf/native-libraries/)
|
||||||
@@ -83,10 +85,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 +186,18 @@ Applications using FlatLaf
|
|||||||
relational data browsing tool
|
relational data browsing tool
|
||||||
-  [MagicPlot](https://magicplot.com/) (**commercial**) -
|
-  [MagicPlot](https://magicplot.com/) (**commercial**) -
|
||||||
Software for nonlinear fitting, plotting and data analysis
|
Software for nonlinear fitting, plotting and data analysis
|
||||||
-  [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)
|
||||||
- 
|
- [Kafka Visualizer](https://github.com/kumait/kafkavisualizer) - Kafka GUI
|
||||||
[Kafka Visualizer](https://github.com/kumait/kafkavisualizer) - Kafka GUI
|
|
||||||
client
|
client
|
||||||
|
- 
|
||||||
|
[RedisFront](https://github.com/dromara/RedisFront/blob/master/README_EN.md) -
|
||||||
|
Cross-platform redis GUI
|
||||||
|
- 
|
||||||
|
[Zettelkasten](https://github.com/Zettelkasten-Team/Zettelkasten) - knowledge
|
||||||
|
management tool
|
||||||
|
-  [QStudio](https://www.timestored.com/qstudio/) - free
|
||||||
|
SQL editor
|
||||||
|
|
||||||
### Security
|
### Security
|
||||||
|
|
||||||
@@ -197,11 +206,9 @@ Applications using FlatLaf
|
|||||||
- 
|
- 
|
||||||
[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
|
||||||
- 
|
- [Ghidra](https://github.com/NationalSecurityAgency/ghidra) - a software
|
||||||
[Ghidra](https://github.com/NationalSecurityAgency/ghidra) - a software
|
|
||||||
reverse engineering (SRE) framework
|
reverse engineering (SRE) framework
|
||||||
-  [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 +220,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/)
|
||||||
- 
|
- [muCommander](https://github.com/mucommander/mucommander) - lightweight
|
||||||
[muCommander](https://github.com/mucommander/mucommander) - lightweight
|
|
||||||
cross-platform file manager
|
cross-platform file manager
|
||||||
-  [Guiffy](https://www.guiffy.com/) (**commercial**) -
|
- [Guiffy](https://www.guiffy.com/) (**commercial**) - advanced cross-platform
|
||||||
advanced cross-platform Diff/Merge
|
Diff/Merge
|
||||||
-  [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 +234,12 @@ Applications using FlatLaf
|
|||||||
systems development platform
|
systems development platform
|
||||||
-  [Consulo](https://github.com/consulo/consulo) - open
|
-  [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
|
||||||
|
-  [EduMIPS64](https://github.com/EduMIPS64/edumips64) -
|
||||||
|
visual MIPS64 CPU simulator
|
||||||
|
-  [Launch4j](https://launch4j.sourceforge.net/) -
|
||||||
|
cross-platform Java executable wrapper
|
||||||
|
|
||||||
### Electrical
|
### Electrical
|
||||||
|
|
||||||
@@ -235,6 +247,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
|
||||||
|
-  [OpenPnP](https://github.com/openpnp/openpnp) - SMT
|
||||||
|
Pick and Place Hardware and Software
|
||||||
|
- 
|
||||||
|
[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 +266,10 @@ Applications using FlatLaf
|
|||||||
|
|
||||||
-  [jAlbum](https://jalbum.net/) (**commercial**) -
|
-  [jAlbum](https://jalbum.net/) (**commercial**) -
|
||||||
creates photo album websites
|
creates photo album websites
|
||||||
-  [MediathekView](https://mediathekview.de/) - search in
|
- [MediathekView](https://mediathekview.de/) - search in media libraries of
|
||||||
media libraries of various German broadcasters
|
various German broadcasters
|
||||||
|
-  [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
|
||||||
@@ -266,19 +285,31 @@ Applications using FlatLaf
|
|||||||
from any webnovel and lightnovel site
|
from any webnovel and lightnovel site
|
||||||
- [lectureStudio](https://www.lecturestudio.org/) - digitize your lectures with
|
- [lectureStudio](https://www.lecturestudio.org/) - digitize your lectures with
|
||||||
ease
|
ease
|
||||||
|
-  [Nortantis](https://jandjheydorn.com/nortantis) -
|
||||||
|
fantasy map generator and editor
|
||||||
|
|
||||||
### Modelling
|
### Modelling / Planning
|
||||||
|
|
||||||
-  [Astah](https://astah.net/) (**commercial**) - create
|
-  [OpenRocket](https://github.com/openrocket/openrocket) -
|
||||||
UML, ER Diagram, Flowchart, Data Flow Diagram, Requirement Diagram, SysML
|
model-rocketry aerodynamics and trajectory simulation software
|
||||||
diagrams and more
|
- 
|
||||||
|
[Warteschlangensimulator](https://github.com/A-Herzog/Warteschlangensimulator) -
|
||||||
|
discrete-event stochastic simulator
|
||||||
|
-  [Gephi](https://github.com/gephi/gephi) - the Open
|
||||||
|
Graph Viz Platform
|
||||||
|
- [Astah](https://astah.net/) (**commercial**) - create UML, ER Diagram,
|
||||||
|
Flowchart, Data Flow Diagram, Requirement Diagram, SysML diagrams and more
|
||||||
- [IGMAS+](https://www.gfz-potsdam.de/igmas) - Interactive Gravity and Magnetic
|
- [IGMAS+](https://www.gfz-potsdam.de/igmas) - Interactive Gravity and Magnetic
|
||||||
Application System
|
Application System
|
||||||
|
-  [StarPlan](https://www.progotec.de/) (**commercial**) -
|
||||||
|
die Stundenplan Software für Bildungseinrichtungen
|
||||||
|
-  [SSPlot](https://github.com/babaissarkar/ssplot) -
|
||||||
|
plotting utility for plotting CSV data
|
||||||
|
|
||||||
### Documents
|
### Documents
|
||||||
|
|
||||||
-  [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 +327,9 @@ Applications using FlatLaf
|
|||||||
|
|
||||||
### Business / Legal
|
### Business / Legal
|
||||||
|
|
||||||
|
-  
|
||||||
|
[Lisheane ERP](https://www.lisheane.ch/) (**commercial**) - backoffice
|
||||||
|
applikation
|
||||||
- 
|
- 
|
||||||
[j-lawyer](https://github.com/jlawyerorg/j-lawyer-org) - Kanzleisoftware
|
[j-lawyer](https://github.com/jlawyerorg/j-lawyer-org) - Kanzleisoftware
|
||||||
-  [Jeyla Studio](https://www.jeylastudio.com/) -
|
-  [Jeyla Studio](https://www.jeylastudio.com/) -
|
||||||
@@ -312,20 +346,20 @@ Applications using FlatLaf
|
|||||||
|
|
||||||
### Messaging
|
### Messaging
|
||||||
|
|
||||||
-  [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
|
||||||
-  [Chatty](https://github.com/chatty/chatty) - Twitch
|
- [Chatty](https://github.com/chatty/chatty) - Twitch Chat Client
|
||||||
Chat Client
|
|
||||||
|
|
||||||
### Gaming
|
### Gaming
|
||||||
|
|
||||||
-  
|
-  [BGBlitz](https://www.bgblitz.com/)
|
||||||
[BGBlitz](https://www.bgblitz.com/) (**commercial**) - professional Backgammon
|
(**commercial**) - professional Backgammon
|
||||||
-  [MCreator](https://github.com/MCreator/MCreator) -
|
-  [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
|
-  [MCreator](https://github.com/MCreator/MCreator) - make
|
||||||
-  [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 +371,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
|
||||||
- 
|
- [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 +380,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
|
||||||
|
-  [Termora](https://github.com/TermoraDev/termora) -
|
||||||
|
Terminal emulator and SSH client
|
||||||
|
|
||||||
### Miscellaneous
|
### Miscellaneous
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#Signature file v4.1
|
#Signature file v4.1
|
||||||
#Version 3.6
|
#Version 3.6.2
|
||||||
|
|
||||||
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"
|
||||||
@@ -297,6 +297,7 @@ CLSS public abstract interface com.formdev.flatlaf.FlatSystemProperties
|
|||||||
fld public final static java.lang.String ANIMATION = "flatlaf.animation"
|
fld public final static java.lang.String ANIMATION = "flatlaf.animation"
|
||||||
fld public final static java.lang.String MENUBAR_EMBEDDED = "flatlaf.menuBarEmbedded"
|
fld public final static java.lang.String MENUBAR_EMBEDDED = "flatlaf.menuBarEmbedded"
|
||||||
fld public final static java.lang.String NATIVE_LIBRARY_PATH = "flatlaf.nativeLibraryPath"
|
fld public final static java.lang.String NATIVE_LIBRARY_PATH = "flatlaf.nativeLibraryPath"
|
||||||
|
fld public final static java.lang.String REUSE_VISIBLE_POPUP_WINDOW = "flatlaf.reuseVisiblePopupWindow"
|
||||||
fld public final static java.lang.String UI_SCALE = "flatlaf.uiScale"
|
fld public final static java.lang.String UI_SCALE = "flatlaf.uiScale"
|
||||||
fld public final static java.lang.String UI_SCALE_ALLOW_SCALE_DOWN = "flatlaf.uiScale.allowScaleDown"
|
fld public final static java.lang.String UI_SCALE_ALLOW_SCALE_DOWN = "flatlaf.uiScale.allowScaleDown"
|
||||||
fld public final static java.lang.String UI_SCALE_ENABLED = "flatlaf.uiScale.enabled"
|
fld public final static java.lang.String UI_SCALE_ENABLED = "flatlaf.uiScale.enabled"
|
||||||
@@ -324,7 +325,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,jsonColors,jsonIcons,jsonUI,namedColors,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
|
||||||
|
|||||||
@@ -911,8 +911,7 @@ public abstract class FlatLaf
|
|||||||
* <p>
|
* <p>
|
||||||
* Invoke this method before setting the look and feel.
|
* Invoke this method before setting the look and feel.
|
||||||
* <p>
|
* <p>
|
||||||
* If using Java modules, the package must be opened in {@code module-info.java}.
|
* If using Java modules, it is not necessary to open the package in {@code module-info.java}.
|
||||||
* Otherwise, use {@link #registerCustomDefaultsSource(URL)}.
|
|
||||||
*
|
*
|
||||||
* @param packageName a package name (e.g. "com.myapp.resources")
|
* @param packageName a package name (e.g. "com.myapp.resources")
|
||||||
*/
|
*/
|
||||||
@@ -959,9 +958,9 @@ public abstract class FlatLaf
|
|||||||
* <p>
|
* <p>
|
||||||
* See {@link #registerCustomDefaultsSource(String)} for details.
|
* See {@link #registerCustomDefaultsSource(String)} for details.
|
||||||
* <p>
|
* <p>
|
||||||
* This method is useful if using Java modules and the package containing the properties files
|
|
||||||
* is not opened in {@code module-info.java}.
|
|
||||||
* E.g. {@code FlatLaf.registerCustomDefaultsSource( MyApp.class.getResource( "/com/myapp/themes/" ) )}.
|
* E.g. {@code FlatLaf.registerCustomDefaultsSource( MyApp.class.getResource( "/com/myapp/themes/" ) )}.
|
||||||
|
* <p>
|
||||||
|
* If using Java modules, it is not necessary to open the package in {@code module-info.java}.
|
||||||
*
|
*
|
||||||
* @param packageUrl a package URL
|
* @param packageUrl a package URL
|
||||||
* @since 2
|
* @since 2
|
||||||
|
|||||||
@@ -20,6 +20,9 @@ import java.io.File;
|
|||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
@@ -62,8 +65,8 @@ public class FlatPropertiesLaf
|
|||||||
throws IOException
|
throws IOException
|
||||||
{
|
{
|
||||||
Properties properties = new Properties();
|
Properties properties = new Properties();
|
||||||
try( InputStream in2 = in ) {
|
try( Reader reader = new InputStreamReader( in, StandardCharsets.UTF_8 )) {
|
||||||
properties.load( in2 );
|
properties.load( reader );
|
||||||
}
|
}
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf;
|
package com.formdev.flatlaf;
|
||||||
|
|
||||||
|
import javax.swing.JPopupMenu;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
import com.formdev.flatlaf.util.UIScale;
|
import com.formdev.flatlaf.util.UIScale;
|
||||||
|
|
||||||
@@ -147,6 +148,25 @@ public interface FlatSystemProperties
|
|||||||
*/
|
*/
|
||||||
String USE_ROUNDED_POPUP_BORDER = "flatlaf.useRoundedPopupBorder";
|
String USE_ROUNDED_POPUP_BORDER = "flatlaf.useRoundedPopupBorder";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Species whether popup windows may be reused without (temporary) hiding them.
|
||||||
|
* E.g. if "moving" a tooltip to follow the mouse pointer, normally it is necessary
|
||||||
|
* to hide the tooltip and show it again at the new location, which causes some
|
||||||
|
* flicker with heavy-weight popup windows that FlatLaf uses on all platforms.
|
||||||
|
* <p>
|
||||||
|
* If {@code true}, hiding popup window is deferred for an event cycle,
|
||||||
|
* which allows reusing still visible popup window and avoids flicker when "moving" the popup.
|
||||||
|
* <p>
|
||||||
|
* Note that {@link JPopupMenu} popup windows (menus and combobox lists) are newer reused.
|
||||||
|
* <p>
|
||||||
|
* <strong>Allowed Values</strong> {@code false} and {@code true}<br>
|
||||||
|
* <strong>Default</strong> {@code true}
|
||||||
|
*
|
||||||
|
* @since 3.6.2
|
||||||
|
*/
|
||||||
|
String REUSE_VISIBLE_POPUP_WINDOW = "flatlaf.reuseVisiblePopupWindow";
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies whether vertical text position is corrected when UI is scaled on HiDPI screens.
|
* Specifies whether vertical text position is corrected when UI is scaled on HiDPI screens.
|
||||||
* <p>
|
* <p>
|
||||||
|
|||||||
@@ -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" );
|
||||||
|
|||||||
@@ -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 )
|
||||||
|
|||||||
@@ -25,12 +25,15 @@ import java.io.FileInputStream;
|
|||||||
import java.io.FileNotFoundException;
|
import java.io.FileNotFoundException;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.Reader;
|
||||||
import java.io.StreamTokenizer;
|
import java.io.StreamTokenizer;
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Executable;
|
import java.lang.reflect.Executable;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
@@ -112,6 +115,14 @@ class UIDefaultsLoader
|
|||||||
Set<String> specialPrefixes = FlatLaf.getUIKeySpecialPrefixes();
|
Set<String> specialPrefixes = FlatLaf.getUIKeySpecialPrefixes();
|
||||||
|
|
||||||
return new Properties() {
|
return new Properties() {
|
||||||
|
@Override
|
||||||
|
public void load( InputStream in ) throws IOException {
|
||||||
|
// use UTF-8 to load properties file
|
||||||
|
try( Reader reader = new InputStreamReader( in, StandardCharsets.UTF_8 )) {
|
||||||
|
super.load( reader );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized Object put( Object k, Object value ) {
|
public synchronized Object put( Object k, Object value ) {
|
||||||
// process key prefixes (while loading properties files)
|
// process key prefixes (while loading properties files)
|
||||||
@@ -198,16 +209,46 @@ class UIDefaultsLoader
|
|||||||
if( classLoader == null )
|
if( classLoader == null )
|
||||||
classLoader = FlatLaf.class.getClassLoader();
|
classLoader = FlatLaf.class.getClassLoader();
|
||||||
|
|
||||||
|
boolean found = false;
|
||||||
for( Class<?> lafClass : lafClasses ) {
|
for( Class<?> lafClass : lafClasses ) {
|
||||||
String propertiesName = packageName + '/' + simpleClassName( lafClass ) + ".properties";
|
String propertiesName = packageName + '/' + simpleClassName( lafClass ) + ".properties";
|
||||||
try( InputStream in = classLoader.getResourceAsStream( propertiesName ) ) {
|
try( InputStream in = classLoader.getResourceAsStream( propertiesName ) ) {
|
||||||
if( in != null )
|
if( in != null ) {
|
||||||
properties.load( in );
|
properties.load( in );
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// fallback for named Java modules
|
||||||
|
if( !found ) {
|
||||||
|
// Get package URL using ClassLoader.getResource(...) because this works
|
||||||
|
// also in named Java modules, even without opening the package in module-info.java.
|
||||||
|
// This extra step is necessary because ClassLoader.getResource("<package>/<file>.properties")
|
||||||
|
// does not work for named Java modules.
|
||||||
|
URL url = classLoader.getResource( packageName );
|
||||||
|
if( url == null )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
String packageUrl = url.toExternalForm();
|
||||||
|
if( !packageUrl.endsWith( "/" ) )
|
||||||
|
packageUrl = packageUrl.concat( "/" );
|
||||||
|
|
||||||
|
for( Class<?> lafClass : lafClasses ) {
|
||||||
|
URL propertiesUrl = new URL( packageUrl + simpleClassName( lafClass ) + ".properties" );
|
||||||
|
|
||||||
|
try( InputStream in = propertiesUrl.openStream() ) {
|
||||||
|
properties.load( in );
|
||||||
|
} catch( FileNotFoundException ex ) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if( source instanceof URL ) {
|
} else if( source instanceof URL ) {
|
||||||
// load from package URL
|
// load from package URL
|
||||||
URL packageUrl = (URL) source;
|
String packageUrl = ((URL)source).toExternalForm();
|
||||||
|
if( !packageUrl.endsWith( "/" ) )
|
||||||
|
packageUrl = packageUrl.concat( "/" );
|
||||||
for( Class<?> lafClass : lafClasses ) {
|
for( Class<?> lafClass : lafClasses ) {
|
||||||
URL propertiesUrl = new URL( packageUrl + simpleClassName( lafClass ) + ".properties" );
|
URL propertiesUrl = new URL( packageUrl + simpleClassName( lafClass ) + ".properties" );
|
||||||
|
|
||||||
@@ -649,22 +690,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 +780,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 +793,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 +1424,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 +1574,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 + "'" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 );
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -302,6 +302,7 @@ public class FlatListUI
|
|||||||
ListModel dataModel, ListSelectionModel selModel, int leadIndex )
|
ListModel dataModel, ListSelectionModel selModel, int leadIndex )
|
||||||
{
|
{
|
||||||
boolean isSelected = selModel.isSelectedIndex( row );
|
boolean isSelected = selModel.isSelectedIndex( row );
|
||||||
|
boolean isDropRow = isDropRow( row );
|
||||||
|
|
||||||
// paint alternating rows
|
// paint alternating rows
|
||||||
if( alternateRowColor != null && row % 2 != 0 &&
|
if( alternateRowColor != null && row % 2 != 0 &&
|
||||||
@@ -335,7 +336,7 @@ public class FlatListUI
|
|||||||
}
|
}
|
||||||
|
|
||||||
// rounded selection or selection insets
|
// rounded selection or selection insets
|
||||||
if( isSelected &&
|
if( (isSelected || isDropRow) &&
|
||||||
!isFileList && // rounded selection is not supported for file list
|
!isFileList && // rounded selection is not supported for file list
|
||||||
(rendererComponent instanceof DefaultListCellRenderer ||
|
(rendererComponent instanceof DefaultListCellRenderer ||
|
||||||
rendererComponent instanceof BasicComboBoxRenderer) &&
|
rendererComponent instanceof BasicComboBoxRenderer) &&
|
||||||
@@ -376,7 +377,22 @@ public class FlatListUI
|
|||||||
this.getColor() == rendererComponent.getBackground() )
|
this.getColor() == rendererComponent.getBackground() )
|
||||||
{
|
{
|
||||||
inPaintSelection = true;
|
inPaintSelection = true;
|
||||||
paintCellSelection( this, row, x, y, width, height );
|
if( isDropRow ) {
|
||||||
|
// for rounded drop background, it is necessary to first
|
||||||
|
// paint selection background because may be not rounded on some corners
|
||||||
|
if( isSelected ) {
|
||||||
|
Color oldColor = getColor();
|
||||||
|
setColor( list.getSelectionBackground() );
|
||||||
|
paintCellSelection( this, row, x, y, width, height );
|
||||||
|
setColor( oldColor );
|
||||||
|
}
|
||||||
|
|
||||||
|
// paint drop background
|
||||||
|
float arc = UIScale.scale( selectionArc / 2f );
|
||||||
|
FlatUIUtils.paintSelection( this, x, y, width, height,
|
||||||
|
UIScale.scale( selectionInsets ), arc, arc, arc, arc, 0 );
|
||||||
|
} else
|
||||||
|
paintCellSelection( this, row, x, y, width, height );
|
||||||
inPaintSelection = false;
|
inPaintSelection = false;
|
||||||
} else
|
} else
|
||||||
super.fillRect( x, y, width, height );
|
super.fillRect( x, y, width, height );
|
||||||
@@ -475,4 +491,15 @@ public class FlatListUI
|
|||||||
FlatListUI ui = (FlatListUI) list.getUI();
|
FlatListUI ui = (FlatListUI) list.getUI();
|
||||||
ui.paintCellSelection( g, row, x, y, width, height );
|
ui.paintCellSelection( g, row, x, y, width, height );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether dropping on a row.
|
||||||
|
* See DefaultListCellRenderer.getListCellRendererComponent().
|
||||||
|
*/
|
||||||
|
private boolean isDropRow( int row ) {
|
||||||
|
JList.DropLocation dropLocation = list.getDropLocation();
|
||||||
|
return dropLocation != null &&
|
||||||
|
!dropLocation.isInsert() &&
|
||||||
|
dropLocation.getIndex() == row;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -547,7 +546,15 @@ public class FlatPopupFactory
|
|||||||
int x = popupWindow.getX();
|
int x = popupWindow.getX();
|
||||||
int y = popupWindow.getY();
|
int y = popupWindow.getY();
|
||||||
|
|
||||||
popup.show();
|
if( !popupWindow.isVisible() )
|
||||||
|
popup.show();
|
||||||
|
else {
|
||||||
|
// if the popup window is already visible (because it is reused),
|
||||||
|
// do not invoke Popup.show() because this would invoke Window.toFront(),
|
||||||
|
// which may have the side effect that an inactive owner window
|
||||||
|
// would be also moved to front and maybe hide previously active window
|
||||||
|
popupWindow.pack();
|
||||||
|
}
|
||||||
|
|
||||||
// restore popup window location if it has changed
|
// restore popup window location if it has changed
|
||||||
// (probably scaled when screens use different scale factors)
|
// (probably scaled when screens use different scale factors)
|
||||||
@@ -619,7 +626,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
|
||||||
@@ -646,8 +676,11 @@ public class FlatPopupFactory
|
|||||||
return;
|
return;
|
||||||
disposed = true;
|
disposed = true;
|
||||||
|
|
||||||
// immediately hide non-heavy weight popups or combobox popups
|
// immediately hide non-heavy weight popups, popup menus and combobox popups
|
||||||
if( !(popupWindow instanceof JWindow) || contents instanceof BasicComboPopup ) {
|
// of if system property is false
|
||||||
|
if( !(popupWindow instanceof JWindow) || contents instanceof JPopupMenu ||
|
||||||
|
!FlatSystemProperties.getBoolean( FlatSystemProperties.REUSE_VISIBLE_POPUP_WINDOW, true ) )
|
||||||
|
{
|
||||||
hideImpl();
|
hideImpl();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -678,6 +711,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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import java.awt.Color;
|
|||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Container;
|
import java.awt.Container;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
|
import java.awt.EventQueue;
|
||||||
import java.awt.Frame;
|
import java.awt.Frame;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
@@ -153,8 +154,28 @@ public class FlatRootPaneUI
|
|||||||
Container parent = c.getParent();
|
Container parent = c.getParent();
|
||||||
if( parent instanceof JFrame || parent instanceof JDialog ) {
|
if( parent instanceof JFrame || parent instanceof JDialog ) {
|
||||||
Color background = parent.getBackground();
|
Color background = parent.getBackground();
|
||||||
if( background == null || background instanceof UIResource )
|
if( background == null || background instanceof UIResource ) {
|
||||||
parent.setBackground( UIManager.getColor( "control" ) );
|
if( SystemInfo.isMacOS ) {
|
||||||
|
// Setting window background on macOS immediately fills the whole window
|
||||||
|
// with that color, and slightly delayed, the Swing repaint manager
|
||||||
|
// repaints the actual window content. This results in some flashing
|
||||||
|
// when switching from a light to a dark theme (or vice versa).
|
||||||
|
// --> delay setting window background and immediately repaint window content
|
||||||
|
Runnable r = () -> {
|
||||||
|
parent.setBackground( UIManager.getColor( "control" ) );
|
||||||
|
c.paintImmediately( 0, 0, c.getWidth(), c.getHeight() );
|
||||||
|
};
|
||||||
|
|
||||||
|
// for class FlatAnimatedLafChange:
|
||||||
|
// if animated Laf change is in progress, set background color when
|
||||||
|
// animation has finished to avoid/reduce flashing
|
||||||
|
if( c.getClientProperty( "FlatLaf.internal.animatedLafChange" ) != null )
|
||||||
|
c.putClientProperty( "FlatLaf.internal.animatedLafChange.runWhenFinished", r );
|
||||||
|
else
|
||||||
|
EventQueue.invokeLater( r );
|
||||||
|
} else
|
||||||
|
parent.setBackground( UIManager.getColor( "control" ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
macClearBackgroundForTranslucentWindow( c );
|
macClearBackgroundForTranslucentWindow( c );
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -914,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
|
||||||
|
|||||||
@@ -577,7 +577,6 @@ public class FlatTreeUI
|
|||||||
boolean isEditing = (editingComponent != null && editingRow == row);
|
boolean isEditing = (editingComponent != null && editingRow == row);
|
||||||
boolean isSelected = tree.isRowSelected( row );
|
boolean isSelected = tree.isRowSelected( row );
|
||||||
boolean isDropRow = isDropRow( row );
|
boolean isDropRow = isDropRow( row );
|
||||||
boolean needsSelectionPainting = (isSelected || isDropRow) && isPaintSelection();
|
|
||||||
|
|
||||||
// paint alternating rows
|
// paint alternating rows
|
||||||
if( alternateRowColor != null && row % 2 != 0 ) {
|
if( alternateRowColor != null && row % 2 != 0 ) {
|
||||||
@@ -608,7 +607,7 @@ public class FlatTreeUI
|
|||||||
if( isSelected && isWideSelection() ) {
|
if( isSelected && isWideSelection() ) {
|
||||||
Color oldColor = g.getColor();
|
Color oldColor = g.getColor();
|
||||||
g.setColor( selectionInactiveBackground );
|
g.setColor( selectionInactiveBackground );
|
||||||
paintWideSelection( g, bounds, row );
|
paintWideSelection( g, bounds, row, false );
|
||||||
g.setColor( oldColor );
|
g.setColor( oldColor );
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@@ -628,7 +627,7 @@ public class FlatTreeUI
|
|||||||
|
|
||||||
// renderer background/foreground
|
// renderer background/foreground
|
||||||
Color oldBackgroundSelectionColor = null;
|
Color oldBackgroundSelectionColor = null;
|
||||||
if( isSelected && !hasFocus && !isDropRow ) {
|
if( isSelected && !hasFocus ) {
|
||||||
// apply inactive selection background/foreground if tree is not focused
|
// apply inactive selection background/foreground if tree is not focused
|
||||||
oldBackgroundSelectionColor = setRendererBackgroundSelectionColor( rendererComponent, selectionInactiveBackground );
|
oldBackgroundSelectionColor = setRendererBackgroundSelectionColor( rendererComponent, selectionInactiveBackground );
|
||||||
setRendererForeground( rendererComponent, selectionInactiveForeground );
|
setRendererForeground( rendererComponent, selectionInactiveForeground );
|
||||||
@@ -655,26 +654,12 @@ public class FlatTreeUI
|
|||||||
}
|
}
|
||||||
|
|
||||||
// paint selection background
|
// paint selection background
|
||||||
if( needsSelectionPainting ) {
|
if( isSelected && isPaintSelection() ) {
|
||||||
// set selection color
|
Color selectionColor = rendererComponent instanceof DefaultTreeCellRenderer
|
||||||
Color oldColor = g.getColor();
|
? ((DefaultTreeCellRenderer)rendererComponent).getBackgroundSelectionColor()
|
||||||
g.setColor( isDropRow
|
: (hasFocus ? selectionBackground : selectionInactiveBackground);
|
||||||
? UIManager.getColor( "Tree.dropCellBackground" )
|
|
||||||
: (rendererComponent instanceof DefaultTreeCellRenderer
|
|
||||||
? ((DefaultTreeCellRenderer)rendererComponent).getBackgroundSelectionColor()
|
|
||||||
: (hasFocus ? selectionBackground : selectionInactiveBackground)) );
|
|
||||||
|
|
||||||
if( isWideSelection() ) {
|
paintRowSelection( g, selectionColor, rendererComponent, bounds, row, false );
|
||||||
// wide selection
|
|
||||||
paintWideSelection( g, bounds, row );
|
|
||||||
} else {
|
|
||||||
// non-wide selection
|
|
||||||
paintCellBackground( g, rendererComponent, bounds, row, true );
|
|
||||||
}
|
|
||||||
|
|
||||||
// this is actually not necessary because renderer should always set color
|
|
||||||
// before painting, but doing anyway to avoid any side effect (in bad renderers)
|
|
||||||
g.setColor( oldColor );
|
|
||||||
} else {
|
} else {
|
||||||
// paint cell background if DefaultTreeCellRenderer.getBackgroundNonSelectionColor() is set
|
// paint cell background if DefaultTreeCellRenderer.getBackgroundNonSelectionColor() is set
|
||||||
if( rendererComponent instanceof DefaultTreeCellRenderer ) {
|
if( rendererComponent instanceof DefaultTreeCellRenderer ) {
|
||||||
@@ -683,12 +668,19 @@ public class FlatTreeUI
|
|||||||
if( bg != null && !bg.equals( defaultCellNonSelectionBackground ) ) {
|
if( bg != null && !bg.equals( defaultCellNonSelectionBackground ) ) {
|
||||||
Color oldColor = g.getColor();
|
Color oldColor = g.getColor();
|
||||||
g.setColor( bg );
|
g.setColor( bg );
|
||||||
paintCellBackground( g, rendererComponent, bounds, row, false );
|
paintCellBackground( g, rendererComponent, bounds, row, false, false );
|
||||||
g.setColor( oldColor );
|
g.setColor( oldColor );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// paint drop background
|
||||||
|
// (this needs to be an extra step for rounded selection)
|
||||||
|
if( isDropRow && isPaintSelection() ) {
|
||||||
|
paintRowSelection( g, UIManager.getColor( "Tree.dropCellBackground" ),
|
||||||
|
rendererComponent, bounds, row, true );
|
||||||
|
}
|
||||||
|
|
||||||
// paint renderer
|
// paint renderer
|
||||||
rendererPane.paintComponent( g, rendererComponent, tree, bounds.x, bounds.y, bounds.width, bounds.height, true );
|
rendererPane.paintComponent( g, rendererComponent, tree, bounds.x, bounds.y, bounds.width, bounds.height, true );
|
||||||
|
|
||||||
@@ -699,6 +691,26 @@ public class FlatTreeUI
|
|||||||
((DefaultTreeCellRenderer)rendererComponent).setBorderSelectionColor( oldBorderSelectionColor );
|
((DefaultTreeCellRenderer)rendererComponent).setBorderSelectionColor( oldBorderSelectionColor );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void paintRowSelection( Graphics g, Color color, Component rendererComponent,
|
||||||
|
Rectangle bounds, int row, boolean paintDropSelection )
|
||||||
|
{
|
||||||
|
// set selection color
|
||||||
|
Color oldColor = g.getColor();
|
||||||
|
g.setColor( color );
|
||||||
|
|
||||||
|
if( isWideSelection() ) {
|
||||||
|
// wide selection
|
||||||
|
paintWideSelection( g, bounds, row, paintDropSelection );
|
||||||
|
} else {
|
||||||
|
// non-wide selection
|
||||||
|
paintCellBackground( g, rendererComponent, bounds, row, true, paintDropSelection );
|
||||||
|
}
|
||||||
|
|
||||||
|
// this is actually not necessary because renderer should always set color
|
||||||
|
// before painting, but doing anyway to avoid any side effect (in bad renderers)
|
||||||
|
g.setColor( oldColor );
|
||||||
|
}
|
||||||
|
|
||||||
private Color setRendererBackgroundSelectionColor( Component rendererComponent, Color color ) {
|
private Color setRendererBackgroundSelectionColor( Component rendererComponent, Color color ) {
|
||||||
Color oldColor = null;
|
Color oldColor = null;
|
||||||
|
|
||||||
@@ -735,11 +747,11 @@ public class FlatTreeUI
|
|||||||
return oldColor;
|
return oldColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void paintWideSelection( Graphics g, Rectangle bounds, int row ) {
|
private void paintWideSelection( Graphics g, Rectangle bounds, int row, boolean paintDropSelection ) {
|
||||||
float arcTop, arcBottom;
|
float arcTop, arcBottom;
|
||||||
arcTop = arcBottom = UIScale.scale( selectionArc / 2f );
|
arcTop = arcBottom = UIScale.scale( selectionArc / 2f );
|
||||||
|
|
||||||
if( useUnitedRoundedSelection() ) {
|
if( useUnitedRoundedSelection() && !paintDropSelection ) {
|
||||||
if( row > 0 && tree.isRowSelected( row - 1 ) )
|
if( row > 0 && tree.isRowSelected( row - 1 ) )
|
||||||
arcTop = 0;
|
arcTop = 0;
|
||||||
if( row < tree.getRowCount() - 1 && tree.isRowSelected( row + 1 ) )
|
if( row < tree.getRowCount() - 1 && tree.isRowSelected( row + 1 ) )
|
||||||
@@ -751,7 +763,7 @@ public class FlatTreeUI
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void paintCellBackground( Graphics g, Component rendererComponent, Rectangle bounds,
|
private void paintCellBackground( Graphics g, Component rendererComponent, Rectangle bounds,
|
||||||
int row, boolean paintSelection )
|
int row, boolean paintSelection, boolean paintDropSelection )
|
||||||
{
|
{
|
||||||
int xOffset = 0;
|
int xOffset = 0;
|
||||||
int imageOffset = 0;
|
int imageOffset = 0;
|
||||||
@@ -769,7 +781,7 @@ public class FlatTreeUI
|
|||||||
float arcTopLeft, arcTopRight, arcBottomLeft, arcBottomRight;
|
float arcTopLeft, arcTopRight, arcBottomLeft, arcBottomRight;
|
||||||
arcTopLeft = arcTopRight = arcBottomLeft = arcBottomRight = UIScale.scale( selectionArc / 2f );
|
arcTopLeft = arcTopRight = arcBottomLeft = arcBottomRight = UIScale.scale( selectionArc / 2f );
|
||||||
|
|
||||||
if( useUnitedRoundedSelection() ) {
|
if( useUnitedRoundedSelection() && !paintDropSelection ) {
|
||||||
if( row > 0 && tree.isRowSelected( row - 1 ) ) {
|
if( row > 0 && tree.isRowSelected( row - 1 ) ) {
|
||||||
Rectangle r = getPathBounds( tree, tree.getPathForRow( row - 1 ) );
|
Rectangle r = getPathBounds( tree, tree.getPathForRow( row - 1 ) );
|
||||||
arcTopLeft = Math.min( arcTopLeft, r.x - bounds.x );
|
arcTopLeft = Math.min( arcTopLeft, r.x - bounds.x );
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
@@ -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 );
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 ----
|
||||||
|
|||||||
@@ -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 ----
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -35,11 +35,16 @@ build script:
|
|||||||
|
|
||||||
Otherwise, download `flatlaf-extras-<version>.jar` here:
|
Otherwise, download `flatlaf-extras-<version>.jar` here:
|
||||||
|
|
||||||
[](https://maven-badges.herokuapp.com/maven-central/com.formdev/flatlaf-extras)
|
[](https://central.sonatype.com/artifact/com.formdev/flatlaf-extras)
|
||||||
|
|
||||||
If SVG classes are used, `jsvg-<version>.jar` is also required:
|
If SVG classes are used, `jsvg-<version>.jar` is also required:
|
||||||
|
|
||||||
[](https://maven-badges.herokuapp.com/maven-central/com.github.weisj/jsvg)
|
[](https://central.sonatype.com/artifact/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
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ import java.util.Map;
|
|||||||
import java.util.WeakHashMap;
|
import java.util.WeakHashMap;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
import javax.swing.JLayeredPane;
|
import javax.swing.JLayeredPane;
|
||||||
|
import javax.swing.JRootPane;
|
||||||
import javax.swing.RootPaneContainer;
|
import javax.swing.RootPaneContainer;
|
||||||
import com.formdev.flatlaf.FlatSystemProperties;
|
import com.formdev.flatlaf.FlatSystemProperties;
|
||||||
import com.formdev.flatlaf.util.Animator;
|
import com.formdev.flatlaf.util.Animator;
|
||||||
@@ -52,15 +53,13 @@ public class FlatAnimatedLafChange
|
|||||||
public static int duration = 160;
|
public static int duration = 160;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The resolution of the animation in milliseconds. Default is 30 ms.
|
* The resolution of the animation in milliseconds. Default is 16 ms.
|
||||||
*/
|
*/
|
||||||
public static int resolution = 30;
|
public static int resolution = 16;
|
||||||
|
|
||||||
private static Animator animator;
|
private static Animator animator;
|
||||||
private static final Map<JLayeredPane, JComponent> oldUIsnapshots = new WeakHashMap<>();
|
private static final Map<JLayeredPane, SnapshotLayer> snapshots = new WeakHashMap<>();
|
||||||
private static final Map<JLayeredPane, JComponent> newUIsnapshots = new WeakHashMap<>();
|
|
||||||
private static float alpha;
|
private static float alpha;
|
||||||
private static boolean inShowSnapshot;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a snapshot of the old UI and shows it on top of the UI.
|
* Create a snapshot of the old UI and shows it on top of the UI.
|
||||||
@@ -77,59 +76,52 @@ public class FlatAnimatedLafChange
|
|||||||
alpha = 1;
|
alpha = 1;
|
||||||
|
|
||||||
// show snapshot of old UI
|
// show snapshot of old UI
|
||||||
showSnapshot( true, oldUIsnapshots );
|
showSnapshot( true );
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void showSnapshot( boolean useAlpha, Map<JLayeredPane, JComponent> map ) {
|
private static void showSnapshot( boolean old ) {
|
||||||
inShowSnapshot = true;
|
|
||||||
|
|
||||||
// create snapshots for all shown windows
|
// create snapshots for all shown windows
|
||||||
Window[] windows = Window.getWindows();
|
Window[] windows = Window.getWindows();
|
||||||
for( Window window : windows ) {
|
for( Window window : windows ) {
|
||||||
if( !(window instanceof RootPaneContainer) || !window.isShowing() )
|
if( !(window instanceof RootPaneContainer) || !window.isShowing() )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
JLayeredPane layeredPane = ((RootPaneContainer)window).getLayeredPane();
|
||||||
|
|
||||||
// create snapshot image
|
// create snapshot image
|
||||||
// (using volatile image to have correct sub-pixel text rendering on Java 9+)
|
// (using volatile image to have correct sub-pixel text rendering on Java 9+)
|
||||||
VolatileImage snapshot = window.createVolatileImage( window.getWidth(), window.getHeight() );
|
VolatileImage snapshotImage = layeredPane.createVolatileImage( layeredPane.getWidth(), layeredPane.getHeight() );
|
||||||
if( snapshot == null )
|
if( snapshotImage == null )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// paint window to snapshot image
|
// paint window to snapshot image
|
||||||
JLayeredPane layeredPane = ((RootPaneContainer)window).getLayeredPane();
|
layeredPane.paint( snapshotImage.getGraphics() );
|
||||||
layeredPane.paint( snapshot.getGraphics() );
|
|
||||||
|
|
||||||
// create snapshot layer, which is added to layered pane and paints
|
if( old ) {
|
||||||
// snapshot with animated alpha
|
// create snapshot layer, which is added to layered pane and paints
|
||||||
JComponent snapshotLayer = new JComponent() {
|
// snapshot with animated alpha
|
||||||
@Override
|
SnapshotLayer snapshotLayer = new SnapshotLayer();
|
||||||
public void paint( Graphics g ) {
|
|
||||||
if( inShowSnapshot || snapshot.contentsLost() )
|
|
||||||
return;
|
|
||||||
|
|
||||||
if( useAlpha )
|
|
||||||
((Graphics2D)g).setComposite( AlphaComposite.getInstance( AlphaComposite.SRC_OVER, alpha ) );
|
|
||||||
g.drawImage( snapshot, 0, 0, null );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void removeNotify() {
|
|
||||||
super.removeNotify();
|
|
||||||
|
|
||||||
// release system resources used by volatile image
|
|
||||||
snapshot.flush();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if( !useAlpha )
|
|
||||||
snapshotLayer.setOpaque( true );
|
snapshotLayer.setOpaque( true );
|
||||||
snapshotLayer.setSize( layeredPane.getSize() );
|
snapshotLayer.setSize( layeredPane.getSize() );
|
||||||
|
snapshotLayer.oldSnapshotImage = snapshotImage;
|
||||||
|
|
||||||
// add image layer to layered pane
|
snapshots.put( layeredPane, snapshotLayer );
|
||||||
layeredPane.add( snapshotLayer, Integer.valueOf( JLayeredPane.DRAG_LAYER + (useAlpha ? 2 : 1) ) );
|
} else {
|
||||||
map.put( layeredPane, snapshotLayer );
|
SnapshotLayer snapshotLayer = snapshots.get( layeredPane );
|
||||||
|
if( snapshotLayer == null ) {
|
||||||
|
snapshotImage.flush();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
snapshotLayer.newSnapshotImage = snapshotImage;
|
||||||
|
|
||||||
|
// add snapshot layer to layered pane
|
||||||
|
layeredPane.add( snapshotLayer, Integer.valueOf( JLayeredPane.DRAG_LAYER + 1 ) );
|
||||||
|
|
||||||
|
// let FlatRootPaneUI know that animated Laf change is in progress
|
||||||
|
layeredPane.getRootPane().putClientProperty( "FlatLaf.internal.animatedLafChange", true );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inShowSnapshot = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -141,23 +133,22 @@ public class FlatAnimatedLafChange
|
|||||||
if( !FlatSystemProperties.getBoolean( "flatlaf.animatedLafChange", true ) )
|
if( !FlatSystemProperties.getBoolean( "flatlaf.animatedLafChange", true ) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if( oldUIsnapshots.isEmpty() )
|
if( snapshots.isEmpty() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// show snapshot of new UI
|
// show snapshot of new UI
|
||||||
showSnapshot( false, newUIsnapshots );
|
showSnapshot( false );
|
||||||
|
|
||||||
// create animator
|
// create animator
|
||||||
animator = new Animator( duration, fraction -> {
|
animator = new Animator( duration, fraction -> {
|
||||||
if( fraction < 0.1 || fraction > 0.9 )
|
|
||||||
return; // ignore initial and last events
|
|
||||||
|
|
||||||
alpha = 1f - fraction;
|
alpha = 1f - fraction;
|
||||||
|
|
||||||
// repaint snapshots
|
// repaint snapshots
|
||||||
for( Map.Entry<JLayeredPane, JComponent> e : oldUIsnapshots.entrySet() ) {
|
for( Map.Entry<JLayeredPane, SnapshotLayer> e : snapshots.entrySet() ) {
|
||||||
if( e.getKey().isShowing() )
|
if( e.getKey().isShowing() ) {
|
||||||
e.getValue().repaint();
|
SnapshotLayer snapshotLayer = e.getValue();
|
||||||
|
snapshotLayer.paintImmediately( 0, 0, snapshotLayer.getWidth(),snapshotLayer.getHeight() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Toolkit.getDefaultToolkit().sync();
|
Toolkit.getDefaultToolkit().sync();
|
||||||
@@ -171,18 +162,27 @@ public class FlatAnimatedLafChange
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static void hideSnapshot() {
|
private static void hideSnapshot() {
|
||||||
hideSnapshot( oldUIsnapshots );
|
|
||||||
hideSnapshot( newUIsnapshots );
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void hideSnapshot( Map<JLayeredPane, JComponent> map ) {
|
|
||||||
// remove snapshots
|
// remove snapshots
|
||||||
for( Map.Entry<JLayeredPane, JComponent> e : map.entrySet() ) {
|
for( Map.Entry<JLayeredPane, SnapshotLayer> e : snapshots.entrySet() ) {
|
||||||
e.getKey().remove( e.getValue() );
|
JLayeredPane layeredPane = e.getKey();
|
||||||
e.getKey().repaint();
|
SnapshotLayer snapshotLayer = e.getValue();
|
||||||
|
|
||||||
|
layeredPane.remove( snapshotLayer );
|
||||||
|
layeredPane.repaint();
|
||||||
|
|
||||||
|
snapshotLayer.flushSnapshotImages();
|
||||||
|
|
||||||
|
// run Runnable that FlatRootPaneUI put into client properties
|
||||||
|
JRootPane rootPane = layeredPane.getRootPane();
|
||||||
|
rootPane.putClientProperty( "FlatLaf.internal.animatedLafChange", null );
|
||||||
|
Runnable r = (Runnable) rootPane.getClientProperty( "FlatLaf.internal.animatedLafChange.runWhenFinished" );
|
||||||
|
if( r != null ) {
|
||||||
|
rootPane.putClientProperty( "FlatLaf.internal.animatedLafChange.runWhenFinished", null );
|
||||||
|
r.run();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
map.clear();
|
snapshots.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -194,4 +194,40 @@ public class FlatAnimatedLafChange
|
|||||||
else
|
else
|
||||||
hideSnapshot();
|
hideSnapshot();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---- class SnapshotLayer ------------------------------------------------
|
||||||
|
|
||||||
|
private static class SnapshotLayer
|
||||||
|
extends JComponent
|
||||||
|
{
|
||||||
|
VolatileImage oldSnapshotImage;
|
||||||
|
VolatileImage newSnapshotImage;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void paint( Graphics g ) {
|
||||||
|
if( oldSnapshotImage.contentsLost() ||
|
||||||
|
newSnapshotImage == null || newSnapshotImage.contentsLost() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// draw new UI snapshot
|
||||||
|
g.drawImage( newSnapshotImage, 0, 0, null );
|
||||||
|
|
||||||
|
// draw old UI snapshot
|
||||||
|
((Graphics2D)g).setComposite( AlphaComposite.getInstance( AlphaComposite.SRC_OVER, alpha ) );
|
||||||
|
g.drawImage( oldSnapshotImage, 0, 0, null );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void removeNotify() {
|
||||||
|
super.removeNotify();
|
||||||
|
flushSnapshotImages();
|
||||||
|
}
|
||||||
|
|
||||||
|
void flushSnapshotImages() {
|
||||||
|
// release system resources used by volatile image
|
||||||
|
oldSnapshotImage.flush();
|
||||||
|
if( newSnapshotImage != null )
|
||||||
|
newSnapshotImage.flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 );
|
||||||
|
|
||||||
|
|||||||
@@ -102,4 +102,4 @@ build script:
|
|||||||
|
|
||||||
Otherwise, download `flatlaf-fonts-inter-<version>.jar` here:
|
Otherwise, download `flatlaf-fonts-inter-<version>.jar` here:
|
||||||
|
|
||||||
[](https://maven-badges.herokuapp.com/maven-central/com.formdev/flatlaf-fonts-inter)
|
[](https://central.sonatype.com/artifact/com.formdev/flatlaf-fonts-inter)
|
||||||
|
|||||||
@@ -83,4 +83,4 @@ build script:
|
|||||||
|
|
||||||
Otherwise, download `flatlaf-fonts-jetbrains-mono-<version>.jar` here:
|
Otherwise, download `flatlaf-fonts-jetbrains-mono-<version>.jar` here:
|
||||||
|
|
||||||
[](https://maven-badges.herokuapp.com/maven-central/com.formdev/flatlaf-fonts-jetbrains-mono)
|
[](https://central.sonatype.com/artifact/com.formdev/flatlaf-fonts-jetbrains-mono)
|
||||||
|
|||||||
@@ -83,4 +83,4 @@ build script:
|
|||||||
|
|
||||||
Otherwise, download `flatlaf-fonts-roboto-mono-<version>.jar` here:
|
Otherwise, download `flatlaf-fonts-roboto-mono-<version>.jar` here:
|
||||||
|
|
||||||
[](https://maven-badges.herokuapp.com/maven-central/com.formdev/flatlaf-fonts-roboto-mono)
|
[](https://central.sonatype.com/artifact/com.formdev/flatlaf-fonts-roboto-mono)
|
||||||
|
|||||||
@@ -99,4 +99,4 @@ build script:
|
|||||||
|
|
||||||
Otherwise, download `flatlaf-fonts-roboto-<version>.jar` here:
|
Otherwise, download `flatlaf-fonts-roboto-<version>.jar` here:
|
||||||
|
|
||||||
[](https://maven-badges.herokuapp.com/maven-central/com.formdev/flatlaf-fonts-roboto)
|
[](https://central.sonatype.com/artifact/com.formdev/flatlaf-fonts-roboto)
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ build script:
|
|||||||
|
|
||||||
Otherwise, download `flatlaf-intellij-themes-<version>.jar` here:
|
Otherwise, download `flatlaf-intellij-themes-<version>.jar` here:
|
||||||
|
|
||||||
[](https://maven-badges.herokuapp.com/maven-central/com.formdev/flatlaf-intellij-themes)
|
[](https://central.sonatype.com/artifact/com.formdev/flatlaf-intellij-themes)
|
||||||
|
|
||||||
|
|
||||||
How to use?
|
How to use?
|
||||||
|
|||||||
@@ -37,10 +37,10 @@ build script:
|
|||||||
|
|
||||||
Otherwise, download `flatlaf-jide-oss-<version>.jar` here:
|
Otherwise, download `flatlaf-jide-oss-<version>.jar` here:
|
||||||
|
|
||||||
[](https://maven-badges.herokuapp.com/maven-central/com.formdev/flatlaf-jide-oss)
|
[](https://central.sonatype.com/artifact/com.formdev/flatlaf-jide-oss)
|
||||||
|
|
||||||
|
|
||||||
JIDE Common Layer library `jide-oss-<version>.jar` (or
|
JIDE Common Layer library `jide-oss-<version>.jar` (or
|
||||||
`jide-common-<version>.jar`) is also required:
|
`jide-common-<version>.jar`) is also required:
|
||||||
|
|
||||||
[](https://maven-badges.herokuapp.com/maven-central/com.formdev/jide-oss)
|
[](https://central.sonatype.com/artifact/com.formdev/jide-oss)
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -38,9 +38,9 @@ build script:
|
|||||||
|
|
||||||
Otherwise, download `flatlaf-swingx-<version>.jar` here:
|
Otherwise, download `flatlaf-swingx-<version>.jar` here:
|
||||||
|
|
||||||
[](https://maven-badges.herokuapp.com/maven-central/com.formdev/flatlaf-swingx)
|
[](https://central.sonatype.com/artifact/com.formdev/flatlaf-swingx)
|
||||||
|
|
||||||
|
|
||||||
SwingX library `swingx-all-<version>.jar` is also required:
|
SwingX library `swingx-all-<version>.jar` is also required:
|
||||||
|
|
||||||
[](https://maven-badges.herokuapp.com/maven-central/org.swinglabs.swingx/swingx-all)
|
[](https://central.sonatype.com/artifact/org.swinglabs.swingx/swingx-all)
|
||||||
|
|||||||
@@ -7,6 +7,8 @@
|
|||||||
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
|
<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES">
|
||||||
<listEntry value="4"/>
|
<listEntry value="4"/>
|
||||||
</listAttribute>
|
</listAttribute>
|
||||||
|
<stringAttribute key="org.eclipse.debug.core.source_locator_id" value="org.eclipse.jdt.launching.sourceLocator.JavaSourceLookupDirector"/>
|
||||||
|
<stringAttribute key="org.eclipse.debug.core.source_locator_memento" value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <sourceLookupDirector> <sourceContainers duplicates="false"> <container memento="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;javaProject name=&quot;flatlaf-core&quot;/&gt;&#13;&#10;" typeId="org.eclipse.jdt.launching.sourceContainer.javaProject"/> <container memento="&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot; standalone=&quot;no&quot;?&gt;&#13;&#10;&lt;javaProject name=&quot;flatlaf-testing-modular-app&quot;/&gt;&#13;&#10;" typeId="org.eclipse.jdt.launching.sourceContainer.javaProject"/> </sourceContainers> </sourceLookupDirector> "/>
|
||||||
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_ATTR_USE_ARGFILE" value="false"/>
|
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_ATTR_USE_ARGFILE" value="false"/>
|
||||||
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_EXCLUDE_TEST_CODE" value="true"/>
|
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_EXCLUDE_TEST_CODE" value="true"/>
|
||||||
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_SHOW_CODEDETAILS_IN_EXCEPTION_MESSAGES" value="true"/>
|
<booleanAttribute key="org.eclipse.jdt.launching.ATTR_SHOW_CODEDETAILS_IN_EXCEPTION_MESSAGES" value="true"/>
|
||||||
@@ -17,11 +19,11 @@
|
|||||||
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="-Ddummy=dummy"/>
|
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="-Ddummy=dummy"/>
|
||||||
<listAttribute key="org.eclipse.jdt.launching.MODULEPATH">
|
<listAttribute key="org.eclipse.jdt.launching.MODULEPATH">
|
||||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry containerPath="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jdk-17/" path="4" type="4"/> "/>
|
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry containerPath="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jdk-17/" path="4" type="4"/> "/>
|
||||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/flatlaf-testing-modular-app/build/libs/flatlaf-testing-modular-app-3.0-SNAPSHOT.jar" path="4" type="2"/> "/>
|
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/flatlaf-testing-modular-app/run/flatlaf-testing-modular-app-999-SNAPSHOT.jar" path="4" type="2"/> "/>
|
||||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/flatlaf-core/build/libs/flatlaf-3.0-SNAPSHOT.jar" path="4" type="2"/> "/>
|
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/flatlaf-testing-modular-app/run/flatlaf-999-SNAPSHOT.jar" path="4" type="2"/> "/>
|
||||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/flatlaf-extras/build/libs/flatlaf-extras-3.0-SNAPSHOT.jar" path="4" type="2"/> "/>
|
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/flatlaf-testing-modular-app/run/flatlaf-extras-999-SNAPSHOT.jar" path="4" type="2"/> "/>
|
||||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/flatlaf-fonts-inter/build/libs/flatlaf-fonts-inter-3.19-SNAPSHOT.jar" path="4" type="2"/> "/>
|
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/flatlaf-testing-modular-app/run/flatlaf-fonts-inter-999-SNAPSHOT.jar" path="4" type="2"/> "/>
|
||||||
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry externalArchive="C:/Users/charly/.gradle/caches/modules-2/files-2.1/com.formdev/svgSalamander/1.1.4/e61742cb8baaf9ecf57a9779763d1de21ca9db5a/svgSalamander-1.1.4.jar" path="4" type="2"/> "/>
|
<listEntry value="<?xml version="1.0" encoding="UTF-8" standalone="no"?> <runtimeClasspathEntry internalArchive="/flatlaf-testing-modular-app/run/jsvg-999.jar" path="4" type="2"/> "/>
|
||||||
</listAttribute>
|
</listAttribute>
|
||||||
<stringAttribute key="org.eclipse.jdt.launching.MODULE_NAME" value="flatlaf-testing-modular-app"/>
|
<stringAttribute key="org.eclipse.jdt.launching.MODULE_NAME" value="flatlaf-testing-modular-app"/>
|
||||||
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-m com.formdev.flatlaf.testing.modular.app/com.formdev.flatlaf.testing.modular.app.FlatModularAppTest"/>
|
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="-m com.formdev.flatlaf.testing.modular.app/com.formdev.flatlaf.testing.modular.app.FlatModularAppTest"/>
|
||||||
|
|||||||
@@ -30,3 +30,20 @@ flatlafModuleInfo {
|
|||||||
dependsOn( ":flatlaf-extras:jar" )
|
dependsOn( ":flatlaf-extras:jar" )
|
||||||
dependsOn( ":flatlaf-fonts-inter:jar" )
|
dependsOn( ":flatlaf-fonts-inter:jar" )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tasks {
|
||||||
|
register( "build-for-debugging" ) {
|
||||||
|
group = "build"
|
||||||
|
|
||||||
|
dependsOn( "build" )
|
||||||
|
|
||||||
|
doLast {
|
||||||
|
copy {
|
||||||
|
from( project.tasks["jar"].outputs )
|
||||||
|
from( configurations.runtimeClasspath )
|
||||||
|
into( "run" )
|
||||||
|
rename( "-[0-9][0-9.]*[0-9]", "-999" )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -38,8 +38,12 @@ public class FlatModularAppTest
|
|||||||
SwingUtilities.invokeLater( () -> {
|
SwingUtilities.invokeLater( () -> {
|
||||||
FlatInterFont.installBasic();
|
FlatInterFont.installBasic();
|
||||||
|
|
||||||
|
FlatLaf.registerCustomDefaultsSource( "com.formdev.flatlaf.testing.modular.app.themes" );
|
||||||
|
FlatLaf.registerCustomDefaultsSource( "com.formdev.flatlaf.testing.modular.app.themes2",
|
||||||
|
FlatModularAppTest.class.getClassLoader() );
|
||||||
FlatLaf.registerCustomDefaultsSource(
|
FlatLaf.registerCustomDefaultsSource(
|
||||||
FlatModularAppTest.class.getResource( "/com/formdev/flatlaf/testing/modular/app/themes/" ) );
|
FlatModularAppTest.class.getResource( "/com/formdev/flatlaf/testing/modular/app/themes3" ) );
|
||||||
|
|
||||||
FlatLightLaf.setup();
|
FlatLightLaf.setup();
|
||||||
|
|
||||||
JButton button1 = new JButton( "Hello" );
|
JButton button1 = new JButton( "Hello" );
|
||||||
|
|||||||
@@ -14,7 +14,4 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
|
|
||||||
@background = #fff
|
|
||||||
@foreground = #f00
|
@foreground = #f00
|
||||||
|
|
||||||
ButtonUI = com.formdev.flatlaf.testing.modular.app.plaf.MyButtonUI
|
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
@background = #efe
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
ButtonUI = com.formdev.flatlaf.testing.modular.app.plaf.MyButtonUI
|
||||||
@@ -162,6 +162,11 @@ public class FlatComponents2Test
|
|||||||
|
|
||||||
for( JTree tree : allTrees )
|
for( JTree tree : allTrees )
|
||||||
expandTree( tree );
|
expandTree( tree );
|
||||||
|
|
||||||
|
// drop mode
|
||||||
|
dropModeComboBox.init( DropMode.class, false );
|
||||||
|
dropModeComboBox.setSelectedItem( DropMode.ON_OR_INSERT );
|
||||||
|
dropModeChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initTableEditors( JTable table ) {
|
private void initTableEditors( JTable table ) {
|
||||||
@@ -311,13 +316,6 @@ public class FlatComponents2Test
|
|||||||
xTable1.setDragEnabled( dnd );
|
xTable1.setDragEnabled( dnd );
|
||||||
xTreeTable1.setDragEnabled( dnd );
|
xTreeTable1.setDragEnabled( dnd );
|
||||||
|
|
||||||
DropMode dropMode = dnd ? DropMode.ON_OR_INSERT : DropMode.USE_SELECTION;
|
|
||||||
list1.setDropMode( dropMode );
|
|
||||||
tree1.setDropMode( dropMode );
|
|
||||||
table1.setDropMode( dropMode );
|
|
||||||
xTable1.setDropMode( dropMode );
|
|
||||||
xTreeTable1.setDropMode( dropMode );
|
|
||||||
|
|
||||||
String key = "FlatLaf.oldTransferHandler";
|
String key = "FlatLaf.oldTransferHandler";
|
||||||
if( dnd ) {
|
if( dnd ) {
|
||||||
list1.putClientProperty( key, list1.getTransferHandler() );
|
list1.putClientProperty( key, list1.getTransferHandler() );
|
||||||
@@ -341,6 +339,32 @@ public class FlatComponents2Test
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void dropModeChanged() {
|
||||||
|
DropMode dropMode = dropModeComboBox.getSelectedValue();
|
||||||
|
DropMode dropMode2;
|
||||||
|
switch( dropMode ) {
|
||||||
|
case INSERT_ROWS:
|
||||||
|
case INSERT_COLS:
|
||||||
|
dropMode2 = DropMode.INSERT;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ON_OR_INSERT_ROWS:
|
||||||
|
case ON_OR_INSERT_COLS:
|
||||||
|
dropMode2 = DropMode.ON_OR_INSERT;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
dropMode2 = dropMode;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
list1.setDropMode( dropMode2 );
|
||||||
|
tree1.setDropMode( dropMode2 );
|
||||||
|
table1.setDropMode( dropMode );
|
||||||
|
xTable1.setDropMode( dropMode );
|
||||||
|
xTreeTable1.setDropMode( dropMode );
|
||||||
|
}
|
||||||
|
|
||||||
private void tableHeaderButtonChanged() {
|
private void tableHeaderButtonChanged() {
|
||||||
tableHeaderButtonChanged( table1ScrollPane );
|
tableHeaderButtonChanged( table1ScrollPane );
|
||||||
tableHeaderButtonChanged( xTable1ScrollPane );
|
tableHeaderButtonChanged( xTable1ScrollPane );
|
||||||
@@ -618,6 +642,7 @@ public class FlatComponents2Test
|
|||||||
super.updateUI();
|
super.updateUI();
|
||||||
|
|
||||||
EventQueue.invokeLater( () -> {
|
EventQueue.invokeLater( () -> {
|
||||||
|
dropModeChanged();
|
||||||
showHorizontalLinesChanged();
|
showHorizontalLinesChanged();
|
||||||
showVerticalLinesChanged();
|
showVerticalLinesChanged();
|
||||||
intercellSpacingChanged();
|
intercellSpacingChanged();
|
||||||
@@ -673,6 +698,7 @@ public class FlatComponents2Test
|
|||||||
leftSelectionInsetsCheckBox = new JCheckBox();
|
leftSelectionInsetsCheckBox = new JCheckBox();
|
||||||
rightSelectionInsetsCheckBox = new JCheckBox();
|
rightSelectionInsetsCheckBox = new JCheckBox();
|
||||||
dndCheckBox = new JCheckBox();
|
dndCheckBox = new JCheckBox();
|
||||||
|
dropModeComboBox = new FlatTestEnumComboBox<>();
|
||||||
listOptionsPanel = new JPanel();
|
listOptionsPanel = new JPanel();
|
||||||
JLabel listRendererLabel = new JLabel();
|
JLabel listRendererLabel = new JLabel();
|
||||||
listRendererComboBox = new JComboBox<>();
|
listRendererComboBox = new JComboBox<>();
|
||||||
@@ -963,6 +989,7 @@ public class FlatComponents2Test
|
|||||||
"[]0" +
|
"[]0" +
|
||||||
"[]0" +
|
"[]0" +
|
||||||
"[]rel" +
|
"[]rel" +
|
||||||
|
"[]" +
|
||||||
"[]"));
|
"[]"));
|
||||||
|
|
||||||
//---- roundedSelectionCheckBox ----
|
//---- roundedSelectionCheckBox ----
|
||||||
@@ -1004,6 +1031,10 @@ public class FlatComponents2Test
|
|||||||
dndCheckBox.setMnemonic('D');
|
dndCheckBox.setMnemonic('D');
|
||||||
dndCheckBox.addActionListener(e -> dndChanged());
|
dndCheckBox.addActionListener(e -> dndChanged());
|
||||||
generalOptionsPanel.add(dndCheckBox, "cell 0 4");
|
generalOptionsPanel.add(dndCheckBox, "cell 0 4");
|
||||||
|
|
||||||
|
//---- dropModeComboBox ----
|
||||||
|
dropModeComboBox.addActionListener(e -> dropModeChanged());
|
||||||
|
generalOptionsPanel.add(dropModeComboBox, "cell 0 5");
|
||||||
}
|
}
|
||||||
add(generalOptionsPanel, "cell 0 4 4 1");
|
add(generalOptionsPanel, "cell 0 4 4 1");
|
||||||
|
|
||||||
@@ -1272,6 +1303,7 @@ public class FlatComponents2Test
|
|||||||
private JCheckBox leftSelectionInsetsCheckBox;
|
private JCheckBox leftSelectionInsetsCheckBox;
|
||||||
private JCheckBox rightSelectionInsetsCheckBox;
|
private JCheckBox rightSelectionInsetsCheckBox;
|
||||||
private JCheckBox dndCheckBox;
|
private JCheckBox dndCheckBox;
|
||||||
|
private FlatTestEnumComboBox<DropMode> dropModeComboBox;
|
||||||
private JPanel listOptionsPanel;
|
private JPanel listOptionsPanel;
|
||||||
private JComboBox<String> listRendererComboBox;
|
private JComboBox<String> listRendererComboBox;
|
||||||
private JComboBox<String> listLayoutOrientationField;
|
private JComboBox<String> listLayoutOrientationField;
|
||||||
|
|||||||
@@ -299,7 +299,7 @@ new FormModel {
|
|||||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
||||||
"$layoutConstraints": "insets 8,hidemode 3"
|
"$layoutConstraints": "insets 8,hidemode 3"
|
||||||
"$columnConstraints": "[left]"
|
"$columnConstraints": "[left]"
|
||||||
"$rowConstraints": "[][]0[]0[]rel[]"
|
"$rowConstraints": "[][]0[]0[]rel[][]"
|
||||||
} ) {
|
} ) {
|
||||||
name: "generalOptionsPanel"
|
name: "generalOptionsPanel"
|
||||||
"border": new javax.swing.border.TitledBorder( "General Control" )
|
"border": new javax.swing.border.TitledBorder( "General Control" )
|
||||||
@@ -379,6 +379,16 @@ new FormModel {
|
|||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
"value": "cell 0 4"
|
"value": "cell 0 4"
|
||||||
} )
|
} )
|
||||||
|
add( new FormComponent( "com.formdev.flatlaf.testing.FlatTestEnumComboBox" ) {
|
||||||
|
name: "dropModeComboBox"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
"JavaCodeGenerator.typeParameters": "DropMode"
|
||||||
|
}
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "dropModeChanged", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 5"
|
||||||
|
} )
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
"value": "cell 0 4 4 1"
|
"value": "cell 0 4 4 1"
|
||||||
} )
|
} )
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import java.io.IOException;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.io.StringReader;
|
import java.io.StringReader;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@@ -177,7 +178,7 @@ class FlatCompletionProvider
|
|||||||
try {
|
try {
|
||||||
try( InputStream in = getClass().getResourceAsStream( "/com/formdev/flatlaf/themeeditor/FlatLafUIKeys.txt" ) ) {
|
try( InputStream in = getClass().getResourceAsStream( "/com/formdev/flatlaf/themeeditor/FlatLafUIKeys.txt" ) ) {
|
||||||
if( in != null ) {
|
if( in != null ) {
|
||||||
try( BufferedReader reader = new BufferedReader( new InputStreamReader( in, "UTF-8" ) ) ) {
|
try( BufferedReader reader = new BufferedReader( new InputStreamReader( in, StandardCharsets.UTF_8 ) ) ) {
|
||||||
String key;
|
String key;
|
||||||
while( (key = reader.readLine()) != null ) {
|
while( (key = reader.readLine()) != null ) {
|
||||||
if( !isIgnored( key ) )
|
if( !isIgnored( key ) )
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import java.awt.Window;
|
|||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import javax.swing.Action;
|
import javax.swing.Action;
|
||||||
import javax.swing.BorderFactory;
|
import javax.swing.BorderFactory;
|
||||||
import javax.swing.InputMap;
|
import javax.swing.InputMap;
|
||||||
@@ -211,7 +212,7 @@ class FlatThemeEditorPane
|
|||||||
void load( File file ) throws IOException {
|
void load( File file ) throws IOException {
|
||||||
this.file = file;
|
this.file = file;
|
||||||
|
|
||||||
textArea.load( FileLocation.create( file ), "UTF-8" );
|
textArea.load( FileLocation.create( file ), StandardCharsets.UTF_8 );
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean reloadIfNecessary() {
|
boolean reloadIfNecessary() {
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ import java.io.OutputStreamWriter;
|
|||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.time.Year;
|
import java.time.Year;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@@ -675,7 +676,7 @@ class FlatThemeFileEditor
|
|||||||
{
|
{
|
||||||
try(
|
try(
|
||||||
FileOutputStream out = new FileOutputStream( file );
|
FileOutputStream out = new FileOutputStream( file );
|
||||||
Writer writer = new OutputStreamWriter( out, "UTF-8" );
|
Writer writer = new OutputStreamWriter( out, StandardCharsets.UTF_8 );
|
||||||
) {
|
) {
|
||||||
writer.write( content );
|
writer.write( content );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,9 @@ package com.formdev.flatlaf.themeeditor;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@@ -109,8 +112,11 @@ class FlatThemePropertiesBaseManager
|
|||||||
String propertiesName = '/' + lafClass.getName().replace( '.', '/' ) + ".properties";
|
String propertiesName = '/' + lafClass.getName().replace( '.', '/' ) + ".properties";
|
||||||
try( InputStream in = lafClass.getResourceAsStream( propertiesName ) ) {
|
try( InputStream in = lafClass.getResourceAsStream( propertiesName ) ) {
|
||||||
Properties properties = new Properties();
|
Properties properties = new Properties();
|
||||||
if( in != null )
|
if( in != null ) {
|
||||||
properties.load( in );
|
try( Reader reader = new InputStreamReader( in, StandardCharsets.UTF_8 )) {
|
||||||
|
properties.load( in );
|
||||||
|
}
|
||||||
|
}
|
||||||
coreThemes.put( lafClass.getSimpleName(), properties );
|
coreThemes.put( lafClass.getSimpleName(), properties );
|
||||||
} catch( IOException ex ) {
|
} catch( IOException ex ) {
|
||||||
ex.printStackTrace();
|
ex.printStackTrace();
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
|
|
||||||
flatlaf.releaseVersion = 3.6
|
flatlaf.releaseVersion = 3.6.2
|
||||||
flatlaf.developmentVersion = 3.7-SNAPSHOT
|
flatlaf.developmentVersion = 3.7-SNAPSHOT
|
||||||
|
|
||||||
org.gradle.parallel = true
|
org.gradle.parallel = true
|
||||||
|
|||||||
@@ -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" }
|
||||||
|
|||||||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -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
6
gradlew
vendored
@@ -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
4
gradlew.bat
vendored
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user