mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2026-02-11 06:27:13 -06:00
Compare commits
106 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2870ee5c51 | ||
|
|
23f8ce867b | ||
|
|
835a1f155b | ||
|
|
3925f198d9 | ||
|
|
d8e59f2cf3 | ||
|
|
666b99971d | ||
|
|
0ba7798cbd | ||
|
|
c486f695f2 | ||
|
|
0bc2513c46 | ||
|
|
bc3504378b | ||
|
|
94fc75dc78 | ||
|
|
681c0cd4fe | ||
|
|
f7495a0a5b | ||
|
|
dd44d3ed2d | ||
|
|
86a4d0ab12 | ||
|
|
b43c3a9e00 | ||
|
|
babc8aa55d | ||
|
|
5dc88a6210 | ||
|
|
d612b9f4b8 | ||
|
|
9b1ae5c74a | ||
|
|
143f96360b | ||
|
|
f5e6b90e02 | ||
|
|
f36886aeb3 | ||
|
|
d26eb2674f | ||
|
|
68b8769d0d | ||
|
|
7f37e884d3 | ||
|
|
a4dc1b4151 | ||
|
|
022a67929a | ||
|
|
f7c867fb97 | ||
|
|
f0685d179e | ||
|
|
c8eaf5f587 | ||
|
|
ed69049c08 | ||
|
|
ae4037ee82 | ||
|
|
411a2f6d29 | ||
|
|
f24b3a6022 | ||
|
|
ebacad2d04 | ||
|
|
76f436726f | ||
|
|
6c8f813e53 | ||
|
|
5f6cc719ad | ||
|
|
00858002de | ||
|
|
072cc3c488 | ||
|
|
1f594b2ba8 | ||
|
|
c32c00a5eb | ||
|
|
3a8a55a545 | ||
|
|
6c49b8bc4d | ||
|
|
cca9707f6b | ||
|
|
f30dd876e4 | ||
|
|
c6872d48b3 | ||
|
|
5e78b21df7 | ||
|
|
2ef87dc789 | ||
|
|
28904c34cc | ||
|
|
91f19bf94c | ||
|
|
0ea188f8db | ||
|
|
6c77b81277 | ||
|
|
ddee4ef526 | ||
|
|
f11f68282b | ||
|
|
ac0cceb09b | ||
|
|
a238fd4505 | ||
|
|
8dc6242889 | ||
|
|
d17fffb82a | ||
|
|
0ad3180b10 | ||
|
|
80ba75fdeb | ||
|
|
7027821c00 | ||
|
|
a3a49cef73 | ||
|
|
abf77d5399 | ||
|
|
6404b8de2a | ||
|
|
19055d5a18 | ||
|
|
c12adf12e7 | ||
|
|
b9c68fbe77 | ||
|
|
7bdfd49921 | ||
|
|
58fa2a5085 | ||
|
|
a400799db5 | ||
|
|
2a8e487c1f | ||
|
|
145631fd43 | ||
|
|
6a774d8c70 | ||
|
|
bfd746f981 | ||
|
|
3af54b7215 | ||
|
|
3ba9fc6c1c | ||
|
|
0a9ecd66a9 | ||
|
|
6991d6729e | ||
|
|
304cb0d57b | ||
|
|
41332de275 | ||
|
|
ef61ae504b | ||
|
|
f96baf1bc2 | ||
|
|
1462636e97 | ||
|
|
7e59a7f4af | ||
|
|
e9a21848bc | ||
|
|
1dcb251ecb | ||
|
|
3f33543cee | ||
|
|
84bd2088f2 | ||
|
|
4f4a3132c5 | ||
|
|
e064c934cb | ||
|
|
16fc3cabf2 | ||
|
|
7e002ff6c2 | ||
|
|
323c0c62c3 | ||
|
|
ff5bd301cc | ||
|
|
c37712b0f0 | ||
|
|
ee9e238592 | ||
|
|
da5d6fa157 | ||
|
|
d471f08b15 | ||
|
|
b97424f767 | ||
|
|
a20cfa6db3 | ||
|
|
6ac6698ecf | ||
|
|
8004d2761a | ||
|
|
25c2bbc851 | ||
|
|
33e37a7167 |
99
.github/workflows/ci.yml
vendored
99
.github/workflows/ci.yml
vendored
@@ -20,8 +20,43 @@ on:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: build (11)
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: gradle/actions/wrapper-validation@v4
|
||||
|
||||
- name: Setup Java 11
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
java-version: 11
|
||||
distribution: temurin # pre-installed on ubuntu-latest
|
||||
cache: gradle
|
||||
|
||||
- name: Check with Error Prone
|
||||
run: ./gradlew errorprone clean
|
||||
|
||||
- name: Build with Gradle
|
||||
run: ./gradlew build
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: FlatLaf-build-artifacts
|
||||
path: |
|
||||
flatlaf-*/build/libs
|
||||
flatlaf-*/flatlaf-*/build/libs
|
||||
!**/*-javadoc.jar
|
||||
!**/*-sources.jar
|
||||
|
||||
|
||||
build-on:
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
if: github.repository == 'JFormDesigner/FlatLaf'
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
# test against
|
||||
@@ -30,7 +65,6 @@ jobs:
|
||||
# - latest Java version(s)
|
||||
java:
|
||||
- 8
|
||||
- 11 # LTS
|
||||
- 17 # LTS
|
||||
- 21 # LTS
|
||||
- 23 # latest
|
||||
@@ -42,9 +76,6 @@ jobs:
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: gradle/wrapper-validation-action@v2
|
||||
if: matrix.java == '8'
|
||||
|
||||
- name: Setup Java ${{ matrix.java }}
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
@@ -52,28 +83,13 @@ jobs:
|
||||
distribution: temurin # Java 8, 11, 17 and 21 are pre-installed on ubuntu-latest
|
||||
cache: gradle
|
||||
|
||||
- name: Check with Error Prone
|
||||
if: matrix.java == '11'
|
||||
run: ./gradlew errorprone clean -Dtoolchain=${{ matrix.toolchain }}
|
||||
|
||||
- name: Build with Gradle
|
||||
run: ./gradlew build -Dtoolchain=${{ matrix.toolchain }}
|
||||
|
||||
- name: Upload artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
if: matrix.java == '11'
|
||||
with:
|
||||
name: FlatLaf-build-artifacts
|
||||
path: |
|
||||
flatlaf-*/build/libs
|
||||
flatlaf-*/flatlaf-*/build/libs
|
||||
!**/*-javadoc.jar
|
||||
!**/*-sources.jar
|
||||
|
||||
|
||||
snapshot:
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
needs: build-on
|
||||
if: |
|
||||
github.event_name == 'push' &&
|
||||
(github.ref == 'refs/heads/main' || startsWith( github.ref, 'refs/heads/develop-' )) &&
|
||||
@@ -90,26 +106,15 @@ jobs:
|
||||
cache: gradle
|
||||
|
||||
- name: Publish snapshot to oss.sonatype.org
|
||||
run: ./gradlew publish :flatlaf-theme-editor:build -PskipFonts -Dorg.gradle.internal.publish.checksums.insecure=true -Dorg.gradle.parallel=false
|
||||
run: ./gradlew publish -PskipFonts -Dorg.gradle.internal.publish.checksums.insecure=true -Dorg.gradle.parallel=false
|
||||
env:
|
||||
OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }}
|
||||
OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }}
|
||||
|
||||
- name: Upload theme editor
|
||||
uses: sebastianpopp/ftp-action@releases/v2
|
||||
with:
|
||||
host: ${{ secrets.FTP_SERVER }}
|
||||
user: ${{ secrets.FTP_USERNAME }}
|
||||
password: ${{ secrets.FTP_PASSWORD }}
|
||||
forceSsl: true
|
||||
localDir: "flatlaf-theme-editor/build/libs"
|
||||
remoteDir: "snapshots"
|
||||
options: "--only-newer --no-recursion --verbose=1"
|
||||
|
||||
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
needs: build-on
|
||||
if: |
|
||||
github.event_name == 'push' &&
|
||||
startsWith( github.ref, 'refs/tags/' ) &&
|
||||
@@ -133,24 +138,12 @@ jobs:
|
||||
SIGNING_KEY: ${{ secrets.SIGNING_KEY }}
|
||||
SIGNING_PASSWORD: ${{ secrets.SIGNING_PASSWORD }}
|
||||
|
||||
- name: Upload demo
|
||||
uses: sebastianpopp/ftp-action@releases/v2
|
||||
with:
|
||||
host: ${{ secrets.FTP_SERVER }}
|
||||
user: ${{ secrets.FTP_USERNAME }}
|
||||
password: ${{ secrets.FTP_PASSWORD }}
|
||||
forceSsl: true
|
||||
localDir: "flatlaf-demo/build/libs"
|
||||
remoteDir: "."
|
||||
options: "--only-newer --no-recursion --verbose=1"
|
||||
- name: Install lftp
|
||||
run: sudo apt-get -y install lftp
|
||||
|
||||
- name: Upload theme editor
|
||||
uses: sebastianpopp/ftp-action@releases/v2
|
||||
with:
|
||||
host: ${{ secrets.FTP_SERVER }}
|
||||
user: ${{ secrets.FTP_USERNAME }}
|
||||
password: ${{ secrets.FTP_PASSWORD }}
|
||||
forceSsl: true
|
||||
localDir: "flatlaf-theme-editor/build/libs"
|
||||
remoteDir: "."
|
||||
options: "--only-newer --no-recursion --verbose=1"
|
||||
- name: Upload demo and theme editor
|
||||
run: >
|
||||
lftp -c "set ftp:ssl-force true;
|
||||
open -u ${{ secrets.FTP_USERNAME }},${{ secrets.FTP_PASSWORD }} ${{ secrets.FTP_SERVER }};
|
||||
mput flatlaf-demo/build/libs/flatlaf-demo-*.jar;
|
||||
mput flatlaf-theme-editor/build/libs/flatlaf-theme-editor-*.jar"
|
||||
|
||||
19
.github/workflows/natives.yml
vendored
19
.github/workflows/natives.yml
vendored
@@ -21,16 +21,25 @@ jobs:
|
||||
strategy:
|
||||
matrix:
|
||||
os:
|
||||
- windows
|
||||
- macos
|
||||
- ubuntu
|
||||
- windows-latest
|
||||
- macos-latest
|
||||
- ubuntu-latest
|
||||
- ubuntu-24.04-arm
|
||||
|
||||
runs-on: ${{ matrix.os }}-latest
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- uses: gradle/wrapper-validation-action@v2
|
||||
- uses: gradle/actions/wrapper-validation@v4
|
||||
|
||||
- name: install libxt-dev
|
||||
if: matrix.os == 'ubuntu-latest' || matrix.os == 'ubuntu-24.04-arm'
|
||||
run: sudo apt install libxt-dev
|
||||
|
||||
- name: install g++-aarch64-linux-gnu
|
||||
if: matrix.os == 'ubuntu-latest'
|
||||
run: sudo apt install g++-aarch64-linux-gnu
|
||||
|
||||
- name: Setup Java 11
|
||||
uses: actions/setup-java@v4
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -5,6 +5,7 @@ build/
|
||||
.project
|
||||
.settings/
|
||||
.idea/
|
||||
.consulo/
|
||||
out/
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
154
CHANGELOG.md
154
CHANGELOG.md
@@ -1,6 +1,160 @@
|
||||
FlatLaf Change Log
|
||||
==================
|
||||
|
||||
## 3.6
|
||||
|
||||
#### New features and improvements
|
||||
|
||||
- macOS: Re-enabled rounded popup border (see PR #772) on macOS 14.4+ (was
|
||||
disabled in 3.5.x).
|
||||
- Increased contrast of text for better readability: (PR #972; issue #762)
|
||||
- In **FlatLaf Dark**, **FlatLaf Darcula** and many dark IntelliJ themes, made
|
||||
all text colors brighter.
|
||||
- In **FlatLaf Light**, **FlatLaf IntelliJ** and many light IntelliJ themes,
|
||||
made disabled text colors slightly darker.
|
||||
- In **FlatLaf macOS Light**, made disabled text colors darker.
|
||||
- In **FlatLaf macOS Dark**, made text colors of "default" button and selected
|
||||
ToggleButton lighter.
|
||||
- CheckBox: Support styling indeterminate state of
|
||||
[tri-state check boxes](https://www.javadoc.io/doc/com.formdev/flatlaf-extras/latest/com/formdev/flatlaf/extras/components/FlatTriStateCheckBox.html).
|
||||
(PR #936; issue #919)
|
||||
- List: Support for alternate row highlighting. (PR #939)
|
||||
- Tree: Support for alternate row highlighting. (PR #903)
|
||||
- Tree: Support wide cell renderer. (issue #922)
|
||||
- ScrollBar: Use rounded thumb also on Windows (as on macOS and Linux) and made
|
||||
thumb slightly darker/lighter. (issue #918)
|
||||
- Extras: `FlatSVGIcon` color filters now can access painting component to
|
||||
implement component state based color mappings. (issue #906)
|
||||
- Linux:
|
||||
- Rounded iconify/maximize/close buttons if using FlatLaf window decorations.
|
||||
(PR #971)
|
||||
- Added `libflatlaf-linux-arm64.so` for Linux on ARM64. (issue #899)
|
||||
- Use X11 window manager events to resize window, if FlatLaf window
|
||||
decorations are enabled. This gives FlatLaf windows a more "native" feeling.
|
||||
(issue #866)
|
||||
- IntelliJ Themes:
|
||||
- Updated to latest versions and fixed various issues.
|
||||
- Support customizing through properties files. (issue #824)
|
||||
- SwingX: Support `JXTipOfTheDay` component. (issue #980)
|
||||
- Support key prefixes for Linux desktop environments (e.g. `[gnome]`, `[kde]`
|
||||
or `[xfce]`) in properties files. (issue #974)
|
||||
- Support custom key prefixes (e.g. `[win10]` or `[test]`) in properties files.
|
||||
(issue #649)
|
||||
- Support multi-prefixed keys (e.g. `[dark][gnome]TitlePane.buttonBackground`).
|
||||
The value is only used if all prefixes match current platform/theme.
|
||||
- Support new component border color to indicate success state (set client
|
||||
property `JComponent.outline` to `success`). (PR #982, issue #945)
|
||||
- Fonts: Updated **Inter** to
|
||||
[v4.1](https://github.com/rsms/inter/releases/tag/v4.1).
|
||||
|
||||
#### Fixed bugs
|
||||
|
||||
- Button: Fixed background and foreground colors for `borderless` and
|
||||
`toolBarButton` style default buttons (`JButton.isDefaultButton()` is `true`).
|
||||
(issue #947)
|
||||
- FileChooser: Improved performance when navigating to large directories with
|
||||
thousands of files. (issue #953)
|
||||
- PopupFactory: Fixed NPE on Windows 10 when `owner` is `null`. (issue #952)
|
||||
- Popup: On Windows 10, drop shadow of heavy-weight popup was not updated if
|
||||
popup moved/resized. (issue #942)
|
||||
- FlatLaf window decorations:
|
||||
- Minimize and maximize icons were not shown for custom scale factors less
|
||||
than 100% (e.g. `-Dflatlaf.uiScale=75%`). (issue #951)
|
||||
- Linux: Fixed occasional maximizing of window when single-clicking the
|
||||
window's title bar. (issue #637)
|
||||
- Styling: MigLayout visual padding was not updated after applying style to
|
||||
Button, ComboBox, Spinner, TextField (and subclasses) and ToggleButton. (issue
|
||||
#965)
|
||||
- Linux: Popups (menus and combobox lists) were not hidden when window is moved,
|
||||
resized, maximized, restored, iconified or switched to another window. (issue
|
||||
#962)
|
||||
- Fixed loading FlatLaf UI delegate classes when using FlatLaf in special
|
||||
application where multiple class loaders are involved. E.g. in Eclipse plugin
|
||||
or in LibreOffice extension. (issues #955 and #851)
|
||||
- HTML: Fixed rendering of `<hr noshade>` in dark themes. (issue #932)
|
||||
- TextComponents: `selectAllOnFocusPolicy` related changes:
|
||||
- No longer select all text if selection (or caret position) was changed by
|
||||
application and `selectAllOnFocusPolicy` is `once` (the default). (issue
|
||||
#983)
|
||||
- FormattedTextField and Spinner: `selectAllOnFocusPolicy = once` behaves now
|
||||
as `always` (was `never` before), which means that all text is selected when
|
||||
component gains focus. This is because of special behavior of
|
||||
`JFormattedTextField` that did not allow implementation of `once`.
|
||||
- Client property `JTextField.selectAllOnFocusPolicy` now also works on
|
||||
(editable) `JComboBox` and on `JSpinner`.
|
||||
- Added client property `JTextField.selectAllOnMouseClick` to override UI
|
||||
property `TextComponent.selectAllOnMouseClick`. (issue #961)
|
||||
- For `selectAllOnMouseClick = true`, clicking with the mouse into the text
|
||||
field, to focus it, now always selects all text, even if
|
||||
`selectAllOnFocusPolicy` is `once`.
|
||||
|
||||
#### Incompatibilities
|
||||
|
||||
- IntelliJ Themes:
|
||||
- Theme prefix in `IntelliJTheme$ThemeLaf.properties` changed from
|
||||
`[theme-name]` to `{theme-name}`.
|
||||
- Renamed classes in package
|
||||
`com.formdev.flatlaf.intellijthemes.materialthemeuilite` from `Flat<theme>`
|
||||
to `FlatMT<theme>`.
|
||||
- Removed `Gruvbox Dark Medium` and `Gruvbox Dark Soft` themes.
|
||||
- Prefixed keys in properties files (e.g. `[dark]Button.background` or
|
||||
`[win]Button.arc`) are now handled earlier than before. In previous versions,
|
||||
prefixed keys always had higher priority than unprefixed keys and did always
|
||||
overwrite unprefixed keys. Now prefixed keys are handled in same order as
|
||||
unprefixed keys, which means that if a key is prefixed and unprefixed (e.g.
|
||||
`[win]Button.arc` and `Button.arc`), the one which is last specified in
|
||||
properties file is used.\
|
||||
Following worked in previous versions, but now `Button.arc` is always `6`:
|
||||
~~~properties
|
||||
[win]Button.arc = 12
|
||||
Button.arc = 6
|
||||
~~~
|
||||
This works in new (and old) versions:
|
||||
~~~properties
|
||||
Button.arc = 6
|
||||
[win]Button.arc = 12
|
||||
~~~
|
||||
|
||||
|
||||
## 3.5.4
|
||||
|
||||
#### Fixed bugs
|
||||
|
||||
- HTML: Fixed NPE when using HTML text on a component with `null` font. (issue
|
||||
#930; PR #931; regression in 3.5)
|
||||
- Linux: Fixed NPE when using FlatLaf window decorations and switching theme.
|
||||
(issue #933; regression in 3.5.3)
|
||||
|
||||
|
||||
## 3.5.3
|
||||
|
||||
#### Fixed bugs
|
||||
|
||||
- HTML: Fixed wrong rendering if HTML text contains `<style>` tag with
|
||||
attributes (e.g. `<style type='text/css'>`). (issue #905; regression in 3.5.1)
|
||||
- FlatLaf window decorations:
|
||||
- Windows: Fixed possible deadlock with TabbedPane in window title area in
|
||||
"full window content" mode. (issue #909)
|
||||
- Windows: Fixed wrong layout in maximized frame after changing screen scale
|
||||
factor. (issue #904)
|
||||
- Linux: Fixed continuous cursor toggling between resize and standard cursor
|
||||
when resizing window. (issue #907)
|
||||
- Fixed sometimes broken window moving with SplitPane in window title area in
|
||||
"full window content" mode. (issue #926)
|
||||
- Popup: On Windows 10, fixed misplaced popup drop shadow. (issue #911;
|
||||
regression in 3.5)
|
||||
- Popup: Fixed NPE if `GraphicsConfiguration` is `null` on Windows. (issue #921)
|
||||
- Theme Editor: Fixed using color picker on secondary screen.
|
||||
- Fixed detection of Windows 11 if custom exe launcher does not specify Windows
|
||||
10+ compatibility in application manifest. (issue #916)
|
||||
- Linux: Fixed slightly different font size (or letter width) used to paint HTML
|
||||
text when default font family is _Cantarell_ (e.g. on Fedora). (issue #912)
|
||||
|
||||
#### Other Changes
|
||||
|
||||
- Class `FlatPropertiesLaf` now supports FlatLaf macOS themes as base themes.
|
||||
|
||||
|
||||
## 3.5.2
|
||||
|
||||
#### Fixed bugs
|
||||
|
||||
@@ -35,7 +35,9 @@ Sponsors
|
||||
|
||||
### Current Sponsors
|
||||
|
||||
[](https://www.formdev.com/flatlaf/sponsor/)
|
||||
<a href="https://exocharts.com/"><img src="https://www.formdev.com/flatlaf/sponsor/Exocharts.png" width="200" alt="Exocharts" title="Exocharts - Professional Grade OrderFlow"></a>
|
||||
|
||||
<!-- [](https://www.formdev.com/flatlaf/sponsor/) -->
|
||||
|
||||
[Become a Sponsor](https://www.formdev.com/flatlaf/sponsor/)
|
||||
|
||||
@@ -224,6 +226,8 @@ Applications using FlatLaf
|
||||
language created to learn programming
|
||||
- [lsfusion platform](https://github.com/lsfusion/platform) - information
|
||||
systems development platform
|
||||
-  [Consulo](https://github.com/consulo/consulo) - open
|
||||
source cross-platform multi-language IDE (Java, .NET, JS, etc)
|
||||
|
||||
### Electrical
|
||||
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
||||
org.eclipse.jdt.core.compiler.compliance=1.8
|
||||
org.eclipse.jdt.core.compiler.source=1.8
|
||||
org.eclipse.jdt.core.formatter.align_assignment_statements_on_columns=false
|
||||
org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647
|
||||
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
|
||||
|
||||
@@ -156,5 +156,6 @@ flatlafPublish {
|
||||
NativeArtifact( "${natives}/libflatlaf-macos-arm64.dylib", "macos-arm64", "dylib" ),
|
||||
NativeArtifact( "${natives}/libflatlaf-macos-x86_64.dylib", "macos-x86_64", "dylib" ),
|
||||
NativeArtifact( "${natives}/libflatlaf-linux-x86_64.so", "linux-x86_64", "so" ),
|
||||
NativeArtifact( "${natives}/libflatlaf-linux-arm64.so", "linux-arm64", "so" ),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#Signature file v4.1
|
||||
#Version 3.5.2
|
||||
#Version 3.6
|
||||
|
||||
CLSS public abstract interface com.formdev.flatlaf.FlatClientProperties
|
||||
fld public final static java.lang.String BUTTON_TYPE = "JButton.buttonType"
|
||||
@@ -24,6 +24,7 @@ fld public final static java.lang.String MINIMUM_HEIGHT = "JComponent.minimumHei
|
||||
fld public final static java.lang.String MINIMUM_WIDTH = "JComponent.minimumWidth"
|
||||
fld public final static java.lang.String OUTLINE = "JComponent.outline"
|
||||
fld public final static java.lang.String OUTLINE_ERROR = "error"
|
||||
fld public final static java.lang.String OUTLINE_SUCCESS = "success"
|
||||
fld public final static java.lang.String OUTLINE_WARNING = "warning"
|
||||
fld public final static java.lang.String PLACEHOLDER_TEXT = "JTextField.placeholderText"
|
||||
fld public final static java.lang.String POPUP_BORDER_CORNER_RADIUS = "Popup.borderCornerRadius"
|
||||
@@ -40,6 +41,7 @@ fld public final static java.lang.String SELECT_ALL_ON_FOCUS_POLICY = "JTextFiel
|
||||
fld public final static java.lang.String SELECT_ALL_ON_FOCUS_POLICY_ALWAYS = "always"
|
||||
fld public final static java.lang.String SELECT_ALL_ON_FOCUS_POLICY_NEVER = "never"
|
||||
fld public final static java.lang.String SELECT_ALL_ON_FOCUS_POLICY_ONCE = "once"
|
||||
fld public final static java.lang.String SELECT_ALL_ON_MOUSE_CLICK = "JTextField.selectAllOnMouseClick"
|
||||
fld public final static java.lang.String SPLIT_PANE_EXPANDABLE_SIDE = "JSplitPane.expandableSide"
|
||||
fld public final static java.lang.String SPLIT_PANE_EXPANDABLE_SIDE_LEFT = "left"
|
||||
fld public final static java.lang.String SPLIT_PANE_EXPANDABLE_SIDE_RIGHT = "right"
|
||||
@@ -107,6 +109,7 @@ fld public final static java.lang.String TITLE_BAR_SHOW_ICONIFFY = "JRootPane.ti
|
||||
fld public final static java.lang.String TITLE_BAR_SHOW_MAXIMIZE = "JRootPane.titleBarShowMaximize"
|
||||
fld public final static java.lang.String TITLE_BAR_SHOW_TITLE = "JRootPane.titleBarShowTitle"
|
||||
fld public final static java.lang.String TREE_PAINT_SELECTION = "JTree.paintSelection"
|
||||
fld public final static java.lang.String TREE_WIDE_CELL_RENDERER = "JTree.wideCellRenderer"
|
||||
fld public final static java.lang.String TREE_WIDE_SELECTION = "JTree.wideSelection"
|
||||
fld public final static java.lang.String USE_WINDOW_DECORATIONS = "JRootPane.useWindowDecorations"
|
||||
fld public final static java.lang.String WINDOW_STYLE = "Window.style"
|
||||
@@ -220,8 +223,11 @@ meth public static java.lang.String getPreferredFontFamily()
|
||||
meth public static java.lang.String getPreferredLightFontFamily()
|
||||
meth public static java.lang.String getPreferredMonospacedFontFamily()
|
||||
meth public static java.lang.String getPreferredSemiboldFontFamily()
|
||||
meth public static java.lang.String getUIKeyLightOrDarkPrefix(boolean)
|
||||
meth public static java.util.Map<java.lang.String,java.lang.Class<?>> getStyleableInfos(javax.swing.JComponent)
|
||||
meth public static java.util.Map<java.lang.String,java.lang.String> getGlobalExtraDefaults()
|
||||
meth public static java.util.Set<java.lang.String> getUIKeyPlatformPrefixes()
|
||||
meth public static java.util.Set<java.lang.String> getUIKeySpecialPrefixes()
|
||||
meth public static java.util.function.Function<java.lang.String,java.awt.Color> getSystemColorGetter()
|
||||
meth public static javax.swing.UIDefaults$ActiveValue createActiveFontValue(float)
|
||||
meth public static void disableWindowsD3Donscreen()
|
||||
@@ -255,7 +261,7 @@ meth public void setExtraDefaults(java.util.Map<java.lang.String,java.lang.Strin
|
||||
meth public void uninitialize()
|
||||
meth public void unregisterUIDefaultsGetter(java.util.function.Function<java.lang.Object,java.lang.Object>)
|
||||
supr javax.swing.plaf.basic.BasicLookAndFeel
|
||||
hfds DESKTOPFONTHINTS,aquaLoaded,customDefaultsSources,desktopPropertyListener,desktopPropertyName,desktopPropertyName2,extraDefaults,globalExtraDefaults,mnemonicHandler,oldPopupFactory,postInitialization,preferredFontFamily,preferredLightFontFamily,preferredMonospacedFontFamily,preferredSemiboldFontFamily,subMenuUsabilityHelperInstalled,systemColorGetter,uiDefaultsGetters,updateUIPending
|
||||
hfds DESKTOPFONTHINTS,aquaLoaded,customDefaultsSources,desktopPropertyListener,desktopPropertyName,desktopPropertyName2,extraDefaults,globalExtraDefaults,linuxPopupMenuCanceler,mnemonicHandler,oldPopupFactory,postInitialization,preferredFontFamily,preferredLightFontFamily,preferredMonospacedFontFamily,preferredSemiboldFontFamily,subMenuUsabilityHelperInstalled,systemColorGetter,uiDefaultsGetters,uiKeyPlatformPrefixes,uiKeySpecialPrefixes,updateUIPending
|
||||
hcls ActiveFont,FlatUIDefaults,ImageIconUIResource
|
||||
|
||||
CLSS public abstract interface static com.formdev.flatlaf.FlatLaf$DisabledIconProvider
|
||||
@@ -318,7 +324,7 @@ meth public static boolean setup(java.io.InputStream)
|
||||
meth public static com.formdev.flatlaf.FlatLaf createLaf(com.formdev.flatlaf.IntelliJTheme)
|
||||
meth public static com.formdev.flatlaf.FlatLaf createLaf(java.io.InputStream) throws java.io.IOException
|
||||
supr java.lang.Object
|
||||
hfds checkboxDuplicateColors,checkboxKeyMapping,colors,icons,isMaterialUILite,namedColors,ui,uiKeyCopying,uiKeyDoNotOverride,uiKeyExcludes,uiKeyInverseMapping,uiKeyMapping
|
||||
hfds checkboxDuplicateColors,checkboxKeyMapping,jsonColors,jsonIcons,jsonUI,namedColors,uiKeyCopying,uiKeyDoNotOverride,uiKeyExcludes,uiKeyInverseMapping,uiKeyMapping
|
||||
|
||||
CLSS public static com.formdev.flatlaf.IntelliJTheme$ThemeLaf
|
||||
outer com.formdev.flatlaf.IntelliJTheme
|
||||
@@ -413,6 +419,7 @@ innr public static Fade
|
||||
innr public static HSLChange
|
||||
innr public static HSLIncreaseDecrease
|
||||
innr public static Mix
|
||||
innr public static Mix2
|
||||
meth public !varargs static java.awt.Color applyFunctions(java.awt.Color,com.formdev.flatlaf.util.ColorFunctions$ColorFunction[])
|
||||
meth public static float clamp(float)
|
||||
meth public static float luma(java.awt.Color)
|
||||
@@ -474,6 +481,16 @@ meth public java.lang.String toString()
|
||||
meth public void apply(float[])
|
||||
supr java.lang.Object
|
||||
|
||||
CLSS public static com.formdev.flatlaf.util.ColorFunctions$Mix2
|
||||
outer com.formdev.flatlaf.util.ColorFunctions
|
||||
cons public init(java.awt.Color,float)
|
||||
fld public final float weight
|
||||
fld public final java.awt.Color color1
|
||||
intf com.formdev.flatlaf.util.ColorFunctions$ColorFunction
|
||||
meth public java.lang.String toString()
|
||||
meth public void apply(float[])
|
||||
supr java.lang.Object
|
||||
|
||||
CLSS public com.formdev.flatlaf.util.CubicBezierEasing
|
||||
cons public init(float,float,float,float)
|
||||
fld public final static com.formdev.flatlaf.util.CubicBezierEasing EASE
|
||||
@@ -755,6 +772,7 @@ supr java.lang.Object
|
||||
CLSS public com.formdev.flatlaf.util.SystemInfo
|
||||
cons public init()
|
||||
fld public final static boolean isAARCH64
|
||||
fld public final static boolean isGNOME
|
||||
fld public final static boolean isJava_11_orLater
|
||||
fld public final static boolean isJava_12_orLater
|
||||
fld public final static boolean isJava_15_orLater
|
||||
@@ -771,6 +789,7 @@ fld public final static boolean isMacOS_10_11_ElCapitan_orLater
|
||||
fld public final static boolean isMacOS_10_14_Mojave_orLater
|
||||
fld public final static boolean isMacOS_10_15_Catalina_orLater
|
||||
fld public final static boolean isProjector
|
||||
fld public final static boolean isUnknownOS
|
||||
fld public final static boolean isWebswing
|
||||
fld public final static boolean isWinPE
|
||||
fld public final static boolean isWindows
|
||||
|
||||
@@ -21,6 +21,8 @@ import java.awt.IllegalComponentStateException;
|
||||
import java.awt.Window;
|
||||
import java.util.Objects;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JFormattedTextField;
|
||||
import javax.swing.JSpinner;
|
||||
import javax.swing.SwingConstants;
|
||||
|
||||
/**
|
||||
@@ -220,6 +222,7 @@ public interface FlatClientProperties
|
||||
* <strong>Allowed Values</strong>
|
||||
* {@link #OUTLINE_ERROR},
|
||||
* {@link #OUTLINE_WARNING},
|
||||
* {@link #OUTLINE_SUCCESS},
|
||||
* any color (type {@link java.awt.Color}) or
|
||||
* an array of two colors (type {@link java.awt.Color}[2]) where the first color
|
||||
* is for focused state and the second for unfocused state
|
||||
@@ -240,6 +243,14 @@ public interface FlatClientProperties
|
||||
*/
|
||||
String OUTLINE_WARNING = "warning";
|
||||
|
||||
/**
|
||||
* Paint the component border in another color (usually greenish) to indicate a success.
|
||||
*
|
||||
* @see #OUTLINE
|
||||
* @since 3.6
|
||||
*/
|
||||
String OUTLINE_SUCCESS = "success";
|
||||
|
||||
/**
|
||||
* Specifies a callback that is invoked to check whether a component is permanent focus owner.
|
||||
* Used to paint focus indicators.
|
||||
@@ -1200,12 +1211,15 @@ public interface FlatClientProperties
|
||||
/**
|
||||
* Specifies whether all text is selected when the text component gains focus.
|
||||
* <p>
|
||||
* <strong>Component</strong> {@link javax.swing.JTextField} (and subclasses)<br>
|
||||
* <strong>Components</strong> {@link javax.swing.text.JTextComponent} (and subclasses),
|
||||
* {@link javax.swing.JComboBox} (since 3.6) and {@link javax.swing.JSpinner} (since 3.6)<br>
|
||||
* <strong>Value type</strong> {@link java.lang.String}<br>
|
||||
* <strong>Allowed Values</strong>
|
||||
* {@link #SELECT_ALL_ON_FOCUS_POLICY_NEVER},
|
||||
* {@link #SELECT_ALL_ON_FOCUS_POLICY_ONCE} (default) or
|
||||
* {@link #SELECT_ALL_ON_FOCUS_POLICY_ALWAYS}
|
||||
*
|
||||
* @see #SELECT_ALL_ON_MOUSE_CLICK
|
||||
*/
|
||||
String SELECT_ALL_ON_FOCUS_POLICY = "JTextField.selectAllOnFocusPolicy";
|
||||
|
||||
@@ -1220,6 +1234,12 @@ public interface FlatClientProperties
|
||||
* Select all text when the text component gains focus for the first time
|
||||
* and selection was not modified (is at end of text).
|
||||
* This is the default.
|
||||
* <p>
|
||||
* <b>Limitations:</b>
|
||||
* For {@link JFormattedTextField} and {@link JSpinner} this behaves
|
||||
* as {@link #SELECT_ALL_ON_FOCUS_POLICY_ALWAYS}.
|
||||
* This is because of special behavior of {@link JFormattedTextField}
|
||||
* that did not allow implementation of {@code "once"}.
|
||||
*
|
||||
* @see #SELECT_ALL_ON_FOCUS_POLICY
|
||||
*/
|
||||
@@ -1232,6 +1252,19 @@ public interface FlatClientProperties
|
||||
*/
|
||||
String SELECT_ALL_ON_FOCUS_POLICY_ALWAYS = "always";
|
||||
|
||||
/**
|
||||
* Specifies whether all text is selected when when clicking with the mouse
|
||||
* into the text field (and if "select all on focus" policy is enabled).
|
||||
* <p>
|
||||
* <strong>Components</strong> {@link javax.swing.text.JTextComponent} (and subclasses),
|
||||
* {@link javax.swing.JComboBox} and {@link javax.swing.JSpinner}<br>
|
||||
* <strong>Value type</strong> {@link java.lang.Boolean}
|
||||
*
|
||||
* @see #SELECT_ALL_ON_FOCUS_POLICY
|
||||
* @since 3.6
|
||||
*/
|
||||
String SELECT_ALL_ON_MOUSE_CLICK = "JTextField.selectAllOnMouseClick";
|
||||
|
||||
/**
|
||||
* Placeholder text that is only painted if the text field is empty.
|
||||
* <p>
|
||||
@@ -1410,13 +1443,23 @@ public interface FlatClientProperties
|
||||
//---- JTree --------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Override if a tree shows a wide selection. Default is {@code true}.
|
||||
* Specifies whether tree shows a wide selection. Default is {@code true}.
|
||||
* <p>
|
||||
* <strong>Component</strong> {@link javax.swing.JTree}<br>
|
||||
* <strong>Value type</strong> {@link java.lang.Boolean}
|
||||
*/
|
||||
String TREE_WIDE_SELECTION = "JTree.wideSelection";
|
||||
|
||||
/**
|
||||
* Specifies whether tree uses a wide cell renderer. Default is {@code false}.
|
||||
* <p>
|
||||
* <strong>Component</strong> {@link javax.swing.JTree}<br>
|
||||
* <strong>Value type</strong> {@link java.lang.Boolean}
|
||||
*
|
||||
* @since 3.6
|
||||
*/
|
||||
String TREE_WIDE_CELL_RENDERER = "JTree.wideCellRenderer";
|
||||
|
||||
/**
|
||||
* Specifies whether tree item selection is painted. Default is {@code true}.
|
||||
* If set to {@code false}, then the tree cell renderer is responsible for painting selection.
|
||||
|
||||
@@ -37,6 +37,7 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
@@ -44,6 +45,7 @@ import java.util.MissingResourceException;
|
||||
import java.util.Properties;
|
||||
import java.util.ResourceBundle;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.IntUnaryOperator;
|
||||
@@ -100,6 +102,8 @@ public abstract class FlatLaf
|
||||
private static Map<String, String> globalExtraDefaults;
|
||||
private Map<String, String> extraDefaults;
|
||||
private static Function<String, Color> systemColorGetter;
|
||||
private static Set<String> uiKeyPlatformPrefixes;
|
||||
private static Set<String> uiKeySpecialPrefixes;
|
||||
|
||||
private String desktopPropertyName;
|
||||
private String desktopPropertyName2;
|
||||
@@ -111,6 +115,7 @@ public abstract class FlatLaf
|
||||
private PopupFactory oldPopupFactory;
|
||||
private MnemonicHandler mnemonicHandler;
|
||||
private boolean subMenuUsabilityHelperInstalled;
|
||||
private LinuxPopupMenuCanceler linuxPopupMenuCanceler;
|
||||
|
||||
private Consumer<UIDefaults> postInitialization;
|
||||
private List<Function<Object, Object>> uiDefaultsGetters;
|
||||
@@ -305,6 +310,10 @@ public abstract class FlatLaf
|
||||
// install submenu usability helper
|
||||
subMenuUsabilityHelperInstalled = SubMenuUsabilityHelper.install();
|
||||
|
||||
// install Linux popup menu canceler
|
||||
if( SystemInfo.isLinux )
|
||||
linuxPopupMenuCanceler = new LinuxPopupMenuCanceler();
|
||||
|
||||
// listen to desktop property changes to update UI if system font or scaling changes
|
||||
if( SystemInfo.isWindows ) {
|
||||
// Windows 10 allows increasing font size independent of scaling:
|
||||
@@ -397,6 +406,12 @@ public abstract class FlatLaf
|
||||
subMenuUsabilityHelperInstalled = false;
|
||||
}
|
||||
|
||||
// uninstall Linux popup menu canceler
|
||||
if( linuxPopupMenuCanceler != null ) {
|
||||
linuxPopupMenuCanceler.uninstall();
|
||||
linuxPopupMenuCanceler = null;
|
||||
}
|
||||
|
||||
// restore default link color
|
||||
new HTMLEditorKit().getStyleSheet().addRule( "a, address { color: blue; }" );
|
||||
postInitialization = null;
|
||||
@@ -510,10 +525,10 @@ public abstract class FlatLaf
|
||||
|
||||
// load defaults from properties
|
||||
List<Class<?>> lafClassesForDefaultsLoading = getLafClassesForDefaultsLoading();
|
||||
if( lafClassesForDefaultsLoading != null )
|
||||
UIDefaultsLoader.loadDefaultsFromProperties( lafClassesForDefaultsLoading, addons, getAdditionalDefaults(), isDark(), defaults );
|
||||
else
|
||||
UIDefaultsLoader.loadDefaultsFromProperties( getClass(), addons, getAdditionalDefaults(), isDark(), defaults );
|
||||
if( lafClassesForDefaultsLoading == null )
|
||||
lafClassesForDefaultsLoading = UIDefaultsLoader.getLafClassesForDefaultsLoading( getClass() );
|
||||
UIDefaultsLoader.loadDefaultsFromProperties( lafClassesForDefaultsLoading, addons,
|
||||
this::applyAdditionalProperties, getAdditionalDefaults(), isDark(), defaults );
|
||||
|
||||
// setup default font after loading defaults from properties
|
||||
// to allow defining "defaultFont" in properties
|
||||
@@ -530,9 +545,6 @@ public abstract class FlatLaf
|
||||
// initialize text antialiasing
|
||||
putAATextInfo( defaults );
|
||||
|
||||
// apply additional defaults (e.g. from IntelliJ themes)
|
||||
applyAdditionalDefaults( defaults );
|
||||
|
||||
// allow addons modifying UI defaults
|
||||
for( FlatDefaultsAddon addon : addons )
|
||||
addon.afterDefaultsLoading( this, defaults );
|
||||
@@ -542,6 +554,9 @@ public abstract class FlatLaf
|
||||
return UIScale.getUserScaleFactor();
|
||||
} );
|
||||
|
||||
// add lazy UI delegate class loading (if necessary)
|
||||
addLazyUIdelegateClassLoading( defaults );
|
||||
|
||||
if( postInitialization != null ) {
|
||||
postInitialization.accept( defaults );
|
||||
postInitialization = null;
|
||||
@@ -550,7 +565,8 @@ public abstract class FlatLaf
|
||||
return defaults;
|
||||
}
|
||||
|
||||
void applyAdditionalDefaults( UIDefaults defaults ) {
|
||||
// apply additional properties (e.g. from IntelliJ themes)
|
||||
void applyAdditionalProperties( Properties properties ) {
|
||||
}
|
||||
|
||||
protected List<Class<?>> getLafClassesForDefaultsLoading() {
|
||||
@@ -739,6 +755,53 @@ public abstract class FlatLaf
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle UI delegate classes if running in special application where multiple class loaders are involved.
|
||||
* E.g. in Eclipse plugin or in LibreOffice extension.
|
||||
* <p>
|
||||
* Problem: Swing runs in Java's system classloader and FlatLaf is loaded in plugin classloader.
|
||||
* When Swing tries to load UI delegate class in {@link UIDefaults#getUIClass(String, ClassLoader)},
|
||||
* invoked from {@link UIDefaults#getUI(JComponent)}, it uses the component's classloader,
|
||||
* which is Java's system classloader for core Swing components,
|
||||
* and can not find FlatLaf UI delegates.
|
||||
* <p>
|
||||
* Solution: Add lazy values for UI delegate class names.
|
||||
* Those lazy values use FlatLaf classloader to load UI delegate class.
|
||||
* This is similar to what {@link UIDefaults#getUIClass(String, ClassLoader)} does.
|
||||
* <p>
|
||||
* Not using {@code defaults.put( "ClassLoader", FlatLaf.class.getClassLoader() )},
|
||||
* which would work for FlatLaf UI delegates, but it would break custom
|
||||
* UI delegates used in other classloaders.
|
||||
*/
|
||||
private static void addLazyUIdelegateClassLoading( UIDefaults defaults ) {
|
||||
if( FlatLaf.class.getClassLoader() == ClassLoader.getSystemClassLoader() )
|
||||
return; // not necessary
|
||||
|
||||
Map<String, LazyValue> map = new HashMap<>();
|
||||
for( Map.Entry<Object, Object> e : defaults.entrySet() ) {
|
||||
Object key = e.getKey();
|
||||
Object value = e.getValue();
|
||||
if( key instanceof String && ((String)key).endsWith( "UI" ) &&
|
||||
value instanceof String && !defaults.containsKey( value ) )
|
||||
{
|
||||
String className = (String) value;
|
||||
map.put( className, (LazyValue) t -> {
|
||||
try {
|
||||
Class<?> uiClass = FlatLaf.class.getClassLoader().loadClass( className );
|
||||
if( ComponentUI.class.isAssignableFrom( uiClass ) )
|
||||
return uiClass;
|
||||
} catch( ClassNotFoundException ex ) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
// let UIDefaults.getUIClass() try to load UI delegate class
|
||||
return null;
|
||||
} );
|
||||
}
|
||||
}
|
||||
defaults.putAll( map );
|
||||
}
|
||||
|
||||
private void putAATextInfo( UIDefaults defaults ) {
|
||||
if ( SystemInfo.isMacOS && SystemInfo.isJetBrainsJVM ) {
|
||||
// The awt.font.desktophints property suggests sub-pixel anti-aliasing
|
||||
@@ -1063,6 +1126,92 @@ public abstract class FlatLaf
|
||||
FlatLaf.systemColorGetter = systemColorGetter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns UI key prefix, used in FlatLaf properties files, for light or dark themes.
|
||||
* Return value is either {@code [light]} or {@code [dark]}.
|
||||
*
|
||||
* @since 3.6
|
||||
*/
|
||||
public static String getUIKeyLightOrDarkPrefix( boolean dark ) {
|
||||
return dark ? "[dark]" : "[light]";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns set of UI key prefixes, used in FlatLaf properties files, for current platform.
|
||||
* If UI keys in properties files start with a prefix (e.g. {@code [someprefix]Button.background}),
|
||||
* then they are only used if that prefix is contained in this set
|
||||
* (or is one of {@code [light]} or {@code [dark]} depending on current theme).
|
||||
* <p>
|
||||
* By default, the set contains one or more of following prefixes:
|
||||
* <ul>
|
||||
* <li>{@code [win]} on Windows
|
||||
* <li>{@code [mac]} on macOS
|
||||
* <li>{@code [linux]} on Linux
|
||||
* <li>{@code [unknown]} on other platforms
|
||||
* <li>{@code [gnome]} on Linux with GNOME desktop environment
|
||||
* <li>{@code [kde]} on Linux with KDE desktop environment
|
||||
* <li>on Linux, the value of the environment variable {@code XDG_CURRENT_DESKTOP},
|
||||
* split at colons and converted to lower case (e.g. if value of {@code XDG_CURRENT_DESKTOP}
|
||||
* is {@code ubuntu:GNOME}, then {@code [ubuntu]} and {@code [gnome]})
|
||||
* </ul>
|
||||
* <p>
|
||||
* You can add own prefixes to the set.
|
||||
* The prefixes must start with '[' and end with ']' characters, otherwise they will be ignored.
|
||||
*
|
||||
* @since 3.6
|
||||
*/
|
||||
public static Set<String> getUIKeyPlatformPrefixes() {
|
||||
if( uiKeyPlatformPrefixes == null ) {
|
||||
uiKeyPlatformPrefixes = new HashSet<>();
|
||||
uiKeyPlatformPrefixes.add(
|
||||
SystemInfo.isWindows ? "[win]" :
|
||||
SystemInfo.isMacOS ? "[mac]" :
|
||||
SystemInfo.isLinux ? "[linux]" : "[unknown]" );
|
||||
|
||||
// Linux
|
||||
if( SystemInfo.isLinux ) {
|
||||
if( SystemInfo.isGNOME )
|
||||
uiKeyPlatformPrefixes.add( "[gnome]" );
|
||||
else if( SystemInfo.isKDE )
|
||||
uiKeyPlatformPrefixes.add( "[kde]" );
|
||||
|
||||
// add values from XDG_CURRENT_DESKTOP for other desktops
|
||||
String desktop = System.getenv( "XDG_CURRENT_DESKTOP" );
|
||||
if( desktop != null ) {
|
||||
// XDG_CURRENT_DESKTOP is a colon-separated list of strings
|
||||
// https://specifications.freedesktop.org/desktop-entry-spec/latest/recognized-keys.html#key-onlyshowin
|
||||
// e.g. "ubuntu:GNOME" on Ubuntu 24.10 or "GNOME-Classic:GNOME" on CentOS 7
|
||||
for( String desk : StringUtils.split( desktop.toLowerCase( Locale.ENGLISH ), ':', true, true ) )
|
||||
uiKeyPlatformPrefixes.add( '[' + desk + ']' );
|
||||
}
|
||||
}
|
||||
}
|
||||
return uiKeyPlatformPrefixes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns set of special UI key prefixes, used in FlatLaf properties files.
|
||||
* Unlike other prefixes, properties with special prefixes are preserved.
|
||||
* You can access them using `UIManager`. E.g. `UIManager.get( "[someSpecialPrefix]someKey" )`.
|
||||
* <p>
|
||||
* By default, the set contains following special prefixes:
|
||||
* <ul>
|
||||
* <li>{@code [style]}
|
||||
* </ul>
|
||||
* <p>
|
||||
* You can add own prefixes to the set.
|
||||
* The prefixes must start with '[' and end with ']' characters, otherwise they will be ignored.
|
||||
*
|
||||
* @since 3.6
|
||||
*/
|
||||
public static Set<String> getUIKeySpecialPrefixes() {
|
||||
if( uiKeySpecialPrefixes == null ) {
|
||||
uiKeySpecialPrefixes = new HashSet<>();
|
||||
uiKeySpecialPrefixes.add( "[style]" );
|
||||
}
|
||||
return uiKeySpecialPrefixes;
|
||||
}
|
||||
|
||||
private static void reSetLookAndFeel() {
|
||||
EventQueue.invokeLater( () -> {
|
||||
LookAndFeel lookAndFeel = UIManager.getLookAndFeel();
|
||||
|
||||
@@ -23,13 +23,15 @@ import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Locale;
|
||||
import java.util.Properties;
|
||||
import com.formdev.flatlaf.themes.FlatMacDarkLaf;
|
||||
import com.formdev.flatlaf.themes.FlatMacLightLaf;
|
||||
|
||||
/**
|
||||
* A Flat LaF that is able to load UI defaults from properties passed to the constructor.
|
||||
* <p>
|
||||
* Specify the base theme in the properties with {@code @baseTheme=<baseTheme>}.
|
||||
* Allowed values for {@code <baseTheme>} are {@code light} (the default), {@code dark},
|
||||
* {@code intellij} or {@code darcula}.
|
||||
* {@code intellij}, {@code darcula}, {@code maclight} or {@code macdark}.
|
||||
* <p>
|
||||
* The properties are applied after loading the base theme and may overwrite base properties.
|
||||
* All features of FlatLaf properties files are available.
|
||||
@@ -71,7 +73,8 @@ public class FlatPropertiesLaf
|
||||
this.properties = properties;
|
||||
|
||||
baseTheme = properties.getProperty( "@baseTheme", "light" );
|
||||
dark = "dark".equalsIgnoreCase( baseTheme ) || "darcula".equalsIgnoreCase( baseTheme );
|
||||
dark = "dark".equalsIgnoreCase( baseTheme ) || "darcula".equalsIgnoreCase( baseTheme ) ||
|
||||
"macdark".equalsIgnoreCase( baseTheme );
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -116,6 +119,16 @@ public class FlatPropertiesLaf
|
||||
lafClasses.add( FlatDarkLaf.class );
|
||||
lafClasses.add( FlatDarculaLaf.class );
|
||||
break;
|
||||
|
||||
case "maclight":
|
||||
lafClasses.add( FlatLightLaf.class );
|
||||
lafClasses.add( FlatMacLightLaf.class );
|
||||
break;
|
||||
|
||||
case "macdark":
|
||||
lafClasses.add( FlatDarkLaf.class );
|
||||
lafClasses.add( FlatMacDarkLaf.class );
|
||||
break;
|
||||
}
|
||||
return lafClasses;
|
||||
}
|
||||
|
||||
@@ -138,10 +138,10 @@ public interface FlatSystemProperties
|
||||
/**
|
||||
* Specifies whether native rounded popup borders should be used (if supported by operating system).
|
||||
* <p>
|
||||
* (requires Window 11 or macOS)
|
||||
* (requires Windows 11 or macOS)
|
||||
* <p>
|
||||
* <strong>Allowed Values</strong> {@code false} and {@code true}<br>
|
||||
* <strong>Default</strong> {@code true}; except on macOS 14.4+ where it is {@code false}
|
||||
* <strong>Default</strong> {@code true}; except in FlatLaf 3.5.x on macOS 14.4+ where it was {@code false}
|
||||
*
|
||||
* @since 3.5.2
|
||||
*/
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package com.formdev.flatlaf;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
@@ -25,20 +24,16 @@ import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.Map.Entry;
|
||||
import javax.swing.UIDefaults;
|
||||
import javax.swing.plaf.ColorUIResource;
|
||||
import com.formdev.flatlaf.json.Json;
|
||||
import com.formdev.flatlaf.json.ParseException;
|
||||
import com.formdev.flatlaf.util.ColorFunctions;
|
||||
import com.formdev.flatlaf.util.LoggingFacade;
|
||||
import com.formdev.flatlaf.util.StringUtils;
|
||||
import com.formdev.flatlaf.util.SystemInfo;
|
||||
@@ -63,13 +58,11 @@ public class IntelliJTheme
|
||||
public final boolean dark;
|
||||
public final String author;
|
||||
|
||||
private final boolean isMaterialUILite;
|
||||
private Map<String, String> jsonColors;
|
||||
private Map<String, Object> jsonUI;
|
||||
private Map<String, Object> jsonIcons;
|
||||
|
||||
private Map<String, String> colors;
|
||||
private Map<String, Object> ui;
|
||||
private Map<String, Object> icons;
|
||||
|
||||
private Map<String, ColorUIResource> namedColors = Collections.emptyMap();
|
||||
private Map<String, String> namedColors = Collections.emptyMap();
|
||||
|
||||
/**
|
||||
* Loads a IntelliJ .theme.json file from the given input stream,
|
||||
@@ -84,7 +77,7 @@ public class IntelliJTheme
|
||||
try {
|
||||
return FlatLaf.setup( createLaf( in ) );
|
||||
} catch( Exception ex ) {
|
||||
LoggingFacade.INSTANCE.logSevere( "FlatLaf: Failed to load IntelliJ theme", ex );
|
||||
LoggingFacade.INSTANCE.logSevere( "FlatLaf: Failed to load IntelliJ theme", ex );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -138,94 +131,90 @@ public class IntelliJTheme
|
||||
dark = Boolean.parseBoolean( (String) json.get( "dark" ) );
|
||||
author = (String) json.get( "author" );
|
||||
|
||||
isMaterialUILite = author.equals( "Mallowigi" );
|
||||
|
||||
colors = (Map<String, String>) json.get( "colors" );
|
||||
ui = (Map<String, Object>) json.get( "ui" );
|
||||
icons = (Map<String, Object>) json.get( "icons" );
|
||||
jsonColors = (Map<String, String>) json.get( "colors" );
|
||||
jsonUI = (Map<String, Object>) json.get( "ui" );
|
||||
jsonIcons = (Map<String, Object>) json.get( "icons" );
|
||||
}
|
||||
|
||||
private void applyProperties( UIDefaults defaults ) {
|
||||
if( ui == null )
|
||||
private void applyProperties( Properties properties ) {
|
||||
if( jsonUI == null )
|
||||
return;
|
||||
|
||||
defaults.put( "Component.isIntelliJTheme", true );
|
||||
put( properties, "Component.isIntelliJTheme", "true" );
|
||||
|
||||
// enable button shadows
|
||||
defaults.put( "Button.paintShadow", true );
|
||||
defaults.put( "Button.shadowWidth", dark ? 2 : 1 );
|
||||
put( properties, "Button.paintShadow", "true" );
|
||||
put( properties, "Button.shadowWidth", dark ? "2" : "1" );
|
||||
|
||||
Map<Object, Object> themeSpecificDefaults = removeThemeSpecificDefaults( defaults );
|
||||
Map<String, String> themeSpecificProps = removeThemeSpecificProps( properties );
|
||||
Set<String> jsonUIKeys = new HashSet<>();
|
||||
|
||||
loadNamedColors( defaults );
|
||||
// Json node "colors"
|
||||
loadNamedColors( properties, jsonUIKeys );
|
||||
|
||||
// convert Json "ui" structure to UI defaults
|
||||
ArrayList<Object> defaultsKeysCache = new ArrayList<>();
|
||||
Set<String> uiKeys = new HashSet<>();
|
||||
for( Map.Entry<String, Object> e : ui.entrySet() )
|
||||
apply( e.getKey(), e.getValue(), defaults, defaultsKeysCache, uiKeys );
|
||||
// convert Json "ui" structure to UI properties
|
||||
for( Map.Entry<String, Object> e : jsonUI.entrySet() )
|
||||
apply( e.getKey(), e.getValue(), properties, jsonUIKeys );
|
||||
|
||||
applyColorPalette( defaults );
|
||||
applyCheckBoxColors( defaults );
|
||||
// set FlatLaf variables
|
||||
copyIfSetInJson( properties, jsonUIKeys, "@background", "Panel.background", "*.background" );
|
||||
copyIfSetInJson( properties, jsonUIKeys, "@foreground", "CheckBox.foreground", "*.foreground" );
|
||||
copyIfSetInJson( properties, jsonUIKeys, "@accentBaseColor",
|
||||
"ColorPalette.accent", // Material UI Lite, Hiberbee
|
||||
"ColorPalette.accentColor", // Dracula, One Dark
|
||||
"ProgressBar.foreground",
|
||||
"*.selectionBackground" );
|
||||
copyIfSetInJson( properties, jsonUIKeys, "@accentUnderlineColor", "*.underlineColor", "TabbedPane.underlineColor" );
|
||||
copyIfSetInJson( properties, jsonUIKeys, "@selectionBackground", "*.selectionBackground" );
|
||||
copyIfSetInJson( properties, jsonUIKeys, "@selectionForeground", "*.selectionForeground" );
|
||||
copyIfSetInJson( properties, jsonUIKeys, "@selectionInactiveBackground", "*.selectionInactiveBackground" );
|
||||
copyIfSetInJson( properties, jsonUIKeys, "@selectionInactiveForeground", "*.selectionInactiveForeground" );
|
||||
|
||||
// Json node "icons/ColorPalette"
|
||||
applyIconsColorPalette( properties );
|
||||
|
||||
// apply "CheckBox.icon." colors
|
||||
applyCheckBoxColors( properties );
|
||||
|
||||
// copy values
|
||||
for( Map.Entry<String, String> e : uiKeyCopying.entrySet() ) {
|
||||
Object value = defaults.get( e.getValue() );
|
||||
Object value = properties.get( e.getValue() );
|
||||
if( value != null )
|
||||
defaults.put( e.getKey(), value );
|
||||
put( properties, e.getKey(), value );
|
||||
}
|
||||
|
||||
// IDEA does not paint button background if disabled, but FlatLaf does
|
||||
Object panelBackground = defaults.get( "Panel.background" );
|
||||
defaults.put( "Button.disabledBackground", panelBackground );
|
||||
defaults.put( "ToggleButton.disabledBackground", panelBackground );
|
||||
put( properties, "Button.disabledBackground", "@disabledBackground" );
|
||||
put( properties, "ToggleButton.disabledBackground", "@disabledBackground" );
|
||||
|
||||
// fix Button borders
|
||||
copyIfNotSet( defaults, "Button.focusedBorderColor", "Component.focusedBorderColor", uiKeys );
|
||||
defaults.put( "Button.hoverBorderColor", defaults.get( "Button.focusedBorderColor" ) );
|
||||
defaults.put( "HelpButton.hoverBorderColor", defaults.get( "Button.focusedBorderColor" ) );
|
||||
|
||||
// IDEA uses an SVG icon for the help button, but paints the background with Button.startBackground and Button.endBackground
|
||||
Object helpButtonBackground = defaults.get( "Button.startBackground" );
|
||||
Object helpButtonBorderColor = defaults.get( "Button.startBorderColor" );
|
||||
if( helpButtonBackground == null )
|
||||
helpButtonBackground = defaults.get( "Button.background" );
|
||||
if( helpButtonBorderColor == null )
|
||||
helpButtonBorderColor = defaults.get( "Button.borderColor" );
|
||||
defaults.put( "HelpButton.background", helpButtonBackground );
|
||||
defaults.put( "HelpButton.borderColor", helpButtonBorderColor );
|
||||
defaults.put( "HelpButton.disabledBackground", panelBackground );
|
||||
defaults.put( "HelpButton.disabledBorderColor", defaults.get( "Button.disabledBorderColor" ) );
|
||||
defaults.put( "HelpButton.focusedBorderColor", defaults.get( "Button.focusedBorderColor" ) );
|
||||
defaults.put( "HelpButton.focusedBackground", defaults.get( "Button.focusedBackground" ) );
|
||||
// fix Button
|
||||
fixStartEnd( properties, jsonUIKeys, "Button.startBackground", "Button.endBackground", "Button.background" );
|
||||
fixStartEnd( properties, jsonUIKeys, "Button.startBorderColor", "Button.endBorderColor", "Button.borderColor" );
|
||||
fixStartEnd( properties, jsonUIKeys, "Button.default.startBackground", "Button.default.endBackground", "Button.default.background" );
|
||||
fixStartEnd( properties, jsonUIKeys, "Button.default.startBorderColor", "Button.default.endBorderColor", "Button.default.borderColor" );
|
||||
|
||||
// IDEA uses TextField.background for editable ComboBox and Spinner
|
||||
Object textFieldBackground = get( defaults, themeSpecificDefaults, "TextField.background" );
|
||||
defaults.put( "ComboBox.editableBackground", textFieldBackground );
|
||||
defaults.put( "Spinner.background", textFieldBackground );
|
||||
|
||||
// Spinner arrow button always has same colors as ComboBox arrow button
|
||||
defaults.put( "Spinner.buttonBackground", defaults.get( "ComboBox.buttonEditableBackground" ) );
|
||||
defaults.put( "Spinner.buttonArrowColor", defaults.get( "ComboBox.buttonArrowColor" ) );
|
||||
defaults.put( "Spinner.buttonDisabledArrowColor", defaults.get( "ComboBox.buttonDisabledArrowColor" ) );
|
||||
Object textFieldBackground = get( properties, themeSpecificProps, "TextField.background" );
|
||||
put( properties, "ComboBox.editableBackground", textFieldBackground );
|
||||
put( properties, "Spinner.background", textFieldBackground );
|
||||
|
||||
// some themes specify colors for TextField.background, but forget to specify it for other components
|
||||
// (probably because those components are not used in IntelliJ IDEA)
|
||||
putAll( defaults, textFieldBackground,
|
||||
putAll( properties, textFieldBackground,
|
||||
"EditorPane.background",
|
||||
"FormattedTextField.background",
|
||||
"PasswordField.background",
|
||||
"TextArea.background",
|
||||
"TextPane.background"
|
||||
);
|
||||
putAll( defaults, get( defaults, themeSpecificDefaults, "TextField.selectionBackground" ),
|
||||
putAll( properties, get( properties, themeSpecificProps, "TextField.selectionBackground" ),
|
||||
"EditorPane.selectionBackground",
|
||||
"FormattedTextField.selectionBackground",
|
||||
"PasswordField.selectionBackground",
|
||||
"TextArea.selectionBackground",
|
||||
"TextPane.selectionBackground"
|
||||
);
|
||||
putAll( defaults, get( defaults, themeSpecificDefaults, "TextField.selectionForeground" ),
|
||||
putAll( properties, get( properties, themeSpecificProps, "TextField.selectionForeground" ),
|
||||
"EditorPane.selectionForeground",
|
||||
"FormattedTextField.selectionForeground",
|
||||
"PasswordField.selectionForeground",
|
||||
@@ -235,7 +224,7 @@ public class IntelliJTheme
|
||||
|
||||
// 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,
|
||||
putAll( properties, "@disabledBackground",
|
||||
"ComboBox.disabledBackground",
|
||||
"EditorPane.disabledBackground", "EditorPane.inactiveBackground",
|
||||
"FormattedTextField.disabledBackground", "FormattedTextField.inactiveBackground",
|
||||
@@ -246,132 +235,148 @@ public class IntelliJTheme
|
||||
"TextPane.disabledBackground", "TextPane.inactiveBackground"
|
||||
);
|
||||
|
||||
// fix ToggleButton
|
||||
if( !uiKeys.contains( "ToggleButton.startBackground" ) && !uiKeys.contains( "*.startBackground" ) )
|
||||
defaults.put( "ToggleButton.startBackground", defaults.get( "Button.startBackground" ) );
|
||||
if( !uiKeys.contains( "ToggleButton.endBackground" ) && !uiKeys.contains( "*.endBackground" ) )
|
||||
defaults.put( "ToggleButton.endBackground", defaults.get( "Button.endBackground" ) );
|
||||
if( !uiKeys.contains( "ToggleButton.foreground" ) && uiKeys.contains( "Button.foreground" ) )
|
||||
defaults.put( "ToggleButton.foreground", defaults.get( "Button.foreground" ) );
|
||||
|
||||
// fix DesktopPane background (use Panel.background and make it 5% darker/lighter)
|
||||
Color desktopBackgroundBase = defaults.getColor( "Panel.background" );
|
||||
Color desktopBackground = ColorFunctions.applyFunctions( desktopBackgroundBase,
|
||||
new ColorFunctions.HSLIncreaseDecrease( 2, dark, 5, false, true ) );
|
||||
defaults.put( "Desktop.background", new ColorUIResource( desktopBackground ) );
|
||||
|
||||
// fix List and Table background colors in Material UI Lite themes
|
||||
if( isMaterialUILite ) {
|
||||
defaults.put( "List.background", defaults.get( "Tree.background" ) );
|
||||
defaults.put( "Table.background", defaults.get( "Tree.background" ) );
|
||||
}
|
||||
put( properties, "Desktop.background", dark ? "lighten($Panel.background,5%)" : "darken($Panel.background,5%)" );
|
||||
|
||||
// limit tree row height
|
||||
int rowHeight = defaults.getInt( "Tree.rowHeight" );
|
||||
String rowHeightStr = (String) properties.get( "Tree.rowHeight" );
|
||||
int rowHeight = (rowHeightStr != null) ? Integer.parseInt( rowHeightStr ) : 0;
|
||||
if( rowHeight > 22 )
|
||||
defaults.put( "Tree.rowHeight", 22 );
|
||||
put( properties, "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();
|
||||
// get (and remove) theme specific wildcard replacements, which override all other properties that end with same suffix
|
||||
HashMap<String, String> wildcardProps = new HashMap<>();
|
||||
Iterator<Map.Entry<String, String>> it = themeSpecificProps.entrySet().iterator();
|
||||
while( it.hasNext() ) {
|
||||
Entry<Object, Object> e = it.next();
|
||||
String key = (String) e.getKey();
|
||||
Map.Entry<String, String> e = it.next();
|
||||
String key = e.getKey();
|
||||
if( key.startsWith( "*." ) ) {
|
||||
wildcards.put( key.substring( "*.".length() ), e.getValue() );
|
||||
wildcardProps.put( key, 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 );
|
||||
}
|
||||
// override properties with theme specific wildcard replacements
|
||||
if( !wildcardProps.isEmpty() ) {
|
||||
for( Map.Entry<String, String> e : wildcardProps.entrySet() )
|
||||
applyWildcard( properties, e.getKey(), e.getValue() );
|
||||
}
|
||||
|
||||
// apply theme specific UI defaults at the end to allow overwriting
|
||||
for( Map.Entry<Object, Object> e : themeSpecificDefaults.entrySet() ) {
|
||||
Object key = e.getKey();
|
||||
Object value = e.getValue();
|
||||
// apply theme specific properties at the end to allow overwriting
|
||||
for( Map.Entry<String, String> e : themeSpecificProps.entrySet() ) {
|
||||
String key = e.getKey();
|
||||
String value = e.getValue();
|
||||
|
||||
// append styles to existing styles
|
||||
if( key instanceof String && ((String)key).startsWith( "[style]" ) ) {
|
||||
Object oldValue = defaults.get( key );
|
||||
if( key.startsWith( "[style]" ) ) {
|
||||
String oldValue = (String) properties.get( key );
|
||||
if( oldValue != null )
|
||||
value = oldValue + "; " + value;
|
||||
}
|
||||
|
||||
defaults.put( key, value );
|
||||
put( properties, key, value );
|
||||
}
|
||||
|
||||
// let Java release memory
|
||||
colors = null;
|
||||
ui = null;
|
||||
icons = null;
|
||||
jsonColors = null;
|
||||
jsonUI = null;
|
||||
jsonIcons = null;
|
||||
}
|
||||
|
||||
private Object get( UIDefaults defaults, Map<Object, Object> themeSpecificDefaults, String key ) {
|
||||
return themeSpecificDefaults.getOrDefault( key, defaults.get( key ) );
|
||||
private String get( Properties properties, Map<String, String> themeSpecificProps, String key ) {
|
||||
return themeSpecificProps.getOrDefault( key, (String) properties.get( key ) );
|
||||
}
|
||||
|
||||
private void putAll( UIDefaults defaults, Object value, String... keys ) {
|
||||
private void put( Properties properties, Object key, Object value ) {
|
||||
if( value != null )
|
||||
properties.put( key, value );
|
||||
else
|
||||
properties.remove( key );
|
||||
}
|
||||
|
||||
private void putAll( Properties properties, Object value, String... keys ) {
|
||||
for( String key : keys )
|
||||
defaults.put( key, value );
|
||||
put( properties, key, value );
|
||||
}
|
||||
|
||||
private Map<Object, Object> removeThemeSpecificDefaults( UIDefaults defaults ) {
|
||||
// search for theme specific UI defaults keys
|
||||
private void copyIfSetInJson( Properties properties, Set<String> jsonUIKeys, String destKey, String... srcKeys ) {
|
||||
for( String srcKey : srcKeys ) {
|
||||
if( jsonUIKeys.contains( srcKey ) ) {
|
||||
Object value = properties.get( srcKey );
|
||||
if( value != null ) {
|
||||
put( properties, destKey, value );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void fixStartEnd( Properties properties, Set<String> jsonUIKeys, String startKey, String endKey, String key ) {
|
||||
if( jsonUIKeys.contains( startKey ) && jsonUIKeys.contains( endKey ) )
|
||||
put( properties, key, "$" + startKey );
|
||||
}
|
||||
|
||||
private Map<String, String> removeThemeSpecificProps( Properties properties ) {
|
||||
// search for theme specific properties keys
|
||||
ArrayList<String> themeSpecificKeys = new ArrayList<>();
|
||||
for( Object key : defaults.keySet() ) {
|
||||
if( key instanceof String && ((String)key).startsWith( "[" ) && !((String)key).startsWith( "[style]" ) )
|
||||
for( Object key : properties.keySet() ) {
|
||||
if( ((String)key).startsWith( "{" ) )
|
||||
themeSpecificKeys.add( (String) key );
|
||||
}
|
||||
|
||||
// remove theme specific UI defaults and remember only those for current theme
|
||||
Map<Object, Object> themeSpecificDefaults = new HashMap<>();
|
||||
String currentThemePrefix = '[' + name.replace( ' ', '_' ) + ']';
|
||||
String currentThemeAndAuthorPrefix = '[' + name.replace( ' ', '_' ) + "---" + author.replace( ' ', '_' ) + ']';
|
||||
String currentAuthorPrefix = "[author-" + author.replace( ' ', '_' ) + ']';
|
||||
String allThemesPrefix = "[*]";
|
||||
String[] prefixes = { currentThemePrefix, currentThemeAndAuthorPrefix, currentAuthorPrefix, allThemesPrefix };
|
||||
// special prefixes (priority from highest to lowest)
|
||||
String currentThemePrefix = '{' + name.replace( ' ', '_' ) + '}';
|
||||
String currentThemeAndAuthorPrefix = '{' + name.replace( ' ', '_' ) + "---" + author.replace( ' ', '_' ) + '}';
|
||||
String currentAuthorPrefix = "{author-" + author.replace( ' ', '_' ) + '}';
|
||||
String lightOrDarkPrefix = dark ? "{*-dark}" : "{*-light}";
|
||||
String allThemesPrefix = "{*}";
|
||||
String[] prefixes = { currentThemePrefix, currentThemeAndAuthorPrefix, currentAuthorPrefix, lightOrDarkPrefix, allThemesPrefix };
|
||||
|
||||
// collect values for special prefixes in its own maps
|
||||
@SuppressWarnings( "unchecked" )
|
||||
Map<String, String>[] maps = new Map[prefixes.length];
|
||||
for( int i = 0; i < maps.length; i++ )
|
||||
maps[i] = new HashMap<>();
|
||||
|
||||
// remove theme specific properties and remember only those for current theme
|
||||
for( String key : themeSpecificKeys ) {
|
||||
Object value = defaults.remove( key );
|
||||
for( String prefix : prefixes ) {
|
||||
String value = (String) properties.remove( key );
|
||||
for( int i = 0; i < prefixes.length; i++ ) {
|
||||
String prefix = prefixes[i];
|
||||
if( key.startsWith( prefix ) ) {
|
||||
themeSpecificDefaults.put( key.substring( prefix.length() ), value );
|
||||
maps[i].put( key.substring( prefix.length() ), value );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return themeSpecificDefaults;
|
||||
// copy values into single map (from lowest to highest priority)
|
||||
Map<String, String> themeSpecificProps = new HashMap<>();
|
||||
for( int i = maps.length - 1; i >= 0; i-- )
|
||||
themeSpecificProps.putAll( maps[i] );
|
||||
return themeSpecificProps;
|
||||
}
|
||||
|
||||
/**
|
||||
* http://www.jetbrains.org/intellij/sdk/docs/reference_guide/ui_themes/themes_customize.html#defining-named-colors
|
||||
*/
|
||||
private void loadNamedColors( UIDefaults defaults ) {
|
||||
if( colors == null )
|
||||
private void loadNamedColors( Properties properties, Set<String> jsonUIKeys ) {
|
||||
if( jsonColors == null )
|
||||
return;
|
||||
|
||||
namedColors = new HashMap<>();
|
||||
|
||||
for( Map.Entry<String, String> e : colors.entrySet() ) {
|
||||
for( Map.Entry<String, String> e : jsonColors.entrySet() ) {
|
||||
String value = e.getValue();
|
||||
ColorUIResource color = parseColor( value );
|
||||
if( color != null ) {
|
||||
if( canParseColor( value ) ) {
|
||||
String key = e.getKey();
|
||||
namedColors.put( key, color );
|
||||
defaults.put( "ColorPalette." + key, color );
|
||||
namedColors.put( key, value );
|
||||
|
||||
String uiKey = "ColorPalette." + key;
|
||||
put( properties, uiKey, value );
|
||||
|
||||
// this is only necessary for copyIfSetInJson() (used for accent color)
|
||||
jsonUIKeys.add( uiKey );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -380,7 +385,7 @@ public class IntelliJTheme
|
||||
* http://www.jetbrains.org/intellij/sdk/docs/reference_guide/ui_themes/themes_customize.html#custom-ui-control-colors
|
||||
*/
|
||||
@SuppressWarnings( "unchecked" )
|
||||
private void apply( String key, Object value, UIDefaults defaults, ArrayList<Object> defaultsKeysCache, Set<String> uiKeys ) {
|
||||
private void apply( String key, Object value, Properties properties, Set<String> jsonUIKeys ) {
|
||||
if( value instanceof Map ) {
|
||||
Map<String, Object> map = (Map<String, Object>)value;
|
||||
if( map.containsKey( "os.default" ) || map.containsKey( "os.windows" ) || map.containsKey( "os.mac" ) || map.containsKey( "os.linux" ) ) {
|
||||
@@ -388,12 +393,12 @@ public class IntelliJTheme
|
||||
: SystemInfo.isMacOS ? "os.mac"
|
||||
: SystemInfo.isLinux ? "os.linux" : null;
|
||||
if( osKey != null && map.containsKey( osKey ) )
|
||||
apply( key, map.get( osKey ), defaults, defaultsKeysCache, uiKeys );
|
||||
apply( key, map.get( osKey ), properties, jsonUIKeys );
|
||||
else if( map.containsKey( "os.default" ) )
|
||||
apply( key, map.get( "os.default" ), defaults, defaultsKeysCache, uiKeys );
|
||||
apply( key, map.get( "os.default" ), properties, jsonUIKeys );
|
||||
} else {
|
||||
for( Map.Entry<String, Object> e : map.entrySet() )
|
||||
apply( key + '.' + e.getKey(), e.getValue(), defaults, defaultsKeysCache, uiKeys );
|
||||
apply( key + '.' + e.getKey(), e.getValue(), properties, jsonUIKeys );
|
||||
}
|
||||
} else {
|
||||
if( "".equals( value ) )
|
||||
@@ -418,15 +423,15 @@ public class IntelliJTheme
|
||||
if( dot > 0 && uiKeyExcludes.contains( key.substring( 0, dot + 1 ) ) )
|
||||
return;
|
||||
|
||||
if( uiKeyDoNotOverride.contains( key ) && uiKeys.contains( key ) )
|
||||
if( uiKeyDoNotOverride.contains( key ) && jsonUIKeys.contains( key ) )
|
||||
return;
|
||||
|
||||
uiKeys.add( key );
|
||||
jsonUIKeys.add( key );
|
||||
|
||||
String valueStr = value.toString();
|
||||
|
||||
// map named colors
|
||||
Object uiValue = namedColors.get( valueStr );
|
||||
String uiValue = namedColors.get( valueStr );
|
||||
|
||||
// parse value
|
||||
if( uiValue == null ) {
|
||||
@@ -445,47 +450,64 @@ public class IntelliJTheme
|
||||
|
||||
// parse value
|
||||
try {
|
||||
uiValue = UIDefaultsLoader.parseValue( key, valueStr, null );
|
||||
UIDefaultsLoader.parseValue( key, valueStr, null );
|
||||
uiValue = valueStr;
|
||||
} catch( RuntimeException ex ) {
|
||||
UIDefaultsLoader.logParseError( key, valueStr, ex, false );
|
||||
UIDefaultsLoader.logParseError( key, valueStr, ex, true );
|
||||
return; // ignore invalid value
|
||||
}
|
||||
}
|
||||
|
||||
if( key.startsWith( "*." ) ) {
|
||||
// wildcard
|
||||
String tail = key.substring( 1 );
|
||||
// wildcards
|
||||
if( applyWildcard( properties, key, uiValue ) )
|
||||
return;
|
||||
|
||||
// because we can not iterate over the UI defaults keys while
|
||||
// modifying UI defaults in the same loop, we have to copy the keys
|
||||
if( defaultsKeysCache.size() != defaults.size() ) {
|
||||
defaultsKeysCache.clear();
|
||||
Enumeration<Object> e = defaults.keys();
|
||||
while( e.hasMoreElements() )
|
||||
defaultsKeysCache.add( e.nextElement() );
|
||||
}
|
||||
|
||||
// replace all values in UI defaults that match the wildcard key
|
||||
for( Object k : defaultsKeysCache ) {
|
||||
if( k.equals( "Desktop.background" ) ||
|
||||
k.equals( "DesktopIcon.background" ) ||
|
||||
k.equals( "TabbedPane.focusColor" ) )
|
||||
continue;
|
||||
|
||||
if( k instanceof String ) {
|
||||
// support replacing of mapped keys
|
||||
// (e.g. set ComboBox.buttonEditableBackground to *.background
|
||||
// because it is mapped from ComboBox.ArrowButton.background)
|
||||
String km = uiKeyInverseMapping.getOrDefault( k, (String) k );
|
||||
if( km.endsWith( tail ) && !((String)k).startsWith( "CheckBox.icon." ) )
|
||||
defaults.put( k, uiValue );
|
||||
}
|
||||
}
|
||||
} else
|
||||
defaults.put( key, uiValue );
|
||||
put( properties, key, uiValue );
|
||||
}
|
||||
}
|
||||
|
||||
private boolean applyWildcard( Properties properties, String key, String value ) {
|
||||
if( !key.startsWith( "*." ) )
|
||||
return false;
|
||||
|
||||
String tail = key.substring( 1 );
|
||||
|
||||
// because we can not iterate over the properties keys while
|
||||
// modifying properties in the same loop, we have to copy the keys
|
||||
String[] keys = properties.keySet().toArray( new String[properties.size()] );
|
||||
|
||||
// replace all values in properties that match the wildcard key
|
||||
for( String k : keys ) {
|
||||
if( k.startsWith( "*" ) ||
|
||||
k.startsWith( "@" ) ||
|
||||
k.startsWith( "HelpButton." ) ||
|
||||
k.startsWith( "JX" ) ||
|
||||
k.startsWith( "Jide" ) ||
|
||||
k.startsWith( "ProgressBar.selection" ) ||
|
||||
k.startsWith( "TitlePane." ) ||
|
||||
k.startsWith( "ToggleButton.tab." ) ||
|
||||
k.equals( "Desktop.background" ) ||
|
||||
k.equals( "DesktopIcon.background" ) ||
|
||||
k.equals( "TabbedPane.focusColor" ) ||
|
||||
k.endsWith( ".hoverBackground" ) ||
|
||||
k.endsWith( ".pressedBackground" ) )
|
||||
continue;
|
||||
|
||||
// support replacing of mapped keys
|
||||
// (e.g. set ComboBox.buttonEditableBackground to *.background
|
||||
// because it is mapped from ComboBox.ArrowButton.background)
|
||||
String km = uiKeyInverseMapping.getOrDefault( k, k );
|
||||
if( km.endsWith( tail ) && !k.startsWith( "CheckBox.icon." ) )
|
||||
put( properties, k, value );
|
||||
}
|
||||
|
||||
// Note: also add wildcards to properties and let UIDefaultsLoader
|
||||
// process it on BasicLookAndFeel UI defaults
|
||||
put( properties, key, value );
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private String fixColorIfValid( String newColorStr, String colorStr ) {
|
||||
try {
|
||||
// check whether it is valid
|
||||
@@ -497,11 +519,11 @@ public class IntelliJTheme
|
||||
}
|
||||
}
|
||||
|
||||
private void applyColorPalette( UIDefaults defaults ) {
|
||||
if( icons == null )
|
||||
private void applyIconsColorPalette( Properties properties ) {
|
||||
if( jsonIcons == null )
|
||||
return;
|
||||
|
||||
Object palette = icons.get( "ColorPalette" );
|
||||
Object palette = jsonIcons.get( "ColorPalette" );
|
||||
if( !(palette instanceof Map) )
|
||||
return;
|
||||
|
||||
@@ -510,44 +532,48 @@ public class IntelliJTheme
|
||||
for( Map.Entry<String, Object> e : colorPalette.entrySet() ) {
|
||||
String key = e.getKey();
|
||||
Object value = e.getValue();
|
||||
if( key.startsWith( "Checkbox." ) || !(value instanceof String) )
|
||||
if( key.startsWith( "Checkbox." ) || key.startsWith( "#" ) || !(value instanceof String) )
|
||||
continue;
|
||||
|
||||
if( dark )
|
||||
key = StringUtils.removeTrailing( key, ".Dark" );
|
||||
|
||||
ColorUIResource color = toColor( (String) value );
|
||||
String color = toColor( (String) value );
|
||||
if( color != null )
|
||||
defaults.put( key, color );
|
||||
put( properties, key, color );
|
||||
}
|
||||
}
|
||||
|
||||
private ColorUIResource toColor( String value ) {
|
||||
private String toColor( String value ) {
|
||||
if( value.startsWith( "##" ) )
|
||||
value = fixColorIfValid( value.substring( 1 ), value );
|
||||
|
||||
// map named colors
|
||||
ColorUIResource color = namedColors.get( value );
|
||||
String color = namedColors.get( value );
|
||||
|
||||
// parse color
|
||||
return (color != null) ? color : parseColor( value );
|
||||
return (color != null) ? color : (canParseColor( value ) ? value : null);
|
||||
}
|
||||
|
||||
private ColorUIResource parseColor( String value ) {
|
||||
private boolean canParseColor( String value ) {
|
||||
try {
|
||||
return UIDefaultsLoader.parseColor( value );
|
||||
return UIDefaultsLoader.parseColor( value ) != null;
|
||||
} catch( IllegalArgumentException ex ) {
|
||||
return null;
|
||||
LoggingFacade.INSTANCE.logSevere( "FlatLaf: Failed to parse color: '" + value + '\'', ex );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Because IDEA uses SVGs for check boxes and radio buttons, the colors for
|
||||
* 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 properties.
|
||||
*/
|
||||
private void applyCheckBoxColors( UIDefaults defaults ) {
|
||||
if( icons == null )
|
||||
private void applyCheckBoxColors( Properties properties ) {
|
||||
if( jsonIcons == null )
|
||||
return;
|
||||
|
||||
Object palette = icons.get( "ColorPalette" );
|
||||
Object palette = jsonIcons.get( "ColorPalette" );
|
||||
if( !(palette instanceof Map) )
|
||||
return;
|
||||
|
||||
@@ -569,9 +595,9 @@ public class IntelliJTheme
|
||||
if( !dark && newKey.startsWith( checkBoxIconPrefix ) )
|
||||
newKey = "CheckBox.icon[filled].".concat( newKey.substring( checkBoxIconPrefix.length() ) );
|
||||
|
||||
ColorUIResource color = toColor( (String) value );
|
||||
String color = toColor( (String) value );
|
||||
if( color != null ) {
|
||||
defaults.put( newKey, color );
|
||||
put( properties, newKey, color );
|
||||
|
||||
String key2 = checkboxDuplicateColors.get( key + ".Dark");
|
||||
if( key2 != null ) {
|
||||
@@ -592,7 +618,7 @@ public class IntelliJTheme
|
||||
|
||||
String newKey2 = checkboxKeyMapping.get( key2 );
|
||||
if( newKey2 != null )
|
||||
defaults.put( newKey2, color );
|
||||
put( properties, newKey2, color );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -603,13 +629,13 @@ public class IntelliJTheme
|
||||
// update hover, pressed and focused colors
|
||||
if( checkboxModified ) {
|
||||
// for non-filled checkbox/radiobutton used in dark themes
|
||||
defaults.remove( "CheckBox.icon.focusWidth" );
|
||||
defaults.put( "CheckBox.icon.hoverBorderColor", defaults.get( "CheckBox.icon.focusedBorderColor" ) );
|
||||
properties.remove( "CheckBox.icon.focusWidth" );
|
||||
put( properties, "CheckBox.icon.hoverBorderColor", properties.get( "CheckBox.icon.focusedBorderColor" ) );
|
||||
|
||||
// for filled checkbox/radiobutton used in light themes
|
||||
defaults.remove( "CheckBox.icon[filled].focusWidth" );
|
||||
defaults.put( "CheckBox.icon[filled].hoverBorderColor", defaults.get( "CheckBox.icon[filled].focusedBorderColor" ) );
|
||||
defaults.put( "CheckBox.icon[filled].focusedSelectedBackground", defaults.get( "CheckBox.icon[filled].selectedBackground" ) );
|
||||
properties.remove( "CheckBox.icon[filled].focusWidth" );
|
||||
put( properties, "CheckBox.icon[filled].hoverBorderColor", properties.get( "CheckBox.icon[filled].focusedBorderColor" ) );
|
||||
put( properties, "CheckBox.icon[filled].focusedSelectedBackground", properties.get( "CheckBox.icon[filled].selectedBackground" ) );
|
||||
|
||||
if( dark ) {
|
||||
// IDEA Darcula checkBoxFocused.svg, checkBoxSelectedFocused.svg,
|
||||
@@ -623,21 +649,14 @@ public class IntelliJTheme
|
||||
"CheckBox.icon[filled].focusedSelectedBorderColor",
|
||||
};
|
||||
for( String key : focusedBorderColorKeys ) {
|
||||
Color color = defaults.getColor( key );
|
||||
if( color != null ) {
|
||||
defaults.put( key, new ColorUIResource( new Color(
|
||||
(color.getRGB() & 0xffffff) | 0xa6000000, true ) ) );
|
||||
}
|
||||
Object color = properties.get( key );
|
||||
if( color != null )
|
||||
put( properties, key, "fade(" + color + ", 65%)" );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void copyIfNotSet( UIDefaults defaults, String destKey, String srcKey, Set<String> uiKeys ) {
|
||||
if( !uiKeys.contains( destKey ) )
|
||||
defaults.put( destKey, defaults.get( srcKey ) );
|
||||
}
|
||||
|
||||
private static final Set<String> uiKeyExcludes;
|
||||
private static final Set<String> uiKeyDoNotOverride;
|
||||
/** Rename UI default keys (key --> value). */
|
||||
@@ -653,26 +672,27 @@ public class IntelliJTheme
|
||||
uiKeyExcludes = new HashSet<>( Arrays.asList(
|
||||
"ActionButton.", "ActionToolbar.", "ActionsList.", "AppInspector.", "AssignedMnemonic.", "Autocomplete.",
|
||||
"AvailableMnemonic.",
|
||||
"BigSpinner.", "Bookmark.", "BookmarkIcon.", "BookmarkMnemonicAssigned.", "BookmarkMnemonicAvailable.",
|
||||
"Badge.", "Banner.", "BigSpinner.", "Bookmark.", "BookmarkIcon.", "BookmarkMnemonicAssigned.", "BookmarkMnemonicAvailable.",
|
||||
"BookmarkMnemonicCurrent.", "BookmarkMnemonicIcon.", "Borders.", "Breakpoint.",
|
||||
"Canvas.", "CodeWithMe.", "ComboBoxButton.", "CompletionPopup.", "ComplexPopup.", "Content.",
|
||||
"CurrentMnemonic.", "Counter.",
|
||||
"Debugger.", "DebuggerPopup.", "DebuggerTabs.", "DefaultTabs.", "Dialog.", "DialogWrapper.", "DragAndDrop.",
|
||||
"Canvas.", "CellEditor.", "Code.", "CodeWithMe.", "ColumnControlButton.", "CombinedDiff.", "ComboBoxButton.",
|
||||
"CompilationCharts.", "CompletionPopup.", "ComplexPopup.", "Content.", "ContextHelp.", "CurrentMnemonic.", "Counter.",
|
||||
"Debugger.", "DebuggerPopup.", "DebuggerTabs.", "DefaultTabs.", "Dialog.", "DialogWrapper.",
|
||||
"DisclosureButton.", "DragAndDrop.",
|
||||
"Editor.", "EditorGroupsTabs.", "EditorTabs.",
|
||||
"FileColor.", "FlameGraph.", "Focus.",
|
||||
"FileColor.", "FindPopup.", "FlameGraph.", "Focus.",
|
||||
"Git.", "Github.", "GotItTooltip.", "Group.", "Gutter.", "GutterTooltip.",
|
||||
"HeaderColor.", "HelpTooltip.", "Hg.",
|
||||
"IconBadge.", "InformationHint.", "InplaceRefactoringPopup.",
|
||||
"Lesson.", "Link.", "LiveIndicator.",
|
||||
"MainMenu.", "MainToolbar.", "MemoryIndicator.", "MlModelBinding.", "MnemonicIcon.",
|
||||
"IconBadge.", "InformationHint.", "InlineBanner.", "InplaceRefactoringPopup.",
|
||||
"Lesson.", "LineProfiler.", "Link.", "LiveIndicator.",
|
||||
"MainMenu.", "MainToolbar.", "MainWindow.", "MemoryIndicator.", "MlModelBinding.", "MnemonicIcon.",
|
||||
"NavBar.", "NewClass.", "NewPSD.", "Notification.", "Notifications.", "NotificationsToolwindow.",
|
||||
"OnePixelDivider.", "OptionButton.", "Outline.",
|
||||
"ParameterInfo.", "Plugins.", "ProgressIcon.", "PsiViewer.",
|
||||
"ReviewList.", "RunWidget.",
|
||||
"ParameterInfo.", "PresentationAssistant.", "Plugins.", "Profiler.", "ProgressIcon.", "PsiViewer.",
|
||||
"Resizable.", "Review.", "ReviewList.", "RunToolbar.", "RunWidget.",
|
||||
"ScreenView.", "SearchEverywhere.", "SearchFieldWithExtension.", "SearchMatch.", "SearchOption.",
|
||||
"SearchResults.", "SegmentedButton.", "Settings.", "SidePanel.", "Space.", "SpeedSearch.", "StateWidget.",
|
||||
"StatusBar.",
|
||||
"Tag.", "TipOfTheDay.", "ToolbarComboWidget.", "ToolWindow.",
|
||||
"StatusBar.", "StripeToolbar.",
|
||||
"Tag.", "TipOfTheDay.", "ToolbarComboWidget.", "ToolWindow.", "TrialWidget.",
|
||||
"UIDesigner.", "UnattendedHostStatus.",
|
||||
"ValidationTooltip.", "VersionControl.",
|
||||
"WelcomeScreen.",
|
||||
@@ -688,6 +708,9 @@ public class IntelliJTheme
|
||||
"TabbedPane.selectedForeground"
|
||||
) );
|
||||
|
||||
// Button
|
||||
uiKeyMapping.put( "Button.minimumSize", "" ); // ignore (used in Material Theme UI Lite)
|
||||
|
||||
// ComboBox
|
||||
uiKeyMapping.put( "ComboBox.background", "" ); // ignore
|
||||
uiKeyMapping.put( "ComboBox.buttonBackground", "" ); // ignore
|
||||
@@ -696,14 +719,17 @@ public class IntelliJTheme
|
||||
uiKeyMapping.put( "ComboBox.ArrowButton.disabledIconColor", "ComboBox.buttonDisabledArrowColor" );
|
||||
uiKeyMapping.put( "ComboBox.ArrowButton.iconColor", "ComboBox.buttonArrowColor" );
|
||||
uiKeyMapping.put( "ComboBox.ArrowButton.nonEditableBackground", "ComboBox.buttonBackground" );
|
||||
uiKeyCopying.put( "ComboBox.buttonSeparatorColor", "Component.borderColor" );
|
||||
uiKeyCopying.put( "ComboBox.buttonDisabledSeparatorColor", "Component.disabledBorderColor" );
|
||||
|
||||
// Component
|
||||
uiKeyMapping.put( "Component.inactiveErrorFocusColor", "Component.error.borderColor" );
|
||||
uiKeyMapping.put( "Component.errorFocusColor", "Component.error.focusedBorderColor" );
|
||||
uiKeyMapping.put( "Component.inactiveWarningFocusColor", "Component.warning.borderColor" );
|
||||
uiKeyMapping.put( "Component.warningFocusColor", "Component.warning.focusedBorderColor" );
|
||||
uiKeyMapping.put( "Component.inactiveSuccessFocusColor", "Component.success.borderColor" );
|
||||
uiKeyMapping.put( "Component.successFocusColor", "Component.success.focusedBorderColor" );
|
||||
|
||||
// Label
|
||||
uiKeyMapping.put( "Label.disabledForegroundColor", "" ); // ignore (used in Material Theme UI Lite)
|
||||
|
||||
// Link
|
||||
uiKeyMapping.put( "Link.activeForeground", "Component.linkColor" );
|
||||
@@ -711,10 +737,7 @@ public class IntelliJTheme
|
||||
// Menu
|
||||
uiKeyMapping.put( "Menu.border", "Menu.margin" );
|
||||
uiKeyMapping.put( "MenuItem.border", "MenuItem.margin" );
|
||||
uiKeyCopying.put( "CheckBoxMenuItem.margin", "MenuItem.margin" );
|
||||
uiKeyCopying.put( "RadioButtonMenuItem.margin", "MenuItem.margin" );
|
||||
uiKeyMapping.put( "PopupMenu.border", "PopupMenu.borderInsets" );
|
||||
uiKeyCopying.put( "MenuItem.underlineSelectionColor", "TabbedPane.underlineColor" );
|
||||
|
||||
// IDEA uses List.selectionBackground also for menu selection
|
||||
uiKeyCopying.put( "Menu.selectionBackground", "List.selectionBackground" );
|
||||
@@ -722,13 +745,11 @@ public class IntelliJTheme
|
||||
uiKeyCopying.put( "CheckBoxMenuItem.selectionBackground", "List.selectionBackground" );
|
||||
uiKeyCopying.put( "RadioButtonMenuItem.selectionBackground", "List.selectionBackground" );
|
||||
|
||||
// ProgressBar
|
||||
// ProgressBar: IDEA uses ProgressBar.trackColor and ProgressBar.progressColor
|
||||
uiKeyMapping.put( "ProgressBar.background", "" ); // ignore
|
||||
uiKeyMapping.put( "ProgressBar.foreground", "" ); // ignore
|
||||
uiKeyMapping.put( "ProgressBar.trackColor", "ProgressBar.background" );
|
||||
uiKeyMapping.put( "ProgressBar.progressColor", "ProgressBar.foreground" );
|
||||
uiKeyCopying.put( "ProgressBar.selectionForeground", "ProgressBar.background" );
|
||||
uiKeyCopying.put( "ProgressBar.selectionBackground", "ProgressBar.foreground" );
|
||||
|
||||
// ScrollBar
|
||||
uiKeyMapping.put( "ScrollBar.trackColor", "ScrollBar.track" );
|
||||
@@ -738,34 +759,30 @@ public class IntelliJTheme
|
||||
uiKeyMapping.put( "Separator.separatorColor", "Separator.foreground" );
|
||||
|
||||
// Slider
|
||||
uiKeyMapping.put( "Slider.buttonColor", "Slider.thumbColor" );
|
||||
uiKeyMapping.put( "Slider.buttonBorderColor", "" ); // ignore
|
||||
uiKeyMapping.put( "Slider.thumb", "" ); // ignore (used in Material Theme UI Lite)
|
||||
uiKeyMapping.put( "Slider.track", "" ); // ignore (used in Material Theme UI Lite)
|
||||
uiKeyMapping.put( "Slider.trackDisabled", "" ); // ignore (used in Material Theme UI Lite)
|
||||
uiKeyMapping.put( "Slider.trackWidth", "" ); // ignore (used in Material Theme UI Lite)
|
||||
uiKeyCopying.put( "Slider.trackValueColor", "ProgressBar.foreground" );
|
||||
uiKeyCopying.put( "Slider.thumbColor", "ProgressBar.foreground" );
|
||||
uiKeyCopying.put( "Slider.trackColor", "ProgressBar.background" );
|
||||
|
||||
// Spinner
|
||||
uiKeyCopying.put( "Spinner.buttonSeparatorColor", "Component.borderColor" );
|
||||
uiKeyCopying.put( "Spinner.buttonDisabledSeparatorColor", "Component.disabledBorderColor" );
|
||||
|
||||
// TabbedPane
|
||||
uiKeyMapping.put( "DefaultTabs.underlinedTabBackground", "TabbedPane.selectedBackground" );
|
||||
uiKeyMapping.put( "DefaultTabs.underlinedTabForeground", "TabbedPane.selectedForeground" );
|
||||
uiKeyMapping.put( "DefaultTabs.inactiveUnderlineColor", "TabbedPane.inactiveUnderlineColor" );
|
||||
uiKeyMapping.put( "TabbedPane.tabAreaInsets", "" ); // ignore (used in Material Theme UI Lite)
|
||||
|
||||
// TableHeader
|
||||
uiKeyMapping.put( "TableHeader.cellBorder", "" ); // ignore (used in Material Theme UI Lite)
|
||||
uiKeyMapping.put( "TableHeader.height", "" ); // ignore (used in Material Theme UI Lite)
|
||||
|
||||
// TitlePane
|
||||
uiKeyCopying.put( "TitlePane.inactiveBackground", "TitlePane.background" );
|
||||
uiKeyMapping.put( "TitlePane.infoForeground", "TitlePane.foreground" );
|
||||
uiKeyMapping.put( "TitlePane.inactiveInfoForeground", "TitlePane.inactiveForeground" );
|
||||
|
||||
for( Map.Entry<String, String> e : uiKeyMapping.entrySet() )
|
||||
uiKeyInverseMapping.put( e.getValue(), e.getKey() );
|
||||
|
||||
uiKeyCopying.put( "ToggleButton.tab.underlineColor", "TabbedPane.underlineColor" );
|
||||
uiKeyCopying.put( "ToggleButton.tab.disabledUnderlineColor", "TabbedPane.disabledUnderlineColor" );
|
||||
uiKeyCopying.put( "ToggleButton.tab.selectedBackground", "TabbedPane.selectedBackground" );
|
||||
uiKeyCopying.put( "ToggleButton.tab.hoverBackground", "TabbedPane.hoverColor" );
|
||||
uiKeyCopying.put( "ToggleButton.tab.focusBackground", "TabbedPane.focusColor" );
|
||||
|
||||
checkboxKeyMapping.put( "Checkbox.Background.Default", "CheckBox.icon.background" );
|
||||
checkboxKeyMapping.put( "Checkbox.Background.Disabled", "CheckBox.icon.disabledBackground" );
|
||||
checkboxKeyMapping.put( "Checkbox.Border.Default", "CheckBox.icon.borderColor" );
|
||||
@@ -818,17 +835,15 @@ public class IntelliJTheme
|
||||
}
|
||||
|
||||
@Override
|
||||
void applyAdditionalDefaults( UIDefaults defaults ) {
|
||||
theme.applyProperties( defaults );
|
||||
void applyAdditionalProperties( Properties properties ) {
|
||||
theme.applyProperties( properties );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ArrayList<Class<?>> getLafClassesForDefaultsLoading() {
|
||||
ArrayList<Class<?>> lafClasses = new ArrayList<>();
|
||||
lafClasses.add( FlatLaf.class );
|
||||
lafClasses.add( theme.dark ? FlatDarkLaf.class : FlatLightLaf.class );
|
||||
lafClasses.add( theme.dark ? FlatDarculaLaf.class : FlatIntelliJLaf.class );
|
||||
lafClasses.add( ThemeLaf.class );
|
||||
ArrayList<Class<?>> lafClasses = UIDefaultsLoader.getLafClassesForDefaultsLoading( getClass() );
|
||||
lafClasses.add( 1, theme.dark ? FlatDarkLaf.class : FlatLightLaf.class );
|
||||
lafClasses.add( 2, theme.dark ? FlatDarculaLaf.class : FlatIntelliJLaf.class );
|
||||
return lafClasses;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,7 +111,7 @@ class LinuxFontPolicy
|
||||
if( logicalFamily != null )
|
||||
family = logicalFamily;
|
||||
|
||||
return createFontEx( family, style, size, dsize );
|
||||
return createFontEx( family, style, size );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -121,9 +121,9 @@ class LinuxFontPolicy
|
||||
* E.g. family 'URW Bookman Light' is not found, but 'URW Bookman' is found.
|
||||
* If still not found, then font of family 'Dialog' is returned.
|
||||
*/
|
||||
private static Font createFontEx( String family, int style, int size, double dsize ) {
|
||||
private static Font createFontEx( String family, int style, int size ) {
|
||||
for(;;) {
|
||||
Font font = createFont( family, style, size, dsize );
|
||||
Font font = FlatLaf.createCompositeFont( family, style, size );
|
||||
|
||||
if( Font.DIALOG.equals( family ) )
|
||||
return font;
|
||||
@@ -135,7 +135,7 @@ class LinuxFontPolicy
|
||||
// - character width is zero (e.g. font Cantarell; Fedora; Oracle Java 8)
|
||||
FontMetrics fm = StyleContext.getDefaultStyleContext().getFontMetrics( font );
|
||||
if( fm.getHeight() > size * 2 || fm.stringWidth( "a" ) == 0 )
|
||||
return createFont( Font.DIALOG, style, size, dsize );
|
||||
return FlatLaf.createCompositeFont( Font.DIALOG, style, size );
|
||||
|
||||
return font;
|
||||
}
|
||||
@@ -143,7 +143,7 @@ class LinuxFontPolicy
|
||||
// find last word in family
|
||||
int index = family.lastIndexOf( ' ' );
|
||||
if( index < 0 )
|
||||
return createFont( Font.DIALOG, style, size, dsize );
|
||||
return FlatLaf.createCompositeFont( Font.DIALOG, style, size );
|
||||
|
||||
// check whether last work contains some font weight (e.g. Ultra-Bold or Heavy)
|
||||
String lastWord = family.substring( index + 1 ).toLowerCase( Locale.ENGLISH );
|
||||
@@ -155,15 +155,6 @@ class LinuxFontPolicy
|
||||
}
|
||||
}
|
||||
|
||||
private static Font createFont( String family, int style, int size, double dsize ) {
|
||||
Font font = FlatLaf.createCompositeFont( family, style, size );
|
||||
|
||||
// set font size in floating points
|
||||
font = font.deriveFont( style, (float) dsize );
|
||||
|
||||
return font;
|
||||
}
|
||||
|
||||
private static double getGnomeFontScale() {
|
||||
// do not scale font here if JRE scales
|
||||
if( isSystemScaling() )
|
||||
@@ -257,7 +248,7 @@ class LinuxFontPolicy
|
||||
if( size < 1 )
|
||||
size = 1;
|
||||
|
||||
return createFont( family, style, size, dsize );
|
||||
return FlatLaf.createCompositeFont( family, style, size );
|
||||
}
|
||||
|
||||
@SuppressWarnings( "MixedMutabilityReturnType" ) // Error Prone
|
||||
|
||||
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* Copyright 2025 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Window;
|
||||
import java.awt.event.ComponentEvent;
|
||||
import java.awt.event.ComponentListener;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import javax.swing.JPopupMenu;
|
||||
import javax.swing.MenuElement;
|
||||
import javax.swing.MenuSelectionManager;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.event.ChangeEvent;
|
||||
import javax.swing.event.ChangeListener;
|
||||
|
||||
/**
|
||||
* Cancels (hides) popup menus on Linux.
|
||||
* <p>
|
||||
* On Linux, popups are not hidden under following conditions, which results in
|
||||
* misplaced popups:
|
||||
* <ul>
|
||||
* <li>window moved or resized
|
||||
* <li>window maximized or restored
|
||||
* <li>window iconified
|
||||
* <li>window deactivated (e.g. activated other application)
|
||||
* </ul>
|
||||
*
|
||||
* On Windows and macOS, popups are automatically hidden.
|
||||
* <p>
|
||||
* The implementation is similar to what's done in
|
||||
* {@code javax.swing.plaf.basic.BasicPopupMenuUI.MouseGrabber},
|
||||
* but only hides popup in some conditions.
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
class LinuxPopupMenuCanceler
|
||||
extends WindowAdapter
|
||||
implements ChangeListener, ComponentListener
|
||||
{
|
||||
private MenuElement[] lastPathSelectedPath;
|
||||
private Window window;
|
||||
|
||||
LinuxPopupMenuCanceler() {
|
||||
MenuSelectionManager msm = MenuSelectionManager.defaultManager();
|
||||
msm.addChangeListener( this );
|
||||
|
||||
lastPathSelectedPath = msm.getSelectedPath();
|
||||
if( lastPathSelectedPath.length > 0 )
|
||||
addWindowListeners( lastPathSelectedPath[0] );
|
||||
}
|
||||
|
||||
void uninstall() {
|
||||
MenuSelectionManager.defaultManager().removeChangeListener( this );
|
||||
}
|
||||
|
||||
private void addWindowListeners( MenuElement selected ) {
|
||||
// see BasicPopupMenuUI.MouseGrabber.grabWindow()
|
||||
Component invoker = selected.getComponent();
|
||||
if( invoker instanceof JPopupMenu )
|
||||
invoker = ((JPopupMenu)invoker).getInvoker();
|
||||
window = (invoker instanceof Window)
|
||||
? (Window) invoker
|
||||
: SwingUtilities.windowForComponent( invoker );
|
||||
|
||||
if( window != null ) {
|
||||
window.addWindowListener( this );
|
||||
window.addComponentListener( this );
|
||||
}
|
||||
}
|
||||
|
||||
private void removeWindowListeners() {
|
||||
if( window != null ) {
|
||||
window.removeWindowListener( this );
|
||||
window.removeComponentListener( this );
|
||||
window = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void cancelPopupMenu() {
|
||||
try {
|
||||
MenuSelectionManager msm = MenuSelectionManager.defaultManager();
|
||||
MenuElement[] selectedPath = msm.getSelectedPath();
|
||||
for( MenuElement e : selectedPath ) {
|
||||
if( e instanceof JPopupMenu )
|
||||
((JPopupMenu)e).putClientProperty( "JPopupMenu.firePopupMenuCanceled", true );
|
||||
}
|
||||
msm.clearSelectedPath();
|
||||
} catch( RuntimeException ex ) {
|
||||
removeWindowListeners();
|
||||
throw ex;
|
||||
} catch( Error ex ) {
|
||||
removeWindowListeners();
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
//---- ChangeListener ----
|
||||
|
||||
@Override
|
||||
public void stateChanged( ChangeEvent e ) {
|
||||
MenuElement[] selectedPath = MenuSelectionManager.defaultManager().getSelectedPath();
|
||||
|
||||
if( selectedPath.length == 0 )
|
||||
removeWindowListeners();
|
||||
else if( lastPathSelectedPath.length == 0 )
|
||||
addWindowListeners( selectedPath[0] );
|
||||
|
||||
lastPathSelectedPath = selectedPath;
|
||||
}
|
||||
|
||||
//---- WindowListener ----
|
||||
|
||||
@Override
|
||||
public void windowIconified( WindowEvent e ) {
|
||||
cancelPopupMenu();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windowDeactivated( WindowEvent e ) {
|
||||
cancelPopupMenu();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void windowClosing( WindowEvent e ) {
|
||||
cancelPopupMenu();
|
||||
}
|
||||
|
||||
//---- ComponentListener ----
|
||||
|
||||
@Override
|
||||
public void componentResized( ComponentEvent e ) {
|
||||
cancelPopupMenu();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void componentMoved( ComponentEvent e ) {
|
||||
cancelPopupMenu();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void componentShown( ComponentEvent e ) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void componentHidden( ComponentEvent e ) {
|
||||
cancelPopupMenu();
|
||||
}
|
||||
}
|
||||
@@ -41,6 +41,8 @@ import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.UIDefaults;
|
||||
@@ -61,7 +63,6 @@ import com.formdev.flatlaf.util.HSLColor;
|
||||
import com.formdev.flatlaf.util.LoggingFacade;
|
||||
import com.formdev.flatlaf.util.SoftCache;
|
||||
import com.formdev.flatlaf.util.StringUtils;
|
||||
import com.formdev.flatlaf.util.SystemInfo;
|
||||
import com.formdev.flatlaf.util.UIScale;
|
||||
|
||||
/**
|
||||
@@ -85,15 +86,14 @@ class UIDefaultsLoader
|
||||
private static final String WILDCARD_PREFIX = "*.";
|
||||
|
||||
static final String KEY_VARIABLES = "FlatLaf.internal.variables";
|
||||
static final String KEY_PROPERTIES = "FlatLaf.internal.properties";
|
||||
|
||||
private static int parseColorDepth;
|
||||
|
||||
private static Map<String, ColorUIResource> systemColorCache;
|
||||
private static final SoftCache<String, Object> fontCache = new SoftCache<>();
|
||||
|
||||
static void loadDefaultsFromProperties( Class<?> lookAndFeelClass, List<FlatDefaultsAddon> addons,
|
||||
Properties additionalDefaults, boolean dark, UIDefaults defaults )
|
||||
{
|
||||
static ArrayList<Class<?>> getLafClassesForDefaultsLoading( Class<?> lookAndFeelClass ) {
|
||||
// determine classes in class hierarchy in reverse order
|
||||
ArrayList<Class<?>> lafClasses = new ArrayList<>();
|
||||
for( Class<?> lafClass = lookAndFeelClass;
|
||||
@@ -102,20 +102,54 @@ class UIDefaultsLoader
|
||||
{
|
||||
lafClasses.add( 0, lafClass );
|
||||
}
|
||||
return lafClasses;
|
||||
}
|
||||
|
||||
loadDefaultsFromProperties( lafClasses, addons, additionalDefaults, dark, defaults );
|
||||
static Properties newUIProperties( boolean dark ) {
|
||||
// UI key prefixes
|
||||
String lightOrDarkPrefix = FlatLaf.getUIKeyLightOrDarkPrefix( dark );
|
||||
Set<String> platformPrefixes = FlatLaf.getUIKeyPlatformPrefixes();
|
||||
Set<String> specialPrefixes = FlatLaf.getUIKeySpecialPrefixes();
|
||||
|
||||
return new Properties() {
|
||||
@Override
|
||||
public synchronized Object put( Object k, Object value ) {
|
||||
// process key prefixes (while loading properties files)
|
||||
String key = (String) k;
|
||||
while( key.startsWith( "[" ) ) {
|
||||
int closeIndex = key.indexOf( ']' );
|
||||
if( closeIndex < 0 )
|
||||
return null; // ignore property with invalid prefix
|
||||
|
||||
String prefix = key.substring( 0, closeIndex + 1 );
|
||||
|
||||
if( specialPrefixes.contains( prefix ) )
|
||||
break; // keep special prefix
|
||||
|
||||
if( !lightOrDarkPrefix.equals( prefix ) && !platformPrefixes.contains( prefix ) )
|
||||
return null; // ignore property
|
||||
|
||||
// prefix is known and enabled --> remove prefix
|
||||
key = key.substring( closeIndex + 1 );
|
||||
}
|
||||
|
||||
return super.put( key, value );
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
static void loadDefaultsFromProperties( List<Class<?>> lafClasses, List<FlatDefaultsAddon> addons,
|
||||
Properties additionalDefaults, boolean dark, UIDefaults defaults )
|
||||
Consumer<Properties> intellijThemesHook, Properties additionalDefaults, boolean dark, UIDefaults defaults )
|
||||
{
|
||||
try {
|
||||
// temporary cache system colors while loading defaults,
|
||||
// which avoids that system color getter is invoked multiple times
|
||||
systemColorCache = (FlatLaf.getSystemColorGetter() != null) ? new HashMap<>() : null;
|
||||
|
||||
// all properties files will be loaded into this map
|
||||
Properties properties = newUIProperties( dark );
|
||||
|
||||
// load core properties files
|
||||
Properties properties = new Properties();
|
||||
for( Class<?> lafClass : lafClasses ) {
|
||||
String propertiesName = '/' + lafClass.getName().replace( '.', '/' ) + ".properties";
|
||||
try( InputStream in = lafClass.getResourceAsStream( propertiesName ) ) {
|
||||
@@ -142,6 +176,10 @@ class UIDefaultsLoader
|
||||
addonClassLoaders.add( addonClassLoader );
|
||||
}
|
||||
|
||||
// apply IntelliJ themes properties
|
||||
if( intellijThemesHook != null )
|
||||
intellijThemesHook.accept( properties );
|
||||
|
||||
// load custom properties files (usually provided by applications)
|
||||
List<Object> customDefaultsSources = FlatLaf.getCustomDefaultsSources();
|
||||
int size = (customDefaultsSources != null) ? customDefaultsSources.size() : 0;
|
||||
@@ -198,41 +236,6 @@ class UIDefaultsLoader
|
||||
if( additionalDefaults != null )
|
||||
properties.putAll( additionalDefaults );
|
||||
|
||||
// collect all platform specific keys (but do not modify properties)
|
||||
ArrayList<String> platformSpecificKeys = new ArrayList<>();
|
||||
for( Object okey : properties.keySet() ) {
|
||||
String key = (String) okey;
|
||||
if( key.startsWith( "[" ) &&
|
||||
(key.startsWith( "[win]" ) ||
|
||||
key.startsWith( "[mac]" ) ||
|
||||
key.startsWith( "[linux]" ) ||
|
||||
key.startsWith( "[light]" ) ||
|
||||
key.startsWith( "[dark]" )) )
|
||||
platformSpecificKeys.add( key );
|
||||
}
|
||||
|
||||
// remove platform specific properties and re-add only properties
|
||||
// for current platform, but with platform prefix removed
|
||||
if( !platformSpecificKeys.isEmpty() ) {
|
||||
// handle light/dark specific properties
|
||||
String lightOrDarkPrefix = dark ? "[dark]" : "[light]";
|
||||
for( String key : platformSpecificKeys ) {
|
||||
if( key.startsWith( lightOrDarkPrefix ) )
|
||||
properties.put( key.substring( lightOrDarkPrefix.length() ), properties.remove( key ) );
|
||||
}
|
||||
|
||||
// handle platform specific properties
|
||||
String platformPrefix =
|
||||
SystemInfo.isWindows ? "[win]" :
|
||||
SystemInfo.isMacOS ? "[mac]" :
|
||||
SystemInfo.isLinux ? "[linux]" : "[unknown]";
|
||||
for( String key : platformSpecificKeys ) {
|
||||
Object value = properties.remove( key );
|
||||
if( key.startsWith( platformPrefix ) )
|
||||
properties.put( key.substring( platformPrefix.length() ), value );
|
||||
}
|
||||
}
|
||||
|
||||
// get (and remove) wildcard replacements, which override all other defaults that end with same suffix
|
||||
HashMap<String, String> wildcards = new HashMap<>();
|
||||
Iterator<Entry<Object, Object>> it = properties.entrySet().iterator();
|
||||
@@ -287,6 +290,15 @@ class UIDefaultsLoader
|
||||
// remember variables in defaults to allow using them in styles
|
||||
defaults.put( KEY_VARIABLES, variables );
|
||||
|
||||
// remember properties (for testing)
|
||||
if( FlatSystemProperties.getBoolean( KEY_PROPERTIES, false ) ) {
|
||||
Properties properties2 = new Properties();
|
||||
properties2.putAll( properties );
|
||||
for( Map.Entry<String, String> e : wildcards.entrySet() )
|
||||
properties2.put( WILDCARD_PREFIX + e.getKey(), e.getValue() );
|
||||
defaults.put( KEY_PROPERTIES, properties2 );
|
||||
}
|
||||
|
||||
// clear/disable system color cache
|
||||
systemColorCache = null;
|
||||
} catch( IOException ex ) {
|
||||
@@ -830,6 +842,7 @@ class UIDefaultsLoader
|
||||
try {
|
||||
switch( function ) {
|
||||
case "if": return parseColorIf( value, params, resolver );
|
||||
case "lazy": return parseColorLazy( value, params, resolver );
|
||||
case "systemColor": return parseColorSystemColor( value, params, resolver );
|
||||
case "rgb": return parseColorRgbOrRgba( false, params, resolver );
|
||||
case "rgba": return parseColorRgbOrRgba( true, params, resolver );
|
||||
@@ -877,6 +890,32 @@ class UIDefaultsLoader
|
||||
return parseColorOrFunction( resolver.apply( ifValue ), resolver );
|
||||
}
|
||||
|
||||
/**
|
||||
* Syntax: lazy(uiKey)
|
||||
* <p>
|
||||
* This "lazy" function is only used if the "lazy" is passed as parameter to another
|
||||
* color function. Otherwise, the general "lazy" function is used.
|
||||
* <p>
|
||||
* Note: The color is resolved immediately, not lazy, because it is passed as parameter to another color function.
|
||||
* So e.g. {@code darken(lazy(List.background), 10%)} is the same as {@code darken($List.background, 10%)}.
|
||||
* <p>
|
||||
* Only useful if a property is defined as lazy and that property is used
|
||||
* in another property's color function. E.g.
|
||||
*
|
||||
* <pre>{@code
|
||||
* someProperty = lazy(List.background)
|
||||
* anotherProperty = darken($someProperty, 10%)
|
||||
* }</pre>
|
||||
*/
|
||||
private static Object parseColorLazy( String value, List<String> params, Function<String, String> resolver )
|
||||
throws IllegalArgumentException
|
||||
{
|
||||
if( params.size() != 1 )
|
||||
throw newMissingParametersException( value );
|
||||
|
||||
return parseColorOrFunction( resolver.apply( PROPERTY_PREFIX + params.get( 0 ) ), resolver );
|
||||
}
|
||||
|
||||
/**
|
||||
* Syntax: systemColor(name[,defaultValue])
|
||||
* - name: system color name
|
||||
@@ -974,7 +1013,7 @@ class UIDefaultsLoader
|
||||
* fadein(color,amount[,options]) or fadeout(color,amount[,options])
|
||||
* - color: a color (e.g. #f00) or a color function
|
||||
* - amount: percentage 0-100%
|
||||
* - options: [relative] [autoInverse] [noAutoInverse] [lazy] [derived]
|
||||
* - options: [relative] [autoInverse] [noAutoInverse] [derived] [lazy]
|
||||
*/
|
||||
private static Object parseColorHSLIncreaseDecrease( int hslIndex, boolean increase,
|
||||
List<String> params, Function<String, String> resolver )
|
||||
@@ -984,15 +1023,15 @@ class UIDefaultsLoader
|
||||
int amount = parsePercentage( params.get( 1 ) );
|
||||
boolean relative = false;
|
||||
boolean autoInverse = false;
|
||||
boolean lazy = false;
|
||||
boolean derived = false;
|
||||
boolean lazy = false;
|
||||
|
||||
if( params.size() > 2 ) {
|
||||
String options = params.get( 2 );
|
||||
relative = options.contains( "relative" );
|
||||
autoInverse = options.contains( "autoInverse" );
|
||||
lazy = options.contains( "lazy" );
|
||||
derived = options.contains( "derived" );
|
||||
lazy = options.contains( "lazy" );
|
||||
|
||||
// use autoInverse by default for derived colors, except if noAutoInverse is set
|
||||
if( derived && !options.contains( "noAutoInverse" ) )
|
||||
@@ -1003,14 +1042,8 @@ class UIDefaultsLoader
|
||||
ColorFunction function = new ColorFunctions.HSLIncreaseDecrease(
|
||||
hslIndex, increase, amount, relative, autoInverse );
|
||||
|
||||
if( lazy ) {
|
||||
return (LazyValue) t -> {
|
||||
Object color = lazyUIManagerGet( colorStr );
|
||||
return (color instanceof Color)
|
||||
? new ColorUIResource( ColorFunctions.applyFunctions( (Color) color, function ) )
|
||||
: null;
|
||||
};
|
||||
}
|
||||
if( lazy )
|
||||
return newLazyColorFunction( colorStr, function );
|
||||
|
||||
// parse base color, apply function and create derived color
|
||||
return parseFunctionBaseColor( colorStr, function, derived, resolver );
|
||||
@@ -1039,14 +1072,8 @@ class UIDefaultsLoader
|
||||
// create function
|
||||
ColorFunction function = new ColorFunctions.Fade( amount );
|
||||
|
||||
if( lazy ) {
|
||||
return (LazyValue) t -> {
|
||||
Object color = lazyUIManagerGet( colorStr );
|
||||
return (color instanceof Color)
|
||||
? new ColorUIResource( ColorFunctions.applyFunctions( (Color) color, function ) )
|
||||
: null;
|
||||
};
|
||||
}
|
||||
if( lazy )
|
||||
return newLazyColorFunction( colorStr, function );
|
||||
|
||||
// parse base color, apply function and create derived color
|
||||
return parseFunctionBaseColor( colorStr, function, derived, resolver );
|
||||
@@ -1056,7 +1083,7 @@ class UIDefaultsLoader
|
||||
* Syntax: spin(color,angle[,options])
|
||||
* - color: a color (e.g. #f00) or a color function
|
||||
* - angle: number of degrees to rotate
|
||||
* - options: [derived]
|
||||
* - options: [derived] [lazy]
|
||||
*/
|
||||
private static Object parseColorSpin( List<String> params, Function<String, String> resolver )
|
||||
throws IllegalArgumentException
|
||||
@@ -1064,15 +1091,20 @@ class UIDefaultsLoader
|
||||
String colorStr = params.get( 0 );
|
||||
int amount = parseInteger( params.get( 1 ) );
|
||||
boolean derived = false;
|
||||
boolean lazy = false;
|
||||
|
||||
if( params.size() > 2 ) {
|
||||
String options = params.get( 2 );
|
||||
derived = options.contains( "derived" );
|
||||
lazy = options.contains( "lazy" );
|
||||
}
|
||||
|
||||
// create function
|
||||
ColorFunction function = new ColorFunctions.HSLIncreaseDecrease( 0, true, amount, false, false );
|
||||
|
||||
if( lazy )
|
||||
return newLazyColorFunction( colorStr, function );
|
||||
|
||||
// parse base color, apply function and create derived color
|
||||
return parseFunctionBaseColor( colorStr, function, derived, resolver );
|
||||
}
|
||||
@@ -1084,7 +1116,7 @@ class UIDefaultsLoader
|
||||
* changeAlpha(color,value[,options])
|
||||
* - color: a color (e.g. #f00) or a color function
|
||||
* - value: for hue: number of degrees; otherwise: percentage 0-100%
|
||||
* - options: [derived]
|
||||
* - options: [derived] [lazy]
|
||||
*/
|
||||
private static Object parseColorChange( int hslIndex,
|
||||
List<String> params, Function<String, String> resolver )
|
||||
@@ -1095,27 +1127,33 @@ class UIDefaultsLoader
|
||||
? parseInteger( params.get( 1 ) )
|
||||
: parsePercentage( params.get( 1 ) );
|
||||
boolean derived = false;
|
||||
boolean lazy = false;
|
||||
|
||||
if( params.size() > 2 ) {
|
||||
String options = params.get( 2 );
|
||||
derived = options.contains( "derived" );
|
||||
lazy = options.contains( "lazy" );
|
||||
}
|
||||
|
||||
// create function
|
||||
ColorFunction function = new ColorFunctions.HSLChange( hslIndex, value );
|
||||
|
||||
if( lazy )
|
||||
return newLazyColorFunction( colorStr, function );
|
||||
|
||||
// parse base color, apply function and create derived color
|
||||
return parseFunctionBaseColor( colorStr, function, derived, resolver );
|
||||
}
|
||||
|
||||
/**
|
||||
* Syntax: mix(color1,color2[,weight]) or
|
||||
* tint(color[,weight]) or
|
||||
* shade(color[,weight])
|
||||
* Syntax: mix(color1,color2[,weight][,options]) or
|
||||
* tint(color[,weight][,options]) or
|
||||
* shade(color[,weight][,options])
|
||||
* - color1: a color (e.g. #f00) or a color function
|
||||
* - color2: a color (e.g. #f00) or a color function
|
||||
* - 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
|
||||
* - options: [derived] [lazy]
|
||||
*/
|
||||
private static Object parseColorMix( String color1Str, List<String> params, Function<String, String> resolver )
|
||||
throws IllegalArgumentException
|
||||
@@ -1124,18 +1162,36 @@ class UIDefaultsLoader
|
||||
if( color1Str == null )
|
||||
color1Str = params.get( i++ );
|
||||
String color2Str = params.get( i++ );
|
||||
int weight = (params.size() > i) ? parsePercentage( params.get( i ) ) : 50;
|
||||
int weight = 50;
|
||||
boolean derived = false;
|
||||
boolean lazy = false;
|
||||
|
||||
if( params.size() > i ) {
|
||||
String weightStr = params.get( i );
|
||||
if( !weightStr.isEmpty() && Character.isDigit( weightStr.charAt( 0 ) ) ) {
|
||||
weight = parsePercentage( weightStr );
|
||||
i++;
|
||||
}
|
||||
}
|
||||
if( params.size() > i ) {
|
||||
String options = params.get( i );
|
||||
derived = options.contains( "derived" );
|
||||
lazy = options.contains( "lazy" );
|
||||
}
|
||||
|
||||
// parse second color
|
||||
ColorUIResource color2 = (ColorUIResource) parseColorOrFunction( resolver.apply( color2Str ), resolver );
|
||||
if( color2 == null )
|
||||
ColorUIResource color1 = (ColorUIResource) parseColorOrFunction( resolver.apply( color1Str ), resolver );
|
||||
if( color1 == null )
|
||||
return null;
|
||||
|
||||
// create function
|
||||
ColorFunction function = new ColorFunctions.Mix( color2, weight );
|
||||
ColorFunction function = new ColorFunctions.Mix2( color1, weight );
|
||||
|
||||
if( lazy )
|
||||
return newLazyColorFunction( color2Str, function );
|
||||
|
||||
// parse first color, apply function and create mixed color
|
||||
return parseFunctionBaseColor( color1Str, function, false, resolver );
|
||||
return parseFunctionBaseColor( color2Str, function, derived, resolver );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1229,6 +1285,15 @@ class UIDefaultsLoader
|
||||
return new ColorUIResource( newColor );
|
||||
}
|
||||
|
||||
private static LazyValue newLazyColorFunction( String uiKey, ColorFunction function ) {
|
||||
return (LazyValue) t -> {
|
||||
Object color = lazyUIManagerGet( uiKey );
|
||||
return (color instanceof Color)
|
||||
? new ColorUIResource( ColorFunctions.applyFunctions( (Color) color, function ) )
|
||||
: null;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Syntax: [normal] [bold|+bold|-bold] [italic|+italic|-italic] [<size>|+<incr>|-<decr>|<percent>%] [family[, family]] [$baseFontKey]
|
||||
*/
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.formdev.flatlaf.icons;
|
||||
|
||||
import static com.formdev.flatlaf.FlatClientProperties.*;
|
||||
import static com.formdev.flatlaf.ui.FlatUIUtils.stateColor;
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
@@ -48,6 +49,8 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
* @uiDefault CheckBox.icon.borderWidth int or float optional; defaults to Component.borderWidth
|
||||
* @uiDefault CheckBox.icon.selectedBorderWidth int or float optional; defaults to CheckBox.icon.borderWidth
|
||||
* @uiDefault CheckBox.icon.disabledSelectedBorderWidth int or float optional; defaults to CheckBox.icon.selectedBorderWidth
|
||||
* @uiDefault CheckBox.icon.indeterminateBorderWidth int or float optional; defaults to CheckBox.icon.selectedBorderWidth
|
||||
* @uiDefault CheckBox.icon.disabledIndeterminateBorderWidth int or float optional; defaults to CheckBox.icon.disabledSelectedBorderWidth
|
||||
* @uiDefault CheckBox.arc int
|
||||
*
|
||||
* @uiDefault CheckBox.icon.focusColor Color optional; defaults to Component.focusColor
|
||||
@@ -56,30 +59,45 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
* @uiDefault CheckBox.icon.selectedBorderColor Color
|
||||
* @uiDefault CheckBox.icon.selectedBackground Color
|
||||
* @uiDefault CheckBox.icon.checkmarkColor Color
|
||||
* @uiDefault CheckBox.icon.indeterminateBorderColor Color optional; defaults to CheckBox.icon.selectedBorderColor
|
||||
* @uiDefault CheckBox.icon.indeterminateBackground Color optional; defaults to CheckBox.icon.selectedBackground
|
||||
* @uiDefault CheckBox.icon.indeterminateCheckmarkColor Color optional; defaults to CheckBox.icon.checkmarkColor
|
||||
*
|
||||
* @uiDefault CheckBox.icon.disabledBorderColor Color
|
||||
* @uiDefault CheckBox.icon.disabledBackground Color
|
||||
* @uiDefault CheckBox.icon.disabledSelectedBorderColor Color optional; CheckBox.icon.disabledBorderColor is used if not specified
|
||||
* @uiDefault CheckBox.icon.disabledSelectedBackground Color optional; CheckBox.icon.disabledBackground is used if not specified
|
||||
* @uiDefault CheckBox.icon.disabledCheckmarkColor Color
|
||||
* @uiDefault CheckBox.icon.disabledBorderColor Color
|
||||
* @uiDefault CheckBox.icon.disabledBackground Color
|
||||
* @uiDefault CheckBox.icon.disabledSelectedBorderColor Color optional; defaults to CheckBox.icon.disabledBorderColor
|
||||
* @uiDefault CheckBox.icon.disabledSelectedBackground Color optional; defaults to CheckBox.icon.disabledBackground
|
||||
* @uiDefault CheckBox.icon.disabledCheckmarkColor Color
|
||||
* @uiDefault CheckBox.icon.disabledIndeterminateBorderColor Color optional; defaults to CheckBox.icon.disabledSelectedBorderColor
|
||||
* @uiDefault CheckBox.icon.disabledIndeterminateBackground Color optional; defaults to CheckBox.icon.disabledSelectedBackground
|
||||
* @uiDefault CheckBox.icon.disabledIndeterminateCheckmarkColor Color optional; defaults to CheckBox.icon.disabledCheckmarkColor
|
||||
*
|
||||
* @uiDefault CheckBox.icon.focusedBorderColor Color optional
|
||||
* @uiDefault CheckBox.icon.focusedBackground Color optional
|
||||
* @uiDefault CheckBox.icon.focusedSelectedBorderColor Color optional; CheckBox.icon.focusedBorderColor is used if not specified
|
||||
* @uiDefault CheckBox.icon.focusedSelectedBackground Color optional; CheckBox.icon.focusedBackground is used if not specified
|
||||
* @uiDefault CheckBox.icon.focusedCheckmarkColor Color optional; CheckBox.icon.checkmarkColor is used if not specified
|
||||
* @uiDefault CheckBox.icon.focusedBorderColor Color optional
|
||||
* @uiDefault CheckBox.icon.focusedBackground Color optional
|
||||
* @uiDefault CheckBox.icon.focusedSelectedBorderColor Color optional; defaults to CheckBox.icon.focusedBorderColor
|
||||
* @uiDefault CheckBox.icon.focusedSelectedBackground Color optional; defaults to CheckBox.icon.focusedBackground
|
||||
* @uiDefault CheckBox.icon.focusedCheckmarkColor Color optional; defaults to CheckBox.icon.checkmarkColor
|
||||
* @uiDefault CheckBox.icon.focusedIndeterminateBorderColor Color optional; defaults to CheckBox.icon.focusedSelectedBorderColor
|
||||
* @uiDefault CheckBox.icon.focusedIndeterminateBackground Color optional; defaults to CheckBox.icon.focusedSelectedBackground
|
||||
* @uiDefault CheckBox.icon.focusedIndeterminateCheckmarkColor Color optional; defaults to CheckBox.icon.focusedCheckmarkColor
|
||||
*
|
||||
* @uiDefault CheckBox.icon.hoverBorderColor Color optional
|
||||
* @uiDefault CheckBox.icon.hoverBackground Color optional
|
||||
* @uiDefault CheckBox.icon.hoverSelectedBorderColor Color optional; CheckBox.icon.hoverBorderColor is used if not specified
|
||||
* @uiDefault CheckBox.icon.hoverSelectedBackground Color optional; CheckBox.icon.hoverBackground is used if not specified
|
||||
* @uiDefault CheckBox.icon.hoverCheckmarkColor Color optional; CheckBox.icon.checkmarkColor is used if not specified
|
||||
* @uiDefault CheckBox.icon.hoverBorderColor Color optional
|
||||
* @uiDefault CheckBox.icon.hoverBackground Color optional
|
||||
* @uiDefault CheckBox.icon.hoverSelectedBorderColor Color optional; defaults to CheckBox.icon.hoverBorderColor
|
||||
* @uiDefault CheckBox.icon.hoverSelectedBackground Color optional; defaults to CheckBox.icon.hoverBackground
|
||||
* @uiDefault CheckBox.icon.hoverCheckmarkColor Color optional; defaults to CheckBox.icon.checkmarkColor
|
||||
* @uiDefault CheckBox.icon.hoverIndeterminateBorderColor Color optional; defaults to CheckBox.icon.hoverSelectedBorderColor
|
||||
* @uiDefault CheckBox.icon.hoverIndeterminateBackground Color optional; defaults to CheckBox.icon.hoverSelectedBackground
|
||||
* @uiDefault CheckBox.icon.hoverIndeterminateCheckmarkColor Color optional; defaults to CheckBox.icon.hoverCheckmarkColor
|
||||
*
|
||||
* @uiDefault CheckBox.icon.pressedBorderColor Color optional
|
||||
* @uiDefault CheckBox.icon.pressedBackground Color optional
|
||||
* @uiDefault CheckBox.icon.pressedSelectedBorderColor Color optional; CheckBox.icon.pressedBorderColor is used if not specified
|
||||
* @uiDefault CheckBox.icon.pressedSelectedBackground Color optional; CheckBox.icon.pressedBackground is used if not specified
|
||||
* @uiDefault CheckBox.icon.pressedCheckmarkColor Color optional; CheckBox.icon.checkmarkColor is used if not specified
|
||||
* @uiDefault CheckBox.icon.pressedBorderColor Color optional
|
||||
* @uiDefault CheckBox.icon.pressedBackground Color optional
|
||||
* @uiDefault CheckBox.icon.pressedSelectedBorderColor Color optional; defaults to CheckBox.icon.pressedBorderColor
|
||||
* @uiDefault CheckBox.icon.pressedSelectedBackground Color optional; defaults to CheckBox.icon.pressedBackground
|
||||
* @uiDefault CheckBox.icon.pressedCheckmarkColor Color optional; defaults to CheckBox.icon.checkmarkColor
|
||||
* @uiDefault CheckBox.icon.pressedIndeterminateBorderColor Color optional; defaults to CheckBox.icon.pressedSelectedBorderColor
|
||||
* @uiDefault CheckBox.icon.pressedIndeterminateBackground Color optional; defaults to CheckBox.icon.pressedSelectedBackground
|
||||
* @uiDefault CheckBox.icon.pressedIndeterminateCheckmarkColor Color optional; defaults to CheckBox.icon.pressedCheckmarkColor
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
@@ -92,6 +110,8 @@ public class FlatCheckBoxIcon
|
||||
/** @since 2 */ @Styleable protected float borderWidth = getUIFloat( "CheckBox.icon.borderWidth", FlatUIUtils.getUIFloat( "Component.borderWidth", 1 ), style );
|
||||
/** @since 2 */ @Styleable protected float selectedBorderWidth = getUIFloat( "CheckBox.icon.selectedBorderWidth", Float.MIN_VALUE, style );
|
||||
/** @since 2 */ @Styleable protected float disabledSelectedBorderWidth = getUIFloat( "CheckBox.icon.disabledSelectedBorderWidth", Float.MIN_VALUE, style );
|
||||
/** @since 3.6 */ @Styleable protected float indeterminateBorderWidth = getUIFloat( "CheckBox.icon.indeterminateBorderWidth", Float.MIN_VALUE, style );
|
||||
/** @since 3.6 */ @Styleable protected float disabledIndeterminateBorderWidth = getUIFloat( "CheckBox.icon.disabledIndeterminateBorderWidth", Float.MIN_VALUE, style );
|
||||
@Styleable protected int arc = FlatUIUtils.getUIInt( "CheckBox.arc", 2 );
|
||||
|
||||
// enabled
|
||||
@@ -100,6 +120,9 @@ public class FlatCheckBoxIcon
|
||||
@Styleable protected Color selectedBorderColor = getUIColor( "CheckBox.icon.selectedBorderColor", style );
|
||||
@Styleable protected Color selectedBackground = getUIColor( "CheckBox.icon.selectedBackground", style );
|
||||
@Styleable protected Color checkmarkColor = getUIColor( "CheckBox.icon.checkmarkColor", style );
|
||||
/** @since 3.6 */ @Styleable protected Color indeterminateBorderColor = getUIColor( "CheckBox.icon.indeterminateBorderColor", style );
|
||||
/** @since 3.6 */ @Styleable protected Color indeterminateBackground = getUIColor( "CheckBox.icon.indeterminateBackground", style );
|
||||
/** @since 3.6 */ @Styleable protected Color indeterminateCheckmarkColor = getUIColor( "CheckBox.icon.indeterminateCheckmarkColor", style );
|
||||
|
||||
// disabled
|
||||
@Styleable protected Color disabledBorderColor = getUIColor( "CheckBox.icon.disabledBorderColor", style );
|
||||
@@ -107,6 +130,9 @@ public class FlatCheckBoxIcon
|
||||
/** @since 2 */ @Styleable protected Color disabledSelectedBorderColor = getUIColor( "CheckBox.icon.disabledSelectedBorderColor", style );
|
||||
/** @since 2 */ @Styleable protected Color disabledSelectedBackground = getUIColor( "CheckBox.icon.disabledSelectedBackground", style );
|
||||
@Styleable protected Color disabledCheckmarkColor = getUIColor( "CheckBox.icon.disabledCheckmarkColor", style );
|
||||
/** @since 3.6 */ @Styleable protected Color disabledIndeterminateBorderColor = getUIColor( "CheckBox.icon.disabledIndeterminateBorderColor", style );
|
||||
/** @since 3.6 */ @Styleable protected Color disabledIndeterminateBackground = getUIColor( "CheckBox.icon.disabledIndeterminateBackground", style );
|
||||
/** @since 3.6 */ @Styleable protected Color disabledIndeterminateCheckmarkColor = getUIColor( "CheckBox.icon.disabledIndeterminateCheckmarkColor", style );
|
||||
|
||||
// focused
|
||||
@Styleable protected Color focusedBorderColor = getUIColor( "CheckBox.icon.focusedBorderColor", style );
|
||||
@@ -114,6 +140,9 @@ public class FlatCheckBoxIcon
|
||||
/** @since 2 */ @Styleable protected Color focusedSelectedBorderColor = getUIColor( "CheckBox.icon.focusedSelectedBorderColor", style );
|
||||
/** @since 2 */ @Styleable protected Color focusedSelectedBackground = getUIColor( "CheckBox.icon.focusedSelectedBackground", style );
|
||||
/** @since 2 */ @Styleable protected Color focusedCheckmarkColor = getUIColor( "CheckBox.icon.focusedCheckmarkColor", style );
|
||||
/** @since 3.6 */ @Styleable protected Color focusedIndeterminateBorderColor = getUIColor( "CheckBox.icon.focusedIndeterminateBorderColor", style );
|
||||
/** @since 3.6 */ @Styleable protected Color focusedIndeterminateBackground = getUIColor( "CheckBox.icon.focusedIndeterminateBackground", style );
|
||||
/** @since 3.6 */ @Styleable protected Color focusedIndeterminateCheckmarkColor = getUIColor( "CheckBox.icon.focusedIndeterminateCheckmarkColor", style );
|
||||
|
||||
// hover
|
||||
@Styleable protected Color hoverBorderColor = getUIColor( "CheckBox.icon.hoverBorderColor", style );
|
||||
@@ -121,6 +150,9 @@ public class FlatCheckBoxIcon
|
||||
/** @since 2 */ @Styleable protected Color hoverSelectedBorderColor = getUIColor( "CheckBox.icon.hoverSelectedBorderColor", style );
|
||||
/** @since 2 */ @Styleable protected Color hoverSelectedBackground = getUIColor( "CheckBox.icon.hoverSelectedBackground", style );
|
||||
/** @since 2 */ @Styleable protected Color hoverCheckmarkColor = getUIColor( "CheckBox.icon.hoverCheckmarkColor", style );
|
||||
/** @since 3.6 */ @Styleable protected Color hoverIndeterminateBorderColor = getUIColor( "CheckBox.icon.hoverIndeterminateBorderColor", style );
|
||||
/** @since 3.6 */ @Styleable protected Color hoverIndeterminateBackground = getUIColor( "CheckBox.icon.hoverIndeterminateBackground", style );
|
||||
/** @since 3.6 */ @Styleable protected Color hoverIndeterminateCheckmarkColor = getUIColor( "CheckBox.icon.hoverIndeterminateCheckmarkColor", style );
|
||||
|
||||
// pressed
|
||||
/** @since 2 */ @Styleable protected Color pressedBorderColor = getUIColor( "CheckBox.icon.pressedBorderColor", style );
|
||||
@@ -128,6 +160,9 @@ public class FlatCheckBoxIcon
|
||||
/** @since 2 */ @Styleable protected Color pressedSelectedBorderColor = getUIColor( "CheckBox.icon.pressedSelectedBorderColor", style );
|
||||
/** @since 2 */ @Styleable protected Color pressedSelectedBackground = getUIColor( "CheckBox.icon.pressedSelectedBackground", style );
|
||||
/** @since 2 */ @Styleable protected Color pressedCheckmarkColor = getUIColor( "CheckBox.icon.pressedCheckmarkColor", style );
|
||||
/** @since 3.6 */ @Styleable protected Color pressedIndeterminateBorderColor = getUIColor( "CheckBox.icon.pressedIndeterminateBorderColor", style );
|
||||
/** @since 3.6 */ @Styleable protected Color pressedIndeterminateBackground = getUIColor( "CheckBox.icon.pressedIndeterminateBackground", style );
|
||||
/** @since 3.6 */ @Styleable protected Color pressedIndeterminateCheckmarkColor = getUIColor( "CheckBox.icon.pressedIndeterminateCheckmarkColor", style );
|
||||
|
||||
protected String getPropertyPrefix() {
|
||||
return "CheckBox.";
|
||||
@@ -182,11 +217,17 @@ public class FlatCheckBoxIcon
|
||||
boolean indeterminate = isIndeterminate( c );
|
||||
boolean selected = indeterminate || isSelected( c );
|
||||
boolean isFocused = FlatUIUtils.isPermanentFocusOwner( c );
|
||||
float bw = selected
|
||||
? (disabledSelectedBorderWidth != Float.MIN_VALUE && !c.isEnabled()
|
||||
? disabledSelectedBorderWidth
|
||||
: (selectedBorderWidth != Float.MIN_VALUE ? selectedBorderWidth : borderWidth))
|
||||
: borderWidth;
|
||||
float bw = Float.MIN_VALUE;
|
||||
if( !c.isEnabled() ) {
|
||||
bw = (indeterminate && disabledIndeterminateBorderWidth != Float.MIN_VALUE)
|
||||
? disabledIndeterminateBorderWidth
|
||||
: (selected ? disabledSelectedBorderWidth : selectedBorderWidth);
|
||||
}
|
||||
if( bw == Float.MIN_VALUE ) {
|
||||
bw = (indeterminate && indeterminateBorderWidth != Float.MIN_VALUE)
|
||||
? indeterminateBorderWidth
|
||||
: ((selected && selectedBorderWidth != Float.MIN_VALUE) ? selectedBorderWidth : borderWidth);
|
||||
}
|
||||
|
||||
// paint focused border
|
||||
if( isFocused && focusWidth > 0 && FlatButtonUI.isFocusPainted( c ) ) {
|
||||
@@ -195,15 +236,15 @@ public class FlatCheckBoxIcon
|
||||
}
|
||||
|
||||
// paint border
|
||||
g.setColor( getBorderColor( c, selected ) );
|
||||
g.setColor( getBorderColor( c, selected, indeterminate ) );
|
||||
paintBorder( c, g, bw );
|
||||
|
||||
// paint background
|
||||
Color bg = FlatUIUtils.deriveColor( getBackground( c, selected ),
|
||||
selected ? selectedBackground : background );
|
||||
Color baseBg = stateColor( indeterminate, indeterminateBackground, selected, selectedBackground, background );
|
||||
Color bg = FlatUIUtils.deriveColor( getBackground( c, selected, indeterminate ), baseBg );
|
||||
if( bg.getAlpha() < 255 ) {
|
||||
// fill background with default color before filling with non-opaque background
|
||||
g.setColor( selected ? selectedBackground : background );
|
||||
g.setColor( baseBg );
|
||||
paintBackground( c, g, bw );
|
||||
}
|
||||
g.setColor( bg );
|
||||
@@ -211,7 +252,7 @@ public class FlatCheckBoxIcon
|
||||
|
||||
// paint checkmark
|
||||
if( selected ) {
|
||||
g.setColor( getCheckmarkColor( c ) );
|
||||
g.setColor( getCheckmarkColor( c, indeterminate ) );
|
||||
if( indeterminate )
|
||||
paintIndeterminate( c, g );
|
||||
else
|
||||
@@ -272,30 +313,33 @@ public class FlatCheckBoxIcon
|
||||
return focusColor;
|
||||
}
|
||||
|
||||
protected Color getBorderColor( Component c, boolean selected ) {
|
||||
/** @since 3.6 */
|
||||
protected Color getBorderColor( Component c, boolean selected, boolean indeterminate ) {
|
||||
return FlatButtonUI.buttonStateColor( c,
|
||||
selected ? selectedBorderColor : borderColor,
|
||||
(selected && disabledSelectedBorderColor != null) ? disabledSelectedBorderColor : disabledBorderColor,
|
||||
(selected && focusedSelectedBorderColor != null) ? focusedSelectedBorderColor : focusedBorderColor,
|
||||
(selected && hoverSelectedBorderColor != null) ? hoverSelectedBorderColor : hoverBorderColor,
|
||||
(selected && pressedSelectedBorderColor != null) ? pressedSelectedBorderColor : pressedBorderColor );
|
||||
stateColor( indeterminate, indeterminateBorderColor, selected, selectedBorderColor, borderColor ),
|
||||
stateColor( indeterminate, disabledIndeterminateBorderColor, selected, disabledSelectedBorderColor, disabledBorderColor ),
|
||||
stateColor( indeterminate, focusedIndeterminateBorderColor, selected, focusedSelectedBorderColor, focusedBorderColor ),
|
||||
stateColor( indeterminate, hoverIndeterminateBorderColor, selected, hoverSelectedBorderColor, hoverBorderColor ),
|
||||
stateColor( indeterminate, pressedIndeterminateBorderColor, selected, pressedSelectedBorderColor, pressedBorderColor ) );
|
||||
}
|
||||
|
||||
protected Color getBackground( Component c, boolean selected ) {
|
||||
/** @since 3.6 */
|
||||
protected Color getBackground( Component c, boolean selected, boolean indeterminate ) {
|
||||
return FlatButtonUI.buttonStateColor( c,
|
||||
selected ? selectedBackground : background,
|
||||
(selected && disabledSelectedBackground != null) ? disabledSelectedBackground : disabledBackground,
|
||||
(selected && focusedSelectedBackground != null) ? focusedSelectedBackground : focusedBackground,
|
||||
(selected && hoverSelectedBackground != null) ? hoverSelectedBackground : hoverBackground,
|
||||
(selected && pressedSelectedBackground != null) ? pressedSelectedBackground : pressedBackground );
|
||||
stateColor( indeterminate, indeterminateBackground, selected, selectedBackground, background ),
|
||||
stateColor( indeterminate, disabledIndeterminateBackground, selected, disabledSelectedBackground, disabledBackground ),
|
||||
stateColor( indeterminate, focusedIndeterminateBackground, selected, focusedSelectedBackground, focusedBackground ),
|
||||
stateColor( indeterminate, hoverIndeterminateBackground, selected, hoverSelectedBackground, hoverBackground ),
|
||||
stateColor( indeterminate, pressedIndeterminateBackground, selected, pressedSelectedBackground, pressedBackground ) );
|
||||
}
|
||||
|
||||
protected Color getCheckmarkColor( Component c ) {
|
||||
/** @since 3.6 */
|
||||
protected Color getCheckmarkColor( Component c, boolean indeterminate ) {
|
||||
return FlatButtonUI.buttonStateColor( c,
|
||||
checkmarkColor,
|
||||
disabledCheckmarkColor,
|
||||
focusedCheckmarkColor,
|
||||
hoverCheckmarkColor,
|
||||
pressedCheckmarkColor );
|
||||
stateColor( indeterminate, indeterminateCheckmarkColor, checkmarkColor ),
|
||||
stateColor( indeterminate, disabledIndeterminateCheckmarkColor, disabledCheckmarkColor ),
|
||||
stateColor( indeterminate, focusedIndeterminateCheckmarkColor, focusedCheckmarkColor ),
|
||||
stateColor( indeterminate, hoverIndeterminateCheckmarkColor, hoverCheckmarkColor ),
|
||||
stateColor( indeterminate, pressedIndeterminateCheckmarkColor, pressedCheckmarkColor ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,44 +18,95 @@ package com.formdev.flatlaf.icons;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.RenderingHints;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Window;
|
||||
import javax.swing.SwingUtilities;
|
||||
import com.formdev.flatlaf.ui.FlatButtonUI;
|
||||
import com.formdev.flatlaf.ui.FlatTitlePane;
|
||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
import com.formdev.flatlaf.util.DerivedColor;
|
||||
import com.formdev.flatlaf.util.HiDPIUtils;
|
||||
import com.formdev.flatlaf.util.UIScale;
|
||||
|
||||
/**
|
||||
* Base class for window icons.
|
||||
*
|
||||
* @uiDefault TitlePane.buttonSize Dimension
|
||||
* @uiDefault TitlePane.buttonInsets Insets optional
|
||||
* @uiDefault TitlePane.buttonArc int optional
|
||||
* @uiDefault TitlePane.buttonSymbolHeight int
|
||||
* @uiDefault TitlePane.buttonHoverBackground Color
|
||||
* @uiDefault TitlePane.buttonPressedBackground Color
|
||||
* @uiDefault TitlePane.buttonBackground Color optional
|
||||
* @uiDefault TitlePane.buttonForeground Color optional
|
||||
* @uiDefault TitlePane.buttonInactiveBackground Color optional
|
||||
* @uiDefault TitlePane.buttonInactiveForeground Color optional
|
||||
* @uiDefault TitlePane.buttonHoverBackground Color optional
|
||||
* @uiDefault TitlePane.buttonHoverForeground Color optional
|
||||
* @uiDefault TitlePane.buttonPressedBackground Color optional
|
||||
* @uiDefault TitlePane.buttonPressedForeground Color optional
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public abstract class FlatWindowAbstractIcon
|
||||
extends FlatAbstractIcon
|
||||
{
|
||||
private final int symbolHeight;
|
||||
private final Color hoverBackground;
|
||||
private final Color pressedBackground;
|
||||
/** @since 3.6 */ protected final Insets insets;
|
||||
/** @since 3.6 */ protected final int arc;
|
||||
/** @since 3.6 */ protected final int symbolHeight;
|
||||
|
||||
/** @since 3.6 */ protected final Color background;
|
||||
/** @since 3.6 */ protected final Color foreground;
|
||||
/** @since 3.6 */ protected final Color inactiveBackground;
|
||||
/** @since 3.6 */ protected final Color inactiveForeground;
|
||||
protected final Color hoverBackground;
|
||||
/** @since 3.6 */ protected final Color hoverForeground;
|
||||
protected final Color pressedBackground;
|
||||
/** @since 3.6 */ protected final Color pressedForeground;
|
||||
|
||||
/** @since 3.2 */
|
||||
protected FlatWindowAbstractIcon( String windowStyle ) {
|
||||
this( FlatUIUtils.getSubUIDimension( "TitlePane.buttonSize", windowStyle ),
|
||||
FlatUIUtils.getSubUIInt( "TitlePane.buttonSymbolHeight", windowStyle, 10 ),
|
||||
FlatUIUtils.getSubUIColor( "TitlePane.buttonHoverBackground", windowStyle ),
|
||||
FlatUIUtils.getSubUIColor( "TitlePane.buttonPressedBackground", windowStyle ) );
|
||||
this( windowStyle, null, null, null, null, null, null, null, null );
|
||||
}
|
||||
|
||||
/** @since 3.2 */
|
||||
protected FlatWindowAbstractIcon( Dimension size, int symbolHeight, Color hoverBackground, Color pressedBackground ) {
|
||||
/** @since 3.6 */
|
||||
protected FlatWindowAbstractIcon( String windowStyle,
|
||||
Color background, Color foreground, Color inactiveBackground, Color inactiveForeground,
|
||||
Color hoverBackground, Color hoverForeground, Color pressedBackground, Color pressedForeground )
|
||||
{
|
||||
this( FlatUIUtils.getSubUIDimension( "TitlePane.buttonSize", windowStyle ),
|
||||
FlatUIUtils.getSubUIInsets( "TitlePane.buttonInsets", windowStyle ),
|
||||
FlatUIUtils.getSubUIInt( "TitlePane.buttonArc", windowStyle, 0 ),
|
||||
FlatUIUtils.getSubUIInt( "TitlePane.buttonSymbolHeight", windowStyle, 10 ),
|
||||
(background != null) ? background : FlatUIUtils.getSubUIColor( "TitlePane.buttonBackground", windowStyle ),
|
||||
(foreground != null) ? foreground : FlatUIUtils.getSubUIColor( "TitlePane.buttonForeground", windowStyle ),
|
||||
(inactiveBackground != null) ? inactiveBackground : FlatUIUtils.getSubUIColor( "TitlePane.buttonInactiveBackground", windowStyle ),
|
||||
(inactiveForeground != null) ? inactiveForeground : FlatUIUtils.getSubUIColor( "TitlePane.buttonInactiveForeground", windowStyle ),
|
||||
(hoverBackground != null) ? hoverBackground : FlatUIUtils.getSubUIColor( "TitlePane.buttonHoverBackground", windowStyle ),
|
||||
(hoverForeground != null) ? hoverForeground : FlatUIUtils.getSubUIColor( "TitlePane.buttonHoverForeground", windowStyle ),
|
||||
(pressedBackground != null) ? pressedBackground : FlatUIUtils.getSubUIColor( "TitlePane.buttonPressedBackground", windowStyle ),
|
||||
(pressedForeground != null) ? pressedForeground : FlatUIUtils.getSubUIColor( "TitlePane.buttonPressedForeground", windowStyle ) );
|
||||
}
|
||||
|
||||
/** @since 3.6 */
|
||||
protected FlatWindowAbstractIcon( Dimension size, Insets insets, int arc, int symbolHeight,
|
||||
Color background, Color foreground, Color inactiveBackground, Color inactiveForeground,
|
||||
Color hoverBackground, Color hoverForeground, Color pressedBackground, Color pressedForeground )
|
||||
{
|
||||
super( size.width, size.height, null );
|
||||
this.insets = (insets != null) ? insets : new Insets( 0, 0, 0, 0 );
|
||||
this.arc = arc;
|
||||
this.symbolHeight = symbolHeight;
|
||||
|
||||
this.background = background;
|
||||
this.foreground = foreground;
|
||||
this.inactiveBackground = inactiveBackground;
|
||||
this.inactiveForeground = inactiveForeground;
|
||||
this.hoverBackground = hoverBackground;
|
||||
this.hoverForeground = hoverForeground;
|
||||
this.pressedBackground = pressedBackground;
|
||||
this.pressedForeground = pressedForeground;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -69,26 +120,39 @@ public abstract class FlatWindowAbstractIcon
|
||||
/** @since 3.5.2 */
|
||||
@Override
|
||||
protected void paintBackground( Component c, Graphics2D g, int x, int y ) {
|
||||
Color background = FlatButtonUI.buttonStateColor( c, null, null, null, hoverBackground, pressedBackground );
|
||||
Color bg = null;
|
||||
if( background != null || inactiveBackground != null ) {
|
||||
Window window = SwingUtilities.windowForComponent( c );
|
||||
bg = (window == null || window.isActive()) ? background : inactiveBackground;
|
||||
}
|
||||
|
||||
Color background = FlatButtonUI.buttonStateColor( c, bg, null, null, hoverBackground, pressedBackground );
|
||||
if( background != null ) {
|
||||
// disable antialiasing for background rectangle painting to avoid blurry edges when scaled (e.g. at 125% or 175%)
|
||||
Object oldHint = g.getRenderingHint( RenderingHints.KEY_ANTIALIASING );
|
||||
g.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF );
|
||||
Insets insets = UIScale.scale( this.insets );
|
||||
float arc = UIScale.scale( (float) this.arc );
|
||||
|
||||
// fill background of whole component
|
||||
g.setColor( FlatUIUtils.deriveColor( background, c.getBackground() ) );
|
||||
g.fillRect( 0, 0, c.getWidth(), c.getHeight() );
|
||||
// derive color from title pane background
|
||||
if( background instanceof DerivedColor ) {
|
||||
Container titlePane = SwingUtilities.getAncestorOfClass( FlatTitlePane.class, c );
|
||||
Component baseComp = (titlePane != null) ? titlePane : c;
|
||||
background = FlatUIUtils.deriveColor( background, baseComp.getBackground() );
|
||||
}
|
||||
|
||||
g.setRenderingHint( RenderingHints.KEY_ANTIALIASING, oldHint );
|
||||
g.setColor( background );
|
||||
FlatUIUtils.paintComponentBackground( g, insets.left, insets.top,
|
||||
c.getWidth() - insets.left - insets.right,
|
||||
c.getHeight() - insets.top - insets.bottom,
|
||||
0, arc );
|
||||
}
|
||||
}
|
||||
|
||||
protected Color getForeground( Component c ) {
|
||||
return c.getForeground();
|
||||
}
|
||||
|
||||
/** @since 3.2 */
|
||||
protected int getSymbolHeight() {
|
||||
return symbolHeight;
|
||||
Color fg = null;
|
||||
if( foreground != null || inactiveForeground != null ) {
|
||||
Window window = SwingUtilities.windowForComponent( c );
|
||||
fg = (window == null || window.isActive()) ? foreground : inactiveForeground;
|
||||
}
|
||||
return FlatButtonUI.buttonStateColor( c, (fg != null) ? fg : c.getForeground(),
|
||||
null, null, hoverForeground, pressedForeground );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,53 +17,54 @@
|
||||
package com.formdev.flatlaf.icons;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.geom.Path2D;
|
||||
import com.formdev.flatlaf.ui.FlatButtonUI;
|
||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
import com.formdev.flatlaf.util.SystemInfo;
|
||||
|
||||
/**
|
||||
* "close" icon for windows (frames and dialogs).
|
||||
*
|
||||
* @uiDefault TitlePane.closeHoverBackground Color
|
||||
* @uiDefault TitlePane.closePressedBackground Color
|
||||
* @uiDefault TitlePane.closeHoverForeground Color
|
||||
* @uiDefault TitlePane.closePressedForeground Color
|
||||
* @uiDefault TitlePane.closeBackground Color optional
|
||||
* @uiDefault TitlePane.closeForeground Color optional
|
||||
* @uiDefault TitlePane.closeInactiveBackground Color optional
|
||||
* @uiDefault TitlePane.closeInactiveForeground Color optional
|
||||
* @uiDefault TitlePane.closeHoverBackground Color optional
|
||||
* @uiDefault TitlePane.closeHoverForeground Color optional
|
||||
* @uiDefault TitlePane.closePressedBackground Color optional
|
||||
* @uiDefault TitlePane.closePressedForeground Color optional
|
||||
*
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class FlatWindowCloseIcon
|
||||
extends FlatWindowAbstractIcon
|
||||
{
|
||||
private final Color hoverForeground;
|
||||
private final Color pressedForeground;
|
||||
|
||||
public FlatWindowCloseIcon() {
|
||||
this( null );
|
||||
}
|
||||
|
||||
/** @since 3.2 */
|
||||
public FlatWindowCloseIcon( String windowStyle ) {
|
||||
super( FlatUIUtils.getSubUIDimension( "TitlePane.buttonSize", windowStyle ),
|
||||
FlatUIUtils.getSubUIInt( "TitlePane.buttonSymbolHeight", windowStyle, 10 ),
|
||||
super( windowStyle,
|
||||
FlatUIUtils.getSubUIColor( "TitlePane.closeBackground", windowStyle ),
|
||||
FlatUIUtils.getSubUIColor( "TitlePane.closeForeground", windowStyle ),
|
||||
FlatUIUtils.getSubUIColor( "TitlePane.closeInactiveBackground", windowStyle ),
|
||||
FlatUIUtils.getSubUIColor( "TitlePane.closeInactiveForeground", windowStyle ),
|
||||
FlatUIUtils.getSubUIColor( "TitlePane.closeHoverBackground", windowStyle ),
|
||||
FlatUIUtils.getSubUIColor( "TitlePane.closePressedBackground", windowStyle ) );
|
||||
|
||||
hoverForeground = FlatUIUtils.getSubUIColor( "TitlePane.closeHoverForeground", windowStyle );
|
||||
pressedForeground = FlatUIUtils.getSubUIColor( "TitlePane.closePressedForeground", windowStyle );
|
||||
FlatUIUtils.getSubUIColor( "TitlePane.closeHoverForeground", windowStyle ),
|
||||
FlatUIUtils.getSubUIColor( "TitlePane.closePressedBackground", windowStyle ),
|
||||
FlatUIUtils.getSubUIColor( "TitlePane.closePressedForeground", windowStyle ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void paintIconAt1x( Graphics2D g, int x, int y, int width, int height, double scaleFactor ) {
|
||||
int iwh = (int) (getSymbolHeight() * scaleFactor);
|
||||
int iwh = (int) (symbolHeight * scaleFactor);
|
||||
int ix = x + ((width - iwh) / 2);
|
||||
int iy = y + ((height - iwh) / 2);
|
||||
int ix2 = ix + iwh - 1;
|
||||
int iy2 = iy + iwh - 1;
|
||||
float thickness = SystemInfo.isWindows_11_orLater ? (float) scaleFactor : (int) scaleFactor;
|
||||
boolean isWindows10 = SystemInfo.isWindows_10_orLater && !SystemInfo.isWindows_11_orLater;
|
||||
float thickness = Math.max( isWindows10 ? (int) scaleFactor : (float) scaleFactor, 1 );
|
||||
|
||||
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD, 4 );
|
||||
path.moveTo( ix, iy );
|
||||
@@ -73,9 +74,4 @@ public class FlatWindowCloseIcon
|
||||
g.setStroke( new BasicStroke( thickness ) );
|
||||
g.draw( path );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Color getForeground( Component c ) {
|
||||
return FlatButtonUI.buttonStateColor( c, c.getForeground(), null, null, hoverForeground, pressedForeground );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,8 +37,8 @@ public class FlatWindowIconifyIcon
|
||||
|
||||
@Override
|
||||
protected void paintIconAt1x( Graphics2D g, int x, int y, int width, int height, double scaleFactor ) {
|
||||
int iw = (int) (getSymbolHeight() * scaleFactor);
|
||||
int ih = (int) scaleFactor;
|
||||
int iw = (int) (symbolHeight * scaleFactor);
|
||||
int ih = Math.max( (int) scaleFactor, 1 );
|
||||
int ix = x + ((width - iw) / 2);
|
||||
int iy = y + ((height - ih) / 2);
|
||||
|
||||
|
||||
@@ -39,10 +39,11 @@ public class FlatWindowMaximizeIcon
|
||||
|
||||
@Override
|
||||
protected void paintIconAt1x( Graphics2D g, int x, int y, int width, int height, double scaleFactor ) {
|
||||
int iwh = (int) (getSymbolHeight() * scaleFactor);
|
||||
int iwh = (int) (symbolHeight * scaleFactor);
|
||||
int ix = x + ((width - iwh) / 2);
|
||||
int iy = y + ((height - iwh) / 2);
|
||||
float thickness = SystemInfo.isWindows_11_orLater ? (float) scaleFactor : (int) scaleFactor;
|
||||
boolean isWindows10 = SystemInfo.isWindows_10_orLater && !SystemInfo.isWindows_11_orLater;
|
||||
float thickness = Math.max( isWindows10 ? (int) scaleFactor : (float) scaleFactor, 1 );
|
||||
int arc = Math.max( (int) (1.5 * scaleFactor), 2 );
|
||||
|
||||
g.fill( SystemInfo.isWindows_11_orLater
|
||||
|
||||
@@ -42,14 +42,15 @@ public class FlatWindowRestoreIcon
|
||||
|
||||
@Override
|
||||
protected void paintIconAt1x( Graphics2D g, int x, int y, int width, int height, double scaleFactor ) {
|
||||
int iwh = (int) (getSymbolHeight() * scaleFactor);
|
||||
int iwh = (int) (symbolHeight * scaleFactor);
|
||||
int ix = x + ((width - iwh) / 2);
|
||||
int iy = y + ((height - iwh) / 2);
|
||||
float thickness = SystemInfo.isWindows_11_orLater ? (float) scaleFactor : (int) scaleFactor;
|
||||
boolean isWindows10 = SystemInfo.isWindows_10_orLater && !SystemInfo.isWindows_11_orLater;
|
||||
float thickness = Math.max( isWindows10 ? (int) scaleFactor : (float) scaleFactor, 1 );
|
||||
int arc = Math.max( (int) (1.5 * scaleFactor), 2 );
|
||||
int arcOuter = (int) (arc + (1.5 * scaleFactor));
|
||||
|
||||
int rwh = (int) ((getSymbolHeight() - 2) * scaleFactor);
|
||||
int rwh = (int) ((symbolHeight - 2) * scaleFactor);
|
||||
int ro2 = iwh - rwh;
|
||||
|
||||
// upper-right rectangle
|
||||
|
||||
@@ -59,6 +59,8 @@ import com.formdev.flatlaf.util.DerivedColor;
|
||||
* @uiDefault Component.error.focusedBorderColor Color
|
||||
* @uiDefault Component.warning.borderColor Color
|
||||
* @uiDefault Component.warning.focusedBorderColor Color
|
||||
* @uiDefault Component.success.borderColor Color
|
||||
* @uiDefault Component.success.focusedBorderColor Color
|
||||
* @uiDefault Component.custom.borderColor Color
|
||||
*
|
||||
* @author Karl Tauber
|
||||
@@ -81,6 +83,8 @@ public class FlatBorder
|
||||
@Styleable(dot=true) protected Color errorFocusedBorderColor = UIManager.getColor( "Component.error.focusedBorderColor" );
|
||||
@Styleable(dot=true) protected Color warningBorderColor = UIManager.getColor( "Component.warning.borderColor" );
|
||||
@Styleable(dot=true) protected Color warningFocusedBorderColor = UIManager.getColor( "Component.warning.focusedBorderColor" );
|
||||
/** @since 3.6 */ @Styleable(dot=true) protected Color successBorderColor = UIManager.getColor( "Component.success.borderColor" );
|
||||
/** @since 3.6 */ @Styleable(dot=true) protected Color successFocusedBorderColor = UIManager.getColor( "Component.success.focusedBorderColor" );
|
||||
@Styleable(dot=true) protected Color customBorderColor = UIManager.getColor( "Component.custom.borderColor" );
|
||||
|
||||
// only used via styling (not in UI defaults, but has likewise client properties)
|
||||
@@ -168,6 +172,9 @@ public class FlatBorder
|
||||
|
||||
case FlatClientProperties.OUTLINE_WARNING:
|
||||
return isFocused( c ) ? warningFocusedBorderColor : warningBorderColor;
|
||||
|
||||
case FlatClientProperties.OUTLINE_SUCCESS:
|
||||
return isFocused( c ) ? successFocusedBorderColor : successBorderColor;
|
||||
}
|
||||
} else if( outline instanceof Color ) {
|
||||
Color color = (Color) outline;
|
||||
|
||||
@@ -280,8 +280,6 @@ public class FlatButtonUI
|
||||
|
||||
LookAndFeel.installProperty( b, "opaque", false );
|
||||
LookAndFeel.installProperty( b, "iconTextGap", scale( iconTextGap ) );
|
||||
|
||||
MigLayoutVisualPadding.install( b );
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -291,10 +289,23 @@ public class FlatButtonUI
|
||||
oldStyleValues = null;
|
||||
borderShared = null;
|
||||
|
||||
MigLayoutVisualPadding.uninstall( b );
|
||||
defaults_initialized = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void installListeners( AbstractButton b ) {
|
||||
super.installListeners( b );
|
||||
|
||||
MigLayoutVisualPadding.install( b );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void uninstallListeners( AbstractButton b ) {
|
||||
super.uninstallListeners( b );
|
||||
|
||||
MigLayoutVisualPadding.uninstall( b );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected BasicButtonListener createButtonListener( AbstractButton b ) {
|
||||
return new FlatButtonListener( b );
|
||||
@@ -653,7 +664,8 @@ public class FlatButtonUI
|
||||
}
|
||||
|
||||
protected Color getBackground( JComponent c ) {
|
||||
boolean toolBarButton = isToolBarButton( c ) || isBorderlessButton( c );
|
||||
boolean def = isDefaultButton( c );
|
||||
boolean toolBarButton = !def && (isToolBarButton( c ) || isBorderlessButton( c ));
|
||||
|
||||
// selected state
|
||||
if( ((AbstractButton)c).isSelected() ) {
|
||||
@@ -681,7 +693,6 @@ public class FlatButtonUI
|
||||
toolbarPressedBackground );
|
||||
}
|
||||
|
||||
boolean def = isDefaultButton( c );
|
||||
return buttonStateColor( c,
|
||||
getBackgroundBase( c, def ),
|
||||
disabledBackground,
|
||||
@@ -733,7 +744,8 @@ public class FlatButtonUI
|
||||
|
||||
protected Color getForeground( JComponent c ) {
|
||||
Color fg = c.getForeground();
|
||||
boolean toolBarButton = isToolBarButton( c ) || isBorderlessButton( c );
|
||||
boolean def = isDefaultButton( c );
|
||||
boolean toolBarButton = !def && (isToolBarButton( c ) || isBorderlessButton( c ));
|
||||
|
||||
// selected state
|
||||
if( ((AbstractButton)c).isSelected() ) {
|
||||
@@ -759,7 +771,6 @@ public class FlatButtonUI
|
||||
toolbarPressedForeground );
|
||||
}
|
||||
|
||||
boolean def = isDefaultButton( c );
|
||||
return buttonStateColor( c,
|
||||
getForegroundBase( c, def ),
|
||||
disabledText,
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.formdev.flatlaf.ui;
|
||||
|
||||
import static com.formdev.flatlaf.FlatClientProperties.*;
|
||||
import java.awt.Container;
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.event.ActionEvent;
|
||||
@@ -24,7 +25,9 @@ import java.awt.event.FocusEvent;
|
||||
import java.awt.event.MouseEvent;
|
||||
import javax.swing.Action;
|
||||
import javax.swing.ActionMap;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JFormattedTextField;
|
||||
import javax.swing.JSpinner;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.plaf.UIResource;
|
||||
@@ -33,6 +36,7 @@ import javax.swing.text.DefaultCaret;
|
||||
import javax.swing.text.DefaultEditorKit;
|
||||
import javax.swing.text.Document;
|
||||
import javax.swing.text.JTextComponent;
|
||||
import javax.swing.text.Position;
|
||||
import javax.swing.text.Utilities;
|
||||
|
||||
/**
|
||||
@@ -48,12 +52,15 @@ public class FlatCaret
|
||||
{
|
||||
private static final String KEY_CARET_INFO = "FlatLaf.internal.caretInfo";
|
||||
|
||||
// selectAllOnFocusPolicy
|
||||
private static final int NEVER = 0, ONCE = 1, ALWAYS = 2;
|
||||
|
||||
private final String selectAllOnFocusPolicy;
|
||||
private final boolean selectAllOnMouseClick;
|
||||
|
||||
private boolean inInstall;
|
||||
private boolean wasFocused;
|
||||
private boolean wasTemporaryLost;
|
||||
private boolean wasFocusTemporaryLost;
|
||||
private boolean isMousePressed;
|
||||
private boolean isWordSelection;
|
||||
private boolean isLineSelection;
|
||||
@@ -94,6 +101,9 @@ public class FlatCaret
|
||||
// restore selection
|
||||
select( (int) ci[1], (int) ci[0] );
|
||||
|
||||
if( ci[4] != 0 )
|
||||
wasFocused = true;
|
||||
|
||||
// if text component is focused, then caret and selection are visible,
|
||||
// but when switching theme, the component does not yet have
|
||||
// a highlighter and the selection is not painted
|
||||
@@ -121,6 +131,7 @@ public class FlatCaret
|
||||
getMark(),
|
||||
getBlinkRate(),
|
||||
System.currentTimeMillis(),
|
||||
wasFocused ? 1 : 0,
|
||||
} );
|
||||
|
||||
super.deinstall( c );
|
||||
@@ -140,11 +151,36 @@ public class FlatCaret
|
||||
super.adjustVisibility( nloc );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDot( int dot ) {
|
||||
super.setDot( dot );
|
||||
|
||||
// mark as focused if invoked from JTextComponent.setCaretPosition()
|
||||
// to disable SELECT_ALL_ON_FOCUS_POLICY_ONCE if application explicitly changes selection
|
||||
if( !wasFocused &&
|
||||
getSelectAllOnFocusPolicy() == ONCE &&
|
||||
StackUtils.wasInvokedFrom( JTextComponent.class.getName(), "setCaretPosition", 6 ) )
|
||||
wasFocused = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moveDot( int dot ) {
|
||||
super.moveDot( dot );
|
||||
|
||||
// mark as focused if invoked from JTextComponent.moveCaretPosition()
|
||||
// to disable SELECT_ALL_ON_FOCUS_POLICY_ONCE if application explicitly changes selection
|
||||
if( !wasFocused &&
|
||||
getSelectAllOnFocusPolicy() == ONCE &&
|
||||
StackUtils.wasInvokedFrom( JTextComponent.class.getName(), "moveCaretPosition", 6 ) )
|
||||
wasFocused = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void focusGained( FocusEvent e ) {
|
||||
if( !inInstall && !wasTemporaryLost && (!isMousePressed || selectAllOnMouseClick) )
|
||||
if( !inInstall && !wasFocusTemporaryLost && (!isMousePressed || isSelectAllOnMouseClick()) )
|
||||
selectAllOnFocusGained();
|
||||
wasTemporaryLost = false;
|
||||
|
||||
wasFocusTemporaryLost = false;
|
||||
wasFocused = true;
|
||||
|
||||
super.focusGained( e );
|
||||
@@ -152,7 +188,7 @@ public class FlatCaret
|
||||
|
||||
@Override
|
||||
public void focusLost( FocusEvent e ) {
|
||||
wasTemporaryLost = e.isTemporary();
|
||||
wasFocusTemporaryLost = e.isTemporary();
|
||||
super.focusLost( e );
|
||||
}
|
||||
|
||||
@@ -232,24 +268,13 @@ public class FlatCaret
|
||||
if( doc == null || !c.isEnabled() || !c.isEditable() || FlatUIUtils.isCellEditor( c ) )
|
||||
return;
|
||||
|
||||
Object selectAllOnFocusPolicy = c.getClientProperty( SELECT_ALL_ON_FOCUS_POLICY );
|
||||
if( selectAllOnFocusPolicy == null )
|
||||
selectAllOnFocusPolicy = this.selectAllOnFocusPolicy;
|
||||
|
||||
if( selectAllOnFocusPolicy == null || SELECT_ALL_ON_FOCUS_POLICY_NEVER.equals( selectAllOnFocusPolicy ) )
|
||||
int selectAllOnFocusPolicy = getSelectAllOnFocusPolicy();
|
||||
if( selectAllOnFocusPolicy == NEVER )
|
||||
return;
|
||||
|
||||
if( !SELECT_ALL_ON_FOCUS_POLICY_ALWAYS.equals( selectAllOnFocusPolicy ) ) {
|
||||
// policy is "once" (or null or unknown)
|
||||
|
||||
if( selectAllOnFocusPolicy == ONCE && !isMousePressed ) {
|
||||
// was already focused?
|
||||
if( wasFocused )
|
||||
return;
|
||||
|
||||
// check whether selection was modified before gaining focus
|
||||
int dot = getDot();
|
||||
int mark = getMark();
|
||||
if( dot != mark || dot != doc.getLength() )
|
||||
if( wasFocused && !(c instanceof JFormattedTextField) )
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -265,16 +290,51 @@ public class FlatCaret
|
||||
|
||||
select( 0, c2.getDocument().getLength() );
|
||||
} );
|
||||
} else {
|
||||
} else
|
||||
select( 0, doc.getLength() );
|
||||
}
|
||||
}
|
||||
|
||||
private void select( int mark, int dot ) {
|
||||
if( mark != getMark() )
|
||||
setDot( mark );
|
||||
setDot( mark, Position.Bias.Forward );
|
||||
if( dot != getDot() )
|
||||
moveDot( dot );
|
||||
moveDot( dot, Position.Bias.Forward );
|
||||
}
|
||||
|
||||
private int getSelectAllOnFocusPolicy() {
|
||||
Object value = getClientProperty( SELECT_ALL_ON_FOCUS_POLICY );
|
||||
// Note: using String.valueOf() because selectAllOnFocusPolicy may be null
|
||||
switch( String.valueOf( value instanceof String ? value : selectAllOnFocusPolicy ) ) {
|
||||
default:
|
||||
case SELECT_ALL_ON_FOCUS_POLICY_NEVER: return NEVER;
|
||||
case SELECT_ALL_ON_FOCUS_POLICY_ONCE: return ONCE;
|
||||
case SELECT_ALL_ON_FOCUS_POLICY_ALWAYS: return ALWAYS;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isSelectAllOnMouseClick() {
|
||||
Object value = getClientProperty( SELECT_ALL_ON_MOUSE_CLICK );
|
||||
return (value instanceof Boolean) ? (boolean) value : selectAllOnMouseClick;
|
||||
}
|
||||
|
||||
private Object getClientProperty( String key ) {
|
||||
JTextComponent c = getComponent();
|
||||
if( c == null )
|
||||
return null;
|
||||
|
||||
Object value = c.getClientProperty( key );
|
||||
if( value != null )
|
||||
return value;
|
||||
|
||||
Container parent = c.getParent();
|
||||
if( parent instanceof JComboBox )
|
||||
return ((JComboBox<?>)parent).getClientProperty( key );
|
||||
if( parent instanceof JSpinner.DefaultEditor ) {
|
||||
parent = parent.getParent();
|
||||
if( parent instanceof JSpinner )
|
||||
return ((JSpinner)parent).getClientProperty( key );
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @since 1.4 */
|
||||
|
||||
@@ -225,6 +225,8 @@ public class FlatComboBoxUI
|
||||
}
|
||||
};
|
||||
comboBox.addMouseListener( hoverListener );
|
||||
|
||||
MigLayoutVisualPadding.install( comboBox );
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -233,6 +235,8 @@ public class FlatComboBoxUI
|
||||
|
||||
comboBox.removeMouseListener( hoverListener );
|
||||
hoverListener = null;
|
||||
|
||||
MigLayoutVisualPadding.uninstall( comboBox );
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -274,8 +278,6 @@ public class FlatComboBoxUI
|
||||
comboBox.setMaximumRowCount( maximumRowCount );
|
||||
|
||||
paddingBorder = new CellPaddingBorder( padding );
|
||||
|
||||
MigLayoutVisualPadding.install( comboBox );
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -304,8 +306,6 @@ public class FlatComboBoxUI
|
||||
|
||||
oldStyleValues = null;
|
||||
borderShared = null;
|
||||
|
||||
MigLayoutVisualPadding.uninstall( comboBox );
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -585,7 +585,7 @@ public class FlatComboBoxUI
|
||||
FlatUIUtils.paintComponentBackground( g2, 0, 0, width, height, focusWidth, arc );
|
||||
|
||||
// paint arrow button background
|
||||
if( enabled && !isCellRenderer ) {
|
||||
if( enabled && !isCellRenderer && arrowButton.isVisible() ) {
|
||||
Color buttonColor = paintButton
|
||||
? buttonEditableBackground
|
||||
: (buttonFocusedBackground != null || focusedBackground != null) && isPermanentFocusOwner( comboBox )
|
||||
@@ -612,7 +612,7 @@ public class FlatComboBoxUI
|
||||
}
|
||||
|
||||
// paint vertical line between value and arrow button
|
||||
if( paintButton ) {
|
||||
if( paintButton && arrowButton.isVisible() ) {
|
||||
Color separatorColor = enabled ? buttonSeparatorColor : buttonDisabledSeparatorColor;
|
||||
if( separatorColor != null && buttonSeparatorWidth > 0 ) {
|
||||
g2.setColor( separatorColor );
|
||||
|
||||
@@ -74,7 +74,7 @@ public class FlatDropShadowBorder
|
||||
|
||||
this.shadowColor = shadowColor;
|
||||
this.shadowInsets = shadowInsets;
|
||||
this.shadowOpacity = shadowOpacity;
|
||||
this.shadowOpacity = Math.min( Math.max( shadowOpacity, 0f ), 1f );
|
||||
|
||||
shadowSize = maxInset( shadowInsets );
|
||||
}
|
||||
|
||||
@@ -376,31 +376,68 @@ public class FlatFileChooserUI
|
||||
if( icon != null )
|
||||
return icon;
|
||||
|
||||
// get system icon
|
||||
if( f != null ) {
|
||||
try {
|
||||
icon = getFileChooser().getFileSystemView().getSystemIcon( f );
|
||||
} catch( NullPointerException ex ) {
|
||||
// Java 21 may throw a NPE for exe files that use default Windows exe icon
|
||||
}
|
||||
// new proxy icon
|
||||
//
|
||||
// Note: Since this is a super light weight icon object, we do not add it
|
||||
// to the icon cache here. This keeps cache small in case of large directories
|
||||
// with thousands of files when icons of all files are only needed to compute
|
||||
// the layout of list/table, but never painted because located outside of visible area.
|
||||
// When an icon needs to be painted, the proxy adds it to the icon cache
|
||||
// and loads the real icon.
|
||||
return new FlatFileViewIcon( f );
|
||||
}
|
||||
|
||||
if( icon != null ) {
|
||||
if( icon instanceof ImageIcon )
|
||||
icon = new ScaledImageIcon( (ImageIcon) icon );
|
||||
cacheIcon( f, icon );
|
||||
return icon;
|
||||
}
|
||||
//---- class FlatFileViewIcon -----------------------------------------
|
||||
|
||||
/**
|
||||
* A proxy icon that has a fixed (scaled) width/height (16x16) and
|
||||
* gets/loads the real (system) icon only for painting.
|
||||
* Avoids unnecessary getting/loading system icons.
|
||||
*/
|
||||
private class FlatFileViewIcon
|
||||
implements Icon
|
||||
{
|
||||
private final File f;
|
||||
private Icon realIcon;
|
||||
|
||||
FlatFileViewIcon( File f ) {
|
||||
this.f = f;
|
||||
}
|
||||
|
||||
// get default icon
|
||||
icon = super.getIcon( f );
|
||||
|
||||
if( icon instanceof ImageIcon ) {
|
||||
icon = new ScaledImageIcon( (ImageIcon) icon );
|
||||
cacheIcon( f, icon );
|
||||
@Override
|
||||
public int getIconWidth() {
|
||||
return UIScale.scale( 16 );
|
||||
}
|
||||
|
||||
return icon;
|
||||
@Override
|
||||
public int getIconHeight() {
|
||||
return UIScale.scale( 16 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintIcon( Component c, Graphics g, int x, int y ) {
|
||||
// get icon on demand
|
||||
if( realIcon == null ) {
|
||||
// get system icon
|
||||
try {
|
||||
if( f != null )
|
||||
realIcon = getFileChooser().getFileSystemView().getSystemIcon( f );
|
||||
} catch( NullPointerException ex ) {
|
||||
// Java 21 may throw a NPE for exe files that use default Windows exe icon
|
||||
}
|
||||
|
||||
// get default icon
|
||||
if( realIcon == null )
|
||||
realIcon = FlatFileView.super.getIcon( f );
|
||||
|
||||
if( realIcon instanceof ImageIcon )
|
||||
realIcon = new ScaledImageIcon( (ImageIcon) realIcon );
|
||||
|
||||
cacheIcon( f, this );
|
||||
}
|
||||
|
||||
realIcon.paintIcon( c, g, x, y );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,12 +17,13 @@
|
||||
package com.formdev.flatlaf.ui;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
import java.util.function.BiConsumer;
|
||||
import javax.swing.AbstractButton;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JLabel;
|
||||
@@ -74,9 +75,9 @@ public class FlatHTML
|
||||
for( int i = 1; i <= 7; i++ )
|
||||
System.out.println( i+": "+ styleSheet.getPointSize( i ) );
|
||||
debug*/
|
||||
int fontBaseSize = c.getFont().getSize();
|
||||
Font font = c.getFont();
|
||||
if( styleSheet.getPointSize( 7 ) != 36f ||
|
||||
styleSheet.getPointSize( 4 ) == fontBaseSize )
|
||||
font == null || styleSheet.getPointSize( 4 ) == font.getSize() )
|
||||
return;
|
||||
|
||||
// check whether view uses "absolute-size" keywords (e.g. "x-large") for font-size
|
||||
@@ -93,23 +94,22 @@ debug*/
|
||||
text = ((JToolTip)c).getTipText();
|
||||
else
|
||||
return;
|
||||
if( text == null )
|
||||
if( text == null || !BasicHTML.isHTMLString( text ) )
|
||||
return;
|
||||
|
||||
// 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 " + font.getSize() + "</style>";
|
||||
String openTag = "";
|
||||
String closeTag = "";
|
||||
|
||||
String lowerText = text.toLowerCase( Locale.ENGLISH );
|
||||
int headIndex;
|
||||
int styleIndex;
|
||||
|
||||
int insertIndex;
|
||||
if( (headIndex = lowerText.indexOf( "<head>" )) >= 0 ) {
|
||||
if( (headIndex = indexOfTag( text, "head", true )) >= 0 ) {
|
||||
// there is a <head> tag --> insert after <head> tag
|
||||
insertIndex = headIndex + "<head>".length();
|
||||
} else if( (styleIndex = lowerText.indexOf( "<style>" )) >= 0 ) {
|
||||
insertIndex = headIndex;
|
||||
} else if( (styleIndex = indexOfTag( text, "style", false )) >= 0 ) {
|
||||
// there is a <style> tag --> insert before <style> tag
|
||||
insertIndex = styleIndex;
|
||||
} else {
|
||||
@@ -124,6 +124,41 @@ debug*/
|
||||
+ text.substring( insertIndex );
|
||||
|
||||
BasicHTML.updateRenderer( c, newText );
|
||||
|
||||
// for unit tests
|
||||
if( testUpdateRenderer != null )
|
||||
testUpdateRenderer.accept( c, newText );
|
||||
}
|
||||
|
||||
// for unit tests
|
||||
static BiConsumer<JComponent, String> testUpdateRenderer;
|
||||
|
||||
/**
|
||||
* Returns start or end index of a HTML tag.
|
||||
* Checks only for leading '<' character and (case-ignore) tag name.
|
||||
*/
|
||||
private static int indexOfTag( String html, String tag, boolean endIndex ) {
|
||||
int tagLength = tag.length();
|
||||
int maxLength = html.length() - tagLength - 2;
|
||||
char lastTagChar = tag.charAt( tagLength - 1 );
|
||||
|
||||
for( int i = "<html>".length(); i < maxLength; i++ ) {
|
||||
// check for leading '<' and last tag name character
|
||||
if( html.charAt( i ) == '<' && Character.toLowerCase( html.charAt( i + tagLength ) ) == lastTagChar ) {
|
||||
// compare tag characters from last to first
|
||||
for( int j = tagLength - 2; j >= 0; j-- ) {
|
||||
if( Character.toLowerCase( html.charAt( i + 1 + j ) ) != tag.charAt( j ) )
|
||||
break; // not equal
|
||||
|
||||
if( j == 0 ) {
|
||||
// tag found
|
||||
return endIndex ? html.indexOf( '>', i + tagLength ) + 1 : i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
private static final Set<String> absoluteSizeKeywordsSet = new HashSet<>( Arrays.asList(
|
||||
|
||||
@@ -57,6 +57,7 @@ import com.formdev.flatlaf.util.UIScale;
|
||||
* @uiDefault List.foreground Color
|
||||
* @uiDefault List.selectionBackground Color
|
||||
* @uiDefault List.selectionForeground Color
|
||||
* @uiDefault List.alternateRowColor Color
|
||||
* @uiDefault List.dropLineColor Color
|
||||
* @uiDefault List.border Border
|
||||
* @uiDefault List.cellRenderer ListCellRenderer
|
||||
@@ -93,6 +94,7 @@ public class FlatListUI
|
||||
@Styleable protected Color selectionForeground;
|
||||
@Styleable protected Color selectionInactiveBackground;
|
||||
@Styleable protected Color selectionInactiveForeground;
|
||||
/** @since 3.6 */ @Styleable protected Color alternateRowColor;
|
||||
/** @since 3 */ @Styleable protected Insets selectionInsets;
|
||||
/** @since 3 */ @Styleable protected int selectionArc;
|
||||
|
||||
@@ -129,6 +131,7 @@ public class FlatListUI
|
||||
selectionForeground = UIManager.getColor( "List.selectionForeground" );
|
||||
selectionInactiveBackground = UIManager.getColor( "List.selectionInactiveBackground" );
|
||||
selectionInactiveForeground = UIManager.getColor( "List.selectionInactiveForeground" );
|
||||
alternateRowColor = UIManager.getColor( "List.alternateRowColor" );
|
||||
selectionInsets = UIManager.getInsets( "List.selectionInsets" );
|
||||
selectionArc = UIManager.getInt( "List.selectionArc" );
|
||||
|
||||
@@ -143,6 +146,7 @@ public class FlatListUI
|
||||
selectionForeground = null;
|
||||
selectionInactiveBackground = null;
|
||||
selectionInactiveForeground = null;
|
||||
alternateRowColor = null;
|
||||
|
||||
oldStyleValues = null;
|
||||
}
|
||||
@@ -299,13 +303,24 @@ public class FlatListUI
|
||||
{
|
||||
boolean isSelected = selModel.isSelectedIndex( row );
|
||||
|
||||
// paint alternating rows
|
||||
if( alternateRowColor != null && row % 2 != 0 &&
|
||||
!"ComboBox.list".equals( list.getName() ) ) // combobox does not support alternate row color
|
||||
{
|
||||
g.setColor( alternateRowColor );
|
||||
|
||||
float arc = UIScale.scale( selectionArc / 2f );
|
||||
FlatUIUtils.paintSelection( (Graphics2D) g, rowBounds.x, rowBounds.y, rowBounds.width, rowBounds.height,
|
||||
UIScale.scale( selectionInsets ), arc, arc, arc, arc, 0 );
|
||||
}
|
||||
|
||||
// get renderer component
|
||||
@SuppressWarnings( "unchecked" )
|
||||
Component rendererComponent = cellRenderer.getListCellRendererComponent( list,
|
||||
dataModel.getElementAt( row ), row, isSelected,
|
||||
FlatUIUtils.isPermanentFocusOwner( list ) && (row == leadIndex) );
|
||||
|
||||
//
|
||||
// use smaller cell width if list is used in JFileChooser
|
||||
boolean isFileList = Boolean.TRUE.equals( list.getClientProperty( "List.isFileList" ) );
|
||||
int cx, cw;
|
||||
if( isFileList ) {
|
||||
|
||||
@@ -58,6 +58,7 @@ class FlatNativeLibrary
|
||||
|
||||
String classifier;
|
||||
String ext;
|
||||
boolean unknownArch = false;
|
||||
if( SystemInfo.isWindows_10_orLater && (SystemInfo.isX86 || SystemInfo.isX86_64 || SystemInfo.isAARCH64) ) {
|
||||
// Windows: requires Windows 10/11 (x86, x86_64 or aarch64)
|
||||
|
||||
@@ -90,11 +91,14 @@ class FlatNativeLibrary
|
||||
classifier = SystemInfo.isAARCH64 ? "macos-arm64" : "macos-x86_64";
|
||||
ext = "dylib";
|
||||
|
||||
} else if( SystemInfo.isLinux && SystemInfo.isX86_64 ) {
|
||||
// Linux: requires x86_64
|
||||
} else if( SystemInfo.isLinux ) {
|
||||
// Linux: x86_64 or aarch64 (but also supports unknown architectures)
|
||||
|
||||
classifier = "linux-x86_64";
|
||||
classifier = SystemInfo.isAARCH64 ? "linux-arm64"
|
||||
: (SystemInfo.isX86_64 ? "linux-x86_64"
|
||||
: "linux-" + sanitize( System.getProperty( "os.arch" ) ));
|
||||
ext = "so";
|
||||
unknownArch = !SystemInfo.isX86_64 && !SystemInfo.isAARCH64;
|
||||
|
||||
// Load libjawt.so (part of JRE) explicitly because it is not found
|
||||
// in all Java versions/distributions.
|
||||
@@ -106,7 +110,7 @@ class FlatNativeLibrary
|
||||
return; // no native library available for current OS or CPU architecture
|
||||
|
||||
// load native library
|
||||
NativeLibrary nativeLibrary = createNativeLibrary( classifier, ext );
|
||||
NativeLibrary nativeLibrary = createNativeLibrary( classifier, ext, unknownArch );
|
||||
if( !nativeLibrary.isLoaded() )
|
||||
return;
|
||||
|
||||
@@ -128,7 +132,7 @@ class FlatNativeLibrary
|
||||
FlatNativeLibrary.nativeLibrary = nativeLibrary;
|
||||
}
|
||||
|
||||
private static NativeLibrary createNativeLibrary( String classifier, String ext ) {
|
||||
private static NativeLibrary createNativeLibrary( String classifier, String ext, boolean unknownArch ) {
|
||||
String libraryName = "flatlaf-" + classifier;
|
||||
|
||||
// load from "java.library.path" or from path specified in system property "flatlaf.nativeLibraryPath"
|
||||
@@ -139,9 +143,11 @@ class FlatNativeLibrary
|
||||
if( library.isLoaded() )
|
||||
return library;
|
||||
|
||||
LoggingFacade.INSTANCE.logSevere( "FlatLaf: Native library '" + System.mapLibraryName( libraryName )
|
||||
+ "' not found in java.library.path '" + System.getProperty( "java.library.path" )
|
||||
+ "'. Using extracted native library instead.", null );
|
||||
if( !unknownArch ) {
|
||||
LoggingFacade.INSTANCE.logSevere( "FlatLaf: Native library '" + System.mapLibraryName( libraryName )
|
||||
+ "' not found in java.library.path '" + System.getProperty( "java.library.path" )
|
||||
+ "'. Using extracted native library instead.", null );
|
||||
}
|
||||
} else {
|
||||
// try standard library naming scheme
|
||||
// (same as in flatlaf.jar in package 'com/formdev/flatlaf/natives')
|
||||
@@ -160,11 +166,13 @@ class FlatNativeLibrary
|
||||
return new NativeLibrary( libraryFile2, true );
|
||||
}
|
||||
|
||||
LoggingFacade.INSTANCE.logSevere( "FlatLaf: Native library '"
|
||||
+ libraryFile.getName()
|
||||
+ (libraryName2 != null ? ("' or '" + libraryName2) : "")
|
||||
+ "' not found in '" + libraryFile.getParentFile().getAbsolutePath()
|
||||
+ "'. Using extracted native library instead.", null );
|
||||
if( !unknownArch ) {
|
||||
LoggingFacade.INSTANCE.logSevere( "FlatLaf: Native library '"
|
||||
+ libraryFile.getName()
|
||||
+ (libraryName2 != null ? ("' or '" + libraryName2) : "")
|
||||
+ "' not found in '" + libraryFile.getParentFile().getAbsolutePath()
|
||||
+ "'. Using extracted native library instead.", null );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,7 +183,7 @@ class FlatNativeLibrary
|
||||
return new NativeLibrary( libraryFile, true );
|
||||
|
||||
// load from FlatLaf jar (extract native library to temp folder)
|
||||
return new NativeLibrary( "com/formdev/flatlaf/natives/" + libraryName, null, true );
|
||||
return new NativeLibrary( "com/formdev/flatlaf/natives/" + libraryName, null, !unknownArch );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -273,6 +281,13 @@ class FlatNativeLibrary
|
||||
+ '-' + classifier + '.' + ext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow only 'a'-'z', 'A'-'Z', '0'-'9', '_' and '-' in filenames.
|
||||
*/
|
||||
private static String sanitize( String s ) {
|
||||
return s.replaceAll( "[^a-zA-Z0-9_-]", "_" );
|
||||
}
|
||||
|
||||
private static void loadJAWT() {
|
||||
try {
|
||||
System.loadLibrary( "jawt" );
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.formdev.flatlaf.ui;
|
||||
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.Point;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.Window;
|
||||
@@ -48,8 +49,17 @@ class FlatNativeLinuxLibrary
|
||||
}
|
||||
|
||||
// direction for _NET_WM_MOVERESIZE message
|
||||
// see https://specifications.freedesktop.org/wm-spec/wm-spec-latest.html
|
||||
static final int MOVE = 8;
|
||||
// see https://specifications.freedesktop.org/wm-spec/latest/ar01s04.html
|
||||
static final int
|
||||
SIZE_TOPLEFT = 0,
|
||||
SIZE_TOP = 1,
|
||||
SIZE_TOPRIGHT = 2,
|
||||
SIZE_RIGHT = 3,
|
||||
SIZE_BOTTOMRIGHT = 4,
|
||||
SIZE_BOTTOM = 5,
|
||||
SIZE_BOTTOMLEFT = 6,
|
||||
SIZE_LEFT = 7,
|
||||
MOVE = 8;
|
||||
|
||||
private static Boolean isXWindowSystem;
|
||||
|
||||
@@ -96,7 +106,11 @@ class FlatNativeLinuxLibrary
|
||||
}
|
||||
|
||||
private static Point scale( Window window, Point pt ) {
|
||||
AffineTransform transform = window.getGraphicsConfiguration().getDefaultTransform();
|
||||
GraphicsConfiguration gc = window.getGraphicsConfiguration();
|
||||
if( gc == null )
|
||||
return pt;
|
||||
|
||||
AffineTransform transform = gc.getDefaultTransform();
|
||||
int x = (int) Math.round( pt.x * transform.getScaleX() );
|
||||
int y = (int) Math.round( pt.y * transform.getScaleY() );
|
||||
return new Point( x, y );
|
||||
|
||||
@@ -138,7 +138,8 @@ public class FlatPopupFactory
|
||||
|
||||
// create drop shadow popup
|
||||
Popup popupForScreenOfOwner = getPopupForScreenOfOwner( owner, contents, x, y, forceHeavyWeight );
|
||||
return owner.getGraphicsConfiguration().isTranslucencyCapable()
|
||||
GraphicsConfiguration gc = (owner != null) ? owner.getGraphicsConfiguration() : null;
|
||||
return (gc != null && gc.isTranslucencyCapable())
|
||||
? new DropShadowPopup( popupForScreenOfOwner, owner, contents )
|
||||
: new NonFlashingPopup( popupForScreenOfOwner, owner, contents );
|
||||
}
|
||||
@@ -305,7 +306,7 @@ public class FlatPopupFactory
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( gc == null )
|
||||
if( gc == null && owner != null )
|
||||
gc = owner.getGraphicsConfiguration();
|
||||
if( gc == null )
|
||||
return null;
|
||||
@@ -364,14 +365,8 @@ public class FlatPopupFactory
|
||||
}
|
||||
|
||||
private static boolean isMacOSBorderSupported() {
|
||||
// do not use rounded border on macOS 14.4+ because it may freeze the application
|
||||
// and crash the macOS WindowServer process (reports vary from Finder restarts to OS restarts)
|
||||
// https://github.com/apache/netbeans/issues/7560#issuecomment-2226439215
|
||||
// https://github.com/apache/netbeans/issues/6647#issuecomment-2070124442
|
||||
boolean isMacOS_14_4_orLater = (SystemInfo.osVersion >= SystemInfo.toVersion( 14, 4, 0, 0 ));
|
||||
|
||||
return SystemInfo.isMacOS &&
|
||||
FlatSystemProperties.getBoolean( FlatSystemProperties.USE_ROUNDED_POPUP_BORDER, !isMacOS_14_4_orLater ) &&
|
||||
FlatSystemProperties.getBoolean( FlatSystemProperties.USE_ROUNDED_POPUP_BORDER, true ) &&
|
||||
FlatNativeMacLibrary.isLoaded();
|
||||
}
|
||||
|
||||
@@ -695,8 +690,6 @@ public class FlatPopupFactory
|
||||
Container contentPane = ((JWindow)popupWindow).getContentPane();
|
||||
contentPane.removeAll();
|
||||
contentPane.add( contents, BorderLayout.CENTER );
|
||||
popupWindow.invalidate();
|
||||
popupWindow.validate();
|
||||
popupWindow.pack();
|
||||
|
||||
// update client property on contents
|
||||
@@ -716,6 +709,7 @@ public class FlatPopupFactory
|
||||
|
||||
private class DropShadowPopup
|
||||
extends NonFlashingPopup
|
||||
implements ComponentListener
|
||||
{
|
||||
// light weight
|
||||
private JComponent lightComp;
|
||||
@@ -775,7 +769,7 @@ public class FlatPopupFactory
|
||||
}
|
||||
|
||||
// Windows 11: reset corner preference on reused heavy weight popups
|
||||
if( isWindows11BorderSupported() ) {
|
||||
if( SystemInfo.isWindows_11_orLater && FlatNativeWindowsLibrary.isLoaded() ) {
|
||||
resetWindows11Border( popupWindow );
|
||||
if( dropShadowWindow != null )
|
||||
resetWindows11Border( dropShadowWindow );
|
||||
@@ -845,10 +839,18 @@ public class FlatPopupFactory
|
||||
if( insets.left != 0 || insets.top != 0 )
|
||||
lightComp.setLocation( lightComp.getX() - insets.left, lightComp.getY() - insets.top );
|
||||
}
|
||||
|
||||
if( popupWindow != null ) {
|
||||
removeAllPopupWindowComponentListeners();
|
||||
popupWindow.addComponentListener( this );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
void hideImpl() {
|
||||
if( popupWindow != null )
|
||||
removeAllPopupWindowComponentListeners();
|
||||
|
||||
if( dropShadowDelegate != null ) {
|
||||
dropShadowDelegate.hide();
|
||||
dropShadowDelegate = null;
|
||||
@@ -948,22 +950,55 @@ public class FlatPopupFactory
|
||||
|
||||
@Override
|
||||
void reset( Component contents, int ownerX, int ownerY ) {
|
||||
if( popupWindow != null )
|
||||
removeAllPopupWindowComponentListeners();
|
||||
|
||||
super.reset( contents, ownerX, ownerY );
|
||||
|
||||
if( dropShadowWindow != null ) {
|
||||
// set preferred size of drop shadow panel
|
||||
Dimension prefSize = popupWindow.getPreferredSize();
|
||||
Insets insets = dropShadowPanel2.getInsets();
|
||||
int w = prefSize.width + insets.left + insets.right;
|
||||
int h = prefSize.height + insets.top + insets.bottom;
|
||||
dropShadowPanel2.setPreferredSize( new Dimension( w, h ) );
|
||||
updateDropShadowWindowBounds();
|
||||
}
|
||||
|
||||
// update drop shadow popup window location and size
|
||||
int x = popupWindow.getX() - insets.left;
|
||||
int y = popupWindow.getY() - insets.top;
|
||||
dropShadowWindow.setBounds( x, y, w, h );
|
||||
dropShadowWindow.pack();
|
||||
private void updateDropShadowWindowBounds() {
|
||||
if( dropShadowWindow == null )
|
||||
return;
|
||||
|
||||
// calculate size of drop shadow window
|
||||
Dimension size = popupWindow.getSize();
|
||||
Insets insets = dropShadowPanel2.getInsets();
|
||||
int w = size.width + insets.left + insets.right;
|
||||
int h = size.height + insets.top + insets.bottom;
|
||||
|
||||
// update drop shadow popup window bounds
|
||||
int x = popupWindow.getX() - insets.left;
|
||||
int y = popupWindow.getY() - insets.top;
|
||||
dropShadowWindow.setBounds( x, y, w, h );
|
||||
dropShadowWindow.validate();
|
||||
}
|
||||
|
||||
private void removeAllPopupWindowComponentListeners() {
|
||||
// make sure that there is no old component listener
|
||||
// necessary because this class is cloned if reusing popup windows
|
||||
for( ComponentListener l : popupWindow.getComponentListeners() ) {
|
||||
if( l instanceof DropShadowPopup )
|
||||
popupWindow.removeComponentListener( l );
|
||||
}
|
||||
}
|
||||
|
||||
//---- interface ComponentListener ----
|
||||
|
||||
@Override
|
||||
public void componentResized( ComponentEvent e ) {
|
||||
if( e.getSource() == popupWindow )
|
||||
updateDropShadowWindowBounds();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void componentMoved( ComponentEvent e ) {
|
||||
if( e.getSource() == popupWindow )
|
||||
updateDropShadowWindowBounds();
|
||||
}
|
||||
|
||||
@Override public void componentShown( ComponentEvent e ) {}
|
||||
@Override public void componentHidden( ComponentEvent e ) {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -239,11 +239,13 @@ public class FlatPopupMenuUI
|
||||
if( gc == null && popupMenu.getInvoker() != null )
|
||||
gc = popupMenu.getInvoker().getGraphicsConfiguration();
|
||||
|
||||
// compute screen height
|
||||
if( gc == null )
|
||||
return new Rectangle( Toolkit.getDefaultToolkit().getScreenSize() );
|
||||
|
||||
// compute screen bounds
|
||||
// (always subtract screen insets because there is no API to detect whether
|
||||
// the popup can overlap the taskbar; see JPopupMenu.canPopupOverlapTaskBar())
|
||||
Toolkit toolkit = Toolkit.getDefaultToolkit();
|
||||
Rectangle screenBounds = (gc != null) ? gc.getBounds() : new Rectangle( toolkit.getScreenSize() );
|
||||
Rectangle screenBounds = gc.getBounds();
|
||||
Insets screenInsets = Toolkit.getDefaultToolkit().getScreenInsets( gc );
|
||||
return FlatUIUtils.subtractInsets( screenBounds, screenInsets );
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import java.awt.Window;
|
||||
import java.awt.event.ComponentListener;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Function;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JDialog;
|
||||
@@ -485,8 +486,12 @@ public class FlatRootPaneUI
|
||||
break;
|
||||
|
||||
case "ancestor":
|
||||
if( e.getNewValue() instanceof Window )
|
||||
if( e.getNewValue() instanceof Window ) {
|
||||
if( titlePane != null && !Objects.equals( titlePane.windowStyle, FlatTitlePane.getWindowStyle( rootPane ) ) )
|
||||
setTitlePane( createTitlePane() );
|
||||
|
||||
macClearBackgroundForTranslucentWindow( rootPane );
|
||||
}
|
||||
|
||||
macUninstallWindowBackgroundListener( rootPane );
|
||||
macInstallWindowBackgroundListener( rootPane );
|
||||
@@ -684,7 +689,7 @@ public class FlatRootPaneUI
|
||||
* Window border used for non-native window decorations.
|
||||
*/
|
||||
public static class FlatWindowBorder
|
||||
extends BorderUIResource.EmptyBorderUIResource
|
||||
extends FlatEmptyBorder
|
||||
{
|
||||
protected final Color activeBorderColor = UIManager.getColor( "RootPane.activeBorderColor" );
|
||||
protected final Color inactiveBorderColor = UIManager.getColor( "RootPane.inactiveBorderColor" );
|
||||
@@ -717,7 +722,10 @@ public class FlatRootPaneUI
|
||||
}
|
||||
|
||||
private void paintImpl( Graphics2D g, int x, int y, int width, int height, double scaleFactor ) {
|
||||
g.drawRect( x, y, width - 1, height - 1 );
|
||||
Object[] oldRenderingHints = FlatUIUtils.setRenderingHints( g );
|
||||
float lineWidth = (float) (UIScale.scale( 1f ) * scaleFactor);
|
||||
g.fill( FlatUIUtils.createRectangle( x, y, width, height, lineWidth ) );
|
||||
FlatUIUtils.resetRenderingHints( g, oldRenderingHints );
|
||||
}
|
||||
|
||||
protected boolean isWindowMaximized( Component c ) {
|
||||
|
||||
@@ -140,8 +140,6 @@ public class FlatSpinnerUI
|
||||
buttonHoverArrowColor = UIManager.getColor( "Spinner.buttonHoverArrowColor" );
|
||||
buttonPressedArrowColor = UIManager.getColor( "Spinner.buttonPressedArrowColor" );
|
||||
padding = UIManager.getInsets( "Spinner.padding" );
|
||||
|
||||
MigLayoutVisualPadding.install( spinner );
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -162,8 +160,6 @@ public class FlatSpinnerUI
|
||||
|
||||
oldStyleValues = null;
|
||||
borderShared = null;
|
||||
|
||||
MigLayoutVisualPadding.uninstall( spinner );
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -173,6 +169,8 @@ public class FlatSpinnerUI
|
||||
addEditorFocusListener( spinner.getEditor() );
|
||||
spinner.addFocusListener( getHandler() );
|
||||
spinner.addPropertyChangeListener( getHandler() );
|
||||
|
||||
MigLayoutVisualPadding.install( spinner );
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -184,6 +182,8 @@ public class FlatSpinnerUI
|
||||
spinner.removePropertyChangeListener( getHandler() );
|
||||
|
||||
handler = null;
|
||||
|
||||
MigLayoutVisualPadding.uninstall( spinner );
|
||||
}
|
||||
|
||||
private Handler getHandler() {
|
||||
|
||||
@@ -42,7 +42,6 @@ import com.formdev.flatlaf.FlatClientProperties;
|
||||
import com.formdev.flatlaf.FlatLaf;
|
||||
import com.formdev.flatlaf.util.HiDPIUtils;
|
||||
import com.formdev.flatlaf.util.StringUtils;
|
||||
import com.formdev.flatlaf.util.SystemInfo;
|
||||
|
||||
/**
|
||||
* Support for styling components in CSS syntax.
|
||||
@@ -325,22 +324,24 @@ public class FlatStylingSupport
|
||||
return null;
|
||||
|
||||
Map<String, Object> oldValues = new HashMap<>();
|
||||
outer:
|
||||
for( Map.Entry<String, Object> e : style.entrySet() ) {
|
||||
String key = e.getKey();
|
||||
Object newValue = e.getValue();
|
||||
|
||||
// handle key prefix
|
||||
if( key.startsWith( "[" ) ) {
|
||||
if( (SystemInfo.isWindows && key.startsWith( "[win]" )) ||
|
||||
(SystemInfo.isMacOS && key.startsWith( "[mac]" )) ||
|
||||
(SystemInfo.isLinux && key.startsWith( "[linux]" )) ||
|
||||
(key.startsWith( "[light]" ) && !FlatLaf.isLafDark()) ||
|
||||
(key.startsWith( "[dark]" ) && FlatLaf.isLafDark()) )
|
||||
{
|
||||
// prefix is known and enabled --> remove prefix
|
||||
key = key.substring( key.indexOf( ']' ) + 1 );
|
||||
} else
|
||||
continue;
|
||||
while( key.startsWith( "[" ) ) {
|
||||
int closeIndex = key.indexOf( ']' );
|
||||
if( closeIndex < 0 )
|
||||
continue outer;
|
||||
|
||||
String prefix = key.substring( 0, closeIndex + 1 );
|
||||
String lightOrDarkPrefix = FlatLaf.getUIKeyLightOrDarkPrefix( FlatLaf.isLafDark() );
|
||||
if( !lightOrDarkPrefix.equals( prefix ) && !FlatLaf.getUIKeyPlatformPrefixes().contains( prefix ) )
|
||||
continue outer;
|
||||
|
||||
// prefix is known and enabled --> remove prefix
|
||||
key = key.substring( closeIndex + 1 );
|
||||
}
|
||||
|
||||
Object oldValue = applyProperty.apply( key, newValue );
|
||||
|
||||
@@ -2306,8 +2306,23 @@ debug*/
|
||||
/** @since 3.4 */
|
||||
@Override
|
||||
public Boolean isTitleBarCaptionAt( int x, int y ) {
|
||||
if( tabForCoordinate( tabPane, x, y ) >= 0 )
|
||||
return false;
|
||||
// Note: not using tabForCoordinate() here because this may validate layout and cause dead lock
|
||||
|
||||
if( moreTabsButton != null ) {
|
||||
// convert x,y from JTabbedPane coordinate space to ScrollableTabPanel coordinate space
|
||||
Point viewPosition = tabViewport.getViewPosition();
|
||||
x = x - tabViewport.getX() + viewPosition.x;
|
||||
y = y - tabViewport.getY() + viewPosition.y;
|
||||
|
||||
// check whether point is within viewport
|
||||
if( !tabViewport.getViewRect().contains( x, y ) )
|
||||
return null; // check children
|
||||
}
|
||||
|
||||
for( int i = 0; i < rects.length; i++ ) {
|
||||
if( rects[i].contains( x, y ) )
|
||||
return false;
|
||||
}
|
||||
|
||||
return null; // check children
|
||||
}
|
||||
|
||||
@@ -174,8 +174,6 @@ public class FlatTextFieldUI
|
||||
defaultMargin = UIManager.getInsets( prefix + ".margin" );
|
||||
|
||||
LookAndFeel.installProperty( getComponent(), "opaque", false );
|
||||
|
||||
MigLayoutVisualPadding.install( getComponent() );
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -193,8 +191,6 @@ public class FlatTextFieldUI
|
||||
|
||||
oldStyleValues = null;
|
||||
borderShared = null;
|
||||
|
||||
MigLayoutVisualPadding.uninstall( getComponent() );
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -204,6 +200,8 @@ public class FlatTextFieldUI
|
||||
// necessary to update focus border and background
|
||||
focusListener = new FlatUIUtils.RepaintFocusListener( getComponent(), null );
|
||||
getComponent().addFocusListener( focusListener );
|
||||
|
||||
MigLayoutVisualPadding.install( getComponent() );
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -217,6 +215,8 @@ public class FlatTextFieldUI
|
||||
getComponent().getDocument().removeDocumentListener( documentListener );
|
||||
documentListener = null;
|
||||
}
|
||||
|
||||
MigLayoutVisualPadding.uninstall( getComponent() );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -33,7 +33,6 @@ import java.awt.Image;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.Window;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.ComponentAdapter;
|
||||
@@ -90,13 +89,16 @@ import com.formdev.flatlaf.util.UIScale;
|
||||
* @uiDefault TitlePane.iconSize Dimension
|
||||
* @uiDefault TitlePane.iconMargins Insets
|
||||
* @uiDefault TitlePane.titleMargins Insets
|
||||
* @uiDefault TitlePane.menuBarEmbedded boolean
|
||||
* @uiDefault TitlePane.titleMinimumWidth int
|
||||
* @uiDefault TitlePane.buttonMinimumWidth int
|
||||
* @uiDefault TitlePane.buttonMaximizedHeight int
|
||||
* @uiDefault TitlePane.buttonsGap int
|
||||
* @uiDefault TitlePane.buttonsMargins Insets
|
||||
* @uiDefault TitlePane.buttonsFillVertically boolean
|
||||
* @uiDefault TitlePane.centerTitle boolean
|
||||
* @uiDefault TitlePane.centerTitleIfMenuBarEmbedded boolean
|
||||
* @uiDefault TitlePane.showIconBesideTitle boolean
|
||||
* @uiDefault TitlePane.menuBarEmbedded boolean
|
||||
* @uiDefault TitlePane.menuBarTitleGap int
|
||||
* @uiDefault TitlePane.menuBarTitleMinimumGap int
|
||||
* @uiDefault TitlePane.closeIcon Icon
|
||||
@@ -124,9 +126,14 @@ public class FlatTitlePane
|
||||
/** @since 2.5 */ protected final boolean showIconInDialogs;
|
||||
/** @since 2 */ protected final int noIconLeftGap;
|
||||
protected final Dimension iconSize;
|
||||
/** @since 3.6 */ protected final Insets iconMargins;
|
||||
/** @since 3.6 */ protected final Insets titleMargins;
|
||||
/** @since 2.4 */ protected final int titleMinimumWidth;
|
||||
/** @since 2.4 */ protected final int buttonMinimumWidth;
|
||||
protected final int buttonMaximizedHeight;
|
||||
/** @since 3.6 */ protected final int buttonsGap;
|
||||
/** @since 3.6 */ protected final Insets buttonsMargins;
|
||||
/** @since 3.6 */ protected final boolean buttonsFillVertically;
|
||||
protected final boolean centerTitle;
|
||||
protected final boolean centerTitleIfMenuBarEmbedded;
|
||||
/** @since 2.4 */ protected final boolean showIconBesideTitle;
|
||||
@@ -146,6 +153,9 @@ public class FlatTitlePane
|
||||
protected JButton restoreButton;
|
||||
protected JButton closeButton;
|
||||
|
||||
private JComponent iconifyMaximizeGapComp;
|
||||
private JComponent maximizeCloseGapComp;
|
||||
|
||||
protected Window window;
|
||||
|
||||
private final Handler handler;
|
||||
@@ -180,9 +190,7 @@ public class FlatTitlePane
|
||||
public FlatTitlePane( JRootPane 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 );
|
||||
windowStyle = getWindowStyle( rootPane );
|
||||
|
||||
titleFont = FlatUIUtils.getSubUIFont( "TitlePane.font", windowStyle );
|
||||
activeBackground = FlatUIUtils.getSubUIColor( "TitlePane.background", windowStyle );
|
||||
@@ -197,9 +205,14 @@ public class FlatTitlePane
|
||||
showIconInDialogs = FlatUIUtils.getSubUIBoolean( "TitlePane.showIconInDialogs", windowStyle, true );
|
||||
noIconLeftGap = FlatUIUtils.getSubUIInt( "TitlePane.noIconLeftGap", windowStyle, 8 );
|
||||
iconSize = FlatUIUtils.getSubUIDimension( "TitlePane.iconSize", windowStyle );
|
||||
iconMargins = FlatUIUtils.getSubUIInsets( "TitlePane.iconMargins", windowStyle );
|
||||
titleMargins = FlatUIUtils.getSubUIInsets( "TitlePane.titleMargins", windowStyle );
|
||||
titleMinimumWidth = FlatUIUtils.getSubUIInt( "TitlePane.titleMinimumWidth", windowStyle, 60 );
|
||||
buttonMinimumWidth = FlatUIUtils.getSubUIInt( "TitlePane.buttonMinimumWidth", windowStyle, 30 );
|
||||
buttonMaximizedHeight = FlatUIUtils.getSubUIInt( "TitlePane.buttonMaximizedHeight", windowStyle, 0 );
|
||||
buttonsGap = FlatUIUtils.getSubUIInt( "TitlePane.buttonsGap", windowStyle, 0 );
|
||||
buttonsMargins = FlatUIUtils.getSubUIInsets( "TitlePane.buttonsMargins", windowStyle );
|
||||
buttonsFillVertically = FlatUIUtils.getSubUIBoolean( "TitlePane.buttonsFillVertically", windowStyle, true );
|
||||
centerTitle = FlatUIUtils.getSubUIBoolean( "TitlePane.centerTitle", windowStyle, false );
|
||||
centerTitleIfMenuBarEmbedded = FlatUIUtils.getSubUIBoolean( "TitlePane.centerTitleIfMenuBarEmbedded", windowStyle, true );
|
||||
showIconBesideTitle = FlatUIUtils.getSubUIBoolean( "TitlePane.showIconBesideTitle", windowStyle, false );
|
||||
@@ -229,6 +242,12 @@ public class FlatTitlePane
|
||||
applyComponentOrientation( rootPane.getComponentOrientation() );
|
||||
}
|
||||
|
||||
static String getWindowStyle( JRootPane rootPane ) {
|
||||
Window w = SwingUtilities.getWindowAncestor( rootPane );
|
||||
String defaultWindowStyle = (w != null && w.getType() == Window.Type.UTILITY) ? WINDOW_STYLE_SMALL : null;
|
||||
return clientProperty( rootPane, WINDOW_STYLE, defaultWindowStyle, String.class );
|
||||
}
|
||||
|
||||
protected FlatTitlePaneBorder createTitlePaneBorder() {
|
||||
return new FlatTitlePaneBorder();
|
||||
}
|
||||
@@ -246,8 +265,8 @@ public class FlatTitlePane
|
||||
setUI( new FlatTitleLabelUI() );
|
||||
}
|
||||
};
|
||||
iconLabel.setBorder( new FlatEmptyBorder( FlatUIUtils.getSubUIInsets( "TitlePane.iconMargins", windowStyle ) ) );
|
||||
titleLabel.setBorder( new FlatEmptyBorder( FlatUIUtils.getSubUIInsets( "TitlePane.titleMargins", windowStyle ) ) );
|
||||
iconLabel.setBorder( new FlatEmptyBorder( iconMargins ) );
|
||||
titleLabel.setBorder( new FlatEmptyBorder( titleMargins ) );
|
||||
|
||||
leftPanel.setLayout( new BoxLayout( leftPanel, BoxLayout.LINE_AXIS ) );
|
||||
leftPanel.setOpaque( false );
|
||||
@@ -350,10 +369,15 @@ public class FlatTitlePane
|
||||
restoreButton = createButton( "TitlePane.restoreIcon", "Restore", e -> restore() );
|
||||
closeButton = createButton( "TitlePane.closeIcon", "Close", e -> close() );
|
||||
|
||||
iconifyMaximizeGapComp = createButtonsGapComp();
|
||||
maximizeCloseGapComp = createButtonsGapComp();
|
||||
|
||||
// initially hide buttons that are only supported in frames
|
||||
iconifyButton.setVisible( false );
|
||||
maximizeButton.setVisible( false );
|
||||
restoreButton.setVisible( false );
|
||||
iconifyMaximizeGapComp.setVisible( false );
|
||||
maximizeCloseGapComp.setVisible( false );
|
||||
|
||||
buttonPanel = new JPanel() {
|
||||
@Override
|
||||
@@ -365,12 +389,13 @@ public class FlatTitlePane
|
||||
|
||||
if( buttonMaximizedHeight > 0 && isWindowMaximized() && !hasVisibleEmbeddedMenuBar( rootPane.getJMenuBar() ) ) {
|
||||
// make title pane height smaller when frame is maximized
|
||||
size = new Dimension( size.width, Math.min( size.height, UIScale.scale( buttonMaximizedHeight ) ) );
|
||||
size = new Dimension( size.width, Math.min( size.height, UIScale.scale( buttonMaximizedHeight + buttonsMargins.top + buttonsMargins.bottom ) ) );
|
||||
}
|
||||
return size;
|
||||
}
|
||||
};
|
||||
buttonPanel.setOpaque( false );
|
||||
buttonPanel.setBorder( FlatUIUtils.nonUIResource( new FlatEmptyBorder( buttonsMargins ) ) );
|
||||
buttonPanel.setLayout( new BoxLayout( buttonPanel, BoxLayout.LINE_AXIS ) );
|
||||
if( rootPane.getWindowDecorationStyle() == JRootPane.FRAME ) {
|
||||
// JRootPane.FRAME works only for frames (and not for dialogs)
|
||||
@@ -379,8 +404,10 @@ public class FlatTitlePane
|
||||
// later in frameStateChanged(), which is invoked from addNotify()
|
||||
|
||||
buttonPanel.add( iconifyButton );
|
||||
buttonPanel.add( iconifyMaximizeGapComp );
|
||||
buttonPanel.add( maximizeButton );
|
||||
buttonPanel.add( restoreButton );
|
||||
buttonPanel.add( maximizeCloseGapComp );
|
||||
}
|
||||
buttonPanel.add( closeButton );
|
||||
|
||||
@@ -397,13 +424,17 @@ public class FlatTitlePane
|
||||
@Override
|
||||
public Dimension getMinimumSize() {
|
||||
// allow the button to shrink if space is rare
|
||||
return new Dimension( UIScale.scale( buttonMinimumWidth ), super.getMinimumSize().height );
|
||||
return new Dimension(
|
||||
Math.min( UIScale.scale( buttonMinimumWidth ), super.getPreferredSize().width ),
|
||||
super.getMinimumSize().height );
|
||||
}
|
||||
@Override
|
||||
public Dimension getMaximumSize() {
|
||||
// allow the button to fill whole button area height
|
||||
// see also BasicMenuUI.getMaximumSize()
|
||||
return new Dimension( super.getMaximumSize().width, Short.MAX_VALUE );
|
||||
return buttonsFillVertically
|
||||
? new Dimension( super.getMaximumSize().width, Short.MAX_VALUE )
|
||||
: super.getMaximumSize();
|
||||
}
|
||||
};
|
||||
button.setFocusable( false );
|
||||
@@ -414,6 +445,14 @@ public class FlatTitlePane
|
||||
return button;
|
||||
}
|
||||
|
||||
private JComponent createButtonsGapComp() {
|
||||
JComponent gapComp = new JPanel();
|
||||
gapComp.setOpaque( false );
|
||||
gapComp.setMinimumSize( new Dimension( 0, 0 ) );
|
||||
gapComp.setPreferredSize( new Dimension( UIScale.scale( buttonsGap ), 0 ) );
|
||||
return gapComp;
|
||||
}
|
||||
|
||||
protected void activeChanged( boolean active ) {
|
||||
Color background = clientPropertyColor( rootPane, TITLE_BAR_BACKGROUND, null );
|
||||
Color foreground = clientPropertyColor( rootPane, TITLE_BAR_FOREGROUND, null );
|
||||
@@ -435,6 +474,9 @@ public class FlatTitlePane
|
||||
closeButton.setForeground( foreground );
|
||||
|
||||
// this is necessary because hover/pressed colors are derived from background color
|
||||
// (since FlatWindowAbstractIcon now invokes FlatTitlePane.getBackground()
|
||||
// to get base color, this is no longer necessary, but keep it for compatibility;
|
||||
// e.g. for custom window icons)
|
||||
iconifyButton.setBackground( background );
|
||||
maximizeButton.setBackground( background );
|
||||
restoreButton.setBackground( background );
|
||||
@@ -494,6 +536,13 @@ public class FlatTitlePane
|
||||
maximizeButton.setVisible( false );
|
||||
restoreButton.setVisible( false );
|
||||
}
|
||||
|
||||
boolean iconifyVisible = iconifyButton.isVisible();
|
||||
boolean maximizeVisible = maximizeButton.isVisible();
|
||||
boolean restoreVisible = restoreButton.isVisible();
|
||||
boolean closeVisible = closeButton.isVisible();
|
||||
iconifyMaximizeGapComp.setVisible( iconifyVisible && (maximizeVisible || restoreVisible || closeVisible) );
|
||||
maximizeCloseGapComp.setVisible( closeVisible && (maximizeVisible || restoreVisible) );
|
||||
}
|
||||
|
||||
protected void updateIcon() {
|
||||
@@ -747,12 +796,17 @@ public class FlatTitlePane
|
||||
if( isFullWindowContent() )
|
||||
return;
|
||||
|
||||
g.setColor( getBackground() );
|
||||
g.fillRect( 0, 0, getWidth(), getHeight() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Color getBackground() {
|
||||
// not storing value of "TitlePane.unifiedBackground" in class to allow changing at runtime
|
||||
g.setColor( (UIManager.getBoolean( "TitlePane.unifiedBackground" ) &&
|
||||
return (UIManager.getBoolean( "TitlePane.unifiedBackground" ) &&
|
||||
clientPropertyColor( rootPane, TITLE_BAR_BACKGROUND, null ) == null)
|
||||
? FlatUIUtils.getParentBackground( this )
|
||||
: getBackground() );
|
||||
g.fillRect( 0, 0, getWidth(), getHeight() );
|
||||
: super.getBackground();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -824,7 +878,8 @@ public class FlatTitlePane
|
||||
Rectangle oldMaximizedBounds = frame.getMaximizedBounds();
|
||||
if( !hasNativeCustomDecoration() &&
|
||||
(oldMaximizedBounds == null ||
|
||||
Objects.equals( oldMaximizedBounds, rootPane.getClientProperty( "_flatlaf.maximizedBounds" ) )) )
|
||||
Objects.equals( oldMaximizedBounds, rootPane.getClientProperty( "_flatlaf.maximizedBounds" ) )) &&
|
||||
window.getGraphicsConfiguration() != null )
|
||||
{
|
||||
GraphicsConfiguration gc = window.getGraphicsConfiguration();
|
||||
|
||||
@@ -1058,10 +1113,11 @@ public class FlatTitlePane
|
||||
* <p>
|
||||
* Note:
|
||||
* <ul>
|
||||
* <li>This method is invoked often when mouse is moved over title bar
|
||||
* <li>This method is invoked often when mouse is moved over window title bar area
|
||||
* and should therefore return quickly.
|
||||
* <li>This method is invoked on 'AWT-Windows' thread (not 'AWT-EventQueue' thread)
|
||||
* while processing Windows messages.
|
||||
* It <b>must not</b> change any component property or layout because this could cause a dead lock.
|
||||
* </ul>
|
||||
*/
|
||||
private boolean captionHitTest( Point pt ) {
|
||||
@@ -1092,6 +1148,7 @@ public class FlatTitlePane
|
||||
if( !c.isDisplayable() || !c.isVisible() || !contains( c, x, y ) || c == mouseLayer )
|
||||
return true; // continue checking with next component
|
||||
|
||||
// check enabled component that has mouse listeners
|
||||
if( c.isEnabled() &&
|
||||
(c.getMouseListeners().length > 0 ||
|
||||
c.getMouseMotionListeners().length > 0) )
|
||||
@@ -1107,8 +1164,18 @@ public class FlatTitlePane
|
||||
// if component is not fully layouted, do not invoke function
|
||||
// because it is too dangerous that the function tries to layout the component,
|
||||
// which could cause a dead lock
|
||||
if( !c.isValid() )
|
||||
if( !c.isValid() ) {
|
||||
// revalidate if necessary so that it is valid when invoked again later
|
||||
EventQueue.invokeLater( () -> {
|
||||
Window w = SwingUtilities.windowForComponent( c );
|
||||
if( w != null )
|
||||
w.revalidate();
|
||||
else
|
||||
c.revalidate();
|
||||
} );
|
||||
|
||||
return false; // assume that this is not a caption because the component has mouse listeners
|
||||
}
|
||||
|
||||
if( caption instanceof Function ) {
|
||||
// check client property function value
|
||||
@@ -1405,22 +1472,9 @@ debug*/
|
||||
|
||||
private Point dragOffset;
|
||||
private boolean linuxNativeMove;
|
||||
private long lastSingleClickWhen;
|
||||
|
||||
@Override
|
||||
public void mouseClicked( MouseEvent e ) {
|
||||
// on Linux, when using native library, the mouse clicked event
|
||||
// is usually not sent and maximize/restore is done in mouse pressed event
|
||||
// this check is here for the case that a mouse clicked event comes through for some reason
|
||||
if( linuxNativeMove && SystemInfo.isLinux && FlatNativeLinuxLibrary.isWMUtilsSupported( window ) ) {
|
||||
// see comment in mousePressed()
|
||||
if( lastSingleClickWhen != 0 && (e.getWhen() - lastSingleClickWhen) <= getMultiClickInterval() ) {
|
||||
lastSingleClickWhen = 0;
|
||||
maximizeOrRestore();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if( e.getClickCount() == 2 && SwingUtilities.isLeftMouseButton( e ) ) {
|
||||
if( SwingUtilities.getDeepestComponentAt( FlatTitlePane.this, e.getX(), e.getY() ) == iconLabel ) {
|
||||
// double-click on icon closes window
|
||||
@@ -1451,42 +1505,6 @@ debug*/
|
||||
|
||||
dragOffset = SwingUtilities.convertPoint( mouseLayer, e.getPoint(), window );
|
||||
linuxNativeMove = false;
|
||||
|
||||
// on Linux, move or maximize/restore window
|
||||
if( SystemInfo.isLinux && FlatNativeLinuxLibrary.isWMUtilsSupported( window ) ) {
|
||||
// The fired Java mouse events, when doing a double-click and the first click
|
||||
// sends a _NET_WM_MOVERESIZE message, are different for various Linux distributions:
|
||||
// CentOS 7 (GNOME 3.28.2, X11): PRESSED(clickCount=1) PRESSED(clickCount=2) RELEASED(clickCount=2)
|
||||
// Ubuntu 20.04 (GNOME 3.36.1, X11): PRESSED(clickCount=1) PRESSED(clickCount=2) RELEASED(clickCount=2)
|
||||
// Ubuntu 22.04 (GNOME 42.2, Wayland): PRESSED(clickCount=1) RELEASED(clickCount=1) CLICKED(clickCount=1)
|
||||
// Kubuntu 22.04 (KDE 5.24.4, X11): PRESSED(clickCount=1) PRESSED(clickCount=1) RELEASED(clickCount=1)
|
||||
|
||||
// double-click is not always recognized in Java when using _NET_WM_MOVERESIZE message
|
||||
int clickCount = e.getClickCount();
|
||||
if( clickCount == 1 && lastSingleClickWhen != 0 && (e.getWhen() - lastSingleClickWhen) <= getMultiClickInterval() )
|
||||
clickCount = 2;
|
||||
|
||||
switch( clickCount ) {
|
||||
case 1:
|
||||
// move window via _NET_WM_MOVERESIZE message
|
||||
e.consume();
|
||||
linuxNativeMove = FlatNativeLinuxLibrary.moveOrResizeWindow( window, e, FlatNativeLinuxLibrary.MOVE );
|
||||
lastSingleClickWhen = e.getWhen();
|
||||
break;
|
||||
|
||||
case 2:
|
||||
// maximize/restore on double-click
|
||||
// also done here because no mouse clicked event is sent when using _NET_WM_MOVERESIZE message
|
||||
lastSingleClickWhen = 0;
|
||||
maximizeOrRestore();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private int getMultiClickInterval() {
|
||||
Object value = Toolkit.getDefaultToolkit().getDesktopProperty( "awt.multiClickInterval" );
|
||||
return (value instanceof Integer) ? (Integer) value : 500;
|
||||
}
|
||||
|
||||
@Override public void mouseReleased( MouseEvent e ) {}
|
||||
@@ -1509,6 +1527,13 @@ debug*/
|
||||
if( hasNativeCustomDecoration() )
|
||||
return; // do nothing if having native window border
|
||||
|
||||
// on Linux, move window using window manager
|
||||
if( SystemInfo.isLinux && FlatNativeLinuxLibrary.isWMUtilsSupported( window ) ) {
|
||||
linuxNativeMove = FlatNativeLinuxLibrary.moveOrResizeWindow( window, e, FlatNativeLinuxLibrary.MOVE );
|
||||
if( linuxNativeMove )
|
||||
return;
|
||||
}
|
||||
|
||||
// restore window if it is maximized
|
||||
if( window instanceof Frame ) {
|
||||
Frame frame = (Frame) window;
|
||||
@@ -1578,6 +1603,15 @@ debug*/
|
||||
* Useful for components that do not use mouse input on whole component bounds.
|
||||
* E.g. a tabbed pane with a few tabs has some empty space beside the tabs
|
||||
* that can be used to move the window.
|
||||
* <p>
|
||||
* Note:
|
||||
* <ul>
|
||||
* <li>This method is invoked often when mouse is moved over window title bar area
|
||||
* and should therefore return quickly.
|
||||
* <li>This method is invoked on 'AWT-Windows' thread (not 'AWT-EventQueue' thread)
|
||||
* while processing Windows messages.
|
||||
* It <b>must not</b> change any component property or layout because this could cause a dead lock.
|
||||
* </ul>
|
||||
*
|
||||
* @return {@code true} if the component is not interested in mouse input at the given location
|
||||
* {@code false} if the component wants process mouse input at the given location
|
||||
|
||||
@@ -102,9 +102,11 @@ import com.formdev.flatlaf.util.UIScale;
|
||||
* @uiDefault Tree.selectionForeground Color
|
||||
* @uiDefault Tree.selectionInactiveBackground Color
|
||||
* @uiDefault Tree.selectionInactiveForeground Color
|
||||
* @uiDefault Tree.alternateRowColor Color
|
||||
* @uiDefault Tree.selectionInsets Insets
|
||||
* @uiDefault Tree.selectionArc int
|
||||
* @uiDefault Tree.wideSelection boolean
|
||||
* @uiDefault Tree.wideCellRenderer boolean
|
||||
* @uiDefault Tree.showCellFocusIndicator boolean
|
||||
* @uiDefault Tree.showDefaultIcons boolean
|
||||
*
|
||||
@@ -141,9 +143,11 @@ public class FlatTreeUI
|
||||
@Styleable protected Color selectionInactiveBackground;
|
||||
@Styleable protected Color selectionInactiveForeground;
|
||||
@Styleable protected Color selectionBorderColor;
|
||||
/** @since 3.6 */ @Styleable protected Color alternateRowColor;
|
||||
/** @since 3 */ @Styleable protected Insets selectionInsets;
|
||||
/** @since 3 */ @Styleable protected int selectionArc;
|
||||
@Styleable protected boolean wideSelection;
|
||||
/** @since 3.6 */ @Styleable protected boolean wideCellRenderer;
|
||||
@Styleable protected boolean showCellFocusIndicator;
|
||||
/** @since 3 */ protected boolean showDefaultIcons;
|
||||
|
||||
@@ -192,9 +196,11 @@ public class FlatTreeUI
|
||||
selectionInactiveBackground = UIManager.getColor( "Tree.selectionInactiveBackground" );
|
||||
selectionInactiveForeground = UIManager.getColor( "Tree.selectionInactiveForeground" );
|
||||
selectionBorderColor = UIManager.getColor( "Tree.selectionBorderColor" );
|
||||
alternateRowColor = UIManager.getColor( "Tree.alternateRowColor" );
|
||||
selectionInsets = UIManager.getInsets( "Tree.selectionInsets" );
|
||||
selectionArc = UIManager.getInt( "Tree.selectionArc" );
|
||||
wideSelection = UIManager.getBoolean( "Tree.wideSelection" );
|
||||
wideCellRenderer = UIManager.getBoolean( "Tree.wideCellRenderer" );
|
||||
showCellFocusIndicator = UIManager.getBoolean( "Tree.showCellFocusIndicator" );
|
||||
showDefaultIcons = UIManager.getBoolean( "Tree.showDefaultIcons" );
|
||||
|
||||
@@ -227,6 +233,7 @@ public class FlatTreeUI
|
||||
selectionInactiveBackground = null;
|
||||
selectionInactiveForeground = null;
|
||||
selectionBorderColor = null;
|
||||
alternateRowColor = null;
|
||||
|
||||
defaultLeafIcon = null;
|
||||
defaultClosedIcon = null;
|
||||
@@ -310,6 +317,7 @@ public class FlatTreeUI
|
||||
if( e.getSource() == tree ) {
|
||||
switch( e.getPropertyName() ) {
|
||||
case TREE_WIDE_SELECTION:
|
||||
case TREE_WIDE_CELL_RENDERER:
|
||||
case TREE_PAINT_SELECTION:
|
||||
HiDPIUtils.repaint( tree );
|
||||
break;
|
||||
@@ -571,6 +579,27 @@ public class FlatTreeUI
|
||||
boolean isDropRow = isDropRow( row );
|
||||
boolean needsSelectionPainting = (isSelected || isDropRow) && isPaintSelection();
|
||||
|
||||
// paint alternating rows
|
||||
if( alternateRowColor != null && row % 2 != 0 ) {
|
||||
g.setColor( alternateRowColor );
|
||||
|
||||
float arc = UIScale.scale( selectionArc / 2f );
|
||||
FlatUIUtils.paintSelection( (Graphics2D) g, 0, bounds.y, tree.getWidth(), bounds.height,
|
||||
UIScale.scale( selectionInsets ), arc, arc, arc, arc, 0 );
|
||||
}
|
||||
|
||||
// update bounds for wide cell renderer
|
||||
if( isWideSelection() && isWideCellRenderer() ) {
|
||||
Rectangle wideBounds = new Rectangle( bounds );
|
||||
if( tree.getComponentOrientation().isLeftToRight() )
|
||||
wideBounds.width = tree.getWidth() - bounds.x - insets.right;
|
||||
else {
|
||||
wideBounds.x = insets.left;
|
||||
wideBounds.width = bounds.x + bounds.width - insets.left;
|
||||
}
|
||||
bounds = wideBounds;
|
||||
}
|
||||
|
||||
// do not paint row if editing
|
||||
if( isEditing ) {
|
||||
// paint wide selection
|
||||
@@ -795,6 +824,11 @@ public class FlatTreeUI
|
||||
return clientPropertyBoolean( tree, TREE_WIDE_SELECTION, wideSelection );
|
||||
}
|
||||
|
||||
/** @since 3.6 */
|
||||
protected boolean isWideCellRenderer() {
|
||||
return clientPropertyBoolean( tree, TREE_WIDE_CELL_RENDERER, wideCellRenderer );
|
||||
}
|
||||
|
||||
protected boolean isPaintSelection() {
|
||||
return clientPropertyBoolean( tree, TREE_PAINT_SELECTION, paintSelection );
|
||||
}
|
||||
|
||||
@@ -129,6 +129,20 @@ public class FlatUIUtils
|
||||
return insets.top == 0 && insets.left == 0 && insets.bottom == 0 && insets.right == 0;
|
||||
}
|
||||
|
||||
/** @since 3.6 */
|
||||
public static Color stateColor( boolean state, Color stateColor, Color defaultColor ) {
|
||||
return (state && stateColor != null) ? stateColor : defaultColor;
|
||||
}
|
||||
|
||||
/** @since 3.6 */
|
||||
public static Color stateColor( boolean state1, Color state1Color,
|
||||
boolean state2, Color state2Color, Color defaultColor )
|
||||
{
|
||||
return (state1 && state1Color != null)
|
||||
? state1Color
|
||||
: ((state2 && state2Color != null) ? state2Color : defaultColor);
|
||||
}
|
||||
|
||||
public static Color getUIColor( String key, int defaultColorRGB ) {
|
||||
Color color = UIManager.getColor( key );
|
||||
return (color != null) ? color : new Color( defaultColorRGB );
|
||||
|
||||
@@ -41,7 +41,7 @@ import java.util.function.Supplier;
|
||||
import javax.swing.DesktopManager;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JInternalFrame;
|
||||
import javax.swing.JLayeredPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JRootPane;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.UIManager;
|
||||
@@ -59,8 +59,6 @@ import com.formdev.flatlaf.util.UIScale;
|
||||
public abstract class FlatWindowResizer
|
||||
implements PropertyChangeListener, ComponentListener
|
||||
{
|
||||
protected final static Integer WINDOW_RESIZER_LAYER = JLayeredPane.DRAG_LAYER + 1;
|
||||
|
||||
protected final JComponent resizeComp;
|
||||
|
||||
protected final int borderDragThickness = FlatUIUtils.getUIInt( "RootPane.borderDragThickness", 5 );
|
||||
@@ -81,12 +79,12 @@ public abstract class FlatWindowResizer
|
||||
leftDragComp = createDragBorderComponent( NW_RESIZE_CURSOR, W_RESIZE_CURSOR, SW_RESIZE_CURSOR );
|
||||
rightDragComp = createDragBorderComponent( NE_RESIZE_CURSOR, E_RESIZE_CURSOR, SE_RESIZE_CURSOR );
|
||||
|
||||
Container cont = (resizeComp instanceof JRootPane) ? ((JRootPane)resizeComp).getLayeredPane() : resizeComp;
|
||||
Object cons = (cont instanceof JLayeredPane) ? WINDOW_RESIZER_LAYER : null;
|
||||
cont.add( topDragComp, cons, 0 );
|
||||
cont.add( bottomDragComp, cons, 1 );
|
||||
cont.add( leftDragComp, cons, 2 );
|
||||
cont.add( rightDragComp, cons, 3 );
|
||||
// for rootpanes, add after glasspane
|
||||
int insertIndex = (resizeComp instanceof JRootPane) ? 1 : 0;
|
||||
resizeComp.add( topDragComp, insertIndex++ );
|
||||
resizeComp.add( bottomDragComp, insertIndex++ );
|
||||
resizeComp.add( leftDragComp, insertIndex++ );
|
||||
resizeComp.add( rightDragComp, insertIndex++ );
|
||||
|
||||
resizeComp.addComponentListener( this );
|
||||
resizeComp.addPropertyChangeListener( "ancestor", this );
|
||||
@@ -105,11 +103,10 @@ public abstract class FlatWindowResizer
|
||||
resizeComp.removeComponentListener( this );
|
||||
resizeComp.removePropertyChangeListener( "ancestor", this );
|
||||
|
||||
Container cont = topDragComp.getParent();
|
||||
cont.remove( topDragComp );
|
||||
cont.remove( bottomDragComp );
|
||||
cont.remove( leftDragComp );
|
||||
cont.remove( rightDragComp );
|
||||
resizeComp.remove( topDragComp );
|
||||
resizeComp.remove( bottomDragComp );
|
||||
resizeComp.remove( leftDragComp );
|
||||
resizeComp.remove( rightDragComp );
|
||||
}
|
||||
|
||||
public void doLayout() {
|
||||
@@ -120,7 +117,7 @@ public abstract class FlatWindowResizer
|
||||
int y = 0;
|
||||
int width = resizeComp.getWidth();
|
||||
int height = resizeComp.getHeight();
|
||||
if( width == 0 || height == 0 )
|
||||
if( width <= 0 || height <= 0 )
|
||||
return;
|
||||
|
||||
Insets resizeInsets = getResizeInsets();
|
||||
@@ -191,7 +188,7 @@ public abstract class FlatWindowResizer
|
||||
protected abstract Dimension getWindowMinimumSize();
|
||||
protected abstract Dimension getWindowMaximumSize();
|
||||
|
||||
protected void beginResizing( int direction ) {}
|
||||
protected void beginResizing( int resizeDir, MouseEvent e ) {}
|
||||
protected void endResizing() {}
|
||||
|
||||
//---- interface PropertyChangeListener ----
|
||||
@@ -234,17 +231,45 @@ public abstract class FlatWindowResizer
|
||||
{
|
||||
protected Window window;
|
||||
|
||||
private final JComponent centerComp;
|
||||
private final boolean limitResizeToScreenBounds;
|
||||
|
||||
public WindowResizer( JRootPane rootPane ) {
|
||||
super( rootPane );
|
||||
|
||||
// Transparent "center" component that is made visible only while resizing window.
|
||||
// It uses same cursor as the area where resize dragging started.
|
||||
// This ensures that the cursor shape stays stable while dragging mouse
|
||||
// into the window to make window smaller. Otherwise it would toggling between
|
||||
// resize and standard cursor because the component layout is not updated
|
||||
// fast enough and the mouse cursor is always updated from the component
|
||||
// at the mouse location.
|
||||
centerComp = new JPanel();
|
||||
centerComp.setOpaque( false );
|
||||
centerComp.setVisible( false );
|
||||
rootPane.add( centerComp, 5 );
|
||||
|
||||
// On Linux, limit window resizing to screen bounds because otherwise
|
||||
// there would be a strange effect when the mouse is moved over a sidebar
|
||||
// while resizing and the opposite window side is also resized.
|
||||
limitResizeToScreenBounds = SystemInfo.isLinux;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uninstall() {
|
||||
resizeComp.remove( centerComp );
|
||||
|
||||
super.uninstall();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doLayout() {
|
||||
super.doLayout();
|
||||
|
||||
if( centerComp != null && centerComp.isVisible() )
|
||||
centerComp.setBounds( 0, 0, resizeComp.getWidth(), resizeComp.getHeight() );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void addNotify() {
|
||||
Container parent = resizeComp.getParent();
|
||||
@@ -299,20 +324,17 @@ public abstract class FlatWindowResizer
|
||||
|
||||
@Override
|
||||
protected boolean limitToParentBounds() {
|
||||
return limitResizeToScreenBounds && window != null;
|
||||
return limitResizeToScreenBounds && window != null && window.getGraphicsConfiguration() != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Rectangle getParentBounds() {
|
||||
if( limitResizeToScreenBounds && window != null ) {
|
||||
GraphicsConfiguration gc = window.getGraphicsConfiguration();
|
||||
Rectangle bounds = gc.getBounds();
|
||||
Insets insets = window.getToolkit().getScreenInsets( gc );
|
||||
return new Rectangle( bounds.x + insets.left, bounds.y + insets.top,
|
||||
bounds.width - insets.left - insets.right,
|
||||
bounds.height - insets.top - insets.bottom );
|
||||
}
|
||||
return null;
|
||||
GraphicsConfiguration gc = window.getGraphicsConfiguration();
|
||||
Rectangle bounds = gc.getBounds();
|
||||
Insets insets = window.getToolkit().getScreenInsets( gc );
|
||||
return new Rectangle( bounds.x + insets.left, bounds.y + insets.top,
|
||||
bounds.width - insets.left - insets.right,
|
||||
bounds.height - insets.top - insets.bottom );
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -346,6 +368,37 @@ public abstract class FlatWindowResizer
|
||||
public void windowStateChanged( WindowEvent e ) {
|
||||
updateVisibility();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void beginResizing( int resizeDir, MouseEvent e ) {
|
||||
// on Linux, resize window using window manager
|
||||
if( SystemInfo.isLinux && window != null && FlatNativeLinuxLibrary.isWMUtilsSupported( window ) ) {
|
||||
int direction = -1;
|
||||
switch( resizeDir ) {
|
||||
case N_RESIZE_CURSOR: direction = FlatNativeLinuxLibrary.SIZE_TOP; break;
|
||||
case S_RESIZE_CURSOR: direction = FlatNativeLinuxLibrary.SIZE_BOTTOM; break;
|
||||
case W_RESIZE_CURSOR: direction = FlatNativeLinuxLibrary.SIZE_LEFT; break;
|
||||
case E_RESIZE_CURSOR: direction = FlatNativeLinuxLibrary.SIZE_RIGHT; break;
|
||||
case NW_RESIZE_CURSOR: direction = FlatNativeLinuxLibrary.SIZE_TOPLEFT; break;
|
||||
case NE_RESIZE_CURSOR: direction = FlatNativeLinuxLibrary.SIZE_TOPRIGHT; break;
|
||||
case SW_RESIZE_CURSOR: direction = FlatNativeLinuxLibrary.SIZE_BOTTOMLEFT; break;
|
||||
case SE_RESIZE_CURSOR: direction = FlatNativeLinuxLibrary.SIZE_BOTTOMRIGHT; break;
|
||||
}
|
||||
|
||||
if( direction >= 0 && FlatNativeLinuxLibrary.moveOrResizeWindow( window, e, direction ) )
|
||||
return;
|
||||
}
|
||||
|
||||
centerComp.setBounds( 0, 0, resizeComp.getWidth(), resizeComp.getHeight() );
|
||||
centerComp.setCursor( getPredefinedCursor( resizeDir ) );
|
||||
centerComp.setVisible( true );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void endResizing() {
|
||||
centerComp.setVisible( false );
|
||||
centerComp.setCursor( null );
|
||||
}
|
||||
}
|
||||
|
||||
//---- class InternalFrameResizer -----------------------------------------
|
||||
@@ -427,7 +480,18 @@ public abstract class FlatWindowResizer
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void beginResizing( int direction ) {
|
||||
protected void beginResizing( int resizeDir, MouseEvent e ) {
|
||||
int direction = 0;
|
||||
switch( resizeDir ) {
|
||||
case N_RESIZE_CURSOR: direction = NORTH; break;
|
||||
case S_RESIZE_CURSOR: direction = SOUTH; break;
|
||||
case W_RESIZE_CURSOR: direction = WEST; break;
|
||||
case E_RESIZE_CURSOR: direction = EAST; break;
|
||||
case NW_RESIZE_CURSOR: direction = NORTH_WEST; break;
|
||||
case NE_RESIZE_CURSOR: direction = NORTH_EAST; break;
|
||||
case SW_RESIZE_CURSOR: direction = SOUTH_WEST; break;
|
||||
case SE_RESIZE_CURSOR: direction = SOUTH_EAST; break;
|
||||
}
|
||||
desktopManager.get().beginResizingFrame( getFrame(), direction );
|
||||
}
|
||||
|
||||
@@ -535,18 +599,7 @@ debug*/
|
||||
dragRightOffset = windowBounds.x + windowBounds.width - xOnScreen;
|
||||
dragBottomOffset = windowBounds.y + windowBounds.height - yOnScreen;
|
||||
|
||||
int direction = 0;
|
||||
switch( resizeDir ) {
|
||||
case N_RESIZE_CURSOR: direction = NORTH; break;
|
||||
case S_RESIZE_CURSOR: direction = SOUTH; break;
|
||||
case W_RESIZE_CURSOR: direction = WEST; break;
|
||||
case E_RESIZE_CURSOR: direction = EAST; break;
|
||||
case NW_RESIZE_CURSOR: direction = NORTH_WEST; break;
|
||||
case NE_RESIZE_CURSOR: direction = NORTH_EAST; break;
|
||||
case SW_RESIZE_CURSOR: direction = SOUTH_WEST; break;
|
||||
case SE_RESIZE_CURSOR: direction = SOUTH_EAST; break;
|
||||
}
|
||||
beginResizing( direction );
|
||||
beginResizing( resizeDir, e );
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -21,7 +21,7 @@ import java.util.function.BiPredicate;
|
||||
/**
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
class StackUtils
|
||||
public class StackUtils
|
||||
{
|
||||
private static final StackUtils INSTANCE = new StackUtilsImpl();
|
||||
|
||||
|
||||
@@ -224,6 +224,9 @@ public class ColorFunctions
|
||||
if( functions.length == 1 && functions[0] instanceof Mix ) {
|
||||
Mix mixFunction = (Mix) functions[0];
|
||||
return mix( color, mixFunction.color2, mixFunction.weight / 100 );
|
||||
} else if( functions.length == 1 && functions[0] instanceof Mix2 ) {
|
||||
Mix2 mixFunction = (Mix2) functions[0];
|
||||
return mix( mixFunction.color1, color, mixFunction.weight / 100 );
|
||||
}
|
||||
|
||||
// convert RGB to HSL
|
||||
@@ -386,7 +389,11 @@ public class ColorFunctions
|
||||
//---- class Mix ----------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Mix two colors.
|
||||
* Mix two colors using {@link ColorFunctions#mix(Color, Color, float)}.
|
||||
* First color is passed to {@link #apply(float[])}.
|
||||
* Second color is {@link #color2}.
|
||||
* <p>
|
||||
* Use {@link Mix2} to tint or shade color.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
@@ -420,4 +427,44 @@ public class ColorFunctions
|
||||
return String.format( "mix(#%08x,%.0f%%)", color2.getRGB(), weight );
|
||||
}
|
||||
}
|
||||
|
||||
//---- class Mix2 ---------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Mix two colors using {@link ColorFunctions#mix(Color, Color, float)}.
|
||||
* First color is {@link #color1}.
|
||||
* Second color is passed to {@link #apply(float[])}.
|
||||
*
|
||||
* @since 3.6
|
||||
*/
|
||||
public static class Mix2
|
||||
implements ColorFunction
|
||||
{
|
||||
public final Color color1;
|
||||
public final float weight;
|
||||
|
||||
public Mix2( Color color1, float weight ) {
|
||||
this.color1 = color1;
|
||||
this.weight = weight;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply( float[] hsla ) {
|
||||
// convert from HSL to RGB because color mixing is done on RGB values
|
||||
Color color2 = HSLColor.toRGB( hsla[0], hsla[1], hsla[2], hsla[3] / 100 );
|
||||
|
||||
// mix
|
||||
Color color = mix( color1, color2, weight / 100 );
|
||||
|
||||
// convert RGB to HSL
|
||||
float[] hsl = HSLColor.fromRGB( color );
|
||||
System.arraycopy( hsl, 0, hsla, 0, hsl.length );
|
||||
hsla[3] = (color.getAlpha() / 255f) * 100;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format( "mix2(#%08x,%.0f%%)", color1.getRGB(), weight );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.formdev.flatlaf.util;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Font;
|
||||
import java.awt.Graphics;
|
||||
@@ -27,7 +28,9 @@ import java.awt.geom.Rectangle2D;
|
||||
import java.text.AttributedCharacterIterator;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.RepaintManager;
|
||||
import com.formdev.flatlaf.FlatLaf;
|
||||
import com.formdev.flatlaf.FlatSystemProperties;
|
||||
import com.formdev.flatlaf.ui.StackUtils;
|
||||
|
||||
/**
|
||||
* @author Karl Tauber
|
||||
@@ -323,6 +326,19 @@ public class HiDPIUtils
|
||||
public void drawGlyphVector( GlyphVector g, float x, float y ) {
|
||||
super.drawGlyphVector( g, x, y + yCorrection );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fillRect( int x, int y, int width, int height ) {
|
||||
// fix hard coded black color in HRuleView.paint() of '<hr noshade>'
|
||||
if( super.getColor() == Color.black &&
|
||||
StackUtils.wasInvokedFrom( "javax.swing.text.html.HRuleView", "paint", 4 ) )
|
||||
{
|
||||
super.setColor( FlatLaf.isLafDark() ? Color.lightGray : Color.darkGray );
|
||||
super.fillRect( x, y, width, height );
|
||||
super.setColor( Color.black );
|
||||
} else
|
||||
super.fillRect( x, y, width, height );
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@ public class SystemInfo
|
||||
public static final boolean isWindows;
|
||||
public static final boolean isMacOS;
|
||||
public static final boolean isLinux;
|
||||
/** @since 3.6 */ public static final boolean isUnknownOS;
|
||||
|
||||
// OS versions
|
||||
public static final long osVersion;
|
||||
@@ -59,6 +60,7 @@ public class SystemInfo
|
||||
public static final boolean isJetBrainsJVM_11_orLater;
|
||||
|
||||
// UI toolkits
|
||||
/** @since 3.6 */ public static final boolean isGNOME;
|
||||
public static final boolean isKDE;
|
||||
|
||||
// other
|
||||
@@ -75,6 +77,7 @@ public class SystemInfo
|
||||
isWindows = osName.startsWith( "windows" );
|
||||
isMacOS = osName.startsWith( "mac" );
|
||||
isLinux = osName.startsWith( "linux" );
|
||||
isUnknownOS = !isWindows && !isMacOS && !isLinux;
|
||||
|
||||
// OS versions
|
||||
osVersion = scanVersion( System.getProperty( "os.version" ) );
|
||||
@@ -104,7 +107,13 @@ public class SystemInfo
|
||||
isJetBrainsJVM_11_orLater = isJetBrainsJVM && isJava_11_orLater;
|
||||
|
||||
// UI toolkits
|
||||
isKDE = (isLinux && System.getenv( "KDE_FULL_SESSION" ) != null);
|
||||
String desktop = isLinux ? System.getenv( "XDG_CURRENT_DESKTOP" ) : null;
|
||||
isGNOME = (isLinux &&
|
||||
(System.getenv( "GNOME_DESKTOP_SESSION_ID" ) != null ||
|
||||
(desktop != null && desktop.contains( "GNOME" ))));
|
||||
isKDE = (isLinux &&
|
||||
(System.getenv( "KDE_FULL_SESSION" ) != null ||
|
||||
(desktop != null && desktop.contains( "KDE" ))));
|
||||
|
||||
// other
|
||||
isProjector = Boolean.getBoolean( "org.jetbrains.projector.server.enable" );
|
||||
|
||||
@@ -33,6 +33,7 @@ import javax.swing.plaf.DimensionUIResource;
|
||||
import javax.swing.plaf.FontUIResource;
|
||||
import javax.swing.plaf.InsetsUIResource;
|
||||
import javax.swing.plaf.UIResource;
|
||||
import com.formdev.flatlaf.FlatLaf;
|
||||
import com.formdev.flatlaf.FlatSystemProperties;
|
||||
|
||||
/**
|
||||
@@ -188,7 +189,9 @@ public class UIScale
|
||||
// because even if we are on a HiDPI display it is not sure
|
||||
// that a larger font size is set by the current LaF
|
||||
// (e.g. can avoid large icons with small text)
|
||||
Font font = UIManager.getFont( "defaultFont" );
|
||||
Font font = null;
|
||||
if( UIManager.getLookAndFeel() instanceof FlatLaf )
|
||||
font = UIManager.getFont( "defaultFont" );
|
||||
if( font == null )
|
||||
font = UIManager.getFont( "Label.font" );
|
||||
|
||||
@@ -244,6 +247,16 @@ public class UIScale
|
||||
}
|
||||
|
||||
private static float computeScaleFactor( Font font ) {
|
||||
String customFontSizeDivider = System.getProperty( "flatlaf.uiScale.fontSizeDivider" );
|
||||
if( customFontSizeDivider != null ) {
|
||||
try {
|
||||
float fontSizeDivider = Math.max( Integer.parseInt( customFontSizeDivider ), 10 );
|
||||
return font.getSize() / fontSizeDivider;
|
||||
} catch( NumberFormatException ex ) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
// default font size
|
||||
float fontSizeDivider = 12f;
|
||||
|
||||
|
||||
@@ -61,7 +61,6 @@ Component.arrowType = triangle
|
||||
#---- ProgressBar ----
|
||||
|
||||
ProgressBar.foreground = darken(@foreground,10%)
|
||||
ProgressBar.selectionForeground = @background
|
||||
|
||||
|
||||
#---- RadioButton ----
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
|
||||
# general background and foreground (text color)
|
||||
@background = #3c3f41
|
||||
@foreground = #bbb
|
||||
@foreground = #ddd
|
||||
@disabledBackground = @background
|
||||
@disabledForeground = shade(@foreground,25%)
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
|
||||
# selection
|
||||
@selectionBackground = @accentSelectionBackground
|
||||
@selectionForeground = contrast(@selectionBackground, @background, @foreground, 25%)
|
||||
@selectionForeground = contrast(@selectionBackground, shade(@background), tint(@foreground), 25%)
|
||||
@selectionInactiveBackground = spin(saturate(shade(@selectionBackground,70%),20%),-15)
|
||||
@selectionInactiveForeground = @foreground
|
||||
|
||||
@@ -187,6 +187,8 @@ Component.error.borderColor = desaturate($Component.error.focusedBorderColor,25%
|
||||
Component.error.focusedBorderColor = #8b3c3c
|
||||
Component.warning.borderColor = darken(desaturate($Component.warning.focusedBorderColor,20%),10%)
|
||||
Component.warning.focusedBorderColor = #ac7920
|
||||
Component.success.borderColor = desaturate($Component.success.focusedBorderColor,25%)
|
||||
Component.success.focusedBorderColor = #648b3c
|
||||
Component.custom.borderColor = desaturate(#f00,50%,relative derived noAutoInverse)
|
||||
|
||||
|
||||
@@ -262,7 +264,7 @@ PopupMenu.hoverScrollArrowBackground = lighten(@background,5%)
|
||||
ProgressBar.background = lighten(@background,8%)
|
||||
ProgressBar.foreground = @accentSliderColor
|
||||
ProgressBar.selectionBackground = @foreground
|
||||
ProgressBar.selectionForeground = contrast($ProgressBar.foreground, @background, @foreground, 25%)
|
||||
ProgressBar.selectionForeground = contrast($ProgressBar.foreground, shade(@background), tint(@foreground), 25%)
|
||||
|
||||
|
||||
#---- RootPane ----
|
||||
@@ -274,7 +276,7 @@ RootPane.inactiveBorderColor = lighten(@background,5%,derived)
|
||||
#---- ScrollBar ----
|
||||
|
||||
ScrollBar.track = lighten(@background,1%,derived noAutoInverse)
|
||||
ScrollBar.thumb = lighten($ScrollBar.track,10%,derived noAutoInverse)
|
||||
ScrollBar.thumb = lighten($ScrollBar.track,15%,derived noAutoInverse)
|
||||
ScrollBar.hoverTrackColor = lighten($ScrollBar.track,4%,derived noAutoInverse)
|
||||
ScrollBar.hoverThumbColor = lighten($ScrollBar.thumb,10%,derived noAutoInverse)
|
||||
ScrollBar.pressedThumbColor = lighten($ScrollBar.thumb,15%,derived noAutoInverse)
|
||||
@@ -284,7 +286,7 @@ ScrollBar.pressedButtonBackground = lighten(@background,10%,derived noAutoInvers
|
||||
|
||||
#---- Separator ----
|
||||
|
||||
Separator.foreground = tint(@background,10%)
|
||||
Separator.foreground = tint(@background,15%)
|
||||
|
||||
|
||||
#---- Slider ----
|
||||
@@ -341,8 +343,13 @@ TableHeader.bottomSeparatorColor = $TableHeader.separatorColor
|
||||
#---- TitlePane ----
|
||||
|
||||
TitlePane.embeddedForeground = darken($TitlePane.foreground,15%)
|
||||
TitlePane.buttonHoverBackground = lighten($TitlePane.background,15%,derived)
|
||||
TitlePane.buttonPressedBackground = lighten($TitlePane.background,10%,derived)
|
||||
TitlePane.buttonHoverBackground = lighten($TitlePane.background,10%,derived)
|
||||
TitlePane.buttonPressedBackground = lighten($TitlePane.background,6%,derived)
|
||||
|
||||
# Linux
|
||||
[linux]TitlePane.buttonBackground = lighten($TitlePane.background,5%,derived)
|
||||
[linux]TitlePane.buttonHoverBackground = lighten($TitlePane.background,10%,derived)
|
||||
[linux]TitlePane.buttonPressedBackground = lighten($TitlePane.background,15%,derived)
|
||||
|
||||
|
||||
#---- ToggleButton ----
|
||||
|
||||
@@ -50,6 +50,9 @@ mini.font = -3
|
||||
#defaultFont = ...
|
||||
|
||||
# font weights
|
||||
# fallback for unknown platform
|
||||
light.font = +0
|
||||
semibold.font = +0
|
||||
# Windows
|
||||
[win]light.font = "Segoe UI Light"
|
||||
[win]semibold.font = "Segoe UI Semibold"
|
||||
@@ -59,15 +62,12 @@ mini.font = -3
|
||||
# Linux
|
||||
[linux]light.font = "Lato Light", "Ubuntu Light", "Cantarell Light"
|
||||
[linux]semibold.font = "Lato Semibold", "Ubuntu Medium", "Montserrat SemiBold"
|
||||
# fallback for unknown platform
|
||||
light.font = +0
|
||||
semibold.font = +0
|
||||
|
||||
# monospaced
|
||||
monospaced.font = Monospaced
|
||||
[win]monospaced.font = Monospaced
|
||||
[mac]monospaced.font = Menlo, Monospaced
|
||||
[linux]monospaced.font = "Liberation Mono", "Ubuntu Mono", Monospaced
|
||||
monospaced.font = Monospaced
|
||||
|
||||
# styles
|
||||
[style].h00 = font: $h00.font
|
||||
@@ -564,8 +564,8 @@ RadioButtonMenuItem.background = @menuBackground
|
||||
#---- RootPane ----
|
||||
|
||||
RootPane.border = com.formdev.flatlaf.ui.FlatRootPaneUI$FlatWindowBorder
|
||||
RootPane.borderDragThickness = 5
|
||||
RootPane.cornerDragWidth = 16
|
||||
RootPane.borderDragThickness = 6
|
||||
RootPane.cornerDragWidth = 32
|
||||
RootPane.honorFrameMinimumSizeOnResize = false
|
||||
RootPane.honorDialogMinimumSizeOnResize = true
|
||||
|
||||
@@ -574,12 +574,12 @@ RootPane.honorDialogMinimumSizeOnResize = true
|
||||
|
||||
ScrollBar.width = 10
|
||||
ScrollBar.minimumButtonSize = 12,12
|
||||
ScrollBar.minimumThumbSize = 10,10
|
||||
ScrollBar.minimumThumbSize = 18,18
|
||||
ScrollBar.maximumThumbSize = 100000,100000
|
||||
ScrollBar.trackInsets = 0,0,0,0
|
||||
ScrollBar.thumbInsets = 0,0,0,0
|
||||
ScrollBar.thumbInsets = 2,2,2,2
|
||||
ScrollBar.trackArc = 0
|
||||
ScrollBar.thumbArc = 0
|
||||
ScrollBar.thumbArc = 999
|
||||
ScrollBar.hoverThumbWithTrack = false
|
||||
ScrollBar.pressedThumbWithTrack = false
|
||||
ScrollBar.showButtons = false
|
||||
@@ -588,15 +588,8 @@ ScrollBar.buttonArrowColor = @buttonArrowColor
|
||||
ScrollBar.buttonDisabledArrowColor = @buttonDisabledArrowColor
|
||||
ScrollBar.allowsAbsolutePositioning = true
|
||||
|
||||
[mac]ScrollBar.minimumThumbSize = 18,18
|
||||
[mac]ScrollBar.thumbInsets = 2,2,2,2
|
||||
[mac]ScrollBar.thumbArc = 999
|
||||
[mac]ScrollBar.hoverThumbWithTrack = true
|
||||
|
||||
[linux]ScrollBar.minimumThumbSize = 18,18
|
||||
[linux]ScrollBar.thumbInsets = 2,2,2,2
|
||||
[linux]ScrollBar.thumbArc = 999
|
||||
|
||||
|
||||
#---- ScrollPane ----
|
||||
|
||||
@@ -823,9 +816,14 @@ TitlePane.iconMargins = 3,8,3,8
|
||||
TitlePane.titleMargins = 3,0,3,0
|
||||
TitlePane.titleMinimumWidth = 60
|
||||
TitlePane.buttonSize = 44,30
|
||||
TitlePane.buttonInsets = 0,0,0,0
|
||||
TitlePane.buttonArc = 0
|
||||
TitlePane.buttonMinimumWidth = 30
|
||||
TitlePane.buttonMaximizedHeight = 22
|
||||
TitlePane.buttonSymbolHeight = 10
|
||||
TitlePane.buttonsGap = 0
|
||||
TitlePane.buttonsMargins = 0,0,0,0
|
||||
TitlePane.buttonsFillVertically = true
|
||||
TitlePane.centerTitle = false
|
||||
TitlePane.centerTitleIfMenuBarEmbedded = true
|
||||
TitlePane.showIconBesideTitle = false
|
||||
@@ -856,6 +854,27 @@ TitlePane.small.iconifyIcon = com.formdev.flatlaf.icons.FlatWindowIconifyIcon, s
|
||||
TitlePane.small.maximizeIcon = com.formdev.flatlaf.icons.FlatWindowMaximizeIcon, small
|
||||
TitlePane.small.restoreIcon = com.formdev.flatlaf.icons.FlatWindowRestoreIcon, small
|
||||
|
||||
# Linux
|
||||
[linux]TitlePane.buttonSize = 26,26
|
||||
[linux]TitlePane.buttonInsets = 2,2,2,2
|
||||
[linux]TitlePane.buttonArc = 999
|
||||
[linux]TitlePane.buttonMaximizedHeight = -1
|
||||
[linux]TitlePane.buttonSymbolHeight = 8
|
||||
[linux]TitlePane.buttonsGap = 8
|
||||
[linux]TitlePane.buttonsMargins = 4,4,4,4
|
||||
[linux]TitlePane.buttonsFillVertically = false
|
||||
[linux]TitlePane.small.buttonSize = 20,20
|
||||
[linux]TitlePane.small.buttonInsets = 1,1,1,1
|
||||
[linux]TitlePane.small.buttonSymbolHeight = 6
|
||||
[linux]TitlePane.small.buttonsGap = 4
|
||||
[linux]TitlePane.small.buttonsMargins = 2,2,2,2
|
||||
[linux]TitlePane.closeBackground = $?TitlePane.buttonBackground
|
||||
[linux]TitlePane.closeInactiveBackground = $?TitlePane.buttonInactiveBackground
|
||||
[linux]TitlePane.closeHoverBackground = $?TitlePane.buttonHoverBackground
|
||||
[linux]TitlePane.closePressedBackground = $?TitlePane.buttonPressedBackground
|
||||
[linux]TitlePane.closeHoverForeground = $?TitlePane.foreground
|
||||
[linux]TitlePane.closePressedForeground = $?TitlePane.foreground
|
||||
|
||||
|
||||
#---- ToggleButton ----
|
||||
|
||||
@@ -934,6 +953,7 @@ Tree.rendererMargins = 1,2,1,2
|
||||
Tree.selectionInsets = 0,0,0,0
|
||||
Tree.selectionArc = 0
|
||||
Tree.wideSelection = true
|
||||
Tree.wideCellRenderer = false
|
||||
Tree.repaintWholeRow = true
|
||||
Tree.paintLines = false
|
||||
Tree.showCellFocusIndicator = false
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
@background = #f2f2f2
|
||||
@foreground = #000
|
||||
@disabledBackground = @background
|
||||
@disabledForeground = tint(@foreground,55%)
|
||||
@disabledForeground = tint(@foreground,50%)
|
||||
|
||||
# component background
|
||||
@buttonBackground = lighten(@background,5%)
|
||||
@@ -194,6 +194,8 @@ Component.error.borderColor = lighten(desaturate($Component.error.focusedBorderC
|
||||
Component.error.focusedBorderColor = #e53e4d
|
||||
Component.warning.borderColor = lighten(saturate($Component.warning.focusedBorderColor,25%),20%)
|
||||
Component.warning.focusedBorderColor = #e2a53a
|
||||
Component.success.borderColor = lighten(desaturate($Component.success.focusedBorderColor,20%),25%)
|
||||
Component.success.focusedBorderColor = #14dc92
|
||||
Component.custom.borderColor = lighten(desaturate(#f00,20%,derived noAutoInverse),25%,derived noAutoInverse)
|
||||
|
||||
|
||||
@@ -280,7 +282,7 @@ RootPane.inactiveBorderColor = darken(@background,30%,derived)
|
||||
#---- ScrollBar ----
|
||||
|
||||
ScrollBar.track = lighten(@background,1%,derived noAutoInverse)
|
||||
ScrollBar.thumb = darken($ScrollBar.track,10%,derived noAutoInverse)
|
||||
ScrollBar.thumb = darken($ScrollBar.track,15%,derived noAutoInverse)
|
||||
ScrollBar.hoverTrackColor = darken($ScrollBar.track,3%,derived noAutoInverse)
|
||||
ScrollBar.hoverThumbColor = darken($ScrollBar.thumb,10%,derived noAutoInverse)
|
||||
ScrollBar.pressedThumbColor = darken($ScrollBar.thumb,20%,derived noAutoInverse)
|
||||
@@ -347,8 +349,13 @@ TableHeader.bottomSeparatorColor = $TableHeader.separatorColor
|
||||
#---- TitlePane ----
|
||||
|
||||
TitlePane.embeddedForeground = lighten($TitlePane.foreground,35%)
|
||||
TitlePane.buttonHoverBackground = darken($TitlePane.background,10%,derived)
|
||||
TitlePane.buttonPressedBackground = darken($TitlePane.background,8%,derived)
|
||||
TitlePane.buttonHoverBackground = darken($TitlePane.background,5%,derived)
|
||||
TitlePane.buttonPressedBackground = darken($TitlePane.background,3%,derived)
|
||||
|
||||
# Linux
|
||||
[linux]TitlePane.buttonBackground = darken($TitlePane.background,5%,derived)
|
||||
[linux]TitlePane.buttonHoverBackground = darken($TitlePane.background,10%,derived)
|
||||
[linux]TitlePane.buttonPressedBackground = darken($TitlePane.background,15%,derived)
|
||||
|
||||
|
||||
#---- ToggleButton ----
|
||||
|
||||
@@ -21,27 +21,41 @@
|
||||
# - https://www.formdev.com/flatlaf/properties-files/
|
||||
# - https://www.formdev.com/flatlaf/how-to-customize/
|
||||
#
|
||||
# Properties in this file are applied in following order:
|
||||
# 1. properties without '{...}' and without '[...]' prefix
|
||||
# 2. properties specified in .theme.json file
|
||||
# 3. properties starting with '{*}'
|
||||
# 4. properties starting with '{*-light}' or '{*-dark}'
|
||||
# 5. properties starting with '{author-<author>}',
|
||||
# where '<author>' is replaced with "author" value from .theme.json file
|
||||
# 6. properties starting with '{<name>---<author>}',
|
||||
# where '<name>' and '<author>' are replaced with "name" and "author" values from .theme.json file
|
||||
# 7. properties starting with '{<name>}',
|
||||
# where '<name>' is replaced with "name" value from .theme.json file
|
||||
# 8. properties with '[...]' prefix
|
||||
#
|
||||
|
||||
|
||||
#---- system colors ----
|
||||
|
||||
# fix (most) system colors because they are usually not set in .json files
|
||||
desktop = lazy(TextField.background)
|
||||
activeCaptionText = lazy(TextField.foreground)
|
||||
inactiveCaptionText = lazy(TextField.foreground)
|
||||
window = lazy(Panel.background)
|
||||
windowBorder = lazy(TextField.foreground)
|
||||
windowText = lazy(TextField.foreground)
|
||||
menu = lazy(Menu.background)
|
||||
menuText = lazy(Menu.foreground)
|
||||
text = lazy(TextField.background)
|
||||
textText = lazy(TextField.foreground)
|
||||
textHighlight = lazy(TextField.selectionBackground)
|
||||
textHighlightText = lazy(TextField.selectionForeground)
|
||||
textInactiveText = lazy(TextField.inactiveForeground)
|
||||
control = lazy(Panel.background)
|
||||
controlText = lazy(TextField.foreground)
|
||||
info = lazy(ToolTip.background)
|
||||
infoText = lazy(ToolTip.foreground)
|
||||
desktop = $TextField.background
|
||||
activeCaptionText = $TextField.foreground
|
||||
inactiveCaptionText = $TextField.foreground
|
||||
window = $Panel.background
|
||||
windowBorder = $TextField.foreground
|
||||
windowText = $TextField.foreground
|
||||
menu = $Menu.background
|
||||
menuText = $Menu.foreground
|
||||
text = $TextField.background
|
||||
textText = $TextField.foreground
|
||||
textHighlight = $TextField.selectionBackground
|
||||
textHighlightText = $TextField.selectionForeground
|
||||
textInactiveText = $TextField.inactiveForeground
|
||||
control = $Panel.background
|
||||
controlText = $TextField.foreground
|
||||
info = $ToolTip.background
|
||||
infoText = $ToolTip.foreground
|
||||
|
||||
|
||||
#---- variables ----
|
||||
@@ -49,26 +63,13 @@ infoText = lazy(ToolTip.foreground)
|
||||
# make sure that accent color (set via FlatLaf.setSystemColorGetter()) is ignored
|
||||
@accentColor = null
|
||||
|
||||
# use same accent color for checkmark, slider, tab underline, etc.
|
||||
@accentBase2Color = @accentBaseColor
|
||||
|
||||
# use fixed color because it is used in borders
|
||||
@cellFocusColor = #222
|
||||
|
||||
|
||||
#---- Button ----
|
||||
|
||||
Button.startBackground = $Button.background
|
||||
Button.endBackground = $Button.background
|
||||
Button.startBorderColor = $Button.borderColor
|
||||
Button.endBorderColor = $Button.borderColor
|
||||
|
||||
Button.default.startBackground = $Button.default.background
|
||||
Button.default.endBackground = $Button.default.background
|
||||
Button.default.startBorderColor = $Button.default.borderColor
|
||||
Button.default.endBorderColor = $Button.default.borderColor
|
||||
|
||||
Button.hoverBorderColor = null
|
||||
Button.default.hoverBorderColor = null
|
||||
|
||||
|
||||
#---- CheckBoxMenuItem ----
|
||||
|
||||
# colors from intellij/checkmark.svg and darcula/checkmark.svg
|
||||
@@ -76,34 +77,33 @@ Button.default.hoverBorderColor = null
|
||||
[dark]CheckBoxMenuItem.icon.checkmarkColor=#fff9
|
||||
|
||||
|
||||
#---- Component ----
|
||||
|
||||
Component.accentColor = lazy(ProgressBar.foreground)
|
||||
|
||||
|
||||
#---- HelpButton ----
|
||||
|
||||
HelpButton.hoverBorderColor = null
|
||||
|
||||
|
||||
#---- Slider ----
|
||||
|
||||
Slider.focusedColor = fade($Component.focusColor,40%,derived)
|
||||
# this "reverses" definition in FlatLightLaf/FlatDarkLaf.properties
|
||||
Slider.trackValueColor = $Slider.thumbColor
|
||||
Slider.thumbColor = @accentSliderColor
|
||||
|
||||
|
||||
#---- Spinner ----
|
||||
|
||||
# Spinner arrow button always has same colors as ComboBox arrow button
|
||||
Spinner.buttonBackground = $ComboBox.buttonEditableBackground
|
||||
Spinner.buttonArrowColor = $ComboBox.buttonArrowColor
|
||||
Spinner.buttonDisabledArrowColor = $ComboBox.buttonDisabledArrowColor
|
||||
|
||||
|
||||
#---- TabbedPane ----
|
||||
|
||||
# colors from JBUI.CurrentTheme.DefaultTabs.inactiveUnderlineColor()
|
||||
[light]TabbedPane.inactiveUnderlineColor = #9ca7b8
|
||||
[dark]TabbedPane.inactiveUnderlineColor = #747a80
|
||||
{*-light}TabbedPane.inactiveUnderlineColor = #9ca7b8
|
||||
{*-dark}TabbedPane.inactiveUnderlineColor = #747a80
|
||||
|
||||
|
||||
#---- ToggleButton ----
|
||||
|
||||
ToggleButton.startBackground = $ToggleButton.background
|
||||
ToggleButton.endBackground = $ToggleButton.background
|
||||
[dark]ToggleButton.selectedBackground = lighten($ToggleButton.background,15%,derived)
|
||||
[dark]ToggleButton.disabledSelectedBackground = lighten($ToggleButton.background,5%,derived)
|
||||
{*}ToggleButton.background = $Button.background
|
||||
{*-dark}ToggleButton.selectedBackground = lighten($ToggleButton.background,15%,derived)
|
||||
{*-dark}ToggleButton.disabledSelectedBackground = lighten($ToggleButton.background,5%,derived)
|
||||
|
||||
|
||||
#---- theme specific ----
|
||||
@@ -112,357 +112,434 @@ ToggleButton.endBackground = $ToggleButton.background
|
||||
@ijMenuCheckBackgroundL20 = lighten(@selectionBackground,20%,derived noAutoInverse)
|
||||
@ijMenuCheckBackgroundD10 = darken(@selectionBackground,10%,derived noAutoInverse)
|
||||
|
||||
@ijTextBackgroundL3 = lighten(Panel.background,3%,lazy)
|
||||
@ijTextBackgroundL4 = lighten(Panel.background,4%,lazy)
|
||||
@ijSeparatorLight = shade(@background,15%)
|
||||
@ijSeparatorDark = tint(@background,25%)
|
||||
|
||||
[Arc_Theme]CheckBoxMenuItem.foreground = lazy(MenuItem.foreground)
|
||||
[Arc_Theme]PopupMenu.foreground = lazy(MenuItem.foreground)
|
||||
[Arc_Theme]RadioButtonMenuItem.foreground = lazy(MenuItem.foreground)
|
||||
[Arc_Theme]ProgressBar.selectionBackground = #000
|
||||
[Arc_Theme]ProgressBar.selectionForeground = #fff
|
||||
[Arc_Theme]List.selectionInactiveForeground = #fff
|
||||
[Arc_Theme]Table.selectionInactiveForeground = #fff
|
||||
[Arc_Theme]Tree.selectionInactiveForeground = #fff
|
||||
@ijTextBackgroundL3 = lighten($Panel.background,3%)
|
||||
@ijTextBackgroundL4 = lighten($Panel.background,4%)
|
||||
|
||||
[Arc_Theme_-_Orange]CheckBoxMenuItem.foreground = lazy(MenuItem.foreground)
|
||||
[Arc_Theme_-_Orange]PopupMenu.foreground = lazy(MenuItem.foreground)
|
||||
[Arc_Theme_-_Orange]RadioButtonMenuItem.foreground = lazy(MenuItem.foreground)
|
||||
[Arc_Theme_-_Orange]ProgressBar.selectionBackground = #000
|
||||
[Arc_Theme_-_Orange]ProgressBar.selectionForeground = #fff
|
||||
[Arc_Theme_-_Orange]List.selectionInactiveForeground = #fff
|
||||
[Arc_Theme_-_Orange]Table.selectionInactiveForeground = #fff
|
||||
[Arc_Theme_-_Orange]Tree.selectionInactiveForeground = #fff
|
||||
{Arc_Theme}@selectionInactiveForeground = @selectionForeground
|
||||
{Arc_Theme}CheckBoxMenuItem.foreground = $MenuItem.foreground
|
||||
{Arc_Theme}PopupMenu.foreground = $MenuItem.foreground
|
||||
{Arc_Theme}RadioButtonMenuItem.foreground = $MenuItem.foreground
|
||||
|
||||
[Arc_Theme_Dark]CheckBoxMenuItem.foreground = lazy(MenuItem.foreground)
|
||||
[Arc_Theme_Dark]PopupMenu.foreground = lazy(MenuItem.foreground)
|
||||
[Arc_Theme_Dark]RadioButtonMenuItem.foreground = lazy(MenuItem.foreground)
|
||||
[Arc_Theme_Dark]ProgressBar.selectionBackground = #ddd
|
||||
[Arc_Theme_Dark]ProgressBar.selectionForeground = #ddd
|
||||
[Arc_Theme_Dark]ToolBar.separatorColor = lazy(Separator.foreground)
|
||||
{Arc_Theme_-_Orange}@selectionInactiveForeground = @selectionForeground
|
||||
{Arc_Theme_-_Orange}CheckBoxMenuItem.foreground = $MenuItem.foreground
|
||||
{Arc_Theme_-_Orange}PopupMenu.foreground = $MenuItem.foreground
|
||||
{Arc_Theme_-_Orange}RadioButtonMenuItem.foreground = $MenuItem.foreground
|
||||
|
||||
[Arc_Theme_Dark_-_Orange]CheckBoxMenuItem.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]ProgressBar.selectionBackground = #ddd
|
||||
[Arc_Theme_Dark_-_Orange]ProgressBar.selectionForeground = #fff
|
||||
[Arc_Theme_Dark_-_Orange]ToolBar.separatorColor = lazy(Separator.foreground)
|
||||
{Arc_Theme_Dark}CheckBoxMenuItem.foreground = $MenuItem.foreground
|
||||
{Arc_Theme_Dark}PopupMenu.foreground = $MenuItem.foreground
|
||||
{Arc_Theme_Dark}RadioButtonMenuItem.foreground = $MenuItem.foreground
|
||||
{Arc_Theme_Dark}ToolBar.background = @background
|
||||
|
||||
[Carbon]Table.selectionBackground = lazy(List.selectionBackground)
|
||||
[Carbon]Table.selectionInactiveForeground = lazy(List.selectionInactiveForeground)
|
||||
[Carbon]TextField.background = @ijTextBackgroundL4
|
||||
{Arc_Theme_Dark_-_Orange}CheckBoxMenuItem.foreground = $MenuItem.foreground
|
||||
{Arc_Theme_Dark_-_Orange}PopupMenu.foreground = $MenuItem.foreground
|
||||
{Arc_Theme_Dark_-_Orange}ProgressBar.selectionForeground = #fff
|
||||
{Arc_Theme_Dark_-_Orange}RadioButtonMenuItem.foreground = $MenuItem.foreground
|
||||
{Arc_Theme_Dark_-_Orange}ToolBar.background = @background
|
||||
|
||||
[Cobalt_2]Component.accentColor = lazy(Component.focusColor)
|
||||
[Cobalt_2]CheckBox.icon.background = #002946
|
||||
[Cobalt_2]CheckBox.icon.checkmarkColor = #002946
|
||||
[Cobalt_2]MenuItem.checkBackground = @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)
|
||||
{Carbon}Separator.foreground = @ijSeparatorDark
|
||||
{Carbon}ToolBar.separatorColor = $Separator.foreground
|
||||
{Carbon}Table.selectionBackground = $List.selectionBackground
|
||||
{Carbon}TextField.background = @ijTextBackgroundL4
|
||||
|
||||
[Cyan_light]MenuItem.checkBackground = @ijMenuCheckBackgroundL20
|
||||
[Cyan_light]MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundL20
|
||||
{Cobalt_2}@accentBaseColor = $ColorPalette.hue3
|
||||
{Cobalt_2}CheckBox.icon.background = @background
|
||||
{Cobalt_2}MenuItem.checkBackground = @ijMenuCheckBackgroundL10
|
||||
{Cobalt_2}MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundL10
|
||||
{Cobalt_2}ComboBox.background = @ijTextBackgroundL3
|
||||
{Cobalt_2}Slider.thumbColor = $ProgressBar.foreground
|
||||
{Cobalt_2}Slider.disabledTrackColor = $Separator.foreground
|
||||
{Cobalt_2}TextField.background = @ijTextBackgroundL3
|
||||
{Cobalt_2}Table.background = $List.background
|
||||
{Cobalt_2}Tree.background = $List.background
|
||||
|
||||
[Dark_Flat_Theme]*.inactiveForeground = #808080
|
||||
[Dark_Flat_Theme]Component.accentColor = lazy(List.selectionBackground)
|
||||
[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)
|
||||
{Cyan_light}@disabledForeground = tint(@foreground,30%)
|
||||
{Cyan_light}*.disabledText = @disabledForeground
|
||||
{Cyan_light}*.disabledForeground = @disabledForeground
|
||||
{Cyan_light}*.inactiveForeground = @disabledForeground
|
||||
{Cyan_light}Button.background = @buttonBackground
|
||||
{Cyan_light}MenuItem.checkBackground = @ijMenuCheckBackgroundL20
|
||||
{Cyan_light}MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundL20
|
||||
|
||||
[Dark_purple]Slider.focusedColor = fade($Component.focusColor,70%,derived)
|
||||
{Dark_Flat_Theme}@accentBaseColor = $TabbedPane.underlineColor
|
||||
{Dark_Flat_Theme}@disabledForeground = #808080
|
||||
{Dark_Flat_Theme}*.disabledText = @disabledForeground
|
||||
{Dark_Flat_Theme}*.disabledForeground = @disabledForeground
|
||||
{Dark_Flat_Theme}*.inactiveForeground = @disabledForeground
|
||||
{Dark_Flat_Theme}TableHeader.background = #3B3B3B
|
||||
{Dark_Flat_Theme}CheckBoxMenuItem.selectionForeground = $MenuItem.selectionForeground
|
||||
{Dark_Flat_Theme}ComboBox.background = $TextField.background
|
||||
{Dark_Flat_Theme}ComboBox.buttonBackground = $ComboBox.background
|
||||
{Dark_Flat_Theme}List.selectionForeground = $Tree.selectionForeground
|
||||
{Dark_Flat_Theme}ProgressBar.selectionForeground = @foreground
|
||||
{Dark_Flat_Theme}RadioButtonMenuItem.selectionForeground = $MenuItem.selectionForeground
|
||||
{Dark_Flat_Theme}Separator.foreground = @ijSeparatorDark
|
||||
{Dark_Flat_Theme}Slider.trackColor = $ProgressBar.background
|
||||
{Dark_Flat_Theme}Slider.thumbColor = fade($ProgressBar.foreground,100%)
|
||||
{Dark_Flat_Theme}TextPane.foreground = $TextField.foreground
|
||||
{Dark_Flat_Theme}ToggleButton.foreground = $Button.foreground
|
||||
|
||||
[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.selectionForeground = #fff
|
||||
{Dracula---Zihan_Ma}CheckBox.icon.background = @background
|
||||
{Dracula---Zihan_Ma}ComboBox.selectionBackground = $List.selectionBackground
|
||||
{Dracula---Zihan_Ma}ProgressBar.selectionBackground = #fff
|
||||
{Dracula---Zihan_Ma}ProgressBar.selectionForeground = #fff
|
||||
{Dracula---Zihan_Ma}Slider.trackColor = $?ColorPalette.selectionBackground
|
||||
{Dracula---Zihan_Ma}ToggleButton.foreground = $Button.foreground
|
||||
|
||||
[Gradianto_Dark_Fuchsia]*.selectionBackground = #8452a7
|
||||
[Gradianto_Dark_Fuchsia]*.selectionInactiveBackground = #562C6A
|
||||
[Gradianto_Dark_Fuchsia]MenuItem.checkBackground = @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_Dark_Fuchsia}MenuItem.checkBackground = @ijMenuCheckBackgroundL10
|
||||
{Gradianto_Dark_Fuchsia}MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundL10
|
||||
{Gradianto_Dark_Fuchsia}TextField.background = @ijTextBackgroundL4
|
||||
{Gradianto_Dark_Fuchsia}Tree.background = $List.background
|
||||
{Gradianto_Dark_Fuchsia}Tree.selectionInactiveBackground = $List.selectionInactiveBackground
|
||||
{Gradianto_Dark_Fuchsia}Separator.foreground = @ijSeparatorDark
|
||||
{Gradianto_Dark_Fuchsia}ToolBar.separatorColor = $Separator.foreground
|
||||
{Gradianto_Dark_Fuchsia}ProgressBar.background = $ScrollBar.track
|
||||
{Gradianto_Dark_Fuchsia}Slider.trackColor = $ScrollBar.track
|
||||
|
||||
[Gradianto_Deep_Ocean]TextField.background = @ijTextBackgroundL3
|
||||
[Gradianto_Deep_Ocean]Tree.background = lazy(List.background)
|
||||
{Gradianto_Deep_Ocean}Separator.foreground = @ijSeparatorDark
|
||||
{Gradianto_Deep_Ocean}ToolBar.separatorColor = $Separator.foreground
|
||||
{Gradianto_Deep_Ocean}TextField.background = @ijTextBackgroundL3
|
||||
{Gradianto_Deep_Ocean}Tree.background = $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_Midnight_Blue}ScrollBar.thumb = #533B6B
|
||||
{Gradianto_Midnight_Blue}Separator.foreground = @ijSeparatorDark
|
||||
{Gradianto_Midnight_Blue}ToolBar.separatorColor = $Separator.foreground
|
||||
{Gradianto_Midnight_Blue}Table.selectionForeground = $List.selectionForeground
|
||||
{Gradianto_Midnight_Blue}TextField.background = @ijTextBackgroundL4
|
||||
{Gradianto_Midnight_Blue}Tree.background = $List.background
|
||||
|
||||
[Gradianto_Nature_Green]Table.selectionForeground = lazy(List.selectionForeground)
|
||||
[Gradianto_Nature_Green]TextField.background = @ijTextBackgroundL4
|
||||
{Gradianto_Nature_Green}Separator.foreground = @ijSeparatorDark
|
||||
{Gradianto_Nature_Green}ToolBar.separatorColor = $Separator.foreground
|
||||
{Gradianto_Nature_Green}Table.selectionForeground = $List.selectionForeground
|
||||
{Gradianto_Nature_Green}TextField.background = @ijTextBackgroundL4
|
||||
|
||||
[Gray]Separator.foreground = lazy(Slider.trackColor)
|
||||
[Gray]ToolBar.separatorColor = lazy(Slider.trackColor)
|
||||
{Gray}@disabledForeground = tint(@foreground,40%)
|
||||
{Gray}*.disabledText = @disabledForeground
|
||||
{Gray}*.disabledForeground = @disabledForeground
|
||||
{Gray}*.inactiveForeground = @disabledForeground
|
||||
{Gray}Button.background = @buttonBackground
|
||||
{Gray}Separator.foreground = @ijSeparatorLight
|
||||
{Gray}ToolBar.separatorColor = $Separator.foreground
|
||||
|
||||
[Gruvbox_Dark_Hard]Component.accentColor = lazy(TabbedPane.underlineColor)
|
||||
[Gruvbox_Dark_Hard]ToggleButton.selectedBackground = $ToggleButton.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_Hard}@accentBaseColor = #4B6EAF
|
||||
{Gruvbox_Dark_Hard}ComboBox.background = @ijTextBackgroundL3
|
||||
{Gruvbox_Dark_Hard}ComboBox.buttonBackground = $ComboBox.background
|
||||
{Gruvbox_Dark_Hard}TextField.background = @ijTextBackgroundL3
|
||||
|
||||
[Gruvbox_Dark_Medium]Component.accentColor = lazy(TabbedPane.underlineColor)
|
||||
[Gruvbox_Dark_Medium]ToggleButton.selectedBackground = $ToggleButton.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
|
||||
{Hiberbee_Dark}@disabledForeground = $ColorPalette.light3
|
||||
{Hiberbee_Dark}*.disabledText = @disabledForeground
|
||||
{Hiberbee_Dark}*.disabledForeground = @disabledForeground
|
||||
{Hiberbee_Dark}*.inactiveForeground = @disabledForeground
|
||||
{Hiberbee_Dark}List.selectionInactiveBackground = $Table.selectionInactiveBackground
|
||||
{Hiberbee_Dark}ProgressBar.background = $Separator.foreground
|
||||
{Hiberbee_Dark}RadioButtonMenuItem.selectionForeground = $MenuItem.selectionForeground
|
||||
{Hiberbee_Dark}Slider.trackColor = $ColorPalette.light1
|
||||
{Hiberbee_Dark}Slider.trackColor = $ColorPalette.dark10
|
||||
{Hiberbee_Dark}Slider.thumbColor = @accentBaseColor
|
||||
{Hiberbee_Dark}ToggleButton.foreground = $Button.foreground
|
||||
{Hiberbee_Dark}ToolBar.background = @background
|
||||
|
||||
[Gruvbox_Dark_Soft]Component.accentColor = lazy(TabbedPane.underlineColor)
|
||||
[Gruvbox_Dark_Soft]MenuItem.checkBackground = @ijMenuCheckBackgroundL10
|
||||
[Gruvbox_Dark_Soft]MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundL10
|
||||
[Gruvbox_Dark_Soft]ToggleButton.selectedBackground = $ToggleButton.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.selectedBackground = #434241
|
||||
[Hiberbee_Dark]TabbedPane.selectedForeground = #70D7FF
|
||||
[Hiberbee_Dark]ToggleButton.selectedBackground = $ToggleButton.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]ToggleButton.selectedBackground = #fff
|
||||
[High_contrast]ToggleButton.selectedForeground = #000
|
||||
[High_contrast]ToggleButton.disabledSelectedBackground = #444
|
||||
[High_contrast]ToggleButton.toolbar.selectedBackground = #fff
|
||||
[High_contrast][style]Button.inTextField = \
|
||||
{High_Contrast}@accentBaseColor = $TabbedPane.underlineColor
|
||||
{High_Contrast}Slider.thumbBorderColor = $Slider.thumbColor
|
||||
{High_Contrast}Slider.focusedThumbBorderColor = @background
|
||||
{High_Contrast}Slider.focusedColor = $Component.focusColor
|
||||
{High_Contrast}Slider.focusWidth = 2
|
||||
{High_Contrast}ToggleButton.selectedBackground = @selectionBackground
|
||||
{High_Contrast}ToggleButton.selectedForeground = @selectionForeground
|
||||
{High_Contrast}ToggleButton.disabledSelectedBackground = shade(@selectionBackground,50%)
|
||||
{High_Contrast}ToggleButton.toolbar.selectedBackground = @selectionBackground
|
||||
{High_Contrast}[style]Button.inTextField = \
|
||||
toolbar.hoverBackground: #444; \
|
||||
toolbar.pressedBackground: #666; \
|
||||
toolbar.selectedBackground: #fff
|
||||
[High_contrast][style]ToggleButton.inTextField = $[High_contrast][style]Button.inTextField
|
||||
toolbar.selectedBackground: @selectionBackground
|
||||
|
||||
[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]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]TextPane.foreground = lazy(TextField.foreground)
|
||||
[Light_Flat]CheckBoxMenuItem.selectionForeground = lazy(MenuItem.selectionForeground)
|
||||
[Light_Flat]RadioButtonMenuItem.selectionForeground = lazy(MenuItem.selectionForeground)
|
||||
{Light_Flat}@accentBaseColor = $TabbedPane.underlineColor
|
||||
{Light_Flat}@accentFocusColor = lighten(@accentBaseColor,15%)
|
||||
{Light_Flat}@disabledForeground = #808080
|
||||
{Light_Flat}*.disabledText = @disabledForeground
|
||||
{Light_Flat}*.disabledForeground = @disabledForeground
|
||||
{Light_Flat}*.inactiveForeground = @disabledForeground
|
||||
{Light_Flat}CheckBox.icon[filled].background = #fff
|
||||
{Light_Flat}CheckBox.icon[filled].checkmarkColor = #fff
|
||||
{Light_Flat}ComboBox.background = $ComboBox.editableBackground
|
||||
{Light_Flat}ComboBox.buttonBackground = $ComboBox.background
|
||||
{Light_Flat}ProgressBar.selectionForeground = @foreground
|
||||
{Light_Flat}Separator.foreground = @ijSeparatorLight
|
||||
{Light_Flat}TableHeader.background = #E5E5E9
|
||||
{Light_Flat}TextPane.foreground = $TextField.foreground
|
||||
{Light_Flat}ToggleButton.foreground = $Button.foreground
|
||||
{Light_Flat}CheckBoxMenuItem.selectionForeground = $MenuItem.selectionForeground
|
||||
{Light_Flat}RadioButtonMenuItem.selectionForeground = $MenuItem.selectionForeground
|
||||
|
||||
[Monocai]Button.default.foreground = #2D2A2F
|
||||
[Monocai]MenuItem.checkBackground = @ijMenuCheckBackgroundL10
|
||||
[Monocai]MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundL10
|
||||
@Monocai.acceleratorForeground = lazy(MenuItem.disabledForeground)
|
||||
@Monocai.acceleratorSelectionForeground = lighten(MenuItem.disabledForeground,10%,lazy)
|
||||
[Monocai]CheckBoxMenuItem.acceleratorForeground = @Monocai.acceleratorForeground
|
||||
[Monocai]CheckBoxMenuItem.acceleratorSelectionForeground = @Monocai.acceleratorSelectionForeground
|
||||
[Monocai]Menu.acceleratorForeground = @Monocai.acceleratorForeground
|
||||
[Monocai]Menu.acceleratorSelectionForeground = @Monocai.acceleratorSelectionForeground
|
||||
[Monocai]MenuItem.acceleratorForeground = @Monocai.acceleratorForeground
|
||||
[Monocai]MenuItem.acceleratorSelectionForeground = @Monocai.acceleratorSelectionForeground
|
||||
[Monocai]RadioButtonMenuItem.acceleratorForeground = @Monocai.acceleratorForeground
|
||||
[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
|
||||
{Monocai}@accentUnderlineColor = @accentBaseColor
|
||||
{Monocai}*.acceleratorForeground = @menuAcceleratorForeground
|
||||
{Monocai}*.acceleratorSelectionForeground = @menuAcceleratorSelectionForeground
|
||||
{Monocai}Button.default.foreground = @background
|
||||
{Monocai}MenuItem.checkBackground = @ijMenuCheckBackgroundL10
|
||||
{Monocai}TabbedPane.underlineColor = @accentUnderlineColor
|
||||
{Monocai}TextField.background = @ijTextBackgroundL4
|
||||
@Monocai.selectionBackground = $TextField.selectionBackground
|
||||
{Monocai}ComboBox.selectionBackground = @Monocai.selectionBackground
|
||||
{Monocai}List.selectionBackground = @Monocai.selectionBackground
|
||||
{Monocai}Table.selectionBackground = @Monocai.selectionBackground
|
||||
{Monocai}Tree.selectionBackground = @Monocai.selectionBackground
|
||||
@Monocai.selectionInactiveBackground = $MenuItem.selectionBackground
|
||||
{Monocai}List.selectionInactiveBackground = @Monocai.selectionInactiveBackground
|
||||
{Monocai}Table.selectionInactiveBackground = @Monocai.selectionInactiveBackground
|
||||
{Monocai}Tree.selectionInactiveBackground = @Monocai.selectionInactiveBackground
|
||||
|
||||
[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)
|
||||
{Monokai_Pro---Subtheme}@disabledForeground = shade(@foreground,40%)
|
||||
{Monokai_Pro---Subtheme}*.disabledText = @disabledForeground
|
||||
{Monokai_Pro---Subtheme}*.disabledForeground = @disabledForeground
|
||||
{Monokai_Pro---Subtheme}*.inactiveForeground = @disabledForeground
|
||||
{Monokai_Pro---Subtheme}ProgressBar.selectionBackground = #fff
|
||||
{Monokai_Pro---Subtheme}Table.selectionInactiveForeground = $List.selectionInactiveForeground
|
||||
{Monokai_Pro---Subtheme}Tree.selectionBackground = $List.selectionBackground
|
||||
{Monokai_Pro---Subtheme}ToggleButton.foreground = $Button.foreground
|
||||
{Monokai_Pro---Subtheme}Separator.foreground = @ijSeparatorDark
|
||||
{Monokai_Pro---Subtheme}ToolBar.separatorColor = $Separator.foreground
|
||||
{Monokai_Pro---Subtheme}ToolBar.background = @background
|
||||
|
||||
[Nord]*.inactiveForeground = #616E88
|
||||
[Nord]MenuItem.checkBackground = @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)
|
||||
{Nord}@disabledForeground = #616E88
|
||||
{Nord}*.disabledText = @disabledForeground
|
||||
{Nord}*.disabledForeground = @disabledForeground
|
||||
{Nord}*.inactiveForeground = @disabledForeground
|
||||
{Nord}MenuItem.checkBackground = @ijMenuCheckBackgroundL10
|
||||
{Nord}MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundL10
|
||||
{Nord}RadioButtonMenuItem.selectionBackground = $MenuItem.selectionBackground
|
||||
{Nord}ProgressBar.selectionBackground = @foreground
|
||||
{Nord}ProgressBar.selectionForeground = @background
|
||||
{Nord}List.selectionBackground = $Tree.selectionBackground
|
||||
{Nord}List.selectionForeground = $Tree.selectionForeground
|
||||
{Nord}Table.selectionBackground = $Tree.selectionBackground
|
||||
{Nord}Table.selectionForeground = $Tree.selectionForeground
|
||||
{Nord}TextField.selectionBackground = $Tree.selectionBackground
|
||||
{Nord}TextField.selectionForeground = $Tree.selectionForeground
|
||||
{Nord}Tree.selectionInactiveForeground = $List.selectionInactiveForeground
|
||||
|
||||
[NotReallyMDTheme]*.selectionInactiveBackground = #21384E
|
||||
[NotReallyMDTheme]ToolBar.separatorColor = lazy(Separator.foreground)
|
||||
{NotReallyMDTheme}*.selectionInactiveBackground = #21384E
|
||||
{NotReallyMDTheme}ToolBar.separatorColor = $Separator.foreground
|
||||
|
||||
[One_Dark]List.selectionInactiveForeground = lazy(Tree.selectionInactiveForeground)
|
||||
[One_Dark]MenuItem.checkBackground = @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]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)
|
||||
{One_Dark}MenuItem.checkBackground = @ijMenuCheckBackgroundL10
|
||||
{One_Dark}MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundL10
|
||||
{One_Dark}ProgressBar.background = $Separator.foreground
|
||||
{One_Dark}ProgressBar.selectionForeground = #fff
|
||||
{One_Dark}Table.background = $Tree.background
|
||||
{One_Dark}Table.selectionBackground = $Tree.selectionBackground
|
||||
{One_Dark}TextField.selectionBackground = $List.selectionBackground
|
||||
{One_Dark}Tree.selectionForeground = $List.selectionForeground
|
||||
|
||||
[Solarized_Dark---4lex4]*.inactiveForeground = #657B83
|
||||
[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]ToolBar.separatorColor = lazy(Separator.foreground)
|
||||
{Solarized_Dark---4lex4}@accentBaseColor = $TabbedPane.underlineColor
|
||||
{Solarized_Dark---4lex4}*.acceleratorForeground = @menuAcceleratorForeground
|
||||
{Solarized_Dark---4lex4}ComboBox.background = $ComboBox.editableBackground
|
||||
{Solarized_Dark---4lex4}ComboBox.buttonBackground = $ComboBox.editableBackground
|
||||
{Solarized_Dark---4lex4}Slider.disabledTrackColor = $ColorPalette.colorSeparator
|
||||
|
||||
[Solarized_Light---4lex4]*.inactiveForeground = #839496
|
||||
[Solarized_Light---4lex4]Button.default.hoverBackground = darken($Button.default.background,3%,derived)
|
||||
[Solarized_Light---4lex4]Component.accentColor = lazy(TabbedPane.underlineColor)
|
||||
{Solarized_Light---4lex4}@accentBaseColor = $TabbedPane.underlineColor
|
||||
{Solarized_Light---4lex4}Slider.thumbColor = $ProgressBar.foreground
|
||||
{Solarized_Light---4lex4}Slider.disabledTrackColor = $ColorPalette.colorSeparator
|
||||
|
||||
[Spacegray]ComboBox.background = @ijTextBackgroundL4
|
||||
[Spacegray]ComboBox.buttonBackground = @ijTextBackgroundL4
|
||||
[Spacegray]TextField.background = @ijTextBackgroundL4
|
||||
[Spacegray]TextField.selectionBackground = lazy(Tree.selectionBackground)
|
||||
[Spacegray]TextField.selectionForeground = lazy(Tree.selectionForeground)
|
||||
{Spacegray}ComboBox.background = @ijTextBackgroundL4
|
||||
{Spacegray}ComboBox.buttonBackground = $ComboBox.background
|
||||
{Spacegray}TextField.background = @ijTextBackgroundL4
|
||||
|
||||
[vuesion-theme]*.disabledForeground = #8C8C8C
|
||||
[vuesion-theme]*.disabledText = #8C8C8C
|
||||
[vuesion-theme]*.inactiveForeground = #8C8C8C
|
||||
[vuesion-theme]Component.accentColor = lazy(Button.default.endBackground)
|
||||
[vuesion-theme]MenuItem.checkBackground = @ijMenuCheckBackgroundL10
|
||||
[vuesion-theme]MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundL10
|
||||
[vuesion-theme]Slider.trackValueColor = #ececee
|
||||
[vuesion-theme]Slider.trackColor = #303a45
|
||||
[vuesion-theme]Slider.thumbColor = #ececee
|
||||
[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%)
|
||||
{vuesion-theme}@accentBaseColor = $TabbedPane.underlineColor
|
||||
{vuesion-theme}@disabledForeground = #8C8C8C
|
||||
{vuesion-theme}*.disabledText = @disabledForeground
|
||||
{vuesion-theme}*.disabledForeground = @disabledForeground
|
||||
{vuesion-theme}*.inactiveForeground = @disabledForeground
|
||||
{vuesion-theme}MenuItem.checkBackground = @ijMenuCheckBackgroundL10
|
||||
{vuesion-theme}MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundL10
|
||||
{vuesion-theme}ProgressBar.background = #303a45
|
||||
{vuesion-theme}ProgressBar.foreground = #ececee
|
||||
{vuesion-theme}Slider.thumbColor = #ececee
|
||||
{vuesion-theme}Slider.focusedColor = fade($Slider.thumbColor,20%)
|
||||
{vuesion-theme}ComboBox.background = @ijTextBackgroundL4
|
||||
{vuesion-theme}ComboBox.buttonBackground = $ComboBox.background
|
||||
{vuesion-theme}TextField.background = @ijTextBackgroundL4
|
||||
{vuesion-theme}TextField.selectionBackground = lighten(#303A45,15%)
|
||||
|
||||
[Xcode-Dark]TextField.background = @ijTextBackgroundL4
|
||||
{Xcode-Dark}@accentBaseColor = $List.selectionBackground
|
||||
{Xcode-Dark}TextField.background = @ijTextBackgroundL4
|
||||
|
||||
|
||||
# Material Theme UI Lite
|
||||
|
||||
[light][author-Mallowigi]MenuItem.checkBackground = @ijMenuCheckBackgroundD10
|
||||
[light][author-Mallowigi]MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundD10
|
||||
[dark][author-Mallowigi]MenuItem.checkBackground = @ijMenuCheckBackgroundL20
|
||||
[dark][author-Mallowigi]MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundL20
|
||||
{author-Mallowigi}[light]controlHighlight = lighten($controlShadow,8%)
|
||||
{author-Mallowigi}[light]controlLtHighlight = lighten($controlShadow,15%)
|
||||
{author-Mallowigi}[light]controlDkShadow = darken($controlShadow,15%)
|
||||
{author-Mallowigi}[dark]controlHighlight = darken($controlShadow,10%)
|
||||
{author-Mallowigi}[dark]controlLtHighlight = darken($controlShadow,15%)
|
||||
{author-Mallowigi}[dark]controlDkShadow = lighten($controlShadow,10%)
|
||||
|
||||
[author-Mallowigi]Tree.selectionInactiveBackground = lazy(List.selectionInactiveBackground)
|
||||
{author-Mallowigi}Button.hoverBorderColor = $Button.focusedBorderColor
|
||||
{author-Mallowigi}HelpButton.hoverBorderColor = $Button.focusedBorderColor
|
||||
|
||||
[Arc_Dark]ComboBox.selectionBackground = lazy(List.selectionBackground)
|
||||
[Arc_Dark]Table.selectionBackground = lazy(List.selectionBackground)
|
||||
{author-Mallowigi}[light]ToggleButton.selectedForeground = #000
|
||||
{author-Mallowigi}[dark]ToggleButton.selectedForeground = #fff
|
||||
|
||||
[Atom_One_Dark]Separator.foreground = lazy(Slider.trackColor)
|
||||
[Atom_One_Dark]ToolBar.separatorColor = lazy(Slider.trackColor)
|
||||
{author-Mallowigi}[light]MenuItem.checkBackground = @ijMenuCheckBackgroundD10
|
||||
{author-Mallowigi}[light]MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundD10
|
||||
{author-Mallowigi}[dark]MenuItem.checkBackground = @ijMenuCheckBackgroundL20
|
||||
{author-Mallowigi}[dark]MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundL20
|
||||
|
||||
[Atom_One_Light]List.selectionBackground = lazy(Table.selectionBackground)
|
||||
[Atom_One_Light]Tree.selectionBackground = lazy(Table.selectionBackground)
|
||||
[Atom_One_Light]TabbedPane.contentAreaColor = lazy(Separator.foreground)
|
||||
{author-Mallowigi}[light]Separator.foreground = @ijSeparatorLight
|
||||
{author-Mallowigi}[dark]Separator.foreground = @ijSeparatorDark
|
||||
{author-Mallowigi}ProgressBar.selectionBackground = @foreground
|
||||
{author-Mallowigi}TabbedPane.selectedBackground = mix(@background,$ColorPalette.table,60%)
|
||||
{author-Mallowigi}ToolBar.separatorColor = $Separator.foreground
|
||||
{author-Mallowigi}Button.foreground = @foreground
|
||||
{author-Mallowigi}Tree.foreground = @foreground
|
||||
|
||||
[Dracula---Mallowigi]*.selectionBackground = #44475A
|
||||
[Dracula---Mallowigi]List.selectionInactiveForeground = lazy(Tree.selectionInactiveForeground)
|
||||
[Dracula---Mallowigi]ProgressBar.selectionBackground = #fff
|
||||
[Dracula---Mallowigi]ProgressBar.selectionForeground = #fff
|
||||
[Dracula---Mallowigi]RadioButtonMenuItem.selectionForeground = lazy(CheckBoxMenuItem.selectionForeground)
|
||||
[Dracula---Mallowigi]Table.selectionForeground = lazy(List.selectionForeground)
|
||||
[Dracula---Mallowigi]Separator.foreground = lazy(Slider.trackColor)
|
||||
[Dracula---Mallowigi]ToolBar.separatorColor = lazy(Slider.trackColor)
|
||||
|
||||
[GitHub]ProgressBar.selectionBackground = #222
|
||||
[GitHub]ProgressBar.selectionForeground = #222
|
||||
[GitHub]TextField.background = @ijTextBackgroundL3
|
||||
[GitHub]List.selectionBackground = lazy(Table.selectionBackground)
|
||||
[GitHub]Tree.selectionBackground = lazy(Table.selectionBackground)
|
||||
{Arc_Dark}ComboBox.selectionBackground = $List.selectionBackground
|
||||
{Arc_Dark}ProgressBar.selectionBackground = #fff
|
||||
{Arc_Dark}ProgressBar.selectionForeground = #fff
|
||||
{Arc_Dark}Table.selectionBackground = $List.selectionBackground
|
||||
{Arc_Dark}Tree.selectionInactiveBackground = $List.selectionInactiveBackground
|
||||
|
||||
[GitHub_Dark]ComboBox.selectionBackground = lazy(Tree.selectionBackground)
|
||||
[GitHub_Dark]Table.selectionBackground = lazy(Tree.selectionBackground)
|
||||
[GitHub_Dark]Separator.foreground = lazy(Slider.trackColor)
|
||||
[GitHub_Dark]ToolBar.separatorColor = lazy(Slider.trackColor)
|
||||
{Atom_One_Dark}ProgressBar.selectionBackground = #fff
|
||||
{Atom_One_Dark}ProgressBar.selectionForeground = #fff
|
||||
{Atom_One_Dark}List.selectionBackground = $Table.selectionBackground
|
||||
{Atom_One_Dark}Tree.selectionBackground = $Table.selectionBackground
|
||||
{Atom_One_Dark}List.selectionInactiveBackground = $Tree.selectionInactiveBackground
|
||||
{Atom_One_Dark}Table.selectionInactiveBackground = $Tree.selectionInactiveBackground
|
||||
|
||||
[Light_Owl]CheckBoxMenuItem.selectionForeground = lazy(CheckBoxMenuItem.foreground)
|
||||
[Light_Owl]ComboBox.selectionForeground = lazy(ComboBox.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.selectionForeground = #fff
|
||||
[Light_Owl]Spinner.selectionForeground = lazy(Spinner.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)
|
||||
{Atom_One_Light}@disabledForeground = shade($ColorPalette.dis,20%)
|
||||
{Atom_One_Light}*.disabledText = @disabledForeground
|
||||
{Atom_One_Light}*.disabledForeground = @disabledForeground
|
||||
{Atom_One_Light}*.inactiveForeground = @disabledForeground
|
||||
{Atom_One_Light}TabbedPane.contentAreaColor = $Separator.foreground
|
||||
|
||||
[Material_Darker]*.selectionBackground = lighten(#2D2D2D,15%)
|
||||
[Material_Darker]Separator.foreground = lazy(Slider.trackColor)
|
||||
[Material_Darker]ToolBar.separatorColor = lazy(Slider.trackColor)
|
||||
{Dracula---Mallowigi}ProgressBar.selectionBackground = #fff
|
||||
{Dracula---Mallowigi}ProgressBar.selectionForeground = #fff
|
||||
{Dracula---Mallowigi}List.selectionBackground = $Table.selectionBackground
|
||||
{Dracula---Mallowigi}Tree.selectionBackground = $Table.selectionBackground
|
||||
{Dracula---Mallowigi}List.selectionInactiveBackground = $Tree.selectionInactiveBackground
|
||||
{Dracula---Mallowigi}Table.selectionInactiveBackground = $Tree.selectionInactiveBackground
|
||||
|
||||
[Material_Deep_Ocean]*.selectionBackground = lighten(#222533,15%)
|
||||
[Material_Deep_Ocean]Separator.foreground = lazy(Slider.trackColor)
|
||||
[Material_Deep_Ocean]ToolBar.separatorColor = lazy(Slider.trackColor)
|
||||
{GitHub}ProgressBar.selectionBackground = #222
|
||||
{GitHub}ProgressBar.selectionForeground = #222
|
||||
{GitHub}TextField.background = @ijTextBackgroundL3
|
||||
{GitHub}List.selectionBackground = $Table.selectionBackground
|
||||
{GitHub}Tree.selectionBackground = $Table.selectionBackground
|
||||
{GitHub}List.selectionInactiveBackground = $Tree.selectionInactiveBackground
|
||||
{GitHub}Table.selectionInactiveBackground = $Tree.selectionInactiveBackground
|
||||
|
||||
[Material_Lighter]List.selectionInactiveForeground = lazy(Tree.selectionInactiveForeground)
|
||||
[Material_Lighter]ProgressBar.selectionBackground = #222
|
||||
[Material_Lighter]ProgressBar.selectionForeground = #fff
|
||||
[Material_Lighter]ComboBox.selectionBackground = lazy(List.selectionBackground)
|
||||
[Material_Lighter]Table.selectionBackground = lazy(List.selectionBackground)
|
||||
[Material_Lighter]List.selectionForeground = lazy(Table.selectionForeground)
|
||||
[Material_Lighter]RadioButtonMenuItem.selectionForeground = lazy(Table.selectionForeground)
|
||||
[Material_Lighter]Tree.selectionForeground = lazy(Table.selectionForeground)
|
||||
{GitHub_Dark}ComboBox.selectionBackground = $Tree.selectionBackground
|
||||
{GitHub_Dark}ProgressBar.selectionForeground = #fff
|
||||
{GitHub_Dark}Slider.trackColor = lighten(#2b3036,5%)
|
||||
{GitHub_Dark}Table.selectionBackground = $Tree.selectionBackground
|
||||
{GitHub_Dark}Tree.selectionInactiveBackground = $Table.selectionInactiveBackground
|
||||
|
||||
[Material_Oceanic]ProgressBar.selectionBackground = #ddd
|
||||
[Material_Oceanic]ProgressBar.selectionForeground = #ddd
|
||||
[Material_Oceanic]Separator.foreground = lazy(Slider.trackColor)
|
||||
[Material_Oceanic]ToolBar.separatorColor = lazy(Slider.trackColor)
|
||||
{Light_Owl}@disabledForeground = shade($ColorPalette.dis,10%)
|
||||
{Light_Owl}*.disabledText = @disabledForeground
|
||||
{Light_Owl}*.disabledForeground = @disabledForeground
|
||||
{Light_Owl}*.inactiveForeground = @disabledForeground
|
||||
{Light_Owl}CheckBoxMenuItem.selectionForeground = $CheckBoxMenuItem.foreground
|
||||
{Light_Owl}ComboBox.selectionForeground = $ComboBox.foreground
|
||||
{Light_Owl}List.selectionInactiveForeground = $Table.selectionInactiveForeground
|
||||
{Light_Owl}Menu.selectionForeground = $Menu.foreground
|
||||
{Light_Owl}MenuBar.selectionForeground = $MenuBar.foreground
|
||||
{Light_Owl}MenuItem.selectionForeground = $MenuItem.foreground
|
||||
{Light_Owl}Table.selectionForeground = $List.selectionForeground
|
||||
{Light_Owl}TextField.selectionForeground = $TextField.foreground
|
||||
{Light_Owl}TextField.background = @ijTextBackgroundL3
|
||||
{Light_Owl}List.selectionBackground = $Table.selectionBackground
|
||||
{Light_Owl}Tree.selectionBackground = $Table.selectionBackground
|
||||
{Light_Owl}List.selectionInactiveBackground = $Tree.selectionInactiveBackground
|
||||
{Light_Owl}Table.selectionInactiveBackground = $Tree.selectionInactiveBackground
|
||||
|
||||
[Material_Palenight]ProgressBar.selectionBackground = #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_Darker}@disabledForeground = tint($ColorPalette.dis,30%)
|
||||
{Material_Darker}*.disabledText = @disabledForeground
|
||||
{Material_Darker}*.disabledForeground = @disabledForeground
|
||||
{Material_Darker}*.inactiveForeground = @disabledForeground
|
||||
{Material_Darker}*.selectionBackground = lighten($ColorPalette.tree,15%)
|
||||
{Material_Darker}ProgressBar.selectionForeground = #fff
|
||||
{Material_Darker}Tree.selectionInactiveBackground = $List.selectionInactiveBackground
|
||||
|
||||
[Monokai_Pro---Mallowigi]List.selectionForeground = lazy(Table.selectionForeground)
|
||||
[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)
|
||||
{Material_Deep_Ocean}@disabledForeground = tint($ColorPalette.dis,10%)
|
||||
{Material_Deep_Ocean}*.disabledText = @disabledForeground
|
||||
{Material_Deep_Ocean}*.disabledForeground = @disabledForeground
|
||||
{Material_Deep_Ocean}*.inactiveForeground = @disabledForeground
|
||||
{Material_Deep_Ocean}*.selectionBackground = lighten($ColorPalette.tree,15%)
|
||||
{Material_Deep_Ocean}ProgressBar.selectionBackground = #fff
|
||||
{Material_Deep_Ocean}Slider.trackColor = lighten(#1A1C25,5%)
|
||||
{Material_Deep_Ocean}Tree.selectionInactiveBackground = $List.selectionInactiveBackground
|
||||
|
||||
[Moonlight]ComboBox.selectionBackground = lazy(List.selectionBackground)
|
||||
[Moonlight]Table.selectionBackground = lazy(List.selectionBackground)
|
||||
[Moonlight]Separator.foreground = lazy(Slider.trackColor)
|
||||
[Moonlight]ToolBar.separatorColor = lazy(Slider.trackColor)
|
||||
{Material_Lighter}@disabledForeground = shade($ColorPalette.dis,30%)
|
||||
{Material_Lighter}*.disabledText = @disabledForeground
|
||||
{Material_Lighter}*.disabledForeground = @disabledForeground
|
||||
{Material_Lighter}*.inactiveForeground = @disabledForeground
|
||||
{Material_Lighter}ComboBox.selectionBackground = $List.selectionBackground
|
||||
{Material_Lighter}List.selectionForeground = $Table.selectionForeground
|
||||
{Material_Lighter}List.selectionInactiveForeground = $Table.selectionInactiveForeground
|
||||
{Material_Lighter}ProgressBar.selectionBackground = #222
|
||||
{Material_Lighter}RadioButtonMenuItem.selectionForeground = $Table.selectionForeground
|
||||
{Material_Lighter}Table.selectionBackground = $List.selectionBackground
|
||||
{Material_Lighter}Tree.selectionForeground = $Table.selectionForeground
|
||||
{Material_Lighter}Tree.selectionInactiveBackground = $List.selectionInactiveBackground
|
||||
|
||||
[Night_Owl]ProgressBar.selectionBackground = #ddd
|
||||
[Night_Owl]ProgressBar.selectionForeground = #ddd
|
||||
{Material_Oceanic}@disabledForeground = tint($ColorPalette.dis,30%)
|
||||
{Material_Oceanic}*.disabledText = @disabledForeground
|
||||
{Material_Oceanic}*.disabledForeground = @disabledForeground
|
||||
{Material_Oceanic}*.inactiveForeground = @disabledForeground
|
||||
{Material_Oceanic}ProgressBar.selectionBackground = #ddd
|
||||
{Material_Oceanic}ProgressBar.selectionForeground = #ddd
|
||||
{Material_Oceanic}List.selectionBackground = $Table.selectionBackground
|
||||
{Material_Oceanic}Tree.selectionBackground = $Table.selectionBackground
|
||||
{Material_Oceanic}List.selectionInactiveBackground = $Tree.selectionInactiveBackground
|
||||
{Material_Oceanic}Table.selectionInactiveBackground = $Tree.selectionInactiveBackground
|
||||
|
||||
[Solarized_Dark---Mallowigi]ProgressBar.selectionBackground = #ccc
|
||||
[Solarized_Dark---Mallowigi]ProgressBar.selectionForeground = #ccc
|
||||
[Solarized_Dark---Mallowigi]Separator.foreground = lazy(Slider.trackColor)
|
||||
[Solarized_Dark---Mallowigi]ToolBar.separatorColor = lazy(Slider.trackColor)
|
||||
{Material_Palenight}@disabledForeground = tint($ColorPalette.dis,20%)
|
||||
{Material_Palenight}*.disabledText = @disabledForeground
|
||||
{Material_Palenight}*.disabledForeground = @disabledForeground
|
||||
{Material_Palenight}*.inactiveForeground = @disabledForeground
|
||||
{Material_Palenight}ProgressBar.selectionBackground = #ddd
|
||||
{Material_Palenight}ProgressBar.selectionForeground = #ddd
|
||||
{Material_Palenight}List.selectionBackground = $Table.selectionBackground
|
||||
{Material_Palenight}Tree.selectionBackground = $Table.selectionBackground
|
||||
{Material_Palenight}List.selectionInactiveBackground = $Tree.selectionInactiveBackground
|
||||
{Material_Palenight}Table.selectionInactiveBackground = $Tree.selectionInactiveBackground
|
||||
|
||||
[Solarized_Light---Mallowigi]ProgressBar.selectionBackground = #222
|
||||
[Solarized_Light---Mallowigi]ProgressBar.selectionForeground = #fff
|
||||
[Solarized_Light---Mallowigi]ComboBox.selectionBackground = lazy(List.selectionBackground)
|
||||
[Solarized_Light---Mallowigi]Table.selectionBackground = lazy(List.selectionBackground)
|
||||
[Solarized_Light---Mallowigi]Separator.foreground = lazy(Slider.trackColor)
|
||||
[Solarized_Light---Mallowigi]ToolBar.separatorColor = lazy(Slider.trackColor)
|
||||
{Monokai_Pro---Mallowigi}@disabledForeground = tint($ColorPalette.dis,20%)
|
||||
{Monokai_Pro---Mallowigi}*.disabledText = @disabledForeground
|
||||
{Monokai_Pro---Mallowigi}*.disabledForeground = @disabledForeground
|
||||
{Monokai_Pro---Mallowigi}*.inactiveForeground = @disabledForeground
|
||||
{Monokai_Pro---Mallowigi}RadioButtonMenuItem.selectionForeground = $MenuItem.selectionForeground
|
||||
{Monokai_Pro---Mallowigi}List.selectionForeground = $Table.selectionForeground
|
||||
{Monokai_Pro---Mallowigi}Tree.selectionForeground = $Table.selectionForeground
|
||||
{Monokai_Pro---Mallowigi}List.selectionInactiveForeground = $Table.selectionInactiveForeground
|
||||
{Monokai_Pro---Mallowigi}List.selectionBackground = $Table.selectionBackground
|
||||
{Monokai_Pro---Mallowigi}Tree.selectionBackground = $Table.selectionBackground
|
||||
{Monokai_Pro---Mallowigi}List.selectionInactiveBackground = $Tree.selectionInactiveBackground
|
||||
{Monokai_Pro---Mallowigi}Table.selectionInactiveBackground = $Tree.selectionInactiveBackground
|
||||
|
||||
{Moonlight}ComboBox.selectionBackground = $List.selectionBackground
|
||||
{Moonlight}ProgressBar.selectionForeground = #000
|
||||
{Moonlight}Table.selectionBackground = $List.selectionBackground
|
||||
{Moonlight}Tree.selectionInactiveBackground = $List.selectionInactiveBackground
|
||||
|
||||
{Solarized_Dark---Mallowigi}@disabledForeground = tint($ColorPalette.dis,20%)
|
||||
{Solarized_Dark---Mallowigi}*.disabledForeground = @disabledForeground
|
||||
{Solarized_Dark---Mallowigi}*.inactiveForeground = @disabledForeground
|
||||
{Solarized_Dark---Mallowigi}*.disabledText = @disabledForeground
|
||||
{Solarized_Dark---Mallowigi}ProgressBar.selectionBackground = #ccc
|
||||
{Solarized_Dark---Mallowigi}ProgressBar.selectionForeground = #ccc
|
||||
{Solarized_Dark---Mallowigi}Slider.trackColor = lighten(@background,10%)
|
||||
{Solarized_Dark---Mallowigi}Table.selectionBackground = $List.selectionBackground
|
||||
{Solarized_Dark---Mallowigi}Tree.selectionInactiveBackground = $List.selectionInactiveBackground
|
||||
|
||||
{Solarized_Light---Mallowigi}@disabledForeground = tint(@foreground,30%)
|
||||
{Solarized_Light---Mallowigi}*.disabledForeground = @disabledForeground
|
||||
{Solarized_Light---Mallowigi}*.inactiveForeground = @disabledForeground
|
||||
{Solarized_Light---Mallowigi}*.disabledText = @disabledForeground
|
||||
{Solarized_Light---Mallowigi}ProgressBar.selectionBackground = #222
|
||||
{Solarized_Light---Mallowigi}ComboBox.selectionBackground = $List.selectionBackground
|
||||
{Solarized_Light---Mallowigi}Slider.disabledTrackColor = lighten($Slider.trackColor,5%)
|
||||
{Solarized_Light---Mallowigi}Table.selectionBackground = $List.selectionBackground
|
||||
{Solarized_Light---Mallowigi}Tree.selectionInactiveBackground = $List.selectionInactiveBackground
|
||||
{Solarized_Light---Mallowigi}Button.toolbar.selectedBackground = darken($@background,15%)
|
||||
{Solarized_Light---Mallowigi}ToggleButton.toolbar.selectedBackground = $Button.toolbar.selectedBackground
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -112,6 +112,7 @@ Button.borderWidth = 0
|
||||
Button.disabledBackground = darken($Button.background,10%)
|
||||
|
||||
Button.default.borderWidth = 0
|
||||
Button.default.foreground = contrast($Button.default.background, @background, @selectionForeground, 25%)
|
||||
|
||||
Button.toolbar.hoverBackground = #fff1
|
||||
Button.toolbar.pressedBackground = #fff2
|
||||
@@ -293,6 +294,7 @@ TextPane.selectionForeground = @textSelectionForeground
|
||||
|
||||
ToggleButton.disabledBackground = $Button.disabledBackground
|
||||
ToggleButton.selectedBackground = lighten($ToggleButton.background,20%,derived)
|
||||
ToggleButton.selectedForeground = lighten($ToggleButton.foreground,20%)
|
||||
|
||||
ToggleButton.toolbar.selectedBackground = #fff3
|
||||
|
||||
|
||||
@@ -79,7 +79,7 @@
|
||||
# general background and foreground (text color)
|
||||
@background = #f6f6f6
|
||||
@foreground = over(@nsControlTextColor,@background)
|
||||
@disabledForeground = over(@nsTertiaryLabelColor,@background)
|
||||
@disabledForeground = over(@nsSecondaryLabelColor,@background)
|
||||
|
||||
# component background
|
||||
@buttonBackground = @nsControlColor
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
package com.formdev.flatlaf;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertInstanceOf;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
@@ -29,6 +31,13 @@ import javax.swing.UIDefaults.LazyValue;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import com.formdev.flatlaf.ui.FlatEmptyBorder;
|
||||
import com.formdev.flatlaf.ui.FlatLineBorder;
|
||||
import com.formdev.flatlaf.util.DerivedColor;
|
||||
import com.formdev.flatlaf.util.ColorFunctions.ColorFunction;
|
||||
import com.formdev.flatlaf.util.ColorFunctions.Fade;
|
||||
import com.formdev.flatlaf.util.ColorFunctions.HSLChange;
|
||||
import com.formdev.flatlaf.util.ColorFunctions.HSLIncreaseDecrease;
|
||||
import com.formdev.flatlaf.util.ColorFunctions.Mix;
|
||||
import com.formdev.flatlaf.util.ColorFunctions.Mix2;
|
||||
|
||||
/**
|
||||
* @author Karl Tauber
|
||||
@@ -180,6 +189,269 @@ public class TestUIDefaultsLoader
|
||||
assertEquals( expected, ((LazyValue)UIDefaultsLoader.parseValue( "dummyIcon", value, null )).createValue( null ) );
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseColorFunctions() {
|
||||
// lighten
|
||||
assertEquals( new Color( 0xff6666 ), parseColor( "lighten(#f00, 20%)" ) );
|
||||
assertEquals( new Color( 0xff3333 ), parseColor( "lighten(#f00, 20%, relative)" ) );
|
||||
assertEquals( new Color( 0xaaaaaa ), parseColor( "lighten(#ddd, 20%, autoInverse)" ) );
|
||||
assertEquals( new Color( 0xb1b1b1 ), parseColor( "lighten(#ddd, 20%, relative autoInverse)" ) );
|
||||
|
||||
// darken
|
||||
assertEquals( new Color( 0x990000 ), parseColor( "darken(#f00, 20%)" ) );
|
||||
assertEquals( new Color( 0xcc0000 ), parseColor( "darken(#f00, 20%, relative)" ) );
|
||||
assertEquals( new Color( 0x555555 ), parseColor( "darken(#222, 20%, autoInverse)" ) );
|
||||
assertEquals( new Color( 0x292929 ), parseColor( "darken(#222, 20%, relative autoInverse)" ) );
|
||||
|
||||
// saturate
|
||||
assertEquals( new Color( 0xf32e2e ), parseColor( "saturate(#d44, 20%)" ) );
|
||||
assertEquals( new Color( 0xec3535 ), parseColor( "saturate(#d44, 20%, relative)" ) );
|
||||
assertEquals( new Color( 0xc75a5a ), parseColor( "saturate(#d44, 20%, autoInverse)" ) );
|
||||
assertEquals( new Color( 0xce5353 ), parseColor( "saturate(#d44, 20%, relative autoInverse)" ) );
|
||||
|
||||
// desaturate
|
||||
assertEquals( new Color( 0x745858 ), parseColor( "desaturate(#844, 20%)" ) );
|
||||
assertEquals( new Color( 0x814b4b ), parseColor( "desaturate(#844, 20%, relative)" ) );
|
||||
assertEquals( new Color( 0x9c3030 ), parseColor( "desaturate(#844, 20%, autoInverse)" ) );
|
||||
assertEquals( new Color( 0x8f3d3d ), parseColor( "desaturate(#844, 20%, relative autoInverse)" ) );
|
||||
|
||||
// fadein
|
||||
assertEquals( new Color( 0xddff0000, true ), parseColor( "fadein(#f00a, 20%)" ) );
|
||||
assertEquals( new Color( 0xccff0000, true ), parseColor( "fadein(#f00a, 20%, relative)" ) );
|
||||
assertEquals( new Color( 0x77ff0000, true ), parseColor( "fadein(#f00a, 20%, autoInverse)" ) );
|
||||
assertEquals( new Color( 0x88ff0000, true ), parseColor( "fadein(#f00a, 20%, relative autoInverse)" ) );
|
||||
|
||||
// fadeout
|
||||
assertEquals( new Color( 0x11ff0000, true ), parseColor( "fadeout(#f004, 20%)" ) );
|
||||
assertEquals( new Color( 0x36ff0000, true ), parseColor( "fadeout(#f004, 20%, relative)" ) );
|
||||
assertEquals( new Color( 0x77ff0000, true ), parseColor( "fadeout(#f004, 20%, autoInverse)" ) );
|
||||
assertEquals( new Color( 0x52ff0000, true ), parseColor( "fadeout(#f004, 20%, relative autoInverse)" ) );
|
||||
|
||||
// fade
|
||||
assertEquals( new Color( 0x33ff0000, true ), parseColor( "fade(#f00, 20%)" ) );
|
||||
assertEquals( new Color( 0xccff0000, true ), parseColor( "fade(#ff000010, 80%)" ) );
|
||||
|
||||
// spin
|
||||
assertEquals( new Color( 0xffaa00 ), parseColor( "spin(#f00, 40)" ) );
|
||||
assertEquals( new Color( 0xff00aa ), parseColor( "spin(#f00, -40)" ) );
|
||||
|
||||
// changeHue / changeSaturation / changeLightness / changeAlpha
|
||||
assertEquals( new Color( 0xffaa00 ), parseColor( "changeHue(#f00, 40)" ) );
|
||||
assertEquals( new Color( 0xb34d4d ), parseColor( "changeSaturation(#f00, 40%)" ) );
|
||||
assertEquals( new Color( 0xcc0000 ), parseColor( "changeLightness(#f00, 40%)" ) );
|
||||
assertEquals( new Color( 0x66ff0000, true ), parseColor( "changeAlpha(#f00, 40%)" ) );
|
||||
|
||||
// mix
|
||||
assertEquals( new Color( 0x808000 ), parseColor( "mix(#f00, #0f0)" ) );
|
||||
assertEquals( new Color( 0xbf4000 ), parseColor( "mix(#f00, #0f0, 75%)" ) );
|
||||
|
||||
// tint
|
||||
assertEquals( new Color( 0xff80ff ), parseColor( "tint(#f0f)" ) );
|
||||
assertEquals( new Color( 0xffbfff ), parseColor( "tint(#f0f, 75%)" ) );
|
||||
|
||||
// shade
|
||||
assertEquals( new Color( 0x800080 ), parseColor( "shade(#f0f)" ) );
|
||||
assertEquals( new Color( 0x400040 ), parseColor( "shade(#f0f, 75%)" ) );
|
||||
|
||||
// contrast
|
||||
assertEquals( new Color( 0x0000ff ), parseColor( "contrast(#bbb, #00f, #0f0)" ) );
|
||||
assertEquals( new Color( 0x00ff00 ), parseColor( "contrast(#444, #00f, #0f0)" ) );
|
||||
assertEquals( new Color( 0x00ff00 ), parseColor( "contrast(#bbb, #00f, #0f0, 60%)" ) );
|
||||
|
||||
// rgb / rgba
|
||||
assertEquals( new Color( 0x5a8120 ), parseColor( "rgb(90, 129, 32)" ) );
|
||||
assertEquals( new Color( 0x5a8120 ), parseColor( "rgb(90, 129, 32)" ) );
|
||||
assertEquals( new Color( 0x197fb2 ), parseColor( "rgb(10%,50%,70%)" ) );
|
||||
assertEquals( new Color( 0x197f46 ), parseColor( "rgb(10%,50%,70)" ) );
|
||||
assertEquals( new Color( 0x405a8120, true ), parseColor( "rgba(90, 129, 32, 64)" ) );
|
||||
assertEquals( new Color( 0x335a8120, true ), parseColor( "rgba(90, 129, 32, 20%)" ) );
|
||||
|
||||
// hsl / hsla
|
||||
assertEquals( new Color( 0x7fff00 ), parseColor( "hsl(90, 100%, 50%)" ) );
|
||||
assertEquals( new Color( 0x337fff00, true ), parseColor( "hsla(90, 100%, 50%, 20%)" ) );
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseLazyColorFunctions() {
|
||||
// lighten
|
||||
assertEquals( new Color( 0xff6666 ), parseColorLazy( "lighten(dummyColor, 20%, lazy)", new Color( 0xff0000 ) ) );
|
||||
|
||||
// darken
|
||||
assertEquals( new Color( 0x990000 ), parseColorLazy( "darken(dummyColor, 20%, lazy)", new Color( 0xff0000 ) ) );
|
||||
|
||||
// saturate
|
||||
assertEquals( new Color( 0xf32e2e ), parseColorLazy( "saturate(dummyColor, 20%, lazy)", new Color( 0xdd4444 ) ) );
|
||||
|
||||
// desaturate
|
||||
assertEquals( new Color( 0x745858 ), parseColorLazy( "desaturate(dummyColor, 20%, lazy)", new Color( 0x884444 ) ) );
|
||||
|
||||
// fadein
|
||||
assertEquals( new Color( 0xddff0000, true ), parseColorLazy( "fadein(dummyColor, 20%, lazy)", new Color( 0xaaff0000, true ) ) );
|
||||
|
||||
// fadeout
|
||||
assertEquals( new Color( 0x11ff0000, true ), parseColorLazy( "fadeout(dummyColor, 20%, lazy)", new Color( 0x44ff0000, true ) ) );
|
||||
|
||||
// fade
|
||||
assertEquals( new Color( 0x33ff0000, true ), parseColorLazy( "fade(dummyColor, 20%, lazy)", new Color( 0xff0000 ) ) );
|
||||
assertEquals( new Color( 0xccff0000, true ), parseColorLazy( "fade(dummyColor, 80%, lazy)", new Color( 0x10ff0000, true ) ) );
|
||||
|
||||
// spin
|
||||
assertEquals( new Color( 0xffaa00 ), parseColorLazy( "spin(dummyColor, 40, lazy)", new Color( 0xff0000 ) ) );
|
||||
assertEquals( new Color( 0xff00aa ), parseColorLazy( "spin(dummyColor, -40, lazy)", new Color( 0xff0000 ) ) );
|
||||
|
||||
// changeHue / changeSaturation / changeLightness / changeAlpha
|
||||
assertEquals( new Color( 0xffaa00 ), parseColorLazy( "changeHue(dummyColor, 40, lazy)", new Color( 0xff0000 ) ) );
|
||||
assertEquals( new Color( 0xb34d4d ), parseColorLazy( "changeSaturation(dummyColor, 40%, lazy)", new Color( 0xff0000 ) ) );
|
||||
assertEquals( new Color( 0xcc0000 ), parseColorLazy( "changeLightness(dummyColor, 40%, lazy)", new Color( 0xff0000 ) ) );
|
||||
assertEquals( new Color( 0x66ff0000, true ), parseColorLazy( "changeAlpha(dummyColor, 40%, lazy)", new Color( 0xff0000 ) ) );
|
||||
|
||||
// mix
|
||||
assertEquals( new Color( 0x808000 ), parseColorLazy( "mix(#f00, dummyColor, lazy)", new Color( 0x00ff00 ) ) );
|
||||
assertEquals( new Color( 0xbf4000 ), parseColorLazy( "mix(#f00, dummyColor, 75%, lazy)", new Color( 0x00ff00 ) ) );
|
||||
|
||||
// tint
|
||||
assertEquals( new Color( 0xff80ff ), parseColorLazy( "tint(dummyColor, lazy)", new Color( 0xff00ff ) ) );
|
||||
assertEquals( new Color( 0xffbfff ), parseColorLazy( "tint(dummyColor, 75%, lazy)", new Color( 0xff00ff ) ) );
|
||||
|
||||
// shade
|
||||
assertEquals( new Color( 0x800080 ), parseColorLazy( "shade(dummyColor, lazy)", new Color( 0xff00ff ) ) );
|
||||
assertEquals( new Color( 0x400040 ), parseColorLazy( "shade(dummyColor, 75%, lazy)", new Color( 0xff00ff ) ) );
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseDerivedColorFunctions() {
|
||||
// mix
|
||||
assertDerivedColorEquals( new Color( 0x808000 ), "mix(#f00, #0f0, derived)", new Mix2( Color.red, 50 ) );
|
||||
assertDerivedColorEquals( new Color( 0xbf4000 ), "mix(#f00, #0f0, 75%, derived)", new Mix2( Color.red, 75 ) );
|
||||
|
||||
// tint
|
||||
assertDerivedColorEquals( new Color( 0xff80ff ), "tint(#f0f, derived)", new Mix2( Color.white, 50 ) );
|
||||
assertDerivedColorEquals( new Color( 0xffbfff ), "tint(#f0f, 75%, derived)", new Mix2( Color.white, 75 ) );
|
||||
|
||||
// shade
|
||||
assertDerivedColorEquals( new Color( 0x800080 ), "shade(#f0f, derived)", new Mix2( Color.black, 50 ) );
|
||||
assertDerivedColorEquals( new Color( 0x400040 ), "shade(#f0f, 75%, derived)", new Mix2( Color.black, 75 ) );
|
||||
|
||||
|
||||
// lighten
|
||||
assertDerivedColorEquals( new Color( 0xff6666 ), "lighten(#f00, 20%, derived)", new HSLIncreaseDecrease( 2, true, 20, false, true ) );
|
||||
assertDerivedColorEquals( new Color( 0xff3333 ), "lighten(#f00, 20%, derived relative)", new HSLIncreaseDecrease( 2, true, 20, true, true ) );
|
||||
assertDerivedColorEquals( new Color( 0xffffff ), "lighten(#ddd, 20%, derived noAutoInverse)", new HSLIncreaseDecrease( 2, true, 20, false, false ) );
|
||||
assertDerivedColorEquals( new Color( 0xffffff ), "lighten(#ddd, 20%, derived relative noAutoInverse)", new HSLIncreaseDecrease( 2, true, 20, true, false ) );
|
||||
|
||||
// darken
|
||||
assertDerivedColorEquals( new Color( 0x990000 ), "darken(#f00, 20%, derived)", new HSLIncreaseDecrease( 2, false, 20, false, true ) );
|
||||
assertDerivedColorEquals( new Color( 0xcc0000 ), "darken(#f00, 20%, derived relative)", new HSLIncreaseDecrease( 2, false, 20, true, true ) );
|
||||
assertDerivedColorEquals( new Color( 0x000000 ), "darken(#222, 20%, derived noAutoInverse)", new HSLIncreaseDecrease( 2, false, 20, false, false ) );
|
||||
assertDerivedColorEquals( new Color( 0x1b1b1b ), "darken(#222, 20%, derived relative noAutoInverse)", new HSLIncreaseDecrease( 2, false, 20, true, false ) );
|
||||
|
||||
// saturate
|
||||
assertDerivedColorEquals( new Color( 0xc75a5a ), "saturate(#d44, 20%, derived)", new HSLIncreaseDecrease( 1, true, 20, false, true ) );
|
||||
assertDerivedColorEquals( new Color( 0xce5353 ), "saturate(#d44, 20%, derived relative)", new HSLIncreaseDecrease( 1, true, 20, true, true ) );
|
||||
assertDerivedColorEquals( new Color( 0xf32e2e ), "saturate(#d44, 20%, derived noAutoInverse)", new HSLIncreaseDecrease( 1, true, 20, false, false ) );
|
||||
assertDerivedColorEquals( new Color( 0xec3535 ), "saturate(#d44, 20%, derived relative noAutoInverse)", new HSLIncreaseDecrease( 1, true, 20, true, false ) );
|
||||
|
||||
// desaturate
|
||||
assertDerivedColorEquals( new Color( 0x9c3030 ), "desaturate(#844, 20%, derived)", new HSLIncreaseDecrease( 1, false, 20, false, true ) );
|
||||
assertDerivedColorEquals( new Color( 0x8f3d3d ), "desaturate(#844, 20%, derived relative)", new HSLIncreaseDecrease( 1, false, 20, true, true ) );
|
||||
assertDerivedColorEquals( new Color( 0x745858 ), "desaturate(#844, 20%, derived noAutoInverse)", new HSLIncreaseDecrease( 1, false, 20, false, false ) );
|
||||
assertDerivedColorEquals( new Color( 0x814b4b ), "desaturate(#844, 20%, derived relative noAutoInverse)", new HSLIncreaseDecrease( 1, false, 20, true, false ) );
|
||||
|
||||
// fadein
|
||||
assertDerivedColorEquals( new Color( 0x77ff0000, true ), "fadein(#f00a, 20%, derived)", new HSLIncreaseDecrease( 3, true, 20, false, true ) );
|
||||
assertDerivedColorEquals( new Color( 0x88ff0000, true ), "fadein(#f00a, 20%, derived relative)", new HSLIncreaseDecrease( 3, true, 20, true, true ) );
|
||||
assertDerivedColorEquals( new Color( 0xddff0000, true ), "fadein(#f00a, 20%, derived noAutoInverse)", new HSLIncreaseDecrease( 3, true, 20, false, false ) );
|
||||
assertDerivedColorEquals( new Color( 0xccff0000, true ), "fadein(#f00a, 20%, derived relative noAutoInverse)", new HSLIncreaseDecrease( 3, true, 20, true, false ) );
|
||||
|
||||
// fadeout
|
||||
assertDerivedColorEquals( new Color( 0x77ff0000, true ), "fadeout(#f004, 20%, derived)", new HSLIncreaseDecrease( 3, false, 20, false, true ) );
|
||||
assertDerivedColorEquals( new Color( 0x52ff0000, true ), "fadeout(#f004, 20%, derived relative)", new HSLIncreaseDecrease( 3, false, 20, true, true ) );
|
||||
assertDerivedColorEquals( new Color( 0x11ff0000, true ), "fadeout(#f004, 20%, derived noAutoInverse)", new HSLIncreaseDecrease( 3, false, 20, false, false ) );
|
||||
assertDerivedColorEquals( new Color( 0x36ff0000, true ), "fadeout(#f004, 20%, derived relative noAutoInverse)", new HSLIncreaseDecrease( 3, false, 20, true, false ) );
|
||||
|
||||
// fade
|
||||
assertDerivedColorEquals( new Color( 0x33ff0000, true ), "fade(#f00, 20%, derived)", new Fade( 20 ) );
|
||||
assertDerivedColorEquals( new Color( 0xccff0000, true ), "fade(#ff000010, 80%, derived)", new Fade( 80 ) );
|
||||
|
||||
// spin
|
||||
assertDerivedColorEquals( new Color( 0xffaa00 ), "spin(#f00, 40, derived)", new HSLIncreaseDecrease( 0, true, 40, false, false ) );
|
||||
assertDerivedColorEquals( new Color( 0xff00aa ), "spin(#f00, -40, derived)", new HSLIncreaseDecrease( 0, true, -40, false, false ) );
|
||||
|
||||
// changeHue / changeSaturation / changeLightness / changeAlpha
|
||||
assertDerivedColorEquals( new Color( 0xffaa00 ), "changeHue(#f00, 40, derived)", new HSLChange( 0, 40 ) );
|
||||
assertDerivedColorEquals( new Color( 0xb34d4d ), "changeSaturation(#f00, 40%, derived)", new HSLChange( 1, 40 ) );
|
||||
assertDerivedColorEquals( new Color( 0xcc0000 ), "changeLightness(#f00, 40%, derived)", new HSLChange( 2, 40 ) );
|
||||
assertDerivedColorEquals( new Color( 0x66ff0000, true ), "changeAlpha(#f00, 40%, derived)", new HSLChange( 3, 40 ) );
|
||||
|
||||
// mix
|
||||
assertDerivedColorEquals( new Color( 0x808000 ), "mix(#f00, #0f0, derived)", new Mix2( new Color( 0xff0000 ), 50 ) );
|
||||
assertDerivedColorEquals( new Color( 0xbf4000 ), "mix(#f00, #0f0, 75%, derived)", new Mix2( new Color( 0xff0000 ), 75 ) );
|
||||
|
||||
// tint
|
||||
assertDerivedColorEquals( new Color( 0xff80ff ), "tint(#f0f, derived)", new Mix2( new Color( 0xffffff ), 50 ) );
|
||||
assertDerivedColorEquals( new Color( 0xffbfff ), "tint(#f0f, 75%, derived)", new Mix2( new Color( 0xffffff ), 75 ) );
|
||||
|
||||
// shade
|
||||
assertDerivedColorEquals( new Color( 0x800080 ), "shade(#f0f, derived)", new Mix2( new Color( 0x000000 ), 50 ) );
|
||||
assertDerivedColorEquals( new Color( 0x400040 ), "shade(#f0f, 75%, derived)", new Mix2( new Color( 0x000000 ), 75 ) );
|
||||
}
|
||||
|
||||
private void assertDerivedColorEquals( Color expectedColor, String actualStyle, ColorFunction... expectedFunctions ) {
|
||||
Object actual = parseColor( actualStyle );
|
||||
assertInstanceOf( DerivedColor.class, actual );
|
||||
assertEquals( expectedColor, actual );
|
||||
|
||||
ColorFunction[] actualFunctions = ((DerivedColor)actual).getFunctions();
|
||||
assertEquals( expectedFunctions.length, actualFunctions.length );
|
||||
for( int i = 0; i < expectedFunctions.length; i++ )
|
||||
assertColorFunctionEquals( expectedFunctions[i], actualFunctions[i] );
|
||||
}
|
||||
|
||||
private void assertColorFunctionEquals( ColorFunction expected, ColorFunction actual ) {
|
||||
assertEquals( expected.getClass(), actual.getClass() );
|
||||
|
||||
if( expected instanceof HSLIncreaseDecrease ) {
|
||||
HSLIncreaseDecrease e = (HSLIncreaseDecrease) expected;
|
||||
HSLIncreaseDecrease a = (HSLIncreaseDecrease) actual;
|
||||
assertEquals( e.hslIndex, a.hslIndex );
|
||||
assertEquals( e.increase, a.increase );
|
||||
assertEquals( e.amount, a.amount );
|
||||
assertEquals( e.relative, a.relative );
|
||||
assertEquals( e.autoInverse, a.autoInverse );
|
||||
} else if( expected instanceof HSLChange ) {
|
||||
HSLChange e = (HSLChange) expected;
|
||||
HSLChange a = (HSLChange) actual;
|
||||
assertEquals( e.hslIndex, a.hslIndex );
|
||||
assertEquals( e.value, a.value );
|
||||
} else if( expected instanceof Fade ) {
|
||||
Fade e = (Fade) expected;
|
||||
Fade a = (Fade) actual;
|
||||
assertEquals( e.amount, a.amount );
|
||||
} else if( expected instanceof Mix ) {
|
||||
Mix e = (Mix) expected;
|
||||
Mix a = (Mix) actual;
|
||||
assertEquals( e.color2, a.color2 );
|
||||
assertEquals( e.weight, a.weight );
|
||||
} else if( expected instanceof Mix2 ) {
|
||||
Mix2 e = (Mix2) expected;
|
||||
Mix2 a = (Mix2) actual;
|
||||
assertEquals( e.color1, a.color1 );
|
||||
assertEquals( e.weight, a.weight );
|
||||
} else
|
||||
assertTrue( false );
|
||||
}
|
||||
|
||||
private Object parseColor( String value ) {
|
||||
return UIDefaultsLoader.parseValue( "dummyColor", value, null );
|
||||
}
|
||||
|
||||
private Object parseColorLazy( String value, Color actual ) {
|
||||
UIManager.put( "dummyColor", actual );
|
||||
Object v = UIDefaultsLoader.parseValue( "dummyColor", value, null );
|
||||
assertInstanceOf( LazyValue.class, v );
|
||||
return ((LazyValue)v).createValue( null );
|
||||
}
|
||||
|
||||
//---- class TestInstance -------------------------------------------------
|
||||
|
||||
@SuppressWarnings( "EqualsHashCode" ) // Error Prone
|
||||
|
||||
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright 2024 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.assertDoesNotThrow;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import java.util.Locale;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.plaf.basic.BasicHTML;
|
||||
import javax.swing.text.BadLocationException;
|
||||
import javax.swing.text.Document;
|
||||
import javax.swing.text.View;
|
||||
import org.junit.jupiter.api.AfterAll;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
/**
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class TestFlatHTML
|
||||
{
|
||||
private final String body = "some <small>small</small> text";
|
||||
private final String bodyInBody = "<body>" + body + "</body>";
|
||||
private final String bodyPlain = "some small text";
|
||||
|
||||
@BeforeAll
|
||||
static void setup() {
|
||||
TestUtils.setup( false );
|
||||
TestUtils.scaleFont( 2 );
|
||||
}
|
||||
|
||||
@AfterAll
|
||||
static void cleanup() {
|
||||
TestUtils.cleanup();
|
||||
}
|
||||
|
||||
@Test
|
||||
void simple() {
|
||||
testHtmlBaseSize( "<html>${BASE_SIZE_IN_HEAD}" + body + "</html>", bodyPlain );
|
||||
testHtmlBaseSize( "<html>${BASE_SIZE_IN_HEAD}" + bodyInBody + "</html>", bodyPlain );
|
||||
}
|
||||
|
||||
@Test
|
||||
void htmlWithHeadTag() {
|
||||
testHtmlBaseSize( "<html><head>${BASE_SIZE}<title>test</title><head>" + body + "</html>", bodyPlain );
|
||||
testHtmlBaseSize( "<html><head>${BASE_SIZE}<title>test</title><head>" + bodyInBody + "</html>", bodyPlain );
|
||||
|
||||
testHtmlBaseSize( "<html><head id=\"abc\">${BASE_SIZE}<title>test</title><head>" + body + "</html>", bodyPlain );
|
||||
testHtmlBaseSize( "<html><head id=\"abc\">${BASE_SIZE}<title>test</title><head>" + bodyInBody + "</html>", bodyPlain );
|
||||
}
|
||||
|
||||
@Test
|
||||
void htmlWithStyleTag() {
|
||||
testHtmlBaseSize( "<html>${BASE_SIZE}<style>body { color: #f00; }</style>" + bodyInBody + "</html>", bodyPlain );
|
||||
testHtmlBaseSize( "<html>${BASE_SIZE}<style>body { color: #f00; }</style><h1>header1</h1>" + body + "</html>", "header1\n" + bodyPlain );
|
||||
|
||||
testHtmlBaseSize( "<html>${BASE_SIZE}<style type='text/css'>body { color: #f00; }</style>" + bodyInBody + "</html>", bodyPlain );
|
||||
testHtmlBaseSize( "<html>${BASE_SIZE}<style type='text/css'>body { color: #f00; }</style><h1>header1</h1>" + body + "</html>", "header1\n" + bodyPlain );
|
||||
}
|
||||
|
||||
@Test
|
||||
void htmlOnComponentWithNullFont() {
|
||||
assertDoesNotThrow( () -> {
|
||||
JLabel label = new JLabel();
|
||||
label.setFont( null );
|
||||
label.setText( "<html>foo<br>bar</html>" );
|
||||
} );
|
||||
}
|
||||
|
||||
private void testHtmlBaseSize( String html, String expectedPlain ) {
|
||||
testHtmlBaseSizeImpl( html, expectedPlain );
|
||||
testHtmlBaseSizeImpl( html.toUpperCase( Locale.ENGLISH ), expectedPlain.toUpperCase( Locale.ENGLISH ) );
|
||||
}
|
||||
|
||||
private void testHtmlBaseSizeImpl( String html, String expectedPlain ) {
|
||||
String baseSize = "<style>BASE_SIZE " + UIManager.getFont( "Label.font" ).getSize() + "</style>";
|
||||
String baseSizeInHead = "<head>" + baseSize + "</head>";
|
||||
|
||||
String expectedHtml = html.replace( "${BASE_SIZE}", baseSize ).replace( "${BASE_SIZE_IN_HEAD}", baseSizeInHead );
|
||||
html = html.replace( "${BASE_SIZE}", "" ).replace( "${BASE_SIZE_IN_HEAD}", "" );
|
||||
|
||||
testHtml( html, expectedHtml, expectedPlain );
|
||||
}
|
||||
|
||||
private void testHtml( String html, String expectedHtml, String expectedPlain ) {
|
||||
FlatHTML.testUpdateRenderer = (c, newHtml) -> {
|
||||
assertEquals( expectedHtml, newHtml );
|
||||
assertEquals( expectedPlain, getPlainText( c ) );
|
||||
};
|
||||
new JLabel( html );
|
||||
FlatHTML.testUpdateRenderer = null;
|
||||
}
|
||||
|
||||
private String getPlainText( JComponent c ) {
|
||||
View view = (View) c.getClientProperty( BasicHTML.propertyKey );
|
||||
if( view == null )
|
||||
return null;
|
||||
|
||||
Document doc = view.getDocument();
|
||||
try {
|
||||
return doc.getText( 0, doc.getLength() ).trim();
|
||||
} catch( BadLocationException ex ) {
|
||||
ex.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -270,6 +270,7 @@ public class TestFlatStyleableInfo
|
||||
"selectionForeground", Color.class,
|
||||
"selectionInactiveBackground", Color.class,
|
||||
"selectionInactiveForeground", Color.class,
|
||||
"alternateRowColor", Color.class,
|
||||
"selectionInsets", Insets.class,
|
||||
"selectionArc", int.class,
|
||||
|
||||
@@ -517,6 +518,8 @@ public class TestFlatStyleableInfo
|
||||
"icon.borderWidth", float.class,
|
||||
"icon.selectedBorderWidth", float.class,
|
||||
"icon.disabledSelectedBorderWidth", float.class,
|
||||
"icon.indeterminateBorderWidth", float.class,
|
||||
"icon.disabledIndeterminateBorderWidth", float.class,
|
||||
"icon.arc", int.class,
|
||||
|
||||
// enabled
|
||||
@@ -525,6 +528,9 @@ public class TestFlatStyleableInfo
|
||||
"icon.selectedBorderColor", Color.class,
|
||||
"icon.selectedBackground", Color.class,
|
||||
"icon.checkmarkColor", Color.class,
|
||||
"icon.indeterminateBorderColor", Color.class,
|
||||
"icon.indeterminateBackground", Color.class,
|
||||
"icon.indeterminateCheckmarkColor", Color.class,
|
||||
|
||||
// disabled
|
||||
"icon.disabledBorderColor", Color.class,
|
||||
@@ -532,6 +538,9 @@ public class TestFlatStyleableInfo
|
||||
"icon.disabledSelectedBorderColor", Color.class,
|
||||
"icon.disabledSelectedBackground", Color.class,
|
||||
"icon.disabledCheckmarkColor", Color.class,
|
||||
"icon.disabledIndeterminateBorderColor", Color.class,
|
||||
"icon.disabledIndeterminateBackground", Color.class,
|
||||
"icon.disabledIndeterminateCheckmarkColor", Color.class,
|
||||
|
||||
// focused
|
||||
"icon.focusedBorderColor", Color.class,
|
||||
@@ -539,6 +548,9 @@ public class TestFlatStyleableInfo
|
||||
"icon.focusedSelectedBorderColor", Color.class,
|
||||
"icon.focusedSelectedBackground", Color.class,
|
||||
"icon.focusedCheckmarkColor", Color.class,
|
||||
"icon.focusedIndeterminateBorderColor", Color.class,
|
||||
"icon.focusedIndeterminateBackground", Color.class,
|
||||
"icon.focusedIndeterminateCheckmarkColor", Color.class,
|
||||
|
||||
// hover
|
||||
"icon.hoverBorderColor", Color.class,
|
||||
@@ -546,13 +558,19 @@ public class TestFlatStyleableInfo
|
||||
"icon.hoverSelectedBorderColor", Color.class,
|
||||
"icon.hoverSelectedBackground", Color.class,
|
||||
"icon.hoverCheckmarkColor", Color.class,
|
||||
"icon.hoverIndeterminateBorderColor", Color.class,
|
||||
"icon.hoverIndeterminateBackground", Color.class,
|
||||
"icon.hoverIndeterminateCheckmarkColor", Color.class,
|
||||
|
||||
// pressed
|
||||
"icon.pressedBorderColor", Color.class,
|
||||
"icon.pressedBackground", Color.class,
|
||||
"icon.pressedSelectedBorderColor", Color.class,
|
||||
"icon.pressedSelectedBackground", Color.class,
|
||||
"icon.pressedCheckmarkColor", Color.class
|
||||
"icon.pressedCheckmarkColor", Color.class,
|
||||
"icon.pressedIndeterminateBorderColor", Color.class,
|
||||
"icon.pressedIndeterminateBackground", Color.class,
|
||||
"icon.pressedIndeterminateCheckmarkColor", Color.class
|
||||
);
|
||||
}
|
||||
|
||||
@@ -965,9 +983,11 @@ public class TestFlatStyleableInfo
|
||||
"selectionInactiveBackground", Color.class,
|
||||
"selectionInactiveForeground", Color.class,
|
||||
"selectionBorderColor", Color.class,
|
||||
"alternateRowColor", Color.class,
|
||||
"selectionInsets", Insets.class,
|
||||
"selectionArc", int.class,
|
||||
"wideSelection", boolean.class,
|
||||
"wideCellRenderer", boolean.class,
|
||||
"showCellFocusIndicator", boolean.class,
|
||||
|
||||
"paintSelection", boolean.class,
|
||||
@@ -1060,6 +1080,8 @@ public class TestFlatStyleableInfo
|
||||
"error.focusedBorderColor", Color.class,
|
||||
"warning.borderColor", Color.class,
|
||||
"warning.focusedBorderColor", Color.class,
|
||||
"success.borderColor", Color.class,
|
||||
"success.focusedBorderColor", Color.class,
|
||||
"custom.borderColor", Color.class,
|
||||
|
||||
"outline", String.class,
|
||||
@@ -1144,6 +1166,8 @@ public class TestFlatStyleableInfo
|
||||
"borderWidth", float.class,
|
||||
"selectedBorderWidth", float.class,
|
||||
"disabledSelectedBorderWidth", float.class,
|
||||
"indeterminateBorderWidth", float.class,
|
||||
"disabledIndeterminateBorderWidth", float.class,
|
||||
"arc", int.class,
|
||||
|
||||
// enabled
|
||||
@@ -1152,6 +1176,9 @@ public class TestFlatStyleableInfo
|
||||
"selectedBorderColor", Color.class,
|
||||
"selectedBackground", Color.class,
|
||||
"checkmarkColor", Color.class,
|
||||
"indeterminateBorderColor", Color.class,
|
||||
"indeterminateBackground", Color.class,
|
||||
"indeterminateCheckmarkColor", Color.class,
|
||||
|
||||
// disabled
|
||||
"disabledBorderColor", Color.class,
|
||||
@@ -1159,6 +1186,9 @@ public class TestFlatStyleableInfo
|
||||
"disabledSelectedBorderColor", Color.class,
|
||||
"disabledSelectedBackground", Color.class,
|
||||
"disabledCheckmarkColor", Color.class,
|
||||
"disabledIndeterminateBorderColor", Color.class,
|
||||
"disabledIndeterminateBackground", Color.class,
|
||||
"disabledIndeterminateCheckmarkColor", Color.class,
|
||||
|
||||
// focused
|
||||
"focusedBorderColor", Color.class,
|
||||
@@ -1166,6 +1196,9 @@ public class TestFlatStyleableInfo
|
||||
"focusedSelectedBorderColor", Color.class,
|
||||
"focusedSelectedBackground", Color.class,
|
||||
"focusedCheckmarkColor", Color.class,
|
||||
"focusedIndeterminateBorderColor", Color.class,
|
||||
"focusedIndeterminateBackground", Color.class,
|
||||
"focusedIndeterminateCheckmarkColor", Color.class,
|
||||
|
||||
// hover
|
||||
"hoverBorderColor", Color.class,
|
||||
@@ -1173,13 +1206,19 @@ public class TestFlatStyleableInfo
|
||||
"hoverSelectedBorderColor", Color.class,
|
||||
"hoverSelectedBackground", Color.class,
|
||||
"hoverCheckmarkColor", Color.class,
|
||||
"hoverIndeterminateBorderColor", Color.class,
|
||||
"hoverIndeterminateBackground", Color.class,
|
||||
"hoverIndeterminateCheckmarkColor", Color.class,
|
||||
|
||||
// pressed
|
||||
"pressedBorderColor", Color.class,
|
||||
"pressedBackground", Color.class,
|
||||
"pressedSelectedBorderColor", Color.class,
|
||||
"pressedSelectedBackground", Color.class,
|
||||
"pressedCheckmarkColor", Color.class
|
||||
"pressedCheckmarkColor", Color.class,
|
||||
"pressedIndeterminateBorderColor", Color.class,
|
||||
"pressedIndeterminateBackground", Color.class,
|
||||
"pressedIndeterminateCheckmarkColor", Color.class
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -370,6 +370,7 @@ public class TestFlatStyleableValue
|
||||
testColor( c, ui, "selectionForeground", 0x123456 );
|
||||
testColor( c, ui, "selectionInactiveBackground", 0x123456 );
|
||||
testColor( c, ui, "selectionInactiveForeground", 0x123456 );
|
||||
testColor( c, ui, "alternateRowColor", 0x123456 );
|
||||
testInsets( c, ui, "selectionInsets", 1,2,3,4 );
|
||||
testInteger( c, ui, "selectionArc", 123 );
|
||||
|
||||
@@ -938,9 +939,11 @@ public class TestFlatStyleableValue
|
||||
testColor( c, ui, "selectionInactiveBackground", 0x123456 );
|
||||
testColor( c, ui, "selectionInactiveForeground", 0x123456 );
|
||||
testColor( c, ui, "selectionBorderColor", 0x123456 );
|
||||
testColor( c, ui, "alternateRowColor", 0x123456 );
|
||||
testInsets( c, ui, "selectionInsets", 1,2,3,4 );
|
||||
testInteger( c, ui, "selectionArc", 123 );
|
||||
testBoolean( c, ui, "wideSelection", true );
|
||||
testBoolean( c, ui, "wideCellRenderer", true );
|
||||
testBoolean( c, ui, "showCellFocusIndicator", true );
|
||||
|
||||
testBoolean( c, ui, "paintSelection", false );
|
||||
@@ -1021,6 +1024,8 @@ public class TestFlatStyleableValue
|
||||
testColor( c, ui, "error.focusedBorderColor", 0x123456 );
|
||||
testColor( c, ui, "warning.borderColor", 0x123456 );
|
||||
testColor( c, ui, "warning.focusedBorderColor", 0x123456 );
|
||||
testColor( c, ui, "success.borderColor", 0x123456 );
|
||||
testColor( c, ui, "success.focusedBorderColor", 0x123456 );
|
||||
testColor( c, ui, "custom.borderColor", 0x123456 );
|
||||
|
||||
testString( c, ui, "outline", "error" );
|
||||
@@ -1118,6 +1123,8 @@ public class TestFlatStyleableValue
|
||||
testValue( border, "error.focusedBorderColor", Color.WHITE );
|
||||
testValue( border, "warning.borderColor", Color.WHITE );
|
||||
testValue( border, "warning.focusedBorderColor", Color.WHITE );
|
||||
testValue( border, "success.borderColor", Color.WHITE );
|
||||
testValue( border, "success.focusedBorderColor", Color.WHITE );
|
||||
testValue( border, "custom.borderColor", Color.WHITE );
|
||||
}
|
||||
|
||||
@@ -1146,6 +1153,8 @@ public class TestFlatStyleableValue
|
||||
testValue( icon, "borderWidth", 1.5f );
|
||||
testValue( icon, "selectedBorderWidth", 1.5f );
|
||||
testValue( icon, "disabledSelectedBorderWidth", 1.5f );
|
||||
testValue( icon, "indeterminateBorderWidth", 1.5f );
|
||||
testValue( icon, "disabledIndeterminateBorderWidth", 1.5f );
|
||||
testValue( icon, "arc", 5 );
|
||||
|
||||
// enabled
|
||||
@@ -1154,6 +1163,9 @@ public class TestFlatStyleableValue
|
||||
testValue( icon, "selectedBorderColor", Color.WHITE );
|
||||
testValue( icon, "selectedBackground", Color.WHITE );
|
||||
testValue( icon, "checkmarkColor", Color.WHITE );
|
||||
testValue( icon, "indeterminateBorderColor", Color.WHITE );
|
||||
testValue( icon, "indeterminateBackground", Color.WHITE );
|
||||
testValue( icon, "indeterminateCheckmarkColor", Color.WHITE );
|
||||
|
||||
// disabled
|
||||
testValue( icon, "disabledBorderColor", Color.WHITE );
|
||||
@@ -1161,6 +1173,9 @@ public class TestFlatStyleableValue
|
||||
testValue( icon, "disabledSelectedBorderColor", Color.WHITE );
|
||||
testValue( icon, "disabledSelectedBackground", Color.WHITE );
|
||||
testValue( icon, "disabledCheckmarkColor", Color.WHITE );
|
||||
testValue( icon, "disabledIndeterminateBorderColor", Color.WHITE );
|
||||
testValue( icon, "disabledIndeterminateBackground", Color.WHITE );
|
||||
testValue( icon, "disabledIndeterminateCheckmarkColor", Color.WHITE );
|
||||
|
||||
// focused
|
||||
testValue( icon, "focusedBorderColor", Color.WHITE );
|
||||
@@ -1168,6 +1183,9 @@ public class TestFlatStyleableValue
|
||||
testValue( icon, "focusedSelectedBorderColor", Color.WHITE );
|
||||
testValue( icon, "focusedSelectedBackground", Color.WHITE );
|
||||
testValue( icon, "focusedCheckmarkColor", Color.WHITE );
|
||||
testValue( icon, "focusedIndeterminateBorderColor", Color.WHITE );
|
||||
testValue( icon, "focusedIndeterminateBackground", Color.WHITE );
|
||||
testValue( icon, "focusedIndeterminateCheckmarkColor", Color.WHITE );
|
||||
|
||||
// hover
|
||||
testValue( icon, "hoverBorderColor", Color.WHITE );
|
||||
@@ -1175,6 +1193,9 @@ public class TestFlatStyleableValue
|
||||
testValue( icon, "hoverSelectedBorderColor", Color.WHITE );
|
||||
testValue( icon, "hoverSelectedBackground", Color.WHITE );
|
||||
testValue( icon, "hoverCheckmarkColor", Color.WHITE );
|
||||
testValue( icon, "hoverIndeterminateBorderColor", Color.WHITE );
|
||||
testValue( icon, "hoverIndeterminateBackground", Color.WHITE );
|
||||
testValue( icon, "hoverIndeterminateCheckmarkColor", Color.WHITE );
|
||||
|
||||
// pressed
|
||||
testValue( icon, "pressedBorderColor", Color.WHITE );
|
||||
@@ -1182,6 +1203,9 @@ public class TestFlatStyleableValue
|
||||
testValue( icon, "pressedSelectedBorderColor", Color.WHITE );
|
||||
testValue( icon, "pressedSelectedBackground", Color.WHITE );
|
||||
testValue( icon, "pressedCheckmarkColor", Color.WHITE );
|
||||
testValue( icon, "pressedIndeterminateBorderColor", Color.WHITE );
|
||||
testValue( icon, "pressedIndeterminateBackground", Color.WHITE );
|
||||
testValue( icon, "pressedIndeterminateCheckmarkColor", Color.WHITE );
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -433,6 +433,7 @@ public class TestFlatStyling
|
||||
ui.applyStyle( "selectionForeground: #fff" );
|
||||
ui.applyStyle( "selectionInactiveBackground: #fff" );
|
||||
ui.applyStyle( "selectionInactiveForeground: #fff" );
|
||||
ui.applyStyle( "alternateRowColor: #fff" );
|
||||
ui.applyStyle( "selectionInsets: 1,2,3,4" );
|
||||
ui.applyStyle( "selectionArc: 8" );
|
||||
|
||||
@@ -1187,9 +1188,11 @@ public class TestFlatStyling
|
||||
ui.applyStyle( "selectionInactiveBackground: #fff" );
|
||||
ui.applyStyle( "selectionInactiveForeground: #fff" );
|
||||
ui.applyStyle( "selectionBorderColor: #fff" );
|
||||
ui.applyStyle( "alternateRowColor: #fff" );
|
||||
ui.applyStyle( "selectionInsets: 1,2,3,4" );
|
||||
ui.applyStyle( "selectionArc: 8" );
|
||||
ui.applyStyle( "wideSelection: true" );
|
||||
ui.applyStyle( "wideCellRenderer: true" );
|
||||
ui.applyStyle( "showCellFocusIndicator: true" );
|
||||
|
||||
ui.applyStyle( "paintSelection: false" );
|
||||
@@ -1275,6 +1278,8 @@ public class TestFlatStyling
|
||||
applyStyle.accept( "error.focusedBorderColor: #fff" );
|
||||
applyStyle.accept( "warning.borderColor: #fff" );
|
||||
applyStyle.accept( "warning.focusedBorderColor: #fff" );
|
||||
applyStyle.accept( "success.borderColor: #fff" );
|
||||
applyStyle.accept( "success.focusedBorderColor: #fff" );
|
||||
applyStyle.accept( "custom.borderColor: desaturate(#f00,50%,relative derived noAutoInverse)" );
|
||||
|
||||
applyStyle.accept( "outline: error" );
|
||||
@@ -1360,6 +1365,8 @@ public class TestFlatStyling
|
||||
border.applyStyleProperty( "error.focusedBorderColor", Color.WHITE );
|
||||
border.applyStyleProperty( "warning.borderColor", Color.WHITE );
|
||||
border.applyStyleProperty( "warning.focusedBorderColor", Color.WHITE );
|
||||
border.applyStyleProperty( "success.borderColor", Color.WHITE );
|
||||
border.applyStyleProperty( "success.focusedBorderColor", Color.WHITE );
|
||||
border.applyStyleProperty( "custom.borderColor", Color.WHITE );
|
||||
}
|
||||
|
||||
@@ -1388,6 +1395,8 @@ public class TestFlatStyling
|
||||
icon.applyStyleProperty( "borderWidth", 1.5f );
|
||||
icon.applyStyleProperty( "selectedBorderWidth", 1.5f );
|
||||
icon.applyStyleProperty( "disabledSelectedBorderWidth", 1.5f );
|
||||
icon.applyStyleProperty( "indeterminateBorderWidth", 1.5f );
|
||||
icon.applyStyleProperty( "disabledIndeterminateBorderWidth", 1.5f );
|
||||
icon.applyStyleProperty( "arc", 5 );
|
||||
|
||||
// enabled
|
||||
@@ -1396,6 +1405,9 @@ public class TestFlatStyling
|
||||
icon.applyStyleProperty( "selectedBorderColor", Color.WHITE );
|
||||
icon.applyStyleProperty( "selectedBackground", Color.WHITE );
|
||||
icon.applyStyleProperty( "checkmarkColor", Color.WHITE );
|
||||
icon.applyStyleProperty( "indeterminateBorderColor", Color.WHITE );
|
||||
icon.applyStyleProperty( "indeterminateBackground", Color.WHITE );
|
||||
icon.applyStyleProperty( "indeterminateCheckmarkColor", Color.WHITE );
|
||||
|
||||
// disabled
|
||||
icon.applyStyleProperty( "disabledBorderColor", Color.WHITE );
|
||||
@@ -1403,6 +1415,9 @@ public class TestFlatStyling
|
||||
icon.applyStyleProperty( "disabledSelectedBorderColor", Color.WHITE );
|
||||
icon.applyStyleProperty( "disabledSelectedBackground", Color.WHITE );
|
||||
icon.applyStyleProperty( "disabledCheckmarkColor", Color.WHITE );
|
||||
icon.applyStyleProperty( "disabledIndeterminateBorderColor", Color.WHITE );
|
||||
icon.applyStyleProperty( "disabledIndeterminateBackground", Color.WHITE );
|
||||
icon.applyStyleProperty( "disabledIndeterminateCheckmarkColor", Color.WHITE );
|
||||
|
||||
// focused
|
||||
icon.applyStyleProperty( "focusedBorderColor", Color.WHITE );
|
||||
@@ -1410,6 +1425,9 @@ public class TestFlatStyling
|
||||
icon.applyStyleProperty( "focusedSelectedBorderColor", Color.WHITE );
|
||||
icon.applyStyleProperty( "focusedSelectedBackground", Color.WHITE );
|
||||
icon.applyStyleProperty( "focusedCheckmarkColor", Color.WHITE );
|
||||
icon.applyStyleProperty( "focusedIndeterminateBorderColor", Color.WHITE );
|
||||
icon.applyStyleProperty( "focusedIndeterminateBackground", Color.WHITE );
|
||||
icon.applyStyleProperty( "focusedIndeterminateCheckmarkColor", Color.WHITE );
|
||||
|
||||
// hover
|
||||
icon.applyStyleProperty( "hoverBorderColor", Color.WHITE );
|
||||
@@ -1417,6 +1435,9 @@ public class TestFlatStyling
|
||||
icon.applyStyleProperty( "hoverSelectedBorderColor", Color.WHITE );
|
||||
icon.applyStyleProperty( "hoverSelectedBackground", Color.WHITE );
|
||||
icon.applyStyleProperty( "hoverCheckmarkColor", Color.WHITE );
|
||||
icon.applyStyleProperty( "hoverIndeterminateBorderColor", Color.WHITE );
|
||||
icon.applyStyleProperty( "hoverIndeterminateBackground", Color.WHITE );
|
||||
icon.applyStyleProperty( "hoverIndeterminateCheckmarkColor", Color.WHITE );
|
||||
|
||||
// pressed
|
||||
icon.applyStyleProperty( "pressedBorderColor", Color.WHITE );
|
||||
@@ -1424,6 +1445,9 @@ public class TestFlatStyling
|
||||
icon.applyStyleProperty( "pressedSelectedBorderColor", Color.WHITE );
|
||||
icon.applyStyleProperty( "pressedSelectedBackground", Color.WHITE );
|
||||
icon.applyStyleProperty( "pressedCheckmarkColor", Color.WHITE );
|
||||
icon.applyStyleProperty( "pressedIndeterminateBorderColor", Color.WHITE );
|
||||
icon.applyStyleProperty( "pressedIndeterminateBackground", Color.WHITE );
|
||||
icon.applyStyleProperty( "pressedIndeterminateCheckmarkColor", Color.WHITE );
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
||||
org.eclipse.jdt.core.compiler.compliance=1.8
|
||||
org.eclipse.jdt.core.compiler.source=1.8
|
||||
org.eclipse.jdt.core.formatter.align_assignment_statements_on_columns=false
|
||||
org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647
|
||||
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
# when the Demo window is activated.
|
||||
|
||||
|
||||
# base theme (light, dark, intellij or darcula)
|
||||
# base theme (light, dark, intellij, darcula, maclight or macdark)
|
||||
@baseTheme = light
|
||||
|
||||
# add you theme defaults here
|
||||
|
||||
@@ -48,6 +48,9 @@ tasks {
|
||||
|
||||
if( JavaVersion.current() >= JavaVersion.VERSION_1_9 )
|
||||
attributes( "Multi-Release" to "true" )
|
||||
|
||||
// allow loading FlatLaf native library in Java 24+ (see https://openjdk.org/jeps/472)
|
||||
attributes( "Enable-Native-Access" to "ALL-UNNAMED" )
|
||||
}
|
||||
|
||||
exclude( "module-info.class" )
|
||||
|
||||
@@ -179,14 +179,10 @@ class BasicComponentsPanel
|
||||
JScrollPane scrollPane12 = new JScrollPane();
|
||||
JTextPane textPane4 = new JTextPane();
|
||||
JTextPane textPane5 = new JTextPane();
|
||||
JLabel errorHintsLabel = new JLabel();
|
||||
JLabel hintsLabel = new JLabel();
|
||||
JTextField errorHintsTextField = new JTextField();
|
||||
JComboBox<String> errorHintsComboBox = new JComboBox<>();
|
||||
JSpinner errorHintsSpinner = new JSpinner();
|
||||
JLabel warningHintsLabel = new JLabel();
|
||||
JTextField warningHintsTextField = new JTextField();
|
||||
JComboBox<String> warningHintsComboBox = new JComboBox<>();
|
||||
JSpinner warningHintsSpinner = new JSpinner();
|
||||
JTextField successHintsTextField = new JTextField();
|
||||
JLabel iconsLabel = new JLabel();
|
||||
leadingIconTextField = new JTextField();
|
||||
trailingIconTextField = new JTextField();
|
||||
@@ -241,7 +237,6 @@ class BasicComponentsPanel
|
||||
"[]" +
|
||||
"[]" +
|
||||
"[]" +
|
||||
"[]" +
|
||||
"[]0" +
|
||||
"[]"));
|
||||
|
||||
@@ -277,22 +272,22 @@ class BasicComponentsPanel
|
||||
|
||||
//---- button5 ----
|
||||
button5.setText("Square");
|
||||
button5.putClientProperty("JButton.buttonType", "square");
|
||||
button5.putClientProperty(FlatClientProperties.BUTTON_TYPE, FlatClientProperties.BUTTON_TYPE_SQUARE);
|
||||
add(button5, "cell 3 1");
|
||||
|
||||
//---- button6 ----
|
||||
button6.setText("Round");
|
||||
button6.putClientProperty("JButton.buttonType", "roundRect");
|
||||
button6.putClientProperty(FlatClientProperties.BUTTON_TYPE, FlatClientProperties.BUTTON_TYPE_ROUND_RECT);
|
||||
add(button6, "cell 4 1");
|
||||
|
||||
//---- button3 ----
|
||||
button3.setText("Help");
|
||||
button3.putClientProperty("JButton.buttonType", "help");
|
||||
button3.putClientProperty(FlatClientProperties.BUTTON_TYPE, FlatClientProperties.BUTTON_TYPE_HELP);
|
||||
add(button3, "cell 4 1");
|
||||
|
||||
//---- button4 ----
|
||||
button4.setText("Help");
|
||||
button4.putClientProperty("JButton.buttonType", "help");
|
||||
button4.putClientProperty(FlatClientProperties.BUTTON_TYPE, FlatClientProperties.BUTTON_TYPE_HELP);
|
||||
button4.setEnabled(false);
|
||||
add(button4, "cell 4 1");
|
||||
|
||||
@@ -432,7 +427,7 @@ class BasicComponentsPanel
|
||||
|
||||
//---- comboBox6 ----
|
||||
comboBox6.setEditable(true);
|
||||
comboBox6.putClientProperty("JTextField.placeholderText", "Placeholder");
|
||||
comboBox6.putClientProperty(FlatClientProperties.PLACEHOLDER_TEXT, "Placeholder");
|
||||
add(comboBox6, "cell 5 5,growx");
|
||||
|
||||
//---- textFieldLabel ----
|
||||
@@ -463,7 +458,7 @@ class BasicComponentsPanel
|
||||
add(textField4, "cell 4 6,growx");
|
||||
|
||||
//---- textField6 ----
|
||||
textField6.putClientProperty("JTextField.placeholderText", "Placeholder");
|
||||
textField6.putClientProperty(FlatClientProperties.PLACEHOLDER_TEXT, "Placeholder");
|
||||
add(textField6, "cell 5 6,growx");
|
||||
|
||||
//---- formattedTextFieldLabel ----
|
||||
@@ -494,7 +489,7 @@ class BasicComponentsPanel
|
||||
add(formattedTextField4, "cell 4 7,growx");
|
||||
|
||||
//---- formattedTextField5 ----
|
||||
formattedTextField5.putClientProperty("JTextField.placeholderText", "Placeholder");
|
||||
formattedTextField5.putClientProperty(FlatClientProperties.PLACEHOLDER_TEXT, "Placeholder");
|
||||
add(formattedTextField5, "cell 5 7,growx");
|
||||
|
||||
//---- passwordFieldLabel ----
|
||||
@@ -522,7 +517,7 @@ class BasicComponentsPanel
|
||||
add(passwordField4, "cell 4 8,growx");
|
||||
|
||||
//---- passwordField5 ----
|
||||
passwordField5.putClientProperty("JTextField.placeholderText", "Placeholder");
|
||||
passwordField5.putClientProperty(FlatClientProperties.PLACEHOLDER_TEXT, "Placeholder");
|
||||
add(passwordField5, "cell 5 8,growx");
|
||||
|
||||
//---- textAreaLabel ----
|
||||
@@ -698,145 +693,122 @@ class BasicComponentsPanel
|
||||
textPane5.setText("No scroll pane");
|
||||
add(textPane5, "cell 5 11,growx");
|
||||
|
||||
//---- errorHintsLabel ----
|
||||
errorHintsLabel.setText("Error hints:");
|
||||
add(errorHintsLabel, "cell 0 12");
|
||||
//---- hintsLabel ----
|
||||
hintsLabel.setText("Error/warning/success:");
|
||||
add(hintsLabel, "cell 0 12");
|
||||
|
||||
//---- errorHintsTextField ----
|
||||
errorHintsTextField.putClientProperty("JComponent.outline", "error");
|
||||
errorHintsTextField.putClientProperty(FlatClientProperties.OUTLINE, FlatClientProperties.OUTLINE_ERROR);
|
||||
add(errorHintsTextField, "cell 1 12,growx");
|
||||
|
||||
//---- errorHintsComboBox ----
|
||||
errorHintsComboBox.putClientProperty("JComponent.outline", "error");
|
||||
errorHintsComboBox.setModel(new DefaultComboBoxModel<>(new String[] {
|
||||
"Editable"
|
||||
}));
|
||||
errorHintsComboBox.setEditable(true);
|
||||
add(errorHintsComboBox, "cell 2 12,growx");
|
||||
|
||||
//---- errorHintsSpinner ----
|
||||
errorHintsSpinner.putClientProperty("JComponent.outline", "error");
|
||||
add(errorHintsSpinner, "cell 3 12,growx");
|
||||
|
||||
//---- warningHintsLabel ----
|
||||
warningHintsLabel.setText("Warning hints:");
|
||||
add(warningHintsLabel, "cell 0 13");
|
||||
|
||||
//---- warningHintsTextField ----
|
||||
warningHintsTextField.putClientProperty("JComponent.outline", "warning");
|
||||
add(warningHintsTextField, "cell 1 13,growx");
|
||||
warningHintsTextField.putClientProperty(FlatClientProperties.OUTLINE, FlatClientProperties.OUTLINE_WARNING);
|
||||
add(warningHintsTextField, "cell 2 12,growx");
|
||||
|
||||
//---- warningHintsComboBox ----
|
||||
warningHintsComboBox.putClientProperty("JComponent.outline", "warning");
|
||||
warningHintsComboBox.setModel(new DefaultComboBoxModel<>(new String[] {
|
||||
"Not editable"
|
||||
}));
|
||||
add(warningHintsComboBox, "cell 2 13,growx");
|
||||
|
||||
//---- warningHintsSpinner ----
|
||||
warningHintsSpinner.putClientProperty("JComponent.outline", "warning");
|
||||
add(warningHintsSpinner, "cell 3 13,growx");
|
||||
//---- successHintsTextField ----
|
||||
successHintsTextField.putClientProperty(FlatClientProperties.OUTLINE, "success");
|
||||
add(successHintsTextField, "cell 3 12,growx");
|
||||
|
||||
//---- iconsLabel ----
|
||||
iconsLabel.setText("Leading/trailing icons:");
|
||||
add(iconsLabel, "cell 0 14");
|
||||
add(leadingIconTextField, "cell 1 14,growx");
|
||||
add(iconsLabel, "cell 0 13");
|
||||
add(leadingIconTextField, "cell 1 13,growx");
|
||||
|
||||
//---- trailingIconTextField ----
|
||||
trailingIconTextField.setText("text");
|
||||
add(trailingIconTextField, "cell 2 14,growx");
|
||||
add(trailingIconTextField, "cell 2 13,growx");
|
||||
|
||||
//---- iconsTextField ----
|
||||
iconsTextField.setText("text");
|
||||
add(iconsTextField, "cell 3 14,growx");
|
||||
add(iconsTextField, "cell 3 13,growx");
|
||||
|
||||
//---- compsLabel ----
|
||||
compsLabel.setText("Leading/trailing comp.:");
|
||||
add(compsLabel, "cell 0 15");
|
||||
add(compsTextField, "cell 1 15 2 1,growx");
|
||||
add(compsLabel, "cell 0 14");
|
||||
add(compsTextField, "cell 1 14 2 1,growx");
|
||||
|
||||
//---- clearTextField ----
|
||||
clearTextField.setText("clear me");
|
||||
add(clearTextField, "cell 3 15,growx");
|
||||
add(clearTextField, "cell 3 14,growx");
|
||||
|
||||
//---- fontsLabel ----
|
||||
fontsLabel.setText("Typography / Fonts:");
|
||||
add(fontsLabel, "cell 0 16");
|
||||
add(fontsLabel, "cell 0 15");
|
||||
|
||||
//---- h00Label ----
|
||||
h00Label.setText("H00");
|
||||
h00Label.putClientProperty("FlatLaf.styleClass", "h00");
|
||||
add(h00Label, "cell 1 16 5 1");
|
||||
h00Label.putClientProperty(FlatClientProperties.STYLE_CLASS, "h00");
|
||||
add(h00Label, "cell 1 15 5 1");
|
||||
|
||||
//---- h0Label ----
|
||||
h0Label.setText("H0");
|
||||
h0Label.putClientProperty("FlatLaf.styleClass", "h0");
|
||||
add(h0Label, "cell 1 16 5 1");
|
||||
h0Label.putClientProperty(FlatClientProperties.STYLE_CLASS, "h0");
|
||||
add(h0Label, "cell 1 15 5 1");
|
||||
|
||||
//---- h1Label ----
|
||||
h1Label.setText("H1");
|
||||
h1Label.putClientProperty("FlatLaf.styleClass", "h1");
|
||||
add(h1Label, "cell 1 16 5 1");
|
||||
h1Label.putClientProperty(FlatClientProperties.STYLE_CLASS, "h1");
|
||||
add(h1Label, "cell 1 15 5 1");
|
||||
|
||||
//---- h2Label ----
|
||||
h2Label.setText("H2");
|
||||
h2Label.putClientProperty("FlatLaf.styleClass", "h2");
|
||||
add(h2Label, "cell 1 16 5 1");
|
||||
h2Label.putClientProperty(FlatClientProperties.STYLE_CLASS, "h2");
|
||||
add(h2Label, "cell 1 15 5 1");
|
||||
|
||||
//---- h3Label ----
|
||||
h3Label.setText("H3");
|
||||
h3Label.putClientProperty("FlatLaf.styleClass", "h3");
|
||||
add(h3Label, "cell 1 16 5 1");
|
||||
h3Label.putClientProperty(FlatClientProperties.STYLE_CLASS, "h3");
|
||||
add(h3Label, "cell 1 15 5 1");
|
||||
|
||||
//---- h4Label ----
|
||||
h4Label.setText("H4");
|
||||
h4Label.putClientProperty("FlatLaf.styleClass", "h4");
|
||||
add(h4Label, "cell 1 16 5 1");
|
||||
h4Label.putClientProperty(FlatClientProperties.STYLE_CLASS, "h4");
|
||||
add(h4Label, "cell 1 15 5 1");
|
||||
|
||||
//---- lightLabel ----
|
||||
lightLabel.setText("light");
|
||||
lightLabel.putClientProperty("FlatLaf.style", "font: 200% $light.font");
|
||||
add(lightLabel, "cell 1 16 5 1,gapx 30");
|
||||
lightLabel.putClientProperty(FlatClientProperties.STYLE, "font: 200% $light.font");
|
||||
add(lightLabel, "cell 1 15 5 1,gapx 30");
|
||||
|
||||
//---- semiboldLabel ----
|
||||
semiboldLabel.setText("semibold");
|
||||
semiboldLabel.putClientProperty("FlatLaf.style", "font: 200% $semibold.font");
|
||||
add(semiboldLabel, "cell 1 16 5 1");
|
||||
semiboldLabel.putClientProperty(FlatClientProperties.STYLE, "font: 200% $semibold.font");
|
||||
add(semiboldLabel, "cell 1 15 5 1");
|
||||
|
||||
//---- fontZoomLabel ----
|
||||
fontZoomLabel.setText("(200%)");
|
||||
fontZoomLabel.putClientProperty("FlatLaf.styleClass", "small");
|
||||
fontZoomLabel.putClientProperty(FlatClientProperties.STYLE_CLASS, "small");
|
||||
fontZoomLabel.setEnabled(false);
|
||||
add(fontZoomLabel, "cell 1 16 5 1");
|
||||
add(fontZoomLabel, "cell 1 15 5 1");
|
||||
|
||||
//---- largeLabel ----
|
||||
largeLabel.setText("large");
|
||||
largeLabel.putClientProperty("FlatLaf.styleClass", "large");
|
||||
add(largeLabel, "cell 1 17 5 1");
|
||||
largeLabel.putClientProperty(FlatClientProperties.STYLE_CLASS, "large");
|
||||
add(largeLabel, "cell 1 16 5 1");
|
||||
|
||||
//---- defaultLabel ----
|
||||
defaultLabel.setText("default");
|
||||
add(defaultLabel, "cell 1 17 5 1");
|
||||
add(defaultLabel, "cell 1 16 5 1");
|
||||
|
||||
//---- mediumLabel ----
|
||||
mediumLabel.setText("medium");
|
||||
mediumLabel.putClientProperty("FlatLaf.styleClass", "medium");
|
||||
add(mediumLabel, "cell 1 17 5 1");
|
||||
mediumLabel.putClientProperty(FlatClientProperties.STYLE_CLASS, "medium");
|
||||
add(mediumLabel, "cell 1 16 5 1");
|
||||
|
||||
//---- smallLabel ----
|
||||
smallLabel.setText("small");
|
||||
smallLabel.putClientProperty("FlatLaf.styleClass", "small");
|
||||
add(smallLabel, "cell 1 17 5 1");
|
||||
smallLabel.putClientProperty(FlatClientProperties.STYLE_CLASS, "small");
|
||||
add(smallLabel, "cell 1 16 5 1");
|
||||
|
||||
//---- miniLabel ----
|
||||
miniLabel.setText("mini");
|
||||
miniLabel.putClientProperty("FlatLaf.styleClass", "mini");
|
||||
add(miniLabel, "cell 1 17 5 1");
|
||||
miniLabel.putClientProperty(FlatClientProperties.STYLE_CLASS, "mini");
|
||||
add(miniLabel, "cell 1 16 5 1");
|
||||
|
||||
//---- monospacedLabel ----
|
||||
monospacedLabel.setText("monospaced");
|
||||
monospacedLabel.putClientProperty("FlatLaf.styleClass", "monospaced");
|
||||
add(monospacedLabel, "cell 1 17 5 1,gapx 30");
|
||||
monospacedLabel.putClientProperty(FlatClientProperties.STYLE_CLASS, "monospaced");
|
||||
add(monospacedLabel, "cell 1 16 5 1,gapx 30");
|
||||
|
||||
//======== popupMenu1 ========
|
||||
{
|
||||
@@ -875,8 +847,7 @@ class BasicComponentsPanel
|
||||
editorPaneLabel, scrollPane5, scrollPane6, scrollPane7, scrollPane8, editorPane5,
|
||||
textPaneLabel, scrollPane9, scrollPane10, scrollPane11, scrollPane12, textPane5,
|
||||
|
||||
errorHintsLabel, errorHintsTextField, errorHintsComboBox, errorHintsSpinner,
|
||||
warningHintsLabel, warningHintsTextField, warningHintsComboBox, warningHintsSpinner,
|
||||
hintsLabel, errorHintsTextField, warningHintsTextField, successHintsTextField,
|
||||
|
||||
fontZoomLabel,
|
||||
};
|
||||
@@ -899,8 +870,7 @@ class BasicComponentsPanel
|
||||
rows[11].setGapBefore( zeroGap );
|
||||
rows[11].setGapAfter( zeroGap );
|
||||
rows[12].setGapBefore( zeroGap );
|
||||
rows[13].setGapBefore( zeroGap );
|
||||
rows[16].setGapBefore( zeroGap );
|
||||
rows[15].setGapBefore( zeroGap );
|
||||
layout.setRowConstraints( ac );
|
||||
|
||||
// move two text field into same row as spinners
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
JFDML JFormDesigner: "7.0.5.0.404" Java: "17" encoding: "UTF-8"
|
||||
JFDML JFormDesigner: "8.3" encoding: "UTF-8"
|
||||
|
||||
new FormModel {
|
||||
contentType: "form/swing"
|
||||
@@ -9,7 +9,7 @@ new FormModel {
|
||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
||||
"$layoutConstraints": "insets dialog,hidemode 3"
|
||||
"$columnConstraints": "[][sizegroup 1][sizegroup 1][sizegroup 1][][]"
|
||||
"$rowConstraints": "[][][][][][][][][][][][]para[][][][][]0[]"
|
||||
"$rowConstraints": "[][][][][][][][][][][][]para[][][][]0[]"
|
||||
} ) {
|
||||
name: "this"
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
@@ -595,8 +595,8 @@ new FormModel {
|
||||
"value": "cell 5 11,growx"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "errorHintsLabel"
|
||||
"text": "Error hints:"
|
||||
name: "hintsLabel"
|
||||
"text": "Error/warning/success:"
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 12"
|
||||
} )
|
||||
@@ -606,56 +606,23 @@ new FormModel {
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 1 12,growx"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JComboBox" ) {
|
||||
name: "errorHintsComboBox"
|
||||
"$client.JComponent.outline": "error"
|
||||
"model": new javax.swing.DefaultComboBoxModel {
|
||||
selectedItem: "Editable"
|
||||
addElement( "Editable" )
|
||||
}
|
||||
"editable": true
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 2 12,growx"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JSpinner" ) {
|
||||
name: "errorHintsSpinner"
|
||||
"$client.JComponent.outline": "error"
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 3 12,growx"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "warningHintsLabel"
|
||||
"text": "Warning hints:"
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 13"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JTextField" ) {
|
||||
name: "warningHintsTextField"
|
||||
"$client.JComponent.outline": "warning"
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 1 13,growx"
|
||||
"value": "cell 2 12,growx"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JComboBox" ) {
|
||||
name: "warningHintsComboBox"
|
||||
"$client.JComponent.outline": "warning"
|
||||
"model": new javax.swing.DefaultComboBoxModel {
|
||||
selectedItem: "Not editable"
|
||||
addElement( "Not editable" )
|
||||
}
|
||||
add( new FormComponent( "javax.swing.JTextField" ) {
|
||||
name: "successHintsTextField"
|
||||
"$client.JComponent.outline": "success"
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 2 13,growx"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JSpinner" ) {
|
||||
name: "warningHintsSpinner"
|
||||
"$client.JComponent.outline": "warning"
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 3 13,growx"
|
||||
"value": "cell 3 12,growx"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "iconsLabel"
|
||||
"text": "Leading/trailing icons:"
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 14"
|
||||
"value": "cell 0 13"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JTextField" ) {
|
||||
name: "leadingIconTextField"
|
||||
@@ -663,7 +630,7 @@ new FormModel {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
}
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 1 14,growx"
|
||||
"value": "cell 1 13,growx"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JTextField" ) {
|
||||
name: "trailingIconTextField"
|
||||
@@ -672,7 +639,7 @@ new FormModel {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
}
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 2 14,growx"
|
||||
"value": "cell 2 13,growx"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JTextField" ) {
|
||||
name: "iconsTextField"
|
||||
@@ -681,13 +648,13 @@ new FormModel {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
}
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 3 14,growx"
|
||||
"value": "cell 3 13,growx"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "compsLabel"
|
||||
"text": "Leading/trailing comp.:"
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 15"
|
||||
"value": "cell 0 14"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JTextField" ) {
|
||||
name: "compsTextField"
|
||||
@@ -695,7 +662,7 @@ new FormModel {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
}
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 1 15 2 1,growx"
|
||||
"value": "cell 1 14 2 1,growx"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JTextField" ) {
|
||||
name: "clearTextField"
|
||||
@@ -704,69 +671,69 @@ new FormModel {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
}
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 3 15,growx"
|
||||
"value": "cell 3 14,growx"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "fontsLabel"
|
||||
"text": "Typography / Fonts:"
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 16"
|
||||
"value": "cell 0 15"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "h00Label"
|
||||
"text": "H00"
|
||||
"$client.FlatLaf.styleClass": "h00"
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 1 16 5 1"
|
||||
"value": "cell 1 15 5 1"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "h0Label"
|
||||
"text": "H0"
|
||||
"$client.FlatLaf.styleClass": "h0"
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 1 16 5 1"
|
||||
"value": "cell 1 15 5 1"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "h1Label"
|
||||
"text": "H1"
|
||||
"$client.FlatLaf.styleClass": "h1"
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 1 16 5 1"
|
||||
"value": "cell 1 15 5 1"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "h2Label"
|
||||
"text": "H2"
|
||||
"$client.FlatLaf.styleClass": "h2"
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 1 16 5 1"
|
||||
"value": "cell 1 15 5 1"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "h3Label"
|
||||
"text": "H3"
|
||||
"$client.FlatLaf.styleClass": "h3"
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 1 16 5 1"
|
||||
"value": "cell 1 15 5 1"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "h4Label"
|
||||
"text": "H4"
|
||||
"$client.FlatLaf.styleClass": "h4"
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 1 16 5 1"
|
||||
"value": "cell 1 15 5 1"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "lightLabel"
|
||||
"text": "light"
|
||||
"$client.FlatLaf.style": "font: 200% $light.font"
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 1 16 5 1,gapx 30"
|
||||
"value": "cell 1 15 5 1,gapx 30"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "semiboldLabel"
|
||||
"text": "semibold"
|
||||
"$client.FlatLaf.style": "font: 200% $semibold.font"
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 1 16 5 1"
|
||||
"value": "cell 1 15 5 1"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "fontZoomLabel"
|
||||
@@ -774,52 +741,52 @@ new FormModel {
|
||||
"$client.FlatLaf.styleClass": "small"
|
||||
"enabled": false
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 1 16 5 1"
|
||||
"value": "cell 1 15 5 1"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "largeLabel"
|
||||
"text": "large"
|
||||
"$client.FlatLaf.styleClass": "large"
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 1 17 5 1"
|
||||
"value": "cell 1 16 5 1"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "defaultLabel"
|
||||
"text": "default"
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 1 17 5 1"
|
||||
"value": "cell 1 16 5 1"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "mediumLabel"
|
||||
"text": "medium"
|
||||
"$client.FlatLaf.styleClass": "medium"
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 1 17 5 1"
|
||||
"value": "cell 1 16 5 1"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "smallLabel"
|
||||
"text": "small"
|
||||
"$client.FlatLaf.styleClass": "small"
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 1 17 5 1"
|
||||
"value": "cell 1 16 5 1"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "miniLabel"
|
||||
"text": "mini"
|
||||
"$client.FlatLaf.styleClass": "mini"
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 1 17 5 1"
|
||||
"value": "cell 1 16 5 1"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "monospacedLabel"
|
||||
"text": "monospaced"
|
||||
"$client.FlatLaf.styleClass": "monospaced"
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 1 17 5 1,gapx 30"
|
||||
"value": "cell 1 16 5 1,gapx 30"
|
||||
} )
|
||||
}, new FormLayoutConstraints( null ) {
|
||||
"location": new java.awt.Point( 0, 0 )
|
||||
"size": new java.awt.Dimension( 920, 550 )
|
||||
"size": new java.awt.Dimension( 840, 565 )
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JPopupMenu", new FormLayoutManager( class javax.swing.JPopupMenu ) ) {
|
||||
name: "popupMenu1"
|
||||
@@ -839,7 +806,7 @@ new FormModel {
|
||||
"mnemonic": 80
|
||||
} )
|
||||
}, new FormLayoutConstraints( null ) {
|
||||
"location": new java.awt.Point( 0, 570 )
|
||||
"location": new java.awt.Point( 0, 605 )
|
||||
"size": new java.awt.Dimension( 91, 87 )
|
||||
} )
|
||||
}
|
||||
|
||||
@@ -156,6 +156,9 @@ class ControlBar
|
||||
// register Alt+Shift+F1, F2, ... keys to change system scale factor
|
||||
DemoPrefs.registerSystemScaleFactors( frame );
|
||||
|
||||
// register Alt+Shift+S to enable/disable interprocess Laf sync
|
||||
DemoPrefs.initLafSync( frame );
|
||||
|
||||
// register ESC key to close frame
|
||||
((JComponent)frame.getContentPane()).registerKeyboardAction(
|
||||
e -> {
|
||||
|
||||
@@ -22,6 +22,7 @@ import java.awt.datatransfer.DataFlavor;
|
||||
import java.awt.datatransfer.StringSelection;
|
||||
import java.awt.datatransfer.Transferable;
|
||||
import javax.swing.*;
|
||||
import javax.swing.UIDefaults.ActiveValue;
|
||||
import javax.swing.table.*;
|
||||
import javax.swing.tree.*;
|
||||
import com.formdev.flatlaf.FlatClientProperties;
|
||||
@@ -65,6 +66,45 @@ class DataComponentsPanel
|
||||
tree3.putClientProperty( FlatClientProperties.STYLE, "selectionInsets: 0,1,0,1; selectionArc: 6" );
|
||||
}
|
||||
|
||||
private void listAlternatingRowsChanged() {
|
||||
ActiveValue alternateRowColor = null;
|
||||
if( listAlternatingRowsCheckBox.isSelected() ) {
|
||||
alternateRowColor = table -> {
|
||||
Color background = list1.getBackground();
|
||||
return FlatLaf.isLafDark()
|
||||
? ColorFunctions.lighten( background, 0.05f )
|
||||
: ColorFunctions.darken( background, 0.05f );
|
||||
};
|
||||
}
|
||||
UIManager.put( "List.alternateRowColor", alternateRowColor );
|
||||
list1.updateUI();
|
||||
list2.updateUI();
|
||||
list3.updateUI();
|
||||
}
|
||||
|
||||
private void treeWideSelectionChanged() {
|
||||
boolean wideSelection = treeWideSelectionCheckBox.isSelected();
|
||||
tree1.putClientProperty( FlatClientProperties.TREE_WIDE_SELECTION, wideSelection );
|
||||
tree2.putClientProperty( FlatClientProperties.TREE_WIDE_SELECTION, wideSelection );
|
||||
tree3.putClientProperty( FlatClientProperties.TREE_WIDE_SELECTION, wideSelection );
|
||||
}
|
||||
|
||||
private void treeAlternatingRowsChanged() {
|
||||
ActiveValue alternateRowColor = null;
|
||||
if( treeAlternatingRowsCheckBox.isSelected() ) {
|
||||
alternateRowColor = table -> {
|
||||
Color background = tree1.getBackground();
|
||||
return FlatLaf.isLafDark()
|
||||
? ColorFunctions.lighten( background, 0.05f )
|
||||
: ColorFunctions.darken( background, 0.05f );
|
||||
};
|
||||
}
|
||||
UIManager.put( "Tree.alternateRowColor", alternateRowColor );
|
||||
tree1.updateUI();
|
||||
tree2.updateUI();
|
||||
tree3.updateUI();
|
||||
}
|
||||
|
||||
private void dndChanged() {
|
||||
boolean dnd = dndCheckBox.isSelected();
|
||||
DropMode dropMode = dnd ? DropMode.ON_OR_INSERT : DropMode.USE_SELECTION;
|
||||
@@ -142,18 +182,20 @@ class DataComponentsPanel
|
||||
}
|
||||
|
||||
private void alternatingRowsChanged() {
|
||||
Color alternateRowColor = null;
|
||||
ActiveValue alternateRowColor = null;
|
||||
if( alternatingRowsCheckBox.isSelected() ) {
|
||||
Color background = table1.getBackground();
|
||||
alternateRowColor = FlatLaf.isLafDark()
|
||||
? ColorFunctions.lighten( background, 0.05f )
|
||||
: ColorFunctions.darken( background, 0.05f );
|
||||
alternateRowColor = table -> {
|
||||
Color background = table1.getBackground();
|
||||
return FlatLaf.isLafDark()
|
||||
? ColorFunctions.lighten( background, 0.05f )
|
||||
: ColorFunctions.darken( background, 0.05f );
|
||||
};
|
||||
}
|
||||
UIManager.put( "Table.alternateRowColor", alternateRowColor );
|
||||
table1.repaint();
|
||||
}
|
||||
|
||||
@SuppressWarnings( { "unchecked", "rawtypes" } )
|
||||
@SuppressWarnings( { "rawtypes" } )
|
||||
private void initComponents() {
|
||||
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
|
||||
JLabel label1 = new JLabel();
|
||||
@@ -166,6 +208,8 @@ class DataComponentsPanel
|
||||
list3 = new JList<>();
|
||||
JScrollPane scrollPane2 = new JScrollPane();
|
||||
list2 = new JList<>();
|
||||
JPanel listOptionsPanel = new JPanel();
|
||||
listAlternatingRowsCheckBox = new JCheckBox();
|
||||
JLabel treeLabel = new JLabel();
|
||||
JScrollPane scrollPane3 = new JScrollPane();
|
||||
tree1 = new JTree();
|
||||
@@ -173,6 +217,9 @@ class DataComponentsPanel
|
||||
tree3 = new JTree();
|
||||
JScrollPane scrollPane4 = new JScrollPane();
|
||||
tree2 = new JTree();
|
||||
JPanel treeOptionsPanel = new JPanel();
|
||||
treeWideSelectionCheckBox = new JCheckBox();
|
||||
treeAlternatingRowsCheckBox = new JCheckBox();
|
||||
JLabel tableLabel = new JLabel();
|
||||
JScrollPane scrollPane5 = new JScrollPane();
|
||||
table1 = new JTable();
|
||||
@@ -205,7 +252,7 @@ class DataComponentsPanel
|
||||
"[]" +
|
||||
"[150,grow,sizegroup 1,fill]" +
|
||||
"[150,grow,sizegroup 1,fill]" +
|
||||
"[150,grow,sizegroup 1,fill]"));
|
||||
"[150,grow,fill]"));
|
||||
|
||||
//---- label1 ----
|
||||
label1.setText("Square Selection");
|
||||
@@ -273,6 +320,22 @@ class DataComponentsPanel
|
||||
}
|
||||
add(scrollPane2, "cell 3 1");
|
||||
|
||||
//======== listOptionsPanel ========
|
||||
{
|
||||
listOptionsPanel.setLayout(new MigLayout(
|
||||
"insets 0,hidemode 3",
|
||||
// columns
|
||||
"[fill]",
|
||||
// rows
|
||||
"[]"));
|
||||
|
||||
//---- listAlternatingRowsCheckBox ----
|
||||
listAlternatingRowsCheckBox.setText("alternating rows");
|
||||
listAlternatingRowsCheckBox.addActionListener(e -> listAlternatingRowsChanged());
|
||||
listOptionsPanel.add(listAlternatingRowsCheckBox, "cell 0 0");
|
||||
}
|
||||
add(listOptionsPanel, "cell 4 1");
|
||||
|
||||
//---- treeLabel ----
|
||||
treeLabel.setText("JTree:");
|
||||
add(treeLabel, "cell 0 2,aligny top,growy 0");
|
||||
@@ -334,6 +397,29 @@ class DataComponentsPanel
|
||||
}
|
||||
add(scrollPane4, "cell 3 2");
|
||||
|
||||
//======== treeOptionsPanel ========
|
||||
{
|
||||
treeOptionsPanel.setLayout(new MigLayout(
|
||||
"insets 0,hidemode 3",
|
||||
// columns
|
||||
"[fill]",
|
||||
// rows
|
||||
"[]0" +
|
||||
"[]"));
|
||||
|
||||
//---- treeWideSelectionCheckBox ----
|
||||
treeWideSelectionCheckBox.setText("wide selection");
|
||||
treeWideSelectionCheckBox.setSelected(true);
|
||||
treeWideSelectionCheckBox.addActionListener(e -> treeWideSelectionChanged());
|
||||
treeOptionsPanel.add(treeWideSelectionCheckBox, "cell 0 0");
|
||||
|
||||
//---- treeAlternatingRowsCheckBox ----
|
||||
treeAlternatingRowsCheckBox.setText("alternating rows");
|
||||
treeAlternatingRowsCheckBox.addActionListener(e -> treeAlternatingRowsChanged());
|
||||
treeOptionsPanel.add(treeAlternatingRowsCheckBox, "cell 0 1");
|
||||
}
|
||||
add(treeOptionsPanel, "cell 4 2");
|
||||
|
||||
//---- tableLabel ----
|
||||
tableLabel.setText("JTable:");
|
||||
add(tableLabel, "cell 0 3,aligny top,growy 0");
|
||||
@@ -379,7 +465,7 @@ class DataComponentsPanel
|
||||
{
|
||||
TableColumnModel cm = table1.getColumnModel();
|
||||
cm.getColumn(2).setCellEditor(new DefaultCellEditor(
|
||||
new JComboBox(new DefaultComboBoxModel(new String[] {
|
||||
new JComboBox<>(new DefaultComboBoxModel<>(new String[] {
|
||||
"January",
|
||||
"February",
|
||||
"March",
|
||||
@@ -394,7 +480,7 @@ class DataComponentsPanel
|
||||
"December"
|
||||
}))));
|
||||
cm.getColumn(3).setCellEditor(new DefaultCellEditor(
|
||||
new JComboBox(new DefaultComboBoxModel(new String[] {
|
||||
new JComboBox<>(new DefaultComboBoxModel<>(new String[] {
|
||||
"January",
|
||||
"February",
|
||||
"March",
|
||||
@@ -513,9 +599,12 @@ class DataComponentsPanel
|
||||
private JList<String> list1;
|
||||
private JList<String> list3;
|
||||
private JList<String> list2;
|
||||
private JCheckBox listAlternatingRowsCheckBox;
|
||||
private JTree tree1;
|
||||
private JTree tree3;
|
||||
private JTree tree2;
|
||||
private JCheckBox treeWideSelectionCheckBox;
|
||||
private JCheckBox treeAlternatingRowsCheckBox;
|
||||
private JTable table1;
|
||||
private JCheckBox roundedSelectionCheckBox;
|
||||
private JCheckBox showHorizontalLinesCheckBox;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
JFDML JFormDesigner: "8.2.0.0.331" Java: "21" encoding: "UTF-8"
|
||||
JFDML JFormDesigner: "8.3" encoding: "UTF-8"
|
||||
|
||||
new FormModel {
|
||||
contentType: "form/swing"
|
||||
@@ -9,7 +9,7 @@ new FormModel {
|
||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
||||
"$layoutConstraints": "insets dialog,hidemode 3"
|
||||
"$columnConstraints": "[][150,fill][150,fill][150,fill][fill]"
|
||||
"$rowConstraints": "[][150,grow,sizegroup 1,fill][150,grow,sizegroup 1,fill][150,grow,sizegroup 1,fill]"
|
||||
"$rowConstraints": "[][150,grow,sizegroup 1,fill][150,grow,sizegroup 1,fill][150,grow,fill]"
|
||||
} ) {
|
||||
name: "this"
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
@@ -92,6 +92,25 @@ new FormModel {
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 3 1"
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
||||
"$layoutConstraints": "insets 0,hidemode 3"
|
||||
"$columnConstraints": "[fill]"
|
||||
"$rowConstraints": "[]"
|
||||
} ) {
|
||||
name: "listOptionsPanel"
|
||||
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||
name: "listAlternatingRowsCheckBox"
|
||||
"text": "alternating rows"
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
}
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "listAlternatingRowsChanged", false ) )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 0"
|
||||
} )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 4 1"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "treeLabel"
|
||||
"text": "JTree:"
|
||||
@@ -192,6 +211,36 @@ new FormModel {
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 3 2"
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
||||
"$layoutConstraints": "insets 0,hidemode 3"
|
||||
"$columnConstraints": "[fill]"
|
||||
"$rowConstraints": "[]0[]"
|
||||
} ) {
|
||||
name: "treeOptionsPanel"
|
||||
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||
name: "treeWideSelectionCheckBox"
|
||||
"text": "wide selection"
|
||||
"selected": true
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
}
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "treeWideSelectionChanged", false ) )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 0"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||
name: "treeAlternatingRowsCheckBox"
|
||||
"text": "alternating rows"
|
||||
auxiliary() {
|
||||
"JavaCodeGenerator.variableLocal": false
|
||||
}
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "treeAlternatingRowsChanged", false ) )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 0 1"
|
||||
} )
|
||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||
"value": "cell 4 2"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||
name: "tableLabel"
|
||||
"text": "JTable:"
|
||||
|
||||
@@ -228,8 +228,20 @@ class DemoFrame
|
||||
private void windowDecorationsChanged() {
|
||||
boolean windowDecorations = windowDecorationsCheckBoxMenuItem.isSelected();
|
||||
|
||||
// change window decoration of all frames and dialogs
|
||||
FlatLaf.setUseNativeWindowDecorations( windowDecorations );
|
||||
if( SystemInfo.isLinux ) {
|
||||
// enable/disable custom window decorations
|
||||
JFrame.setDefaultLookAndFeelDecorated( windowDecorations );
|
||||
JDialog.setDefaultLookAndFeelDecorated( windowDecorations );
|
||||
|
||||
// dispose frame, update decoration and re-show frame
|
||||
dispose();
|
||||
setUndecorated( windowDecorations );
|
||||
getRootPane().setWindowDecorationStyle( windowDecorations ? JRootPane.FRAME : JRootPane.NONE );
|
||||
setVisible( true );
|
||||
} else {
|
||||
// change window decoration of all frames and dialogs
|
||||
FlatLaf.setUseNativeWindowDecorations( windowDecorations );
|
||||
}
|
||||
|
||||
menuBarEmbeddedCheckBoxMenuItem.setEnabled( windowDecorations );
|
||||
unifiedTitleBarMenuItem.setEnabled( windowDecorations );
|
||||
@@ -486,7 +498,7 @@ class DemoFrame
|
||||
}
|
||||
|
||||
private boolean supportsFlatLafWindowDecorations() {
|
||||
return FlatLaf.supportsNativeWindowDecorations() || (SystemInfo.isLinux && JFrame.isDefaultLookAndFeelDecorated());
|
||||
return FlatLaf.supportsNativeWindowDecorations() || SystemInfo.isLinux;
|
||||
}
|
||||
|
||||
private void initComponents() {
|
||||
@@ -979,10 +991,9 @@ class DemoFrame
|
||||
scrollingPopupMenu.add( "Item " + i );
|
||||
|
||||
if( supportsFlatLafWindowDecorations() ) {
|
||||
if( SystemInfo.isLinux )
|
||||
unsupported( windowDecorationsCheckBoxMenuItem );
|
||||
else
|
||||
windowDecorationsCheckBoxMenuItem.setSelected( FlatLaf.isUseNativeWindowDecorations() );
|
||||
windowDecorationsCheckBoxMenuItem.setSelected( SystemInfo.isLinux
|
||||
? JFrame.isDefaultLookAndFeelDecorated()
|
||||
: FlatLaf.isUseNativeWindowDecorations() );
|
||||
menuBarEmbeddedCheckBoxMenuItem.setSelected( UIManager.getBoolean( "TitlePane.menuBarEmbedded" ) );
|
||||
unifiedTitleBarMenuItem.setSelected( UIManager.getBoolean( "TitlePane.unifiedBackground" ) );
|
||||
showTitleBarIconMenuItem.setSelected( UIManager.getBoolean( "TitlePane.showIcon" ) );
|
||||
@@ -1026,7 +1037,7 @@ class DemoFrame
|
||||
private void unsupported( JCheckBoxMenuItem menuItem ) {
|
||||
menuItem.setEnabled( false );
|
||||
menuItem.setSelected( false );
|
||||
menuItem.setToolTipText( "Not supported on your system." );
|
||||
menuItem.setToolTipText( "Not supported on this platform." );
|
||||
}
|
||||
|
||||
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
|
||||
|
||||
@@ -16,8 +16,15 @@
|
||||
|
||||
package com.formdev.flatlaf.demo;
|
||||
|
||||
import java.awt.EventQueue;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.InetAddress;
|
||||
import java.net.MulticastSocket;
|
||||
import java.net.SocketException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.prefs.Preferences;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JFrame;
|
||||
@@ -28,7 +35,6 @@ import com.formdev.flatlaf.FlatLaf;
|
||||
import com.formdev.flatlaf.FlatLightLaf;
|
||||
import com.formdev.flatlaf.FlatPropertiesLaf;
|
||||
import com.formdev.flatlaf.IntelliJTheme;
|
||||
import com.formdev.flatlaf.demo.intellijthemes.IJThemesPanel;
|
||||
import com.formdev.flatlaf.util.LoggingFacade;
|
||||
import com.formdev.flatlaf.util.StringUtils;
|
||||
import com.formdev.flatlaf.util.SystemInfo;
|
||||
@@ -38,14 +44,10 @@ import com.formdev.flatlaf.util.SystemInfo;
|
||||
*/
|
||||
public class DemoPrefs
|
||||
{
|
||||
public static final String KEY_LAF = "laf";
|
||||
public static final String KEY_LAF_THEME = "lafTheme";
|
||||
public static final String KEY_LAF_CLASS_NAME = "lafClassName";
|
||||
public static final String KEY_LAF_THEME_FILE = "lafThemeFile";
|
||||
public static final String KEY_SYSTEM_SCALE_FACTOR = "systemScaleFactor";
|
||||
|
||||
public static final String RESOURCE_PREFIX = "res:";
|
||||
public static final String FILE_PREFIX = "file:";
|
||||
|
||||
public static final String THEME_UI_KEY = "__FlatLaf.demo.theme";
|
||||
public static final String KEY_LAF_SYNC = "lafSync";
|
||||
|
||||
private static Preferences state;
|
||||
|
||||
@@ -58,37 +60,14 @@ public class DemoPrefs
|
||||
}
|
||||
|
||||
public static void setupLaf( String[] args ) {
|
||||
// com.formdev.flatlaf.demo.intellijthemes.IJThemesDump.install();
|
||||
|
||||
// set look and feel
|
||||
try {
|
||||
if( args.length > 0 )
|
||||
UIManager.setLookAndFeel( args[0] );
|
||||
else {
|
||||
String lafClassName = state.get( KEY_LAF, FlatLightLaf.class.getName() );
|
||||
if( IntelliJTheme.ThemeLaf.class.getName().equals( lafClassName ) ) {
|
||||
String theme = state.get( KEY_LAF_THEME, "" );
|
||||
if( theme.startsWith( RESOURCE_PREFIX ) )
|
||||
IntelliJTheme.setup( IJThemesPanel.class.getResourceAsStream( IJThemesPanel.THEMES_PACKAGE + theme.substring( RESOURCE_PREFIX.length() ) ) );
|
||||
else if( theme.startsWith( FILE_PREFIX ) )
|
||||
FlatLaf.setup( IntelliJTheme.createLaf( new FileInputStream( theme.substring( FILE_PREFIX.length() ) ) ) );
|
||||
else
|
||||
FlatLightLaf.setup();
|
||||
|
||||
if( !theme.isEmpty() )
|
||||
UIManager.getLookAndFeelDefaults().put( THEME_UI_KEY, theme );
|
||||
} else if( FlatPropertiesLaf.class.getName().equals( lafClassName ) ) {
|
||||
String theme = state.get( KEY_LAF_THEME, "" );
|
||||
if( theme.startsWith( FILE_PREFIX ) ) {
|
||||
File themeFile = new File( theme.substring( FILE_PREFIX.length() ) );
|
||||
String themeName = StringUtils.removeTrailing( themeFile.getName(), ".properties" );
|
||||
FlatLaf.setup( new FlatPropertiesLaf( themeName, themeFile ) );
|
||||
} else
|
||||
FlatLightLaf.setup();
|
||||
|
||||
if( !theme.isEmpty() )
|
||||
UIManager.getLookAndFeelDefaults().put( THEME_UI_KEY, theme );
|
||||
} else
|
||||
UIManager.setLookAndFeel( lafClassName );
|
||||
}
|
||||
else
|
||||
restoreLaf();
|
||||
} catch( Throwable ex ) {
|
||||
LoggingFacade.INSTANCE.logSevere( null, ex );
|
||||
|
||||
@@ -98,16 +77,44 @@ public class DemoPrefs
|
||||
|
||||
// remember active look and feel
|
||||
UIManager.addPropertyChangeListener( e -> {
|
||||
if( "lookAndFeel".equals( e.getPropertyName() ) )
|
||||
state.put( KEY_LAF, UIManager.getLookAndFeel().getClass().getName() );
|
||||
if( "lookAndFeel".equals( e.getPropertyName() ) ) {
|
||||
state.put( KEY_LAF_CLASS_NAME, UIManager.getLookAndFeel().getClass().getName() );
|
||||
notifyLafChange();
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
private static void restoreLaf()
|
||||
throws Exception
|
||||
{
|
||||
String lafClassName = state.get( KEY_LAF_CLASS_NAME, FlatLightLaf.class.getName() );
|
||||
if( FlatPropertiesLaf.class.getName().equals( lafClassName ) ||
|
||||
IntelliJTheme.ThemeLaf.class.getName().equals( lafClassName ) )
|
||||
{
|
||||
String themeFileName = state.get( KEY_LAF_THEME_FILE, "" );
|
||||
if( !themeFileName.isEmpty() ) {
|
||||
File themeFile = new File( themeFileName );
|
||||
|
||||
if( themeFileName.endsWith( ".properties" ) ) {
|
||||
String themeName = StringUtils.removeTrailing( themeFile.getName(), ".properties" );
|
||||
FlatLaf.setup( new FlatPropertiesLaf( themeName, themeFile ) );
|
||||
} else
|
||||
FlatLaf.setup( IntelliJTheme.createLaf( new FileInputStream( themeFile ) ) );
|
||||
} else
|
||||
FlatLightLaf.setup();
|
||||
} else
|
||||
UIManager.setLookAndFeel( lafClassName );
|
||||
}
|
||||
|
||||
public static void initSystemScale() {
|
||||
if( System.getProperty( "sun.java2d.uiScale" ) == null ) {
|
||||
String scaleFactor = getState().get( KEY_SYSTEM_SCALE_FACTOR, null );
|
||||
if( scaleFactor != null )
|
||||
String scaleFactor = state.get( KEY_SYSTEM_SCALE_FACTOR, null );
|
||||
if( scaleFactor != null ) {
|
||||
System.setProperty( "sun.java2d.uiScale", scaleFactor );
|
||||
|
||||
System.out.println( "FlatLaf: setting 'sun.java2d.uiScale' to " + scaleFactor );
|
||||
System.out.println( " use 'Alt+Shift+F1...12' to change it to 1x...4x" );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,10 +165,113 @@ public class DemoPrefs
|
||||
return;
|
||||
|
||||
if( scaleFactor != null )
|
||||
DemoPrefs.getState().put( KEY_SYSTEM_SCALE_FACTOR, scaleFactor );
|
||||
state.put( KEY_SYSTEM_SCALE_FACTOR, scaleFactor );
|
||||
else
|
||||
DemoPrefs.getState().remove( KEY_SYSTEM_SCALE_FACTOR );
|
||||
state.remove( KEY_SYSTEM_SCALE_FACTOR );
|
||||
|
||||
System.exit( 0 );
|
||||
}
|
||||
|
||||
//---- inter-process Laf change notification/synchronisation --------------
|
||||
|
||||
// used for FlatLaf development when running multiple testing apps
|
||||
|
||||
private static final String MULTICAST_ADDRESS = "224.63.31.41";
|
||||
private static final int MULTICAST_PORT = 36584;
|
||||
private static final long PROCESS_ID = System.nanoTime();
|
||||
|
||||
private static Thread thread;
|
||||
private static boolean notifyEnabled = true;
|
||||
|
||||
public static void initLafSync( JFrame frame ) {
|
||||
((JComponent)frame.getContentPane()).registerKeyboardAction(
|
||||
e -> enableDisableLafSync(),
|
||||
KeyStroke.getKeyStroke( "alt shift S" ),
|
||||
JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT );
|
||||
|
||||
if( state.getBoolean( KEY_LAF_SYNC, false ) ) {
|
||||
System.out.println( "FlatLaf: theme sync enabled; use Alt+Shift+S to disable it" );
|
||||
listenToLafChange();
|
||||
}
|
||||
}
|
||||
|
||||
private static void enableDisableLafSync() {
|
||||
boolean enabled = !state.getBoolean( KEY_LAF_SYNC, false );
|
||||
state.putBoolean( KEY_LAF_SYNC, enabled );
|
||||
|
||||
if( enabled )
|
||||
listenToLafChange();
|
||||
else if( thread != null) {
|
||||
thread.interrupt();
|
||||
thread = null;
|
||||
}
|
||||
}
|
||||
|
||||
private static void listenToLafChange() {
|
||||
if( thread != null )
|
||||
return;
|
||||
|
||||
thread = new Thread( "FlatLaf Laf change listener" ) {
|
||||
MulticastSocket socket;
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try( MulticastSocket socket = new MulticastSocket( MULTICAST_PORT ) ) {
|
||||
this.socket = socket;
|
||||
socket.joinGroup( InetAddress.getByName( MULTICAST_ADDRESS ) );
|
||||
|
||||
byte[] buffer = new byte[Long.BYTES];
|
||||
for(;;) {
|
||||
DatagramPacket packet = new DatagramPacket( buffer, buffer.length );
|
||||
socket.receive( packet );
|
||||
|
||||
long id = ByteBuffer.wrap( buffer ).getLong();
|
||||
if( id == PROCESS_ID )
|
||||
continue; // was sent from this process
|
||||
|
||||
EventQueue.invokeLater( () -> {
|
||||
notifyEnabled = false;
|
||||
try {
|
||||
restoreLaf();
|
||||
FlatLaf.updateUI();
|
||||
} catch( Throwable ex ) {
|
||||
LoggingFacade.INSTANCE.logSevere( null, ex );
|
||||
} finally {
|
||||
notifyEnabled = true;
|
||||
}
|
||||
} );
|
||||
}
|
||||
} catch( IOException ex ) {
|
||||
if( ex instanceof SocketException && "Socket closed".equals( ex.getMessage() ) )
|
||||
return; // interrupted
|
||||
|
||||
LoggingFacade.INSTANCE.logSevere( null, ex );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void interrupt() {
|
||||
super.interrupt();
|
||||
socket.close();
|
||||
}
|
||||
};
|
||||
thread.setDaemon( true );
|
||||
thread.start();
|
||||
}
|
||||
|
||||
private static void notifyLafChange() {
|
||||
if( thread == null || !notifyEnabled )
|
||||
return;
|
||||
|
||||
EventQueue.invokeLater( () -> {
|
||||
try( MulticastSocket socket = new MulticastSocket() ) {
|
||||
InetAddress address = InetAddress.getByName( MULTICAST_ADDRESS );
|
||||
byte[] buffer = ByteBuffer.wrap( new byte[Long.BYTES] ).putLong( PROCESS_ID ).array();
|
||||
DatagramPacket packet = new DatagramPacket( buffer, buffer.length, address, MULTICAST_PORT );
|
||||
socket.send( packet );
|
||||
} catch( IOException ex ) {
|
||||
LoggingFacade.INSTANCE.logSevere( null, ex );
|
||||
}
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.formdev.flatlaf.demo;
|
||||
import java.awt.*;
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.*;
|
||||
import com.formdev.flatlaf.FlatClientProperties;
|
||||
import net.miginfocom.swing.*;
|
||||
|
||||
/**
|
||||
@@ -176,12 +177,12 @@ class MoreComponentsPanel
|
||||
add(scrollBar3, "cell 2 0 1 6,growy");
|
||||
|
||||
//---- scrollBar7 ----
|
||||
scrollBar7.putClientProperty("JScrollBar.showButtons", true);
|
||||
scrollBar7.putClientProperty(FlatClientProperties.SCROLL_BAR_SHOW_BUTTONS, true);
|
||||
add(scrollBar7, "cell 2 0 1 6,growy");
|
||||
|
||||
//---- scrollBar8 ----
|
||||
scrollBar8.setEnabled(false);
|
||||
scrollBar8.putClientProperty("JScrollBar.showButtons", true);
|
||||
scrollBar8.putClientProperty(FlatClientProperties.SCROLL_BAR_SHOW_BUTTONS, true);
|
||||
add(scrollBar8, "cell 2 0 1 6,growy");
|
||||
|
||||
//---- separator2 ----
|
||||
@@ -301,13 +302,13 @@ class MoreComponentsPanel
|
||||
|
||||
//---- scrollBar5 ----
|
||||
scrollBar5.setOrientation(Adjustable.HORIZONTAL);
|
||||
scrollBar5.putClientProperty("JScrollBar.showButtons", true);
|
||||
scrollBar5.putClientProperty(FlatClientProperties.SCROLL_BAR_SHOW_BUTTONS, true);
|
||||
add(scrollBar5, "cell 1 3,growx");
|
||||
|
||||
//---- scrollBar6 ----
|
||||
scrollBar6.setOrientation(Adjustable.HORIZONTAL);
|
||||
scrollBar6.setEnabled(false);
|
||||
scrollBar6.putClientProperty("JScrollBar.showButtons", true);
|
||||
scrollBar6.putClientProperty(FlatClientProperties.SCROLL_BAR_SHOW_BUTTONS, true);
|
||||
add(scrollBar6, "cell 1 4,growx");
|
||||
|
||||
//---- separatorLabel ----
|
||||
@@ -518,7 +519,7 @@ class MoreComponentsPanel
|
||||
|
||||
//======== panel5 ========
|
||||
{
|
||||
panel5.putClientProperty("FlatLaf.style", "arc: 16; background: darken($Panel.background,5%)");
|
||||
panel5.putClientProperty(FlatClientProperties.STYLE, "arc: 16; background: darken($Panel.background,5%)");
|
||||
panel5.setLayout(new BorderLayout());
|
||||
|
||||
//---- label9 ----
|
||||
@@ -530,7 +531,7 @@ class MoreComponentsPanel
|
||||
|
||||
//======== panel4 ========
|
||||
{
|
||||
panel4.putClientProperty("FlatLaf.style", "border: 1,1,1,1,@disabledForeground,1,16; background: darken($Panel.background,5%)");
|
||||
panel4.putClientProperty(FlatClientProperties.STYLE, "border: 1,1,1,1,@disabledForeground,1,16; background: darken($Panel.background,5%)");
|
||||
panel4.setLayout(new BorderLayout());
|
||||
|
||||
//---- label8 ----
|
||||
@@ -546,14 +547,14 @@ class MoreComponentsPanel
|
||||
|
||||
//---- label13 ----
|
||||
label13.setText("rounded background");
|
||||
label13.putClientProperty("FlatLaf.style", "arc: 999; border: 2,10,2,10");
|
||||
label13.putClientProperty(FlatClientProperties.STYLE, "arc: 999; border: 2,10,2,10");
|
||||
label13.setBackground(new Color(0xb8e4f3));
|
||||
label13.setForeground(new Color(0x135b76));
|
||||
add(label13, "cell 1 13 4 1");
|
||||
|
||||
//---- label10 ----
|
||||
label10.setText("rounded border");
|
||||
label10.putClientProperty("FlatLaf.style", "arc: 999; border: 2,10,2,10,#135b76");
|
||||
label10.putClientProperty(FlatClientProperties.STYLE, "arc: 999; border: 2,10,2,10,#135b76");
|
||||
label10.setBackground(new Color(0xb8e4f3));
|
||||
label10.setForeground(new Color(0x135b76));
|
||||
add(label10, "cell 1 13 4 1");
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.formdev.flatlaf.demo;
|
||||
|
||||
import com.formdev.flatlaf.FlatClientProperties;
|
||||
import static com.formdev.flatlaf.FlatClientProperties.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.MouseEvent;
|
||||
@@ -471,7 +472,7 @@ class TabsPanel
|
||||
|
||||
//---- tabPlacementLabel ----
|
||||
tabPlacementLabel.setText("Tab placement");
|
||||
tabPlacementLabel.putClientProperty("FlatLaf.styleClass", "h3");
|
||||
tabPlacementLabel.putClientProperty(FlatClientProperties.STYLE_CLASS, "h3");
|
||||
panel1.add(tabPlacementLabel, "cell 0 0");
|
||||
|
||||
//======== tabPlacementToolBar ========
|
||||
@@ -482,38 +483,38 @@ class TabsPanel
|
||||
//---- topPlacementButton ----
|
||||
topPlacementButton.setText("top");
|
||||
topPlacementButton.setSelected(true);
|
||||
topPlacementButton.putClientProperty("FlatLaf.styleClass", "small");
|
||||
topPlacementButton.putClientProperty(FlatClientProperties.STYLE_CLASS, "small");
|
||||
topPlacementButton.addActionListener(e -> tabPlacementChanged());
|
||||
tabPlacementToolBar.add(topPlacementButton);
|
||||
|
||||
//---- bottomPlacementButton ----
|
||||
bottomPlacementButton.setText("bottom");
|
||||
bottomPlacementButton.putClientProperty("FlatLaf.styleClass", "small");
|
||||
bottomPlacementButton.putClientProperty(FlatClientProperties.STYLE_CLASS, "small");
|
||||
bottomPlacementButton.addActionListener(e -> tabPlacementChanged());
|
||||
tabPlacementToolBar.add(bottomPlacementButton);
|
||||
|
||||
//---- leftPlacementButton ----
|
||||
leftPlacementButton.setText("left");
|
||||
leftPlacementButton.putClientProperty("FlatLaf.styleClass", "small");
|
||||
leftPlacementButton.putClientProperty(FlatClientProperties.STYLE_CLASS, "small");
|
||||
leftPlacementButton.addActionListener(e -> tabPlacementChanged());
|
||||
tabPlacementToolBar.add(leftPlacementButton);
|
||||
|
||||
//---- rightPlacementButton ----
|
||||
rightPlacementButton.setText("right");
|
||||
rightPlacementButton.putClientProperty("FlatLaf.styleClass", "small");
|
||||
rightPlacementButton.putClientProperty(FlatClientProperties.STYLE_CLASS, "small");
|
||||
rightPlacementButton.addActionListener(e -> tabPlacementChanged());
|
||||
tabPlacementToolBar.add(rightPlacementButton);
|
||||
tabPlacementToolBar.addSeparator();
|
||||
|
||||
//---- scrollButton ----
|
||||
scrollButton.setText("scroll");
|
||||
scrollButton.putClientProperty("FlatLaf.styleClass", "small");
|
||||
scrollButton.putClientProperty(FlatClientProperties.STYLE_CLASS, "small");
|
||||
scrollButton.addActionListener(e -> scrollChanged());
|
||||
tabPlacementToolBar.add(scrollButton);
|
||||
|
||||
//---- borderButton ----
|
||||
borderButton.setText("border");
|
||||
borderButton.putClientProperty("FlatLaf.styleClass", "small");
|
||||
borderButton.putClientProperty(FlatClientProperties.STYLE_CLASS, "small");
|
||||
borderButton.addActionListener(e -> borderChanged());
|
||||
tabPlacementToolBar.add(borderButton);
|
||||
}
|
||||
@@ -522,7 +523,7 @@ class TabsPanel
|
||||
|
||||
//---- tabLayoutLabel ----
|
||||
tabLayoutLabel.setText("Tab layout");
|
||||
tabLayoutLabel.putClientProperty("FlatLaf.styleClass", "h3");
|
||||
tabLayoutLabel.putClientProperty(FlatClientProperties.STYLE_CLASS, "h3");
|
||||
panel1.add(tabLayoutLabel, "cell 0 2");
|
||||
|
||||
//======== tabLayoutToolBar ========
|
||||
@@ -533,13 +534,13 @@ class TabsPanel
|
||||
//---- scrollTabLayoutButton ----
|
||||
scrollTabLayoutButton.setText("scroll");
|
||||
scrollTabLayoutButton.setSelected(true);
|
||||
scrollTabLayoutButton.putClientProperty("FlatLaf.styleClass", "small");
|
||||
scrollTabLayoutButton.putClientProperty(FlatClientProperties.STYLE_CLASS, "small");
|
||||
scrollTabLayoutButton.addActionListener(e -> tabLayoutChanged());
|
||||
tabLayoutToolBar.add(scrollTabLayoutButton);
|
||||
|
||||
//---- wrapTabLayoutButton ----
|
||||
wrapTabLayoutButton.setText("wrap");
|
||||
wrapTabLayoutButton.putClientProperty("FlatLaf.styleClass", "small");
|
||||
wrapTabLayoutButton.putClientProperty(FlatClientProperties.STYLE_CLASS, "small");
|
||||
wrapTabLayoutButton.addActionListener(e -> tabLayoutChanged());
|
||||
tabLayoutToolBar.add(wrapTabLayoutButton);
|
||||
}
|
||||
@@ -548,20 +549,20 @@ class TabsPanel
|
||||
//---- scrollLayoutNoteLabel ----
|
||||
scrollLayoutNoteLabel.setText("(use mouse wheel to scroll; arrow button shows hidden tabs)");
|
||||
scrollLayoutNoteLabel.setEnabled(false);
|
||||
scrollLayoutNoteLabel.putClientProperty("FlatLaf.styleClass", "small");
|
||||
scrollLayoutNoteLabel.putClientProperty(FlatClientProperties.STYLE_CLASS, "small");
|
||||
panel1.add(scrollLayoutNoteLabel, "cell 0 3");
|
||||
|
||||
//---- wrapLayoutNoteLabel ----
|
||||
wrapLayoutNoteLabel.setText("(probably better to use scroll layout?)");
|
||||
wrapLayoutNoteLabel.setEnabled(false);
|
||||
wrapLayoutNoteLabel.putClientProperty("FlatLaf.styleClass", "small");
|
||||
wrapLayoutNoteLabel.putClientProperty(FlatClientProperties.STYLE_CLASS, "small");
|
||||
panel1.add(wrapLayoutNoteLabel, "cell 0 3");
|
||||
panel1.add(scrollLayoutTabbedPane, "cell 0 4");
|
||||
panel1.add(wrapLayoutTabbedPane, "cell 0 4,width 100:100,height pref*2px");
|
||||
|
||||
//---- closableTabsLabel ----
|
||||
closableTabsLabel.setText("Closable tabs");
|
||||
closableTabsLabel.putClientProperty("FlatLaf.styleClass", "h3");
|
||||
closableTabsLabel.putClientProperty(FlatClientProperties.STYLE_CLASS, "h3");
|
||||
panel1.add(closableTabsLabel, "cell 0 5");
|
||||
|
||||
//======== closableTabsToolBar ========
|
||||
@@ -572,19 +573,19 @@ class TabsPanel
|
||||
//---- squareCloseButton ----
|
||||
squareCloseButton.setText("square");
|
||||
squareCloseButton.setSelected(true);
|
||||
squareCloseButton.putClientProperty("FlatLaf.styleClass", "small");
|
||||
squareCloseButton.putClientProperty(FlatClientProperties.STYLE_CLASS, "small");
|
||||
squareCloseButton.addActionListener(e -> closeButtonStyleChanged());
|
||||
closableTabsToolBar.add(squareCloseButton);
|
||||
|
||||
//---- circleCloseButton ----
|
||||
circleCloseButton.setText("circle");
|
||||
circleCloseButton.putClientProperty("FlatLaf.styleClass", "small");
|
||||
circleCloseButton.putClientProperty(FlatClientProperties.STYLE_CLASS, "small");
|
||||
circleCloseButton.addActionListener(e -> closeButtonStyleChanged());
|
||||
closableTabsToolBar.add(circleCloseButton);
|
||||
|
||||
//---- redCrossCloseButton ----
|
||||
redCrossCloseButton.setText("red cross");
|
||||
redCrossCloseButton.putClientProperty("FlatLaf.styleClass", "small");
|
||||
redCrossCloseButton.putClientProperty(FlatClientProperties.STYLE_CLASS, "small");
|
||||
redCrossCloseButton.addActionListener(e -> closeButtonStyleChanged());
|
||||
closableTabsToolBar.add(redCrossCloseButton);
|
||||
}
|
||||
@@ -593,7 +594,7 @@ class TabsPanel
|
||||
|
||||
//---- tabAreaComponentsLabel ----
|
||||
tabAreaComponentsLabel.setText("Custom tab area components");
|
||||
tabAreaComponentsLabel.putClientProperty("FlatLaf.styleClass", "h3");
|
||||
tabAreaComponentsLabel.putClientProperty(FlatClientProperties.STYLE_CLASS, "h3");
|
||||
panel1.add(tabAreaComponentsLabel, "cell 0 7");
|
||||
|
||||
//======== tabAreaComponentsToolBar ========
|
||||
@@ -604,14 +605,14 @@ class TabsPanel
|
||||
//---- leadingComponentButton ----
|
||||
leadingComponentButton.setText("leading");
|
||||
leadingComponentButton.setSelected(true);
|
||||
leadingComponentButton.putClientProperty("FlatLaf.styleClass", "small");
|
||||
leadingComponentButton.putClientProperty(FlatClientProperties.STYLE_CLASS, "small");
|
||||
leadingComponentButton.addActionListener(e -> customComponentsChanged());
|
||||
tabAreaComponentsToolBar.add(leadingComponentButton);
|
||||
|
||||
//---- trailingComponentButton ----
|
||||
trailingComponentButton.setText("trailing");
|
||||
trailingComponentButton.setSelected(true);
|
||||
trailingComponentButton.putClientProperty("FlatLaf.styleClass", "small");
|
||||
trailingComponentButton.putClientProperty(FlatClientProperties.STYLE_CLASS, "small");
|
||||
trailingComponentButton.addActionListener(e -> customComponentsChanged());
|
||||
tabAreaComponentsToolBar.add(trailingComponentButton);
|
||||
}
|
||||
@@ -642,13 +643,13 @@ class TabsPanel
|
||||
|
||||
//---- tabIconPlacementLabel ----
|
||||
tabIconPlacementLabel.setText("Tab icon placement");
|
||||
tabIconPlacementLabel.putClientProperty("FlatLaf.styleClass", "h3");
|
||||
tabIconPlacementLabel.putClientProperty(FlatClientProperties.STYLE_CLASS, "h3");
|
||||
panel2.add(tabIconPlacementLabel, "cell 0 0");
|
||||
|
||||
//---- tabIconPlacementNodeLabel ----
|
||||
tabIconPlacementNodeLabel.setText("(top/bottom/leading/trailing)");
|
||||
tabIconPlacementNodeLabel.setEnabled(false);
|
||||
tabIconPlacementNodeLabel.putClientProperty("FlatLaf.styleClass", "small");
|
||||
tabIconPlacementNodeLabel.putClientProperty(FlatClientProperties.STYLE_CLASS, "small");
|
||||
panel2.add(tabIconPlacementNodeLabel, "cell 0 1");
|
||||
panel2.add(iconTopTabbedPane, "cell 0 2");
|
||||
panel2.add(iconBottomTabbedPane, "cell 0 3");
|
||||
@@ -657,13 +658,13 @@ class TabsPanel
|
||||
|
||||
//---- tabAreaAlignmentLabel ----
|
||||
tabAreaAlignmentLabel.setText("Tab area alignment");
|
||||
tabAreaAlignmentLabel.putClientProperty("FlatLaf.styleClass", "h3");
|
||||
tabAreaAlignmentLabel.putClientProperty(FlatClientProperties.STYLE_CLASS, "h3");
|
||||
panel2.add(tabAreaAlignmentLabel, "cell 0 6");
|
||||
|
||||
//---- tabAreaAlignmentNoteLabel ----
|
||||
tabAreaAlignmentNoteLabel.setText("(leading/center/trailing/fill)");
|
||||
tabAreaAlignmentNoteLabel.setEnabled(false);
|
||||
tabAreaAlignmentNoteLabel.putClientProperty("FlatLaf.styleClass", "small");
|
||||
tabAreaAlignmentNoteLabel.putClientProperty(FlatClientProperties.STYLE_CLASS, "small");
|
||||
panel2.add(tabAreaAlignmentNoteLabel, "cell 0 7");
|
||||
panel2.add(alignLeadingTabbedPane, "cell 0 8");
|
||||
panel2.add(alignCenterTabbedPane, "cell 0 9");
|
||||
@@ -692,13 +693,13 @@ class TabsPanel
|
||||
|
||||
//---- tabWidthModeLabel ----
|
||||
tabWidthModeLabel.setText("Tab width mode");
|
||||
tabWidthModeLabel.putClientProperty("FlatLaf.styleClass", "h3");
|
||||
tabWidthModeLabel.putClientProperty(FlatClientProperties.STYLE_CLASS, "h3");
|
||||
panel3.add(tabWidthModeLabel, "cell 0 0");
|
||||
|
||||
//---- tabWidthModeNoteLabel ----
|
||||
tabWidthModeNoteLabel.setText("(preferred/equal/compact)");
|
||||
tabWidthModeNoteLabel.setEnabled(false);
|
||||
tabWidthModeNoteLabel.putClientProperty("FlatLaf.styleClass", "small");
|
||||
tabWidthModeNoteLabel.putClientProperty(FlatClientProperties.STYLE_CLASS, "small");
|
||||
panel3.add(tabWidthModeNoteLabel, "cell 0 1");
|
||||
panel3.add(widthPreferredTabbedPane, "cell 0 2");
|
||||
panel3.add(widthEqualTabbedPane, "cell 0 3");
|
||||
@@ -706,14 +707,14 @@ class TabsPanel
|
||||
|
||||
//---- minMaxTabWidthLabel ----
|
||||
minMaxTabWidthLabel.setText("Minimum/maximum tab width");
|
||||
minMaxTabWidthLabel.putClientProperty("FlatLaf.styleClass", "h3");
|
||||
minMaxTabWidthLabel.putClientProperty(FlatClientProperties.STYLE_CLASS, "h3");
|
||||
panel3.add(minMaxTabWidthLabel, "cell 0 5");
|
||||
panel3.add(minimumTabWidthTabbedPane, "cell 0 6");
|
||||
panel3.add(maximumTabWidthTabbedPane, "cell 0 7");
|
||||
|
||||
//---- tabAlignmentLabel ----
|
||||
tabAlignmentLabel.setText("Tab title alignment");
|
||||
tabAlignmentLabel.putClientProperty("FlatLaf.styleClass", "h3");
|
||||
tabAlignmentLabel.putClientProperty(FlatClientProperties.STYLE_CLASS, "h3");
|
||||
panel3.add(tabAlignmentLabel, "cell 0 8");
|
||||
|
||||
//======== panel5 ========
|
||||
@@ -733,13 +734,13 @@ class TabsPanel
|
||||
//---- tabAlignmentNoteLabel ----
|
||||
tabAlignmentNoteLabel.setText("(leading/center/trailing)");
|
||||
tabAlignmentNoteLabel.setEnabled(false);
|
||||
tabAlignmentNoteLabel.putClientProperty("FlatLaf.styleClass", "small");
|
||||
tabAlignmentNoteLabel.putClientProperty(FlatClientProperties.STYLE_CLASS, "small");
|
||||
panel5.add(tabAlignmentNoteLabel, "cell 0 0");
|
||||
|
||||
//---- tabAlignmentNoteLabel2 ----
|
||||
tabAlignmentNoteLabel2.setText("(trailing)");
|
||||
tabAlignmentNoteLabel2.setEnabled(false);
|
||||
tabAlignmentNoteLabel2.putClientProperty("FlatLaf.styleClass", "small");
|
||||
tabAlignmentNoteLabel2.putClientProperty(FlatClientProperties.STYLE_CLASS, "small");
|
||||
panel5.add(tabAlignmentNoteLabel2, "cell 1 0,alignx right,growx 0");
|
||||
panel5.add(tabAlignLeadingTabbedPane, "cell 0 1");
|
||||
|
||||
@@ -787,19 +788,19 @@ class TabsPanel
|
||||
//---- scrollAsNeededSingleButton ----
|
||||
scrollAsNeededSingleButton.setText("asNeededSingle");
|
||||
scrollAsNeededSingleButton.setSelected(true);
|
||||
scrollAsNeededSingleButton.putClientProperty("FlatLaf.styleClass", "small");
|
||||
scrollAsNeededSingleButton.putClientProperty(FlatClientProperties.STYLE_CLASS, "small");
|
||||
scrollAsNeededSingleButton.addActionListener(e -> scrollButtonsPolicyChanged());
|
||||
scrollButtonsPolicyToolBar.add(scrollAsNeededSingleButton);
|
||||
|
||||
//---- scrollAsNeededButton ----
|
||||
scrollAsNeededButton.setText("asNeeded");
|
||||
scrollAsNeededButton.putClientProperty("FlatLaf.styleClass", "small");
|
||||
scrollAsNeededButton.putClientProperty(FlatClientProperties.STYLE_CLASS, "small");
|
||||
scrollAsNeededButton.addActionListener(e -> scrollButtonsPolicyChanged());
|
||||
scrollButtonsPolicyToolBar.add(scrollAsNeededButton);
|
||||
|
||||
//---- scrollNeverButton ----
|
||||
scrollNeverButton.setText("never");
|
||||
scrollNeverButton.putClientProperty("FlatLaf.styleClass", "small");
|
||||
scrollNeverButton.putClientProperty(FlatClientProperties.STYLE_CLASS, "small");
|
||||
scrollNeverButton.addActionListener(e -> scrollButtonsPolicyChanged());
|
||||
scrollButtonsPolicyToolBar.add(scrollNeverButton);
|
||||
}
|
||||
@@ -817,13 +818,13 @@ class TabsPanel
|
||||
//---- popupAsNeededButton ----
|
||||
popupAsNeededButton.setText("asNeeded");
|
||||
popupAsNeededButton.setSelected(true);
|
||||
popupAsNeededButton.putClientProperty("FlatLaf.styleClass", "small");
|
||||
popupAsNeededButton.putClientProperty(FlatClientProperties.STYLE_CLASS, "small");
|
||||
popupAsNeededButton.addActionListener(e -> tabsPopupPolicyChanged());
|
||||
tabsPopupPolicyToolBar.add(popupAsNeededButton);
|
||||
|
||||
//---- popupNeverButton ----
|
||||
popupNeverButton.setText("never");
|
||||
popupNeverButton.putClientProperty("FlatLaf.styleClass", "small");
|
||||
popupNeverButton.putClientProperty(FlatClientProperties.STYLE_CLASS, "small");
|
||||
popupNeverButton.addActionListener(e -> tabsPopupPolicyChanged());
|
||||
tabsPopupPolicyToolBar.add(popupNeverButton);
|
||||
}
|
||||
@@ -846,13 +847,13 @@ class TabsPanel
|
||||
//---- scrollBothButton ----
|
||||
scrollBothButton.setText("both");
|
||||
scrollBothButton.setSelected(true);
|
||||
scrollBothButton.putClientProperty("FlatLaf.styleClass", "small");
|
||||
scrollBothButton.putClientProperty(FlatClientProperties.STYLE_CLASS, "small");
|
||||
scrollBothButton.addActionListener(e -> scrollButtonsPlacementChanged());
|
||||
scrollButtonsPlacementToolBar.add(scrollBothButton);
|
||||
|
||||
//---- scrollTrailingButton ----
|
||||
scrollTrailingButton.setText("trailing");
|
||||
scrollTrailingButton.putClientProperty("FlatLaf.styleClass", "small");
|
||||
scrollTrailingButton.putClientProperty(FlatClientProperties.STYLE_CLASS, "small");
|
||||
scrollTrailingButton.addActionListener(e -> scrollButtonsPlacementChanged());
|
||||
scrollButtonsPlacementToolBar.add(scrollTrailingButton);
|
||||
}
|
||||
@@ -869,13 +870,13 @@ class TabsPanel
|
||||
//---- underlinedTabTypeButton ----
|
||||
underlinedTabTypeButton.setText("underlined");
|
||||
underlinedTabTypeButton.setSelected(true);
|
||||
underlinedTabTypeButton.putClientProperty("FlatLaf.styleClass", "small");
|
||||
underlinedTabTypeButton.putClientProperty(FlatClientProperties.STYLE_CLASS, "small");
|
||||
underlinedTabTypeButton.addActionListener(e -> tabTypeChanged());
|
||||
tabTypeToolBar.add(underlinedTabTypeButton);
|
||||
|
||||
//---- cardTabTypeButton ----
|
||||
cardTabTypeButton.setText("card");
|
||||
cardTabTypeButton.putClientProperty("FlatLaf.styleClass", "small");
|
||||
cardTabTypeButton.putClientProperty(FlatClientProperties.STYLE_CLASS, "small");
|
||||
cardTabTypeButton.addActionListener(e -> tabTypeChanged());
|
||||
tabTypeToolBar.add(cardTabTypeButton);
|
||||
}
|
||||
@@ -893,25 +894,25 @@ class TabsPanel
|
||||
//---- rotationNoneButton ----
|
||||
rotationNoneButton.setText("none");
|
||||
rotationNoneButton.setSelected(true);
|
||||
rotationNoneButton.putClientProperty("FlatLaf.styleClass", "small");
|
||||
rotationNoneButton.putClientProperty(FlatClientProperties.STYLE_CLASS, "small");
|
||||
rotationNoneButton.addActionListener(e -> tabRotationChanged());
|
||||
tabRotationToolBar.add(rotationNoneButton);
|
||||
|
||||
//---- rotationAutoButton ----
|
||||
rotationAutoButton.setText("auto");
|
||||
rotationAutoButton.putClientProperty("FlatLaf.styleClass", "small");
|
||||
rotationAutoButton.putClientProperty(FlatClientProperties.STYLE_CLASS, "small");
|
||||
rotationAutoButton.addActionListener(e -> tabRotationChanged());
|
||||
tabRotationToolBar.add(rotationAutoButton);
|
||||
|
||||
//---- rotationLeftButton ----
|
||||
rotationLeftButton.setText("left");
|
||||
rotationLeftButton.putClientProperty("FlatLaf.styleClass", "small");
|
||||
rotationLeftButton.putClientProperty(FlatClientProperties.STYLE_CLASS, "small");
|
||||
rotationLeftButton.addActionListener(e -> tabRotationChanged());
|
||||
tabRotationToolBar.add(rotationLeftButton);
|
||||
|
||||
//---- rotationRightButton ----
|
||||
rotationRightButton.setText("right");
|
||||
rotationRightButton.putClientProperty("FlatLaf.styleClass", "small");
|
||||
rotationRightButton.putClientProperty(FlatClientProperties.STYLE_CLASS, "small");
|
||||
rotationRightButton.addActionListener(e -> tabRotationChanged());
|
||||
tabRotationToolBar.add(rotationRightButton);
|
||||
}
|
||||
|
||||
@@ -25,24 +25,32 @@ class IJThemeInfo
|
||||
{
|
||||
final String name;
|
||||
final String resourceName;
|
||||
final boolean discontinued;
|
||||
final boolean dark;
|
||||
final String license;
|
||||
final String licenseFile;
|
||||
final String pluginUrl;
|
||||
final String sourceCodeUrl;
|
||||
final String sourceCodePath;
|
||||
final File themeFile;
|
||||
final String lafClassName;
|
||||
|
||||
IJThemeInfo( String name, String resourceName, boolean dark,
|
||||
IJThemeInfo( String name, boolean dark, String lafClassName ) {
|
||||
this( name, null, false, dark, null, null, null, null, null, null, lafClassName );
|
||||
}
|
||||
|
||||
IJThemeInfo( String name, String resourceName, boolean discontinued, boolean dark,
|
||||
String license, String licenseFile,
|
||||
String sourceCodeUrl, String sourceCodePath,
|
||||
String pluginUrl, String sourceCodeUrl, String sourceCodePath,
|
||||
File themeFile, String lafClassName )
|
||||
{
|
||||
this.name = name;
|
||||
this.resourceName = resourceName;
|
||||
this.discontinued = discontinued;
|
||||
this.dark = dark;
|
||||
this.license = license;
|
||||
this.licenseFile = licenseFile;
|
||||
this.pluginUrl = pluginUrl;
|
||||
this.sourceCodeUrl = sourceCodeUrl;
|
||||
this.sourceCodePath = sourceCodePath;
|
||||
this.themeFile = themeFile;
|
||||
|
||||
@@ -73,10 +73,12 @@ public class IJThemesClassGenerator
|
||||
name = name.substring( nameSep + 1 ).trim();
|
||||
|
||||
String themeName = name;
|
||||
if( "material-theme-ui-lite".equals( resourcePath ) )
|
||||
themeName += " (Material)";
|
||||
|
||||
StringBuilder buf = new StringBuilder();
|
||||
if( "material-theme-ui-lite".equals( resourcePath ) ) {
|
||||
themeName += " (Material)";
|
||||
buf.append( "MT" );
|
||||
}
|
||||
|
||||
for( String n : name.split( "[ \\-]" ) ) {
|
||||
if( n.length() == 0 || n.equals( "-" ) )
|
||||
continue;
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright 2025 FormDev Software GmbH
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.formdev.flatlaf.demo.intellijthemes;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import javax.swing.LookAndFeel;
|
||||
import javax.swing.UIDefaults;
|
||||
import javax.swing.UIManager;
|
||||
import com.formdev.flatlaf.FlatLaf;
|
||||
import com.formdev.flatlaf.IntelliJTheme;
|
||||
import com.formdev.flatlaf.util.LoggingFacade;
|
||||
|
||||
/**
|
||||
* @author Karl Tauber
|
||||
*/
|
||||
public class IJThemesDump
|
||||
{
|
||||
// same as UIDefaultsLoader.KEY_PROPERTIES
|
||||
private static final String KEY_PROPERTIES = "FlatLaf.internal.properties";
|
||||
|
||||
public static void enablePropertiesRecording() {
|
||||
System.setProperty( KEY_PROPERTIES, "true" );
|
||||
}
|
||||
|
||||
public static void install() {
|
||||
enablePropertiesRecording();
|
||||
|
||||
UIManager.addPropertyChangeListener( e -> {
|
||||
if( "lookAndFeel".equals( e.getPropertyName() ) ) {
|
||||
LookAndFeel lookAndFeel = UIManager.getLookAndFeel();
|
||||
if( lookAndFeel instanceof IntelliJTheme.ThemeLaf ) {
|
||||
IntelliJTheme theme = (lookAndFeel.getClass() == IntelliJTheme.ThemeLaf.class)
|
||||
? ((IntelliJTheme.ThemeLaf)lookAndFeel).getTheme()
|
||||
: null;
|
||||
String name = (theme != null) ? theme.name : lookAndFeel.getClass().getSimpleName();
|
||||
File dir = new File( "dumps/properties" );
|
||||
dumpProperties( dir, name, UIManager.getLookAndFeelDefaults() );
|
||||
}
|
||||
}
|
||||
} );
|
||||
}
|
||||
|
||||
public static void dumpProperties( File dir, String name, UIDefaults defaults ) {
|
||||
String content = dumpPropertiesToString( defaults );
|
||||
if( content == null )
|
||||
return;
|
||||
|
||||
// write to file
|
||||
File file = new File( dir, name + ".properties" );
|
||||
file.getParentFile().mkdirs();
|
||||
try( Writer fileWriter = new OutputStreamWriter(
|
||||
new FileOutputStream( file ), StandardCharsets.UTF_8 ) )
|
||||
{
|
||||
fileWriter.write( content );
|
||||
} catch( IOException ex ) {
|
||||
LoggingFacade.INSTANCE.logSevere( null, ex );
|
||||
}
|
||||
}
|
||||
|
||||
public static String dumpPropertiesToString( UIDefaults defaults ) {
|
||||
Properties properties = (Properties) defaults.get( KEY_PROPERTIES );
|
||||
if( properties == null )
|
||||
return null;
|
||||
|
||||
// dump to string
|
||||
StringWriter stringWriter = new StringWriter( 100000 );
|
||||
PrintWriter out = new PrintWriter( stringWriter );
|
||||
out.printf( "@baseTheme = %s%n", FlatLaf.isLafDark() ? "dark" : "light" );
|
||||
AtomicReference<String> lastPrefix = new AtomicReference<>();
|
||||
properties.entrySet().stream()
|
||||
.sorted( (e1, e2) -> ((String)e1.getKey()).compareTo( (String) e2.getKey() ) )
|
||||
.forEach( e -> {
|
||||
String key = (String) e.getKey();
|
||||
String value = (String) e.getValue();
|
||||
String prefix = keyPrefix( key );
|
||||
if( !prefix.equals( lastPrefix.get() ) ) {
|
||||
lastPrefix.set( prefix );
|
||||
out.printf( "%n%n#---- %s ----%n%n", prefix );
|
||||
}
|
||||
|
||||
out.printf( "%-50s = %s%n", key, value.replace( ";", "; \\\n\t" ) );
|
||||
} );
|
||||
|
||||
return stringWriter.toString().replace( "\r", "" );
|
||||
}
|
||||
|
||||
private static String keyPrefix( String key ) {
|
||||
int dotIndex = key.indexOf( '.' );
|
||||
return (dotIndex > 0)
|
||||
? key.substring( 0, dotIndex )
|
||||
: key.endsWith( "UI" )
|
||||
? key.substring( 0, key.length() - 2 )
|
||||
: "";
|
||||
}
|
||||
}
|
||||
@@ -56,13 +56,17 @@ class IJThemesManager
|
||||
String resourceName = e.getKey();
|
||||
Map<String, String> value = (Map<String, String>) e.getValue();
|
||||
String name = value.get( "name" );
|
||||
boolean discontinued = Boolean.parseBoolean( value.get( "discontinued" ) );
|
||||
boolean dark = Boolean.parseBoolean( value.get( "dark" ) );
|
||||
String lafClassName = value.get( "lafClassName" );
|
||||
String license = value.get( "license" );
|
||||
String licenseFile = value.get( "licenseFile" );
|
||||
String pluginUrl = value.get( "pluginUrl" );
|
||||
String sourceCodeUrl = value.get( "sourceCodeUrl" );
|
||||
String sourceCodePath = value.get( "sourceCodePath" );
|
||||
|
||||
bundledThemes.add( new IJThemeInfo( name, resourceName, dark, license, licenseFile, sourceCodeUrl, sourceCodePath, null, null ) );
|
||||
bundledThemes.add( new IJThemeInfo( name, resourceName, discontinued, dark,
|
||||
license, licenseFile, pluginUrl, sourceCodeUrl, sourceCodePath, null, lafClassName ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,7 +89,7 @@ class IJThemesManager
|
||||
String name = fname.endsWith( ".properties" )
|
||||
? StringUtils.removeTrailing( fname, ".properties" )
|
||||
: StringUtils.removeTrailing( fname, ".theme.json" );
|
||||
moreThemes.add( new IJThemeInfo( name, null, false, null, null, null, null, f, null ) );
|
||||
moreThemes.add( new IJThemeInfo( name, null, false, false, null, null, null, null, null, f, null ) );
|
||||
lastModifiedMap.put( f, f.lastModified() );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,8 +33,6 @@ import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
@@ -45,6 +43,7 @@ import javax.swing.*;
|
||||
import javax.swing.border.Border;
|
||||
import javax.swing.border.CompoundBorder;
|
||||
import javax.swing.event.*;
|
||||
import com.formdev.flatlaf.FlatClientProperties;
|
||||
import com.formdev.flatlaf.FlatDarculaLaf;
|
||||
import com.formdev.flatlaf.FlatDarkLaf;
|
||||
import com.formdev.flatlaf.FlatIntelliJLaf;
|
||||
@@ -58,7 +57,6 @@ import com.formdev.flatlaf.extras.FlatSVGIcon;
|
||||
import com.formdev.flatlaf.themes.*;
|
||||
import com.formdev.flatlaf.ui.FlatListUI;
|
||||
import com.formdev.flatlaf.util.LoggingFacade;
|
||||
import com.formdev.flatlaf.util.StringUtils;
|
||||
import net.miginfocom.swing.*;
|
||||
|
||||
/**
|
||||
@@ -81,14 +79,13 @@ public class IJThemesPanel
|
||||
};
|
||||
private Window window;
|
||||
|
||||
private File lastDirectory;
|
||||
private boolean isAdjustingThemesList;
|
||||
private long lastLafChangeTime = System.currentTimeMillis();
|
||||
|
||||
public IJThemesPanel() {
|
||||
initComponents();
|
||||
|
||||
saveButton.setEnabled( false );
|
||||
pluginButton.setEnabled( false );
|
||||
sourceCodeButton.setEnabled( false );
|
||||
|
||||
// create renderer
|
||||
@@ -143,7 +140,7 @@ public class IJThemesPanel
|
||||
private String buildToolTip( IJThemeInfo ti ) {
|
||||
if( ti.themeFile != null )
|
||||
return ti.themeFile.getPath();
|
||||
if( ti.resourceName == null )
|
||||
if( ti.license == null )
|
||||
return ti.name;
|
||||
|
||||
return "Name: " + ti.name
|
||||
@@ -178,18 +175,18 @@ public class IJThemesPanel
|
||||
// add core themes at beginning
|
||||
categories.put( themes.size(), "Core Themes" );
|
||||
if( showLight )
|
||||
themes.add( new IJThemeInfo( "FlatLaf Light", null, false, null, null, null, null, null, FlatLightLaf.class.getName() ) );
|
||||
themes.add( new IJThemeInfo( "FlatLaf Light", false, FlatLightLaf.class.getName() ) );
|
||||
if( showDark )
|
||||
themes.add( new IJThemeInfo( "FlatLaf Dark", null, true, null, null, null, null, null, FlatDarkLaf.class.getName() ) );
|
||||
themes.add( new IJThemeInfo( "FlatLaf Dark", true, FlatDarkLaf.class.getName() ) );
|
||||
if( showLight )
|
||||
themes.add( new IJThemeInfo( "FlatLaf IntelliJ", null, false, null, null, null, null, null, FlatIntelliJLaf.class.getName() ) );
|
||||
themes.add( new IJThemeInfo( "FlatLaf IntelliJ", false, FlatIntelliJLaf.class.getName() ) );
|
||||
if( showDark )
|
||||
themes.add( new IJThemeInfo( "FlatLaf Darcula", null, true, null, null, null, null, null, FlatDarculaLaf.class.getName() ) );
|
||||
themes.add( new IJThemeInfo( "FlatLaf Darcula", true, FlatDarculaLaf.class.getName() ) );
|
||||
|
||||
if( showLight )
|
||||
themes.add( new IJThemeInfo( "FlatLaf macOS Light", null, false, null, null, null, null, null, FlatMacLightLaf.class.getName() ) );
|
||||
themes.add( new IJThemeInfo( "FlatLaf macOS Light", false, FlatMacLightLaf.class.getName() ) );
|
||||
if( showDark )
|
||||
themes.add( new IJThemeInfo( "FlatLaf macOS Dark", null, true, null, null, null, null, null, FlatMacDarkLaf.class.getName() ) );
|
||||
themes.add( new IJThemeInfo( "FlatLaf macOS Dark", true, FlatMacDarkLaf.class.getName() ) );
|
||||
|
||||
// add themes from directory
|
||||
categories.put( themes.size(), "Current Directory" );
|
||||
@@ -237,7 +234,6 @@ public class IJThemesPanel
|
||||
for( int i = 0; i < themes.size(); i++ ) {
|
||||
IJThemeInfo theme = themes.get( i );
|
||||
if( oldSel.name.equals( theme.name ) &&
|
||||
Objects.equals( oldSel.resourceName, theme.resourceName ) &&
|
||||
Objects.equals( oldSel.themeFile, theme.themeFile ) &&
|
||||
Objects.equals( oldSel.lafClassName, theme.lafClassName ) )
|
||||
{
|
||||
@@ -273,28 +269,28 @@ public class IJThemesPanel
|
||||
|
||||
private void themesListValueChanged( ListSelectionEvent e ) {
|
||||
IJThemeInfo themeInfo = themesList.getSelectedValue();
|
||||
boolean bundledTheme = (themeInfo != null && themeInfo.resourceName != null);
|
||||
saveButton.setEnabled( bundledTheme );
|
||||
sourceCodeButton.setEnabled( bundledTheme );
|
||||
pluginButton.setEnabled( themeInfo != null && themeInfo.pluginUrl != null );
|
||||
sourceCodeButton.setEnabled( themeInfo != null && themeInfo.sourceCodePath != null );
|
||||
|
||||
if( e.getValueIsAdjusting() || isAdjustingThemesList )
|
||||
return;
|
||||
|
||||
EventQueue.invokeLater( () -> {
|
||||
setTheme( themeInfo );
|
||||
setTheme( themeInfo, false );
|
||||
} );
|
||||
}
|
||||
|
||||
private void setTheme( IJThemeInfo themeInfo ) {
|
||||
private void setTheme( IJThemeInfo themeInfo, boolean reload ) {
|
||||
if( themeInfo == null )
|
||||
return;
|
||||
|
||||
// change look and feel
|
||||
if( themeInfo.lafClassName != null ) {
|
||||
if( themeInfo.lafClassName.equals( UIManager.getLookAndFeel().getClass().getName() ) )
|
||||
if( !reload && themeInfo.lafClassName.equals( UIManager.getLookAndFeel().getClass().getName() ) )
|
||||
return;
|
||||
|
||||
FlatAnimatedLafChange.showSnapshot();
|
||||
if( !reload )
|
||||
FlatAnimatedLafChange.showSnapshot();
|
||||
|
||||
try {
|
||||
UIManager.setLookAndFeel( themeInfo.lafClassName );
|
||||
@@ -303,81 +299,59 @@ public class IJThemesPanel
|
||||
showInformationDialog( "Failed to create '" + themeInfo.lafClassName + "'.", ex );
|
||||
}
|
||||
} else if( themeInfo.themeFile != null ) {
|
||||
FlatAnimatedLafChange.showSnapshot();
|
||||
if( !reload )
|
||||
FlatAnimatedLafChange.showSnapshot();
|
||||
|
||||
try {
|
||||
if( themeInfo.themeFile.getName().endsWith( ".properties" ) ) {
|
||||
if( themeInfo.themeFile.getName().endsWith( ".properties" ) )
|
||||
FlatLaf.setup( new FlatPropertiesLaf( themeInfo.name, themeInfo.themeFile ) );
|
||||
} else
|
||||
else
|
||||
FlatLaf.setup( IntelliJTheme.createLaf( new FileInputStream( themeInfo.themeFile ) ) );
|
||||
|
||||
DemoPrefs.getState().put( DemoPrefs.KEY_LAF_THEME, DemoPrefs.FILE_PREFIX + themeInfo.themeFile );
|
||||
DemoPrefs.getState().put( DemoPrefs.KEY_LAF_THEME_FILE, themeInfo.themeFile.getAbsolutePath() );
|
||||
} catch( Exception ex ) {
|
||||
LoggingFacade.INSTANCE.logSevere( null, ex );
|
||||
showInformationDialog( "Failed to load '" + themeInfo.themeFile + "'.", ex );
|
||||
}
|
||||
} else {
|
||||
FlatAnimatedLafChange.showSnapshot();
|
||||
|
||||
IntelliJTheme.setup( getClass().getResourceAsStream( THEMES_PACKAGE + themeInfo.resourceName ) );
|
||||
DemoPrefs.getState().put( DemoPrefs.KEY_LAF_THEME, DemoPrefs.RESOURCE_PREFIX + themeInfo.resourceName );
|
||||
JOptionPane.showMessageDialog( SwingUtilities.windowForComponent( this ),
|
||||
"Missing lafClassName for '" + themeInfo.name + "'",
|
||||
"FlatLaf", JOptionPane.INFORMATION_MESSAGE );
|
||||
return;
|
||||
}
|
||||
|
||||
// update all components
|
||||
FlatLaf.updateUI();
|
||||
FlatAnimatedLafChange.hideSnapshotWithAnimation();
|
||||
|
||||
if( !reload )
|
||||
FlatAnimatedLafChange.hideSnapshotWithAnimation();
|
||||
}
|
||||
|
||||
private void saveTheme() {
|
||||
private void browsePlugin() {
|
||||
IJThemeInfo themeInfo = themesList.getSelectedValue();
|
||||
if( themeInfo == null || themeInfo.resourceName == null )
|
||||
if( themeInfo == null || themeInfo.pluginUrl == null )
|
||||
return;
|
||||
|
||||
JFileChooser fileChooser = new JFileChooser();
|
||||
fileChooser.setSelectedFile( new File( lastDirectory, themeInfo.resourceName ) );
|
||||
if( fileChooser.showSaveDialog( SwingUtilities.windowForComponent( this ) ) != JFileChooser.APPROVE_OPTION )
|
||||
return;
|
||||
|
||||
File file = fileChooser.getSelectedFile();
|
||||
lastDirectory = file.getParentFile();
|
||||
|
||||
// save theme
|
||||
try {
|
||||
Files.copy( getClass().getResourceAsStream( THEMES_PACKAGE + themeInfo.resourceName ),
|
||||
file.toPath(), StandardCopyOption.REPLACE_EXISTING );
|
||||
} catch( IOException ex ) {
|
||||
showInformationDialog( "Failed to save theme to '" + file + "'.", ex );
|
||||
return;
|
||||
}
|
||||
|
||||
// save license
|
||||
if( themeInfo.licenseFile != null ) {
|
||||
try {
|
||||
File licenseFile = new File( file.getParentFile(),
|
||||
StringUtils.removeTrailing( file.getName(), ".theme.json" ) +
|
||||
themeInfo.licenseFile.substring( themeInfo.licenseFile.indexOf( '.' ) ) );
|
||||
Files.copy( getClass().getResourceAsStream( THEMES_PACKAGE + themeInfo.licenseFile ),
|
||||
licenseFile.toPath(), StandardCopyOption.REPLACE_EXISTING );
|
||||
} catch( IOException ex ) {
|
||||
showInformationDialog( "Failed to save theme license to '" + file + "'.", ex );
|
||||
return;
|
||||
}
|
||||
}
|
||||
browse( themeInfo.pluginUrl );
|
||||
}
|
||||
|
||||
private void browseSourceCode() {
|
||||
IJThemeInfo themeInfo = themesList.getSelectedValue();
|
||||
if( themeInfo == null || themeInfo.resourceName == null )
|
||||
if( themeInfo == null || themeInfo.sourceCodeUrl == null )
|
||||
return;
|
||||
|
||||
String themeUrl = themeInfo.sourceCodeUrl;
|
||||
if( themeInfo.sourceCodePath != null )
|
||||
themeUrl += '/' + themeInfo.sourceCodePath;
|
||||
themeUrl = themeUrl.replace( " ", "%20" );
|
||||
browse( themeUrl );
|
||||
}
|
||||
|
||||
private void browse( String url ) {
|
||||
url = url.replace( " ", "%20" );
|
||||
try {
|
||||
Desktop.getDesktop().browse( new URI( themeUrl ) );
|
||||
Desktop.getDesktop().browse( new URI( url ) );
|
||||
} catch( IOException | URISyntaxException ex ) {
|
||||
showInformationDialog( "Failed to browse '" + themeUrl + "'.", ex );
|
||||
showInformationDialog( "Failed to browse '" + url + "'.", ex );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -413,8 +387,11 @@ public class IJThemesPanel
|
||||
|
||||
private void lafChanged( PropertyChangeEvent e ) {
|
||||
if( "lookAndFeel".equals( e.getPropertyName() ) ) {
|
||||
selectedCurrentLookAndFeel();
|
||||
lastLafChangeTime = System.currentTimeMillis();
|
||||
// use invokeLater() because KEY_LAF_THEME_FILE is updated after this event
|
||||
EventQueue.invokeLater( () -> {
|
||||
selectedCurrentLookAndFeel();
|
||||
lastLafChangeTime = System.currentTimeMillis();
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -429,19 +406,19 @@ public class IJThemesPanel
|
||||
if( laf instanceof FlatLaf ) {
|
||||
List<Class<?>> lafClasses = new ArrayList<>();
|
||||
|
||||
// same as in UIDefaultsLoader.getLafClassesForDefaultsLoading()
|
||||
for( Class<?> lafClass = laf.getClass();
|
||||
FlatLaf.class.isAssignableFrom( lafClass );
|
||||
lafClass = lafClass.getSuperclass() )
|
||||
{
|
||||
lafClasses.add( 0, lafClass );
|
||||
}
|
||||
|
||||
// same as in IntelliJTheme.ThemeLaf.getLafClassesForDefaultsLoading()
|
||||
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 );
|
||||
}
|
||||
lafClasses.add( 1, dark ? FlatDarkLaf.class : FlatLightLaf.class );
|
||||
lafClasses.add( 2, dark ? FlatDarculaLaf.class : FlatIntelliJLaf.class );
|
||||
}
|
||||
|
||||
boolean reload = false;
|
||||
@@ -462,29 +439,25 @@ public class IJThemesPanel
|
||||
}
|
||||
|
||||
if( reload )
|
||||
setTheme( themesList.getSelectedValue() );
|
||||
setTheme( themesList.getSelectedValue(), true );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void selectedCurrentLookAndFeel() {
|
||||
LookAndFeel lookAndFeel = UIManager.getLookAndFeel();
|
||||
String theme = UIManager.getLookAndFeelDefaults().getString( DemoPrefs.THEME_UI_KEY );
|
||||
|
||||
if( theme == null && (lookAndFeel instanceof IntelliJTheme.ThemeLaf || lookAndFeel instanceof FlatPropertiesLaf) )
|
||||
return;
|
||||
|
||||
Predicate<IJThemeInfo> test;
|
||||
if( theme != null && theme.startsWith( DemoPrefs.RESOURCE_PREFIX ) ) {
|
||||
String resourceName = theme.substring( DemoPrefs.RESOURCE_PREFIX.length() );
|
||||
test = ti -> Objects.equals( ti.resourceName, resourceName );
|
||||
} else if( theme != null && theme.startsWith( DemoPrefs.FILE_PREFIX ) ) {
|
||||
File themeFile = new File( theme.substring( DemoPrefs.FILE_PREFIX.length() ) );
|
||||
String lafClassName = UIManager.getLookAndFeel().getClass().getName();
|
||||
if( FlatPropertiesLaf.class.getName().equals( lafClassName ) ||
|
||||
IntelliJTheme.ThemeLaf.class.getName().equals( lafClassName ) )
|
||||
{
|
||||
String themeFileName = DemoPrefs.getState().get( DemoPrefs.KEY_LAF_THEME_FILE, "" );
|
||||
if( themeFileName == null )
|
||||
return;
|
||||
|
||||
File themeFile = new File( themeFileName );
|
||||
test = ti -> Objects.equals( ti.themeFile, themeFile );
|
||||
} else {
|
||||
String lafClassName = lookAndFeel.getClass().getName();
|
||||
} else
|
||||
test = ti -> Objects.equals( ti.lafClassName, lafClassName );
|
||||
}
|
||||
|
||||
int newSel = -1;
|
||||
for( int i = 0; i < themes.size(); i++ ) {
|
||||
@@ -511,7 +484,7 @@ public class IJThemesPanel
|
||||
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
|
||||
JLabel themesLabel = new JLabel();
|
||||
toolBar = new JToolBar();
|
||||
saveButton = new JButton();
|
||||
pluginButton = new JButton();
|
||||
sourceCodeButton = new JButton();
|
||||
filterComboBox = new JComboBox<>();
|
||||
themesScrollPane = new JScrollPane();
|
||||
@@ -534,11 +507,11 @@ public class IJThemesPanel
|
||||
{
|
||||
toolBar.setFloatable(false);
|
||||
|
||||
//---- saveButton ----
|
||||
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());
|
||||
toolBar.add(saveButton);
|
||||
//---- pluginButton ----
|
||||
pluginButton.setToolTipText("Opens the IntelliJ plugin page of selected IntelliJ theme in the browser.");
|
||||
pluginButton.setIcon(new FlatSVGIcon("com/formdev/flatlaf/demo/icons/plugin.svg"));
|
||||
pluginButton.addActionListener(e -> browsePlugin());
|
||||
toolBar.add(pluginButton);
|
||||
|
||||
//---- sourceCodeButton ----
|
||||
sourceCodeButton.setToolTipText("Opens the source code repository of selected IntelliJ theme in the browser.");
|
||||
@@ -554,7 +527,7 @@ public class IJThemesPanel
|
||||
"light",
|
||||
"dark"
|
||||
}));
|
||||
filterComboBox.putClientProperty("JComponent.minimumWidth", 0);
|
||||
filterComboBox.putClientProperty(FlatClientProperties.MINIMUM_WIDTH, 0);
|
||||
filterComboBox.setFocusable(false);
|
||||
filterComboBox.addActionListener(e -> filterChanged());
|
||||
add(filterComboBox, "cell 0 0,alignx right,growx 0");
|
||||
@@ -573,7 +546,7 @@ public class IJThemesPanel
|
||||
|
||||
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
|
||||
private JToolBar toolBar;
|
||||
private JButton saveButton;
|
||||
private JButton pluginButton;
|
||||
private JButton sourceCodeButton;
|
||||
private JComboBox<String> filterComboBox;
|
||||
private JScrollPane themesScrollPane;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
JFDML JFormDesigner: "8.1.0.0.283" Java: "19.0.2" encoding: "UTF-8"
|
||||
JFDML JFormDesigner: "8.3" encoding: "UTF-8"
|
||||
|
||||
new FormModel {
|
||||
contentType: "form/swing"
|
||||
@@ -22,10 +22,10 @@ new FormModel {
|
||||
name: "toolBar"
|
||||
"floatable": false
|
||||
add( new FormComponent( "javax.swing.JButton" ) {
|
||||
name: "saveButton"
|
||||
"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 ) )
|
||||
name: "pluginButton"
|
||||
"toolTipText": "Opens the IntelliJ plugin page of selected IntelliJ theme in the browser."
|
||||
"icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/demo/icons/plugin.svg" )
|
||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "browsePlugin", false ) )
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JButton" ) {
|
||||
name: "sourceCodeButton"
|
||||
|
||||
@@ -38,6 +38,9 @@ public class IJThemesUpdater
|
||||
themesManager.loadBundledThemes();
|
||||
|
||||
for( IJThemeInfo ti : themesManager.bundledThemes ) {
|
||||
if( ti.discontinued )
|
||||
continue;
|
||||
|
||||
if( ti.sourceCodeUrl == null || ti.sourceCodePath == null ) {
|
||||
System.out.println( " " + ti.name + " NOT downloaded. Needs manual update from release on JetBrains Plugin portal." );
|
||||
continue;
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
<!-- Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
|
||||
<g fill="none" fill-rule="evenodd">
|
||||
<polygon fill="#6E6E6E" points="9 7 12 7 8 11 4 7 7 7 7 2 9 2" transform="matrix(-1 0 0 1 16 0)"/>
|
||||
<rect width="12" height="2" x="2" y="12" fill="#6E6E6E"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 448 B |
@@ -0,0 +1,4 @@
|
||||
<!-- Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -->
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M11 4H7C5.34315 4 4 5.34315 4 7V9C4 10.6569 5.34315 12 7 12H11V11V10V6V5V4ZM12 5V4C12 3.44772 11.5523 3 11 3H7C5.13616 3 3.57006 4.27477 3.12602 6H1C0.447715 6 0 6.44772 0 7V9C0 9.55228 0.447715 10 1 10H3.12602C3.57006 11.7252 5.13616 13 7 13H11C11.5523 13 12 12.5523 12 12V11H15.5C15.7761 11 16 10.7761 16 10.5C16 10.2239 15.7761 10 15.5 10H12V6H15.5C15.7761 6 16 5.77614 16 5.5C16 5.22386 15.7761 5 15.5 5H12ZM3 7V9H1V7L3 7Z" fill="#6C707E"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 724 B |
@@ -0,0 +1,4 @@
|
||||
<!-- Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -->
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M11 4H7C5.34315 4 4 5.34315 4 7V9C4 10.6569 5.34315 12 7 12H11V11V10V6V5V4ZM12 5V4C12 3.44772 11.5523 3 11 3H7C5.13616 3 3.57006 4.27477 3.12602 6H1C0.447715 6 0 6.44772 0 7V9C0 9.55228 0.447715 10 1 10H3.12602C3.57006 11.7252 5.13616 13 7 13H11C11.5523 13 12 12.5523 12 12V11H15.5C15.7761 11 16 10.7761 16 10.5C16 10.2239 15.7761 10 15.5 10H12V6H15.5C15.7761 6 16 5.77614 16 5.5C16 5.22386 15.7761 5 15.5 5H12ZM3 7V9H1V7L3 7Z" fill="#CED0D6"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 724 B |
@@ -1,186 +1,213 @@
|
||||
{
|
||||
"arc-theme.theme.json": {
|
||||
"name": "Arc",
|
||||
"lafClassName": "com.formdev.flatlaf.intellijthemes.FlatArcIJTheme",
|
||||
"license": "MIT",
|
||||
"licenseFile": "arc-themes.LICENSE.txt",
|
||||
"pluginUrl": "https://plugins.jetbrains.com/plugin/12451-arc-theme",
|
||||
"sourceCodeUrl": "https://gitlab.com/zlamalp/arc-theme-idea",
|
||||
"sourceCodePath": "blob/master/arc-theme-idea-light/resources/arc-theme.theme.json"
|
||||
},
|
||||
"arc-theme-orange.theme.json": {
|
||||
"name": "Arc - Orange",
|
||||
"lafClassName": "com.formdev.flatlaf.intellijthemes.FlatArcOrangeIJTheme",
|
||||
"license": "MIT",
|
||||
"licenseFile": "arc-themes.LICENSE.txt",
|
||||
"pluginUrl": "https://plugins.jetbrains.com/plugin/12451-arc-theme",
|
||||
"sourceCodeUrl": "https://gitlab.com/zlamalp/arc-theme-idea",
|
||||
"sourceCodePath": "blob/master/arc-theme-idea-light/resources/arc-theme-orange.theme.json"
|
||||
},
|
||||
"arc_theme_dark.theme.json": {
|
||||
"name": "Arc Dark",
|
||||
"dark": true,
|
||||
"lafClassName": "com.formdev.flatlaf.intellijthemes.FlatArcDarkIJTheme",
|
||||
"license": "MIT",
|
||||
"licenseFile": "arc-themes.LICENSE.txt",
|
||||
"pluginUrl": "https://plugins.jetbrains.com/plugin/15175-arc-theme-dark",
|
||||
"sourceCodeUrl": "https://gitlab.com/zlamalp/arc-theme-idea",
|
||||
"sourceCodePath": "blob/master/arc-theme-idea-dark/resources/arc_theme_dark.theme.json"
|
||||
},
|
||||
"arc_theme_dark_orange.theme.json": {
|
||||
"name": "Arc Dark - Orange",
|
||||
"dark": true,
|
||||
"lafClassName": "com.formdev.flatlaf.intellijthemes.FlatArcDarkOrangeIJTheme",
|
||||
"license": "MIT",
|
||||
"licenseFile": "arc-themes.LICENSE.txt",
|
||||
"pluginUrl": "https://plugins.jetbrains.com/plugin/15175-arc-theme-dark",
|
||||
"sourceCodeUrl": "https://gitlab.com/zlamalp/arc-theme-idea",
|
||||
"sourceCodePath": "blob/master/arc-theme-idea-dark/resources/arc_theme_dark_orange.theme.json"
|
||||
},
|
||||
"Carbon.theme.json": {
|
||||
"name": "Carbon",
|
||||
"dark": true,
|
||||
"lafClassName": "com.formdev.flatlaf.intellijthemes.FlatCarbonIJTheme",
|
||||
"license": "Apache License 2.0",
|
||||
"licenseFile": "arc-themes.LICENSE.txt",
|
||||
"pluginUrl": "https://plugins.jetbrains.com/plugin/12280-carbon",
|
||||
"sourceCodeUrl": "https://github.com/luisfer0793/theme-carbon",
|
||||
"sourceCodePath": "blob/master/resources/matte_carbon_basics.theme.json"
|
||||
},
|
||||
"Cobalt_2.theme.json": {
|
||||
"name": "Cobalt 2",
|
||||
"dark": true,
|
||||
"lafClassName": "com.formdev.flatlaf.intellijthemes.FlatCobalt2IJTheme",
|
||||
"license": "MIT",
|
||||
"licenseFile": "Cobalt_2.LICENSE.txt",
|
||||
"pluginUrl": "https://plugins.jetbrains.com/plugin/10745-cobalt-2",
|
||||
"sourceCodeUrl": "https://github.com/ngehlert/cobalt2",
|
||||
"sourceCodePath": "blob/master/Cobalt2-UI-Theme/resources/Cobalt_2.theme.json"
|
||||
},
|
||||
"Cyan.theme.json": {
|
||||
"name": "Cyan light",
|
||||
"license": "MIT",
|
||||
"lafClassName": "com.formdev.flatlaf.intellijthemes.FlatCyanLightIJTheme",
|
||||
"licenseFile": "Cyan.LICENSE.txt",
|
||||
"pluginUrl": "https://plugins.jetbrains.com/plugin/12102-cyan-light-theme",
|
||||
"sourceCodeUrl": "https://github.com/OlyaB/CyanTheme",
|
||||
"sourceCodePath": "blob/master/src/Cyan.theme.json"
|
||||
},
|
||||
"DarkFlatTheme.theme.json": {
|
||||
"name": "Dark Flat",
|
||||
"dark": true,
|
||||
"lafClassName": "com.formdev.flatlaf.intellijthemes.FlatDarkFlatIJTheme",
|
||||
"license": "MIT",
|
||||
"licenseFile": "DarkFlatTheme.LICENSE.txt",
|
||||
"pluginUrl": "https://plugins.jetbrains.com/plugin/12165-dark-flat-theme",
|
||||
"sourceCodeUrl": "https://github.com/nerzhulart/DarkFlatTheme",
|
||||
"sourceCodePath": "blob/master/src/DarkFlatTheme.theme.json"
|
||||
},
|
||||
"DarkPurple.theme.json": {
|
||||
"name": "Dark purple",
|
||||
"dark": true,
|
||||
"lafClassName": "com.formdev.flatlaf.intellijthemes.FlatDarkPurpleIJTheme",
|
||||
"license": "MIT",
|
||||
"licenseFile": "DarkPurple.LICENSE.txt",
|
||||
"pluginUrl": "https://plugins.jetbrains.com/plugin/12100-dark-purple-theme",
|
||||
"sourceCodeUrl": "https://github.com/OlyaB/DarkPurpleTheme",
|
||||
"sourceCodePath": "blob/master/src/DarkPurple.theme.json"
|
||||
},
|
||||
"Dracula.theme.json": {
|
||||
"name": "Dracula",
|
||||
"dark": true,
|
||||
"lafClassName": "com.formdev.flatlaf.intellijthemes.FlatDraculaIJTheme",
|
||||
"license": "MIT",
|
||||
"licenseFile": "Dracula.LICENSE.txt",
|
||||
"pluginUrl": "https://plugins.jetbrains.com/plugin/12275-dracula-theme",
|
||||
"sourceCodeUrl": "https://github.com/dracula/jetbrains",
|
||||
"sourceCodePath": "blob/master/src/main/resources/themes/Dracula.theme.json"
|
||||
},
|
||||
"Gradianto_dark_fuchsia.theme.json": {
|
||||
"name": "Gradianto Dark Fuchsia",
|
||||
"dark": true,
|
||||
"lafClassName": "com.formdev.flatlaf.intellijthemes.FlatGradiantoDarkFuchsiaIJTheme",
|
||||
"license": "MIT",
|
||||
"licenseFile": "Gradianto.LICENSE.txt",
|
||||
"pluginUrl": "https://plugins.jetbrains.com/plugin/12334-gradianto",
|
||||
"sourceCodeUrl": "https://github.com/thvardhan/Gradianto",
|
||||
"sourceCodePath": "blob/master/src/main/resources/Gradianto_dark_fuchsia.theme.json"
|
||||
},
|
||||
"Gradianto_deep_ocean.theme.json": {
|
||||
"name": "Gradianto Deep Ocean",
|
||||
"dark": true,
|
||||
"lafClassName": "com.formdev.flatlaf.intellijthemes.FlatGradiantoDeepOceanIJTheme",
|
||||
"license": "MIT",
|
||||
"licenseFile": "Gradianto.LICENSE.txt",
|
||||
"pluginUrl": "https://plugins.jetbrains.com/plugin/12334-gradianto",
|
||||
"sourceCodeUrl": "https://github.com/thvardhan/Gradianto",
|
||||
"sourceCodePath": "blob/master/src/main/resources/Gradianto_deep_ocean.theme.json"
|
||||
},
|
||||
"Gradianto_midnight_blue.theme.json": {
|
||||
"name": "Gradianto Midnight Blue",
|
||||
"dark": true,
|
||||
"lafClassName": "com.formdev.flatlaf.intellijthemes.FlatGradiantoMidnightBlueIJTheme",
|
||||
"license": "MIT",
|
||||
"licenseFile": "Gradianto.LICENSE.txt",
|
||||
"pluginUrl": "https://plugins.jetbrains.com/plugin/12334-gradianto",
|
||||
"sourceCodeUrl": "https://github.com/thvardhan/Gradianto",
|
||||
"sourceCodePath": "blob/master/src/main/resources/Gradianto_midnight_blue.theme.json"
|
||||
},
|
||||
"Gradianto_Nature_Green.theme.json": {
|
||||
"name": "Gradianto Nature Green",
|
||||
"dark": true,
|
||||
"lafClassName": "com.formdev.flatlaf.intellijthemes.FlatGradiantoNatureGreenIJTheme",
|
||||
"license": "MIT",
|
||||
"licenseFile": "Gradianto.LICENSE.txt",
|
||||
"pluginUrl": "https://plugins.jetbrains.com/plugin/12334-gradianto",
|
||||
"sourceCodeUrl": "https://github.com/thvardhan/Gradianto",
|
||||
"sourceCodePath": "blob/master/src/main/resources/Gradianto_Nature_Green.theme.json"
|
||||
},
|
||||
"Gray.theme.json": {
|
||||
"name": "Gray",
|
||||
"license": "MIT",
|
||||
"lafClassName": "com.formdev.flatlaf.intellijthemes.FlatGrayIJTheme",
|
||||
"licenseFile": "Gray.LICENSE.txt",
|
||||
"pluginUrl": "https://plugins.jetbrains.com/plugin/12103-gray-theme",
|
||||
"sourceCodeUrl": "https://github.com/OlyaB/GreyTheme",
|
||||
"sourceCodePath": "blob/master/src/Gray.theme.json"
|
||||
},
|
||||
"gruvbox_dark_hard.theme.json": {
|
||||
"name": "Gruvbox Dark Hard",
|
||||
"dark": true,
|
||||
"lafClassName": "com.formdev.flatlaf.intellijthemes.FlatGruvboxDarkHardIJTheme",
|
||||
"license": "MIT",
|
||||
"licenseFile": "gruvbox_theme.LICENSE.txt",
|
||||
"pluginUrl": "https://plugins.jetbrains.com/plugin/12310-gruvbox-theme",
|
||||
"sourceCodeUrl": "https://github.com/Vincent-P/gruvbox-intellij-theme",
|
||||
"sourceCodePath": "blob/master/src/main/resources/gruvbox_dark_hard.theme.json"
|
||||
},
|
||||
"gruvbox_dark_medium.theme.json": {
|
||||
"name": "Gruvbox Dark Medium",
|
||||
"dark": true,
|
||||
"license": "MIT",
|
||||
"licenseFile": "gruvbox_theme.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/Vincent-P/gruvbox-intellij-theme",
|
||||
"sourceCodePath": "blob/master/src/main/resources/gruvbox_dark_medium.theme.json"
|
||||
},
|
||||
"gruvbox_dark_soft.theme.json": {
|
||||
"name": "Gruvbox Dark Soft",
|
||||
"dark": true,
|
||||
"license": "MIT",
|
||||
"licenseFile": "gruvbox_theme.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/Vincent-P/gruvbox-intellij-theme",
|
||||
"sourceCodePath": "blob/master/src/main/resources/gruvbox_dark_soft.theme.json"
|
||||
},
|
||||
"HiberbeeDark.theme.json": {
|
||||
"name": "Hiberbee Dark",
|
||||
"dark": true,
|
||||
"lafClassName": "com.formdev.flatlaf.intellijthemes.FlatHiberbeeDarkIJTheme",
|
||||
"license": "MIT",
|
||||
"licenseFile": "Hiberbee.LICENSE.txt",
|
||||
"pluginUrl": "https://plugins.jetbrains.com/plugin/12118-hiberbee-theme",
|
||||
"sourceCodeUrl": "https://github.com/Hiberbee/themes",
|
||||
"sourceCodePath": "blob/latest/src/intellij/src/main/resources/themes/HiberbeeDark.theme.json"
|
||||
},
|
||||
"HighContrast.theme.json": {
|
||||
"name": "High contrast",
|
||||
"name": "High Contrast",
|
||||
"dark": true,
|
||||
"license": "MIT",
|
||||
"lafClassName": "com.formdev.flatlaf.intellijthemes.FlatHighContrastIJTheme",
|
||||
"license": "Apache License 2.0",
|
||||
"licenseFile": "HighContrast.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/OlyaB/HighContrastTheme",
|
||||
"sourceCodePath": "blob/master/src/HighContrast.theme.json"
|
||||
"sourceCodeUrl": "https://github.com/JetBrains/intellij-community",
|
||||
"sourceCodePath": "blob/master/platform/platform-resources/src/themes/HighContrast.theme.json"
|
||||
},
|
||||
"LightFlatTheme.theme.json": {
|
||||
"name": "Light Flat",
|
||||
"license": "MIT",
|
||||
"lafClassName": "com.formdev.flatlaf.intellijthemes.FlatLightFlatIJTheme",
|
||||
"licenseFile": "LightFlatTheme.LICENSE.txt",
|
||||
"pluginUrl": "https://plugins.jetbrains.com/plugin/12169-light-flat-theme",
|
||||
"sourceCodeUrl": "https://github.com/nerzhulart/LightFlatTheme",
|
||||
"sourceCodePath": "blob/master/src/LightFlatTheme.theme.json"
|
||||
},
|
||||
"MaterialTheme.theme.json": {
|
||||
"name": "Material Design Dark",
|
||||
"dark": true,
|
||||
"lafClassName": "com.formdev.flatlaf.intellijthemes.FlatMaterialDesignDarkIJTheme",
|
||||
"license": "MIT",
|
||||
"licenseFile": "MaterialTheme.LICENSE.txt",
|
||||
"pluginUrl": "https://plugins.jetbrains.com/plugin/12134-material-design-dark-theme",
|
||||
"sourceCodeUrl": "https://github.com/xinkunZ/NotReallyMDTheme",
|
||||
"sourceCodePath": "blob/master/src/main/resources/MaterialTheme.theme.json"
|
||||
},
|
||||
"Monocai.theme.json": {
|
||||
"name": "Monocai",
|
||||
"dark": true,
|
||||
"lafClassName": "com.formdev.flatlaf.intellijthemes.FlatMonocaiIJTheme",
|
||||
"license": "MIT",
|
||||
"licenseFile": "Monocai.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/bmikaili/intellij-monocai-theme",
|
||||
"pluginUrl": "https://plugins.jetbrains.com/plugin/12163-monocai-color-theme",
|
||||
"sourceCodeUrl": "https://github.com/TheEggi/intellij-monocai-theme",
|
||||
"sourceCodePath": "blob/master/resources/Monocai.theme.json"
|
||||
},
|
||||
"Monokai_Pro.default.theme.json": {
|
||||
"name": "Monokai Pro",
|
||||
"discontinued": true,
|
||||
"dark": true,
|
||||
"lafClassName": "com.formdev.flatlaf.intellijthemes.FlatMonokaiProIJTheme",
|
||||
"license": "MIT",
|
||||
"licenseFile": "Monokai_Pro.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/subtheme-dev/monokai-pro"
|
||||
@@ -188,22 +215,28 @@
|
||||
"nord.theme.json": {
|
||||
"name": "Nord",
|
||||
"dark": true,
|
||||
"lafClassName": "com.formdev.flatlaf.intellijthemes.FlatNordIJTheme",
|
||||
"license": "MIT",
|
||||
"licenseFile": "nord.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/arcticicestudio/nord-jetbrains",
|
||||
"pluginUrl": "https://plugins.jetbrains.com/plugin/10321-nord",
|
||||
"sourceCodeUrl": "https://github.com/nordtheme/jetbrains",
|
||||
"sourceCodePath": "blob/main/src/nord.theme.json"
|
||||
},
|
||||
"one_dark.theme.json": {
|
||||
"name": "One Dark",
|
||||
"dark": true,
|
||||
"lafClassName": "com.formdev.flatlaf.intellijthemes.FlatOneDarkIJTheme",
|
||||
"license": "MIT",
|
||||
"licenseFile": "one_dark.LICENSE.txt",
|
||||
"pluginUrl": "https://plugins.jetbrains.com/plugin/11938-one-dark-theme",
|
||||
"sourceCodeUrl": "https://github.com/one-dark/jetbrains-one-dark-theme",
|
||||
"sourceCodePath": "blob/master/buildSrc/templates/oneDark.template.theme.json"
|
||||
},
|
||||
"SolarizedDark.theme.json": {
|
||||
"name": "Solarized Dark",
|
||||
"discontinued": true,
|
||||
"dark": true,
|
||||
"lafClassName": "com.formdev.flatlaf.intellijthemes.FlatSolarizedDarkIJTheme",
|
||||
"license": "The Unlicense",
|
||||
"licenseFile": "Solarized.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/4lex4/intellij-platform-solarized",
|
||||
@@ -211,6 +244,8 @@
|
||||
},
|
||||
"SolarizedLight.theme.json": {
|
||||
"name": "Solarized Light",
|
||||
"discontinued": true,
|
||||
"lafClassName": "com.formdev.flatlaf.intellijthemes.FlatSolarizedLightIJTheme",
|
||||
"license": "The Unlicense",
|
||||
"licenseFile": "Solarized.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/4lex4/intellij-platform-solarized",
|
||||
@@ -219,24 +254,30 @@
|
||||
"Spacegray.theme.json": {
|
||||
"name": "Spacegray",
|
||||
"dark": true,
|
||||
"lafClassName": "com.formdev.flatlaf.intellijthemes.FlatSpacegrayIJTheme",
|
||||
"license": "MIT",
|
||||
"licenseFile": "Spacegray.LICENSE.txt",
|
||||
"pluginUrl": "https://plugins.jetbrains.com/plugin/12122-spacegray-theme",
|
||||
"sourceCodeUrl": "https://github.com/mturlo/intellij-spacegray",
|
||||
"sourceCodePath": "blob/master/src/Spacegray.theme.json"
|
||||
},
|
||||
"vuesion_theme.theme.json": {
|
||||
"name": "Vuesion",
|
||||
"dark": true,
|
||||
"lafClassName": "com.formdev.flatlaf.intellijthemes.FlatVuesionIJTheme",
|
||||
"license": "MIT",
|
||||
"licenseFile": "vuesion_theme.LICENSE.txt",
|
||||
"pluginUrl": "https://plugins.jetbrains.com/plugin/12226-vuesion-theme",
|
||||
"sourceCodeUrl": "https://github.com/vuesion/intellij-theme",
|
||||
"sourceCodePath": "blob/master/resources/META-INF/vuesion_theme.theme.json"
|
||||
},
|
||||
"Xcode-Dark.theme.json": {
|
||||
"name": "Xcode-Dark",
|
||||
"dark": true,
|
||||
"lafClassName": "com.formdev.flatlaf.intellijthemes.FlatXcodeDarkIJTheme",
|
||||
"license": "MIT",
|
||||
"licenseFile": "Xcode-Dark.LICENSE.txt",
|
||||
"pluginUrl": "https://plugins.jetbrains.com/plugin/13106-xcode-dark-theme",
|
||||
"sourceCodeUrl": "https://github.com/antelle/intellij-xcode-dark-theme",
|
||||
"sourceCodePath": "blob/master/resources/Xcode-Dark.theme.json"
|
||||
},
|
||||
@@ -244,132 +285,166 @@
|
||||
"material-theme-ui-lite/Arc Dark.theme.json": {
|
||||
"name": "Material Theme UI Lite / Arc Dark",
|
||||
"dark": true,
|
||||
"lafClassName": "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMTArcDarkIJTheme",
|
||||
"license": "MIT",
|
||||
"licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
|
||||
"pluginUrl": "https://plugins.jetbrains.com/plugin/8006-material-theme-ui",
|
||||
"sourceCodeUrl": "https://github.com/AtomMaterialUI/material-theme-ui-lite",
|
||||
"sourceCodePath": "blob/master/src/main/resources/themes/regular/Arc Dark.theme.json"
|
||||
},
|
||||
"material-theme-ui-lite/Atom One Dark.theme.json": {
|
||||
"name": "Material Theme UI Lite / Atom One Dark",
|
||||
"dark": true,
|
||||
"lafClassName": "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMTAtomOneDarkIJTheme",
|
||||
"license": "MIT",
|
||||
"licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
|
||||
"pluginUrl": "https://plugins.jetbrains.com/plugin/8006-material-theme-ui",
|
||||
"sourceCodeUrl": "https://github.com/AtomMaterialUI/material-theme-ui-lite",
|
||||
"sourceCodePath": "blob/master/src/main/resources/themes/regular/Atom One Dark.theme.json"
|
||||
},
|
||||
"material-theme-ui-lite/Atom One Light.theme.json": {
|
||||
"name": "Material Theme UI Lite / Atom One Light",
|
||||
"lafClassName": "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMTAtomOneLightIJTheme",
|
||||
"license": "MIT",
|
||||
"licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
|
||||
"pluginUrl": "https://plugins.jetbrains.com/plugin/8006-material-theme-ui",
|
||||
"sourceCodeUrl": "https://github.com/AtomMaterialUI/material-theme-ui-lite",
|
||||
"sourceCodePath": "blob/master/src/main/resources/themes/regular/Atom One Light.theme.json"
|
||||
},
|
||||
"material-theme-ui-lite/Dracula.theme.json": {
|
||||
"name": "Material Theme UI Lite / Dracula",
|
||||
"dark": true,
|
||||
"lafClassName": "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMTDraculaIJTheme",
|
||||
"license": "MIT",
|
||||
"licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
|
||||
"pluginUrl": "https://plugins.jetbrains.com/plugin/8006-material-theme-ui",
|
||||
"sourceCodeUrl": "https://github.com/AtomMaterialUI/material-theme-ui-lite",
|
||||
"sourceCodePath": "blob/master/src/main/resources/themes/regular/Dracula.theme.json"
|
||||
},
|
||||
"material-theme-ui-lite/GitHub.theme.json": {
|
||||
"name": "Material Theme UI Lite / GitHub",
|
||||
"lafClassName": "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMTGitHubIJTheme",
|
||||
"license": "MIT",
|
||||
"licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
|
||||
"pluginUrl": "https://plugins.jetbrains.com/plugin/8006-material-theme-ui",
|
||||
"sourceCodeUrl": "https://github.com/AtomMaterialUI/material-theme-ui-lite",
|
||||
"sourceCodePath": "blob/master/src/main/resources/themes/regular/GitHub.theme.json"
|
||||
},
|
||||
"material-theme-ui-lite/GitHub Dark.theme.json": {
|
||||
"name": "Material Theme UI Lite / GitHub Dark",
|
||||
"dark": true,
|
||||
"lafClassName": "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMTGitHubDarkIJTheme",
|
||||
"license": "MIT",
|
||||
"licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
|
||||
"pluginUrl": "https://plugins.jetbrains.com/plugin/8006-material-theme-ui",
|
||||
"sourceCodeUrl": "https://github.com/AtomMaterialUI/material-theme-ui-lite",
|
||||
"sourceCodePath": "blob/master/src/main/resources/themes/regular/GitHub Dark.theme.json"
|
||||
},
|
||||
"material-theme-ui-lite/Light Owl.theme.json": {
|
||||
"name": "Material Theme UI Lite / Light Owl",
|
||||
"lafClassName": "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMTLightOwlIJTheme",
|
||||
"license": "MIT",
|
||||
"licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
|
||||
"pluginUrl": "https://plugins.jetbrains.com/plugin/8006-material-theme-ui",
|
||||
"sourceCodeUrl": "https://github.com/AtomMaterialUI/material-theme-ui-lite",
|
||||
"sourceCodePath": "blob/master/src/main/resources/themes/regular/Light Owl.theme.json"
|
||||
},
|
||||
"material-theme-ui-lite/Material Darker.theme.json": {
|
||||
"name": "Material Theme UI Lite / Material Darker",
|
||||
"dark": true,
|
||||
"lafClassName": "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMTMaterialDarkerIJTheme",
|
||||
"license": "MIT",
|
||||
"licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
|
||||
"pluginUrl": "https://plugins.jetbrains.com/plugin/8006-material-theme-ui",
|
||||
"sourceCodeUrl": "https://github.com/AtomMaterialUI/material-theme-ui-lite",
|
||||
"sourceCodePath": "blob/master/src/main/resources/themes/regular/Material Darker.theme.json"
|
||||
},
|
||||
"material-theme-ui-lite/Material Deep Ocean.theme.json": {
|
||||
"name": "Material Theme UI Lite / Material Deep Ocean",
|
||||
"dark": true,
|
||||
"lafClassName": "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMTMaterialDeepOceanIJTheme",
|
||||
"license": "MIT",
|
||||
"licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
|
||||
"pluginUrl": "https://plugins.jetbrains.com/plugin/8006-material-theme-ui",
|
||||
"sourceCodeUrl": "https://github.com/AtomMaterialUI/material-theme-ui-lite",
|
||||
"sourceCodePath": "blob/master/src/main/resources/themes/regular/Material Deep Ocean.theme.json"
|
||||
},
|
||||
"material-theme-ui-lite/Material Lighter.theme.json": {
|
||||
"name": "Material Theme UI Lite / Material Lighter",
|
||||
"lafClassName": "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMTMaterialLighterIJTheme",
|
||||
"license": "MIT",
|
||||
"licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
|
||||
"pluginUrl": "https://plugins.jetbrains.com/plugin/8006-material-theme-ui",
|
||||
"sourceCodeUrl": "https://github.com/AtomMaterialUI/material-theme-ui-lite",
|
||||
"sourceCodePath": "blob/master/src/main/resources/themes/regular/Material Lighter.theme.json"
|
||||
},
|
||||
"material-theme-ui-lite/Material Oceanic.theme.json": {
|
||||
"name": "Material Theme UI Lite / Material Oceanic",
|
||||
"dark": true,
|
||||
"lafClassName": "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMTMaterialOceanicIJTheme",
|
||||
"license": "MIT",
|
||||
"licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
|
||||
"pluginUrl": "https://plugins.jetbrains.com/plugin/8006-material-theme-ui",
|
||||
"sourceCodeUrl": "https://github.com/AtomMaterialUI/material-theme-ui-lite",
|
||||
"sourceCodePath": "blob/master/src/main/resources/themes/regular/Material Oceanic.theme.json"
|
||||
},
|
||||
"material-theme-ui-lite/Material Palenight.theme.json": {
|
||||
"name": "Material Theme UI Lite / Material Palenight",
|
||||
"dark": true,
|
||||
"lafClassName": "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMTMaterialPalenightIJTheme",
|
||||
"license": "MIT",
|
||||
"licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
|
||||
"pluginUrl": "https://plugins.jetbrains.com/plugin/8006-material-theme-ui",
|
||||
"sourceCodeUrl": "https://github.com/AtomMaterialUI/material-theme-ui-lite",
|
||||
"sourceCodePath": "blob/master/src/main/resources/themes/regular/Material Palenight.theme.json"
|
||||
},
|
||||
"material-theme-ui-lite/Monokai Pro.theme.json": {
|
||||
"name": "Material Theme UI Lite / Monokai Pro",
|
||||
"dark": true,
|
||||
"lafClassName": "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMTMonokaiProIJTheme",
|
||||
"license": "MIT",
|
||||
"licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
|
||||
"pluginUrl": "https://plugins.jetbrains.com/plugin/8006-material-theme-ui",
|
||||
"sourceCodeUrl": "https://github.com/AtomMaterialUI/material-theme-ui-lite",
|
||||
"sourceCodePath": "blob/master/src/main/resources/themes/regular/Monokai Pro.theme.json"
|
||||
},
|
||||
"material-theme-ui-lite/Moonlight.theme.json": {
|
||||
"name": "Material Theme UI Lite / Moonlight",
|
||||
"dark": true,
|
||||
"lafClassName": "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMTMoonlightIJTheme",
|
||||
"license": "MIT",
|
||||
"licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
|
||||
"pluginUrl": "https://plugins.jetbrains.com/plugin/8006-material-theme-ui",
|
||||
"sourceCodeUrl": "https://github.com/AtomMaterialUI/material-theme-ui-lite",
|
||||
"sourceCodePath": "blob/master/src/main/resources/themes/regular/Moonlight.theme.json"
|
||||
},
|
||||
"material-theme-ui-lite/Night Owl.theme.json": {
|
||||
"name": "Material Theme UI Lite / Night Owl",
|
||||
"dark": true,
|
||||
"lafClassName": "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMTNightOwlIJTheme",
|
||||
"license": "MIT",
|
||||
"licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
|
||||
"pluginUrl": "https://plugins.jetbrains.com/plugin/8006-material-theme-ui",
|
||||
"sourceCodeUrl": "https://github.com/AtomMaterialUI/material-theme-ui-lite",
|
||||
"sourceCodePath": "blob/master/src/main/resources/themes/regular/Night Owl.theme.json"
|
||||
},
|
||||
"material-theme-ui-lite/Solarized Dark.theme.json": {
|
||||
"name": "Material Theme UI Lite / Solarized Dark",
|
||||
"dark": true,
|
||||
"lafClassName": "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMTSolarizedDarkIJTheme",
|
||||
"license": "MIT",
|
||||
"licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
|
||||
"pluginUrl": "https://plugins.jetbrains.com/plugin/8006-material-theme-ui",
|
||||
"sourceCodeUrl": "https://github.com/AtomMaterialUI/material-theme-ui-lite",
|
||||
"sourceCodePath": "blob/master/src/main/resources/themes/regular/Solarized Dark.theme.json"
|
||||
},
|
||||
"material-theme-ui-lite/Solarized Light.theme.json": {
|
||||
"name": "Material Theme UI Lite / Solarized Light",
|
||||
"lafClassName": "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatMTSolarizedLightIJTheme",
|
||||
"license": "MIT",
|
||||
"licenseFile": "material-theme-ui-lite/Material Theme UI Lite.LICENSE.txt",
|
||||
"sourceCodeUrl": "https://github.com/mallowigi/material-theme-ui-lite",
|
||||
"pluginUrl": "https://plugins.jetbrains.com/plugin/8006-material-theme-ui",
|
||||
"sourceCodeUrl": "https://github.com/AtomMaterialUI/material-theme-ui-lite",
|
||||
"sourceCodePath": "blob/master/src/main/resources/themes/regular/Solarized Light.theme.json"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
|
||||
org.eclipse.jdt.core.compiler.compliance=1.8
|
||||
org.eclipse.jdt.core.compiler.source=1.8
|
||||
org.eclipse.jdt.core.formatter.align_assignment_statements_on_columns=false
|
||||
org.eclipse.jdt.core.formatter.align_fields_grouping_blank_lines=2147483647
|
||||
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.awt.Dimension;
|
||||
import java.awt.EventQueue;
|
||||
import java.awt.Font;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.GraphicsConfiguration;
|
||||
import java.awt.Insets;
|
||||
import java.awt.KeyboardFocusManager;
|
||||
import java.awt.LayoutManager;
|
||||
@@ -124,9 +125,12 @@ public class FlatInspector
|
||||
* Installs a key listener into the application that allows enabling and disabling
|
||||
* the UI inspector with the given keystroke (e.g. "ctrl shift alt X").
|
||||
*
|
||||
* @param activationKeys a keystroke (e.g. "ctrl shift alt X")
|
||||
* @param activationKeys a keystroke (e.g. "ctrl shift alt X"), or {@code null} to use "ctrl shift alt X"
|
||||
*/
|
||||
public static void install( String activationKeys ) {
|
||||
if( activationKeys == null )
|
||||
activationKeys = "ctrl shift alt X";
|
||||
|
||||
KeyStroke keyStroke = KeyStroke.getKeyStroke( activationKeys );
|
||||
Toolkit.getDefaultToolkit().addAWTEventListener( e -> {
|
||||
if( e.getID() == KeyEvent.KEY_RELEASED &&
|
||||
@@ -450,15 +454,18 @@ public class FlatInspector
|
||||
Dimension size = tip.getPreferredSize();
|
||||
|
||||
// position the tip in the visible area
|
||||
Rectangle visibleRect = rootPane.getGraphicsConfiguration().getBounds();
|
||||
if( tx + size.width > visibleRect.x + visibleRect.width )
|
||||
tx -= size.width + UIScale.scale( 16 );
|
||||
if( ty + size.height > visibleRect.y + visibleRect.height )
|
||||
ty -= size.height + UIScale.scale( 32 );
|
||||
if( tx < visibleRect.x )
|
||||
tx = visibleRect.x;
|
||||
if( ty < visibleRect.y )
|
||||
ty = visibleRect.y;
|
||||
GraphicsConfiguration gc = rootPane.getGraphicsConfiguration();
|
||||
if( gc != null ) {
|
||||
Rectangle visibleRect = gc.getBounds();
|
||||
if( tx + size.width > visibleRect.x + visibleRect.width )
|
||||
tx -= size.width + UIScale.scale( 16 );
|
||||
if( ty + size.height > visibleRect.y + visibleRect.height )
|
||||
ty -= size.height + UIScale.scale( 32 );
|
||||
if( tx < visibleRect.x )
|
||||
tx = visibleRect.x;
|
||||
if( ty < visibleRect.y )
|
||||
ty = visibleRect.y;
|
||||
}
|
||||
|
||||
PopupFactory popupFactory = PopupFactory.getSharedInstance();
|
||||
popup = popupFactory.getPopup( c, tip, tx, ty );
|
||||
|
||||
@@ -37,6 +37,7 @@ import java.net.URL;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.ImageIcon;
|
||||
@@ -588,7 +589,12 @@ public class FlatSVGIcon
|
||||
: GrayFilter.createDisabledIconFilter( dark );
|
||||
}
|
||||
|
||||
Graphics2D g2 = new GraphicsFilter( (Graphics2D) g.create(), colorFilter, ColorFilter.getInstance(), grayFilter );
|
||||
ColorFilter globalColorFilter = ColorFilter.getInstance();
|
||||
globalColorFilter.c = c;
|
||||
if( colorFilter != null )
|
||||
colorFilter.c = c;
|
||||
|
||||
Graphics2D g2 = new GraphicsFilter( (Graphics2D) g.create(), colorFilter, globalColorFilter, grayFilter );
|
||||
|
||||
try {
|
||||
setRenderingHints( g2 );
|
||||
@@ -596,6 +602,10 @@ public class FlatSVGIcon
|
||||
paintSvg( g2, x, y );
|
||||
} finally {
|
||||
g2.dispose();
|
||||
|
||||
globalColorFilter.c = null;
|
||||
if( colorFilter != null )
|
||||
colorFilter.c = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -760,6 +770,8 @@ public class FlatSVGIcon
|
||||
private Map<Color, Color> colorMap;
|
||||
private Map<Color, Color> darkColorMap;
|
||||
private Function<Color, Color> mapper;
|
||||
private BiFunction<Component, Color, Color> mapperEx;
|
||||
private Component c;
|
||||
|
||||
/**
|
||||
* Returns the global ColorFilter that is applied to all icons.
|
||||
@@ -800,6 +812,22 @@ public class FlatSVGIcon
|
||||
setMapper( mapper );
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a color modifying function that changes painted colors.
|
||||
* The {@link BiFunction} gets passed the component and
|
||||
* the original color and returns a modified one.
|
||||
* <p>
|
||||
* Examples:
|
||||
* A ColorFilter can be used to brighten colors of the icon (depending on component state if desired):
|
||||
* <pre>new ColorFilter( (c, color) -> c.isEnabled() ? color.brighter() : color );</pre>
|
||||
*
|
||||
* @param mapperEx The color mapper function
|
||||
* @since 3.6
|
||||
*/
|
||||
public ColorFilter( BiFunction<Component, Color, Color> mapperEx ) {
|
||||
setMapperEx( mapperEx );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a color modifying function or {@code null}
|
||||
*
|
||||
@@ -821,12 +849,39 @@ public class FlatSVGIcon
|
||||
* <pre>filter.setMapper( color -> Color.RED );</pre>
|
||||
*
|
||||
* @param mapper The color mapper function
|
||||
* @see #setMapperEx(BiFunction)
|
||||
* @since 1.2
|
||||
*/
|
||||
public void setMapper( Function<Color, Color> mapper ) {
|
||||
this.mapper = mapper;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a color modifying function or {@code null}
|
||||
*
|
||||
* @since 3.6
|
||||
*/
|
||||
public BiFunction<Component, Color, Color> getMapperEx() {
|
||||
return mapperEx;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a color modifying function that changes painted colors.
|
||||
* The {@link BiFunction} gets passed the component and
|
||||
* the original color and returns a modified one.
|
||||
* <p>
|
||||
* Examples:
|
||||
* A ColorFilter can be used to brighten colors of the icon (depending on component state if desired):
|
||||
* <pre>filter.setMapperEx( (c, color) -> c.isEnabled() ? color.brighter() : color );</pre>
|
||||
*
|
||||
* @param mapperEx The color mapper function
|
||||
* @see #setMapper(Function)
|
||||
* @since 3.6
|
||||
*/
|
||||
public void setMapperEx( BiFunction<Component, Color, Color> mapperEx ) {
|
||||
this.mapperEx = mapperEx;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the color mappings used for light themes.
|
||||
*
|
||||
@@ -936,6 +991,11 @@ public class FlatSVGIcon
|
||||
}
|
||||
|
||||
public Color filter( Color color ) {
|
||||
return filter( c, color );
|
||||
}
|
||||
|
||||
/** @since 3.6 */
|
||||
public Color filter( Component c, Color color ) {
|
||||
// apply mappings
|
||||
color = applyMappings( color );
|
||||
|
||||
@@ -943,6 +1003,10 @@ public class FlatSVGIcon
|
||||
if( mapper != null )
|
||||
color = mapper.apply( color );
|
||||
|
||||
// apply mapperEx function
|
||||
if( mapperEx != null )
|
||||
color = mapperEx.apply( c, color );
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
@@ -974,6 +1038,16 @@ public class FlatSVGIcon
|
||||
return color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the component passed to {@link FlatSVGIcon#paintIcon(Component, Graphics, int, int)}.
|
||||
* This allows color mapping depend on component state (e.g. enabled, selected, hover, etc).
|
||||
*
|
||||
* @since 3.6
|
||||
*/
|
||||
public Component getPaintingComponent() {
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a color modifying function that uses {@link RGBImageFilter#filterRGB(int, int, int)}.
|
||||
* Can be set to a {@link ColorFilter} using {@link ColorFilter#setMapper(Function)}.
|
||||
|
||||
@@ -85,9 +85,12 @@ public class FlatUIDefaultsInspector
|
||||
* Installs a key listener into the application that allows enabling and disabling
|
||||
* the UI inspector with the given keystroke (e.g. "ctrl shift alt Y").
|
||||
*
|
||||
* @param activationKeys a keystroke (e.g. "ctrl shift alt Y")
|
||||
* @param activationKeys a keystroke (e.g. "ctrl shift alt Y"), or {@code null} to use "ctrl shift alt Y"
|
||||
*/
|
||||
public static void install( String activationKeys ) {
|
||||
if( activationKeys == null )
|
||||
activationKeys = "ctrl shift alt Y";
|
||||
|
||||
KeyStroke keyStroke = KeyStroke.getKeyStroke( activationKeys );
|
||||
Toolkit.getDefaultToolkit().addAWTEventListener( e -> {
|
||||
if( e.getID() == KeyEvent.KEY_RELEASED &&
|
||||
|
||||
@@ -29,19 +29,37 @@ public class FlatTree
|
||||
implements FlatComponentExtension, FlatStyleableComponent
|
||||
{
|
||||
/**
|
||||
* Returns if the tree shows a wide selection
|
||||
* Returns whether tree shows a wide selection
|
||||
*/
|
||||
public boolean isWideSelection() {
|
||||
return getClientPropertyBoolean( TREE_WIDE_SELECTION, "Tree.wideSelection" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets if the tree shows a wide selection
|
||||
* Specifies whether tree shows a wide selection
|
||||
*/
|
||||
public void setWideSelection( boolean wideSelection ) {
|
||||
putClientProperty( TREE_WIDE_SELECTION, wideSelection );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether tree uses a wide cell renderer.
|
||||
*
|
||||
* @since 3.6
|
||||
*/
|
||||
public boolean isWideCellRenderer() {
|
||||
return getClientPropertyBoolean( TREE_WIDE_CELL_RENDERER, "Tree.wideCellRenderer" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Specifies whether tree uses a wide cell renderer.
|
||||
*
|
||||
* @since 3.6
|
||||
*/
|
||||
public void setWideCellRenderer( boolean wideCellRenderer ) {
|
||||
putClientProperty( TREE_WIDE_CELL_RENDERER, wideCellRenderer );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether tree item selection is painted. Default is {@code true}.
|
||||
* If set to {@code false}, then the tree cell renderer is responsible for painting selection.
|
||||
|
||||
@@ -62,6 +62,9 @@ CheckBox.icon.pressedBackground = CheckBox.icon.background
|
||||
CheckBox.icon.focusedSelectedBackground = CheckBox.icon.selectedBackground
|
||||
CheckBox.icon.hoverSelectedBackground = CheckBox.icon.selectedBackground
|
||||
CheckBox.icon.pressedSelectedBackground = CheckBox.icon.selectedBackground
|
||||
CheckBox.icon.focusedIndeterminateBackground = CheckBox.icon.indeterminateBackground
|
||||
CheckBox.icon.hoverIndeterminateBackground = CheckBox.icon.indeterminateBackground
|
||||
CheckBox.icon.pressedIndeterminateBackground = CheckBox.icon.indeterminateBackground
|
||||
|
||||
CheckBox.icon[filled].disabledBackground = CheckBox.icon[filled].background
|
||||
CheckBox.icon[filled].focusedBackground = CheckBox.icon[filled].background
|
||||
@@ -70,7 +73,9 @@ CheckBox.icon[filled].pressedBackground = CheckBox.icon[filled].background
|
||||
CheckBox.icon[filled].focusedSelectedBackground = CheckBox.icon[filled].selectedBackground
|
||||
CheckBox.icon[filled].hoverSelectedBackground = CheckBox.icon[filled].selectedBackground
|
||||
CheckBox.icon[filled].pressedSelectedBackground = CheckBox.icon[filled].selectedBackground
|
||||
|
||||
CheckBox.icon[filled].focusedIndeterminateBackground = CheckBox.icon[filled].indeterminateBackground
|
||||
CheckBox.icon[filled].hoverIndeterminateBackground = CheckBox.icon[filled].indeterminateBackground
|
||||
CheckBox.icon[filled].pressedIndeterminateBackground = CheckBox.icon[filled].indeterminateBackground
|
||||
|
||||
#---- CheckBoxMenuItem ----
|
||||
|
||||
@@ -210,8 +215,14 @@ TableHeader.pressedForeground = TableHeader.foreground
|
||||
|
||||
#---- TitlePane ----
|
||||
|
||||
TitlePane.buttonBackground = TitlePane.background
|
||||
TitlePane.buttonInactiveBackground = TitlePane.background
|
||||
TitlePane.buttonHoverBackground = TitlePane.background
|
||||
TitlePane.buttonPressedBackground = TitlePane.background
|
||||
TitlePane.closeBackground = TitlePane.background
|
||||
TitlePane.closeInactiveBackground = TitlePane.background
|
||||
TitlePane.closeHoverBackground = TitlePane.background
|
||||
TitlePane.closePressedBackground = TitlePane.background
|
||||
|
||||
|
||||
#---- ToggleButton ----
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
// For maven compatibility, <font-version> should be in format <major>.<minor>[.<micro>].
|
||||
// <build-number> is optional and should be incremented only if a new release is
|
||||
// necessary, but the <font-version> has not changed.
|
||||
version = "4.0"
|
||||
version = "4.1"
|
||||
|
||||
if( !rootProject.hasProperty( "release" ) )
|
||||
version = version.toString() + "-SNAPSHOT"
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user