Compare commits

...

75 Commits
3.1.1 ... 3.2

Author SHA1 Message Date
Karl Tauber
75da361480 GitHub Actions: disable parallel build for publishing to maven central; otherwise two staging repos are created, which can not be closed and released
https://stackoverflow.com/questions/72664149/gradle-maven-publish-sonatype-creates-multiple-repositories-that-cant-be-clos
2023-08-10 19:31:55 +02:00
Karl Tauber
7488bcb7b0 update to Gradle 8.2.1 2023-08-10 19:06:10 +02:00
Karl Tauber
1b1a9be107 release 3.2 2023-08-10 18:34:38 +02:00
Karl Tauber
db2f94aa53 IntelliJ Themes: fixed Table background in "One Dark" theme 2023-08-10 16:06:11 +02:00
Karl Tauber
810146b993 Demo: auto-reload current theme in development environment if .properties files have changed 2023-08-09 14:22:05 +02:00
Karl Tauber
93091662ab IntelliJ Themes: fixed colors for selection background/foreground, Separator, Slider track and ProgressBar background in various themes 2023-08-09 13:58:40 +02:00
Karl Tauber
d349227fbf IntelliJ Themes: fixed wrong disabled text colors in "Dark Flat", "Hiberbee Dark", "Light Flat", "Nord", "Solarized Dark" and "Solarized Light" themes 2023-08-08 17:13:30 +02:00
Karl Tauber
c9423e3aa8 CHANGELOG.md: fixed type on previous commit 2023-08-07 20:00:00 +02:00
Karl Tauber
b9737ca4f1 Merge PR #709: x86: Narrow version range for not using system icons 2023-08-07 19:55:11 +02:00
Karl Tauber
4b4990635d FileChooser: Fixed crash on Windows with Java 17 to 17.0.2 32-bit. Java 17 64-bit is not affected. (regression since FlatLaf 2.3; PR #522, see also issue #403) 2023-08-07 19:35:04 +02:00
Karl Tauber
afaa2c8c78 FileChooser: show localized text for all locales supported by Metal (issue #680) 2023-08-06 18:35:25 +02:00
Karl Tauber
f506ef0d4f Theme Editor: improve order of directories in combobox 2023-08-06 18:34:29 +02:00
Sung Ho Yoon
d30fe66cac Narrow version range for not using system icons 2023-08-06 09:35:00 +09:00
Karl Tauber
270e998e86 Theme Editor:
- fixed missing icon on "open" button (regression in commit 35fa3197c8)
- added icons to "File" menu for add and save actions
2023-08-05 19:18:51 +02:00
Karl Tauber
c395386c05 Merge PR #702: Window decorations: support toolbox-style "small" window title bar 2023-08-05 17:05:54 +02:00
Karl Tauber
4f1207b0db Merge PR #703: TabbedPane: support rounded underline selection and rounded card tabs 2023-08-05 16:59:57 +02:00
Karl Tauber
dc3878e290 Native window libraries: added flatlaf-windows-arm64.dll (for issue #443, PR #707)
built by GitHub Actions:
https://github.com/JFormDesigner/FlatLaf/actions/runs/5771160235

locally signed Windows DLLs with FormDev Software GmbH code signing certificate
2023-08-05 16:26:11 +02:00
Karl Tauber
be2876149d Merge PR #707: Windows on ARM Support 2023-08-05 16:14:00 +02:00
Karl Tauber
52bae9dfb0 Windows on ARM:
- changed DLL filename from aarch64 to arm64
- publish ARM DLL to Maven Central
2023-08-05 16:11:46 +02:00
Karl Tauber
bb636bac3f IntelliJ Themes: fixed ModifyCollectionInEnhancedForLoop Error Prone error 2023-08-04 16:29:21 +02:00
Sung Ho Yoon
502b18fa86 Remove check for x86
Now that the aarch64 library is added, this
check is unnecessary.
2023-08-04 22:10:48 +09:00
Sung Ho Yoon
e0a5450264 Load Windows on ARM (aarch64) native library 2023-08-04 22:10:13 +09:00
Karl Tauber
5ffb23c37f Merge PR #704: Tweak ZAP's name 2023-08-04 12:33:23 +02:00
Sung Ho Yoon
b75f22b7bd Add windows-aarch64 build configuration 2023-08-04 19:19:06 +09:00
Karl Tauber
35fa3197c8 Demo: moved SVG icons to JFormDesigner forms 2023-08-04 12:08:04 +02:00
Karl Tauber
f03725ae36 IntelliJ Themes: fixed ComboBox backgrounds in all "Material UI Lite" themes and in some other themes 2023-08-04 11:18:28 +02:00
Karl Tauber
2b640e2129 IntelliJ Themes: fixed foreground colors of disabled text in "Vuesion" theme 2023-08-04 00:59:41 +02:00
Karl Tauber
2a983f5c03 IntelliJ Themes: fixed background colors of enabled text components, to distinguish from disabled (issue #528) 2023-08-04 00:25:51 +02:00
Karl Tauber
cacc5daa14 IntelliJ Themes: updated theme "Monokai Pro Theme" from version 1.10 2023-08-03 00:37:42 +02:00
Karl Tauber
593502287d IntelliJ Themes: removed all "Contrast" themes from "Material UI Lite" 2023-08-03 00:26:59 +02:00
Karl Tauber
7a9bdf9be0 IntelliJ Themes: updated themes to newest versions (used IJThemesUpdater) 2023-08-02 15:03:57 +02:00
Karl Tauber
170c22c5ed IntelliJ Themes: fixed unselected CheckBox and RadioButton icon colors for themes "Atom One Light", "Cyan Light", "GitHub", "Light Owl", "Material Lighter" and "Solarized Light" 2023-08-02 14:25:15 +02:00
Karl Tauber
7e8fa58bd7 IntelliJ Themes: reduced memory footprint and improved setup speed by ignoring IntelliJ UI properties that are not used in FlatLaf
also fixed `ToggleButton.tab.selectedBackground`
2023-08-02 00:40:49 +02:00
Rick M
046200625c Make world possessive not plural 2023-08-01 16:20:11 -04:00
Rick M
710ed55152 Tweak ZAP's name
Per: https://www.zaproxy.org/blog/2023-08-01-zap-is-joining-the-software-security-project/
2023-08-01 16:18:41 -04:00
Karl Tauber
ce527329a6 ComboBox: fixed search in item list for text with spaces (issue #691) 2023-08-01 15:19:15 +02:00
Karl Tauber
b455dd41ab TabbedPane: going back to 3px tab selection for macOS themes 2023-07-31 22:36:59 +02:00
Karl Tauber
b47ed94f40 PopupMenu: make sure that popup menu does not overlap any operating system task bar (issue #701) 2023-07-31 22:21:35 +02:00
Karl Tauber
f1351a2093 TabbedPane: support rounded underline selection and rounded card tabs 2023-07-31 13:36:18 +02:00
Karl Tauber
c1c5e81df0 fixed error reported by Error Prone 2023-07-30 16:07:26 +02:00
Karl Tauber
8e3c8ba6c5 Window decorations: support toolbox-style "small" window title bar (issue #659) 2023-07-30 15:26:44 +02:00
Karl Tauber
dfe4404a17 fixed build error in flatlaf-testing-modular-app caused by moving to JSVG (PR #684) 2023-07-30 14:33:24 +02:00
Karl Tauber
b3fb63c9f5 ComboBox: improved location of selected item in popup if list is large and scrollable 2023-07-30 14:01:24 +02:00
Karl Tauber
9db3dfff26 CHANGELOG.md: added info about recently merged PR #684 2023-07-30 13:58:49 +02:00
Karl Tauber
3c9051e7de Merge PR #684: Replace svgSalamander with jsvg 2023-07-30 13:46:06 +02:00
Karl Tauber
798a6d061c jsvg: use String instead of URL as cache key to avoid this problem: https://errorprone.info/bugpattern/URLEqualsHashCode 2023-07-17 23:42:26 +02:00
Karl Tauber
19afbe99d9 FormattedTextField: On Linux, fixed IllegalArgumentException: Invalid location if JFormattedTextField.setDocument() is invoked in a focus gained listener on that formatted text field. (issue #698) 2023-07-17 15:46:11 +02:00
Karl Tauber
4715d8d16c jsvg: use RenderingHints.VALUE_STROKE_PURE for correct line rendering 2023-07-17 12:43:09 +02:00
Karl Tauber
193da2bc4d jsvg: updated flatlaf-extras/README.md; removed svgSalamander from libs.versions.toml 2023-07-10 13:49:30 +02:00
Karl Tauber
799f8efe22 jsvg: simplified/fixed loading from input stream; replaced internal usage of URI with URL 2023-07-10 13:41:54 +02:00
Karl Tauber
f6062e1ec4 jsvg: fixed color filter in FlatSVGIcon 2023-07-09 23:16:50 +02:00
Karl Tauber
c790778a46 Window decorations: support moving/resizing JInternalFrame that is child of JLayeredPane and overlaps FlatLaf title bar (issue #658) 2023-07-09 18:23:20 +02:00
Karl Tauber
4344f1b3a0 IntelliJ Themes: fixed focused tab background color for themes "Arc *", "Material Design Dark", "Monocai", "One Dark", "Spacegray" and "Xcode-Dark" (issue #697) 2023-07-09 14:09:01 +02:00
Karl Tauber
d520b30500 TestFlatStylingScale unit tests added for commit fde65b2730, issue #682 2023-07-02 18:47:10 +02:00
Karl Tauber
11c02e5f50 FlatWindowDecorationsTest: redesigned UI; added "FlatLaf window decorations" checkbox 2023-07-02 18:03:39 +02:00
Karl Tauber
aa4c6ee9da Native window libraries: updated Windows DLLs (for issue #673)
built by GitHub Actions:
https://github.com/JFormDesigner/FlatLaf/actions/runs/5431957508

locally signed Windows DLLs with FormDev Software GmbH code signing certificate
2023-07-01 18:37:32 +02:00
Karl Tauber
98f8557392 flatlaf-natives-windows: reworked linking/loading of jawt.dll; now loading jawt.dll when first used (issue #673) 2023-07-01 18:16:59 +02:00
Karl Tauber
6f6a860887 IntelliJ Themes: "Monocai" theme: fixed unreadable text color of default buttons (issue #693) 2023-06-21 17:30:59 +02:00
Karl Tauber
38695e9e16 updated Error Prone to 2.20.0 2023-06-21 17:16:22 +02:00
Karl Tauber
242c478cb3 GitHub Actions:
- build using Java 20 (use toolchain because Gradle 8.1.1 does not support running and compiling on Java 20 because Kotlin does not support 20 as target version)
- use temurin distribution as default because it is pre-installed on ubuntu-latest
2023-06-21 17:14:29 +02:00
Karl Tauber
f003e835bd macOS themes: changing @accentColor variable in FlatLaf properties files did not change all accent related colors for all components 2023-06-21 12:15:12 +02:00
Karl Tauber
267defb321 added system property flatlaf.useNativeLibrary to allow disabling loading of FlatLaf native library (issue #674) 2023-06-21 00:13:35 +02:00
Karl Tauber
4392c7627b IntelliJ Themes:
- "Light Owl" theme: Fixed wrong (unreadable) text color in selected menu
  items, selected text in text components, and selection in ComboBox popup
  list. (issue #687)
- "Gradianto Midnight Blue" theme: Fixed color of ScrollBar track, which was
  not visible. (issue #686)
2023-06-21 00:02:01 +02:00
Karl Tauber
fde65b2730 Styling: fixed scaling of some styling properties (rowHeight for Table and Tree; iconTextGap for Button, CheckBox and RadioButton) (issue #682) 2023-06-20 23:45:41 +02:00
Karl Tauber
e908362f0a fixed IllegalComponentStateException when invoker is not showing in SubMenuUsabilityHelper (issue #692) 2023-06-20 23:15:11 +02:00
Jannis Weis
a40b837634 Replace svgSalamander with jsvg 2023-05-29 16:30:12 +02:00
Karl Tauber
b391465fbf Gradle:
- moved FlatLaf version numbers from build.gradle.kts to gradle.properties
- enabled Gradle parallel build
2023-05-20 12:30:23 +02:00
Karl Tauber
bad0428f5b UIDefaultsLoader and FlatStylingSupport: explicitly specify throws IllegalArgumentException and improved catching 2023-05-20 12:26:46 +02:00
Karl Tauber
97018df2f9 added Error Prone (https://errorprone.info/) and fixed reported errors and warnings
- CI runs Error Prone with Java 11
- use Gradle task `errorprone` to run it on development machine
- fixes are mostly cosmetic except:
  - use Locale.ENGLISH for String.toLowerCase()
  - use explicit character encoding when reading/writing files
  - TabbedPane: wrong logic in mouse-wheel scrolling
  - SplitPane: simplified property change listener (fixes hiding field `propertyChangeListener` of superclass)
2023-05-19 22:58:12 +02:00
Karl Tauber
9d84501bc8 Gradle: moved declaration of all external dependencies to libs.versions.toml and use Gradle version catalog 2023-05-18 15:37:03 +02:00
Karl Tauber
e9fb2b3fdc update to Gradle 8.1.1 2023-05-18 15:32:05 +02:00
Karl T
f60250fd8a Merge pull request #681 from Plyha/spark
Add Spark to Applications
2023-05-18 14:58:39 +02:00
ilya khlevnoy
5fc3cae28a Add Spark to Applications 2023-05-17 23:07:35 +03:00
Karl T
e7935be85b Merge pull request #671 from kumait/main
Add Kafka Visualizer to Applications
2023-04-23 17:01:56 +02:00
kumait
89363b2ea1 Add Kafka Visualizer to Applications 2023-04-22 18:11:55 -04:00
184 changed files with 3227 additions and 32712 deletions

View File

@@ -26,9 +26,9 @@ jobs:
- 17 # LTS - 17 # LTS
- 19 - 19
toolchain: [""] toolchain: [""]
# include: include:
# - java: 17 - java: 17
# toolchain: 19 # latest toolchain: 20 # latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
@@ -40,9 +40,13 @@ jobs:
uses: actions/setup-java@v3 uses: actions/setup-java@v3
with: with:
java-version: ${{ matrix.java }} java-version: ${{ matrix.java }}
distribution: adopt # Java 8 and 11 are pre-installed on ubuntu-latest distribution: temurin # Java 8, 11 and 17 are pre-installed on ubuntu-latest
cache: gradle cache: gradle
- name: Check with Error Prone
if: matrix.java == '11'
run: ./gradlew errorprone clean -Dtoolchain=${{ matrix.toolchain }}
- name: Build with Gradle - name: Build with Gradle
run: ./gradlew build -Dtoolchain=${{ matrix.toolchain }} run: ./gradlew build -Dtoolchain=${{ matrix.toolchain }}
@@ -73,11 +77,11 @@ jobs:
uses: actions/setup-java@v3 uses: actions/setup-java@v3
with: with:
java-version: 11 java-version: 11
distribution: adopt # 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 oss.sonatype.org
run: ./gradlew publish :flatlaf-theme-editor:build -PskipFonts -Dorg.gradle.internal.publish.checksums.insecure=true run: ./gradlew publish :flatlaf-theme-editor:build -PskipFonts -Dorg.gradle.internal.publish.checksums.insecure=true -Dorg.gradle.parallel=false
env: env:
OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }} OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }}
OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }} OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }}
@@ -109,11 +113,11 @@ jobs:
uses: actions/setup-java@v3 uses: actions/setup-java@v3
with: with:
java-version: 11 java-version: 11
distribution: adopt # pre-installed on ubuntu-latest distribution: temurin # pre-installed on ubuntu-latest
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 run: ./gradlew publish :flatlaf-demo:build :flatlaf-theme-editor:build -PskipFonts -Prelease -Dorg.gradle.parallel=false
env: env:
OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }} OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }}
OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }} OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }}

View File

@@ -36,7 +36,7 @@ jobs:
uses: actions/setup-java@v3 uses: actions/setup-java@v3
with: with:
java-version: 11 java-version: 11
distribution: adopt # pre-installed on ubuntu-latest distribution: temurin # pre-installed on ubuntu-latest
cache: gradle cache: gradle
- name: Build with Gradle - name: Build with Gradle

View File

@@ -33,7 +33,7 @@ jobs:
uses: actions/setup-java@v3 uses: actions/setup-java@v3
with: with:
java-version: 11 java-version: 11
distribution: adopt distribution: temurin
cache: gradle cache: gradle
- name: Build with Gradle - name: Build with Gradle

View File

@@ -1,6 +1,86 @@
FlatLaf Change Log FlatLaf Change Log
================== ==================
## 3.2
#### New features and improvements
- TabbedPane: Support rounded underline selection and rounded card tabs. (PR
#703)
- FlatLaf window decorations:
- Support for Windows on ARM 64-bit. (issue #443, PR #707)
- Support toolbox-style "small" window title bar. (issue #659, PR #702)
- Extras: Class `FlatSVGIcon` now uses [JSVG](https://github.com/weisJ/jsvg)
library (instead of svgSalamander) for rendering. JSVG provides improved SVG
rendering and uses less memory compared to svgSalamander. (PR #684)
- ComboBox: Improved location of selected item in popup if list is large and
scrollable.
- FileChooser: Show localized text for all locales supported by Java's Metal
look and feel. (issue #680)
- Added system property `flatlaf.useNativeLibrary` to allow disabling loading of
FlatLaf native library. (issue #674)
- IntelliJ Themes:
- Reduced memory footprint by releasing Json data and ignoring IntelliJ UI
properties that are not used in FlatLaf.
- Updated "Hiberbee Dark" and "Gradianto" themes.
#### Fixed bugs
- Styling: Fixed scaling of some styling properties (`rowHeight` for Table and
Tree; `iconTextGap` for Button, CheckBox and RadioButton). (issue #682)
- Fixed `IllegalComponentStateException` when invoker is not showing in
`SubMenuUsabilityHelper`. (issue #692)
- macOS themes: Changing `@accentColor` variable in FlatLaf properties files did
not change all accent related colors for all components.
- IntelliJ Themes:
- "Light Owl" theme: Fixed wrong (unreadable) text color in selected menu
items, selected text in text components, and selection in ComboBox popup
list. (issue #687)
- "Gradianto Midnight Blue" theme: Fixed color of ScrollBar track, which was
not visible. (issue #686)
- "Monocai" theme: Fixed unreadable text color of default buttons. (issue
#693)
- "Vuesion" theme: Fixed foreground colors of disabled text.
- "Material UI Lite" themes: Fixed non-editable ComboBox button background.
- CheckBox and RadioButton: Fixed unselected icon colors for themes "Atom One
Light", "Cyan Light", "GitHub", "Light Owl", "Material Lighter" and
"Solarized Light".
- TabbedPane: Fixed focused tab background color for themes "Arc *", "Material
Design Dark", "Monocai", "One Dark", "Spacegray" and "Xcode-Dark". (issue
#697)
- TextComponents, ComboBox and Spinner: Fixed background colors of enabled
text components, to distinguish from disabled, for themes "Carbon", "Cobalt
2", "Gradianto *", "Gruvbox *", "Monocai", "Spacegray", "Vuesion",
"Xcode-Dark", "GitHub", and "Light Owl". (issue #528)
- Fixed wrong disabled text colors in "Dark Flat", "Hiberbee Dark", "Light
Flat", "Nord", "Solarized Dark" and "Solarized Light" themes.
- Fixed colors for selection background/foreground, Separator, Slider track
and ProgressBar background in various themes.
- Native Windows libraries: Fixed crash when running in Java 8 and newer Java
version is installed in `PATH` environment variable and using class
`SystemInfo` before AWT initialization. (issue #673)
- ComboBox: Fixed search in item list for text with spaces. (issue #691)
- FormattedTextField: On Linux, fixed `IllegalArgumentException: Invalid
location` if `JFormattedTextField.setDocument()` is invoked in a focus gained
listener on that formatted text field. (issue #698)
- PopupMenu: Make sure that popup menu does not overlap any operating system
task bar. (issue #701)
- FileChooser: Use system icons on Windows with Java 17.0.3 (and later) 32-bit.
Only Java 17 - 17.0.2 32-bit do not use system icons because of a bug in Java
32-bit that crashes the application. (PR #709)
- FileChooser: Fixed crash on Windows with Java 17 to 17.0.2 32-bit. Java 17
64-bit is not affected. (regression since FlatLaf 2.3; PR #522, see also issue
#403)
#### Incompatibilities
- Extras: Class `FlatSVGIcon` now uses [JSVG](https://github.com/weisJ/jsvg)
library for SVG rendering. You need to replace svgSalamander with JSVG in your
build scripts and distribute `jsvg.jar` with your application. Also replace
`com.kitfox.svg` with `com.github.weisj.jsvg` in `module-info.java` files.
- IntelliJ Themes: Removed all "Contrast" themes from "Material UI Lite".
## 3.1.1 ## 3.1.1
- IntelliJ Themes: - IntelliJ Themes:

View File

@@ -149,6 +149,10 @@ Buzz
Applications using FlatLaf Applications using FlatLaf
-------------------------- --------------------------
- ![New](images/new.svg)
[Spark](https://github.com/igniterealtime/Spark) - cross-platform IM client optimized for businesses and organizations.
- ![New](images/new.svg)
[Kafka Visualizer](https://github.com/kumait/kafkavisualizer) Kafka GUI client
- ![New](images/new.svg) - ![New](images/new.svg)
[JProfiler](https://www.ej-technologies.com/products/jprofiler/overview.html) [JProfiler](https://www.ej-technologies.com/products/jprofiler/overview.html)
12 (**commercial**) - the award-winning all-in-one Java profiler 12 (**commercial**) - the award-winning all-in-one Java profiler
@@ -193,7 +197,7 @@ Applications using FlatLaf
- ![Hot](images/hot.svg) - ![Hot](images/hot.svg)
[Thermo-Calc](https://thermocalc.com/products/thermo-calc/) 2021a [Thermo-Calc](https://thermocalc.com/products/thermo-calc/) 2021a
(**commercial**) - Thermodynamics and Properties Software (**commercial**) - Thermodynamics and Properties Software
- ![Hot](images/hot.svg) [OWASP ZAP](https://www.zaproxy.org/) 2.10 - the worlds - ![Hot](images/hot.svg) [ZAP](https://www.zaproxy.org/) 2.10 - the world's
most widely used web app scanner most widely used web app scanner
- ![Hot](images/hot.svg) - ![Hot](images/hot.svg)
[Burp Suite Professional and Community Edition](https://portswigger.net/burp/pro) [Burp Suite Professional and Community Edition](https://portswigger.net/burp/pro)

View File

@@ -14,10 +14,9 @@
* limitations under the License. * limitations under the License.
*/ */
val releaseVersion = "3.1.1" import net.ltgt.gradle.errorprone.errorprone
val developmentVersion = "3.2-SNAPSHOT"
version = if( rootProject.hasProperty( "release" ) ) releaseVersion else developmentVersion version = property( if( hasProperty( "release" ) ) "flatlaf.releaseVersion" else "flatlaf.developmentVersion" ) as String
allprojects { allprojects {
version = rootProject.version version = rootProject.version
@@ -43,6 +42,10 @@ if( !toolchainJavaVersion.isNullOrEmpty() )
println() println()
plugins {
alias( libs.plugins.errorprone ) apply false
}
allprojects { allprojects {
tasks { tasks {
withType<JavaCompile>().configureEach { withType<JavaCompile>().configureEach {
@@ -81,4 +84,56 @@ allprojects {
isFailOnError = false isFailOnError = false
} }
} }
//---- Error Prone ----
tasks.register( "errorprone" ) {
group = "verification"
tasks.withType<JavaCompile>().forEach {
dependsOn( it )
}
}
val useErrorProne = gradle.startParameter.taskNames.contains( "errorprone" )
if( useErrorProne ) {
plugins.withType<JavaPlugin> {
apply( plugin = libs.plugins.errorprone.get().pluginId )
dependencies {
"errorprone"( libs.errorprone )
}
tasks.withType<JavaCompile>().configureEach {
options.compilerArgs.add( "-Werror" )
options.errorprone {
disable(
"ReferenceEquality", // reports usage of '==' for objects
"StringSplitter", // reports String.split()
"JavaTimeDefaultTimeZone", // reports Year.now()
"MissingSummary", // reports `/** @since 2 */`
"InvalidBlockTag", // reports @uiDefault in javadoc
"AlreadyChecked", // reports false positives
"InlineMeSuggester", // suggests using Error Prone annotations for deprecated methods
"TypeParameterUnusedInFormals",
"UnsynchronizedOverridesSynchronized",
"NonApiType", // reports ArrayList/HashSet in parameter or return type
)
when( project.name ) {
"flatlaf-intellij-themes" -> disable(
"MutablePublicArray", // reports FlatAllIJThemes.INFOS
)
"flatlaf-theme-editor" -> disable(
"CatchAndPrintStackTrace",
)
"flatlaf-testing" -> disable(
"CatchAndPrintStackTrace",
"JdkObsolete", // reports Hashtable used for JSlider.setLabelTable()
"JavaUtilDate", // reports usage of class Date
)
}
}
}
}
}
} }

View File

@@ -27,12 +27,11 @@ plugins {
val sigtest = configurations.create( "sigtest" ) val sigtest = configurations.create( "sigtest" )
dependencies { dependencies {
testImplementation( "org.junit.jupiter:junit-jupiter-api:5.7.2" ) testImplementation( libs.bundles.junit )
testImplementation( "org.junit.jupiter:junit-jupiter-params" ) testRuntimeOnly( libs.junit.engine )
testRuntimeOnly( "org.junit.jupiter:junit-jupiter-engine" )
// https://github.com/jtulach/netbeans-apitest // https://github.com/jtulach/netbeans-apitest
sigtest( "org.netbeans.tools:sigtest-maven-plugin:1.7" ) sigtest( libs.sigtest )
} }
java { java {
@@ -130,6 +129,7 @@ flatlafPublish {
nativeArtifacts = listOf( nativeArtifacts = listOf(
NativeArtifact( "${natives}/flatlaf-windows-x86.dll", "windows-x86", "dll" ), NativeArtifact( "${natives}/flatlaf-windows-x86.dll", "windows-x86", "dll" ),
NativeArtifact( "${natives}/flatlaf-windows-x86_64.dll", "windows-x86_64", "dll" ), NativeArtifact( "${natives}/flatlaf-windows-x86_64.dll", "windows-x86_64", "dll" ),
NativeArtifact( "${natives}/flatlaf-windows-arm64.dll", "windows-arm64", "dll" ),
NativeArtifact( "${natives}/libflatlaf-linux-x86_64.so", "linux-x86_64", "so" ), NativeArtifact( "${natives}/libflatlaf-linux-x86_64.so", "linux-x86_64", "so" ),
) )
} }

View File

@@ -17,6 +17,8 @@
package com.formdev.flatlaf; package com.formdev.flatlaf;
import java.awt.Color; import java.awt.Color;
import java.awt.IllegalComponentStateException;
import java.awt.Window;
import java.util.Objects; import java.util.Objects;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.SwingConstants; import javax.swing.SwingConstants;
@@ -124,6 +126,7 @@ public interface FlatClientProperties
*/ */
String SQUARE_SIZE = "JButton.squareSize"; String SQUARE_SIZE = "JButton.squareSize";
//---- JComponent --------------------------------------------------------- //---- JComponent ---------------------------------------------------------
/** /**
@@ -266,6 +269,7 @@ public interface FlatClientProperties
*/ */
String COMPONENT_TITLE_BAR_CAPTION = "JComponent.titleBarCaption"; String COMPONENT_TITLE_BAR_CAPTION = "JComponent.titleBarCaption";
//---- Popup -------------------------------------------------------------- //---- Popup --------------------------------------------------------------
/** /**
@@ -305,6 +309,7 @@ public interface FlatClientProperties
*/ */
String POPUP_FORCE_HEAVY_WEIGHT = "Popup.forceHeavyWeight"; String POPUP_FORCE_HEAVY_WEIGHT = "Popup.forceHeavyWeight";
//---- JProgressBar ------------------------------------------------------- //---- JProgressBar -------------------------------------------------------
/** /**
@@ -323,6 +328,7 @@ public interface FlatClientProperties
*/ */
String PROGRESS_BAR_SQUARE = "JProgressBar.square"; String PROGRESS_BAR_SQUARE = "JProgressBar.square";
//---- JRootPane ---------------------------------------------------------- //---- JRootPane ----------------------------------------------------------
/** /**
@@ -472,6 +478,37 @@ public interface FlatClientProperties
*/ */
String GLASS_PANE_FULL_HEIGHT = "JRootPane.glassPaneFullHeight"; String GLASS_PANE_FULL_HEIGHT = "JRootPane.glassPaneFullHeight";
/**
* Specifies the style of the window title bar.
* Besides the default title bar style, you can use a Utility-style title bar,
* which is smaller than the default title bar.
* <p>
* On Windows 10/11, this requires FlatLaf window decorations.
* On macOS, Java supports this out of the box.
* <p>
* Note that this client property must be set before the window becomes displayable.
* Otherwise an {@link IllegalComponentStateException} is thrown.
* <p>
* <strong>Component</strong> {@link javax.swing.JRootPane}<br>
* <strong>Value type</strong> {@link java.lang.String}<br>
* <strong>Allowed Values</strong>
* {@link #WINDOW_STYLE_SMALL}
*
* @since 3.2
*/
String WINDOW_STYLE = "Window.style";
/**
* The window has Utility-style title bar, which is smaller than default title bar.
* <p>
* This is the same as using {@link Window#setType}( {@link Window.Type#UTILITY} ).
*
* @see #WINDOW_STYLE
* @since 3.2
*/
String WINDOW_STYLE_SMALL = "small";
//---- JScrollBar / JScrollPane ------------------------------------------- //---- JScrollBar / JScrollPane -------------------------------------------
/** /**
@@ -490,6 +527,7 @@ public interface FlatClientProperties
*/ */
String SCROLL_PANE_SMOOTH_SCROLLING = "JScrollPane.smoothScrolling"; String SCROLL_PANE_SMOOTH_SCROLLING = "JScrollPane.smoothScrolling";
//---- JSplitPane --------------------------------------------------------- //---- JSplitPane ---------------------------------------------------------
/** /**
@@ -524,6 +562,7 @@ public interface FlatClientProperties
*/ */
String SPLIT_PANE_EXPANDABLE_SIDE_RIGHT = "right"; String SPLIT_PANE_EXPANDABLE_SIDE_RIGHT = "right";
//---- JTabbedPane -------------------------------------------------------- //---- JTabbedPane --------------------------------------------------------
/** /**
@@ -919,6 +958,7 @@ public interface FlatClientProperties
*/ */
String TABBED_PANE_TRAILING_COMPONENT = "JTabbedPane.trailingComponent"; String TABBED_PANE_TRAILING_COMPONENT = "JTabbedPane.trailingComponent";
//---- JTextField --------------------------------------------------------- //---- JTextField ---------------------------------------------------------
/** /**
@@ -1088,6 +1128,7 @@ public interface FlatClientProperties
*/ */
String TEXT_FIELD_CLEAR_CALLBACK = "JTextField.clearCallback"; String TEXT_FIELD_CLEAR_CALLBACK = "JTextField.clearCallback";
//---- JToggleButton ------------------------------------------------------ //---- JToggleButton ------------------------------------------------------
/** /**
@@ -1129,6 +1170,7 @@ public interface FlatClientProperties
*/ */
String TAB_BUTTON_SELECTED_BACKGROUND = "JToggleButton.tab.selectedBackground"; String TAB_BUTTON_SELECTED_BACKGROUND = "JToggleButton.tab.selectedBackground";
//---- JTree -------------------------------------------------------------- //---- JTree --------------------------------------------------------------
/** /**
@@ -1148,6 +1190,7 @@ public interface FlatClientProperties
*/ */
String TREE_PAINT_SELECTION = "JTree.paintSelection"; String TREE_PAINT_SELECTION = "JTree.paintSelection";
//---- helper methods ----------------------------------------------------- //---- helper methods -----------------------------------------------------
/** /**

View File

@@ -50,7 +50,8 @@ class FlatInputMaps
} }
modifyInputMap( defaults, "ComboBox.ancestorInputMap", modifyInputMap( defaults, "ComboBox.ancestorInputMap",
"SPACE", "spacePopup", // Space key still shows popup, but from FlatComboBoxUI.FlatKeySelectionManager
// "SPACE", "spacePopup",
"UP", mac( "selectPrevious2", "selectPrevious" ), "UP", mac( "selectPrevious2", "selectPrevious" ),
"DOWN", mac( "selectNext2", "selectNext" ), "DOWN", mac( "selectNext2", "selectNext" ),

View File

@@ -71,6 +71,7 @@ import javax.swing.plaf.FontUIResource;
import javax.swing.plaf.IconUIResource; import javax.swing.plaf.IconUIResource;
import javax.swing.plaf.UIResource; import javax.swing.plaf.UIResource;
import javax.swing.plaf.basic.BasicLookAndFeel; import javax.swing.plaf.basic.BasicLookAndFeel;
import javax.swing.plaf.metal.MetalLookAndFeel;
import javax.swing.text.StyleContext; import javax.swing.text.StyleContext;
import javax.swing.text.html.HTMLEditorKit; import javax.swing.text.html.HTMLEditorKit;
import com.formdev.flatlaf.ui.FlatNativeWindowBorder; import com.formdev.flatlaf.ui.FlatNativeWindowBorder;
@@ -391,7 +392,7 @@ public abstract class FlatLaf
Method m = UIManager.class.getMethod( "createLookAndFeel", String.class ); Method m = UIManager.class.getMethod( "createLookAndFeel", String.class );
aquaLaf = (BasicLookAndFeel) m.invoke( null, "Mac OS X" ); aquaLaf = (BasicLookAndFeel) m.invoke( null, "Mac OS X" );
} else } else
aquaLaf = (BasicLookAndFeel) Class.forName( aquaLafClassName ).getDeclaredConstructor().newInstance(); aquaLaf = Class.forName( aquaLafClassName ).asSubclass( BasicLookAndFeel.class ).getDeclaredConstructor().newInstance();
} catch( Exception ex ) { } catch( Exception ex ) {
LoggingFacade.INSTANCE.logSevere( "FlatLaf: Failed to initialize Aqua look and feel '" + aquaLafClassName + "'.", ex ); LoggingFacade.INSTANCE.logSevere( "FlatLaf: Failed to initialize Aqua look and feel '" + aquaLafClassName + "'.", ex );
throw new IllegalStateException(); throw new IllegalStateException();
@@ -543,7 +544,7 @@ public abstract class FlatLaf
// which can happen in applications that use some plugin system // which can happen in applications that use some plugin system
// and load FlatLaf in a plugin that uses its own classloader. // and load FlatLaf in a plugin that uses its own classloader.
// (e.g. Apache NetBeans) // (e.g. Apache NetBeans)
if( defaults.get( "FileChooser.fileNameHeaderText" ) != null ) if( defaults.get( "TabbedPane.moreTabsButtonToolTipText" ) != null )
return; return;
// load FlatLaf resource bundle and add content to defaults // load FlatLaf resource bundle and add content to defaults
@@ -581,10 +582,13 @@ public abstract class FlatLaf
Object activeFont = new ActiveFont( null, null, -1, 0, 0, 0, 0 ); Object activeFont = new ActiveFont( null, null, -1, 0, 0, 0, 0 );
// override fonts // override fonts
List<String> fontKeys = new ArrayList<>( 50 );
for( Object key : defaults.keySet() ) { for( Object key : defaults.keySet() ) {
if( key instanceof String && (((String)key).endsWith( ".font" ) || ((String)key).endsWith( "Font" )) ) if( key instanceof String && (((String)key).endsWith( ".font" ) || ((String)key).endsWith( "Font" )) )
defaults.put( key, activeFont ); fontKeys.add( (String) key );
} }
for( String key : fontKeys )
defaults.put( key, activeFont );
// add fonts that are not set in BasicLookAndFeel // add fonts that are not set in BasicLookAndFeel
defaults.put( "RootPane.font", activeFont ); defaults.put( "RootPane.font", activeFont );
@@ -1428,26 +1432,36 @@ public abstract class FlatLaf
private class FlatUIDefaults private class FlatUIDefaults
extends UIDefaults extends UIDefaults
{ {
private UIDefaults metalDefaults;
FlatUIDefaults( int initialCapacity, float loadFactor ) { FlatUIDefaults( int initialCapacity, float loadFactor ) {
super( initialCapacity, loadFactor ); super( initialCapacity, loadFactor );
} }
@Override @Override
public Object get( Object key ) { public Object get( Object key ) {
Object value = getValue( key ); return get( key, null );
return (value != null) ? (value != NULL_VALUE ? value : null) : super.get( key );
} }
@Override @Override
public Object get( Object key, Locale l ) { public Object get( Object key, Locale l ) {
Object value = getValue( key ); Object value = getFromUIDefaultsGetters( key );
return (value != null) ? (value != NULL_VALUE ? value : null) : super.get( key, l ); if( value != null )
return (value != NULL_VALUE) ? value : null;
value = super.get( key, l );
if( value != null )
return value;
// get file chooser texts from Metal
return (key instanceof String && ((String)key).startsWith( "FileChooser." ))
? getFromMetal( (String) key, l )
: null;
} }
private Object getValue( Object key ) { private Object getFromUIDefaultsGetters( Object key ) {
// use local variable for getters to avoid potential multi-threading issues // use local variable for getters to avoid potential multi-threading issues
List<Function<Object, Object>> uiDefaultsGetters = FlatLaf.this.uiDefaultsGetters; List<Function<Object, Object>> uiDefaultsGetters = FlatLaf.this.uiDefaultsGetters;
if( uiDefaultsGetters == null ) if( uiDefaultsGetters == null )
return null; return null;
@@ -1459,6 +1473,22 @@ public abstract class FlatLaf
return null; return null;
} }
private synchronized Object getFromMetal( String key, Locale l ) {
if( metalDefaults == null ) {
metalDefaults = new MetalLookAndFeel() {
// avoid unnecessary initialization
@Override protected void initClassDefaults( UIDefaults table ) {}
@Override protected void initSystemColorDefaults( UIDefaults table ) {}
}.getDefaults();
// empty not needed defaults (to save memory) because we're only interested
// in resource bundle strings, which are stored in another internal map
metalDefaults.clear();
}
return metalDefaults.get( key, l );
}
} }
//---- class ActiveFont --------------------------------------------------- //---- class ActiveFont ---------------------------------------------------
@@ -1541,7 +1571,7 @@ public abstract class FlatLaf
int newStyle = (style != -1) int newStyle = (style != -1)
? style ? style
: (styleChange != 0) : (styleChange != 0)
? baseStyle & ~((styleChange >> 16) & 0xffff) | (styleChange & 0xffff) ? (baseStyle & ~((styleChange >> 16) & 0xffff)) | (styleChange & 0xffff)
: baseStyle; : baseStyle;
// new size // new size

View File

@@ -21,6 +21,7 @@ import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Locale;
import java.util.Properties; import java.util.Properties;
/** /**
@@ -96,7 +97,7 @@ public class FlatPropertiesLaf
protected ArrayList<Class<?>> getLafClassesForDefaultsLoading() { protected ArrayList<Class<?>> getLafClassesForDefaultsLoading() {
ArrayList<Class<?>> lafClasses = new ArrayList<>(); ArrayList<Class<?>> lafClasses = new ArrayList<>();
lafClasses.add( FlatLaf.class ); lafClasses.add( FlatLaf.class );
switch( baseTheme.toLowerCase() ) { switch( baseTheme.toLowerCase( Locale.ENGLISH ) ) {
default: default:
case "light": case "light":
lafClasses.add( FlatLightLaf.class ); lafClasses.add( FlatLightLaf.class );

View File

@@ -150,10 +150,24 @@ public interface FlatSystemProperties
* <p> * <p>
* <strong>Allowed Values</strong> {@code false} and {@code true}<br> * <strong>Allowed Values</strong> {@code false} and {@code true}<br>
* <strong>Default</strong> {@code true} * <strong>Default</strong> {@code true}
*
* @since 2.5 * @since 2.5
*/ */
String UPDATE_UI_ON_SYSTEM_FONT_CHANGE = "flatlaf.updateUIOnSystemFontChange"; String UPDATE_UI_ON_SYSTEM_FONT_CHANGE = "flatlaf.updateUIOnSystemFontChange";
/**
* Specifies whether FlatLaf native library should be used.
* <p>
* Setting this to {@code false} disables loading native library,
* which also disables some features that depend on the native library.
* <p>
* <strong>Allowed Values</strong> {@code false} and {@code true}<br>
* <strong>Default</strong> {@code true}
*
* @since 3.2
*/
String USE_NATIVE_LIBRARY = "flatlaf.useNativeLibrary";
/** /**
* Specifies a directory in which the native FlatLaf libraries have been extracted. * Specifies a directory in which the native FlatLaf libraries have been extracted.
* The path can be absolute or relative to current application working directory. * The path can be absolute or relative to current application working directory.

View File

@@ -23,13 +23,17 @@ import java.io.InputStreamReader;
import java.io.Reader; import java.io.Reader;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.Map.Entry;
import javax.swing.UIDefaults; import javax.swing.UIDefaults;
import javax.swing.plaf.ColorUIResource; import javax.swing.plaf.ColorUIResource;
import com.formdev.flatlaf.json.Json; import com.formdev.flatlaf.json.Json;
@@ -61,9 +65,9 @@ public class IntelliJTheme
private final boolean isMaterialUILite; private final boolean isMaterialUILite;
private final Map<String, String> colors; private Map<String, String> colors;
private final Map<String, Object> ui; private Map<String, Object> ui;
private final Map<String, Object> icons; private Map<String, Object> icons;
private Map<String, ColorUIResource> namedColors = Collections.emptyMap(); private Map<String, ColorUIResource> namedColors = Collections.emptyMap();
@@ -196,8 +200,9 @@ public class IntelliJTheme
defaults.put( "HelpButton.focusedBackground", defaults.get( "Button.focusedBackground" ) ); defaults.put( "HelpButton.focusedBackground", defaults.get( "Button.focusedBackground" ) );
// IDEA uses TextField.background for editable ComboBox and Spinner // IDEA uses TextField.background for editable ComboBox and Spinner
defaults.put( "ComboBox.editableBackground", defaults.get( "TextField.background" ) ); Object textFieldBackground = get( defaults, themeSpecificDefaults, "TextField.background" );
defaults.put( "Spinner.background", defaults.get( "TextField.background" ) ); defaults.put( "ComboBox.editableBackground", textFieldBackground );
defaults.put( "Spinner.background", textFieldBackground );
// Spinner arrow button always has same colors as ComboBox arrow button // Spinner arrow button always has same colors as ComboBox arrow button
defaults.put( "Spinner.buttonBackground", defaults.get( "ComboBox.buttonEditableBackground" ) ); defaults.put( "Spinner.buttonBackground", defaults.get( "ComboBox.buttonEditableBackground" ) );
@@ -205,22 +210,41 @@ public class IntelliJTheme
defaults.put( "Spinner.buttonDisabledArrowColor", defaults.get( "ComboBox.buttonDisabledArrowColor" ) ); defaults.put( "Spinner.buttonDisabledArrowColor", defaults.get( "ComboBox.buttonDisabledArrowColor" ) );
// some themes specify colors for TextField.background, but forget to specify it for other components // some themes specify colors for TextField.background, but forget to specify it for other components
// (probably because those components are not used in IntelliJ) // (probably because those components are not used in IntelliJ IDEA)
if( uiKeys.contains( "TextField.background" ) ) { putAll( defaults, textFieldBackground,
Object textFieldBackground = defaults.get( "TextField.background" ); "EditorPane.background",
if( !uiKeys.contains( "FormattedTextField.background" ) ) "FormattedTextField.background",
defaults.put( "FormattedTextField.background", textFieldBackground ); "PasswordField.background",
if( !uiKeys.contains( "PasswordField.background" ) ) "TextArea.background",
defaults.put( "PasswordField.background", textFieldBackground ); "TextPane.background"
if( !uiKeys.contains( "EditorPane.background" ) ) );
defaults.put( "EditorPane.background", textFieldBackground ); putAll( defaults, get( defaults, themeSpecificDefaults, "TextField.selectionBackground" ),
if( !uiKeys.contains( "TextArea.background" ) ) "EditorPane.selectionBackground",
defaults.put( "TextArea.background", textFieldBackground ); "FormattedTextField.selectionBackground",
if( !uiKeys.contains( "TextPane.background" ) ) "PasswordField.selectionBackground",
defaults.put( "TextPane.background", textFieldBackground ); "TextArea.selectionBackground",
if( !uiKeys.contains( "Spinner.background" ) ) "TextPane.selectionBackground"
defaults.put( "Spinner.background", textFieldBackground ); );
} putAll( defaults, get( defaults, themeSpecificDefaults, "TextField.selectionForeground" ),
"EditorPane.selectionForeground",
"FormattedTextField.selectionForeground",
"PasswordField.selectionForeground",
"TextArea.selectionForeground",
"TextPane.selectionForeground"
);
// fix disabled and not-editable backgrounds for text components, combobox and spinner
// (IntelliJ IDEA does not use those colors; instead it used background color of parent)
putAll( defaults, panelBackground,
"ComboBox.disabledBackground",
"EditorPane.disabledBackground", "EditorPane.inactiveBackground",
"FormattedTextField.disabledBackground", "FormattedTextField.inactiveBackground",
"PasswordField.disabledBackground", "PasswordField.inactiveBackground",
"Spinner.disabledBackground",
"TextArea.disabledBackground", "TextArea.inactiveBackground",
"TextField.disabledBackground", "TextField.inactiveBackground",
"TextPane.disabledBackground", "TextPane.inactiveBackground"
);
// fix ToggleButton // fix ToggleButton
if( !uiKeys.contains( "ToggleButton.startBackground" ) && !uiKeys.contains( "*.startBackground" ) ) if( !uiKeys.contains( "ToggleButton.startBackground" ) && !uiKeys.contains( "*.startBackground" ) )
@@ -247,6 +271,33 @@ public class IntelliJTheme
if( rowHeight > 22 ) if( rowHeight > 22 )
defaults.put( "Tree.rowHeight", 22 ); defaults.put( "Tree.rowHeight", 22 );
// get (and remove) theme specific wildcard replacements, which override all other defaults that end with same suffix
HashMap<String, Object> wildcards = new HashMap<>();
Iterator<Entry<Object, Object>> it = themeSpecificDefaults.entrySet().iterator();
while( it.hasNext() ) {
Entry<Object, Object> e = it.next();
String key = (String) e.getKey();
if( key.startsWith( "*." ) ) {
wildcards.put( key.substring( "*.".length() ), e.getValue() );
it.remove();
}
}
// override UI defaults with theme specific wildcard replacements
if( !wildcards.isEmpty() ) {
for( Object key : defaults.keySet().toArray() ) {
int dot;
if( !(key instanceof String) ||
(dot = ((String)key).lastIndexOf( '.' )) < 0 )
continue;
String wildcardKey = ((String)key).substring( dot + 1 );
Object wildcardValue = wildcards.get( wildcardKey );
if( wildcardValue != null )
defaults.put( key, wildcardValue );
}
}
// apply theme specific UI defaults at the end to allow overwriting // apply theme specific UI defaults at the end to allow overwriting
for( Map.Entry<Object, Object> e : themeSpecificDefaults.entrySet() ) { for( Map.Entry<Object, Object> e : themeSpecificDefaults.entrySet() ) {
Object key = e.getKey(); Object key = e.getKey();
@@ -261,6 +312,20 @@ public class IntelliJTheme
defaults.put( key, value ); defaults.put( key, value );
} }
// let Java release memory
colors = null;
ui = null;
icons = null;
}
private Object get( UIDefaults defaults, Map<Object, Object> themeSpecificDefaults, String key ) {
return themeSpecificDefaults.getOrDefault( key, defaults.get( key ) );
}
private void putAll( UIDefaults defaults, Object value, String... keys ) {
for( String key : keys )
defaults.put( key, value );
} }
private Map<Object, Object> removeThemeSpecificDefaults( UIDefaults defaults ) { private Map<Object, Object> removeThemeSpecificDefaults( UIDefaults defaults ) {
@@ -334,8 +399,6 @@ public class IntelliJTheme
if( "".equals( value ) ) if( "".equals( value ) )
return; // ignore empty value return; // ignore empty value
uiKeys.add( key );
// ignore some properties that affect sizes // ignore some properties that affect sizes
if( key.endsWith( ".border" ) || if( key.endsWith( ".border" ) ||
key.endsWith( ".rowHeight" ) || key.endsWith( ".rowHeight" ) ||
@@ -350,6 +413,16 @@ public class IntelliJTheme
if( key.isEmpty() ) if( key.isEmpty() )
return; // ignore key return; // ignore key
// exclude properties
int dot = key.indexOf( '.' );
if( dot > 0 && uiKeyExcludes.contains( key.substring( 0, dot + 1 ) ) )
return;
if( uiKeyDoNotOverride.contains( key ) && uiKeys.contains( key ) )
return;
uiKeys.add( key );
String valueStr = value.toString(); String valueStr = value.toString();
// map named colors // map named colors
@@ -395,7 +468,8 @@ public class IntelliJTheme
// replace all values in UI defaults that match the wildcard key // replace all values in UI defaults that match the wildcard key
for( Object k : defaultsKeysCache ) { for( Object k : defaultsKeysCache ) {
if( k.equals( "Desktop.background" ) || if( k.equals( "Desktop.background" ) ||
k.equals( "DesktopIcon.background" ) ) k.equals( "DesktopIcon.background" ) ||
k.equals( "TabbedPane.focusColor" ) )
continue; continue;
if( k instanceof String ) { if( k instanceof String ) {
@@ -466,7 +540,7 @@ public class IntelliJTheme
/** /**
* Because IDEA uses SVGs for check boxes and radio buttons, the colors for * Because IDEA uses SVGs for check boxes and radio buttons, the colors for
* this two components are specified in "icons > ColorPalette". * these two components are specified in "icons > ColorPalette".
* FlatLaf uses vector icons and expects colors for the two components in UI defaults. * FlatLaf uses vector icons and expects colors for the two components in UI defaults.
*/ */
private void applyCheckBoxColors( UIDefaults defaults ) { private void applyCheckBoxColors( UIDefaults defaults ) {
@@ -486,18 +560,6 @@ public class IntelliJTheme
if( !key.startsWith( "Checkbox." ) || !(value instanceof String) ) if( !key.startsWith( "Checkbox." ) || !(value instanceof String) )
continue; continue;
if( key.equals( "Checkbox.Background.Default" ) ||
key.equals( "Checkbox.Foreground.Selected" ) )
{
// This two keys do not work correctly in IDEA because they
// map SVG color "#ffffff" to another color, but checkBox.svg and
// radio.svg (in package com.intellij.ide.ui.laf.icons.intellij)
// use "#fff". So use white to get same appearance as in IDEA.
value = "#ffffff";
}
String key2 = checkboxDuplicateColors.get( key );
if( dark ) if( dark )
key = StringUtils.removeTrailing( key, ".Dark" ); key = StringUtils.removeTrailing( key, ".Dark" );
@@ -511,6 +573,7 @@ public class IntelliJTheme
if( color != null ) { if( color != null ) {
defaults.put( newKey, color ); defaults.put( newKey, color );
String key2 = checkboxDuplicateColors.get( key + ".Dark");
if( key2 != null ) { if( key2 != null ) {
// When IDEA replaces colors in SVGs it uses color values and not the keys // When IDEA replaces colors in SVGs it uses color values and not the keys
// from com.intellij.ide.ui.UITheme.colorPalette, but there are some keys that // from com.intellij.ide.ui.UITheme.colorPalette, but there are some keys that
@@ -575,17 +638,59 @@ public class IntelliJTheme
defaults.put( destKey, defaults.get( srcKey ) ); defaults.put( destKey, defaults.get( srcKey ) );
} }
private static final Set<String> uiKeyExcludes;
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<>();
/** Copy UI default keys (value --> key). */ /** Copy UI default keys (value --> key). */
private static final Map<String, String> uiKeyCopying = new HashMap<>(); private static final Map<String, String> uiKeyCopying = new LinkedHashMap<>();
private static final Map<String, String> uiKeyInverseMapping = new HashMap<>(); private static final Map<String, String> uiKeyInverseMapping = new HashMap<>();
private static final Map<String, String> checkboxKeyMapping = new HashMap<>(); private static final Map<String, String> checkboxKeyMapping = new HashMap<>();
private static final Map<String, String> checkboxDuplicateColors = new HashMap<>(); private static final Map<String, String> checkboxDuplicateColors = new HashMap<>();
static { static {
// IntelliJ UI properties that are not used in FlatLaf
uiKeyExcludes = new HashSet<>( Arrays.asList(
"ActionButton.", "ActionToolbar.", "ActionsList.", "AppInspector.", "AssignedMnemonic.", "Autocomplete.",
"AvailableMnemonic.",
"BigSpinner.", "Bookmark.", "BookmarkIcon.", "BookmarkMnemonicAssigned.", "BookmarkMnemonicAvailable.",
"BookmarkMnemonicCurrent.", "BookmarkMnemonicIcon.", "Borders.", "Breakpoint.",
"Canvas.", "CodeWithMe.", "ComboBoxButton.", "CompletionPopup.", "ComplexPopup.", "Content.",
"CurrentMnemonic.", "Counter.",
"Debugger.", "DebuggerPopup.", "DebuggerTabs.", "DefaultTabs.", "Dialog.", "DialogWrapper.", "DragAndDrop.",
"Editor.", "EditorGroupsTabs.", "EditorTabs.",
"FileColor.", "FlameGraph.", "Focus.",
"Git.", "Github.", "GotItTooltip.", "Group.", "Gutter.", "GutterTooltip.",
"HeaderColor.", "HelpTooltip.", "Hg.",
"IconBadge.", "InformationHint.", "InplaceRefactoringPopup.",
"Lesson.", "Link.", "LiveIndicator.",
"MainMenu.", "MainToolbar.", "MemoryIndicator.", "MlModelBinding.", "MnemonicIcon.",
"NavBar.", "NewClass.", "NewPSD.", "Notification.", "Notifications.", "NotificationsToolwindow.",
"OnePixelDivider.", "OptionButton.", "Outline.",
"ParameterInfo.", "Plugins.", "ProgressIcon.", "PsiViewer.",
"ReviewList.", "RunWidget.",
"ScreenView.", "SearchEverywhere.", "SearchFieldWithExtension.", "SearchMatch.", "SearchOption.",
"SearchResults.", "SegmentedButton.", "Settings.", "SidePanel.", "Space.", "SpeedSearch.", "StateWidget.",
"StatusBar.",
"Tag.", "TipOfTheDay.", "ToolbarComboWidget.", "ToolWindow.",
"UIDesigner.", "UnattendedHostStatus.",
"ValidationTooltip.", "VersionControl.",
"WelcomeScreen.",
// lower case
"darcula.", "dropArea.", "icons.", "intellijlaf.", "macOSWindow.", "material.", "tooltips.",
// possible typos in .theme.json files
"Checkbox.", "Toolbar.", "Tooltip.", "UiDesigner.", "link."
) );
uiKeyDoNotOverride = new HashSet<>( Arrays.asList(
"TabbedPane.selectedForeground"
) );
// ComboBox // ComboBox
uiKeyMapping.put( "ComboBox.background", "" ); // ignore uiKeyMapping.put( "ComboBox.background", "" ); // ignore
uiKeyMapping.put( "ComboBox.buttonBackground", "" ); // ignore
uiKeyMapping.put( "ComboBox.nonEditableBackground", "ComboBox.background" ); uiKeyMapping.put( "ComboBox.nonEditableBackground", "ComboBox.background" );
uiKeyMapping.put( "ComboBox.ArrowButton.background", "ComboBox.buttonEditableBackground" ); uiKeyMapping.put( "ComboBox.ArrowButton.background", "ComboBox.buttonEditableBackground" );
uiKeyMapping.put( "ComboBox.ArrowButton.disabledIconColor", "ComboBox.buttonDisabledArrowColor" ); uiKeyMapping.put( "ComboBox.ArrowButton.disabledIconColor", "ComboBox.buttonDisabledArrowColor" );
@@ -643,9 +748,9 @@ public class IntelliJTheme
uiKeyCopying.put( "Spinner.buttonDisabledSeparatorColor", "Component.disabledBorderColor" ); uiKeyCopying.put( "Spinner.buttonDisabledSeparatorColor", "Component.disabledBorderColor" );
// TabbedPane // TabbedPane
uiKeyCopying.put( "TabbedPane.selectedBackground", "DefaultTabs.underlinedTabBackground" ); uiKeyMapping.put( "DefaultTabs.underlinedTabBackground", "TabbedPane.selectedBackground" );
uiKeyCopying.put( "TabbedPane.selectedForeground", "DefaultTabs.underlinedTabForeground" ); uiKeyMapping.put( "DefaultTabs.underlinedTabForeground", "TabbedPane.selectedForeground" );
uiKeyCopying.put( "TabbedPane.inactiveUnderlineColor", "DefaultTabs.inactiveUnderlineColor" ); uiKeyMapping.put( "DefaultTabs.inactiveUnderlineColor", "TabbedPane.inactiveUnderlineColor" );
// TitlePane // TitlePane
uiKeyCopying.put( "TitlePane.inactiveBackground", "TitlePane.background" ); uiKeyCopying.put( "TitlePane.inactiveBackground", "TitlePane.background" );

View File

@@ -23,11 +23,14 @@ import java.awt.GraphicsEnvironment;
import java.awt.Toolkit; import java.awt.Toolkit;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.File; import java.io.File;
import java.io.FileReader; import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Locale;
import java.util.StringTokenizer; import java.util.StringTokenizer;
import javax.swing.text.StyleContext; import javax.swing.text.StyleContext;
import com.formdev.flatlaf.util.LoggingFacade; import com.formdev.flatlaf.util.LoggingFacade;
@@ -68,7 +71,7 @@ class LinuxFontPolicy
if( word.endsWith( "," ) ) if( word.endsWith( "," ) )
word = word.substring( 0, word.length() - 1 ).trim(); word = word.substring( 0, word.length() - 1 ).trim();
String lword = word.toLowerCase(); String lword = word.toLowerCase( Locale.ENGLISH );
if( lword.equals( "italic" ) || lword.equals( "oblique" ) ) if( lword.equals( "italic" ) || lword.equals( "oblique" ) )
style |= Font.ITALIC; style |= Font.ITALIC;
else if( lword.equals( "bold" ) ) else if( lword.equals( "bold" ) )
@@ -104,7 +107,7 @@ class LinuxFontPolicy
size = 1; size = 1;
// handle logical font names // handle logical font names
String logicalFamily = mapFcName( family.toLowerCase() ); String logicalFamily = mapFcName( family.toLowerCase( Locale.ENGLISH ) );
if( logicalFamily != null ) if( logicalFamily != null )
family = logicalFamily; family = logicalFamily;
@@ -143,7 +146,7 @@ class LinuxFontPolicy
return createFont( Font.DIALOG, style, size, dsize ); return createFont( Font.DIALOG, style, size, dsize );
// check whether last work contains some font weight (e.g. Ultra-Bold or Heavy) // check whether last work contains some font weight (e.g. Ultra-Bold or Heavy)
String lastWord = family.substring( index + 1 ).toLowerCase(); String lastWord = family.substring( index + 1 ).toLowerCase( Locale.ENGLISH );
if( lastWord.contains( "bold" ) || lastWord.contains( "heavy" ) || lastWord.contains( "black" ) ) if( lastWord.contains( "bold" ) || lastWord.contains( "heavy" ) || lastWord.contains( "black" ) )
style |= Font.BOLD; style |= Font.BOLD;
@@ -257,6 +260,7 @@ class LinuxFontPolicy
return createFont( family, style, size, dsize ); return createFont( family, style, size, dsize );
} }
@SuppressWarnings( "MixedMutabilityReturnType" ) // Error Prone
private static List<String> readConfig( String filename ) { private static List<String> readConfig( String filename ) {
File userHome = new File( System.getProperty( "user.home" ) ); File userHome = new File( System.getProperty( "user.home" ) );
@@ -277,7 +281,9 @@ class LinuxFontPolicy
// read config file // read config file
ArrayList<String> lines = new ArrayList<>( 200 ); ArrayList<String> lines = new ArrayList<>( 200 );
try( BufferedReader reader = new BufferedReader( new FileReader( file ) ) ) { try( BufferedReader reader = new BufferedReader( new InputStreamReader(
new FileInputStream( file ), StandardCharsets.US_ASCII ) ) )
{
String line; String line;
while( (line = reader.readLine()) != null ) while( (line = reader.readLine()) != null )
lines.add( line ); lines.add( line );

View File

@@ -153,7 +153,7 @@ debug*/
// get invoker screen bounds // get invoker screen bounds
Component invoker = popup.getInvoker(); Component invoker = popup.getInvoker();
invokerBounds = (invoker != null) invokerBounds = (invoker != null && invoker.isShowing())
? new Rectangle( invoker.getLocationOnScreen(), invoker.getSize() ) ? new Rectangle( invoker.getLocationOnScreen(), invoker.getSize() )
: null; : null;

View File

@@ -27,8 +27,12 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
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.Executable;
import java.lang.reflect.Method;
import java.net.URL; import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
@@ -271,8 +275,9 @@ class UIDefaultsLoader
continue; continue;
} }
String value = resolveValue( (String) e.getValue(), propertiesGetter ); String value = (String) e.getValue();
try { try {
value = resolveValue( value, propertiesGetter );
defaults.put( key, parseValue( key, value, null, null, resolver, addonClassLoaders ) ); defaults.put( key, parseValue( key, value, null, null, resolver, addonClassLoaders ) );
} catch( RuntimeException ex ) { } catch( RuntimeException ex ) {
logParseError( key, value, ex, true ); logParseError( key, value, ex, true );
@@ -297,7 +302,9 @@ class UIDefaultsLoader
LoggingFacade.INSTANCE.logConfig( message, ex ); LoggingFacade.INSTANCE.logConfig( message, ex );
} }
static String resolveValue( String value, Function<String, String> propertiesGetter ) { static String resolveValue( String value, Function<String, String> propertiesGetter )
throws IllegalArgumentException
{
value = value.trim(); value = value.trim();
String value0 = value; String value0 = value;
@@ -326,7 +333,9 @@ class UIDefaultsLoader
return resolveValue( newValue, propertiesGetter ); return resolveValue( newValue, propertiesGetter );
} }
static String resolveValueFromUIManager( String value ) { static String resolveValueFromUIManager( String value )
throws IllegalArgumentException
{
if( value.startsWith( VARIABLE_PREFIX ) ) { if( value.startsWith( VARIABLE_PREFIX ) ) {
@SuppressWarnings( "unchecked" ) @SuppressWarnings( "unchecked" )
Map<String, String> variables = (Map<String, String>) UIManager.get( KEY_VARIABLES ); Map<String, String> variables = (Map<String, String>) UIManager.get( KEY_VARIABLES );
@@ -348,8 +357,11 @@ class UIDefaultsLoader
// convert binary color to string // convert binary color to string
if( newValue instanceof Color ) { if( newValue instanceof Color ) {
Color color = (Color) newValue; Color color = (Color) newValue;
int rgb = color.getRGB() & 0xffffff;
int alpha = color.getAlpha(); int alpha = color.getAlpha();
return String.format( (alpha != 255) ? "#%06x%02x" : "#%06x", color.getRGB() & 0xffffff, alpha ); return (alpha != 255)
? String.format( "#%06x%02x", rgb, alpha )
: String.format( "#%06x", rgb );
} }
throw new IllegalArgumentException( "property value type '" + newValue.getClass().getName() + "' not supported in references" ); throw new IllegalArgumentException( "property value type '" + newValue.getClass().getName() + "' not supported in references" );
@@ -362,12 +374,15 @@ class UIDefaultsLoader
private static Map<Class<?>, ValueType> javaValueTypes; private static Map<Class<?>, ValueType> javaValueTypes;
private static Map<String, ValueType> knownValueTypes; private static Map<String, ValueType> knownValueTypes;
static Object parseValue( String key, String value, Class<?> valueType ) { static Object parseValue( String key, String value, Class<?> valueType )
throws IllegalArgumentException
{
return parseValue( key, value, valueType, null, v -> v, Collections.emptyList() ); return parseValue( key, value, valueType, null, v -> v, Collections.emptyList() );
} }
static Object parseValue( String key, String value, Class<?> javaValueType, ValueType[] resultValueType, static Object parseValue( String key, String value, Class<?> javaValueType, ValueType[] resultValueType,
Function<String, String> resolver, List<ClassLoader> addonClassLoaders ) Function<String, String> resolver, List<ClassLoader> addonClassLoaders )
throws IllegalArgumentException
{ {
if( resultValueType == null ) if( resultValueType == null )
resultValueType = tempResultValueType; resultValueType = tempResultValueType;
@@ -397,7 +412,7 @@ class UIDefaultsLoader
if( value.startsWith( "if(" ) && value.endsWith( ")" ) ) { if( value.startsWith( "if(" ) && value.endsWith( ")" ) ) {
List<String> params = splitFunctionParams( value.substring( 3, value.length() - 1 ), ',' ); List<String> params = splitFunctionParams( value.substring( 3, value.length() - 1 ), ',' );
if( params.size() != 3 ) if( params.size() != 3 )
throwMissingParametersException( value ); throw newMissingParametersException( value );
boolean ifCondition = parseCondition( params.get( 0 ), resolver, addonClassLoaders ); boolean ifCondition = parseCondition( params.get( 0 ), resolver, addonClassLoaders );
String ifValue = params.get( ifCondition ? 1 : 2 ); String ifValue = params.get( ifCondition ? 1 : 2 );
@@ -537,7 +552,7 @@ class UIDefaultsLoader
case INTEGERORFLOAT:return parseIntegerOrFloat( value ); case INTEGERORFLOAT:return parseIntegerOrFloat( value );
case FLOAT: return parseFloat( value ); case FLOAT: return parseFloat( value );
case BORDER: return parseBorder( value, resolver, addonClassLoaders ); case BORDER: return parseBorder( value, resolver, addonClassLoaders );
case ICON: return parseInstance( value, addonClassLoaders ); case ICON: return parseInstance( value, resolver, addonClassLoaders );
case INSETS: return parseInsets( value ); case INSETS: return parseInsets( value );
case DIMENSION: return parseDimension( value ); case DIMENSION: return parseDimension( value );
case COLOR: return parseColorOrFunction( value, resolver ); case COLOR: return parseColorOrFunction( value, resolver );
@@ -546,7 +561,7 @@ class UIDefaultsLoader
case SCALEDFLOAT: return parseScaledFloat( value ); case SCALEDFLOAT: return parseScaledFloat( value );
case SCALEDINSETS: return parseScaledInsets( value ); case SCALEDINSETS: return parseScaledInsets( value );
case SCALEDDIMENSION:return parseScaledDimension( value ); case SCALEDDIMENSION:return parseScaledDimension( value );
case INSTANCE: return parseInstance( value, addonClassLoaders ); case INSTANCE: return parseInstance( value, resolver, addonClassLoaders );
case CLASS: return parseClass( value, addonClassLoaders ); case CLASS: return parseClass( value, addonClassLoaders );
case GRAYFILTER: return parseGrayFilter( value ); case GRAYFILTER: return parseGrayFilter( value );
case UNKNOWN: case UNKNOWN:
@@ -608,9 +623,11 @@ class UIDefaultsLoader
} }
} }
private static Object parseBorder( String value, Function<String, String> resolver, List<ClassLoader> addonClassLoaders ) { private static Object parseBorder( String value, Function<String, String> resolver, List<ClassLoader> addonClassLoaders )
throws IllegalArgumentException
{
if( value.indexOf( ',' ) >= 0 ) { if( value.indexOf( ',' ) >= 0 ) {
// 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 ); Insets insets = parseInsets( value );
ColorUIResource lineColor = (parts.size() >= 5) ColorUIResource lineColor = (parts.size() >= 5)
@@ -625,12 +642,28 @@ class UIDefaultsLoader
: new FlatEmptyBorder( insets ); : new FlatEmptyBorder( insets );
}; };
} else } else
return parseInstance( value, addonClassLoaders ); return parseInstance( value, resolver, addonClassLoaders );
} }
private static Object parseInstance( String value, List<ClassLoader> addonClassLoaders ) { private static Object parseInstance( String value, Function<String, String> resolver, List<ClassLoader> addonClassLoaders ) {
return (LazyValue) t -> { return (LazyValue) t -> {
try { try {
if( value.indexOf( ',' ) >= 0 ) {
// Syntax: className,param1,param2,...
List<String> parts = splitFunctionParams( value, ',' );
String className = parts.get( 0 );
Class<?> cls = findClass( className, addonClassLoaders );
Constructor<?>[] constructors = cls.getDeclaredConstructors();
Object result = invokeConstructorOrStaticMethod( constructors, parts, resolver );
if( result != null )
return result;
LoggingFacade.INSTANCE.logSevere( "FlatLaf: Failed to instantiate '" + className
+ "': no constructor found for parameters '"
+ value.substring( value.indexOf( ',' + 1 ) ) + "'.", null );
return null;
} else
return findClass( value, addonClassLoaders ).getDeclaredConstructor().newInstance(); return findClass( value, addonClassLoaders ).getDeclaredConstructor().newInstance();
} catch( Exception ex ) { } catch( Exception ex ) {
LoggingFacade.INSTANCE.logSevere( "FlatLaf: Failed to instantiate '" + value + "'.", ex ); LoggingFacade.INSTANCE.logSevere( "FlatLaf: Failed to instantiate '" + value + "'.", ex );
@@ -668,7 +701,9 @@ class UIDefaultsLoader
} }
} }
private static Insets parseInsets( String value ) { private static Insets parseInsets( String value )
throws IllegalArgumentException
{
List<String> numbers = StringUtils.split( value, ',', true, false ); List<String> numbers = StringUtils.split( value, ',', true, false );
try { try {
return new InsetsUIResource( return new InsetsUIResource(
@@ -681,7 +716,9 @@ class UIDefaultsLoader
} }
} }
private static Dimension parseDimension( String value ) { private static Dimension parseDimension( String value )
throws IllegalArgumentException
{
List<String> numbers = StringUtils.split( value, ',', true, false ); List<String> numbers = StringUtils.split( value, ',', true, false );
try { try {
return new DimensionUIResource( return new DimensionUIResource(
@@ -692,7 +729,9 @@ class UIDefaultsLoader
} }
} }
private static Object parseColorOrFunction( String value, Function<String, String> resolver ) { private static Object parseColorOrFunction( String value, Function<String, String> resolver )
throws IllegalArgumentException
{
if( value.endsWith( ")" ) ) if( value.endsWith( ")" ) )
return parseColorFunctions( value, resolver ); return parseColorFunctions( value, resolver );
@@ -702,10 +741,10 @@ class UIDefaultsLoader
/** /**
* Parses a hex color in {@code #RGB}, {@code #RGBA}, {@code #RRGGBB} or {@code #RRGGBBAA} * Parses a hex color in {@code #RGB}, {@code #RGBA}, {@code #RRGGBB} or {@code #RRGGBBAA}
* format and returns it as color object. * format and returns it as color object.
*
* @throws IllegalArgumentException
*/ */
static ColorUIResource parseColor( String value ) { static ColorUIResource parseColor( String value )
throws IllegalArgumentException
{
int rgba = parseColorRGBA( value ); int rgba = parseColorRGBA( value );
return ((rgba & 0xff000000) == 0xff000000) return ((rgba & 0xff000000) == 0xff000000)
? new ColorUIResource( rgba ) ? new ColorUIResource( rgba )
@@ -716,10 +755,10 @@ class UIDefaultsLoader
* Parses a hex color in {@code #RGB}, {@code #RGBA}, {@code #RRGGBB} or {@code #RRGGBBAA} * Parses a hex color in {@code #RGB}, {@code #RGBA}, {@code #RRGGBB} or {@code #RRGGBBAA}
* format and returns it as {@code rgba} integer suitable for {@link java.awt.Color}, * format and returns it as {@code rgba} integer suitable for {@link java.awt.Color},
* which includes alpha component in bits 24-31. * which includes alpha component in bits 24-31.
*
* @throws IllegalArgumentException
*/ */
static int parseColorRGBA( String value ) { static int parseColorRGBA( String value )
throws IllegalArgumentException
{
int len = value.length(); int len = value.length();
if( (len != 4 && len != 5 && len != 7 && len != 9) || value.charAt( 0 ) != '#' ) if( (len != 4 && len != 5 && len != 7 && len != 9) || value.charAt( 0 ) != '#' )
throw newInvalidColorException( value ); throw newInvalidColorException( value );
@@ -760,7 +799,9 @@ class UIDefaultsLoader
return new IllegalArgumentException( "invalid color '" + value + "'" ); return new IllegalArgumentException( "invalid color '" + value + "'" );
} }
private static Object parseColorFunctions( String value, Function<String, String> resolver ) { private static Object parseColorFunctions( String value, Function<String, String> resolver )
throws IllegalArgumentException
{
int paramsStart = value.indexOf( '(' ); int paramsStart = value.indexOf( '(' );
if( paramsStart < 0 ) if( paramsStart < 0 )
throw new IllegalArgumentException( "missing opening parenthesis in function '" + value + "'" ); throw new IllegalArgumentException( "missing opening parenthesis in function '" + value + "'" );
@@ -768,7 +809,7 @@ class UIDefaultsLoader
String function = StringUtils.substringTrimmed( value, 0, paramsStart ); String function = StringUtils.substringTrimmed( value, 0, paramsStart );
List<String> params = splitFunctionParams( value.substring( paramsStart + 1, value.length() - 1 ), ',' ); List<String> params = splitFunctionParams( value.substring( paramsStart + 1, value.length() - 1 ), ',' );
if( params.isEmpty() ) if( params.isEmpty() )
throwMissingParametersException( value ); throw newMissingParametersException( value );
if( parseColorDepth > 100 ) if( parseColorDepth > 100 )
throw new IllegalArgumentException( "endless recursion in color function '" + value + "'" ); throw new IllegalArgumentException( "endless recursion in color function '" + value + "'" );
@@ -813,9 +854,11 @@ class UIDefaultsLoader
* This "if" function is only used if the "if" is passed as parameter to another * This "if" function is only used if the "if" is passed as parameter to another
* color function. Otherwise, the general "if" function is used. * color function. Otherwise, the general "if" function is used.
*/ */
private static Object parseColorIf( String value, List<String> params, Function<String, String> resolver ) { private static Object parseColorIf( String value, List<String> params, Function<String, String> resolver )
throws IllegalArgumentException
{
if( params.size() != 3 ) if( params.size() != 3 )
throwMissingParametersException( value ); throw newMissingParametersException( value );
boolean ifCondition = parseCondition( params.get( 0 ), resolver, Collections.emptyList() ); boolean ifCondition = parseCondition( params.get( 0 ), resolver, Collections.emptyList() );
String ifValue = params.get( ifCondition ? 1 : 2 ); String ifValue = params.get( ifCondition ? 1 : 2 );
@@ -827,9 +870,11 @@ class UIDefaultsLoader
* - name: system color name * - name: system color name
* - defaultValue: default color value used if system color is not available * - defaultValue: default color value used if system color is not available
*/ */
private static Object parseColorSystemColor( String value, List<String> params, Function<String, String> resolver ) { private static Object parseColorSystemColor( String value, List<String> params, Function<String, String> resolver )
throws IllegalArgumentException
{
if( params.size() < 1 ) if( params.size() < 1 )
throwMissingParametersException( value ); throw newMissingParametersException( value );
ColorUIResource systemColor = getSystemColor( params.get( 0 ) ); ColorUIResource systemColor = getSystemColor( params.get( 0 ) );
if( systemColor != null ) if( systemColor != null )
@@ -869,6 +914,7 @@ class UIDefaultsLoader
*/ */
private static ColorUIResource parseColorRgbOrRgba( boolean hasAlpha, List<String> params, private static ColorUIResource parseColorRgbOrRgba( boolean hasAlpha, List<String> params,
Function<String, String> resolver ) Function<String, String> resolver )
throws IllegalArgumentException
{ {
if( hasAlpha && params.size() == 2 ) { if( hasAlpha && params.size() == 2 ) {
// syntax rgba(color,alpha), which allows adding alpha to any color // syntax rgba(color,alpha), which allows adding alpha to any color
@@ -898,7 +944,9 @@ class UIDefaultsLoader
* - lightness: a percentage 0-100% * - lightness: a percentage 0-100%
* - alpha: a percentage 0-100% * - alpha: a percentage 0-100%
*/ */
private static ColorUIResource parseColorHslOrHsla( boolean hasAlpha, List<String> params ) { private static ColorUIResource parseColorHslOrHsla( boolean hasAlpha, List<String> params )
throws IllegalArgumentException
{
int hue = parseInteger( params.get( 0 ), 0, 360, false ); int hue = parseInteger( params.get( 0 ), 0, 360, false );
int saturation = parsePercentage( params.get( 1 ) ); int saturation = parsePercentage( params.get( 1 ) );
int lightness = parsePercentage( params.get( 2 ) ); int lightness = parsePercentage( params.get( 2 ) );
@@ -918,6 +966,7 @@ class UIDefaultsLoader
*/ */
private static Object parseColorHSLIncreaseDecrease( int hslIndex, boolean increase, private static Object parseColorHSLIncreaseDecrease( int hslIndex, boolean increase,
List<String> params, Function<String, String> resolver ) List<String> params, Function<String, String> resolver )
throws IllegalArgumentException
{ {
String colorStr = params.get( 0 ); String colorStr = params.get( 0 );
int amount = parsePercentage( params.get( 1 ) ); int amount = parsePercentage( params.get( 1 ) );
@@ -961,7 +1010,9 @@ class UIDefaultsLoader
* - amount: percentage 0-100% * - amount: percentage 0-100%
* - options: [derived] [lazy] * - options: [derived] [lazy]
*/ */
private static Object parseColorFade( List<String> params, Function<String, String> resolver ) { private static Object parseColorFade( List<String> params, Function<String, String> resolver )
throws IllegalArgumentException
{
String colorStr = params.get( 0 ); String colorStr = params.get( 0 );
int amount = parsePercentage( params.get( 1 ) ); int amount = parsePercentage( params.get( 1 ) );
boolean derived = false; boolean derived = false;
@@ -995,7 +1046,9 @@ class UIDefaultsLoader
* - angle: number of degrees to rotate * - angle: number of degrees to rotate
* - options: [derived] * - options: [derived]
*/ */
private static Object parseColorSpin( List<String> params, Function<String, String> resolver ) { private static Object parseColorSpin( List<String> params, Function<String, String> resolver )
throws IllegalArgumentException
{
String colorStr = params.get( 0 ); String colorStr = params.get( 0 );
int amount = parseInteger( params.get( 1 ) ); int amount = parseInteger( params.get( 1 ) );
boolean derived = false; boolean derived = false;
@@ -1023,6 +1076,7 @@ class UIDefaultsLoader
*/ */
private static Object parseColorChange( int hslIndex, private static Object parseColorChange( int hslIndex,
List<String> params, Function<String, String> resolver ) List<String> params, Function<String, String> resolver )
throws IllegalArgumentException
{ {
String colorStr = params.get( 0 ); String colorStr = params.get( 0 );
int value = (hslIndex == 0) int value = (hslIndex == 0)
@@ -1051,7 +1105,9 @@ class UIDefaultsLoader
* - weight: the weight (in range 0-100%) to mix the two colors * - weight: the weight (in range 0-100%) to mix the two colors
* larger weight uses more of first color, smaller weight more of second color * larger weight uses more of first color, smaller weight more of second color
*/ */
private static Object parseColorMix( String color1Str, List<String> params, Function<String, String> resolver ) { private static Object parseColorMix( String color1Str, List<String> params, Function<String, String> resolver )
throws IllegalArgumentException
{
int i = 0; int i = 0;
if( color1Str == null ) if( color1Str == null )
color1Str = params.get( i++ ); color1Str = params.get( i++ );
@@ -1078,7 +1134,9 @@ class UIDefaultsLoader
* - threshold: the threshold (in range 0-100%) to specify where the transition * - threshold: the threshold (in range 0-100%) to specify where the transition
* from "dark" to "light" is (default is 43%) * from "dark" to "light" is (default is 43%)
*/ */
private static Object parseColorContrast( List<String> params, Function<String, String> resolver ) { private static Object parseColorContrast( List<String> params, Function<String, String> resolver )
throws IllegalArgumentException
{
String colorStr = params.get( 0 ); String colorStr = params.get( 0 );
String darkStr = params.get( 1 ); String darkStr = params.get( 1 );
String lightStr = params.get( 2 ); String lightStr = params.get( 2 );
@@ -1104,7 +1162,9 @@ class UIDefaultsLoader
* the alpha of this color is used as weight to mix the two colors * the alpha of this color is used as weight to mix the two colors
* - background: a background color (e.g. #f00) or a color function * - background: a background color (e.g. #f00) or a color function
*/ */
private static ColorUIResource parseColorOver( List<String> params, Function<String, String> resolver ) { private static ColorUIResource parseColorOver( List<String> params, Function<String, String> resolver )
throws IllegalArgumentException
{
String foregroundStr = params.get( 0 ); String foregroundStr = params.get( 0 );
String backgroundStr = params.get( 1 ); String backgroundStr = params.get( 1 );
@@ -1128,6 +1188,7 @@ class UIDefaultsLoader
private static Object parseFunctionBaseColor( String colorStr, ColorFunction function, private static Object parseFunctionBaseColor( String colorStr, ColorFunction function,
boolean derived, Function<String, String> resolver ) boolean derived, Function<String, String> resolver )
throws IllegalArgumentException
{ {
// parse base color // parse base color
String resolvedColorStr = resolver.apply( colorStr ); String resolvedColorStr = resolver.apply( colorStr );
@@ -1159,7 +1220,9 @@ class UIDefaultsLoader
/** /**
* Syntax: [normal] [bold|+bold|-bold] [italic|+italic|-italic] [<size>|+<incr>|-<decr>|<percent>%] [family[, family]] [$baseFontKey] * Syntax: [normal] [bold|+bold|-bold] [italic|+italic|-italic] [<size>|+<incr>|-<decr>|<percent>%] [family[, family]] [$baseFontKey]
*/ */
private static Object parseFont( String value ) { private static Object parseFont( String value )
throws IllegalArgumentException
{
Object font = fontCache.get( value ); Object font = fontCache.get( value );
if( font != null ) if( font != null )
return font; return font;
@@ -1257,7 +1320,9 @@ class UIDefaultsLoader
return font; return font;
} }
private static int parsePercentage( String value ) { private static int parsePercentage( String value )
throws IllegalArgumentException, NumberFormatException
{
if( !value.endsWith( "%" ) ) if( !value.endsWith( "%" ) )
throw new NumberFormatException( "invalid percentage '" + value + "'" ); throw new NumberFormatException( "invalid percentage '" + value + "'" );
@@ -1273,7 +1338,9 @@ class UIDefaultsLoader
return val; return val;
} }
private static Boolean parseBoolean( String value ) { private static Boolean parseBoolean( String value )
throws IllegalArgumentException
{
switch( value ) { switch( value ) {
case "false": return false; case "false": return false;
case "true": return true; case "true": return true;
@@ -1281,13 +1348,17 @@ class UIDefaultsLoader
throw new IllegalArgumentException( "invalid boolean '" + value + "'" ); throw new IllegalArgumentException( "invalid boolean '" + value + "'" );
} }
private static Character parseCharacter( String value ) { private static Character parseCharacter( String value )
throws IllegalArgumentException
{
if( value.length() != 1 ) if( value.length() != 1 )
throw new IllegalArgumentException( "invalid character '" + value + "'" ); throw new IllegalArgumentException( "invalid character '" + value + "'" );
return value.charAt( 0 ); return value.charAt( 0 );
} }
private static Integer parseInteger( String value, int min, int max, boolean allowPercentage ) { private static Integer parseInteger( String value, int min, int max, boolean allowPercentage )
throws IllegalArgumentException, NumberFormatException
{
if( allowPercentage && value.endsWith( "%" ) ) { if( allowPercentage && value.endsWith( "%" ) ) {
int percent = parsePercentage( value ); int percent = parsePercentage( value );
return (max * percent) / 100; return (max * percent) / 100;
@@ -1299,7 +1370,9 @@ class UIDefaultsLoader
return integer; return integer;
} }
private static Integer parseInteger( String value ) { private static Integer parseInteger( String value )
throws NumberFormatException
{
try { try {
return Integer.parseInt( value ); return Integer.parseInt( value );
} catch( NumberFormatException ex ) { } catch( NumberFormatException ex ) {
@@ -1307,7 +1380,9 @@ class UIDefaultsLoader
} }
} }
private static Number parseIntegerOrFloat( String value ) { private static Number parseIntegerOrFloat( String value )
throws NumberFormatException
{
try { try {
return Integer.parseInt( value ); return Integer.parseInt( value );
} catch( NumberFormatException ex ) { } catch( NumberFormatException ex ) {
@@ -1319,7 +1394,9 @@ class UIDefaultsLoader
} }
} }
private static Float parseFloat( String value ) { private static Float parseFloat( String value )
throws NumberFormatException
{
try { try {
return Float.parseFloat( value ); return Float.parseFloat( value );
} catch( NumberFormatException ex ) { } catch( NumberFormatException ex ) {
@@ -1327,35 +1404,45 @@ class UIDefaultsLoader
} }
} }
private static ActiveValue parseScaledInteger( String value ) { private static ActiveValue parseScaledInteger( String value )
throws NumberFormatException
{
int val = parseInteger( value ); int val = parseInteger( value );
return t -> { return t -> {
return UIScale.scale( val ); return UIScale.scale( val );
}; };
} }
private static ActiveValue parseScaledFloat( String value ) { private static ActiveValue parseScaledFloat( String value )
throws NumberFormatException
{
float val = parseFloat( value ); float val = parseFloat( value );
return t -> { return t -> {
return UIScale.scale( val ); return UIScale.scale( val );
}; };
} }
private static ActiveValue parseScaledInsets( String value ) { private static ActiveValue parseScaledInsets( String value )
throws IllegalArgumentException
{
Insets insets = parseInsets( value ); Insets insets = parseInsets( value );
return t -> { return t -> {
return UIScale.scale( insets ); return UIScale.scale( insets );
}; };
} }
private static ActiveValue parseScaledDimension( String value ) { private static ActiveValue parseScaledDimension( String value )
throws IllegalArgumentException
{
Dimension dimension = parseDimension( value ); Dimension dimension = parseDimension( value );
return t -> { return t -> {
return UIScale.scale( dimension ); return UIScale.scale( dimension );
}; };
} }
private static Object parseGrayFilter( String value ) { private static Object parseGrayFilter( String value )
throws IllegalArgumentException
{
List<String> numbers = StringUtils.split( value, ',', true, false ); List<String> numbers = StringUtils.split( value, ',', true, false );
try { try {
int brightness = Integer.parseInt( numbers.get( 0 ) ); int brightness = Integer.parseInt( numbers.get( 0 ) );
@@ -1399,6 +1486,86 @@ class UIDefaultsLoader
return strs; return strs;
} }
private static Object invokeConstructorOrStaticMethod( Executable[] constructorsOrMethods,
List<String> parts, Function<String, String> resolver )
throws Exception
{
// order constructors/methods by parameter types:
// - String parameters to the end
// - int before float parameters
constructorsOrMethods = constructorsOrMethods.clone();
Arrays.sort( constructorsOrMethods, (c1, c2) -> {
Class<?>[] ptypes1 = c1.getParameterTypes();
Class<?>[] ptypes2 = c2.getParameterTypes();
if( ptypes1.length != ptypes2.length )
return ptypes1.length - ptypes2.length;
for( int i = 0; i < ptypes1.length; i++ ) {
Class<?> pt1 = ptypes1[i];
Class<?> pt2 = ptypes2[i];
if( pt1 == pt2 )
continue;
// order methods with String parameters to the end
if( pt1 == String.class )
return 2;
if( pt2 == String.class )
return -2;
// order int before float
if( pt1 == int.class )
return -1;
if( pt2 == int.class )
return 1;
}
return 0;
} );
// search for best constructor/method for given parameter values
for( Executable cm : constructorsOrMethods ) {
if( cm.getParameterCount() != parts.size() - 1 )
continue;
Object[] params = parseMethodParams( cm.getParameterTypes(), parts, resolver );
if( params == null )
continue;
// invoke constructor or static method
if( cm instanceof Constructor )
return ((Constructor<?>)cm).newInstance( params );
else
return ((Method)cm).invoke( null, params );
}
return null;
}
private static Object[] parseMethodParams( Class<?>[] paramTypes, List<String> parts, Function<String, String> resolver ) {
Object[] params = new Object[paramTypes.length];
try {
for( int i = 0; i < params.length; i++ ) {
Class<?> paramType = paramTypes[i];
String paramValue = parts.get( i + 1 );
if( paramType == String.class )
params[i] = paramValue;
else if( paramType == boolean.class )
params[i] = parseBoolean( paramValue );
else if( paramType == int.class )
params[i] = parseInteger( paramValue );
else if( paramType == float.class )
params[i] = parseFloat( paramValue );
else if( paramType == Color.class )
params[i] = parseColorOrFunction( resolver.apply( paramValue ), resolver );
else
return null; // unsupported parameter type
}
} catch( IllegalArgumentException ex ) {
return null; // failed to parse parameter for expected parameter type
}
return params;
}
/** /**
* For use in LazyValue to get value for given key from UIManager and report error * For use in LazyValue to get value for given key from UIManager and report error
* if not found. If key is prefixed by '?', then no error is reported. * if not found. If key is prefixed by '?', then no error is reported.
@@ -1416,7 +1583,7 @@ class UIDefaultsLoader
return value; return value;
} }
private static void throwMissingParametersException( String value ) { private static IllegalArgumentException newMissingParametersException( String value ) {
throw new IllegalArgumentException( "missing parameters in function '" + value + "'" ); return new IllegalArgumentException( "missing parameters in function '" + value + "'" );
} }
} }

View File

@@ -53,8 +53,8 @@ public class FlatInternalFrameCloseIcon
g.setColor( FlatButtonUI.buttonStateColor( c, c.getForeground(), null, null, hoverForeground, pressedForeground ) ); g.setColor( FlatButtonUI.buttonStateColor( c, c.getForeground(), null, null, hoverForeground, pressedForeground ) );
float mx = width / 2; float mx = width / 2f;
float my = height / 2; float my = height / 2f;
float r = 3.25f; float r = 3.25f;
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD, 4 ); Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD, 4 );

View File

@@ -94,8 +94,8 @@ public class FlatTabbedPaneCloseIcon
Color fg = FlatButtonUI.buttonStateColor( c, closeForeground, null, null, closeHoverForeground, closePressedForeground ); Color fg = FlatButtonUI.buttonStateColor( c, closeForeground, null, null, closeHoverForeground, closePressedForeground );
g.setColor( FlatUIUtils.deriveColor( fg, c.getForeground() ) ); g.setColor( FlatUIUtils.deriveColor( fg, c.getForeground() ) );
float mx = width / 2; float mx = width / 2f;
float my = height / 2; float my = height / 2f;
float r = ((bg != null) ? closeCrossFilledSize : closeCrossPlainSize) / 2; float r = ((bg != null) ? closeCrossFilledSize : closeCrossPlainSize) / 2;
// paint cross // paint cross

View File

@@ -21,7 +21,6 @@ import java.awt.Component;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.awt.RenderingHints; import java.awt.RenderingHints;
import javax.swing.UIManager;
import com.formdev.flatlaf.ui.FlatButtonUI; import com.formdev.flatlaf.ui.FlatButtonUI;
import com.formdev.flatlaf.ui.FlatUIUtils; import com.formdev.flatlaf.ui.FlatUIUtils;
import com.formdev.flatlaf.util.HiDPIUtils; import com.formdev.flatlaf.util.HiDPIUtils;
@@ -30,6 +29,7 @@ import com.formdev.flatlaf.util.HiDPIUtils;
* Base class for window icons. * Base class for window icons.
* *
* @uiDefault TitlePane.buttonSize Dimension * @uiDefault TitlePane.buttonSize Dimension
* @uiDefault TitlePane.buttonSymbolHeight int
* @uiDefault TitlePane.buttonHoverBackground Color * @uiDefault TitlePane.buttonHoverBackground Color
* @uiDefault TitlePane.buttonPressedBackground Color * @uiDefault TitlePane.buttonPressedBackground Color
* *
@@ -38,17 +38,22 @@ import com.formdev.flatlaf.util.HiDPIUtils;
public abstract class FlatWindowAbstractIcon public abstract class FlatWindowAbstractIcon
extends FlatAbstractIcon extends FlatAbstractIcon
{ {
private final int symbolHeight;
private final Color hoverBackground; private final Color hoverBackground;
private final Color pressedBackground; private final Color pressedBackground;
public FlatWindowAbstractIcon() { /** @since 3.2 */
this( UIManager.getDimension( "TitlePane.buttonSize" ), protected FlatWindowAbstractIcon( String windowStyle ) {
UIManager.getColor( "TitlePane.buttonHoverBackground" ), this( FlatUIUtils.getSubUIDimension( "TitlePane.buttonSize", windowStyle ),
UIManager.getColor( "TitlePane.buttonPressedBackground" ) ); FlatUIUtils.getSubUIInt( "TitlePane.buttonSymbolHeight", windowStyle, 10 ),
FlatUIUtils.getSubUIColor( "TitlePane.buttonHoverBackground", windowStyle ),
FlatUIUtils.getSubUIColor( "TitlePane.buttonPressedBackground", windowStyle ) );
} }
public FlatWindowAbstractIcon( Dimension size, Color hoverBackground, Color pressedBackground ) { /** @since 3.2 */
protected FlatWindowAbstractIcon( Dimension size, int symbolHeight, Color hoverBackground, Color pressedBackground ) {
super( size.width, size.height, null ); super( size.width, size.height, null );
this.symbolHeight = symbolHeight;
this.hoverBackground = hoverBackground; this.hoverBackground = hoverBackground;
this.pressedBackground = pressedBackground; this.pressedBackground = pressedBackground;
} }
@@ -80,4 +85,9 @@ public abstract class FlatWindowAbstractIcon
protected Color getForeground( Component c ) { protected Color getForeground( Component c ) {
return c.getForeground(); return c.getForeground();
} }
/** @since 3.2 */
protected int getSymbolHeight() {
return symbolHeight;
}
} }

View File

@@ -21,8 +21,8 @@ import java.awt.Color;
import java.awt.Component; import java.awt.Component;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.awt.geom.Path2D; import java.awt.geom.Path2D;
import javax.swing.UIManager;
import com.formdev.flatlaf.ui.FlatButtonUI; import com.formdev.flatlaf.ui.FlatButtonUI;
import com.formdev.flatlaf.ui.FlatUIUtils;
import com.formdev.flatlaf.util.SystemInfo; import com.formdev.flatlaf.util.SystemInfo;
/** /**
@@ -38,18 +38,27 @@ import com.formdev.flatlaf.util.SystemInfo;
public class FlatWindowCloseIcon public class FlatWindowCloseIcon
extends FlatWindowAbstractIcon extends FlatWindowAbstractIcon
{ {
private final Color hoverForeground = UIManager.getColor( "TitlePane.closeHoverForeground" ); private final Color hoverForeground;
private final Color pressedForeground = UIManager.getColor( "TitlePane.closePressedForeground" ); private final Color pressedForeground;
public FlatWindowCloseIcon() { public FlatWindowCloseIcon() {
super( UIManager.getDimension( "TitlePane.buttonSize" ), this( null );
UIManager.getColor( "TitlePane.closeHoverBackground" ), }
UIManager.getColor( "TitlePane.closePressedBackground" ) );
/** @since 3.2 */
public FlatWindowCloseIcon( String windowStyle ) {
super( FlatUIUtils.getSubUIDimension( "TitlePane.buttonSize", windowStyle ),
FlatUIUtils.getSubUIInt( "TitlePane.buttonSymbolHeight", windowStyle, 10 ),
FlatUIUtils.getSubUIColor( "TitlePane.closeHoverBackground", windowStyle ),
FlatUIUtils.getSubUIColor( "TitlePane.closePressedBackground", windowStyle ) );
hoverForeground = FlatUIUtils.getSubUIColor( "TitlePane.closeHoverForeground", windowStyle );
pressedForeground = FlatUIUtils.getSubUIColor( "TitlePane.closePressedForeground", windowStyle );
} }
@Override @Override
protected void paintIconAt1x( Graphics2D g, int x, int y, int width, int height, double scaleFactor ) { protected void paintIconAt1x( Graphics2D g, int x, int y, int width, int height, double scaleFactor ) {
int iwh = (int) (10 * scaleFactor); int iwh = (int) (getSymbolHeight() * scaleFactor);
int ix = x + ((width - iwh) / 2); int ix = x + ((width - iwh) / 2);
int iy = y + ((height - iwh) / 2); int iy = y + ((height - iwh) / 2);
int ix2 = ix + iwh - 1; int ix2 = ix + iwh - 1;

View File

@@ -27,11 +27,17 @@ public class FlatWindowIconifyIcon
extends FlatWindowAbstractIcon extends FlatWindowAbstractIcon
{ {
public FlatWindowIconifyIcon() { public FlatWindowIconifyIcon() {
this( null );
}
/** @since 3.2 */
public FlatWindowIconifyIcon( String windowStyle ) {
super( windowStyle );
} }
@Override @Override
protected void paintIconAt1x( Graphics2D g, int x, int y, int width, int height, double scaleFactor ) { protected void paintIconAt1x( Graphics2D g, int x, int y, int width, int height, double scaleFactor ) {
int iw = (int) (10 * scaleFactor); int iw = (int) (getSymbolHeight() * scaleFactor);
int ih = (int) scaleFactor; int ih = (int) scaleFactor;
int ix = x + ((width - iw) / 2); int ix = x + ((width - iw) / 2);
int iy = y + ((height - ih) / 2); int iy = y + ((height - ih) / 2);

View File

@@ -29,11 +29,17 @@ public class FlatWindowMaximizeIcon
extends FlatWindowAbstractIcon extends FlatWindowAbstractIcon
{ {
public FlatWindowMaximizeIcon() { public FlatWindowMaximizeIcon() {
this( null );
}
/** @since 3.2 */
public FlatWindowMaximizeIcon( String windowStyle ) {
super( windowStyle );
} }
@Override @Override
protected void paintIconAt1x( Graphics2D g, int x, int y, int width, int height, double scaleFactor ) { protected void paintIconAt1x( Graphics2D g, int x, int y, int width, int height, double scaleFactor ) {
int iwh = (int) (10 * scaleFactor); int iwh = (int) (getSymbolHeight() * scaleFactor);
int ix = x + ((width - iwh) / 2); int ix = x + ((width - iwh) / 2);
int iy = y + ((height - iwh) / 2); int iy = y + ((height - iwh) / 2);
float thickness = SystemInfo.isWindows_11_orLater ? (float) scaleFactor : (int) scaleFactor; float thickness = SystemInfo.isWindows_11_orLater ? (float) scaleFactor : (int) scaleFactor;

View File

@@ -32,18 +32,24 @@ public class FlatWindowRestoreIcon
extends FlatWindowAbstractIcon extends FlatWindowAbstractIcon
{ {
public FlatWindowRestoreIcon() { public FlatWindowRestoreIcon() {
this( null );
}
/** @since 3.2 */
public FlatWindowRestoreIcon( String windowStyle ) {
super( windowStyle );
} }
@Override @Override
protected void paintIconAt1x( Graphics2D g, int x, int y, int width, int height, double scaleFactor ) { protected void paintIconAt1x( Graphics2D g, int x, int y, int width, int height, double scaleFactor ) {
int iwh = (int) (10 * scaleFactor); int iwh = (int) (getSymbolHeight() * scaleFactor);
int ix = x + ((width - iwh) / 2); int ix = x + ((width - iwh) / 2);
int iy = y + ((height - iwh) / 2); int iy = y + ((height - iwh) / 2);
float thickness = SystemInfo.isWindows_11_orLater ? (float) scaleFactor : (int) scaleFactor; float thickness = SystemInfo.isWindows_11_orLater ? (float) scaleFactor : (int) scaleFactor;
int arc = Math.max( (int) (1.5 * scaleFactor), 2 ); int arc = Math.max( (int) (1.5 * scaleFactor), 2 );
int arcOuter = (int) (arc + (1.5 * scaleFactor)); int arcOuter = (int) (arc + (1.5 * scaleFactor));
int rwh = (int) (8 * scaleFactor); int rwh = (int) ((getSymbolHeight() - 2) * scaleFactor);
int ro2 = iwh - rwh; int ro2 = iwh - rwh;
// upper-right rectangle // upper-right rectangle

View File

@@ -502,9 +502,9 @@ class JsonParser {
} }
private boolean isHexDigit() { private boolean isHexDigit() {
return current >= '0' && current <= '9' return (current >= '0' && current <= '9')
|| current >= 'a' && current <= 'f' || (current >= 'a' && current <= 'f')
|| current >= 'A' && current <= 'F'; || (current >= 'A' && current <= 'F');
} }
private boolean isEndOfText() { private boolean isEndOfText() {

View File

@@ -69,7 +69,7 @@ public class Location {
if (obj == null) { if (obj == null) {
return false; return false;
} }
if (getClass() != obj.getClass()) { if (!(obj instanceof Location)) {
return false; return false;
} }
Location other = (Location)obj; Location other = (Location)obj;

View File

@@ -362,6 +362,9 @@ public class FlatButtonUI
return ((FlatHelpButtonIcon)helpButtonIcon).applyStyleProperty( key, value ); return ((FlatHelpButtonIcon)helpButtonIcon).applyStyleProperty( key, value );
} }
if( "iconTextGap".equals( key ) && value instanceof Integer )
value = UIScale.scale( (Integer) value );
if( borderShared == null ) if( borderShared == null )
borderShared = new AtomicBoolean( true ); borderShared = new AtomicBoolean( true );
return FlatStylingSupport.applyToAnnotatedObjectOrBorder( this, key, value, b, borderShared ); return FlatStylingSupport.applyToAnnotatedObjectOrBorder( this, key, value, b, borderShared );

View File

@@ -256,10 +256,14 @@ public class FlatCaret
// select all // select all
if( c instanceof JFormattedTextField ) { if( c instanceof JFormattedTextField ) {
EventQueue.invokeLater( () -> { EventQueue.invokeLater( () -> {
if( getComponent() == null ) // Warning: do not use variables from outside of this runnable
// because they may be out-of-date when this runnable is executed
JTextComponent c2 = getComponent();
if( c2 == null )
return; // was deinstalled return; // was deinstalled
select( 0, doc.getLength() ); select( 0, c2.getDocument().getLength() );
} ); } );
} else { } else {
select( 0, doc.getLength() ); select( 0, doc.getLength() );

View File

@@ -24,6 +24,7 @@ import java.awt.Component;
import java.awt.ComponentOrientation; import java.awt.ComponentOrientation;
import java.awt.Container; import java.awt.Container;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FontMetrics; import java.awt.FontMetrics;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.Graphics2D; import java.awt.Graphics2D;
@@ -48,10 +49,12 @@ import java.util.concurrent.atomic.AtomicBoolean;
import javax.swing.AbstractAction; import javax.swing.AbstractAction;
import javax.swing.BorderFactory; import javax.swing.BorderFactory;
import javax.swing.CellRendererPane; import javax.swing.CellRendererPane;
import javax.swing.ComboBoxModel;
import javax.swing.DefaultListCellRenderer; import javax.swing.DefaultListCellRenderer;
import javax.swing.InputMap; import javax.swing.InputMap;
import javax.swing.JButton; import javax.swing.JButton;
import javax.swing.JComboBox; import javax.swing.JComboBox;
import javax.swing.JComboBox.KeySelectionManager;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.JList; import javax.swing.JList;
import javax.swing.JPanel; import javax.swing.JPanel;
@@ -102,7 +105,6 @@ import com.formdev.flatlaf.util.SystemInfo;
* @uiDefault ComboBox.maximumRowCount int * @uiDefault ComboBox.maximumRowCount int
* @uiDefault ComboBox.buttonStyle String auto (default), button, mac or none * @uiDefault ComboBox.buttonStyle String auto (default), button, mac or none
* @uiDefault Component.arrowType String chevron (default) or triangle * @uiDefault Component.arrowType String chevron (default) or triangle
* @uiDefault Component.isIntelliJTheme boolean
* @uiDefault ComboBox.editableBackground Color optional; defaults to ComboBox.background * @uiDefault ComboBox.editableBackground Color optional; defaults to ComboBox.background
* @uiDefault ComboBox.focusedBackground Color optional * @uiDefault ComboBox.focusedBackground Color optional
* @uiDefault ComboBox.disabledBackground Color * @uiDefault ComboBox.disabledBackground Color
@@ -134,7 +136,6 @@ public class FlatComboBoxUI
@Styleable protected int editorColumns; @Styleable protected int editorColumns;
@Styleable protected String buttonStyle; @Styleable protected String buttonStyle;
@Styleable protected String arrowType; @Styleable protected String arrowType;
protected boolean isIntelliJTheme;
private Color background; private Color background;
@Styleable protected Color editableBackground; @Styleable protected Color editableBackground;
@@ -182,6 +183,9 @@ public class FlatComboBoxUI
private void installUIImpl( JComponent c ) { private void installUIImpl( JComponent c ) {
super.installUI( c ); super.installUI( c );
// install key selection manager that shows popup when Space key is pressed
comboBox.setKeySelectionManager( new FlatKeySelectionManager( comboBox.getKeySelectionManager() ) );
installStyle(); installStyle();
} }
@@ -240,7 +244,6 @@ public class FlatComboBoxUI
editorColumns = UIManager.getInt( "ComboBox.editorColumns" ); editorColumns = UIManager.getInt( "ComboBox.editorColumns" );
buttonStyle = UIManager.getString( "ComboBox.buttonStyle" ); buttonStyle = UIManager.getString( "ComboBox.buttonStyle" );
arrowType = UIManager.getString( "Component.arrowType" ); arrowType = UIManager.getString( "Component.arrowType" );
isIntelliJTheme = UIManager.getBoolean( "Component.isIntelliJTheme" );
background = UIManager.getColor( "ComboBox.background" ); background = UIManager.getColor( "ComboBox.background" );
editableBackground = UIManager.getColor( "ComboBox.editableBackground" ); editableBackground = UIManager.getColor( "ComboBox.editableBackground" );
@@ -679,7 +682,7 @@ public class FlatComboBoxUI
return (editableBackground != null && comboBox.isEditable()) ? editableBackground : background; return (editableBackground != null && comboBox.isEditable()) ? editableBackground : background;
} else } else
return isIntelliJTheme ? FlatUIUtils.getParentBackground( comboBox ) : disabledBackground; return disabledBackground;
} }
protected Color getForeground( boolean enabled ) { protected Color getForeground( boolean enabled ) {
@@ -986,6 +989,29 @@ public class FlatComboBoxUI
} }
} }
// improve location of selected item in popup if list is large and scrollable
if( list.getHeight() == 0 ) {
// If popup is shown for the first time (or after a laf switch) and is scrollable,
// then BasicComboPopup scrolls the selected item to the top of the visible area.
// But for usability it would be better to have selected item somewhere
// in the middle of the visible area so that the user can see items above
// the selected item, which are usually more "important".
int selectedIndex = list.getSelectedIndex();
if( selectedIndex >= 1 ) {
int maximumRowCount = comboBox.getMaximumRowCount();
if( selectedIndex < maximumRowCount ) {
// selected item is in the first visible items --> scroll to top
list.scrollRectToVisible( new Rectangle() );
} else {
// scroll the selected item to the middle of the visible area
int firstVisibleIndex = Math.max( selectedIndex - (maximumRowCount / 2), 0 );
if( firstVisibleIndex > 0 )
list.ensureIndexIsVisible( firstVisibleIndex );
}
}
}
super.show( invoker, x, y ); super.show( invoker, x, y );
} }
@@ -1209,4 +1235,46 @@ public class FlatComboBoxUI
} }
} }
} }
//---- class FlatKeySelectionManager --------------------------------------
/**
* Key selection manager that delegates to the default manager.
* Shows the popup if Space key is pressed and "typed characters" buffer is empty.
* If items contain spaces (e.g. "a b") it is still possible to select them
* by pressing keys a, Space and b.
*/
private class FlatKeySelectionManager
implements JComboBox.KeySelectionManager, UIResource
{
private final KeySelectionManager delegate;
private final long timeFactor;
private long lastTime;
FlatKeySelectionManager( JComboBox.KeySelectionManager delegate ) {
this.delegate = delegate;
Long value = (Long) UIManager.get( "ComboBox.timeFactor" );
timeFactor = (value != null) ? value : 1000;
}
@SuppressWarnings( "rawtypes" )
@Override
public int selectionForKey( char aKey, ComboBoxModel aModel ) {
long time = EventQueue.getMostRecentEventTime();
long oldLastTime = lastTime;
lastTime = time;
// SPACE key shows popup if not yet visible
if( aKey == ' ' &&
time - oldLastTime >= timeFactor &&
!comboBox.isPopupVisible() )
{
comboBox.setPopupVisible( true );
return -1;
}
return delegate.selectionForKey( aKey, aModel );
}
}
} }

View File

@@ -59,7 +59,6 @@ import com.formdev.flatlaf.util.LoggingFacade;
* <!-- FlatEditorPaneUI --> * <!-- FlatEditorPaneUI -->
* *
* @uiDefault Component.minimumWidth int * @uiDefault Component.minimumWidth int
* @uiDefault Component.isIntelliJTheme boolean
* @uiDefault EditorPane.focusedBackground Color optional * @uiDefault EditorPane.focusedBackground Color optional
* *
* @author Karl Tauber * @author Karl Tauber
@@ -69,7 +68,6 @@ public class FlatEditorPaneUI
implements StyleableUI implements StyleableUI
{ {
@Styleable protected int minimumWidth; @Styleable protected int minimumWidth;
protected boolean isIntelliJTheme;
private Color background; private Color background;
@Styleable protected Color disabledBackground; @Styleable protected Color disabledBackground;
@Styleable protected Color inactiveBackground; @Styleable protected Color inactiveBackground;
@@ -101,7 +99,6 @@ public class FlatEditorPaneUI
String prefix = getPropertyPrefix(); String prefix = getPropertyPrefix();
minimumWidth = UIManager.getInt( "Component.minimumWidth" ); minimumWidth = UIManager.getInt( "Component.minimumWidth" );
isIntelliJTheme = UIManager.getBoolean( "Component.isIntelliJTheme" );
background = UIManager.getColor( prefix + ".background" ); background = UIManager.getColor( prefix + ".background" );
disabledBackground = UIManager.getColor( prefix + ".disabledBackground" ); disabledBackground = UIManager.getColor( prefix + ".disabledBackground" );
inactiveBackground = UIManager.getColor( prefix + ".inactiveBackground" ); inactiveBackground = UIManager.getColor( prefix + ".inactiveBackground" );
@@ -252,11 +249,11 @@ public class FlatEditorPaneUI
@Override @Override
protected void paintBackground( Graphics g ) { protected void paintBackground( Graphics g ) {
paintBackground( g, getComponent(), isIntelliJTheme, focusedBackground ); paintBackground( g, getComponent(), focusedBackground );
} }
static void paintBackground( Graphics g, JTextComponent c, boolean isIntelliJTheme, Color focusedBackground ) { static void paintBackground( Graphics g, JTextComponent c, Color focusedBackground ) {
g.setColor( FlatTextFieldUI.getBackground( c, isIntelliJTheme, focusedBackground ) ); g.setColor( FlatTextFieldUI.getBackground( c, focusedBackground ) );
g.fillRect( 0, 0, c.getWidth(), c.getHeight() ); g.fillRect( 0, 0, c.getWidth(), c.getHeight() );
} }
} }

View File

@@ -53,6 +53,7 @@ import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.metal.MetalFileChooserUI; import javax.swing.plaf.metal.MetalFileChooserUI;
import javax.swing.table.TableCellRenderer; import javax.swing.table.TableCellRenderer;
import com.formdev.flatlaf.FlatClientProperties; import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.icons.FlatFileViewDirectoryIcon;
import com.formdev.flatlaf.util.LoggingFacade; import com.formdev.flatlaf.util.LoggingFacade;
import com.formdev.flatlaf.util.ScaledImageIcon; import com.formdev.flatlaf.util.ScaledImageIcon;
import com.formdev.flatlaf.util.SystemInfo; import com.formdev.flatlaf.util.SystemInfo;
@@ -346,12 +347,12 @@ public class FlatFileChooserUI
fileView.clearIconCache(); fileView.clearIconCache();
} }
private boolean doNotUseSystemIcons() { private static boolean doNotUseSystemIcons() {
// Java 17 32bit craches on Windows when using system icons // Java 17 32bit craches on Windows when using system icons
// fixed in Java 18+ (see https://bugs.openjdk.java.net/browse/JDK-8277299) // fixed in Java 18+, fix backported in Java 17.0.3+ (see https://bugs.openjdk.java.net/browse/JDK-8277299)
return SystemInfo.isWindows && return SystemInfo.isWindows &&
SystemInfo.isX86 && SystemInfo.isX86 &&
(SystemInfo.isJava_17_orLater && !SystemInfo.isJava_18_orLater); (SystemInfo.isJava_17_orLater && SystemInfo.javaVersion < SystemInfo.toVersion( 17, 0, 3, 0 ));
} }
//---- class FlatFileView ------------------------------------------------- //---- class FlatFileView -------------------------------------------------
@@ -526,6 +527,9 @@ public class FlatFileChooserUI
return icon; return icon;
} }
if( doNotUseSystemIcons() )
return new FlatFileViewDirectoryIcon();
// Java 17+ supports getting larger system icons // Java 17+ supports getting larger system icons
try { try {
if( SystemInfo.isJava_17_orLater ) { if( SystemInfo.isJava_17_orLater ) {

View File

@@ -40,7 +40,6 @@ import javax.swing.plaf.ComponentUI;
* <!-- FlatTextFieldUI --> * <!-- FlatTextFieldUI -->
* *
* @uiDefault Component.minimumWidth int * @uiDefault Component.minimumWidth int
* @uiDefault Component.isIntelliJTheme boolean
* @uiDefault FormattedTextField.placeholderForeground Color * @uiDefault FormattedTextField.placeholderForeground Color
* @uiDefault FormattedTextField.focusedBackground Color optional * @uiDefault FormattedTextField.focusedBackground Color optional
* @uiDefault FormattedTextField.iconTextGap int optional, default is 4 * @uiDefault FormattedTextField.iconTextGap int optional, default is 4

View File

@@ -24,6 +24,7 @@ import java.awt.Rectangle;
import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeEvent;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import javax.swing.Icon; import javax.swing.Icon;
@@ -179,7 +180,7 @@ public class FlatLabelUI
// BASE_SIZE rule is parsed in javax.swing.text.html.StyleSheet.addRule() // BASE_SIZE rule is parsed in javax.swing.text.html.StyleSheet.addRule()
String style = "<style>BASE_SIZE " + c.getFont().getSize() + "</style>"; String style = "<style>BASE_SIZE " + c.getFont().getSize() + "</style>";
String lowerText = text.toLowerCase(); String lowerText = text.toLowerCase( Locale.ENGLISH );
int headIndex; int headIndex;
int styleIndex; int styleIndex;
@@ -228,7 +229,7 @@ public class FlatLabelUI
int tagBegin = i + 1; int tagBegin = i + 1;
for( i += 2; i < textLength; i++ ) { for( i += 2; i < textLength; i++ ) {
if( !Character.isLetterOrDigit( text.charAt( i ) ) ) { if( !Character.isLetterOrDigit( text.charAt( i ) ) ) {
String tag = text.substring( tagBegin, i ).toLowerCase(); String tag = text.substring( tagBegin, i ).toLowerCase( Locale.ENGLISH );
if( tagsUseFontSizeSet.contains( tag ) ) if( tagsUseFontSizeSet.contains( tag ) )
return true; return true;

View File

@@ -33,6 +33,7 @@ import com.formdev.flatlaf.util.SystemInfo;
*/ */
class FlatNativeLibrary class FlatNativeLibrary
{ {
private static boolean initialized;
private static NativeLibrary nativeLibrary; private static NativeLibrary nativeLibrary;
/** /**
@@ -45,24 +46,41 @@ class FlatNativeLibrary
} }
private static void initialize() { private static void initialize() {
if( nativeLibrary != null ) if( initialized )
return;
initialized = true;
if( !FlatSystemProperties.getBoolean( FlatSystemProperties.USE_NATIVE_LIBRARY, true ) )
return; return;
String classifier; String classifier;
String ext; String ext;
if( SystemInfo.isWindows_10_orLater && (SystemInfo.isX86 || SystemInfo.isX86_64) ) { if( SystemInfo.isWindows_10_orLater && (SystemInfo.isX86 || SystemInfo.isX86_64 || SystemInfo.isAARCH64) ) {
// Windows: requires Windows 10/11 (x86 or x86_64) // Windows: requires Windows 10/11 (x86, x86_64 or aarch64)
if( SystemInfo.isAARCH64 )
classifier = "windows-arm64";
else if( SystemInfo.isX86_64 )
classifier = "windows-x86_64";
else
classifier = "windows-x86";
classifier = SystemInfo.isX86_64 ? "windows-x86_64" : "windows-x86";
ext = "dll"; ext = "dll";
// In Java 8, load jawt.dll (part of JRE) explicitly because it // Do not load jawt.dll (part of JRE) here explicitly because
// is not found when running application with <jdk>/bin/java.exe. // the FlatLaf native library flatlaf.dll may be loaded very early on Windows
// When using <jdk>/jre/bin/java.exe, it is found. // (e.g. from class com.formdev.flatlaf.util.SystemInfo) and before AWT is
// jawt.dll is located in <jdk>/jre/bin/. // initialized (and awt.dll is loaded). Loading jawt.dll also loads awt.dll.
// Java 9 and later do not have this problem, // In Java 8, loading jawt.dll before AWT is initialized may load
// but load jawt.dll anyway to be on the safe side. // a wrong version of awt.dll if a newer Java version (e.g. 19)
loadJAWT(); // is in PATH environment variable. Then Java 19 awt.dll and Java 8 awt.dll
// are loaded at same time and calling JAWT_GetAWT() crashes the application.
//
// To avoid this, flatlaf.dll is not linked to jawt.dll,
// which avoids loading jawt.dll when flatlaf.dll is loaded.
// Instead flatlaf.dll dynamically loads jawt.dll when first used,
// which is guaranteed after AWT initialization.
} else if( SystemInfo.isLinux && SystemInfo.isX86_64 ) { } else if( SystemInfo.isLinux && SystemInfo.isX86_64 ) {
// Linux: requires x86_64 // Linux: requires x86_64

View File

@@ -66,7 +66,6 @@ import com.formdev.flatlaf.util.UIScale;
* <!-- FlatTextFieldUI --> * <!-- FlatTextFieldUI -->
* *
* @uiDefault Component.minimumWidth int * @uiDefault Component.minimumWidth int
* @uiDefault Component.isIntelliJTheme boolean
* @uiDefault PasswordField.placeholderForeground Color * @uiDefault PasswordField.placeholderForeground Color
* @uiDefault PasswordField.focusedBackground Color optional * @uiDefault PasswordField.focusedBackground Color optional
* @uiDefault PasswordField.iconTextGap int optional, default is 4 * @uiDefault PasswordField.iconTextGap int optional, default is 4

View File

@@ -391,7 +391,7 @@ public class FlatPopupFactory
//---- class NonFlashingPopup --------------------------------------------- //---- class NonFlashingPopup ---------------------------------------------
private class NonFlashingPopup private static class NonFlashingPopup
extends Popup extends Popup
{ {
private Popup delegate; private Popup delegate;

View File

@@ -193,27 +193,38 @@ public class FlatPopupMenuUI
@Override @Override
public Popup getPopup( JPopupMenu popup, int x, int y ) { public Popup getPopup( JPopupMenu popup, int x, int y ) {
Dimension popupSize = popup.getPreferredSize();
Rectangle screenBounds = getScreenBoundsAt( x, y );
// make sure that popup does not overlap any task/side bar
if( x + popupSize.width > screenBounds.x + screenBounds.width )
x = screenBounds.x + screenBounds.width - popupSize.width;
if( y + popupSize.height > screenBounds.y + screenBounds.height )
y = screenBounds.y + screenBounds.height - popupSize.height;
if( x < screenBounds.x )
x = screenBounds.x;
if( y < screenBounds.y )
y = screenBounds.y;
// do not add scroller to combobox popups or to popups that already have a scroll pane // do not add scroller to combobox popups or to popups that already have a scroll pane
if( popup instanceof BasicComboPopup || if( popup instanceof BasicComboPopup ||
(popup.getComponentCount() > 0 && popup.getComponent( 0 ) instanceof JScrollPane) ) (popup.getComponentCount() > 0 && popup.getComponent( 0 ) instanceof JScrollPane) )
return super.getPopup( popup, x, y ); return super.getPopup( popup, x, y );
// do not add scroller if popup fits into screen // do not add scroller if popup fits into screen
Dimension prefSize = popup.getPreferredSize(); if( popupSize.height <= screenBounds.height )
int screenHeight = getScreenHeightAt( x, y );
if( prefSize.height <= screenHeight )
return super.getPopup( popup, x, y ); return super.getPopup( popup, x, y );
// create scroller // create scroller
FlatPopupScroller scroller = new FlatPopupScroller( popup ); FlatPopupScroller scroller = new FlatPopupScroller( popup );
scroller.setPreferredSize( new Dimension( prefSize.width, screenHeight ) ); scroller.setPreferredSize( new Dimension( popupSize.width, screenBounds.height ) );
// create popup // create popup
PopupFactory popupFactory = PopupFactory.getSharedInstance(); PopupFactory popupFactory = PopupFactory.getSharedInstance();
return popupFactory.getPopup( popup.getInvoker(), scroller, x, y ); return popupFactory.getPopup( popup.getInvoker(), scroller, x, y );
} }
private int getScreenHeightAt( int x, int y ) { private Rectangle getScreenBoundsAt( int x, int y ) {
// find GraphicsConfiguration at popup location (similar to JPopupMenu.getCurrentGraphicsConfiguration()) // find GraphicsConfiguration at popup location (similar to JPopupMenu.getCurrentGraphicsConfiguration())
GraphicsConfiguration gc = null; GraphicsConfiguration gc = null;
for( GraphicsDevice device : GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices() ) { for( GraphicsDevice device : GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices() ) {
@@ -234,7 +245,7 @@ public class FlatPopupMenuUI
Toolkit toolkit = Toolkit.getDefaultToolkit(); Toolkit toolkit = Toolkit.getDefaultToolkit();
Rectangle screenBounds = (gc != null) ? gc.getBounds() : new Rectangle( toolkit.getScreenSize() ); Rectangle screenBounds = (gc != null) ? gc.getBounds() : new Rectangle( toolkit.getScreenSize() );
Insets screenInsets = Toolkit.getDefaultToolkit().getScreenInsets( gc ); Insets screenInsets = Toolkit.getDefaultToolkit().getScreenInsets( gc );
return screenBounds.height - screenInsets.top - screenInsets.bottom; return FlatUIUtils.subtractInsets( screenBounds, screenInsets );
} }
//---- class FlatPopupMenuLayout ------------------------------------------ //---- class FlatPopupMenuLayout ------------------------------------------

View File

@@ -208,6 +208,9 @@ public class FlatRadioButtonUI
return ((FlatCheckBoxIcon)icon).applyStyleProperty( key, value ); return ((FlatCheckBoxIcon)icon).applyStyleProperty( key, value );
} }
if( "iconTextGap".equals( key ) && value instanceof Integer )
value = UIScale.scale( (Integer) value );
return FlatStylingSupport.applyToAnnotatedObjectOrComponent( this, b, key, value ); return FlatStylingSupport.applyToAnnotatedObjectOrComponent( this, b, key, value );
} }

View File

@@ -23,6 +23,7 @@ import java.awt.Dimension;
import java.awt.Frame; import java.awt.Frame;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.awt.IllegalComponentStateException;
import java.awt.Insets; import java.awt.Insets;
import java.awt.LayoutManager; import java.awt.LayoutManager;
import java.awt.LayoutManager2; import java.awt.LayoutManager2;
@@ -366,6 +367,11 @@ public class FlatRootPaneUI
case FlatClientProperties.GLASS_PANE_FULL_HEIGHT: case FlatClientProperties.GLASS_PANE_FULL_HEIGHT:
rootPane.revalidate(); rootPane.revalidate();
break; break;
case FlatClientProperties.WINDOW_STYLE:
if( rootPane.isDisplayable() )
throw new IllegalComponentStateException( "The client property 'Window.style' must be set before the window becomes displayable." );
break;
} }
} }

View File

@@ -360,8 +360,8 @@ public class FlatScrollPaneUI
protected void updateViewport( PropertyChangeEvent e ) { protected void updateViewport( PropertyChangeEvent e ) {
super.updateViewport( e ); super.updateViewport( e );
JViewport oldViewport = (JViewport) (e.getOldValue()); JViewport oldViewport = (JViewport) e.getOldValue();
JViewport newViewport = (JViewport) (e.getNewValue()); JViewport newViewport = (JViewport) e.getNewValue();
removeViewportListeners( oldViewport ); removeViewportListeners( oldViewport );
addViewportListeners( newViewport ); addViewportListeners( newViewport );

View File

@@ -67,7 +67,6 @@ import com.formdev.flatlaf.util.LoggingFacade;
* @uiDefault Component.minimumWidth int * @uiDefault Component.minimumWidth int
* @uiDefault Spinner.buttonStyle String button (default), mac or none * @uiDefault Spinner.buttonStyle String button (default), mac or none
* @uiDefault Component.arrowType String chevron (default) or triangle * @uiDefault Component.arrowType String chevron (default) or triangle
* @uiDefault Component.isIntelliJTheme boolean
* @uiDefault Spinner.disabledBackground Color * @uiDefault Spinner.disabledBackground Color
* @uiDefault Spinner.disabledForeground Color * @uiDefault Spinner.disabledForeground Color
* @uiDefault Spinner.focusedBackground Color optional * @uiDefault Spinner.focusedBackground Color optional
@@ -92,7 +91,6 @@ public class FlatSpinnerUI
@Styleable protected int minimumWidth; @Styleable protected int minimumWidth;
@Styleable protected String buttonStyle; @Styleable protected String buttonStyle;
@Styleable protected String arrowType; @Styleable protected String arrowType;
protected boolean isIntelliJTheme;
@Styleable protected Color disabledBackground; @Styleable protected Color disabledBackground;
@Styleable protected Color disabledForeground; @Styleable protected Color disabledForeground;
@Styleable protected Color focusedBackground; @Styleable protected Color focusedBackground;
@@ -129,7 +127,6 @@ public class FlatSpinnerUI
minimumWidth = UIManager.getInt( "Component.minimumWidth" ); minimumWidth = UIManager.getInt( "Component.minimumWidth" );
buttonStyle = UIManager.getString( "Spinner.buttonStyle" ); buttonStyle = UIManager.getString( "Spinner.buttonStyle" );
arrowType = UIManager.getString( "Component.arrowType" ); arrowType = UIManager.getString( "Component.arrowType" );
isIntelliJTheme = UIManager.getBoolean( "Component.isIntelliJTheme" );
disabledBackground = UIManager.getColor( "Spinner.disabledBackground" ); disabledBackground = UIManager.getColor( "Spinner.disabledBackground" );
disabledForeground = UIManager.getColor( "Spinner.disabledForeground" ); disabledForeground = UIManager.getColor( "Spinner.disabledForeground" );
focusedBackground = UIManager.getColor( "Spinner.focusedBackground" ); focusedBackground = UIManager.getColor( "Spinner.focusedBackground" );
@@ -316,7 +313,7 @@ public class FlatSpinnerUI
return background; return background;
} else } else
return isIntelliJTheme ? FlatUIUtils.getParentBackground( spinner ) : disabledBackground; return disabledBackground;
} }
protected Color getForeground( boolean enabled ) { protected Color getForeground( boolean enabled ) {

View File

@@ -87,7 +87,6 @@ public class FlatSplitPaneUI
@Styleable protected Color oneTouchHoverArrowColor; @Styleable protected Color oneTouchHoverArrowColor;
@Styleable protected Color oneTouchPressedArrowColor; @Styleable protected Color oneTouchPressedArrowColor;
private PropertyChangeListener propertyChangeListener;
private Map<String, Object> oldStyleValues; private Map<String, Object> oldStyleValues;
public static ComponentUI createUI( JComponent c ) { public static ComponentUI createUI( JComponent c ) {
@@ -126,19 +125,9 @@ public class FlatSplitPaneUI
} }
@Override @Override
protected void installListeners() { protected PropertyChangeListener createPropertyChangeListener() {
super.installListeners(); return FlatStylingSupport.createPropertyChangeListener( splitPane, this::installStyle,
super.createPropertyChangeListener() );
propertyChangeListener = FlatStylingSupport.createPropertyChangeListener( splitPane, this::installStyle, null );
splitPane.addPropertyChangeListener( propertyChangeListener );
}
@Override
protected void uninstallListeners() {
super.uninstallListeners();
splitPane.removePropertyChangeListener( propertyChangeListener );
propertyChangeListener = null;
} }
@Override @Override

View File

@@ -100,15 +100,15 @@ public class FlatStylingSupport
/** @since 2 */ /** @since 2 */
public interface StyleableUI { public interface StyleableUI {
Map<String, Class<?>> getStyleableInfos( JComponent c ); Map<String, Class<?>> getStyleableInfos( JComponent c ) throws IllegalArgumentException;
/** @since 2.5 */ Object getStyleableValue( JComponent c, String key ); /** @since 2.5 */ Object getStyleableValue( JComponent c, String key ) throws IllegalArgumentException;
} }
/** @since 2 */ /** @since 2 */
public interface StyleableBorder { public interface StyleableBorder {
Object applyStyleProperty( String key, Object value ); Object applyStyleProperty( String key, Object value );
Map<String, Class<?>> getStyleableInfos(); Map<String, Class<?>> getStyleableInfos() throws IllegalArgumentException;
/** @since 2.5 */ Object getStyleableValue( String key ); /** @since 2.5 */ Object getStyleableValue( String key ) throws IllegalArgumentException;
} }
/** @since 2.5 */ /** @since 2.5 */
@@ -135,7 +135,9 @@ public class FlatStylingSupport
return getStyle( c ) != null || getStyleClass( c ) != null; return getStyle( c ) != null || getStyleClass( c ) != null;
} }
public static Object getResolvedStyle( JComponent c, String type ) { public static Object getResolvedStyle( JComponent c, String type )
throws IllegalArgumentException
{
Object style = getStyle( c ); Object style = getStyle( c );
Object styleClass = getStyleClass( c ); Object styleClass = getStyleClass( c );
Object styleForClasses = getStyleForClasses( styleClass, type ); Object styleForClasses = getStyleForClasses( styleClass, type );
@@ -175,7 +177,9 @@ public class FlatStylingSupport
* @param type the type of the component * @param type the type of the component
* @return the styles * @return the styles
*/ */
public static Object getStyleForClasses( Object styleClass, String type ) { public static Object getStyleForClasses( Object styleClass, String type )
throws IllegalArgumentException
{
if( styleClass == null ) if( styleClass == null )
return null; return null;
@@ -198,7 +202,9 @@ public class FlatStylingSupport
return null; return null;
} }
private static Object getStyleForClass( String styleClass, String type ) { private static Object getStyleForClass( String styleClass, String type )
throws IllegalArgumentException
{
return joinStyles( return joinStyles(
UIManager.get( "[style]." + styleClass ), UIManager.get( "[style]." + styleClass ),
UIManager.get( "[style]" + type + '.' + styleClass ) ); UIManager.get( "[style]" + type + '.' + styleClass ) );
@@ -218,7 +224,9 @@ public class FlatStylingSupport
* @return new joined style * @return new joined style
*/ */
@SuppressWarnings( "unchecked" ) @SuppressWarnings( "unchecked" )
public static Object joinStyles( Object style1, Object style2 ) { public static Object joinStyles( Object style1, Object style2 )
throws IllegalArgumentException
{
if( style1 == null ) if( style1 == null )
return style2; return style2;
if( style2 == null ) if( style2 == null )
@@ -278,6 +286,7 @@ public class FlatStylingSupport
* @throws IllegalArgumentException on syntax errors * @throws IllegalArgumentException on syntax errors
* @throws ClassCastException if value type does not fit to expected type * @throws ClassCastException if value type does not fit to expected type
*/ */
@SuppressWarnings( "ReturnValueIgnored" ) // Error Prone
public static Map<String, Object> parseAndApply( Map<String, Object> oldStyleValues, public static Map<String, Object> parseAndApply( Map<String, Object> oldStyleValues,
Object style, BiFunction<String, Object, Object> applyProperty ) Object style, BiFunction<String, Object, Object> applyProperty )
throws UnknownStyleException, IllegalArgumentException throws UnknownStyleException, IllegalArgumentException
@@ -379,7 +388,9 @@ public class FlatStylingSupport
return map; return map;
} }
private static Object parseValue( String key, String value ) { private static Object parseValue( String key, String value )
throws IllegalArgumentException
{
// simple reference // simple reference
if( value.startsWith( "$" ) ) if( value.startsWith( "$" ) )
return UIManager.get( value.substring( 1 ) ); return UIManager.get( value.substring( 1 ) );
@@ -474,7 +485,9 @@ public class FlatStylingSupport
} }
} }
private static Object applyToField( Field f, Object obj, Object value, boolean useMethodHandles ) { private static Object applyToField( Field f, Object obj, Object value, boolean useMethodHandles )
throws IllegalArgumentException
{
checkValidField( f ); checkValidField( f );
if( useMethodHandles && obj instanceof StyleableLookupProvider ) { if( useMethodHandles && obj instanceof StyleableLookupProvider ) {
@@ -504,7 +517,9 @@ public class FlatStylingSupport
} }
} }
private static Object getFieldValue( Field f, Object obj, boolean useMethodHandles ) { private static Object getFieldValue( Field f, Object obj, boolean useMethodHandles )
throws IllegalArgumentException
{
checkValidField( f ); checkValidField( f );
if( useMethodHandles && obj instanceof StyleableLookupProvider ) { if( useMethodHandles && obj instanceof StyleableLookupProvider ) {
@@ -529,7 +544,9 @@ public class FlatStylingSupport
return new IllegalArgumentException( "failed to access field '" + f.getDeclaringClass().getName() + "." + f.getName() + "'", ex ); return new IllegalArgumentException( "failed to access field '" + f.getDeclaringClass().getName() + "." + f.getName() + "'", ex );
} }
private static void checkValidField( Field f ) { private static void checkValidField( Field f )
throws IllegalArgumentException
{
if( !isValidField( f ) ) if( !isValidField( f ) )
throw new IllegalArgumentException( "field '" + f.getDeclaringClass().getName() + "." + f.getName() + "' is final or static" ); throw new IllegalArgumentException( "field '" + f.getDeclaringClass().getName() + "." + f.getName() + "' is final or static" );
} }
@@ -539,7 +556,9 @@ public class FlatStylingSupport
return (modifiers & (Modifier.FINAL|Modifier.STATIC)) == 0 && !f.isSynthetic(); return (modifiers & (Modifier.FINAL|Modifier.STATIC)) == 0 && !f.isSynthetic();
} }
private static Field getStyleableField( StyleableField styleableField ) { private static Field getStyleableField( StyleableField styleableField )
throws IllegalArgumentException
{
String fieldName = styleableField.fieldName(); String fieldName = styleableField.fieldName();
if( fieldName.isEmpty() ) if( fieldName.isEmpty() )
fieldName = styleableField.key(); fieldName = styleableField.key();
@@ -647,6 +666,7 @@ public class FlatStylingSupport
static Object applyToAnnotatedObjectOrBorder( Object obj, String key, Object value, static Object applyToAnnotatedObjectOrBorder( Object obj, String key, Object value,
JComponent c, AtomicBoolean borderShared ) JComponent c, AtomicBoolean borderShared )
throws IllegalArgumentException
{ {
try { try {
return applyToAnnotatedObject( obj, key, value ); return applyToAnnotatedObject( obj, key, value );
@@ -695,7 +715,9 @@ public class FlatStylingSupport
}; };
} }
static Border cloneBorder( Border border ) { static Border cloneBorder( Border border )
throws IllegalArgumentException
{
Class<? extends Border> borderClass = border.getClass(); Class<? extends Border> borderClass = border.getClass();
try { try {
return borderClass.getDeclaredConstructor().newInstance(); return borderClass.getDeclaredConstructor().newInstance();
@@ -704,7 +726,9 @@ public class FlatStylingSupport
} }
} }
static Icon cloneIcon( Icon icon ) { static Icon cloneIcon( Icon icon )
throws IllegalArgumentException
{
Class<? extends Icon> iconClass = icon.getClass(); Class<? extends Icon> iconClass = icon.getClass();
try { try {
return iconClass.getDeclaredConstructor().newInstance(); return iconClass.getDeclaredConstructor().newInstance();
@@ -717,11 +741,15 @@ public class FlatStylingSupport
* Returns a map of all fields annotated with {@link Styleable}. * Returns a map of all fields annotated with {@link Styleable}.
* The key is the name of the field and the value the type of the field. * The key is the name of the field and the value the type of the field.
*/ */
public static Map<String, Class<?>> getAnnotatedStyleableInfos( Object obj ) { public static Map<String, Class<?>> getAnnotatedStyleableInfos( Object obj )
throws IllegalArgumentException
{
return getAnnotatedStyleableInfos( obj, null ); return getAnnotatedStyleableInfos( obj, null );
} }
public static Map<String, Class<?>> getAnnotatedStyleableInfos( Object obj, Border border ) { public static Map<String, Class<?>> getAnnotatedStyleableInfos( Object obj, Border border )
throws IllegalArgumentException
{
Map<String, Class<?>> infos = new StyleableInfosMap<>(); Map<String, Class<?>> infos = new StyleableInfosMap<>();
collectAnnotatedStyleableInfos( obj, infos ); collectAnnotatedStyleableInfos( obj, infos );
collectStyleableInfos( border, infos ); collectStyleableInfos( border, infos );
@@ -732,7 +760,9 @@ public class FlatStylingSupport
* Search for all fields annotated with {@link Styleable} and add them to the given map. * Search for all fields annotated with {@link Styleable} and add them to the given map.
* The key is the name of the field and the value the type of the field. * The key is the name of the field and the value the type of the field.
*/ */
public static void collectAnnotatedStyleableInfos( Object obj, Map<String, Class<?>> infos ) { public static void collectAnnotatedStyleableInfos( Object obj, Map<String, Class<?>> infos )
throws IllegalArgumentException
{
HashSet<String> processedFields = new HashSet<>(); HashSet<String> processedFields = new HashSet<>();
Class<?> cls = obj.getClass(); Class<?> cls = obj.getClass();
@@ -810,7 +840,9 @@ public class FlatStylingSupport
infos.put( keyPrefix.concat( e.getKey() ), e.getValue() ); infos.put( keyPrefix.concat( e.getKey() ), e.getValue() );
} }
public static Object getAnnotatedStyleableValue( Object obj, String key ) { public static Object getAnnotatedStyleableValue( Object obj, String key )
throws IllegalArgumentException
{
String fieldName = keyToFieldName( key ); String fieldName = keyToFieldName( key );
Class<?> cls = obj.getClass(); Class<?> cls = obj.getClass();
@@ -877,7 +909,9 @@ public class FlatStylingSupport
extends LinkedHashMap<K,V> extends LinkedHashMap<K,V>
{ {
@Override @Override
public V put( K key, V value ) { public V put( K key, V value )
throws IllegalArgumentException
{
V oldValue = super.put( key, value ); V oldValue = super.put( key, value );
if( oldValue != null ) if( oldValue != null )
throw new IllegalArgumentException( "duplicate key '" + key + "'" ); throw new IllegalArgumentException( "duplicate key '" + key + "'" );

View File

@@ -49,6 +49,7 @@ import java.awt.event.MouseEvent;
import java.awt.event.MouseListener; import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener; import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent; import java.awt.event.MouseWheelEvent;
import java.awt.geom.Area;
import java.awt.geom.Path2D; import java.awt.geom.Path2D;
import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D;
import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeEvent;
@@ -143,6 +144,11 @@ import com.formdev.flatlaf.util.UIScale;
* @uiDefault TabbedPane.tabHeight int * @uiDefault TabbedPane.tabHeight int
* @uiDefault TabbedPane.tabSelectionHeight int * @uiDefault TabbedPane.tabSelectionHeight int
* @uiDefault TabbedPane.cardTabSelectionHeight int * @uiDefault TabbedPane.cardTabSelectionHeight int
* @uiDefault TabbedPane.tabArc int
* @uiDefault TabbedPane.tabSelectionArc int
* @uiDefault TabbedPane.cardTabArc int
* @uiDefault TabbedPane.selectedInsets Insets
* @uiDefault TabbedPane.tabSelectionInsets Insets
* @uiDefault TabbedPane.contentSeparatorHeight int * @uiDefault TabbedPane.contentSeparatorHeight int
* @uiDefault TabbedPane.showTabSeparators boolean * @uiDefault TabbedPane.showTabSeparators boolean
* @uiDefault TabbedPane.tabSeparatorsFullHeight boolean * @uiDefault TabbedPane.tabSeparatorsFullHeight boolean
@@ -219,6 +225,11 @@ public class FlatTabbedPaneUI
@Styleable protected int tabHeight; @Styleable protected int tabHeight;
@Styleable protected int tabSelectionHeight; @Styleable protected int tabSelectionHeight;
/** @since 2 */ @Styleable protected int cardTabSelectionHeight; /** @since 2 */ @Styleable protected int cardTabSelectionHeight;
/** @since 3.2 */ @Styleable protected int tabArc;
/** @since 3.2 */ @Styleable protected int tabSelectionArc;
/** @since 3.2 */ @Styleable protected int cardTabArc;
/** @since 3.2 */ @Styleable protected Insets selectedInsets;
/** @since 3.2 */ @Styleable protected Insets tabSelectionInsets;
@Styleable protected int contentSeparatorHeight; @Styleable protected int contentSeparatorHeight;
@Styleable protected boolean showTabSeparators; @Styleable protected boolean showTabSeparators;
@Styleable protected boolean tabSeparatorsFullHeight; @Styleable protected boolean tabSeparatorsFullHeight;
@@ -344,6 +355,11 @@ public class FlatTabbedPaneUI
tabHeight = UIManager.getInt( "TabbedPane.tabHeight" ); tabHeight = UIManager.getInt( "TabbedPane.tabHeight" );
tabSelectionHeight = UIManager.getInt( "TabbedPane.tabSelectionHeight" ); tabSelectionHeight = UIManager.getInt( "TabbedPane.tabSelectionHeight" );
cardTabSelectionHeight = UIManager.getInt( "TabbedPane.cardTabSelectionHeight" ); cardTabSelectionHeight = UIManager.getInt( "TabbedPane.cardTabSelectionHeight" );
tabArc = UIManager.getInt( "TabbedPane.tabArc" );
tabSelectionArc = UIManager.getInt( "TabbedPane.tabSelectionArc" );
cardTabArc = UIManager.getInt( "TabbedPane.cardTabArc" );
selectedInsets = UIManager.getInsets( "TabbedPane.selectedInsets" );
tabSelectionInsets = UIManager.getInsets( "TabbedPane.tabSelectionInsets" );
contentSeparatorHeight = UIManager.getInt( "TabbedPane.contentSeparatorHeight" ); contentSeparatorHeight = UIManager.getInt( "TabbedPane.contentSeparatorHeight" );
showTabSeparators = UIManager.getBoolean( "TabbedPane.showTabSeparators" ); showTabSeparators = UIManager.getBoolean( "TabbedPane.showTabSeparators" );
tabSeparatorsFullHeight = UIManager.getBoolean( "TabbedPane.tabSeparatorsFullHeight" ); tabSeparatorsFullHeight = UIManager.getBoolean( "TabbedPane.tabSeparatorsFullHeight" );
@@ -1184,9 +1200,40 @@ public class FlatTabbedPaneUI
protected void paintTabBackground( Graphics g, int tabPlacement, int tabIndex, protected void paintTabBackground( Graphics g, int tabPlacement, int tabIndex,
int x, int y, int w, int h, boolean isSelected ) int x, int y, int w, int h, boolean isSelected )
{ {
boolean isCard = (getTabType() == TAB_TYPE_CARD);
// fill whole tab background if tab is rounded or has insets
if( (!isCard && tabArc > 0) ||
(isCard && cardTabArc > 0) ||
(!isCard && selectedInsets != null &&
(selectedInsets.top != 0 || selectedInsets.left != 0 ||
selectedInsets.bottom != 0 || selectedInsets.right != 0)) )
{
Color background = tabPane.getBackgroundAt( tabIndex );
g.setColor( FlatUIUtils.deriveColor( background, tabPane.getBackground() ) );
g.fillRect( x, y, w, h );
}
// apply insets
if( !isCard && selectedInsets != null ) {
Insets insets = new Insets( 0, 0, 0, 0 );
rotateInsets( selectedInsets, insets, tabPane.getTabPlacement() );
x += scale( insets.left );
y += scale( insets.top );
w -= scale( insets.left + insets.right );
h -= scale( insets.top + insets.bottom );
}
// paint tab background // paint tab background
Color background = getTabBackground( tabPlacement, tabIndex, isSelected ); Color background = getTabBackground( tabPlacement, tabIndex, isSelected );
g.setColor( FlatUIUtils.deriveColor( background, tabPane.getBackground() ) ); g.setColor( FlatUIUtils.deriveColor( background, tabPane.getBackground() ) );
if( !isCard && tabArc > 0 ) {
float arc = scale( (float) tabArc ) / 2f;
FlatUIUtils.paintSelection( (Graphics2D) g, x, y, w, h, null, arc, arc, arc, arc, 0 );
} else if( isCard && cardTabArc > 0 )
((Graphics2D)g).fill( createCardTabOuterPath( tabPlacement, x, y, w, h ) );
else
g.fillRect( x, y, w, h ); g.fillRect( x, y, w, h );
} }
@@ -1241,42 +1288,38 @@ public class FlatTabbedPaneUI
protected void paintCardTabBorder( Graphics g, int tabPlacement, int tabIndex, int x, int y, int w, int h ) { protected void paintCardTabBorder( Graphics g, int tabPlacement, int tabIndex, int x, int y, int w, int h ) {
Graphics2D g2 = (Graphics2D) g; Graphics2D g2 = (Graphics2D) g;
float borderWidth = scale( (float) contentSeparatorHeight ); Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD );
path.append( createCardTabOuterPath( tabPlacement, x, y, w, h ), false );
path.append( createCardTabInnerPath( tabPlacement, x, y, w, h ), false );
g.setColor( (tabSeparatorColor != null) ? tabSeparatorColor : contentAreaColor ); g.setColor( (tabSeparatorColor != null) ? tabSeparatorColor : contentAreaColor );
g2.fill( path );
}
/** @since 3.2 */
protected Shape createCardTabOuterPath( int tabPlacement, int x, int y, int w, int h ) {
float arc = scale( (float) cardTabArc ) / 2f;
switch( tabPlacement ) { switch( tabPlacement ) {
default: default:
case TOP: case TOP: return FlatUIUtils.createRoundRectanglePath( x, y, w, h, arc, arc, 0, 0 );
case BOTTOM: case BOTTOM: return FlatUIUtils.createRoundRectanglePath( x, y, w, h, 0, 0, arc, arc );
// paint left and right tab border case LEFT: return FlatUIUtils.createRoundRectanglePath( x, y, w, h, arc, 0, arc, 0 );
g2.fill( new Rectangle2D.Float( x, y, borderWidth, h ) ); case RIGHT: return FlatUIUtils.createRoundRectanglePath( x, y, w, h, 0, arc, 0, arc );
g2.fill( new Rectangle2D.Float( x + w - borderWidth, y, borderWidth, h ) ); }
break;
case LEFT:
case RIGHT:
// paint top and bottom tab border
g2.fill( new Rectangle2D.Float( x, y, w, borderWidth ) );
g2.fill( new Rectangle2D.Float( x, y + h - borderWidth, w, borderWidth ) );
break;
} }
if( cardTabSelectionHeight <= 0 ) { /** @since 3.2 */
// if there is no tab selection indicator, paint a top border as well protected Shape createCardTabInnerPath( int tabPlacement, int x, int y, int w, int h ) {
float bw = scale( (float) contentSeparatorHeight );
float arc = (scale( (float) cardTabArc ) / 2f) - bw;
switch( tabPlacement ) { switch( tabPlacement ) {
default: default:
case TOP: case TOP: return FlatUIUtils.createRoundRectanglePath( x + bw, y + bw, w - (bw * 2), h - bw, arc, arc, 0, 0 );
g2.fill( new Rectangle2D.Float( x, y, w, borderWidth ) ); case BOTTOM: return FlatUIUtils.createRoundRectanglePath( x + bw, y, w - (bw * 2), h - bw, 0, 0, arc, arc );
break; case LEFT: return FlatUIUtils.createRoundRectanglePath( x + bw, y + bw, w - bw, h - (bw * 2), arc, 0, arc, 0 );
case BOTTOM: case RIGHT: return FlatUIUtils.createRoundRectanglePath( x, y + bw, w - bw, h - (bw * 2), 0, arc, 0, arc );
g2.fill( new Rectangle2D.Float( x, y + h - borderWidth, w, borderWidth ) );
break;
case LEFT:
g2.fill( new Rectangle2D.Float( x, y, borderWidth, h ) );
break;
case RIGHT:
g2.fill( new Rectangle2D.Float( x + w - borderWidth, y, borderWidth, h ) );
break;
}
} }
} }
@@ -1324,38 +1367,62 @@ public class FlatTabbedPaneUI
? (isTabbedPaneOrChildFocused() ? underlineColor : inactiveUnderlineColor) ? (isTabbedPaneOrChildFocused() ? underlineColor : inactiveUnderlineColor)
: disabledUnderlineColor ); : disabledUnderlineColor );
// paint underline selection boolean isCard = (getTabType() == TAB_TYPE_CARD);
boolean atBottom = (getTabType() != TAB_TYPE_CARD); boolean atBottom = !isCard;
Insets contentInsets = atBottom Insets contentInsets = atBottom
? ((!rotateTabRuns && runCount > 1 && !isScrollTabLayout() && getRunForTab( tabPane.getTabCount(), tabIndex ) > 0) ? ((!rotateTabRuns && runCount > 1 && !isScrollTabLayout() && getRunForTab( tabPane.getTabCount(), tabIndex ) > 0)
? new Insets( 0, 0, 0, 0 ) ? new Insets( 0, 0, 0, 0 )
: getContentBorderInsets( tabPlacement )) : getContentBorderInsets( tabPlacement ))
: null; : null;
int tabSelectionHeight = scale( atBottom ? this.tabSelectionHeight : cardTabSelectionHeight ); int tabSelectionHeight = scale( isCard ? cardTabSelectionHeight : this.tabSelectionHeight );
int sx, sy; float arc = scale( (float) (isCard ? cardTabArc : tabSelectionArc) ) / 2f;
int sx = x, sy = y, sw = w, sh = h;
switch( tabPlacement ) { switch( tabPlacement ) {
case TOP: case TOP:
default: default:
sy = atBottom ? (y + h + contentInsets.top - tabSelectionHeight) : y; sy = atBottom ? (y + h + contentInsets.top - tabSelectionHeight) : y;
g.fillRect( x, sy, w, tabSelectionHeight ); sh = tabSelectionHeight;
break; break;
case BOTTOM: case BOTTOM:
sy = atBottom ? (y - contentInsets.bottom) : (y + h - tabSelectionHeight); sy = atBottom ? (y - contentInsets.bottom) : (y + h - tabSelectionHeight);
g.fillRect( x, sy, w, tabSelectionHeight ); sh = tabSelectionHeight;
break; break;
case LEFT: case LEFT:
sx = atBottom ? (x + w + contentInsets.left - tabSelectionHeight) : x; sx = atBottom ? (x + w + contentInsets.left - tabSelectionHeight) : x;
g.fillRect( sx, y, tabSelectionHeight, h ); sw = tabSelectionHeight;
break; break;
case RIGHT: case RIGHT:
sx = atBottom ? (x - contentInsets.right) : (x + w - tabSelectionHeight); sx = atBottom ? (x - contentInsets.right) : (x + w - tabSelectionHeight);
g.fillRect( sx, y, tabSelectionHeight, h ); sw = tabSelectionHeight;
break; break;
} }
// apply insets
if( !isCard && tabSelectionInsets != null ) {
Insets insets = new Insets( 0, 0, 0, 0 );
rotateInsets( tabSelectionInsets, insets, tabPane.getTabPlacement() );
sx += scale( insets.left );
sy += scale( insets.top );
sw -= scale( insets.left + insets.right );
sh -= scale( insets.top + insets.bottom );
}
// paint underline selection
if( arc <= 0 )
g.fillRect( sx, sy, sw, sh );
else {
if( isCard ) {
Area area = new Area( createCardTabOuterPath( tabPlacement, x, y, w, h ) );
area.intersect( new Area( new Rectangle2D.Float( sx, sy, sw, sh ) ) );
((Graphics2D)g).fill( area );
} else
FlatUIUtils.paintSelection( (Graphics2D) g, sx, sy, sw, sh, null, arc, arc, arc, arc, 0 );
}
} }
/** @since 2.2 */ /** @since 2.2 */
@@ -1967,7 +2034,7 @@ public class FlatTabbedPaneUI
//---- class TabCloseButton ----------------------------------------------- //---- class TabCloseButton -----------------------------------------------
private class TabCloseButton private static class TabCloseButton
extends JButton extends JButton
implements UIResource implements UIResource
{ {
@@ -1977,7 +2044,7 @@ public class FlatTabbedPaneUI
//---- class ContainerUIResource ------------------------------------------ //---- class ContainerUIResource ------------------------------------------
private class ContainerUIResource private static class ContainerUIResource
extends JPanel extends JPanel
implements UIResource implements UIResource
{ {
@@ -2382,7 +2449,7 @@ public class FlatTabbedPaneUI
if( isPreciseWheel && if( isPreciseWheel &&
getScrollButtonsPlacement() == BOTH && getScrollButtonsPlacement() == BOTH &&
getScrollButtonsPolicy() == AS_NEEDED_SINGLE && getScrollButtonsPolicy() == AS_NEEDED_SINGLE &&
(isLeftToRight() || !horizontal) || // scroll buttons are hidden in right-to-left (isLeftToRight() || !horizontal) && // scroll buttons are hidden in right-to-left
scrollBackwardButtonPrefSize != null ) scrollBackwardButtonPrefSize != null )
{ {
// special cases for scrolling with touchpad or high-resolution wheel: // special cases for scrolling with touchpad or high-resolution wheel:
@@ -3051,7 +3118,7 @@ public class FlatTabbedPaneUI
break; break;
case CENTER: case CENTER:
shiftTabs( 0, (diff) / 2 ); shiftTabs( 0, diff / 2 );
topHeight += diff / 2; topHeight += diff / 2;
bottomHeight += diff - (diff / 2); bottomHeight += diff - (diff / 2);
break; break;

View File

@@ -277,6 +277,9 @@ public class FlatTableUI
/** @since 2 */ /** @since 2 */
protected Object applyStyleProperty( String key, Object value ) { protected Object applyStyleProperty( String key, Object value ) {
if( "rowHeight".equals( key ) && value instanceof Integer )
value = UIScale.scale( (Integer) value );
return FlatStylingSupport.applyToAnnotatedObjectOrComponent( this, table, key, value ); return FlatStylingSupport.applyToAnnotatedObjectOrComponent( this, table, key, value );
} }

View File

@@ -54,7 +54,6 @@ import com.formdev.flatlaf.util.LoggingFacade;
* <!-- FlatTextAreaUI --> * <!-- FlatTextAreaUI -->
* *
* @uiDefault Component.minimumWidth int * @uiDefault Component.minimumWidth int
* @uiDefault Component.isIntelliJTheme boolean
* @uiDefault TextArea.disabledBackground Color used if not enabled * @uiDefault TextArea.disabledBackground Color used if not enabled
* @uiDefault TextArea.inactiveBackground Color used if not editable * @uiDefault TextArea.inactiveBackground Color used if not editable
* @uiDefault TextArea.focusedBackground Color optional * @uiDefault TextArea.focusedBackground Color optional
@@ -66,7 +65,6 @@ public class FlatTextAreaUI
implements StyleableUI implements StyleableUI
{ {
@Styleable protected int minimumWidth; @Styleable protected int minimumWidth;
protected boolean isIntelliJTheme;
private Color background; private Color background;
@Styleable protected Color disabledBackground; @Styleable protected Color disabledBackground;
@Styleable protected Color inactiveBackground; @Styleable protected Color inactiveBackground;
@@ -103,7 +101,6 @@ public class FlatTextAreaUI
super.installDefaults(); super.installDefaults();
minimumWidth = UIManager.getInt( "Component.minimumWidth" ); minimumWidth = UIManager.getInt( "Component.minimumWidth" );
isIntelliJTheme = UIManager.getBoolean( "Component.isIntelliJTheme" );
background = UIManager.getColor( "TextArea.background" ); background = UIManager.getColor( "TextArea.background" );
disabledBackground = UIManager.getColor( "TextArea.disabledBackground" ); disabledBackground = UIManager.getColor( "TextArea.disabledBackground" );
inactiveBackground = UIManager.getColor( "TextArea.inactiveBackground" ); inactiveBackground = UIManager.getColor( "TextArea.inactiveBackground" );
@@ -227,6 +224,6 @@ public class FlatTextAreaUI
@Override @Override
protected void paintBackground( Graphics g ) { protected void paintBackground( Graphics g ) {
FlatEditorPaneUI.paintBackground( g, getComponent(), isIntelliJTheme, focusedBackground ); FlatEditorPaneUI.paintBackground( g, getComponent(), focusedBackground );
} }
} }

View File

@@ -81,7 +81,6 @@ import com.formdev.flatlaf.util.LoggingFacade;
* <!-- FlatTextFieldUI --> * <!-- FlatTextFieldUI -->
* *
* @uiDefault Component.minimumWidth int * @uiDefault Component.minimumWidth int
* @uiDefault Component.isIntelliJTheme boolean
* @uiDefault TextField.placeholderForeground Color * @uiDefault TextField.placeholderForeground Color
* @uiDefault TextField.focusedBackground Color optional * @uiDefault TextField.focusedBackground Color optional
* @uiDefault TextField.iconTextGap int optional, default is 4 * @uiDefault TextField.iconTextGap int optional, default is 4
@@ -95,7 +94,6 @@ public class FlatTextFieldUI
implements StyleableUI implements StyleableUI
{ {
@Styleable protected int minimumWidth; @Styleable protected int minimumWidth;
protected boolean isIntelliJTheme;
private Color background; private Color background;
@Styleable protected Color disabledBackground; @Styleable protected Color disabledBackground;
@Styleable protected Color inactiveBackground; @Styleable protected Color inactiveBackground;
@@ -165,7 +163,6 @@ public class FlatTextFieldUI
String prefix = getPropertyPrefix(); String prefix = getPropertyPrefix();
minimumWidth = UIManager.getInt( "Component.minimumWidth" ); minimumWidth = UIManager.getInt( "Component.minimumWidth" );
isIntelliJTheme = UIManager.getBoolean( "Component.isIntelliJTheme" );
background = UIManager.getColor( prefix + ".background" ); background = UIManager.getColor( prefix + ".background" );
disabledBackground = UIManager.getColor( prefix + ".disabledBackground" ); disabledBackground = UIManager.getColor( prefix + ".disabledBackground" );
inactiveBackground = UIManager.getColor( prefix + ".inactiveBackground" ); inactiveBackground = UIManager.getColor( prefix + ".inactiveBackground" );
@@ -402,7 +399,7 @@ public class FlatTextFieldUI
@Override @Override
protected void paintSafely( Graphics g ) { protected void paintSafely( Graphics g ) {
paintBackground( g, getComponent(), isIntelliJTheme, focusedBackground ); paintBackground( g, getComponent(), focusedBackground );
paintPlaceholder( g ); paintPlaceholder( g );
if( hasLeadingIcon() || hasTrailingIcon() ) if( hasLeadingIcon() || hasTrailingIcon() )
@@ -422,7 +419,7 @@ debug*/
// background is painted elsewhere // background is painted elsewhere
} }
static void paintBackground( Graphics g, JTextComponent c, boolean isIntelliJTheme, Color focusedBackground ) { static void paintBackground( Graphics g, JTextComponent c, Color focusedBackground ) {
// do not paint background if: // do not paint background if:
// - not opaque and // - not opaque and
// - border is not a flat border and // - border is not a flat border and
@@ -443,14 +440,14 @@ debug*/
try { try {
FlatUIUtils.setRenderingHints( g2 ); FlatUIUtils.setRenderingHints( g2 );
g2.setColor( getBackground( c, isIntelliJTheme, focusedBackground ) ); g2.setColor( getBackground( c, focusedBackground ) );
FlatUIUtils.paintComponentBackground( g2, 0, 0, c.getWidth(), c.getHeight(), focusWidth, arc ); FlatUIUtils.paintComponentBackground( g2, 0, 0, c.getWidth(), c.getHeight(), focusWidth, arc );
} finally { } finally {
g2.dispose(); g2.dispose();
} }
} }
static Color getBackground( JTextComponent c, boolean isIntelliJTheme, Color focusedBackground ) { static Color getBackground( JTextComponent c, Color focusedBackground ) {
Color background = c.getBackground(); Color background = c.getBackground();
// always use explicitly set color // always use explicitly set color
@@ -461,10 +458,6 @@ debug*/
if( focusedBackground != null && FlatUIUtils.isPermanentFocusOwner( c ) ) if( focusedBackground != null && FlatUIUtils.isPermanentFocusOwner( c ) )
return focusedBackground; return focusedBackground;
// for compatibility with IntelliJ themes
if( isIntelliJTheme && (!c.isEnabled() || !c.isEditable()) )
return FlatUIUtils.getParentBackground( c );
return background; return background;
} }

View File

@@ -56,7 +56,6 @@ import com.formdev.flatlaf.util.LoggingFacade;
* <!-- FlatTextPaneUI --> * <!-- FlatTextPaneUI -->
* *
* @uiDefault Component.minimumWidth int * @uiDefault Component.minimumWidth int
* @uiDefault Component.isIntelliJTheme boolean
* @uiDefault TextPane.focusedBackground Color optional * @uiDefault TextPane.focusedBackground Color optional
* *
* @author Karl Tauber * @author Karl Tauber
@@ -66,7 +65,6 @@ public class FlatTextPaneUI
implements StyleableUI implements StyleableUI
{ {
@Styleable protected int minimumWidth; @Styleable protected int minimumWidth;
protected boolean isIntelliJTheme;
private Color background; private Color background;
@Styleable protected Color disabledBackground; @Styleable protected Color disabledBackground;
@Styleable protected Color inactiveBackground; @Styleable protected Color inactiveBackground;
@@ -98,7 +96,6 @@ public class FlatTextPaneUI
String prefix = getPropertyPrefix(); String prefix = getPropertyPrefix();
minimumWidth = UIManager.getInt( "Component.minimumWidth" ); minimumWidth = UIManager.getInt( "Component.minimumWidth" );
isIntelliJTheme = UIManager.getBoolean( "Component.isIntelliJTheme" );
background = UIManager.getColor( prefix + ".background" ); background = UIManager.getColor( prefix + ".background" );
disabledBackground = UIManager.getColor( prefix + ".disabledBackground" ); disabledBackground = UIManager.getColor( prefix + ".disabledBackground" );
inactiveBackground = UIManager.getColor( prefix + ".inactiveBackground" ); inactiveBackground = UIManager.getColor( prefix + ".inactiveBackground" );
@@ -220,6 +217,6 @@ public class FlatTextPaneUI
@Override @Override
protected void paintBackground( Graphics g ) { protected void paintBackground( Graphics g ) {
FlatEditorPaneUI.paintBackground( g, getComponent(), isIntelliJTheme, focusedBackground ); FlatEditorPaneUI.paintBackground( g, getComponent(), focusedBackground );
} }
} }

View File

@@ -57,6 +57,7 @@ import javax.swing.Icon;
import javax.swing.JButton; import javax.swing.JButton;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.JDialog; import javax.swing.JDialog;
import javax.swing.JInternalFrame;
import javax.swing.JLabel; import javax.swing.JLabel;
import javax.swing.JMenuBar; import javax.swing.JMenuBar;
import javax.swing.JPanel; import javax.swing.JPanel;
@@ -96,6 +97,7 @@ import com.formdev.flatlaf.util.UIScale;
* @uiDefault TitlePane.centerTitleIfMenuBarEmbedded boolean * @uiDefault TitlePane.centerTitleIfMenuBarEmbedded boolean
* @uiDefault TitlePane.showIconBesideTitle boolean * @uiDefault TitlePane.showIconBesideTitle boolean
* @uiDefault TitlePane.menuBarTitleGap int * @uiDefault TitlePane.menuBarTitleGap int
* @uiDefault TitlePane.menuBarTitleMinimumGap int
* @uiDefault TitlePane.menuBarResizeHeight int * @uiDefault TitlePane.menuBarResizeHeight int
* @uiDefault TitlePane.closeIcon Icon * @uiDefault TitlePane.closeIcon Icon
* @uiDefault TitlePane.iconifyIcon Icon * @uiDefault TitlePane.iconifyIcon Icon
@@ -109,29 +111,30 @@ public class FlatTitlePane
{ {
private static final String KEY_DEBUG_SHOW_RECTANGLES = "FlatLaf.debug.titlebar.showRectangles"; private static final String KEY_DEBUG_SHOW_RECTANGLES = "FlatLaf.debug.titlebar.showRectangles";
/** @since 2.5 */ protected final Font titleFont = UIManager.getFont( "TitlePane.font" ); /** @since 2.5 */ protected final Font titleFont;
protected final Color activeBackground = UIManager.getColor( "TitlePane.background" ); protected final Color activeBackground;
protected final Color inactiveBackground = UIManager.getColor( "TitlePane.inactiveBackground" ); protected final Color inactiveBackground;
protected final Color activeForeground = UIManager.getColor( "TitlePane.foreground" ); protected final Color activeForeground;
protected final Color inactiveForeground = UIManager.getColor( "TitlePane.inactiveForeground" ); protected final Color inactiveForeground;
protected final Color embeddedForeground = UIManager.getColor( "TitlePane.embeddedForeground" ); protected final Color embeddedForeground;
protected final Color borderColor = UIManager.getColor( "TitlePane.borderColor" ); protected final Color borderColor;
/** @since 2 */ protected final boolean showIcon = FlatUIUtils.getUIBoolean( "TitlePane.showIcon", true ); /** @since 2 */ protected final boolean showIcon;
/** @since 2.5 */ protected final boolean showIconInDialogs = FlatUIUtils.getUIBoolean( "TitlePane.showIconInDialogs", true ); /** @since 2.5 */ protected final boolean showIconInDialogs;
/** @since 2 */ protected final int noIconLeftGap = FlatUIUtils.getUIInt( "TitlePane.noIconLeftGap", 8 ); /** @since 2 */ protected final int noIconLeftGap;
protected final Dimension iconSize = UIManager.getDimension( "TitlePane.iconSize" ); protected final Dimension iconSize;
/** @since 2.4 */ protected final int titleMinimumWidth = FlatUIUtils.getUIInt( "TitlePane.titleMinimumWidth", 60 ); /** @since 2.4 */ protected final int titleMinimumWidth;
/** @since 2.4 */ protected final int buttonMinimumWidth = FlatUIUtils.getUIInt( "TitlePane.buttonMinimumWidth", 30 ); /** @since 2.4 */ protected final int buttonMinimumWidth;
protected final int buttonMaximizedHeight = UIManager.getInt( "TitlePane.buttonMaximizedHeight" ); protected final int buttonMaximizedHeight;
protected final boolean centerTitle = UIManager.getBoolean( "TitlePane.centerTitle" ); protected final boolean centerTitle;
protected final boolean centerTitleIfMenuBarEmbedded = FlatUIUtils.getUIBoolean( "TitlePane.centerTitleIfMenuBarEmbedded", true ); protected final boolean centerTitleIfMenuBarEmbedded;
/** @since 2.4 */ protected final boolean showIconBesideTitle = UIManager.getBoolean( "TitlePane.showIconBesideTitle" ); /** @since 2.4 */ protected final boolean showIconBesideTitle;
protected final int menuBarTitleGap = FlatUIUtils.getUIInt( "TitlePane.menuBarTitleGap", 40 ); protected final int menuBarTitleGap;
/** @since 2.4 */ protected final int menuBarTitleMinimumGap = FlatUIUtils.getUIInt( "TitlePane.menuBarTitleMinimumGap", 12 ); /** @since 2.4 */ protected final int menuBarTitleMinimumGap;
/** @since 2.4 */ protected final int menuBarResizeHeight = FlatUIUtils.getUIInt( "TitlePane.menuBarResizeHeight", 4 ); /** @since 2.4 */ protected final int menuBarResizeHeight;
protected final JRootPane rootPane; protected final JRootPane rootPane;
protected final String windowStyle;
protected JPanel leftPanel; protected JPanel leftPanel;
protected JLabel iconLabel; protected JLabel iconLabel;
@@ -150,6 +153,34 @@ public class FlatTitlePane
public FlatTitlePane( JRootPane rootPane ) { public FlatTitlePane( JRootPane rootPane ) {
this.rootPane = rootPane; this.rootPane = rootPane;
Window w = SwingUtilities.getWindowAncestor( rootPane );
String defaultWindowStyle = (w != null && w.getType() == Window.Type.UTILITY) ? WINDOW_STYLE_SMALL : null;
windowStyle = clientProperty( rootPane, WINDOW_STYLE, defaultWindowStyle, String.class );
titleFont = FlatUIUtils.getSubUIFont( "TitlePane.font", windowStyle );
activeBackground = FlatUIUtils.getSubUIColor( "TitlePane.background", windowStyle );
inactiveBackground = FlatUIUtils.getSubUIColor( "TitlePane.inactiveBackground", windowStyle );
activeForeground = FlatUIUtils.getSubUIColor( "TitlePane.foreground", windowStyle );
inactiveForeground = FlatUIUtils.getSubUIColor( "TitlePane.inactiveForeground", windowStyle );
embeddedForeground = FlatUIUtils.getSubUIColor( "TitlePane.embeddedForeground", windowStyle );
// not using windowStyle here because TitlePane.borderColor is also used in FlatRootPaneUI
borderColor = UIManager.getColor( "TitlePane.borderColor" );
showIcon = FlatUIUtils.getSubUIBoolean( "TitlePane.showIcon", windowStyle, true );
showIconInDialogs = FlatUIUtils.getSubUIBoolean( "TitlePane.showIconInDialogs", windowStyle, true );
noIconLeftGap = FlatUIUtils.getSubUIInt( "TitlePane.noIconLeftGap", windowStyle, 8 );
iconSize = FlatUIUtils.getSubUIDimension( "TitlePane.iconSize", windowStyle );
titleMinimumWidth = FlatUIUtils.getSubUIInt( "TitlePane.titleMinimumWidth", windowStyle, 60 );
buttonMinimumWidth = FlatUIUtils.getSubUIInt( "TitlePane.buttonMinimumWidth", windowStyle, 30 );
buttonMaximizedHeight = FlatUIUtils.getSubUIInt( "TitlePane.buttonMaximizedHeight", windowStyle, 0 );
centerTitle = FlatUIUtils.getSubUIBoolean( "TitlePane.centerTitle", windowStyle, false );
centerTitleIfMenuBarEmbedded = FlatUIUtils.getSubUIBoolean( "TitlePane.centerTitleIfMenuBarEmbedded", windowStyle, true );
showIconBesideTitle = FlatUIUtils.getSubUIBoolean( "TitlePane.showIconBesideTitle", windowStyle, false );
menuBarTitleGap = FlatUIUtils.getSubUIInt( "TitlePane.menuBarTitleGap", windowStyle, 40 );
menuBarTitleMinimumGap = FlatUIUtils.getSubUIInt( "TitlePane.menuBarTitleMinimumGap", windowStyle, 12 );
menuBarResizeHeight = FlatUIUtils.getSubUIInt( "TitlePane.menuBarResizeHeight", windowStyle, 4 );
handler = createHandler(); handler = createHandler();
setBorder( createTitlePaneBorder() ); setBorder( createTitlePaneBorder() );
@@ -182,8 +213,8 @@ public class FlatTitlePane
setUI( new FlatTitleLabelUI() ); setUI( new FlatTitleLabelUI() );
} }
}; };
iconLabel.setBorder( new FlatEmptyBorder( UIManager.getInsets( "TitlePane.iconMargins" ) ) ); iconLabel.setBorder( new FlatEmptyBorder( FlatUIUtils.getSubUIInsets( "TitlePane.iconMargins", windowStyle ) ) );
titleLabel.setBorder( new FlatEmptyBorder( UIManager.getInsets( "TitlePane.titleMargins" ) ) ); titleLabel.setBorder( new FlatEmptyBorder( FlatUIUtils.getSubUIInsets( "TitlePane.titleMargins", windowStyle ) ) );
leftPanel.setLayout( new BoxLayout( leftPanel, BoxLayout.LINE_AXIS ) ); leftPanel.setLayout( new BoxLayout( leftPanel, BoxLayout.LINE_AXIS ) );
leftPanel.setOpaque( false ); leftPanel.setOpaque( false );
@@ -310,7 +341,7 @@ public class FlatTitlePane
} }
protected JButton createButton( String iconKey, String accessibleName, ActionListener action ) { protected JButton createButton( String iconKey, String accessibleName, ActionListener action ) {
JButton button = new JButton( UIManager.getIcon( iconKey ) ) { JButton button = new JButton( FlatUIUtils.getSubUIIcon( iconKey, windowStyle ) ) {
@Override @Override
public Dimension getMinimumSize() { public Dimension getMinimumSize() {
// allow the button to shrink if space is rare // allow the button to shrink if space is rare
@@ -682,7 +713,7 @@ public class FlatTitlePane
// Seems to be a bug in sun.awt.X11.XNETProtocol.requestState(), // Seems to be a bug in sun.awt.X11.XNETProtocol.requestState(),
// which does some strange state XOR-ing... // which does some strange state XOR-ing...
if( (oldState & Frame.MAXIMIZED_BOTH) == Frame.MAXIMIZED_VERT ) if( (oldState & Frame.MAXIMIZED_BOTH) == Frame.MAXIMIZED_VERT )
newState = oldState & ~Frame.MAXIMIZED_BOTH | Frame.MAXIMIZED_HORIZ; newState = (oldState & ~Frame.MAXIMIZED_BOTH) | Frame.MAXIMIZED_HORIZ;
} }
frame.setExtendedState( newState ); frame.setExtendedState( newState );
@@ -952,6 +983,13 @@ public class FlatTitlePane
} }
} }
// allow internal frames in layered pane to be moved/resized when placed over title bar
for( Component c : rootPane.getLayeredPane().getComponents() ) {
r = (c instanceof JInternalFrame) ? getNativeHitTestSpot( (JInternalFrame) c ) : null;
if( r != null )
hitTestSpots.add( r );
}
Rectangle minimizeButtonBounds = boundsInWindow( iconifyButton ); Rectangle minimizeButtonBounds = boundsInWindow( iconifyButton );
Rectangle maximizeButtonBounds = boundsInWindow( maximizeButton.isVisible() ? maximizeButton : restoreButton ); Rectangle maximizeButtonBounds = boundsInWindow( maximizeButton.isVisible() ? maximizeButton : restoreButton );
Rectangle closeButtonBounds = boundsInWindow( closeButton ); Rectangle closeButtonBounds = boundsInWindow( closeButton );

View File

@@ -39,10 +39,12 @@ import javax.swing.JComboBox;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.JToolBar; import javax.swing.JToolBar;
import javax.swing.LayoutFocusTraversalPolicy; import javax.swing.LayoutFocusTraversalPolicy;
import javax.swing.RootPaneContainer;
import javax.swing.UIManager; import javax.swing.UIManager;
import javax.swing.border.Border; import javax.swing.border.Border;
import javax.swing.plaf.ComponentUI; import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicToolBarUI; import javax.swing.plaf.basic.BasicToolBarUI;
import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable; import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI; import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
import com.formdev.flatlaf.util.LoggingFacade; import com.formdev.flatlaf.util.LoggingFacade;
@@ -156,6 +158,13 @@ public class FlatToolBarUI
} }
} }
@Override
protected RootPaneContainer createFloatingWindow( JToolBar toolbar ) {
RootPaneContainer floatingWindow = super.createFloatingWindow( toolbar );
floatingWindow.getRootPane().putClientProperty( FlatClientProperties.WINDOW_STYLE, FlatClientProperties.WINDOW_STYLE_SMALL );
return floatingWindow;
}
@Override @Override
protected ContainerListener createToolBarContListener() { protected ContainerListener createToolBarContListener() {
return new ToolBarContListener() { return new ToolBarContListener() {

View File

@@ -420,6 +420,9 @@ public class FlatTreeUI
/** @since 2 */ /** @since 2 */
protected Object applyStyleProperty( String key, Object value ) { protected Object applyStyleProperty( String key, Object value ) {
if( "rowHeight".equals( key ) && value instanceof Integer )
value = UIScale.scale( (Integer) value );
return FlatStylingSupport.applyToAnnotatedObjectOrComponent( this, tree, key, value ); return FlatStylingSupport.applyToAnnotatedObjectOrComponent( this, tree, key, value );
} }
@@ -575,7 +578,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, clipBounds, insets, bounds, path, row, isExpanded, hasBeenExpanded, isLeaf ); paintWideSelection( g, bounds, row );
g.setColor( oldColor ); g.setColor( oldColor );
} }
return; return;
@@ -633,7 +636,7 @@ public class FlatTreeUI
if( isWideSelection() ) { if( isWideSelection() ) {
// wide selection // wide selection
paintWideSelection( g, clipBounds, insets, bounds, path, row, isExpanded, hasBeenExpanded, isLeaf ); paintWideSelection( g, bounds, row );
} else { } else {
// non-wide selection // non-wide selection
paintCellBackground( g, rendererComponent, bounds, row, true ); paintCellBackground( g, rendererComponent, bounds, row, true );
@@ -702,9 +705,7 @@ public class FlatTreeUI
return oldColor; return oldColor;
} }
private void paintWideSelection( Graphics g, Rectangle clipBounds, Insets insets, Rectangle bounds, private void paintWideSelection( Graphics g, Rectangle bounds, int row ) {
TreePath path, int row, boolean isExpanded, boolean hasBeenExpanded, boolean isLeaf )
{
float arcTop, arcBottom; float arcTop, arcBottom;
arcTop = arcBottom = UIScale.scale( selectionArc / 2f ); arcTop = arcBottom = UIScale.scale( selectionArc / 2f );

View File

@@ -46,6 +46,7 @@ import java.util.IdentityHashMap;
import java.util.WeakHashMap; import java.util.WeakHashMap;
import java.util.function.Predicate; import java.util.function.Predicate;
import java.util.function.Supplier; import java.util.function.Supplier;
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;
@@ -166,6 +167,88 @@ public class FlatUIUtils
return defaultValue; return defaultValue;
} }
/** @since 3.2 */
public static Color getSubUIColor( String key, String subKey ) {
if( subKey != null ) {
Color value = UIManager.getColor( buildSubKey( key, subKey ) );
if( value != null )
return value;
}
return UIManager.getColor( key );
}
/** @since 3.2 */
public static boolean getSubUIBoolean( String key, String subKey, boolean defaultValue ) {
if( subKey != null ) {
Object value = UIManager.get( buildSubKey( key, subKey ) );
if( value instanceof Boolean )
return (Boolean) value;
}
return getUIBoolean( key, defaultValue );
}
/** @since 3.2 */
public static int getSubUIInt( String key, String subKey, int defaultValue ) {
if( subKey != null ) {
Object value = UIManager.get( buildSubKey( key, subKey ) );
if( value instanceof Integer )
return (Integer) value;
}
return getUIInt( key, defaultValue );
}
/** @since 3.2 */
public static Insets getSubUIInsets( String key, String subKey ) {
if( subKey != null ) {
Insets value = UIManager.getInsets( buildSubKey( key, subKey ) );
if( value != null )
return value;
}
return UIManager.getInsets( key );
}
/** @since 3.2 */
public static Dimension getSubUIDimension( String key, String subKey ) {
if( subKey != null ) {
Dimension value = UIManager.getDimension( buildSubKey( key, subKey ) );
if( value != null )
return value;
}
return UIManager.getDimension( key );
}
/** @since 3.2 */
public static Icon getSubUIIcon( String key, String subKey ) {
if( subKey != null ) {
Icon value = UIManager.getIcon( buildSubKey( key, subKey ) );
if( value != null )
return value;
}
return UIManager.getIcon( key );
}
/** @since 3.2 */
public static Font getSubUIFont( String key, String subKey ) {
if( subKey != null ) {
Font value = UIManager.getFont( buildSubKey( key, subKey ) );
if( value != null )
return value;
}
return UIManager.getFont( key );
}
/**
* Inserts {@code subKey} at last dot in {@code key}.
* <p>
* E.g. {@code buildSubKey( "TitlePane.font", "small" )} returns {@code "TitlePane.small.font"}.
*/
private static String buildSubKey( String key, String subKey ) {
int dot = key.lastIndexOf( '.' );
return (dot >= 0)
? key.substring( 0, dot ) + '.' + subKey + '.' + key.substring( dot + 1 )
: key;
}
/** @since 1.1.2 */ /** @since 1.1.2 */
public static boolean getBoolean( JComponent c, String systemPropertyKey, public static boolean getBoolean( JComponent c, String systemPropertyKey,
String clientPropertyKey, String uiKey, boolean defaultValue ) String clientPropertyKey, String uiKey, boolean defaultValue )
@@ -725,7 +808,7 @@ public class FlatUIUtils
{ {
dotSize = UIScale.scale( dotSize ); dotSize = UIScale.scale( dotSize );
gap = UIScale.scale( gap ); gap = UIScale.scale( gap );
int gripSize = (dotSize * dotCount) + ((gap * (dotCount - 1))); int gripSize = (dotSize * dotCount) + (gap * (dotCount - 1));
// calculate grip position // calculate grip position
float gx; float gx;

View File

@@ -88,10 +88,6 @@ class FlatWindowsNativeWindowBorder
if( !SystemInfo.isWindows_10_orLater ) if( !SystemInfo.isWindows_10_orLater )
return null; return null;
// requires x86 architecture
if( !SystemInfo.isX86 && !SystemInfo.isX86_64 )
return null;
// check whether native library was successfully loaded // check whether native library was successfully loaded
if( !FlatNativeLibrary.isLoaded() ) if( !FlatNativeLibrary.isLoaded() )
return null; return null;

View File

@@ -28,7 +28,6 @@ import java.awt.Paint;
import java.awt.Polygon; import java.awt.Polygon;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.awt.RenderingHints; import java.awt.RenderingHints;
import java.awt.RenderingHints.Key;
import java.awt.Shape; import java.awt.Shape;
import java.awt.Stroke; import java.awt.Stroke;
import java.awt.font.FontRenderContext; import java.awt.font.FontRenderContext;
@@ -368,12 +367,12 @@ public class Graphics2DProxy
} }
@Override @Override
public void setRenderingHint( Key hintKey, Object hintValue ) { public void setRenderingHint( RenderingHints.Key hintKey, Object hintValue ) {
delegate.setRenderingHint( hintKey, hintValue ); delegate.setRenderingHint( hintKey, hintValue );
} }
@Override @Override
public Object getRenderingHint( Key hintKey ) { public Object getRenderingHint( RenderingHints.Key hintKey ) {
return delegate.getRenderingHint( hintKey ); return delegate.getRenderingHint( hintKey );
} }

View File

@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
/** /*
* @author Karl Tauber * @author Karl Tauber
*/ */
module com.formdev.flatlaf { module com.formdev.flatlaf {

View File

@@ -671,7 +671,12 @@ SplitPaneDivider.gripGap = 2
TabbedPane.tabHeight = 32 TabbedPane.tabHeight = 32
TabbedPane.tabSelectionHeight = 3 TabbedPane.tabSelectionHeight = 3
TabbedPane.cardTabSelectionHeight = 2 TabbedPane.cardTabSelectionHeight = 3
TabbedPane.tabArc = 0
TabbedPane.tabSelectionArc = 0
TabbedPane.cardTabArc = 12
TabbedPane.selectedInsets = 0,0,0,0
TabbedPane.tabSelectionInsets = 0,0,0,0
TabbedPane.contentSeparatorHeight = 1 TabbedPane.contentSeparatorHeight = 1
TabbedPane.showTabSeparators = false TabbedPane.showTabSeparators = false
TabbedPane.tabSeparatorsFullHeight = false TabbedPane.tabSeparatorsFullHeight = false
@@ -808,6 +813,7 @@ TitlePane.titleMinimumWidth = 60
TitlePane.buttonSize = 44,30 TitlePane.buttonSize = 44,30
TitlePane.buttonMinimumWidth = 30 TitlePane.buttonMinimumWidth = 30
TitlePane.buttonMaximizedHeight = 22 TitlePane.buttonMaximizedHeight = 22
TitlePane.buttonSymbolHeight = 10
TitlePane.centerTitle = false TitlePane.centerTitle = false
TitlePane.centerTitleIfMenuBarEmbedded = true TitlePane.centerTitleIfMenuBarEmbedded = true
TitlePane.showIconBesideTitle = false TitlePane.showIconBesideTitle = false
@@ -829,6 +835,16 @@ TitlePane.closePressedBackground = fade($TitlePane.closeHoverBackground,90%)
TitlePane.closeHoverForeground = #fff TitlePane.closeHoverForeground = #fff
TitlePane.closePressedForeground = #fff TitlePane.closePressedForeground = #fff
# window style "small"
TitlePane.small.font = -1
TitlePane.small.showIcon = false
TitlePane.small.buttonSize = 30,20
TitlePane.small.buttonSymbolHeight = 8
TitlePane.small.closeIcon = com.formdev.flatlaf.icons.FlatWindowCloseIcon, small
TitlePane.small.iconifyIcon = com.formdev.flatlaf.icons.FlatWindowIconifyIcon, small
TitlePane.small.maximizeIcon = com.formdev.flatlaf.icons.FlatWindowMaximizeIcon, small
TitlePane.small.restoreIcon = com.formdev.flatlaf.icons.FlatWindowRestoreIcon, small
#---- ToggleButton ---- #---- ToggleButton ----

View File

@@ -112,6 +112,9 @@ ToggleButton.endBackground = $ToggleButton.background
@ijMenuCheckBackgroundL20 = lighten(@selectionBackground,20%,derived noAutoInverse) @ijMenuCheckBackgroundL20 = lighten(@selectionBackground,20%,derived noAutoInverse)
@ijMenuCheckBackgroundD10 = darken(@selectionBackground,10%,derived noAutoInverse) @ijMenuCheckBackgroundD10 = darken(@selectionBackground,10%,derived noAutoInverse)
@ijTextBackgroundL3 = lighten(Panel.background,3%,lazy)
@ijTextBackgroundL4 = lighten(Panel.background,4%,lazy)
[Arc_Theme]CheckBoxMenuItem.foreground = lazy(MenuItem.foreground) [Arc_Theme]CheckBoxMenuItem.foreground = lazy(MenuItem.foreground)
[Arc_Theme]PopupMenu.foreground = lazy(MenuItem.foreground) [Arc_Theme]PopupMenu.foreground = lazy(MenuItem.foreground)
[Arc_Theme]RadioButtonMenuItem.foreground = lazy(MenuItem.foreground) [Arc_Theme]RadioButtonMenuItem.foreground = lazy(MenuItem.foreground)
@@ -135,53 +138,110 @@ ToggleButton.endBackground = $ToggleButton.background
[Arc_Theme_Dark]RadioButtonMenuItem.foreground = lazy(MenuItem.foreground) [Arc_Theme_Dark]RadioButtonMenuItem.foreground = lazy(MenuItem.foreground)
[Arc_Theme_Dark]ProgressBar.selectionBackground = #ddd [Arc_Theme_Dark]ProgressBar.selectionBackground = #ddd
[Arc_Theme_Dark]ProgressBar.selectionForeground = #ddd [Arc_Theme_Dark]ProgressBar.selectionForeground = #ddd
[Arc_Theme_Dark]ToolBar.separatorColor = lazy(Separator.foreground)
[Arc_Theme_Dark_-_Orange]CheckBoxMenuItem.foreground = lazy(MenuItem.foreground) [Arc_Theme_Dark_-_Orange]CheckBoxMenuItem.foreground = lazy(MenuItem.foreground)
[Arc_Theme_Dark_-_Orange]PopupMenu.foreground = lazy(MenuItem.foreground) [Arc_Theme_Dark_-_Orange]PopupMenu.foreground = lazy(MenuItem.foreground)
[Arc_Theme_Dark_-_Orange]RadioButtonMenuItem.foreground = lazy(MenuItem.foreground) [Arc_Theme_Dark_-_Orange]RadioButtonMenuItem.foreground = lazy(MenuItem.foreground)
[Arc_Theme_Dark_-_Orange]ProgressBar.selectionBackground = #ddd [Arc_Theme_Dark_-_Orange]ProgressBar.selectionBackground = #ddd
[Arc_Theme_Dark_-_Orange]ProgressBar.selectionForeground = #fff [Arc_Theme_Dark_-_Orange]ProgressBar.selectionForeground = #fff
[Arc_Theme_Dark_-_Orange]ToolBar.separatorColor = lazy(Separator.foreground)
[Carbon]Table.selectionBackground = lazy(List.selectionBackground)
[Carbon]Table.selectionInactiveForeground = lazy(List.selectionInactiveForeground)
[Carbon]TextField.background = @ijTextBackgroundL4
[Cobalt_2]Component.accentColor = lazy(Component.focusColor) [Cobalt_2]Component.accentColor = lazy(Component.focusColor)
[Cobalt_2]CheckBox.icon.background = #002946 [Cobalt_2]CheckBox.icon.background = #002946
[Cobalt_2]CheckBox.icon.checkmarkColor = #002946 [Cobalt_2]CheckBox.icon.checkmarkColor = #002946
[Cobalt_2]MenuItem.checkBackground = @ijMenuCheckBackgroundL10 [Cobalt_2]MenuItem.checkBackground = @ijMenuCheckBackgroundL10
[Cobalt_2]MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundL10 [Cobalt_2]MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundL10
[Cobalt_2]ComboBox.background = @ijTextBackgroundL3
[Cobalt_2]ComboBox.buttonBackground = @ijTextBackgroundL3
[Cobalt_2]TextField.background = @ijTextBackgroundL3
[Cobalt_2]Table.background = lazy(List.background)
[Cobalt_2]Tree.background = lazy(List.background)
[Cyan_light]MenuItem.checkBackground = @ijMenuCheckBackgroundL20 [Cyan_light]MenuItem.checkBackground = @ijMenuCheckBackgroundL20
[Cyan_light]MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundL20 [Cyan_light]MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundL20
[Dark_Flat_Theme]*.inactiveForeground = #808080
[Dark_Flat_Theme]Component.accentColor = lazy(List.selectionBackground) [Dark_Flat_Theme]Component.accentColor = lazy(List.selectionBackground)
[Dark_Flat_Theme]TableHeader.background = #3B3B3B [Dark_Flat_Theme]TableHeader.background = #3B3B3B
[Dark_Flat_Theme]TextPane.foreground = lazy(TextField.foreground)
[Dark_Flat_Theme]CheckBoxMenuItem.selectionForeground = lazy(MenuItem.selectionForeground)
[Dark_Flat_Theme]List.selectionForeground = lazy(Tree.selectionForeground)
[Dark_Flat_Theme]RadioButtonMenuItem.selectionForeground = lazy(MenuItem.selectionForeground)
[Dark_Flat_Theme]Separator.foreground = lazy(ToolBar.separatorColor)
[Dark_purple]Slider.focusedColor = fade($Component.focusColor,70%,derived) [Dark_purple]Slider.focusedColor = fade($Component.focusColor,70%,derived)
[Dracula---Zihan_Ma]Component.accentColor = lazy(Component.focusColor) [Dracula---Zihan_Ma]Component.accentColor = lazy(Component.focusColor)
[Dracula---Zihan_Ma]ComboBox.selectionBackground = lazy(List.selectionBackground)
[Dracula---Zihan_Ma]ProgressBar.selectionBackground = #fff [Dracula---Zihan_Ma]ProgressBar.selectionBackground = #fff
[Dracula---Zihan_Ma]ProgressBar.selectionForeground = #fff [Dracula---Zihan_Ma]ProgressBar.selectionForeground = #fff
[Gradianto_Dark_Fuchsia]*.selectionBackground = #8452a7
[Gradianto_Dark_Fuchsia]*.selectionInactiveBackground = #562C6A
[Gradianto_Dark_Fuchsia]MenuItem.checkBackground = @ijMenuCheckBackgroundL10 [Gradianto_Dark_Fuchsia]MenuItem.checkBackground = @ijMenuCheckBackgroundL10
[Gradianto_Dark_Fuchsia]MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundL10 [Gradianto_Dark_Fuchsia]MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundL10
[Gradianto_Dark_Fuchsia]TextField.background = @ijTextBackgroundL4
[Gradianto_Dark_Fuchsia]Tree.background = lazy(List.background)
[Gradianto_Dark_Fuchsia]Separator.foreground = lazy(ScrollBar.track)
[Gradianto_Dark_Fuchsia]ToolBar.separatorColor = lazy(ScrollBar.track)
[Gradianto_Dark_Fuchsia]ProgressBar.background = lazy(ScrollBar.track)
[Gradianto_Dark_Fuchsia]Slider.trackColor = lazy(ScrollBar.track)
[Gradianto_Deep_Ocean]TextField.background = @ijTextBackgroundL3
[Gradianto_Deep_Ocean]Tree.background = lazy(List.background)
[Gradianto_Midnight_Blue]ScrollBar.thumb = #533B6B
[Gradianto_Midnight_Blue]Table.selectionForeground = lazy(List.selectionForeground)
[Gradianto_Midnight_Blue]TextField.background = @ijTextBackgroundL4
[Gradianto_Midnight_Blue]Tree.background = lazy(List.background)
[Gradianto_Nature_Green]Table.selectionForeground = lazy(List.selectionForeground)
[Gradianto_Nature_Green]TextField.background = @ijTextBackgroundL4
[Gray]Separator.foreground = lazy(Slider.trackColor)
[Gray]ToolBar.separatorColor = lazy(Slider.trackColor)
[Gruvbox_Dark_Hard]Component.accentColor = lazy(TabbedPane.underlineColor) [Gruvbox_Dark_Hard]Component.accentColor = lazy(TabbedPane.underlineColor)
[Gruvbox_Dark_Hard]ToggleButton.selectedBackground = $ToggleButton.selectedBackground [Gruvbox_Dark_Hard]ToggleButton.selectedBackground = $ToggleButton.selectedBackground
[Gruvbox_Dark_Hard]ToggleButton.toolbar.selectedBackground = $ToggleButton.toolbar.selectedBackground [Gruvbox_Dark_Hard]ToggleButton.toolbar.selectedBackground = $ToggleButton.toolbar.selectedBackground
[Gruvbox_Dark_Hard]ComboBox.background = @ijTextBackgroundL3
[Gruvbox_Dark_Hard]ComboBox.buttonBackground = @ijTextBackgroundL3
[Gruvbox_Dark_Hard]TextField.background = @ijTextBackgroundL3
[Gruvbox_Dark_Medium]Component.accentColor = lazy(TabbedPane.underlineColor) [Gruvbox_Dark_Medium]Component.accentColor = lazy(TabbedPane.underlineColor)
[Gruvbox_Dark_Medium]ToggleButton.selectedBackground = $ToggleButton.selectedBackground [Gruvbox_Dark_Medium]ToggleButton.selectedBackground = $ToggleButton.selectedBackground
[Gruvbox_Dark_Medium]ToggleButton.toolbar.selectedBackground = $ToggleButton.toolbar.selectedBackground [Gruvbox_Dark_Medium]ToggleButton.toolbar.selectedBackground = $ToggleButton.toolbar.selectedBackground
[Gruvbox_Dark_Medium]ComboBox.background = @ijTextBackgroundL3
[Gruvbox_Dark_Medium]ComboBox.buttonBackground = @ijTextBackgroundL3
[Gruvbox_Dark_Medium]TextField.background = @ijTextBackgroundL3
[Gruvbox_Dark_Soft]Component.accentColor = lazy(TabbedPane.underlineColor) [Gruvbox_Dark_Soft]Component.accentColor = lazy(TabbedPane.underlineColor)
[Gruvbox_Dark_Soft]MenuItem.checkBackground = @ijMenuCheckBackgroundL10 [Gruvbox_Dark_Soft]MenuItem.checkBackground = @ijMenuCheckBackgroundL10
[Gruvbox_Dark_Soft]MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundL10 [Gruvbox_Dark_Soft]MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundL10
[Gruvbox_Dark_Soft]ToggleButton.selectedBackground = $ToggleButton.selectedBackground [Gruvbox_Dark_Soft]ToggleButton.selectedBackground = $ToggleButton.selectedBackground
[Gruvbox_Dark_Soft]ToggleButton.toolbar.selectedBackground = $ToggleButton.toolbar.selectedBackground [Gruvbox_Dark_Soft]ToggleButton.toolbar.selectedBackground = $ToggleButton.toolbar.selectedBackground
[Gruvbox_Dark_Soft]ComboBox.background = @ijTextBackgroundL3
[Gruvbox_Dark_Soft]ComboBox.buttonBackground = @ijTextBackgroundL3
[Gruvbox_Dark_Soft]TextField.background = @ijTextBackgroundL3
[Hiberbee_Dark]*.disabledForeground = #7F7E7D
[Hiberbee_Dark]*.disabledText = #7F7E7D
[Hiberbee_Dark]*.inactiveForeground = #7F7E7D
[Hiberbee_Dark]ProgressBar.background = lazy(Separator.foreground)
[Hiberbee_Dark]Slider.trackColor = lazy(Separator.foreground)
[Hiberbee_Dark]TabbedPane.focusColor = #5A5A5A [Hiberbee_Dark]TabbedPane.focusColor = #5A5A5A
[Hiberbee_Dark]TabbedPane.selectedBackground = #434241 [Hiberbee_Dark]TabbedPane.selectedBackground = #434241
[Hiberbee_Dark]TabbedPane.selectedForeground = #70D7FF [Hiberbee_Dark]TabbedPane.selectedForeground = #70D7FF
[Hiberbee_Dark]ToggleButton.selectedBackground = $ToggleButton.selectedBackground [Hiberbee_Dark]ToggleButton.selectedBackground = $ToggleButton.selectedBackground
[Hiberbee_Dark]ToggleButton.toolbar.selectedBackground = $ToggleButton.toolbar.selectedBackground [Hiberbee_Dark]ToggleButton.toolbar.selectedBackground = $ToggleButton.toolbar.selectedBackground
[Hiberbee_Dark]Table.selectionInactiveBackground = lazy(List.selectionInactiveBackground)
[Hiberbee_Dark]Tree.selectionBackground = lazy(List.selectionBackground)
[Hiberbee_Dark]Tree.selectionInactiveBackground = lazy(List.selectionInactiveBackground)
[High_contrast]Component.accentColor = lazy(Component.focusColor) [High_contrast]Component.accentColor = lazy(Component.focusColor)
[High_contrast]ToggleButton.selectedBackground = #fff [High_contrast]ToggleButton.selectedBackground = #fff
@@ -194,9 +254,20 @@ ToggleButton.endBackground = $ToggleButton.background
toolbar.selectedBackground: #fff toolbar.selectedBackground: #fff
[High_contrast][style]ToggleButton.inTextField = $[High_contrast][style]Button.inTextField [High_contrast][style]ToggleButton.inTextField = $[High_contrast][style]Button.inTextField
[Light_Flat]*.disabledForeground = #8C8C8C
[Light_Flat]*.inactiveForeground = #8C8C8C
[Light_Flat]CheckBox.icon[filled].background = #fff
[Light_Flat]CheckBox.icon[filled].checkmarkColor = #fff
[Light_Flat]Component.accentColor = lazy(TabbedPane.underlineColor) [Light_Flat]Component.accentColor = lazy(TabbedPane.underlineColor)
[Light_Flat]ComboBox.background = lazy(ComboBox.editableBackground)
[Light_Flat]ComboBox.buttonBackground = lazy(ComboBox.editableBackground)
[Light_Flat]Separator.foreground = lazy(ToolBar.separatorColor)
[Light_Flat]TableHeader.background = #E5E5E9 [Light_Flat]TableHeader.background = #E5E5E9
[Light_Flat]TextPane.foreground = lazy(TextField.foreground)
[Light_Flat]CheckBoxMenuItem.selectionForeground = lazy(MenuItem.selectionForeground)
[Light_Flat]RadioButtonMenuItem.selectionForeground = lazy(MenuItem.selectionForeground)
[Monocai]Button.default.foreground = #2D2A2F
[Monocai]MenuItem.checkBackground = @ijMenuCheckBackgroundL10 [Monocai]MenuItem.checkBackground = @ijMenuCheckBackgroundL10
[Monocai]MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundL10 [Monocai]MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundL10
@Monocai.acceleratorForeground = lazy(MenuItem.disabledForeground) @Monocai.acceleratorForeground = lazy(MenuItem.disabledForeground)
@@ -209,22 +280,67 @@ ToggleButton.endBackground = $ToggleButton.background
[Monocai]MenuItem.acceleratorSelectionForeground = @Monocai.acceleratorSelectionForeground [Monocai]MenuItem.acceleratorSelectionForeground = @Monocai.acceleratorSelectionForeground
[Monocai]RadioButtonMenuItem.acceleratorForeground = @Monocai.acceleratorForeground [Monocai]RadioButtonMenuItem.acceleratorForeground = @Monocai.acceleratorForeground
[Monocai]RadioButtonMenuItem.acceleratorSelectionForeground = @Monocai.acceleratorSelectionForeground [Monocai]RadioButtonMenuItem.acceleratorSelectionForeground = @Monocai.acceleratorSelectionForeground
[Monocai]TextField.background = @ijTextBackgroundL4
@Monocai.selectionBackground = lazy(TextField.selectionBackground)
[Monocai]ComboBox.selectionBackground = @Monocai.selectionBackground
[Monocai]List.selectionBackground = @Monocai.selectionBackground
[Monocai]Table.selectionBackground = @Monocai.selectionBackground
[Monocai]Tree.selectionBackground = @Monocai.selectionBackground
@Monocai.selectionInactiveBackground = lazy(MenuItem.selectionBackground)
[Monocai]List.selectionInactiveBackground = @Monocai.selectionInactiveBackground
[Monocai]Table.selectionInactiveBackground = @Monocai.selectionInactiveBackground
[Monocai]Tree.selectionInactiveBackground = @Monocai.selectionInactiveBackground
[Monokai_Pro]TitledBorder.titleColor = @foreground [Monokai_Pro---Subtheme]Table.selectionInactiveForeground = lazy(List.selectionInactiveForeground)
[Monokai_Pro---Subtheme]Tree.selectionBackground = lazy(List.selectionBackground)
[Monokai_Pro---Subtheme]Separator.foreground = lazy(Slider.trackColor)
[Monokai_Pro---Subtheme]ToolBar.separatorColor = lazy(Slider.trackColor)
[Nord]*.inactiveForeground = #616E88
[Nord]MenuItem.checkBackground = @ijMenuCheckBackgroundL10 [Nord]MenuItem.checkBackground = @ijMenuCheckBackgroundL10
[Nord]MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundL10 [Nord]MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundL10
[Nord]List.selectionBackground = lazy(Tree.selectionBackground)
[Nord]List.selectionForeground = lazy(Tree.selectionForeground)
[Nord]Table.selectionBackground = lazy(Tree.selectionBackground)
[Nord]Table.selectionForeground = lazy(Tree.selectionForeground)
[Nord]TextField.selectionBackground = lazy(Tree.selectionBackground)
[Nord]TextField.selectionForeground = lazy(Tree.selectionForeground)
[Nord]Tree.selectionInactiveForeground = lazy(List.selectionInactiveForeground)
[NotReallyMDTheme]*.selectionInactiveBackground = #21384E
[NotReallyMDTheme]ToolBar.separatorColor = lazy(Separator.foreground)
[One_Dark]List.selectionInactiveForeground = lazy(Tree.selectionInactiveForeground)
[One_Dark]MenuItem.checkBackground = @ijMenuCheckBackgroundL10 [One_Dark]MenuItem.checkBackground = @ijMenuCheckBackgroundL10
[One_Dark]MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundL10 [One_Dark]MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundL10
[One_Dark]ProgressBar.background = lazy(Separator.foreground)
[One_Dark]Slider.trackColor = lazy(Separator.foreground)
[One_Dark]Slider.focusedColor = fade(#568af2,40%) [One_Dark]Slider.focusedColor = fade(#568af2,40%)
[One_Dark]Table.background = lazy(Tree.background)
[One_Dark]Table.selectionBackground = lazy(Tree.selectionBackground)
[One_Dark]TextField.selectionBackground = lazy(List.selectionBackground)
[One_Dark]Tree.selectionForeground = lazy(List.selectionForeground)
[Solarized_Dark---4lex4]*.inactiveForeground = #657B83
[Solarized_Dark---4lex4]Component.accentColor = lazy(TabbedPane.underlineColor) [Solarized_Dark---4lex4]Component.accentColor = lazy(TabbedPane.underlineColor)
[Solarized_Dark---4lex4]ComboBox.background = lazy(ComboBox.editableBackground)
[Solarized_Dark---4lex4]ComboBox.buttonBackground = lazy(ComboBox.editableBackground)
[Solarized_Dark---4lex4]Slider.focusedColor = fade($Component.focusColor,80%,derived) [Solarized_Dark---4lex4]Slider.focusedColor = fade($Component.focusColor,80%,derived)
[Solarized_Dark---4lex4]ToolBar.separatorColor = lazy(Separator.foreground)
[Solarized_Light---4lex4]*.inactiveForeground = #839496
[Solarized_Light---4lex4]Button.default.hoverBackground = darken($Button.default.background,3%,derived) [Solarized_Light---4lex4]Button.default.hoverBackground = darken($Button.default.background,3%,derived)
[Solarized_Light---4lex4]Component.accentColor = lazy(TabbedPane.underlineColor) [Solarized_Light---4lex4]Component.accentColor = lazy(TabbedPane.underlineColor)
[Spacegray]ComboBox.background = @ijTextBackgroundL4
[Spacegray]ComboBox.buttonBackground = @ijTextBackgroundL4
[Spacegray]TextField.background = @ijTextBackgroundL4
[Spacegray]TextField.selectionBackground = lazy(Tree.selectionBackground)
[Spacegray]TextField.selectionForeground = lazy(Tree.selectionForeground)
[vuesion-theme]*.disabledForeground = #8C8C8C
[vuesion-theme]*.disabledText = #8C8C8C
[vuesion-theme]*.inactiveForeground = #8C8C8C
[vuesion-theme]Component.accentColor = lazy(Button.default.endBackground) [vuesion-theme]Component.accentColor = lazy(Button.default.endBackground)
[vuesion-theme]MenuItem.checkBackground = @ijMenuCheckBackgroundL10 [vuesion-theme]MenuItem.checkBackground = @ijMenuCheckBackgroundL10
[vuesion-theme]MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundL10 [vuesion-theme]MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundL10
@@ -232,6 +348,12 @@ ToggleButton.endBackground = $ToggleButton.background
[vuesion-theme]Slider.trackColor = #303a45 [vuesion-theme]Slider.trackColor = #303a45
[vuesion-theme]Slider.thumbColor = #ececee [vuesion-theme]Slider.thumbColor = #ececee
[vuesion-theme]Slider.focusedColor = fade(#ececee,20%) [vuesion-theme]Slider.focusedColor = fade(#ececee,20%)
[vuesion-theme]ComboBox.background = @ijTextBackgroundL4
[vuesion-theme]ComboBox.buttonBackground = @ijTextBackgroundL4
[vuesion-theme]TextField.background = @ijTextBackgroundL4
[vuesion-theme]TextField.selectionBackground = lighten(#303A45,15%)
[Xcode-Dark]TextField.background = @ijTextBackgroundL4
# Material Theme UI Lite # Material Theme UI Lite
@@ -241,62 +363,106 @@ ToggleButton.endBackground = $ToggleButton.background
[dark][author-Mallowigi]MenuItem.checkBackground = @ijMenuCheckBackgroundL20 [dark][author-Mallowigi]MenuItem.checkBackground = @ijMenuCheckBackgroundL20
[dark][author-Mallowigi]MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundL20 [dark][author-Mallowigi]MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundL20
[author-Mallowigi]Tree.selectionInactiveBackground = lazy(List.selectionInactiveBackground)
[Arc_Dark]ComboBox.selectionBackground = lazy(List.selectionBackground)
[Arc_Dark]Table.selectionBackground = lazy(List.selectionBackground)
[Atom_One_Dark]Separator.foreground = lazy(Slider.trackColor)
[Atom_One_Dark]ToolBar.separatorColor = lazy(Slider.trackColor)
[Atom_One_Light]List.selectionBackground = lazy(Table.selectionBackground)
[Atom_One_Light]Tree.selectionBackground = lazy(Table.selectionBackground)
[Atom_One_Light]TabbedPane.contentAreaColor = lazy(Separator.foreground)
[Dracula---Mallowigi]*.selectionBackground = #44475A
[Dracula---Mallowigi]List.selectionInactiveForeground = lazy(Tree.selectionInactiveForeground)
[Dracula---Mallowigi]ProgressBar.selectionBackground = #fff [Dracula---Mallowigi]ProgressBar.selectionBackground = #fff
[Dracula---Mallowigi]ProgressBar.selectionForeground = #fff [Dracula---Mallowigi]ProgressBar.selectionForeground = #fff
[Dracula---Mallowigi]RadioButtonMenuItem.selectionForeground = lazy(CheckBoxMenuItem.selectionForeground)
[Dracula_Contrast]ProgressBar.selectionBackground = #fff [Dracula---Mallowigi]Table.selectionForeground = lazy(List.selectionForeground)
[Dracula_Contrast]ProgressBar.selectionForeground = #fff [Dracula---Mallowigi]Separator.foreground = lazy(Slider.trackColor)
[Dracula---Mallowigi]ToolBar.separatorColor = lazy(Slider.trackColor)
[GitHub]ProgressBar.selectionBackground = #222 [GitHub]ProgressBar.selectionBackground = #222
[GitHub]ProgressBar.selectionForeground = #222 [GitHub]ProgressBar.selectionForeground = #222
[GitHub]TextField.background = @ijTextBackgroundL3
[GitHub]List.selectionBackground = lazy(Table.selectionBackground)
[GitHub]Tree.selectionBackground = lazy(Table.selectionBackground)
[GitHub_Contrast]ProgressBar.selectionBackground = #222 [GitHub_Dark]ComboBox.selectionBackground = lazy(Tree.selectionBackground)
[GitHub_Contrast]ProgressBar.selectionForeground = #222 [GitHub_Dark]Table.selectionBackground = lazy(Tree.selectionBackground)
[GitHub_Dark]Separator.foreground = lazy(Slider.trackColor)
[GitHub_Dark]ToolBar.separatorColor = lazy(Slider.trackColor)
[Light_Owl]CheckBoxMenuItem.selectionForeground = lazy(CheckBoxMenuItem.foreground)
[Light_Owl]ComboBox.selectionForeground = lazy(ComboBox.foreground)
[Light_Owl]List.selectionInactiveForeground = lazy(List.foreground) [Light_Owl]List.selectionInactiveForeground = lazy(List.foreground)
[Light_Owl]Menu.selectionForeground = lazy(Menu.foreground)
[Light_Owl]MenuBar.selectionForeground = lazy(MenuBar.foreground)
[Light_Owl]MenuItem.selectionForeground = lazy(MenuItem.foreground)
[Light_Owl]ProgressBar.selectionBackground = #111 [Light_Owl]ProgressBar.selectionBackground = #111
[Light_Owl]ProgressBar.selectionForeground = #fff [Light_Owl]ProgressBar.selectionForeground = #fff
[Light_Owl]TabbedPane.selectedForeground = lazy(TabbedPane.foreground) [Light_Owl]Spinner.selectionForeground = lazy(Spinner.foreground)
[Light_Owl]Table.selectionForeground = lazy(Table.foreground) [Light_Owl]Table.selectionForeground = lazy(Table.foreground)
[Light_Owl]TextField.selectionForeground = lazy(TextField.foreground)
[Light_Owl]TextField.background = @ijTextBackgroundL3
[Light_Owl]List.selectionBackground = lazy(Table.selectionBackground)
[Light_Owl]Tree.selectionBackground = lazy(Table.selectionBackground)
[Light_Owl_Contrast]List.selectionInactiveForeground = lazy(List.foreground) [Material_Darker]*.selectionBackground = lighten(#2D2D2D,15%)
[Light_Owl_Contrast]ProgressBar.selectionBackground = #111 [Material_Darker]Separator.foreground = lazy(Slider.trackColor)
[Light_Owl_Contrast]ProgressBar.selectionForeground = #fff [Material_Darker]ToolBar.separatorColor = lazy(Slider.trackColor)
[Light_Owl_Contrast]TabbedPane.selectedForeground = lazy(TabbedPane.foreground)
[Light_Owl_Contrast]Table.selectionForeground = lazy(Table.foreground)
[Material_Deep_Ocean]*.selectionBackground = lighten(#222533,15%)
[Material_Deep_Ocean]Separator.foreground = lazy(Slider.trackColor)
[Material_Deep_Ocean]ToolBar.separatorColor = lazy(Slider.trackColor)
[Material_Lighter]List.selectionInactiveForeground = lazy(Tree.selectionInactiveForeground)
[Material_Lighter]ProgressBar.selectionBackground = #222 [Material_Lighter]ProgressBar.selectionBackground = #222
[Material_Lighter]ProgressBar.selectionForeground = #fff [Material_Lighter]ProgressBar.selectionForeground = #fff
[Material_Lighter]ComboBox.selectionBackground = lazy(List.selectionBackground)
[Material_Lighter_Contrast]ProgressBar.selectionBackground = #222 [Material_Lighter]Table.selectionBackground = lazy(List.selectionBackground)
[Material_Lighter_Contrast]ProgressBar.selectionForeground = #fff [Material_Lighter]List.selectionForeground = lazy(Table.selectionForeground)
[Material_Lighter]RadioButtonMenuItem.selectionForeground = lazy(Table.selectionForeground)
[Material_Lighter]Tree.selectionForeground = lazy(Table.selectionForeground)
[Material_Oceanic]ProgressBar.selectionBackground = #ddd [Material_Oceanic]ProgressBar.selectionBackground = #ddd
[Material_Oceanic]ProgressBar.selectionForeground = #ddd [Material_Oceanic]ProgressBar.selectionForeground = #ddd
[Material_Oceanic]Separator.foreground = lazy(Slider.trackColor)
[Material_Oceanic_Contrast]ProgressBar.selectionBackground = #ddd [Material_Oceanic]ToolBar.separatorColor = lazy(Slider.trackColor)
[Material_Oceanic_Contrast]ProgressBar.selectionForeground = #ddd
[Material_Palenight]ProgressBar.selectionBackground = #ddd [Material_Palenight]ProgressBar.selectionBackground = #ddd
[Material_Palenight]ProgressBar.selectionForeground = #ddd [Material_Palenight]ProgressBar.selectionForeground = #ddd
[Material_Palenight]List.selectionBackground = lazy(Table.selectionBackground)
[Material_Palenight]Tree.selectionBackground = lazy(Table.selectionBackground)
[Material_Palenight]Separator.foreground = lazy(Slider.trackColor)
[Material_Palenight]ToolBar.separatorColor = lazy(Slider.trackColor)
[Material_Palenight_Contrast]ProgressBar.selectionBackground = #ddd [Monokai_Pro---Mallowigi]List.selectionForeground = lazy(Table.selectionForeground)
[Material_Palenight_Contrast]ProgressBar.selectionForeground = #ddd [Monokai_Pro---Mallowigi]RadioButtonMenuItem.selectionForeground = lazy(Table.selectionForeground)
[Monokai_Pro---Mallowigi]Table.selectionInactiveForeground = lazy(List.selectionInactiveForeground)
[Monokai_Pro---Mallowigi]Tree.selectionForeground = lazy(Table.selectionForeground)
[Monokai_Pro---Mallowigi]Tree.selectionInactiveForeground = lazy(List.selectionInactiveForeground)
[Monokai_Pro---Mallowigi]Separator.foreground = lazy(Slider.trackColor)
[Monokai_Pro---Mallowigi]ToolBar.separatorColor = lazy(Slider.trackColor)
[Moonlight]ComboBox.selectionBackground = lazy(List.selectionBackground)
[Moonlight]Table.selectionBackground = lazy(List.selectionBackground)
[Moonlight]Separator.foreground = lazy(Slider.trackColor)
[Moonlight]ToolBar.separatorColor = lazy(Slider.trackColor)
[Night_Owl]ProgressBar.selectionBackground = #ddd [Night_Owl]ProgressBar.selectionBackground = #ddd
[Night_Owl]ProgressBar.selectionForeground = #ddd [Night_Owl]ProgressBar.selectionForeground = #ddd
[Night_Owl_Contrast]ProgressBar.selectionBackground = #ddd
[Night_Owl_Contrast]ProgressBar.selectionForeground = #ddd
[Solarized_Dark---Mallowigi]ProgressBar.selectionBackground = #ccc [Solarized_Dark---Mallowigi]ProgressBar.selectionBackground = #ccc
[Solarized_Dark---Mallowigi]ProgressBar.selectionForeground = #ccc [Solarized_Dark---Mallowigi]ProgressBar.selectionForeground = #ccc
[Solarized_Dark---Mallowigi]Separator.foreground = lazy(Slider.trackColor)
[Solarized_Dark_Contrast]ProgressBar.selectionBackground = #ccc [Solarized_Dark---Mallowigi]ToolBar.separatorColor = lazy(Slider.trackColor)
[Solarized_Dark_Contrast]ProgressBar.selectionForeground = #ccc
[Solarized_Light---Mallowigi]ProgressBar.selectionBackground = #222 [Solarized_Light---Mallowigi]ProgressBar.selectionBackground = #222
[Solarized_Light---Mallowigi]ProgressBar.selectionForeground = #fff [Solarized_Light---Mallowigi]ProgressBar.selectionForeground = #fff
[Solarized_Light---Mallowigi]ComboBox.selectionBackground = lazy(List.selectionBackground)
[Solarized_Light_Contrast]ProgressBar.selectionBackground = #222 [Solarized_Light---Mallowigi]Table.selectionBackground = lazy(List.selectionBackground)
[Solarized_Light_Contrast]ProgressBar.selectionForeground = #fff [Solarized_Light---Mallowigi]Separator.foreground = lazy(Slider.trackColor)
[Solarized_Light---Mallowigi]ToolBar.separatorColor = lazy(Slider.trackColor)

View File

@@ -12,42 +12,6 @@
# limitations under the License. # limitations under the License.
# #
#---- FileChooser ----
#fields
FileChooser.lookInLabel.textAndMnemonic = Look &In:
FileChooser.saveInLabelText = Save In:
FileChooser.fileNameLabel.textAndMnemonic = File &Name:
FileChooser.folderNameLabel.textAndMnemonic = Folder &name:
FileChooser.filesOfTypeLabel.textAndMnemonic = Files of &Type:
# toolbar
FileChooser.upFolderToolTipText = Up One Level
FileChooser.upFolderAccessibleName = Up
FileChooser.homeFolderToolTipText = Home
FileChooser.homeFolderAccessibleName = Home
FileChooser.newFolderToolTipText = Create New Folder
FileChooser.newFolderAccessibleName = New Folder
FileChooser.listViewButtonToolTipText = List
FileChooser.listViewButtonAccessibleName = List
FileChooser.detailsViewButtonToolTipText = Details
FileChooser.detailsViewButtonAccessibleName = Details
# details table header
FileChooser.fileNameHeaderText = Name
FileChooser.fileSizeHeaderText = Size
FileChooser.fileTypeHeaderText = Type
FileChooser.fileDateHeaderText = Modified
FileChooser.fileAttrHeaderText = Attributes
# popup menu
FileChooser.viewMenuLabelText = View
FileChooser.refreshActionLabelText = Refresh
FileChooser.newFolderActionLabelText = New Folder
FileChooser.listViewActionLabelText = List
FileChooser.detailsViewActionLabelText = Details
#---- SplitPaneDivider ---- #---- SplitPaneDivider ----
SplitPaneDivider.collapseLeftToolTipText = Collapse Left Pane SplitPaneDivider.collapseLeftToolTipText = Collapse Left Pane

View File

@@ -12,42 +12,6 @@
# limitations under the License. # limitations under the License.
# #
#---- FileChooser ----
#fields
FileChooser.lookInLabel.textAndMnemonic = Suchen &in:
FileChooser.saveInLabelText = Speichern in:
FileChooser.fileNameLabel.textAndMnemonic = &Dateiname:
FileChooser.folderNameLabel.textAndMnemonic = Ordner&name:
FileChooser.filesOfTypeLabel.textAndMnemonic = Datei&typ:
# toolbar
FileChooser.upFolderToolTipText = Eine Ebene h\u00F6her
FileChooser.upFolderAccessibleName = Nach oben
FileChooser.homeFolderToolTipText = Home
FileChooser.homeFolderAccessibleName = Home
FileChooser.newFolderToolTipText = Neuen Ordner erstellen
FileChooser.newFolderAccessibleName = Neuer Ordner
FileChooser.listViewButtonToolTipText = Liste
FileChooser.listViewButtonAccessibleName = Liste
FileChooser.detailsViewButtonToolTipText = Details
FileChooser.detailsViewButtonAccessibleName = Details
# details table header
FileChooser.fileNameHeaderText = Name
FileChooser.fileSizeHeaderText = Gr\u00F6\u00DFe
FileChooser.fileTypeHeaderText = Typ
FileChooser.fileDateHeaderText = \u00C4nderungsdatum
FileChooser.fileAttrHeaderText = Attribute
# popup menu
FileChooser.viewMenuLabelText = Ansicht
FileChooser.refreshActionLabelText = Aktualisieren
FileChooser.newFolderActionLabelText = Neuer Ordner
FileChooser.listViewActionLabelText = Liste
FileChooser.detailsViewActionLabelText = Details
#---- TabbedPane ---- #---- TabbedPane ----
TabbedPane.moreTabsButtonToolTipText = Verdeckte Tabs anzeigen TabbedPane.moreTabsButtonToolTipText = Verdeckte Tabs anzeigen

View File

@@ -12,42 +12,6 @@
# limitations under the License. # limitations under the License.
# #
#---- FileChooser ----
#fields
FileChooser.lookInLabel.textAndMnemonic = Buscar &en:
FileChooser.saveInLabelText = Guardar en:
FileChooser.fileNameLabel.textAndMnemonic = &Nombre de fichero:
FileChooser.folderNameLabel.textAndMnemonic = &Nombre de carpeta:
FileChooser.filesOfTypeLabel.textAndMnemonic = Ficheros de &Tipo:
# toolbar
FileChooser.upFolderToolTipText = Subir un nivel
FileChooser.upFolderAccessibleName = Subir
FileChooser.homeFolderToolTipText = Inicio
FileChooser.homeFolderAccessibleName = Inicio
FileChooser.newFolderToolTipText = Crear nueva carpeta
FileChooser.newFolderAccessibleName = Nueva carpeta
FileChooser.listViewButtonToolTipText = Lista
FileChooser.listViewButtonAccessibleName = Lista
FileChooser.detailsViewButtonToolTipText = Detalles
FileChooser.detailsViewButtonAccessibleName = Detalles
# details table header
FileChooser.fileNameHeaderText = Nombre
FileChooser.fileSizeHeaderText = Tama\u00F1o
FileChooser.fileTypeHeaderText = Tipo
FileChooser.fileDateHeaderText = Modificado
FileChooser.fileAttrHeaderText = Atributos
# popup menu
FileChooser.viewMenuLabelText = Ver
FileChooser.refreshActionLabelText = Refrescar
FileChooser.newFolderActionLabelText = Nueva carpeta
FileChooser.listViewActionLabelText = Lista
FileChooser.detailsViewActionLabelText = Detalles
#---- SplitPaneDivider ---- #---- SplitPaneDivider ----
SplitPaneDivider.collapseLeftToolTipText = Contraer Panel Izquierdo SplitPaneDivider.collapseLeftToolTipText = Contraer Panel Izquierdo

View File

@@ -12,37 +12,3 @@
# limitations under the License. # limitations under the License.
# #
#---- FileChooser ----
#fields
FileChooser.lookInLabel.textAndMnemonic = Rechercher &dans:
FileChooser.saveInLabelText = Enregistrer dans:
FileChooser.fileNameLabel.textAndMnemonic = &Nom du fichier:
FileChooser.folderNameLabel.textAndMnemonic = &Nom du dossier:
FileChooser.filesOfTypeLabel.textAndMnemonic = &Type de fichier:
# toolbar
FileChooser.upFolderToolTipText = Remonte d'un niveau
FileChooser.upFolderAccessibleName = Monter
FileChooser.homeFolderToolTipText = R\u00E9pertoire de base
FileChooser.homeFolderAccessibleName = R\u00E9pertoire de base
FileChooser.newFolderToolTipText = Cr\u00E9e un dossier
FileChooser.newFolderAccessibleName = Nouveau dossier
FileChooser.listViewButtonToolTipText = Liste
FileChooser.listViewButtonAccessibleName = Liste
FileChooser.detailsViewButtonToolTipText = D\u00E9tails
FileChooser.detailsViewButtonAccessibleName = D\u00E9tails
# details table header
FileChooser.fileNameHeaderText = Nom
FileChooser.fileSizeHeaderText = Taille
FileChooser.fileTypeHeaderText = Type
FileChooser.fileDateHeaderText = Modifi\u00E9
FileChooser.fileAttrHeaderText = Attributs
# popup menu
FileChooser.viewMenuLabelText = Affichage
FileChooser.refreshActionLabelText = Actualiser
FileChooser.newFolderActionLabelText = Nouveau dossier
FileChooser.listViewActionLabelText = Liste
FileChooser.detailsViewActionLabelText = D\u00E9tails

View File

@@ -67,11 +67,11 @@
@nsControlAccentColor = #007aff @nsControlAccentColor = #007aff
# accent colors are: # accent colors are:
# @nsSelectedTextBackgroundColor # @nsSelectedTextBackgroundColor for @textSelectionBackground
# @nsSelectedContentBackgroundColor # @nsSelectedContentBackgroundColor for @selectionBackground
# @nsSelectedControlColor # @nsSelectedControlColor unused
# @nsKeyboardFocusIndicatorColor # @nsKeyboardFocusIndicatorColor for @accentFocusColor
# @nsControlAccentColor # @nsControlAccentColor for @accentColor
#---- variables ---- #---- variables ----
@@ -88,12 +88,12 @@
@menuBackground = lighten(@background,8%) @menuBackground = lighten(@background,8%)
# selection # selection
@selectionBackground = if(systemColor(accent), shade(spin(systemColor(accent),4),20%), @nsSelectedContentBackgroundColor) @selectionBackground = shade(spin(if(systemColor(accent), systemColor(accent), @accentColor),4),20%)
@selectionForeground = @nsSelectedMenuItemTextColor @selectionForeground = @nsSelectedMenuItemTextColor
@selectionInactiveBackground = @nsUnemphasizedSelectedContentBackgroundColor @selectionInactiveBackground = @nsUnemphasizedSelectedContentBackgroundColor
# text selection # text selection
@textSelectionBackground = systemColor(highlight,if(systemColor(accent), darken(desaturate(systemColor(accent),60%),10%), @nsSelectedTextBackgroundColor)) @textSelectionBackground = systemColor(highlight,darken(desaturate(if(systemColor(accent), systemColor(accent), @accentColor),60%),10%))
@textSelectionForeground = @nsSelectedTextColor @textSelectionForeground = @nsSelectedTextColor
# menu # menu
@@ -102,7 +102,7 @@
# accent colors (blueish) # accent colors (blueish)
@accentColor = systemColor(accent,@nsControlAccentColor) @accentColor = systemColor(accent,@nsControlAccentColor)
@accentFocusColor = if(systemColor(accent), fade(spin(systemColor(accent),-10),50%), @nsKeyboardFocusIndicatorColor) @accentFocusColor = fade(lighten(spin(if(systemColor(accent), systemColor(accent), @accentColor),-8),5%),50%)
#---- Button ---- #---- Button ----
@@ -261,6 +261,13 @@ Spinner.buttonPressedArrowColor = lighten($Spinner.buttonArrowColor,20%,derived
Spinner.buttonSeparatorWidth = 0 Spinner.buttonSeparatorWidth = 0
#---- TabbedPane ----
TabbedPane.tabArc = $Button.arc
TabbedPane.tabSelectionArc = 999
TabbedPane.cardTabArc = $Button.arc
#---- TextArea --- #---- TextArea ---
TextArea.disabledBackground = @disabledComponentBackground TextArea.disabledBackground = @disabledComponentBackground

View File

@@ -67,11 +67,11 @@
@nsControlAccentColor = #007aff @nsControlAccentColor = #007aff
# accent colors are: # accent colors are:
# @nsSelectedTextBackgroundColor # @nsSelectedTextBackgroundColor for @textSelectionBackground
# @nsSelectedContentBackgroundColor # @nsSelectedContentBackgroundColor for @selectionBackground
# @nsSelectedControlColor # @nsSelectedControlColor unused
# @nsKeyboardFocusIndicatorColor # @nsKeyboardFocusIndicatorColor for @accentFocusColor
# @nsControlAccentColor # @nsControlAccentColor for @accentColor
#---- variables ---- #---- variables ----
@@ -88,12 +88,12 @@
@menuBackground = darken(@background,4%) @menuBackground = darken(@background,4%)
# selection # selection
@selectionBackground = if(systemColor(accent), shade(spin(systemColor(accent),4),10%), @nsSelectedContentBackgroundColor) @selectionBackground = shade(spin(if(systemColor(accent), systemColor(accent), @accentColor),4),10%)
@selectionForeground = @nsSelectedMenuItemTextColor @selectionForeground = @nsSelectedMenuItemTextColor
@selectionInactiveBackground = @nsUnemphasizedSelectedContentBackgroundColor @selectionInactiveBackground = @nsUnemphasizedSelectedContentBackgroundColor
# text selection # text selection
@textSelectionBackground = systemColor(highlight,if(systemColor(accent), tint(systemColor(accent),70%), @nsSelectedTextBackgroundColor)) @textSelectionBackground = systemColor(highlight,tint(if(systemColor(accent), systemColor(accent), @accentColor),70%))
@textSelectionForeground = @foreground @textSelectionForeground = @foreground
# menu # menu
@@ -103,7 +103,7 @@
# accent colors (blueish) # accent colors (blueish)
@accentColor = systemColor(accent,@nsControlAccentColor) @accentColor = systemColor(accent,@nsControlAccentColor)
@accentFocusColor = if(systemColor(accent), fade(spin(systemColor(accent),4),50%), @nsKeyboardFocusIndicatorColor) @accentFocusColor = fade(spin(if(systemColor(accent), systemColor(accent), @accentColor),4),50%)
#---- Button ---- #---- Button ----
@@ -260,6 +260,13 @@ Spinner.buttonHoverArrowColor = lighten($Spinner.buttonArrowColor,20%,derived no
Spinner.buttonPressedArrowColor = lighten($Spinner.buttonArrowColor,30%,derived noAutoInverse) Spinner.buttonPressedArrowColor = lighten($Spinner.buttonArrowColor,30%,derived noAutoInverse)
#---- TabbedPane ----
TabbedPane.tabArc = $Button.arc
TabbedPane.tabSelectionArc = 999
TabbedPane.cardTabArc = $Button.arc
#---- TextArea --- #---- TextArea ---
TextArea.disabledBackground = @disabledComponentBackground TextArea.disabledBackground = @disabledComponentBackground

View File

@@ -21,6 +21,7 @@ import java.awt.Color;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.Font; import java.awt.Font;
import java.awt.Insets; import java.awt.Insets;
import java.util.Objects;
import javax.swing.UIManager; import javax.swing.UIManager;
import javax.swing.border.Border; import javax.swing.border.Border;
import javax.swing.UIDefaults.ActiveValue; import javax.swing.UIDefaults.ActiveValue;
@@ -153,4 +154,103 @@ public class TestUIDefaultsLoader
new Font( name, style, size ), new Font( name, style, size ),
((ActiveValue)UIDefaultsLoader.parseValue( "dummyFont", actualStyle, null )).createValue( null ) ); ((ActiveValue)UIDefaultsLoader.parseValue( "dummyFont", actualStyle, null )).createValue( null ) );
} }
@Test
void parseInstance() {
String className = TestInstance.class.getName();
assertEquals( new TestInstance(), ((LazyValue)UIDefaultsLoader.parseValue( "dummyIcon", className, null )).createValue( null ) );
assertInstanceEquals( new TestInstance(), null );
assertInstanceEquals( new TestInstance( "some string" ), "some string" );
assertInstanceEquals( new TestInstance( false ), "false" );
assertInstanceEquals( new TestInstance( true ), "true" );
assertInstanceEquals( new TestInstance( 123 ), "123" );
assertInstanceEquals( new TestInstance( 123.456f ), "123.456" );
assertInstanceEquals( new TestInstance( Color.red ), "#f00" );
assertInstanceEquals( new TestInstance( "some string", true ), "some string, true" );
assertInstanceEquals( new TestInstance( "some string", true, 123 ), "some string, true, 123" );
assertInstanceEquals( new TestInstance( "some string", 123, true ), "some string, 123, true" );
assertInstanceEquals( new TestInstance( "some string", 123.456f, true ), "some string, 123.456, true" );
assertInstanceEquals( new TestInstance( 123, "some string" ), "123, some string" );
}
private void assertInstanceEquals( TestInstance expected, String params ) {
String value = TestInstance.class.getName() + (params != null ? "," + params : "");
assertEquals( expected, ((LazyValue)UIDefaultsLoader.parseValue( "dummyIcon", value, null )).createValue( null ) );
}
//---- class TestInstance -------------------------------------------------
@SuppressWarnings( "EqualsHashCode" ) // Error Prone
public static class TestInstance
{
private String s;
private boolean b;
private int i;
private float f;
private Color color;
public TestInstance() {
}
public TestInstance( String s ) {
this.s = s;
}
public TestInstance( boolean b ) {
this.b = b;
}
public TestInstance( int i ) {
this.i = i;
}
public TestInstance( float f ) {
this.f = f;
}
public TestInstance( Color color ) {
this.color = color;
}
public TestInstance( String s, boolean b ) {
this.s = s;
this.b = b;
}
public TestInstance( String s, boolean b, int i ) {
this.s = s;
this.b = b;
this.i = i;
}
public TestInstance( String s, int i, boolean b ) {
this.s = s;
this.b = b;
this.i = i;
}
public TestInstance( String s, float f, boolean b ) {
this.s = s;
this.b = b;
this.f = f;
}
protected TestInstance( int i, String s ) {
this.s = s;
this.i = i;
}
@Override
public boolean equals( Object obj ) {
if( !(obj instanceof TestInstance) )
return false;
TestInstance inst = (TestInstance) obj;
return Objects.equals( s, inst.s ) &&
b == inst.b &&
i == inst.i &&
f == inst.f &&
Objects.equals( color, inst.color );
}
}
} }

View File

@@ -732,6 +732,11 @@ public class TestFlatStyleableInfo
"tabHeight", int.class, "tabHeight", int.class,
"tabSelectionHeight", int.class, "tabSelectionHeight", int.class,
"cardTabSelectionHeight", int.class, "cardTabSelectionHeight", int.class,
"tabArc", int.class,
"tabSelectionArc", int.class,
"cardTabArc", int.class,
"selectedInsets", Insets.class,
"tabSelectionInsets", Insets.class,
"contentSeparatorHeight", int.class, "contentSeparatorHeight", int.class,
"showTabSeparators", boolean.class, "showTabSeparators", boolean.class,
"tabSeparatorsFullHeight", boolean.class, "tabSeparatorsFullHeight", boolean.class,

View File

@@ -738,6 +738,11 @@ public class TestFlatStyleableValue
testInteger( c, ui, "tabHeight", 123 ); testInteger( c, ui, "tabHeight", 123 );
testInteger( c, ui, "tabSelectionHeight", 123 ); testInteger( c, ui, "tabSelectionHeight", 123 );
testInteger( c, ui, "cardTabSelectionHeight", 123 ); testInteger( c, ui, "cardTabSelectionHeight", 123 );
testInteger( c, ui, "tabArc", 123 );
testInteger( c, ui, "tabSelectionArc", 123 );
testInteger( c, ui, "cardTabArc", 123 );
testInsets( c, ui, "selectedInsets", 1,2,3,4 );
testInsets( c, ui, "tabSelectionInsets", 1,2,3,4 );
testInteger( c, ui, "contentSeparatorHeight", 123 ); testInteger( c, ui, "contentSeparatorHeight", 123 );
testBoolean( c, ui, "showTabSeparators", false ); testBoolean( c, ui, "showTabSeparators", false );
testBoolean( c, ui, "tabSeparatorsFullHeight", false ); testBoolean( c, ui, "tabSeparatorsFullHeight", false );
@@ -1214,6 +1219,7 @@ public class TestFlatStyleableValue
//---- class TestIcon ----------------------------------------------------- //---- class TestIcon -----------------------------------------------------
@SuppressWarnings( "EqualsHashCode" ) // Error Prone
public static class TestIcon public static class TestIcon
implements Icon implements Icon
{ {

View File

@@ -917,6 +917,11 @@ public class TestFlatStyling
ui.applyStyle( "tabHeight: 30" ); ui.applyStyle( "tabHeight: 30" );
ui.applyStyle( "tabSelectionHeight: 3" ); ui.applyStyle( "tabSelectionHeight: 3" );
ui.applyStyle( "cardTabSelectionHeight: 2" ); ui.applyStyle( "cardTabSelectionHeight: 2" );
ui.applyStyle( "tabArc: 3" );
ui.applyStyle( "tabSelectionArc: 4" );
ui.applyStyle( "cardTabArc: 5" );
ui.applyStyle( "selectedInsets: 1,2,3,4" );
ui.applyStyle( "tabSelectionInsets: 1,2,3,4" );
ui.applyStyle( "contentSeparatorHeight: 1" ); ui.applyStyle( "contentSeparatorHeight: 1" );
ui.applyStyle( "showTabSeparators: false" ); ui.applyStyle( "showTabSeparators: false" );
ui.applyStyle( "tabSeparatorsFullHeight: false" ); ui.applyStyle( "tabSeparatorsFullHeight: false" );

View File

@@ -0,0 +1,117 @@
/*
* Copyright 2023 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 javax.swing.*;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import com.formdev.flatlaf.FlatClientProperties;
/**
* @author Karl Tauber
*/
public class TestFlatStylingScale
{
private static final float[] FACTORS = { 1f, 1.5f, 2f };
@BeforeAll
static void setup() {
TestUtils.setup( false );
}
@AfterAll
static void cleanup() {
TestUtils.cleanup();
}
static float[] factors() {
return FACTORS;
}
@ParameterizedTest
@MethodSource( "factors" )
void button( float factor ) {
abstractButton( factor, new JButton() );
}
@ParameterizedTest
@MethodSource( "factors" )
void checkBox( float factor ) {
abstractButton( factor, new JCheckBox() );
}
@ParameterizedTest
@MethodSource( "factors" )
void radioButton( float factor ) {
abstractButton( factor, new JRadioButton() );
}
private void abstractButton( float factor, AbstractButton button ) {
TestUtils.scaleFont( factor );
button.putClientProperty( FlatClientProperties.STYLE, "iconTextGap: 100" );
assertEquals( (int) (100 * factor), button.getIconTextGap() );
TestUtils.resetFont();
}
@ParameterizedTest
@MethodSource( "factors" )
void tabbedPane( float factor ) {
TestUtils.scaleFont( factor );
JTabbedPane tabbedPane = new JTabbedPane();
FlatTabbedPaneUI ui = (FlatTabbedPaneUI) tabbedPane.getUI();
tabbedPane.putClientProperty( FlatClientProperties.STYLE, "textIconGap: 100" );
assertEquals( 100, ui.getStyleableValue( tabbedPane, "textIconGap" ) );
TestUtils.resetFont();
}
@ParameterizedTest
@MethodSource( "factors" )
void table( float factor ) {
TestUtils.scaleFont( factor );
JTable table = new JTable();
table.putClientProperty( FlatClientProperties.STYLE, "rowHeight: 100" );
assertEquals( (int) (100 * factor), table.getRowHeight() );
TestUtils.resetFont();
}
@ParameterizedTest
@MethodSource( "factors" )
void tree( float factor ) {
TestUtils.scaleFont( factor );
JTree tree = new JTree();
tree.putClientProperty( FlatClientProperties.STYLE, "rowHeight: 10" );
assertEquals( 10 * factor, tree.getRowHeight() );
TestUtils.resetFont();
}
}

View File

@@ -30,6 +30,7 @@ import com.formdev.flatlaf.FlatSystemProperties;
*/ */
public class TestUtils public class TestUtils
{ {
@SuppressWarnings( "MutablePublicArray" ) // Error Prone
public static final float[] FACTORS = { 1f, 1.25f, 1.5f, 1.75f, 2f, 2.25f, 2.5f, 2.75f, 3f, 3.25f, 3.5f, 3.75f, 4f, 5f, 6f }; public static final float[] FACTORS = { 1f, 1.25f, 1.5f, 1.75f, 2f, 2.25f, 2.5f, 2.75f, 3f, 3.25f, 3.5f, 3.75f, 4f, 5f, 6f };
public static void setup( boolean withFocus ) { public static void setup( boolean withFocus ) {

View File

@@ -27,8 +27,8 @@ dependencies {
implementation( project( ":flatlaf-fonts-roboto" ) ) implementation( project( ":flatlaf-fonts-roboto" ) )
implementation( project( ":flatlaf-fonts-roboto-mono" ) ) implementation( project( ":flatlaf-fonts-roboto-mono" ) )
implementation( project( ":flatlaf-intellij-themes" ) ) implementation( project( ":flatlaf-intellij-themes" ) )
implementation( "com.miglayout:miglayout-swing:5.3" ) implementation( libs.miglayout.swing )
implementation( "com.jgoodies:jgoodies-forms:1.9.0" ) implementation( libs.jgoodies.forms )
// implementation( project( ":flatlaf-natives-jna" ) ) // implementation( project( ":flatlaf-natives-jna" ) )
} }

View File

@@ -440,9 +440,9 @@ class DemoFrame
Class<? extends LookAndFeel> lafClass = UIManager.getLookAndFeel().getClass(); Class<? extends LookAndFeel> lafClass = UIManager.getLookAndFeel().getClass();
try { try {
FlatLaf.setup( lafClass.newInstance() ); FlatLaf.setup( lafClass.getDeclaredConstructor().newInstance() );
FlatLaf.updateUI(); FlatLaf.updateUI();
} catch( InstantiationException | IllegalAccessException ex ) { } catch( Exception ex ) {
LoggingFacade.INSTANCE.logSevere( null, ex ); LoggingFacade.INSTANCE.logSevere( null, ex );
} }
} }
@@ -591,6 +591,7 @@ class DemoFrame
undoMenuItem.setText("Undo"); undoMenuItem.setText("Undo");
undoMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Z, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); undoMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Z, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
undoMenuItem.setMnemonic('U'); undoMenuItem.setMnemonic('U');
undoMenuItem.setIcon(new FlatSVGIcon("com/formdev/flatlaf/demo/icons/undo.svg"));
undoMenuItem.addActionListener(e -> menuItemActionPerformed(e)); undoMenuItem.addActionListener(e -> menuItemActionPerformed(e));
editMenu.add(undoMenuItem); editMenu.add(undoMenuItem);
@@ -598,6 +599,7 @@ class DemoFrame
redoMenuItem.setText("Redo"); redoMenuItem.setText("Redo");
redoMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Y, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); redoMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Y, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
redoMenuItem.setMnemonic('R'); redoMenuItem.setMnemonic('R');
redoMenuItem.setIcon(new FlatSVGIcon("com/formdev/flatlaf/demo/icons/redo.svg"));
redoMenuItem.addActionListener(e -> menuItemActionPerformed(e)); redoMenuItem.addActionListener(e -> menuItemActionPerformed(e));
editMenu.add(redoMenuItem); editMenu.add(redoMenuItem);
editMenu.addSeparator(); editMenu.addSeparator();
@@ -606,18 +608,21 @@ class DemoFrame
cutMenuItem.setText("Cut"); cutMenuItem.setText("Cut");
cutMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); cutMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
cutMenuItem.setMnemonic('C'); cutMenuItem.setMnemonic('C');
cutMenuItem.setIcon(new FlatSVGIcon("com/formdev/flatlaf/demo/icons/menu-cut.svg"));
editMenu.add(cutMenuItem); editMenu.add(cutMenuItem);
//---- copyMenuItem ---- //---- copyMenuItem ----
copyMenuItem.setText("Copy"); copyMenuItem.setText("Copy");
copyMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); copyMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
copyMenuItem.setMnemonic('O'); copyMenuItem.setMnemonic('O');
copyMenuItem.setIcon(new FlatSVGIcon("com/formdev/flatlaf/demo/icons/copy.svg"));
editMenu.add(copyMenuItem); editMenu.add(copyMenuItem);
//---- pasteMenuItem ---- //---- pasteMenuItem ----
pasteMenuItem.setText("Paste"); pasteMenuItem.setText("Paste");
pasteMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())); pasteMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
pasteMenuItem.setMnemonic('P'); pasteMenuItem.setMnemonic('P');
pasteMenuItem.setIcon(new FlatSVGIcon("com/formdev/flatlaf/demo/icons/menu-paste.svg"));
editMenu.add(pasteMenuItem); editMenu.add(pasteMenuItem);
editMenu.addSeparator(); editMenu.addSeparator();
@@ -827,34 +832,41 @@ class DemoFrame
//---- backButton ---- //---- backButton ----
backButton.setToolTipText("Back"); backButton.setToolTipText("Back");
backButton.setIcon(new FlatSVGIcon("com/formdev/flatlaf/demo/icons/back.svg"));
toolBar.add(backButton); toolBar.add(backButton);
//---- forwardButton ---- //---- forwardButton ----
forwardButton.setToolTipText("Forward"); forwardButton.setToolTipText("Forward");
forwardButton.setIcon(new FlatSVGIcon("com/formdev/flatlaf/demo/icons/forward.svg"));
toolBar.add(forwardButton); toolBar.add(forwardButton);
toolBar.addSeparator(); toolBar.addSeparator();
//---- cutButton ---- //---- cutButton ----
cutButton.setToolTipText("Cut"); cutButton.setToolTipText("Cut");
cutButton.setIcon(new FlatSVGIcon("com/formdev/flatlaf/demo/icons/menu-cut.svg"));
toolBar.add(cutButton); toolBar.add(cutButton);
//---- copyButton ---- //---- copyButton ----
copyButton.setToolTipText("Copy"); copyButton.setToolTipText("Copy");
copyButton.setIcon(new FlatSVGIcon("com/formdev/flatlaf/demo/icons/copy.svg"));
toolBar.add(copyButton); toolBar.add(copyButton);
//---- pasteButton ---- //---- pasteButton ----
pasteButton.setToolTipText("Paste"); pasteButton.setToolTipText("Paste");
pasteButton.setIcon(new FlatSVGIcon("com/formdev/flatlaf/demo/icons/menu-paste.svg"));
toolBar.add(pasteButton); toolBar.add(pasteButton);
toolBar.addSeparator(); toolBar.addSeparator();
//---- refreshButton ---- //---- refreshButton ----
refreshButton.setToolTipText("Refresh"); refreshButton.setToolTipText("Refresh");
refreshButton.setIcon(new FlatSVGIcon("com/formdev/flatlaf/demo/icons/refresh.svg"));
toolBar.add(refreshButton); toolBar.add(refreshButton);
toolBar.addSeparator(); toolBar.addSeparator();
//---- showToggleButton ---- //---- showToggleButton ----
showToggleButton.setSelected(true); showToggleButton.setSelected(true);
showToggleButton.setToolTipText("Show Details"); showToggleButton.setToolTipText("Show Details");
showToggleButton.setIcon(new FlatSVGIcon("com/formdev/flatlaf/demo/icons/show.svg"));
toolBar.add(showToggleButton); toolBar.add(showToggleButton);
} }
contentPane.add(toolBar, BorderLayout.NORTH); contentPane.add(toolBar, BorderLayout.NORTH);
@@ -901,21 +913,6 @@ class DemoFrame
menuBar1.add( Box.createGlue() ); menuBar1.add( Box.createGlue() );
menuBar1.add( usersButton ); menuBar1.add( usersButton );
undoMenuItem.setIcon( new FlatSVGIcon( "com/formdev/flatlaf/demo/icons/undo.svg" ) );
redoMenuItem.setIcon( new FlatSVGIcon( "com/formdev/flatlaf/demo/icons/redo.svg" ) );
cutMenuItem.setIcon( new FlatSVGIcon( "com/formdev/flatlaf/demo/icons/menu-cut.svg" ) );
copyMenuItem.setIcon( new FlatSVGIcon( "com/formdev/flatlaf/demo/icons/copy.svg" ) );
pasteMenuItem.setIcon( new FlatSVGIcon( "com/formdev/flatlaf/demo/icons/menu-paste.svg" ) );
backButton.setIcon( new FlatSVGIcon( "com/formdev/flatlaf/demo/icons/back.svg" ) );
forwardButton.setIcon( new FlatSVGIcon( "com/formdev/flatlaf/demo/icons/forward.svg" ) );
cutButton.setIcon( new FlatSVGIcon( "com/formdev/flatlaf/demo/icons/menu-cut.svg" ) );
copyButton.setIcon( new FlatSVGIcon( "com/formdev/flatlaf/demo/icons/copy.svg" ) );
pasteButton.setIcon( new FlatSVGIcon( "com/formdev/flatlaf/demo/icons/menu-paste.svg" ) );
refreshButton.setIcon( new FlatSVGIcon( "com/formdev/flatlaf/demo/icons/refresh.svg" ) );
showToggleButton.setIcon( new FlatSVGIcon( "com/formdev/flatlaf/demo/icons/show.svg" ) );
cutMenuItem.addActionListener( new DefaultEditorKit.CutAction() ); cutMenuItem.addActionListener( new DefaultEditorKit.CutAction() );
copyMenuItem.addActionListener( new DefaultEditorKit.CopyAction() ); copyMenuItem.addActionListener( new DefaultEditorKit.CopyAction() );
pasteMenuItem.addActionListener( new DefaultEditorKit.PasteAction() ); pasteMenuItem.addActionListener( new DefaultEditorKit.PasteAction() );
@@ -950,6 +947,9 @@ class DemoFrame
if( SystemInfo.isMacOS ) if( SystemInfo.isMacOS )
unsupported( underlineMenuSelectionMenuItem ); unsupported( underlineMenuSelectionMenuItem );
if( "false".equals( System.getProperty( "flatlaf.animatedLafChange" ) ) )
animatedLafChangeMenuItem.setSelected( false );
// remove contentPanel bottom insets // remove contentPanel bottom insets
MigLayout layout = (MigLayout) contentPanel.getLayout(); MigLayout layout = (MigLayout) contentPanel.getLayout();
LC lc = ConstraintParser.parseLayoutConstraint( (String) layout.getLayoutConstraints() ); LC lc = ConstraintParser.parseLayoutConstraint( (String) layout.getLayoutConstraints() );

View File

@@ -1,4 +1,4 @@
JFDML JFormDesigner: "7.0.4.0.360" Java: "17" encoding: "UTF-8" JFDML JFormDesigner: "8.1.0.0.283" Java: "19.0.2" encoding: "UTF-8"
new FormModel { new FormModel {
contentType: "form/swing" contentType: "form/swing"
@@ -21,10 +21,12 @@ new FormModel {
add( new FormComponent( "javax.swing.JButton" ) { add( new FormComponent( "javax.swing.JButton" ) {
name: "backButton" name: "backButton"
"toolTipText": "Back" "toolTipText": "Back"
"icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/demo/icons/back.svg" )
} ) } )
add( new FormComponent( "javax.swing.JButton" ) { add( new FormComponent( "javax.swing.JButton" ) {
name: "forwardButton" name: "forwardButton"
"toolTipText": "Forward" "toolTipText": "Forward"
"icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/demo/icons/forward.svg" )
} ) } )
add( new FormComponent( "javax.swing.JToolBar$Separator" ) { add( new FormComponent( "javax.swing.JToolBar$Separator" ) {
name: "separator5" name: "separator5"
@@ -32,14 +34,17 @@ new FormModel {
add( new FormComponent( "javax.swing.JButton" ) { add( new FormComponent( "javax.swing.JButton" ) {
name: "cutButton" name: "cutButton"
"toolTipText": "Cut" "toolTipText": "Cut"
"icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/demo/icons/menu-cut.svg" )
} ) } )
add( new FormComponent( "javax.swing.JButton" ) { add( new FormComponent( "javax.swing.JButton" ) {
name: "copyButton" name: "copyButton"
"toolTipText": "Copy" "toolTipText": "Copy"
"icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/demo/icons/copy.svg" )
} ) } )
add( new FormComponent( "javax.swing.JButton" ) { add( new FormComponent( "javax.swing.JButton" ) {
name: "pasteButton" name: "pasteButton"
"toolTipText": "Paste" "toolTipText": "Paste"
"icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/demo/icons/menu-paste.svg" )
} ) } )
add( new FormComponent( "javax.swing.JToolBar$Separator" ) { add( new FormComponent( "javax.swing.JToolBar$Separator" ) {
name: "separator6" name: "separator6"
@@ -47,6 +52,7 @@ new FormModel {
add( new FormComponent( "javax.swing.JButton" ) { add( new FormComponent( "javax.swing.JButton" ) {
name: "refreshButton" name: "refreshButton"
"toolTipText": "Refresh" "toolTipText": "Refresh"
"icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/demo/icons/refresh.svg" )
} ) } )
add( new FormComponent( "javax.swing.JToolBar$Separator" ) { add( new FormComponent( "javax.swing.JToolBar$Separator" ) {
name: "separator7" name: "separator7"
@@ -55,6 +61,7 @@ new FormModel {
name: "showToggleButton" name: "showToggleButton"
"selected": true "selected": true
"toolTipText": "Show Details" "toolTipText": "Show Details"
"icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/demo/icons/show.svg" )
} ) } )
}, new FormLayoutConstraints( class java.lang.String ) { }, new FormLayoutConstraints( class java.lang.String ) {
"value": "North" "value": "North"
@@ -185,6 +192,7 @@ new FormModel {
"text": "Undo" "text": "Undo"
"accelerator": static javax.swing.KeyStroke getKeyStroke( 90, 4226, false ) "accelerator": static javax.swing.KeyStroke getKeyStroke( 90, 4226, false )
"mnemonic": 85 "mnemonic": 85
"icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/demo/icons/undo.svg" )
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) ) addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) )
} ) } )
add( new FormComponent( "javax.swing.JMenuItem" ) { add( new FormComponent( "javax.swing.JMenuItem" ) {
@@ -192,6 +200,7 @@ new FormModel {
"text": "Redo" "text": "Redo"
"accelerator": static javax.swing.KeyStroke getKeyStroke( 89, 4226, false ) "accelerator": static javax.swing.KeyStroke getKeyStroke( 89, 4226, false )
"mnemonic": 82 "mnemonic": 82
"icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/demo/icons/redo.svg" )
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) ) addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) )
} ) } )
add( new FormComponent( "javax.swing.JPopupMenu$Separator" ) { add( new FormComponent( "javax.swing.JPopupMenu$Separator" ) {
@@ -202,18 +211,21 @@ new FormModel {
"text": "Cut" "text": "Cut"
"accelerator": static javax.swing.KeyStroke getKeyStroke( 88, 4226, false ) "accelerator": static javax.swing.KeyStroke getKeyStroke( 88, 4226, false )
"mnemonic": 67 "mnemonic": 67
"icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/demo/icons/menu-cut.svg" )
} ) } )
add( new FormComponent( "javax.swing.JMenuItem" ) { add( new FormComponent( "javax.swing.JMenuItem" ) {
name: "copyMenuItem" name: "copyMenuItem"
"text": "Copy" "text": "Copy"
"accelerator": static javax.swing.KeyStroke getKeyStroke( 67, 4226, false ) "accelerator": static javax.swing.KeyStroke getKeyStroke( 67, 4226, false )
"mnemonic": 79 "mnemonic": 79
"icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/demo/icons/copy.svg" )
} ) } )
add( new FormComponent( "javax.swing.JMenuItem" ) { add( new FormComponent( "javax.swing.JMenuItem" ) {
name: "pasteMenuItem" name: "pasteMenuItem"
"text": "Paste" "text": "Paste"
"accelerator": static javax.swing.KeyStroke getKeyStroke( 86, 4226, false ) "accelerator": static javax.swing.KeyStroke getKeyStroke( 86, 4226, false )
"mnemonic": 80 "mnemonic": 80
"icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/demo/icons/menu-paste.svg" )
} ) } )
add( new FormComponent( "javax.swing.JPopupMenu$Separator" ) { add( new FormComponent( "javax.swing.JPopupMenu$Separator" ) {
name: "separator3" name: "separator3"

View File

@@ -32,6 +32,7 @@ import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.net.URL;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.StandardCopyOption; import java.nio.file.StandardCopyOption;
import java.util.ArrayList; import java.util.ArrayList;
@@ -82,14 +83,13 @@ public class IJThemesPanel
private File lastDirectory; private File lastDirectory;
private boolean isAdjustingThemesList; private boolean isAdjustingThemesList;
private long lastLafChangeTime = System.currentTimeMillis();
public IJThemesPanel() { public IJThemesPanel() {
initComponents(); initComponents();
saveButton.setEnabled( false ); saveButton.setEnabled( false );
sourceCodeButton.setEnabled( false ); sourceCodeButton.setEnabled( false );
saveButton.setIcon( new FlatSVGIcon( "com/formdev/flatlaf/demo/icons/download.svg" ) );
sourceCodeButton.setIcon( new FlatSVGIcon( "com/formdev/flatlaf/demo/icons/github.svg" ) );
// create renderer // create renderer
themesList.setCellRenderer( new DefaultListCellRenderer() { themesList.setCellRenderer( new DefaultListCellRenderer() {
@@ -370,7 +370,10 @@ public class IJThemesPanel
if( themeInfo == null || themeInfo.resourceName == null ) if( themeInfo == null || themeInfo.resourceName == null )
return; return;
String themeUrl = (themeInfo.sourceCodeUrl + '/' + themeInfo.sourceCodePath).replace( " ", "%20" ); String themeUrl = themeInfo.sourceCodeUrl;
if( themeInfo.sourceCodePath != null )
themeUrl += '/' + themeInfo.sourceCodePath;
themeUrl = themeUrl.replace( " ", "%20" );
try { try {
Desktop.getDesktop().browse( new URI( themeUrl ) ); Desktop.getDesktop().browse( new URI( themeUrl ) );
} catch( IOException | URISyntaxException ex ) { } catch( IOException | URISyntaxException ex ) {
@@ -409,14 +412,59 @@ public class IJThemesPanel
} }
private void lafChanged( PropertyChangeEvent e ) { private void lafChanged( PropertyChangeEvent e ) {
if( "lookAndFeel".equals( e.getPropertyName() ) ) if( "lookAndFeel".equals( e.getPropertyName() ) ) {
selectedCurrentLookAndFeel(); selectedCurrentLookAndFeel();
lastLafChangeTime = System.currentTimeMillis();
}
} }
private void windowActivated() { private void windowActivated() {
// refresh themes list on window activation // refresh themes list on window activation
if( themesManager.hasThemesFromDirectoryChanged() ) if( themesManager.hasThemesFromDirectoryChanged() )
updateThemesList(); updateThemesList();
else {
// check whether core .properties files of current Laf have changed
// in development environment since last Laf change and reload theme
LookAndFeel laf = UIManager.getLookAndFeel();
if( laf instanceof FlatLaf ) {
List<Class<?>> lafClasses = new ArrayList<>();
if( laf instanceof IntelliJTheme.ThemeLaf ) {
boolean dark = ((FlatLaf)laf).isDark();
lafClasses.add( FlatLaf.class );
lafClasses.add( dark ? FlatDarkLaf.class : FlatLightLaf.class );
lafClasses.add( dark ? FlatDarculaLaf.class : FlatIntelliJLaf.class );
lafClasses.add( IntelliJTheme.ThemeLaf.class );
} else {
for( Class<?> lafClass = laf.getClass();
FlatLaf.class.isAssignableFrom( lafClass );
lafClass = lafClass.getSuperclass() )
{
lafClasses.add( 0, lafClass );
}
}
boolean reload = false;
for( Class<?> lafClass : lafClasses ) {
String propertiesName = '/' + lafClass.getName().replace( '.', '/' ) + ".properties";
URL url = lafClass.getResource( propertiesName );
if( url != null && "file".equals( url.getProtocol() ) ) {
try {
File file = new File( url.toURI() );
if( file.lastModified() > lastLafChangeTime ) {
reload = true;
break;
}
} catch( URISyntaxException ex ) {
// ignore
}
}
}
if( reload )
setTheme( themesList.getSelectedValue() );
}
}
} }
private void selectedCurrentLookAndFeel() { private void selectedCurrentLookAndFeel() {
@@ -488,11 +536,13 @@ public class IJThemesPanel
//---- saveButton ---- //---- saveButton ----
saveButton.setToolTipText("Save .theme.json of selected IntelliJ theme to file."); saveButton.setToolTipText("Save .theme.json of selected IntelliJ theme to file.");
saveButton.setIcon(new FlatSVGIcon("com/formdev/flatlaf/demo/icons/download.svg"));
saveButton.addActionListener(e -> saveTheme()); saveButton.addActionListener(e -> saveTheme());
toolBar.add(saveButton); toolBar.add(saveButton);
//---- sourceCodeButton ---- //---- sourceCodeButton ----
sourceCodeButton.setToolTipText("Opens the source code repository of selected IntelliJ theme in the browser."); sourceCodeButton.setToolTipText("Opens the source code repository of selected IntelliJ theme in the browser.");
sourceCodeButton.setIcon(new FlatSVGIcon("com/formdev/flatlaf/demo/icons/github.svg"));
sourceCodeButton.addActionListener(e -> browseSourceCode()); sourceCodeButton.addActionListener(e -> browseSourceCode());
toolBar.add(sourceCodeButton); toolBar.add(sourceCodeButton);
} }

View File

@@ -1,4 +1,4 @@
JFDML JFormDesigner: "7.0.2.0.298" Java: "14" encoding: "UTF-8" JFDML JFormDesigner: "8.1.0.0.283" Java: "19.0.2" encoding: "UTF-8"
new FormModel { new FormModel {
contentType: "form/swing" contentType: "form/swing"
@@ -24,11 +24,13 @@ new FormModel {
add( new FormComponent( "javax.swing.JButton" ) { add( new FormComponent( "javax.swing.JButton" ) {
name: "saveButton" name: "saveButton"
"toolTipText": "Save .theme.json of selected IntelliJ theme to file." "toolTipText": "Save .theme.json of selected IntelliJ theme to file."
"icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/demo/icons/download.svg" )
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "saveTheme", false ) ) addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "saveTheme", false ) )
} ) } )
add( new FormComponent( "javax.swing.JButton" ) { add( new FormComponent( "javax.swing.JButton" ) {
name: "sourceCodeButton" name: "sourceCodeButton"
"toolTipText": "Opens the source code repository of selected IntelliJ theme in the browser." "toolTipText": "Opens the source code repository of selected IntelliJ theme in the browser."
"icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/demo/icons/github.svg" )
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "browseSourceCode", false ) ) addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "browseSourceCode", false ) )
} ) } )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {

View File

@@ -38,8 +38,10 @@ public class IJThemesUpdater
themesManager.loadBundledThemes(); themesManager.loadBundledThemes();
for( IJThemeInfo ti : themesManager.bundledThemes ) { for( IJThemeInfo ti : themesManager.bundledThemes ) {
if( ti.sourceCodeUrl == null || ti.sourceCodePath == null ) if( ti.sourceCodeUrl == null || ti.sourceCodePath == null ) {
System.out.println( " " + ti.name + " NOT downloaded. Needs manual update from release on JetBrains Plugin portal." );
continue; continue;
}
String fromUrl = ti.sourceCodeUrl + "/" + ti.sourceCodePath; String fromUrl = ti.sourceCodeUrl + "/" + ti.sourceCodePath;
if( fromUrl.contains( "github.com" ) ) if( fromUrl.contains( "github.com" ) )

View File

@@ -145,7 +145,7 @@
"license": "MIT", "license": "MIT",
"licenseFile": "Hiberbee.LICENSE.txt", "licenseFile": "Hiberbee.LICENSE.txt",
"sourceCodeUrl": "https://github.com/Hiberbee/themes", "sourceCodeUrl": "https://github.com/Hiberbee/themes",
"sourceCodePath": "blob/latest/src/main/resources/themes/HiberbeeDark.theme.json" "sourceCodePath": "blob/latest/src/intellij/src/main/resources/themes/HiberbeeDark.theme.json"
}, },
"HighContrast.theme.json": { "HighContrast.theme.json": {
"name": "High contrast", "name": "High contrast",
@@ -249,14 +249,6 @@
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite", "sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
"sourceCodePath": "blob/master/src/main/resources/themes/regular/Arc Dark.theme.json" "sourceCodePath": "blob/master/src/main/resources/themes/regular/Arc Dark.theme.json"
}, },
"material-theme-ui-lite/Arc Dark Contrast.theme.json": {
"name": "Material Theme UI Lite / Arc Dark Contrast",
"dark": true,
"license": "MIT",
"licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt",
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
"sourceCodePath": "blob/master/src/main/resources/themes/contrast/Arc Dark Contrast.theme.json"
},
"material-theme-ui-lite/Atom One Dark.theme.json": { "material-theme-ui-lite/Atom One Dark.theme.json": {
"name": "Material Theme UI Lite / Atom One Dark", "name": "Material Theme UI Lite / Atom One Dark",
"dark": true, "dark": true,
@@ -265,14 +257,6 @@
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite", "sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
"sourceCodePath": "blob/master/src/main/resources/themes/regular/Atom One Dark.theme.json" "sourceCodePath": "blob/master/src/main/resources/themes/regular/Atom One Dark.theme.json"
}, },
"material-theme-ui-lite/Atom One Dark Contrast.theme.json": {
"name": "Material Theme UI Lite / Atom One Dark Contrast",
"dark": true,
"license": "MIT",
"licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt",
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
"sourceCodePath": "blob/master/src/main/resources/themes/contrast/Atom One Dark Contrast.theme.json"
},
"material-theme-ui-lite/Atom One Light.theme.json": { "material-theme-ui-lite/Atom One Light.theme.json": {
"name": "Material Theme UI Lite / Atom One Light", "name": "Material Theme UI Lite / Atom One Light",
"license": "MIT", "license": "MIT",
@@ -280,13 +264,6 @@
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite", "sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
"sourceCodePath": "blob/master/src/main/resources/themes/regular/Atom One Light.theme.json" "sourceCodePath": "blob/master/src/main/resources/themes/regular/Atom One Light.theme.json"
}, },
"material-theme-ui-lite/Atom One Light Contrast.theme.json": {
"name": "Material Theme UI Lite / Atom One Light Contrast",
"license": "MIT",
"licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt",
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
"sourceCodePath": "blob/master/src/main/resources/themes/contrast/Atom One Light Contrast.theme.json"
},
"material-theme-ui-lite/Dracula.theme.json": { "material-theme-ui-lite/Dracula.theme.json": {
"name": "Material Theme UI Lite / Dracula", "name": "Material Theme UI Lite / Dracula",
"dark": true, "dark": true,
@@ -295,14 +272,6 @@
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite", "sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
"sourceCodePath": "blob/master/src/main/resources/themes/regular/Dracula.theme.json" "sourceCodePath": "blob/master/src/main/resources/themes/regular/Dracula.theme.json"
}, },
"material-theme-ui-lite/Dracula Contrast.theme.json": {
"name": "Material Theme UI Lite / Dracula Contrast",
"dark": true,
"license": "MIT",
"licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt",
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
"sourceCodePath": "blob/master/src/main/resources/themes/contrast/Dracula Contrast.theme.json"
},
"material-theme-ui-lite/GitHub.theme.json": { "material-theme-ui-lite/GitHub.theme.json": {
"name": "Material Theme UI Lite / GitHub", "name": "Material Theme UI Lite / GitHub",
"license": "MIT", "license": "MIT",
@@ -310,13 +279,6 @@
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite", "sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
"sourceCodePath": "blob/master/src/main/resources/themes/regular/GitHub.theme.json" "sourceCodePath": "blob/master/src/main/resources/themes/regular/GitHub.theme.json"
}, },
"material-theme-ui-lite/GitHub Contrast.theme.json": {
"name": "Material Theme UI Lite / GitHub Contrast",
"license": "MIT",
"licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt",
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
"sourceCodePath": "blob/master/src/main/resources/themes/contrast/GitHub Contrast.theme.json"
},
"material-theme-ui-lite/GitHub Dark.theme.json": { "material-theme-ui-lite/GitHub Dark.theme.json": {
"name": "Material Theme UI Lite / GitHub Dark", "name": "Material Theme UI Lite / GitHub Dark",
"dark": true, "dark": true,
@@ -325,14 +287,6 @@
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite", "sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
"sourceCodePath": "blob/master/src/main/resources/themes/regular/GitHub Dark.theme.json" "sourceCodePath": "blob/master/src/main/resources/themes/regular/GitHub Dark.theme.json"
}, },
"material-theme-ui-lite/GitHub Dark Contrast.theme.json": {
"name": "Material Theme UI Lite / GitHub Dark Contrast",
"dark": true,
"license": "MIT",
"licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt",
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
"sourceCodePath": "blob/master/src/main/resources/themes/contrast/GitHub Dark Contrast.theme.json"
},
"material-theme-ui-lite/Light Owl.theme.json": { "material-theme-ui-lite/Light Owl.theme.json": {
"name": "Material Theme UI Lite / Light Owl", "name": "Material Theme UI Lite / Light Owl",
"license": "MIT", "license": "MIT",
@@ -340,13 +294,6 @@
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite", "sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
"sourceCodePath": "blob/master/src/main/resources/themes/regular/Light Owl.theme.json" "sourceCodePath": "blob/master/src/main/resources/themes/regular/Light Owl.theme.json"
}, },
"material-theme-ui-lite/Light Owl Contrast.theme.json": {
"name": "Material Theme UI Lite / Light Owl Contrast",
"license": "MIT",
"licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt",
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
"sourceCodePath": "blob/master/src/main/resources/themes/contrast/Light Owl Contrast.theme.json"
},
"material-theme-ui-lite/Material Darker.theme.json": { "material-theme-ui-lite/Material Darker.theme.json": {
"name": "Material Theme UI Lite / Material Darker", "name": "Material Theme UI Lite / Material Darker",
"dark": true, "dark": true,
@@ -355,14 +302,6 @@
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite", "sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
"sourceCodePath": "blob/master/src/main/resources/themes/regular/Material Darker.theme.json" "sourceCodePath": "blob/master/src/main/resources/themes/regular/Material Darker.theme.json"
}, },
"material-theme-ui-lite/Material Darker Contrast.theme.json": {
"name": "Material Theme UI Lite / Material Darker Contrast",
"dark": true,
"license": "MIT",
"licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt",
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
"sourceCodePath": "blob/master/src/main/resources/themes/contrast/Material Darker Contrast.theme.json"
},
"material-theme-ui-lite/Material Deep Ocean.theme.json": { "material-theme-ui-lite/Material Deep Ocean.theme.json": {
"name": "Material Theme UI Lite / Material Deep Ocean", "name": "Material Theme UI Lite / Material Deep Ocean",
"dark": true, "dark": true,
@@ -371,14 +310,6 @@
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite", "sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
"sourceCodePath": "blob/master/src/main/resources/themes/regular/Material Deep Ocean.theme.json" "sourceCodePath": "blob/master/src/main/resources/themes/regular/Material Deep Ocean.theme.json"
}, },
"material-theme-ui-lite/Material Deep Ocean Contrast.theme.json": {
"name": "Material Theme UI Lite / Material Deep Ocean Contrast",
"dark": true,
"license": "MIT",
"licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt",
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
"sourceCodePath": "blob/master/src/main/resources/themes/contrast/Material Deep Ocean Contrast.theme.json"
},
"material-theme-ui-lite/Material Lighter.theme.json": { "material-theme-ui-lite/Material Lighter.theme.json": {
"name": "Material Theme UI Lite / Material Lighter", "name": "Material Theme UI Lite / Material Lighter",
"license": "MIT", "license": "MIT",
@@ -386,13 +317,6 @@
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite", "sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
"sourceCodePath": "blob/master/src/main/resources/themes/regular/Material Lighter.theme.json" "sourceCodePath": "blob/master/src/main/resources/themes/regular/Material Lighter.theme.json"
}, },
"material-theme-ui-lite/Material Lighter Contrast.theme.json": {
"name": "Material Theme UI Lite / Material Lighter Contrast",
"license": "MIT",
"licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt",
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
"sourceCodePath": "blob/master/src/main/resources/themes/contrast/Material Lighter Contrast.theme.json"
},
"material-theme-ui-lite/Material Oceanic.theme.json": { "material-theme-ui-lite/Material Oceanic.theme.json": {
"name": "Material Theme UI Lite / Material Oceanic", "name": "Material Theme UI Lite / Material Oceanic",
"dark": true, "dark": true,
@@ -401,14 +325,6 @@
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite", "sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
"sourceCodePath": "blob/master/src/main/resources/themes/regular/Material Oceanic.theme.json" "sourceCodePath": "blob/master/src/main/resources/themes/regular/Material Oceanic.theme.json"
}, },
"material-theme-ui-lite/Material Oceanic Contrast.theme.json": {
"name": "Material Theme UI Lite / Material Oceanic Contrast",
"dark": true,
"license": "MIT",
"licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt",
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
"sourceCodePath": "blob/master/src/main/resources/themes/contrast/Material Oceanic Contrast.theme.json"
},
"material-theme-ui-lite/Material Palenight.theme.json": { "material-theme-ui-lite/Material Palenight.theme.json": {
"name": "Material Theme UI Lite / Material Palenight", "name": "Material Theme UI Lite / Material Palenight",
"dark": true, "dark": true,
@@ -417,14 +333,6 @@
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite", "sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
"sourceCodePath": "blob/master/src/main/resources/themes/regular/Material Palenight.theme.json" "sourceCodePath": "blob/master/src/main/resources/themes/regular/Material Palenight.theme.json"
}, },
"material-theme-ui-lite/Material Palenight Contrast.theme.json": {
"name": "Material Theme UI Lite / Material Palenight Contrast",
"dark": true,
"license": "MIT",
"licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt",
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
"sourceCodePath": "blob/master/src/main/resources/themes/contrast/Material Palenight Contrast.theme.json"
},
"material-theme-ui-lite/Monokai Pro.theme.json": { "material-theme-ui-lite/Monokai Pro.theme.json": {
"name": "Material Theme UI Lite / Monokai Pro", "name": "Material Theme UI Lite / Monokai Pro",
"dark": true, "dark": true,
@@ -433,14 +341,6 @@
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite", "sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
"sourceCodePath": "blob/master/src/main/resources/themes/regular/Monokai Pro.theme.json" "sourceCodePath": "blob/master/src/main/resources/themes/regular/Monokai Pro.theme.json"
}, },
"material-theme-ui-lite/Monokai Pro Contrast.theme.json": {
"name": "Material Theme UI Lite / Monokai Pro Contrast",
"dark": true,
"license": "MIT",
"licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt",
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
"sourceCodePath": "blob/master/src/main/resources/themes/contrast/Monokai Pro Contrast.theme.json"
},
"material-theme-ui-lite/Moonlight.theme.json": { "material-theme-ui-lite/Moonlight.theme.json": {
"name": "Material Theme UI Lite / Moonlight", "name": "Material Theme UI Lite / Moonlight",
"dark": true, "dark": true,
@@ -449,14 +349,6 @@
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite", "sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
"sourceCodePath": "blob/master/src/main/resources/themes/regular/Moonlight.theme.json" "sourceCodePath": "blob/master/src/main/resources/themes/regular/Moonlight.theme.json"
}, },
"material-theme-ui-lite/Moonlight Contrast.theme.json": {
"name": "Material Theme UI Lite / Moonlight Contrast",
"dark": true,
"license": "MIT",
"licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt",
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
"sourceCodePath": "blob/master/src/main/resources/themes/contrast/Moonlight Contrast.theme.json"
},
"material-theme-ui-lite/Night Owl.theme.json": { "material-theme-ui-lite/Night Owl.theme.json": {
"name": "Material Theme UI Lite / Night Owl", "name": "Material Theme UI Lite / Night Owl",
"dark": true, "dark": true,
@@ -465,14 +357,6 @@
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite", "sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
"sourceCodePath": "blob/master/src/main/resources/themes/regular/Night Owl.theme.json" "sourceCodePath": "blob/master/src/main/resources/themes/regular/Night Owl.theme.json"
}, },
"material-theme-ui-lite/Night Owl Contrast.theme.json": {
"name": "Material Theme UI Lite / Night Owl Contrast",
"dark": true,
"license": "MIT",
"licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt",
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
"sourceCodePath": "blob/master/src/main/resources/themes/contrast/Night Owl Contrast.theme.json"
},
"material-theme-ui-lite/Solarized Dark.theme.json": { "material-theme-ui-lite/Solarized Dark.theme.json": {
"name": "Material Theme UI Lite / Solarized Dark", "name": "Material Theme UI Lite / Solarized Dark",
"dark": true, "dark": true,
@@ -481,26 +365,11 @@
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite", "sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
"sourceCodePath": "blob/master/src/main/resources/themes/regular/Solarized Dark.theme.json" "sourceCodePath": "blob/master/src/main/resources/themes/regular/Solarized Dark.theme.json"
}, },
"material-theme-ui-lite/Solarized Dark Contrast.theme.json": {
"name": "Material Theme UI Lite / Solarized Dark Contrast",
"dark": true,
"license": "MIT",
"licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt",
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
"sourceCodePath": "blob/master/src/main/resources/themes/contrast/Solarized Dark Contrast.theme.json"
},
"material-theme-ui-lite/Solarized Light.theme.json": { "material-theme-ui-lite/Solarized Light.theme.json": {
"name": "Material Theme UI Lite / Solarized Light", "name": "Material Theme UI Lite / Solarized Light",
"license": "MIT", "license": "MIT",
"licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt", "licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt",
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite", "sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
"sourceCodePath": "blob/master/src/main/resources/themes/regular/Solarized Light.theme.json" "sourceCodePath": "blob/master/src/main/resources/themes/regular/Solarized Light.theme.json"
},
"material-theme-ui-lite/Solarized Light Contrast.theme.json": {
"name": "Material Theme UI Lite / Solarized Light Contrast",
"license": "MIT",
"licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt",
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
"sourceCodePath": "blob/master/src/main/resources/themes/contrast/Solarized Light Contrast.theme.json"
} }
} }

View File

@@ -4,8 +4,7 @@ FlatLaf Extras
This sub-project provides some additional components and classes: This sub-project provides some additional components and classes:
- [FlatSVGIcon](https://www.javadoc.io/doc/com.formdev/flatlaf-extras/latest/com/formdev/flatlaf/extras/FlatSVGIcon.html): - [FlatSVGIcon](https://www.javadoc.io/doc/com.formdev/flatlaf-extras/latest/com/formdev/flatlaf/extras/FlatSVGIcon.html):
An icon that displays SVG using An icon that displays SVG using [JSVG](https://github.com/weisJ/jsvg).\
[svgSalamander](https://github.com/JFormDesigner/svgSalamander).\
![FlatSVGIcon.png](../images/extras-FlatSVGIcon.png) ![FlatSVGIcon.png](../images/extras-FlatSVGIcon.png)
- [FlatTriStateCheckBox](https://www.javadoc.io/doc/com.formdev/flatlaf-extras/latest/com/formdev/flatlaf/extras/components/FlatTriStateCheckBox.html): - [FlatTriStateCheckBox](https://www.javadoc.io/doc/com.formdev/flatlaf-extras/latest/com/formdev/flatlaf/extras/components/FlatTriStateCheckBox.html):
A tri-state check box.\ A tri-state check box.\
@@ -38,9 +37,9 @@ Otherwise download `flatlaf-extras-<version>.jar` here:
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.formdev/flatlaf-extras/badge.svg?style=flat-square&color=007ec6)](https://maven-badges.herokuapp.com/maven-central/com.formdev/flatlaf-extras) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.formdev/flatlaf-extras/badge.svg?style=flat-square&color=007ec6)](https://maven-badges.herokuapp.com/maven-central/com.formdev/flatlaf-extras)
If SVG classes are used, `svgSalamander-<version>.jar` is also required: If SVG classes are used, `jsvg-<version>.jar` is also required:
[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.formdev/svgSalamander/badge.svg?style=flat-square&color=007ec6)](https://maven-badges.herokuapp.com/maven-central/com.formdev/svgSalamander) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.github.weisj/jsvg/badge.svg?style=flat-square&color=007ec6)](https://maven-badges.herokuapp.com/maven-central/com.github.weisj/jsvg)
Tools Tools

View File

@@ -23,7 +23,7 @@ plugins {
dependencies { dependencies {
implementation( project( ":flatlaf-core" ) ) implementation( project( ":flatlaf-core" ) )
implementation( "com.formdev:svgSalamander:1.1.3" ) implementation( libs.jsvg )
} }
flatlafModuleInfo { flatlafModuleInfo {

View File

@@ -30,8 +30,8 @@ import java.awt.image.RGBImageFilter;
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.net.MalformedURLException;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL; import java.net.URL;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
@@ -49,9 +49,9 @@ import com.formdev.flatlaf.util.LoggingFacade;
import com.formdev.flatlaf.util.MultiResolutionImageSupport; 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.kitfox.svg.SVGDiagram; import com.github.weisj.jsvg.SVGDocument;
import com.kitfox.svg.SVGException; import com.github.weisj.jsvg.geometry.size.FloatSize;
import com.kitfox.svg.SVGUniverse; import com.github.weisj.jsvg.parser.SVGLoader;
/** /**
* An icon that loads and paints SVG. * An icon that loads and paints SVG.
@@ -62,12 +62,9 @@ public class FlatSVGIcon
extends ImageIcon extends ImageIcon
implements DisabledIconProvider implements DisabledIconProvider
{ {
// cache that uses soft references for values, which allows freeing SVG diagrams if no longer used // cache that uses soft references for values, which allows freeing SVG documents if no longer used
private static final SoftCache<URI, SVGDiagram> svgCache = new SoftCache<>(); private static final SoftCache<String, SVGDocument> svgCache = new SoftCache<>();
private static final SVGLoader svgLoader = new SVGLoader();
// use own SVG universe so that it can not be cleared from anywhere
private static final SVGUniverse svgUniverse = new SVGUniverse();
private static int streamNumber;
private final String name; private final String name;
private final int width; private final int width;
@@ -75,11 +72,11 @@ public class FlatSVGIcon
private final float scale; private final float scale;
private final boolean disabled; private final boolean disabled;
private final ClassLoader classLoader; private final ClassLoader classLoader;
private final URI uri; private final URL url;
private ColorFilter colorFilter; private ColorFilter colorFilter;
private SVGDiagram diagram; private SVGDocument document;
private boolean dark; private boolean dark;
private boolean loadFailed; private boolean loadFailed;
@@ -220,7 +217,7 @@ public class FlatSVGIcon
* @since 2 * @since 2
*/ */
public FlatSVGIcon( URL url ) { public FlatSVGIcon( URL url ) {
this( null, -1, -1, 1, false, null, url2uri( url ) ); this( null, -1, -1, 1, false, null, url );
} }
/** /**
@@ -236,7 +233,7 @@ public class FlatSVGIcon
* @since 2 * @since 2
*/ */
public FlatSVGIcon( URI uri ) { public FlatSVGIcon( URI uri ) {
this( null, -1, -1, 1, false, null, uri ); this( null, -1, -1, 1, false, null, uri2url( uri ) );
} }
/** /**
@@ -251,7 +248,7 @@ public class FlatSVGIcon
* @since 2 * @since 2
*/ */
public FlatSVGIcon( File file ) { public FlatSVGIcon( File file ) {
this( null, -1, -1, 1, false, null, file.toURI() ); this( null, -1, -1, 1, false, null, uri2url( file.toURI() ) );
} }
/** /**
@@ -267,19 +264,15 @@ public class FlatSVGIcon
* @since 2 * @since 2
*/ */
public FlatSVGIcon( InputStream in ) throws IOException { public FlatSVGIcon( InputStream in ) throws IOException {
this( null, -1, -1, 1, false, null, loadFromStream( in ) ); this( null, -1, -1, 1, false, null, null );
// since the input stream is already loaded and parsed,
// get diagram here and remove it from cache
update();
synchronized( FlatSVGIcon.class ) {
svgCache.remove( uri );
}
}
private static synchronized URI loadFromStream( InputStream in ) throws IOException {
try( InputStream in2 = in ) { try( InputStream in2 = in ) {
return svgUniverse.loadSVG( in2, "/flatlaf-stream-" + (streamNumber++) ); document = svgLoader.load( in2 );
if( document == null ) {
loadFailed = true;
LoggingFacade.INSTANCE.logSevere( "FlatSVGIcon: failed to load SVG icon from input stream", null );
}
} }
} }
@@ -291,20 +284,22 @@ public class FlatSVGIcon
* @since 2.0.1 * @since 2.0.1
*/ */
public FlatSVGIcon( FlatSVGIcon icon ) { public FlatSVGIcon( FlatSVGIcon icon ) {
this( icon.name, icon.width, icon.height, icon.scale, icon.disabled, icon.classLoader, icon.uri ); this( icon.name, icon.width, icon.height, icon.scale, icon.disabled, icon.classLoader, icon.url );
colorFilter = icon.colorFilter; colorFilter = icon.colorFilter;
diagram = icon.diagram; document = icon.document;
dark = icon.dark; dark = icon.dark;
} }
protected FlatSVGIcon( String name, int width, int height, float scale, boolean disabled, ClassLoader classLoader, URI uri ) { protected FlatSVGIcon( String name, int width, int height, float scale,
boolean disabled, ClassLoader classLoader, URL url )
{
this.name = name; this.name = name;
this.width = width; this.width = width;
this.height = height; this.height = height;
this.scale = scale; this.scale = scale;
this.disabled = disabled; this.disabled = disabled;
this.classLoader = classLoader; this.classLoader = classLoader;
this.uri = uri; this.url = url;
} }
/** /**
@@ -383,9 +378,9 @@ public class FlatSVGIcon
if( width == this.width && height == this.height ) if( width == this.width && height == this.height )
return this; return this;
FlatSVGIcon icon = new FlatSVGIcon( name, width, height, scale, disabled, classLoader, uri ); FlatSVGIcon icon = new FlatSVGIcon( name, width, height, scale, disabled, classLoader, url );
icon.colorFilter = colorFilter; icon.colorFilter = colorFilter;
icon.diagram = diagram; icon.document = document;
icon.dark = dark; icon.dark = dark;
return icon; return icon;
} }
@@ -402,9 +397,9 @@ public class FlatSVGIcon
if( scale == this.scale ) if( scale == this.scale )
return this; return this;
FlatSVGIcon icon = new FlatSVGIcon( name, width, height, scale, disabled, classLoader, uri ); FlatSVGIcon icon = new FlatSVGIcon( name, width, height, scale, disabled, classLoader, url );
icon.colorFilter = colorFilter; icon.colorFilter = colorFilter;
icon.diagram = diagram; icon.document = document;
icon.dark = dark; icon.dark = dark;
return icon; return icon;
} }
@@ -421,9 +416,9 @@ public class FlatSVGIcon
if( disabled ) if( disabled )
return this; return this;
FlatSVGIcon icon = new FlatSVGIcon( name, width, height, scale, true, classLoader, uri ); FlatSVGIcon icon = new FlatSVGIcon( name, width, height, scale, true, classLoader, url );
icon.colorFilter = colorFilter; icon.colorFilter = colorFilter;
icon.diagram = diagram; icon.document = document;
icon.dark = dark; icon.dark = dark;
return icon; return icon;
} }
@@ -462,19 +457,19 @@ public class FlatSVGIcon
if( loadFailed ) if( loadFailed )
return; return;
if( dark == isDarkLaf() && diagram != null ) if( dark == isDarkLaf() && document != null )
return; return;
dark = isDarkLaf(); dark = isDarkLaf();
// SVGs already loaded via url or input stream can not have light/dark variants // SVGs already loaded via url, file or input stream can not have light/dark variants
if( uri != null && diagram != null ) if( document != null && name == null )
return; return;
URI uri = this.uri; URL url = this.url;
if( uri == null ) { if( url == null ) {
URL url = getIconURL( name, dark ); url = getIconURL( name, dark );
if( url == null & dark ) if( url == null && dark )
url = getIconURL( name, false ); url = getIconURL( name, false );
if( url == null ) { if( url == null ) {
@@ -482,33 +477,30 @@ public class FlatSVGIcon
LoggingFacade.INSTANCE.logConfig( "FlatSVGIcon: resource '" + name + "' not found (if using Java modules, check whether icon package is opened in module-info.java)", null ); LoggingFacade.INSTANCE.logConfig( "FlatSVGIcon: resource '" + name + "' not found (if using Java modules, check whether icon package is opened in module-info.java)", null );
return; return;
} }
uri = url2uri( url );
} }
diagram = loadSVG( uri ); document = loadSVG( url );
loadFailed = (diagram == null); loadFailed = (document == null);
} }
static synchronized SVGDiagram loadSVG( URI uri ) { static synchronized SVGDocument loadSVG( URL url ) {
// get from our cache // get from our cache
SVGDiagram diagram = svgCache.get( uri ); String cacheKey = url.toString();
if( diagram != null ) SVGDocument document = svgCache.get( cacheKey );
return diagram; if( document != null )
return document;
// load/get SVG diagram // load SVG document
diagram = svgUniverse.getDiagram( uri ); document = svgLoader.load( url );
if( diagram == null ) { if( document == null ) {
LoggingFacade.INSTANCE.logSevere( "FlatSVGIcon: failed to load '" + uri + "'", null ); LoggingFacade.INSTANCE.logSevere( "FlatSVGIcon: failed to load '" + url + "'", null );
return null; return null;
} }
// add to our (soft) cache and remove from SVGUniverse (hard) cache svgCache.put( cacheKey, document );
svgCache.put( uri, diagram );
svgUniverse.removeDocument( uri );
return diagram; return document;
} }
private URL getIconURL( String name, boolean dark ) { private URL getIconURL( String name, boolean dark ) {
@@ -528,7 +520,7 @@ public class FlatSVGIcon
*/ */
public boolean hasFound() { public boolean hasFound() {
update(); update();
return diagram != null; return document != null;
} }
/** /**
@@ -540,7 +532,7 @@ public class FlatSVGIcon
return scaleSize( width ); return scaleSize( width );
update(); update();
return scaleSize( (diagram != null) ? Math.round( diagram.getWidth() ) : 16 ); return scaleSize( (document != null) ? Math.round( document.size().width ) : 16 );
} }
/** /**
@@ -552,7 +544,7 @@ public class FlatSVGIcon
return scaleSize( height ); return scaleSize( height );
update(); update();
return scaleSize( (diagram != null) ? Math.round( diagram.getHeight() ) : 16 ); return scaleSize( (document != null) ? Math.round( document.size().height ) : 16 );
} }
private int scaleSize( int size ) { private int scaleSize( int size ) {
@@ -583,12 +575,7 @@ public class FlatSVGIcon
Graphics2D g2 = new GraphicsFilter( (Graphics2D) g.create(), colorFilter, ColorFilter.getInstance(), grayFilter ); Graphics2D g2 = new GraphicsFilter( (Graphics2D) g.create(), colorFilter, ColorFilter.getInstance(), grayFilter );
try { try {
// same hints as in FlatUIUtils.setRenderingHints() setRenderingHints( g2 );
g2.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON );
g2.setRenderingHint( RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_NORMALIZE );
// enable better image scaling
g2.setRenderingHint( RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR );
paintSvg( g2, x, y ); paintSvg( g2, x, y );
} finally { } finally {
@@ -597,7 +584,7 @@ public class FlatSVGIcon
} }
private void paintSvg( Graphics2D g, int x, int y ) { private void paintSvg( Graphics2D g, int x, int y ) {
if( diagram == null ) { if( document == null ) {
paintSvgError( g, x, y ); paintSvgError( g, x, y );
return; return;
} }
@@ -607,19 +594,18 @@ public class FlatSVGIcon
UIScale.scaleGraphics( g ); UIScale.scaleGraphics( g );
if( width > 0 || height > 0 ) { if( width > 0 || height > 0 ) {
double sx = (width > 0) ? width / diagram.getWidth() : 1; FloatSize svgSize = document.size();
double sy = (height > 0) ? height / diagram.getHeight() : 1; double sx = (width > 0) ? width / svgSize.width : 1;
double sy = (height > 0) ? height / svgSize.height : 1;
if( sx != 1 || sy != 1 ) if( sx != 1 || sy != 1 )
g.scale( sx, sy ); g.scale( sx, sy );
} }
if( scale != 1 ) if( scale != 1 )
g.scale( scale, scale ); g.scale( scale, scale );
diagram.setIgnoringClipHeuristic( true );
try { try {
diagram.render( g ); document.render( null, g );
} catch( SVGException ex ) { } catch( Exception ex ) {
paintSvgError( g, 0, 0 ); paintSvgError( g, 0, 0 );
} }
} }
@@ -662,10 +648,21 @@ public class FlatSVGIcon
return MultiResolutionImageSupport.create( 0, dimensions, producer ); return MultiResolutionImageSupport.create( 0, dimensions, producer );
} }
static URI url2uri( URL url ) { static void setRenderingHints( Graphics2D g ) {
// enable anti-aliasing
g.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON );
// disable coordinate normalization for correct line rendering
g.setRenderingHint( RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE );
// enable better image scaling
g.setRenderingHint( RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR );
}
static URL uri2url( URI uri ) {
try { try {
return url.toURI(); return uri.toURL();
} catch( URISyntaxException ex ) { } catch( MalformedURLException ex ) {
throw new IllegalArgumentException( ex ); throw new IllegalArgumentException( ex );
} }
} }
@@ -964,6 +961,18 @@ public class FlatSVGIcon
this.grayFilter = grayFilter; this.grayFilter = grayFilter;
} }
@Override
public Graphics create() {
return new GraphicsFilter( (Graphics2D) super.create(),
colorFilter, globalColorFilter, grayFilter );
}
@Override
public Graphics create( int x, int y, int width, int height ) {
return new GraphicsFilter( (Graphics2D) super.create( x, y, width, height ),
colorFilter, globalColorFilter, grayFilter );
}
@Override @Override
public void setColor( Color c ) { public void setColor( Color c ) {
super.setColor( filterColor( c ) ); super.setColor( filterColor( c ) );

View File

@@ -19,7 +19,6 @@ 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.RenderingHints;
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,8 +27,8 @@ import java.util.List;
import javax.swing.JWindow; 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.kitfox.svg.SVGDiagram; import com.github.weisj.jsvg.SVGDocument;
import com.kitfox.svg.SVGException; import com.github.weisj.jsvg.geometry.size.FloatSize;
/** /**
* Utility methods for SVG. * Utility methods for SVG.
@@ -83,7 +82,7 @@ public class FlatSVGUtils
* @since 2 * @since 2
*/ */
public static List<Image> createWindowIconImages( URL svgUrl ) { public static List<Image> createWindowIconImages( URL svgUrl ) {
SVGDiagram diagram = loadSVG( svgUrl ); SVGDocument document = FlatSVGIcon.loadSVG( svgUrl );
if( SystemInfo.isWindows && MultiResolutionImageSupport.isAvailable() ) { if( SystemInfo.isWindows && MultiResolutionImageSupport.isAvailable() ) {
// use a multi-resolution image that creates images on demand for requested sizes // use a multi-resolution image that creates images on demand for requested sizes
@@ -102,17 +101,17 @@ public class FlatSVGUtils
new Dimension( 48, 48 ), // 300% new Dimension( 48, 48 ), // 300%
new Dimension( 64, 64 ), // 400% new Dimension( 64, 64 ), // 400%
}, dim -> { }, dim -> {
return svg2image( diagram, dim.width, dim.height ); return svg2image( document, dim.width, dim.height );
} ) ); } ) );
} else { } else {
return Arrays.asList( return Arrays.asList(
svg2image( diagram, 16, 16 ), // 100% svg2image( document, 16, 16 ), // 100%
svg2image( diagram, 20, 20 ), // 125% svg2image( document, 20, 20 ), // 125%
svg2image( diagram, 24, 24 ), // 150% svg2image( document, 24, 24 ), // 150%
svg2image( diagram, 28, 28 ), // 175% svg2image( document, 28, 28 ), // 175%
svg2image( diagram, 32, 32 ), // 200% svg2image( document, 32, 32 ), // 200%
svg2image( diagram, 48, 48 ), // 300% svg2image( document, 48, 48 ), // 300%
svg2image( diagram, 64, 64 ) // 400% svg2image( document, 64, 64 ) // 400%
); );
} }
} }
@@ -148,7 +147,7 @@ public class FlatSVGUtils
* @since 2 * @since 2
*/ */
public static BufferedImage svg2image( URL svgUrl, int width, int height ) { public static BufferedImage svg2image( URL svgUrl, int width, int height ) {
return svg2image( loadSVG( svgUrl ), width, height ); return svg2image( FlatSVGIcon.loadSVG( svgUrl ), width, height );
} }
/** /**
@@ -180,53 +179,43 @@ public class FlatSVGUtils
* @since 2 * @since 2
*/ */
public static BufferedImage svg2image( URL svgUrl, float scaleFactor ) { public static BufferedImage svg2image( URL svgUrl, float scaleFactor ) {
SVGDiagram diagram = loadSVG( svgUrl ); SVGDocument document = FlatSVGIcon.loadSVG( svgUrl );
int width = (int) (diagram.getWidth() * scaleFactor); FloatSize size = document.size();
int height = (int) (diagram.getHeight() * scaleFactor); int width = (int) (size.width * scaleFactor);
return svg2image( diagram, width, height ); int height = (int) (size.height * scaleFactor);
return svg2image( document, width, height );
} }
/** /**
* Creates a buffered image and renders the given SVGDiagram into it. * Creates a buffered image and renders the given SVGDocument into it.
* *
* @param diagram the SVG diagram * @param document the SVG document
* @param width the width of the image * @param width the width of the image
* @param height the height of the image * @param height the height of the image
* @return the image * @return the image
* @throws RuntimeException if failed to render SVG file * @throws RuntimeException if failed to render SVG file
*/ */
public static BufferedImage svg2image( SVGDiagram diagram, int width, int height ) { private static BufferedImage svg2image( SVGDocument document, int width, int height ) {
try {
BufferedImage image = new BufferedImage( width, height, BufferedImage.TYPE_INT_ARGB ); BufferedImage image = new BufferedImage( width, height, BufferedImage.TYPE_INT_ARGB );
Graphics2D g = image.createGraphics(); Graphics2D g = image.createGraphics();
try { try {
g.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON ); FlatSVGIcon.setRenderingHints( g );
g.setRenderingHint( RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR );
double sx = width / diagram.getWidth(); FloatSize size = document.size();
double sy = height / diagram.getHeight(); double sx = width / size.width;
double sy = height / size.height;
if( sx != 1 || sy != 1 ) if( sx != 1 || sy != 1 )
g.scale( sx, sy ); g.scale( sx, sy );
diagram.setIgnoringClipHeuristic( true ); document.render( null, g );
diagram.render( g );
} finally { } finally {
g.dispose(); g.dispose();
} }
return image; return image;
} catch( SVGException ex ) {
throw new RuntimeException( ex );
}
} }
private static URL getResource( String svgName ) { private static URL getResource( String svgName ) {
return FlatSVGUtils.class.getResource( svgName ); return FlatSVGUtils.class.getResource( svgName );
} }
private static SVGDiagram loadSVG( URL url ) {
return FlatSVGIcon.loadSVG( FlatSVGIcon.url2uri( url ) );
}
} }

View File

@@ -770,6 +770,7 @@ public class FlatUIDefaultsInspector
return String.valueOf( value ); return String.valueOf( value );
} }
@SuppressWarnings( "FormatString" ) // Error Prone
private static String color2hex( Color color ) { private static String color2hex( Color color ) {
int rgb = color.getRGB(); int rgb = color.getRGB();
boolean hasAlpha = color.getAlpha() != 255; boolean hasAlpha = color.getAlpha() != 255;

View File

@@ -14,13 +14,13 @@
* limitations under the License. * limitations under the License.
*/ */
/** /*
* @author Karl Tauber * @author Karl Tauber
*/ */
module com.formdev.flatlaf.extras { module com.formdev.flatlaf.extras {
requires java.desktop; requires java.desktop;
requires java.prefs; requires java.prefs;
requires static com.kitfox.svg; // optional at runtime requires static com.github.weisj.jsvg; // optional at runtime
requires com.formdev.flatlaf; requires com.formdev.flatlaf;
exports com.formdev.flatlaf.extras; exports com.formdev.flatlaf.extras;

View File

@@ -33,9 +33,8 @@ plugins {
dependencies { dependencies {
implementation( project( ":flatlaf-core" ) ) implementation( project( ":flatlaf-core" ) )
testImplementation( "org.junit.jupiter:junit-jupiter-api:5.7.2" ) testImplementation( libs.bundles.junit )
testImplementation( "org.junit.jupiter:junit-jupiter-params" ) testRuntimeOnly( libs.junit.engine )
testRuntimeOnly( "org.junit.jupiter:junit-jupiter-engine" )
} }
flatlafModuleInfo { flatlafModuleInfo {

View File

@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
/** /*
* @author Karl Tauber * @author Karl Tauber
*/ */
module com.formdev.flatlaf.fonts.inter { module com.formdev.flatlaf.fonts.inter {

View File

@@ -33,9 +33,8 @@ plugins {
dependencies { dependencies {
implementation( project( ":flatlaf-core" ) ) implementation( project( ":flatlaf-core" ) )
testImplementation( "org.junit.jupiter:junit-jupiter-api:5.7.2" ) testImplementation( libs.bundles.junit )
testImplementation( "org.junit.jupiter:junit-jupiter-params" ) testRuntimeOnly( libs.junit.engine )
testRuntimeOnly( "org.junit.jupiter:junit-jupiter-engine" )
} }
flatlafModuleInfo { flatlafModuleInfo {

View File

@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
/** /*
* @author Karl Tauber * @author Karl Tauber
*/ */
module com.formdev.flatlaf.fonts.jetbrains_mono { module com.formdev.flatlaf.fonts.jetbrains_mono {

View File

@@ -33,9 +33,8 @@ plugins {
dependencies { dependencies {
implementation( project( ":flatlaf-core" ) ) implementation( project( ":flatlaf-core" ) )
testImplementation( "org.junit.jupiter:junit-jupiter-api:5.7.2" ) testImplementation( libs.bundles.junit )
testImplementation( "org.junit.jupiter:junit-jupiter-params" ) testRuntimeOnly( libs.junit.engine )
testRuntimeOnly( "org.junit.jupiter:junit-jupiter-engine" )
} }
flatlafModuleInfo { flatlafModuleInfo {

View File

@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
/** /*
* @author Karl Tauber * @author Karl Tauber
*/ */
module com.formdev.flatlaf.fonts.roboto_mono { module com.formdev.flatlaf.fonts.roboto_mono {

View File

@@ -33,9 +33,8 @@ plugins {
dependencies { dependencies {
implementation( project( ":flatlaf-core" ) ) implementation( project( ":flatlaf-core" ) )
testImplementation( "org.junit.jupiter:junit-jupiter-api:5.7.2" ) testImplementation( libs.bundles.junit )
testImplementation( "org.junit.jupiter:junit-jupiter-params" ) testRuntimeOnly( libs.junit.engine )
testRuntimeOnly( "org.junit.jupiter:junit-jupiter-engine" )
} }
flatlafModuleInfo { flatlafModuleInfo {

View File

@@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
/** /*
* @author Karl Tauber * @author Karl Tauber
*/ */
module com.formdev.flatlaf.fonts.roboto { module com.formdev.flatlaf.fonts.roboto {

View File

@@ -60,7 +60,7 @@ Name | Class
[Gruvbox Dark Hard](https://github.com/Vincent-P/gruvbox-intellij-theme) | `com.formdev.flatlaf.intellijthemes.FlatGruvboxDarkHardIJTheme` [Gruvbox Dark Hard](https://github.com/Vincent-P/gruvbox-intellij-theme) | `com.formdev.flatlaf.intellijthemes.FlatGruvboxDarkHardIJTheme`
[Gruvbox Dark Medium](https://github.com/Vincent-P/gruvbox-intellij-theme) | `com.formdev.flatlaf.intellijthemes.FlatGruvboxDarkMediumIJTheme` [Gruvbox Dark Medium](https://github.com/Vincent-P/gruvbox-intellij-theme) | `com.formdev.flatlaf.intellijthemes.FlatGruvboxDarkMediumIJTheme`
[Gruvbox Dark Soft](https://github.com/Vincent-P/gruvbox-intellij-theme) | `com.formdev.flatlaf.intellijthemes.FlatGruvboxDarkSoftIJTheme` [Gruvbox Dark Soft](https://github.com/Vincent-P/gruvbox-intellij-theme) | `com.formdev.flatlaf.intellijthemes.FlatGruvboxDarkSoftIJTheme`
[Hiberbee Dark](https://github.com/Hiberbee/code-highlight-themes) | `com.formdev.flatlaf.intellijthemes.FlatHiberbeeDarkIJTheme` [Hiberbee Dark](https://github.com/Hiberbee/themes) | `com.formdev.flatlaf.intellijthemes.FlatHiberbeeDarkIJTheme`
[High contrast](https://github.com/OlyaB/HighContrastTheme) | `com.formdev.flatlaf.intellijthemes.FlatHighContrastIJTheme` [High contrast](https://github.com/OlyaB/HighContrastTheme) | `com.formdev.flatlaf.intellijthemes.FlatHighContrastIJTheme`
[Light Flat](https://github.com/nerzhulart/LightFlatTheme) | `com.formdev.flatlaf.intellijthemes.FlatLightFlatIJTheme` [Light Flat](https://github.com/nerzhulart/LightFlatTheme) | `com.formdev.flatlaf.intellijthemes.FlatLightFlatIJTheme`
[Material Design Dark](https://github.com/xinkunZ/NotReallyMDTheme) | `com.formdev.flatlaf.intellijthemes.FlatMaterialDesignDarkIJTheme` [Material Design Dark](https://github.com/xinkunZ/NotReallyMDTheme) | `com.formdev.flatlaf.intellijthemes.FlatMaterialDesignDarkIJTheme`
@@ -79,36 +79,19 @@ Material Theme UI Lite:
Name | Class Name | Class
-----|------ -----|------
[Arc Dark (Material)](https://github.com/mallowigi/material-theme-ui-lite) | `com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatArcDarkIJTheme` [Arc Dark (Material)](https://github.com/mallowigi/material-theme-ui-lite) | `com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatArcDarkIJTheme`
[Arc Dark Contrast (Material)](https://github.com/mallowigi/material-theme-ui-lite) | `com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatArcDarkContrastIJTheme`
[Atom One Dark (Material)](https://github.com/mallowigi/material-theme-ui-lite) | `com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatAtomOneDarkIJTheme` [Atom One Dark (Material)](https://github.com/mallowigi/material-theme-ui-lite) | `com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatAtomOneDarkIJTheme`
[Atom One Dark Contrast (Material)](https://github.com/mallowigi/material-theme-ui-lite) | `com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatAtomOneDarkContrastIJTheme`
[Atom One Light (Material)](https://github.com/mallowigi/material-theme-ui-lite) | `com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatAtomOneLightIJTheme` [Atom One Light (Material)](https://github.com/mallowigi/material-theme-ui-lite) | `com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatAtomOneLightIJTheme`
[Atom One Light Contrast (Material)](https://github.com/mallowigi/material-theme-ui-lite) | `com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatAtomOneLightContrastIJTheme`
[Dracula (Material)](https://github.com/mallowigi/material-theme-ui-lite) | `com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatDraculaIJTheme` [Dracula (Material)](https://github.com/mallowigi/material-theme-ui-lite) | `com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatDraculaIJTheme`
[Dracula Contrast (Material)](https://github.com/mallowigi/material-theme-ui-lite) | `com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatDraculaContrastIJTheme`
[GitHub (Material)](https://github.com/mallowigi/material-theme-ui-lite) | `com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatGitHubIJTheme` [GitHub (Material)](https://github.com/mallowigi/material-theme-ui-lite) | `com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatGitHubIJTheme`
[GitHub Contrast (Material)](https://github.com/mallowigi/material-theme-ui-lite) | `com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatGitHubContrastIJTheme`
[GitHub Dark (Material)](https://github.com/mallowigi/material-theme-ui-lite) | `com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatGitHubDarkIJTheme` [GitHub Dark (Material)](https://github.com/mallowigi/material-theme-ui-lite) | `com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatGitHubDarkIJTheme`
[GitHub Dark Contrast (Material)](https://github.com/mallowigi/material-theme-ui-lite) | `com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatGitHubDarkContrastIJTheme`
[Light Owl (Material)](https://github.com/mallowigi/material-theme-ui-lite) | `com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatLightOwlIJTheme` [Light Owl (Material)](https://github.com/mallowigi/material-theme-ui-lite) | `com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatLightOwlIJTheme`
[Light Owl Contrast (Material)](https://github.com/mallowigi/material-theme-ui-lite) | `com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatLightOwlContrastIJTheme`
[Material Darker (Material)](https://github.com/mallowigi/material-theme-ui-lite) | `com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMaterialDarkerIJTheme` [Material Darker (Material)](https://github.com/mallowigi/material-theme-ui-lite) | `com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMaterialDarkerIJTheme`
[Material Darker Contrast (Material)](https://github.com/mallowigi/material-theme-ui-lite) | `com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMaterialDarkerContrastIJTheme`
[Material Deep Ocean (Material)](https://github.com/mallowigi/material-theme-ui-lite) | `com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMaterialDeepOceanIJTheme` [Material Deep Ocean (Material)](https://github.com/mallowigi/material-theme-ui-lite) | `com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMaterialDeepOceanIJTheme`
[Material Deep Ocean Contrast (Material)](https://github.com/mallowigi/material-theme-ui-lite) | `com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMaterialDeepOceanContrastIJTheme`
[Material Lighter (Material)](https://github.com/mallowigi/material-theme-ui-lite) | `com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMaterialLighterIJTheme` [Material Lighter (Material)](https://github.com/mallowigi/material-theme-ui-lite) | `com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMaterialLighterIJTheme`
[Material Lighter Contrast (Material)](https://github.com/mallowigi/material-theme-ui-lite) | `com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMaterialLighterContrastIJTheme`
[Material Oceanic (Material)](https://github.com/mallowigi/material-theme-ui-lite) | `com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMaterialOceanicIJTheme` [Material Oceanic (Material)](https://github.com/mallowigi/material-theme-ui-lite) | `com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMaterialOceanicIJTheme`
[Material Oceanic Contrast (Material)](https://github.com/mallowigi/material-theme-ui-lite) | `com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMaterialOceanicContrastIJTheme`
[Material Palenight (Material)](https://github.com/mallowigi/material-theme-ui-lite) | `com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMaterialPalenightIJTheme` [Material Palenight (Material)](https://github.com/mallowigi/material-theme-ui-lite) | `com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMaterialPalenightIJTheme`
[Material Palenight Contrast (Material)](https://github.com/mallowigi/material-theme-ui-lite) | `com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMaterialPalenightContrastIJTheme`
[Monokai Pro (Material)](https://github.com/mallowigi/material-theme-ui-lite) | `com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMonokaiProIJTheme` [Monokai Pro (Material)](https://github.com/mallowigi/material-theme-ui-lite) | `com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMonokaiProIJTheme`
[Monokai Pro Contrast (Material)](https://github.com/mallowigi/material-theme-ui-lite) | `com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMonokaiProContrastIJTheme`
[Moonlight (Material)](https://github.com/mallowigi/material-theme-ui-lite) | `com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMoonlightIJTheme` [Moonlight (Material)](https://github.com/mallowigi/material-theme-ui-lite) | `com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMoonlightIJTheme`
[Moonlight Contrast (Material)](https://github.com/mallowigi/material-theme-ui-lite) | `com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMoonlightContrastIJTheme`
[Night Owl (Material)](https://github.com/mallowigi/material-theme-ui-lite) | `com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatNightOwlIJTheme` [Night Owl (Material)](https://github.com/mallowigi/material-theme-ui-lite) | `com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatNightOwlIJTheme`
[Night Owl Contrast (Material)](https://github.com/mallowigi/material-theme-ui-lite) | `com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatNightOwlContrastIJTheme`
[Solarized Dark (Material)](https://github.com/mallowigi/material-theme-ui-lite) | `com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatSolarizedDarkIJTheme` [Solarized Dark (Material)](https://github.com/mallowigi/material-theme-ui-lite) | `com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatSolarizedDarkIJTheme`
[Solarized Dark Contrast (Material)](https://github.com/mallowigi/material-theme-ui-lite) | `com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatSolarizedDarkContrastIJTheme`
[Solarized Light (Material)](https://github.com/mallowigi/material-theme-ui-lite) | `com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatSolarizedLightIJTheme` [Solarized Light (Material)](https://github.com/mallowigi/material-theme-ui-lite) | `com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatSolarizedLightIJTheme`
[Solarized Light Contrast (Material)](https://github.com/mallowigi/material-theme-ui-lite) | `com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatSolarizedLightContrastIJTheme`

View File

@@ -61,39 +61,22 @@ public class FlatAllIJThemes
new FlatIJLookAndFeelInfo( "Vuesion", "com.formdev.flatlaf.intellijthemes.FlatVuesionIJTheme", true ), new FlatIJLookAndFeelInfo( "Vuesion", "com.formdev.flatlaf.intellijthemes.FlatVuesionIJTheme", true ),
new FlatIJLookAndFeelInfo( "Xcode-Dark", "com.formdev.flatlaf.intellijthemes.FlatXcodeDarkIJTheme", true ), new FlatIJLookAndFeelInfo( "Xcode-Dark", "com.formdev.flatlaf.intellijthemes.FlatXcodeDarkIJTheme", true ),
new FlatIJLookAndFeelInfo( "Arc Dark (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatArcDarkIJTheme", true ), new FlatIJLookAndFeelInfo( "Arc Dark (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatArcDarkIJTheme", true ),
new FlatIJLookAndFeelInfo( "Arc Dark Contrast (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatArcDarkContrastIJTheme", true ),
new FlatIJLookAndFeelInfo( "Atom One Dark (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatAtomOneDarkIJTheme", true ), new FlatIJLookAndFeelInfo( "Atom One Dark (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatAtomOneDarkIJTheme", true ),
new FlatIJLookAndFeelInfo( "Atom One Dark Contrast (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatAtomOneDarkContrastIJTheme", true ),
new FlatIJLookAndFeelInfo( "Atom One Light (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatAtomOneLightIJTheme", false ), new FlatIJLookAndFeelInfo( "Atom One Light (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatAtomOneLightIJTheme", false ),
new FlatIJLookAndFeelInfo( "Atom One Light Contrast (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatAtomOneLightContrastIJTheme", false ),
new FlatIJLookAndFeelInfo( "Dracula (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatDraculaIJTheme", true ), new FlatIJLookAndFeelInfo( "Dracula (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatDraculaIJTheme", true ),
new FlatIJLookAndFeelInfo( "Dracula Contrast (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatDraculaContrastIJTheme", true ),
new FlatIJLookAndFeelInfo( "GitHub (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatGitHubIJTheme", false ), new FlatIJLookAndFeelInfo( "GitHub (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatGitHubIJTheme", false ),
new FlatIJLookAndFeelInfo( "GitHub Contrast (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatGitHubContrastIJTheme", false ),
new FlatIJLookAndFeelInfo( "GitHub Dark (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatGitHubDarkIJTheme", true ), new FlatIJLookAndFeelInfo( "GitHub Dark (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatGitHubDarkIJTheme", true ),
new FlatIJLookAndFeelInfo( "GitHub Dark Contrast (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatGitHubDarkContrastIJTheme", true ),
new FlatIJLookAndFeelInfo( "Light Owl (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatLightOwlIJTheme", false ), new FlatIJLookAndFeelInfo( "Light Owl (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatLightOwlIJTheme", false ),
new FlatIJLookAndFeelInfo( "Light Owl Contrast (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatLightOwlContrastIJTheme", false ),
new FlatIJLookAndFeelInfo( "Material Darker (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMaterialDarkerIJTheme", true ), new FlatIJLookAndFeelInfo( "Material Darker (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMaterialDarkerIJTheme", true ),
new FlatIJLookAndFeelInfo( "Material Darker Contrast (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMaterialDarkerContrastIJTheme", true ),
new FlatIJLookAndFeelInfo( "Material Deep Ocean (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMaterialDeepOceanIJTheme", true ), new FlatIJLookAndFeelInfo( "Material Deep Ocean (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMaterialDeepOceanIJTheme", true ),
new FlatIJLookAndFeelInfo( "Material Deep Ocean Contrast (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMaterialDeepOceanContrastIJTheme", true ),
new FlatIJLookAndFeelInfo( "Material Lighter (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMaterialLighterIJTheme", false ), new FlatIJLookAndFeelInfo( "Material Lighter (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMaterialLighterIJTheme", false ),
new FlatIJLookAndFeelInfo( "Material Lighter Contrast (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMaterialLighterContrastIJTheme", false ),
new FlatIJLookAndFeelInfo( "Material Oceanic (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMaterialOceanicIJTheme", true ), new FlatIJLookAndFeelInfo( "Material Oceanic (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMaterialOceanicIJTheme", true ),
new FlatIJLookAndFeelInfo( "Material Oceanic Contrast (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMaterialOceanicContrastIJTheme", true ),
new FlatIJLookAndFeelInfo( "Material Palenight (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMaterialPalenightIJTheme", true ), new FlatIJLookAndFeelInfo( "Material Palenight (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMaterialPalenightIJTheme", true ),
new FlatIJLookAndFeelInfo( "Material Palenight Contrast (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMaterialPalenightContrastIJTheme", true ),
new FlatIJLookAndFeelInfo( "Monokai Pro (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMonokaiProIJTheme", true ), new FlatIJLookAndFeelInfo( "Monokai Pro (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMonokaiProIJTheme", true ),
new FlatIJLookAndFeelInfo( "Monokai Pro Contrast (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMonokaiProContrastIJTheme", true ),
new FlatIJLookAndFeelInfo( "Moonlight (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMoonlightIJTheme", true ), new FlatIJLookAndFeelInfo( "Moonlight (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMoonlightIJTheme", true ),
new FlatIJLookAndFeelInfo( "Moonlight Contrast (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMoonlightContrastIJTheme", true ),
new FlatIJLookAndFeelInfo( "Night Owl (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatNightOwlIJTheme", true ), new FlatIJLookAndFeelInfo( "Night Owl (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatNightOwlIJTheme", true ),
new FlatIJLookAndFeelInfo( "Night Owl Contrast (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatNightOwlContrastIJTheme", true ),
new FlatIJLookAndFeelInfo( "Solarized Dark (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatSolarizedDarkIJTheme", true ), new FlatIJLookAndFeelInfo( "Solarized Dark (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatSolarizedDarkIJTheme", true ),
new FlatIJLookAndFeelInfo( "Solarized Dark Contrast (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatSolarizedDarkContrastIJTheme", true ),
new FlatIJLookAndFeelInfo( "Solarized Light (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatSolarizedLightIJTheme", false ), new FlatIJLookAndFeelInfo( "Solarized Light (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatSolarizedLightIJTheme", false ),
new FlatIJLookAndFeelInfo( "Solarized Light Contrast (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatSolarizedLightContrastIJTheme", false ),
}; };
//---- class FlatIJLookAndFeelInfo ---------------------------------------- //---- class FlatIJLookAndFeelInfo ----------------------------------------

View File

@@ -1,54 +0,0 @@
/*
* Copyright 2020 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.intellijthemes.materialthemeuilite;
//
// DO NOT MODIFY
// Generated with com.formdev.flatlaf.demo.intellijthemes.IJThemesClassGenerator
//
import com.formdev.flatlaf.IntelliJTheme;
/**
* @author Karl Tauber
*/
public class FlatArcDarkContrastIJTheme
extends IntelliJTheme.ThemeLaf
{
public static final String NAME = "Arc Dark Contrast (Material)";
public static boolean setup() {
try {
return setup( new FlatArcDarkContrastIJTheme() );
} catch( RuntimeException ex ) {
return false;
}
}
public static void installLafInfo() {
installLafInfo( NAME, FlatArcDarkContrastIJTheme.class );
}
public FlatArcDarkContrastIJTheme() {
super( Utils.loadTheme( "Arc Dark Contrast.theme.json" ) );
}
@Override
public String getName() {
return NAME;
}
}

View File

@@ -1,54 +0,0 @@
/*
* Copyright 2020 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.intellijthemes.materialthemeuilite;
//
// DO NOT MODIFY
// Generated with com.formdev.flatlaf.demo.intellijthemes.IJThemesClassGenerator
//
import com.formdev.flatlaf.IntelliJTheme;
/**
* @author Karl Tauber
*/
public class FlatAtomOneDarkContrastIJTheme
extends IntelliJTheme.ThemeLaf
{
public static final String NAME = "Atom One Dark Contrast (Material)";
public static boolean setup() {
try {
return setup( new FlatAtomOneDarkContrastIJTheme() );
} catch( RuntimeException ex ) {
return false;
}
}
public static void installLafInfo() {
installLafInfo( NAME, FlatAtomOneDarkContrastIJTheme.class );
}
public FlatAtomOneDarkContrastIJTheme() {
super( Utils.loadTheme( "Atom One Dark Contrast.theme.json" ) );
}
@Override
public String getName() {
return NAME;
}
}

View File

@@ -1,54 +0,0 @@
/*
* Copyright 2020 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.intellijthemes.materialthemeuilite;
//
// DO NOT MODIFY
// Generated with com.formdev.flatlaf.demo.intellijthemes.IJThemesClassGenerator
//
import com.formdev.flatlaf.IntelliJTheme;
/**
* @author Karl Tauber
*/
public class FlatAtomOneLightContrastIJTheme
extends IntelliJTheme.ThemeLaf
{
public static final String NAME = "Atom One Light Contrast (Material)";
public static boolean setup() {
try {
return setup( new FlatAtomOneLightContrastIJTheme() );
} catch( RuntimeException ex ) {
return false;
}
}
public static void installLafInfo() {
installLafInfo( NAME, FlatAtomOneLightContrastIJTheme.class );
}
public FlatAtomOneLightContrastIJTheme() {
super( Utils.loadTheme( "Atom One Light Contrast.theme.json" ) );
}
@Override
public String getName() {
return NAME;
}
}

View File

@@ -1,54 +0,0 @@
/*
* Copyright 2020 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.intellijthemes.materialthemeuilite;
//
// DO NOT MODIFY
// Generated with com.formdev.flatlaf.demo.intellijthemes.IJThemesClassGenerator
//
import com.formdev.flatlaf.IntelliJTheme;
/**
* @author Karl Tauber
*/
public class FlatDraculaContrastIJTheme
extends IntelliJTheme.ThemeLaf
{
public static final String NAME = "Dracula Contrast (Material)";
public static boolean setup() {
try {
return setup( new FlatDraculaContrastIJTheme() );
} catch( RuntimeException ex ) {
return false;
}
}
public static void installLafInfo() {
installLafInfo( NAME, FlatDraculaContrastIJTheme.class );
}
public FlatDraculaContrastIJTheme() {
super( Utils.loadTheme( "Dracula Contrast.theme.json" ) );
}
@Override
public String getName() {
return NAME;
}
}

View File

@@ -1,54 +0,0 @@
/*
* Copyright 2020 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.intellijthemes.materialthemeuilite;
//
// DO NOT MODIFY
// Generated with com.formdev.flatlaf.demo.intellijthemes.IJThemesClassGenerator
//
import com.formdev.flatlaf.IntelliJTheme;
/**
* @author Karl Tauber
*/
public class FlatGitHubContrastIJTheme
extends IntelliJTheme.ThemeLaf
{
public static final String NAME = "GitHub Contrast (Material)";
public static boolean setup() {
try {
return setup( new FlatGitHubContrastIJTheme() );
} catch( RuntimeException ex ) {
return false;
}
}
public static void installLafInfo() {
installLafInfo( NAME, FlatGitHubContrastIJTheme.class );
}
public FlatGitHubContrastIJTheme() {
super( Utils.loadTheme( "GitHub Contrast.theme.json" ) );
}
@Override
public String getName() {
return NAME;
}
}

View File

@@ -1,54 +0,0 @@
/*
* Copyright 2020 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.intellijthemes.materialthemeuilite;
//
// DO NOT MODIFY
// Generated with com.formdev.flatlaf.demo.intellijthemes.IJThemesClassGenerator
//
import com.formdev.flatlaf.IntelliJTheme;
/**
* @author Karl Tauber
*/
public class FlatGitHubDarkContrastIJTheme
extends IntelliJTheme.ThemeLaf
{
public static final String NAME = "GitHub Dark Contrast (Material)";
public static boolean setup() {
try {
return setup( new FlatGitHubDarkContrastIJTheme() );
} catch( RuntimeException ex ) {
return false;
}
}
public static void installLafInfo() {
installLafInfo( NAME, FlatGitHubDarkContrastIJTheme.class );
}
public FlatGitHubDarkContrastIJTheme() {
super( Utils.loadTheme( "GitHub Dark Contrast.theme.json" ) );
}
@Override
public String getName() {
return NAME;
}
}

Some files were not shown because too many files have changed in this diff Show More