Compare commits
57 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
069a7c809c | ||
|
|
883b4d735a | ||
|
|
9f39b269bb | ||
|
|
36c405c708 | ||
|
|
bc7c68ebe4 | ||
|
|
6c502ad4c5 | ||
|
|
100aa0b621 | ||
|
|
8e42b19934 | ||
|
|
1a456d5d68 | ||
|
|
e83c26a76a | ||
|
|
6e7c2a616b | ||
|
|
0699454df8 | ||
|
|
92c110548a | ||
|
|
ca88023560 | ||
|
|
12fc2299ec | ||
|
|
2089c77b84 | ||
|
|
4f5a3e8d8b | ||
|
|
95522846ac | ||
|
|
614ac956de | ||
|
|
c228362c01 | ||
|
|
f6c5db07f2 | ||
|
|
78e7839213 | ||
|
|
86a4f306c6 | ||
|
|
0e523f1193 | ||
|
|
9041a16b22 | ||
|
|
596ff3382d | ||
|
|
cbd80252ed | ||
|
|
bcd7a7e3dd | ||
|
|
9c98f1a553 | ||
|
|
c3d214aa23 | ||
|
|
d301f6e104 | ||
|
|
eb9fa585f7 | ||
|
|
16c6ffb032 | ||
|
|
7858e42e37 | ||
|
|
30132aa6b0 | ||
|
|
bf4d4cc2c5 | ||
|
|
9f0554c883 | ||
|
|
218ea6ce47 | ||
|
|
0baae7da8b | ||
|
|
fb4576fc1b | ||
|
|
16f3f9e6ff | ||
|
|
fee7cf6265 | ||
|
|
2dd75c4a64 | ||
|
|
d2f46cd0b5 | ||
|
|
10914083e6 | ||
|
|
5d167da55e | ||
|
|
b381e20e57 | ||
|
|
475cc9a9a5 | ||
|
|
264d6fbd6d | ||
|
|
2826cf379b | ||
|
|
d28745df29 | ||
|
|
94f9e4a1be | ||
|
|
ec547e1d65 | ||
|
|
61d4eb649b | ||
|
|
52ad15e375 | ||
|
|
ff00a6c0f0 | ||
|
|
9b1ebd658d |
6
.github/workflows/ci.yml
vendored
@@ -26,6 +26,10 @@ jobs:
|
|||||||
- 8
|
- 8
|
||||||
- 11 # LTS
|
- 11 # LTS
|
||||||
- 17 # LTS
|
- 17 # LTS
|
||||||
|
toolchain: [""]
|
||||||
|
include:
|
||||||
|
- java: 17
|
||||||
|
toolchain: 19 # latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
@@ -41,7 +45,7 @@ jobs:
|
|||||||
cache: gradle
|
cache: gradle
|
||||||
|
|
||||||
- name: Build with Gradle
|
- name: Build with Gradle
|
||||||
run: ./gradlew build
|
run: ./gradlew build -Dtoolchain=${{ matrix.toolchain }}
|
||||||
|
|
||||||
- name: Upload artifacts
|
- name: Upload artifacts
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
|
|||||||
20
.github/workflows/natives.yml
vendored
@@ -9,20 +9,26 @@ on:
|
|||||||
tags:
|
tags:
|
||||||
- '[0-9]*'
|
- '[0-9]*'
|
||||||
paths:
|
paths:
|
||||||
- 'flatlaf-natives/flatlaf-natives-windows/**'
|
- 'flatlaf-natives/**'
|
||||||
- '.github/workflows/natives.yml'
|
- '.github/workflows/natives.yml'
|
||||||
- 'gradle/wrapper/gradle-wrapper.properties'
|
- 'gradle/wrapper/gradle-wrapper.properties'
|
||||||
pull_request:
|
pull_request:
|
||||||
branches:
|
branches:
|
||||||
- '*'
|
- '*'
|
||||||
paths:
|
paths:
|
||||||
- 'flatlaf-natives/flatlaf-natives-windows/**'
|
- 'flatlaf-natives/**'
|
||||||
- '.github/workflows/natives.yml'
|
- '.github/workflows/natives.yml'
|
||||||
- 'gradle/wrapper/gradle-wrapper.properties'
|
- 'gradle/wrapper/gradle-wrapper.properties'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
Windows:
|
Natives:
|
||||||
runs-on: windows-latest
|
strategy:
|
||||||
|
matrix:
|
||||||
|
os:
|
||||||
|
- windows
|
||||||
|
- ubuntu
|
||||||
|
|
||||||
|
runs-on: ${{ matrix.os }}-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
@@ -39,12 +45,12 @@ jobs:
|
|||||||
- name: Build with Gradle
|
- name: Build with Gradle
|
||||||
# --no-daemon is necessary on Windows otherwise caching Gradle would fail with:
|
# --no-daemon is necessary on Windows otherwise caching Gradle would fail with:
|
||||||
# tar.exe: Couldn't open ~/.gradle/caches/modules-2/modules-2.lock: Permission denied
|
# tar.exe: Couldn't open ~/.gradle/caches/modules-2/modules-2.lock: Permission denied
|
||||||
run: ./gradlew :flatlaf-natives-windows:build-natives --no-daemon
|
run: ./gradlew build-natives --no-daemon
|
||||||
|
|
||||||
- name: Upload artifacts
|
- name: Upload artifacts
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: FlatLaf-natives-windows-build-artifacts
|
name: FlatLaf-natives-build-artifacts-${{ matrix.os }}
|
||||||
path: |
|
path: |
|
||||||
flatlaf-core/src/main/resources/com/formdev/flatlaf/natives
|
flatlaf-core/src/main/resources/com/formdev/flatlaf/natives
|
||||||
flatlaf-natives/flatlaf-natives-windows/build
|
flatlaf-natives/flatlaf-natives-*/build
|
||||||
|
|||||||
60
CHANGELOG.md
@@ -1,6 +1,66 @@
|
|||||||
FlatLaf Change Log
|
FlatLaf Change Log
|
||||||
==================
|
==================
|
||||||
|
|
||||||
|
## 2.6
|
||||||
|
|
||||||
|
#### New features and improvements
|
||||||
|
|
||||||
|
- If value of system property `flatlaf.nativeLibraryPath` is `system`, then
|
||||||
|
`System.loadLibrary(String)` is used to load the native library.
|
||||||
|
- TabbedPane: Switch and close tabs on left mouse click only. (PR #595)
|
||||||
|
|
||||||
|
#### Fixed bugs
|
||||||
|
|
||||||
|
- ComboBox and Spinner: Fixed missing arrow buttons if preferred height is zero.
|
||||||
|
Minimum width of arrow buttons is 3/4 of default width.
|
||||||
|
- MenuBar: Fixed NPE in `FlatMenuItemRenderer.getTopLevelFont()` if menu item
|
||||||
|
does not have a parent. (issue #600; regression since implementing #589 in
|
||||||
|
FlatLaf 2.5)
|
||||||
|
- ScrollBar: Show "pressed" feedback on track/thumb only for left mouse button.
|
||||||
|
If absolute positioning is enabled (the default), then also for middle mouse
|
||||||
|
button.
|
||||||
|
- Arrow buttons in ComboBox, Spinner, ScrollBar and TabbedPane: Show "pressed"
|
||||||
|
feedback only for left mouse button.
|
||||||
|
- ScaledImageIcon: Do not throw exceptions if image was has invalid size (e.g.
|
||||||
|
not found). Instead, paint a red rectangle (similar to `FlatSVGIcon`).
|
||||||
|
- Fixed NPE in `FlatUIUtils.isCellEditor()`. (issue #601)
|
||||||
|
|
||||||
|
|
||||||
|
## 2.5
|
||||||
|
|
||||||
|
#### New features and improvements
|
||||||
|
|
||||||
|
- Linux: Use X11 window manager events to move window and to show window menu
|
||||||
|
(right-click on window title bar), if custom window decorations are enabled.
|
||||||
|
This gives FlatLaf windows a more "native" feeling. (issue #482)
|
||||||
|
- MenuBar: Support different menu selection style UI defaults for `MenuBar` and
|
||||||
|
`MenuItem`. (issue #587)
|
||||||
|
- MenuBar: Top level menus now use `MenuBar.font` instead of `Menu.font`. (issue
|
||||||
|
#589)
|
||||||
|
- PasswordField: Reveal button is now hidden (and turned off) if password field
|
||||||
|
is disabled. (issue #501)
|
||||||
|
- TabbedPane: New option to disable tab run rotation in wrap layout. Set UI
|
||||||
|
value `TabbedPane.rotateTabRuns` to `false`. (issue #574)
|
||||||
|
- Window decorations:
|
||||||
|
- Added client property to mark components in embedded menu bar as "caption"
|
||||||
|
(allow moving window). (issue #569)
|
||||||
|
- Option to show window icon only in frames, but not in dialogs. Set UI value
|
||||||
|
`TitlePane.showIconInDialogs` to `false`. (issue #589)
|
||||||
|
- Added UI value `TitlePane.font` to customize window title font. (issue #589)
|
||||||
|
- Added system property `flatlaf.updateUIOnSystemFontChange` to allow disabling
|
||||||
|
automatic UI update when system font changes. (issue #580)
|
||||||
|
|
||||||
|
#### Fixed bugs
|
||||||
|
|
||||||
|
- Fixed missing UI value `MenuItem.acceleratorDelimiter` on macOS. (was `null`,
|
||||||
|
is now an empty string)
|
||||||
|
- Fixed possible exception in `FlatUIUtils.resetRenderingHints()`. (issue #575)
|
||||||
|
- Fixed AWT components on macOS, which use Swing components internally. (issue
|
||||||
|
#583)
|
||||||
|
- SwingX: Fixed missing highlighting of "today" in `JXMonthView` and
|
||||||
|
`JXDatePicker`.
|
||||||
|
|
||||||
|
|
||||||
## 2.4
|
## 2.4
|
||||||
|
|
||||||
#### New features and improvements
|
#### New features and improvements
|
||||||
|
|||||||
@@ -14,8 +14,8 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
val releaseVersion = "2.4"
|
val releaseVersion = "2.6"
|
||||||
val developmentVersion = "2.5-SNAPSHOT"
|
val developmentVersion = "3.0-SNAPSHOT"
|
||||||
|
|
||||||
version = if( java.lang.Boolean.getBoolean( "release" ) ) releaseVersion else developmentVersion
|
version = if( java.lang.Boolean.getBoolean( "release" ) ) releaseVersion else developmentVersion
|
||||||
|
|
||||||
@@ -37,6 +37,9 @@ println( "----------------------------------------------------------------------
|
|||||||
println( "FlatLaf Version: ${version}" )
|
println( "FlatLaf Version: ${version}" )
|
||||||
println( "Gradle ${gradle.gradleVersion} at ${gradle.gradleHomeDir}" )
|
println( "Gradle ${gradle.gradleVersion} at ${gradle.gradleHomeDir}" )
|
||||||
println( "Java ${System.getProperty( "java.version" )}" )
|
println( "Java ${System.getProperty( "java.version" )}" )
|
||||||
|
val toolchainJavaVersion = System.getProperty( "toolchain" )
|
||||||
|
if( !toolchainJavaVersion.isNullOrEmpty() )
|
||||||
|
println( "Java toolchain ${toolchainJavaVersion}" )
|
||||||
println()
|
println()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
46
buildSrc/src/main/kotlin/flatlaf-cpp-library.gradle.kts
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2022 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
`cpp-library`
|
||||||
|
}
|
||||||
|
|
||||||
|
library {
|
||||||
|
// disable debuggable for release builds to make shared libraries smaller
|
||||||
|
binaries.configureEach( CppSharedLibrary::class ) {
|
||||||
|
with( compileTask.get() ) {
|
||||||
|
if( name.contains( "Release" ) )
|
||||||
|
isDebuggable = false
|
||||||
|
}
|
||||||
|
with( linkTask.get() ) {
|
||||||
|
if( name.contains( "Release" ) )
|
||||||
|
debuggable.set( false )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks {
|
||||||
|
withType<CppCompile>().configureEach {
|
||||||
|
doFirst {
|
||||||
|
println( "Used Tool Chain:" )
|
||||||
|
println( " - ${toolChain.get()}" )
|
||||||
|
println( "Available Tool Chains:" )
|
||||||
|
toolChains.forEach {
|
||||||
|
println( " - $it" )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
36
buildSrc/src/main/kotlin/flatlaf-jni-headers.gradle.kts
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2022 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
open class JniHeadersExtension {
|
||||||
|
var headers: List<String> = emptyList()
|
||||||
|
}
|
||||||
|
|
||||||
|
val extension = project.extensions.create<JniHeadersExtension>( "flatlafJniHeaders" )
|
||||||
|
|
||||||
|
|
||||||
|
tasks {
|
||||||
|
register<Copy>( "jni-headers" ) {
|
||||||
|
// depend on :flatlaf-core:compileJava because it generates the JNI headers
|
||||||
|
dependsOn( ":flatlaf-core:compileJava" )
|
||||||
|
|
||||||
|
from( project( ":flatlaf-core" ).buildDir.resolve( "generated/jni-headers" ) )
|
||||||
|
into( "src/main/headers" )
|
||||||
|
include( extension.headers )
|
||||||
|
filter<org.apache.tools.ant.filters.FixCrLfFilter>(
|
||||||
|
"eol" to org.apache.tools.ant.filters.FixCrLfFilter.CrLf.newInstance( "lf" )
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
26
buildSrc/src/main/kotlin/flatlaf-toolchain.gradle.kts
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2022 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
plugins {
|
||||||
|
java
|
||||||
|
}
|
||||||
|
|
||||||
|
val toolchainJavaVersion = System.getProperty( "toolchain" )
|
||||||
|
if( !toolchainJavaVersion.isNullOrEmpty() ) {
|
||||||
|
java.toolchain {
|
||||||
|
languageVersion.set( JavaLanguageVersion.of( toolchainJavaVersion ) )
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
`java-library`
|
`java-library`
|
||||||
|
`flatlaf-toolchain`
|
||||||
`flatlaf-module-info`
|
`flatlaf-module-info`
|
||||||
`flatlaf-java9`
|
`flatlaf-java9`
|
||||||
`flatlaf-publish`
|
`flatlaf-publish`
|
||||||
@@ -29,7 +30,7 @@ dependencies {
|
|||||||
testRuntimeOnly( "org.junit.jupiter:junit-jupiter-engine" )
|
testRuntimeOnly( "org.junit.jupiter:junit-jupiter-engine" )
|
||||||
|
|
||||||
// https://github.com/jtulach/netbeans-apitest
|
// https://github.com/jtulach/netbeans-apitest
|
||||||
sigtest( "org.netbeans.tools:sigtest-maven-plugin:1.4" )
|
sigtest( "org.netbeans.tools:sigtest-maven-plugin:1.7" )
|
||||||
}
|
}
|
||||||
|
|
||||||
java {
|
java {
|
||||||
@@ -66,6 +67,9 @@ tasks {
|
|||||||
test {
|
test {
|
||||||
useJUnitPlatform()
|
useJUnitPlatform()
|
||||||
testLogging.exceptionFormat = org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL
|
testLogging.exceptionFormat = org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL
|
||||||
|
|
||||||
|
if( JavaVersion.current() >= JavaVersion.VERSION_1_9 )
|
||||||
|
jvmArgs( listOf( "--add-opens", "java.desktop/javax.swing.plaf.basic=ALL-UNNAMED" ) )
|
||||||
}
|
}
|
||||||
|
|
||||||
register( "sigtestGenerate" ) {
|
register( "sigtestGenerate" ) {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#Signature file v4.1
|
#Signature file v4.1
|
||||||
#Version 2.3
|
#Version 2.5
|
||||||
|
|
||||||
CLSS public abstract interface com.formdev.flatlaf.FlatClientProperties
|
CLSS public abstract interface com.formdev.flatlaf.FlatClientProperties
|
||||||
fld public final static java.lang.String BUTTON_TYPE = "JButton.buttonType"
|
fld public final static java.lang.String BUTTON_TYPE = "JButton.buttonType"
|
||||||
@@ -11,6 +11,7 @@ fld public final static java.lang.String BUTTON_TYPE_TAB = "tab"
|
|||||||
fld public final static java.lang.String BUTTON_TYPE_TOOLBAR_BUTTON = "toolBarButton"
|
fld public final static java.lang.String BUTTON_TYPE_TOOLBAR_BUTTON = "toolBarButton"
|
||||||
fld public final static java.lang.String COMPONENT_FOCUS_OWNER = "JComponent.focusOwner"
|
fld public final static java.lang.String COMPONENT_FOCUS_OWNER = "JComponent.focusOwner"
|
||||||
fld public final static java.lang.String COMPONENT_ROUND_RECT = "JComponent.roundRect"
|
fld public final static java.lang.String COMPONENT_ROUND_RECT = "JComponent.roundRect"
|
||||||
|
fld public final static java.lang.String COMPONENT_TITLE_BAR_CAPTION = "JComponent.titleBarCaption"
|
||||||
fld public final static java.lang.String MENU_BAR_EMBEDDED = "JRootPane.menuBarEmbedded"
|
fld public final static java.lang.String MENU_BAR_EMBEDDED = "JRootPane.menuBarEmbedded"
|
||||||
fld public final static java.lang.String MINIMUM_HEIGHT = "JComponent.minimumHeight"
|
fld public final static java.lang.String MINIMUM_HEIGHT = "JComponent.minimumHeight"
|
||||||
fld public final static java.lang.String MINIMUM_WIDTH = "JComponent.minimumWidth"
|
fld public final static java.lang.String MINIMUM_WIDTH = "JComponent.minimumWidth"
|
||||||
@@ -185,6 +186,7 @@ meth public java.lang.String getID()
|
|||||||
meth public java.util.Map<java.lang.String,java.lang.String> getExtraDefaults()
|
meth public java.util.Map<java.lang.String,java.lang.String> getExtraDefaults()
|
||||||
meth public javax.swing.Icon getDisabledIcon(javax.swing.JComponent,javax.swing.Icon)
|
meth public javax.swing.Icon getDisabledIcon(javax.swing.JComponent,javax.swing.Icon)
|
||||||
meth public javax.swing.UIDefaults getDefaults()
|
meth public javax.swing.UIDefaults getDefaults()
|
||||||
|
meth public static <%0 extends java.lang.Object> {%%0} getStyleableValue(javax.swing.JComponent,java.lang.String)
|
||||||
meth public static boolean install(javax.swing.LookAndFeel)
|
meth public static boolean install(javax.swing.LookAndFeel)
|
||||||
anno 0 java.lang.Deprecated()
|
anno 0 java.lang.Deprecated()
|
||||||
meth public static boolean isLafDark()
|
meth public static boolean isLafDark()
|
||||||
@@ -193,6 +195,7 @@ meth public static boolean isUseNativeWindowDecorations()
|
|||||||
meth public static boolean setup(javax.swing.LookAndFeel)
|
meth public static boolean setup(javax.swing.LookAndFeel)
|
||||||
meth public static boolean supportsNativeWindowDecorations()
|
meth public static boolean supportsNativeWindowDecorations()
|
||||||
meth public static java.lang.Object parseDefaultsValue(java.lang.String,java.lang.String,java.lang.Class<?>)
|
meth public static java.lang.Object parseDefaultsValue(java.lang.String,java.lang.String,java.lang.Class<?>)
|
||||||
|
meth public static java.util.Map<java.lang.String,java.lang.Class<?>> getStyleableInfos(javax.swing.JComponent)
|
||||||
meth public static java.util.Map<java.lang.String,java.lang.String> getGlobalExtraDefaults()
|
meth public static java.util.Map<java.lang.String,java.lang.String> getGlobalExtraDefaults()
|
||||||
meth public static javax.swing.UIDefaults$ActiveValue createActiveFontValue(float)
|
meth public static javax.swing.UIDefaults$ActiveValue createActiveFontValue(float)
|
||||||
meth public static void hideMnemonics()
|
meth public static void hideMnemonics()
|
||||||
@@ -220,7 +223,7 @@ meth public void setExtraDefaults(java.util.Map<java.lang.String,java.lang.Strin
|
|||||||
meth public void uninitialize()
|
meth public void uninitialize()
|
||||||
meth public void unregisterUIDefaultsGetter(java.util.function.Function<java.lang.Object,java.lang.Object>)
|
meth public void unregisterUIDefaultsGetter(java.util.function.Function<java.lang.Object,java.lang.Object>)
|
||||||
supr javax.swing.plaf.basic.BasicLookAndFeel
|
supr javax.swing.plaf.basic.BasicLookAndFeel
|
||||||
hfds DESKTOPFONTHINTS,aquaLoaded,customDefaultsSources,desktopPropertyListener,desktopPropertyName,desktopPropertyName2,extraDefaults,globalExtraDefaults,mnemonicHandler,oldPopupFactory,postInitialization,subMenuUsabilityHelper,uiDefaultsGetters,updateUIPending
|
hfds DESKTOPFONTHINTS,aquaLoaded,customDefaultsSources,desktopPropertyListener,desktopPropertyName,desktopPropertyName2,extraDefaults,getUIMethod,getUIMethodInitialized,globalExtraDefaults,mnemonicHandler,oldPopupFactory,postInitialization,subMenuUsabilityHelperInstalled,uiDefaultsGetters,updateUIPending
|
||||||
hcls ActiveFont,FlatUIDefaults,ImageIconUIResource
|
hcls ActiveFont,FlatUIDefaults,ImageIconUIResource
|
||||||
|
|
||||||
CLSS public abstract interface static com.formdev.flatlaf.FlatLaf$DisabledIconProvider
|
CLSS public abstract interface static com.formdev.flatlaf.FlatLaf$DisabledIconProvider
|
||||||
@@ -259,6 +262,7 @@ fld public final static java.lang.String NATIVE_LIBRARY_PATH = "flatlaf.nativeLi
|
|||||||
fld public final static java.lang.String UI_SCALE = "flatlaf.uiScale"
|
fld public final static java.lang.String UI_SCALE = "flatlaf.uiScale"
|
||||||
fld public final static java.lang.String UI_SCALE_ALLOW_SCALE_DOWN = "flatlaf.uiScale.allowScaleDown"
|
fld public final static java.lang.String UI_SCALE_ALLOW_SCALE_DOWN = "flatlaf.uiScale.allowScaleDown"
|
||||||
fld public final static java.lang.String UI_SCALE_ENABLED = "flatlaf.uiScale.enabled"
|
fld public final static java.lang.String UI_SCALE_ENABLED = "flatlaf.uiScale.enabled"
|
||||||
|
fld public final static java.lang.String UPDATE_UI_ON_SYSTEM_FONT_CHANGE = "flatlaf.updateUIOnSystemFontChange"
|
||||||
fld public final static java.lang.String USE_JETBRAINS_CUSTOM_DECORATIONS = "flatlaf.useJetBrainsCustomDecorations"
|
fld public final static java.lang.String USE_JETBRAINS_CUSTOM_DECORATIONS = "flatlaf.useJetBrainsCustomDecorations"
|
||||||
fld public final static java.lang.String USE_TEXT_Y_CORRECTION = "flatlaf.useTextYCorrection"
|
fld public final static java.lang.String USE_TEXT_Y_CORRECTION = "flatlaf.useTextYCorrection"
|
||||||
fld public final static java.lang.String USE_UBUNTU_FONT = "flatlaf.useUbuntuFont"
|
fld public final static java.lang.String USE_UBUNTU_FONT = "flatlaf.useUbuntuFont"
|
||||||
|
|||||||
@@ -253,6 +253,19 @@ public interface FlatClientProperties
|
|||||||
*/
|
*/
|
||||||
String COMPONENT_FOCUS_OWNER = "JComponent.focusOwner";
|
String COMPONENT_FOCUS_OWNER = "JComponent.focusOwner";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies whether a component in an embedded menu bar should behave as caption
|
||||||
|
* (left-click allows moving window, right-click shows window system menu).
|
||||||
|
* The component does not receive mouse pressed/released/clicked/dragged events,
|
||||||
|
* but it gets mouse entered/exited/moved events.
|
||||||
|
* <p>
|
||||||
|
* <strong>Component</strong> {@link javax.swing.JComponent}<br>
|
||||||
|
* <strong>Value type</strong> {@link java.lang.Boolean}
|
||||||
|
*
|
||||||
|
* @since 2.5
|
||||||
|
*/
|
||||||
|
String COMPONENT_TITLE_BAR_CAPTION = "JComponent.titleBarCaption";
|
||||||
|
|
||||||
//---- Popup --------------------------------------------------------------
|
//---- Popup --------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ public class FlatDarculaLaf
|
|||||||
/**
|
/**
|
||||||
* Sets the application look and feel to this LaF
|
* Sets the application look and feel to this LaF
|
||||||
* using {@link UIManager#setLookAndFeel(javax.swing.LookAndFeel)}.
|
* using {@link UIManager#setLookAndFeel(javax.swing.LookAndFeel)}.
|
||||||
|
*
|
||||||
|
* @since 1.2
|
||||||
*/
|
*/
|
||||||
public static boolean setup() {
|
public static boolean setup() {
|
||||||
return setup( new FlatDarculaLaf() );
|
return setup( new FlatDarculaLaf() );
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ public class FlatDarkLaf
|
|||||||
/**
|
/**
|
||||||
* Sets the application look and feel to this LaF
|
* Sets the application look and feel to this LaF
|
||||||
* using {@link UIManager#setLookAndFeel(javax.swing.LookAndFeel)}.
|
* using {@link UIManager#setLookAndFeel(javax.swing.LookAndFeel)}.
|
||||||
|
*
|
||||||
|
* @since 1.2
|
||||||
*/
|
*/
|
||||||
public static boolean setup() {
|
public static boolean setup() {
|
||||||
return setup( new FlatDarkLaf() );
|
return setup( new FlatDarkLaf() );
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ public class FlatIntelliJLaf
|
|||||||
/**
|
/**
|
||||||
* Sets the application look and feel to this LaF
|
* Sets the application look and feel to this LaF
|
||||||
* using {@link UIManager#setLookAndFeel(javax.swing.LookAndFeel)}.
|
* using {@link UIManager#setLookAndFeel(javax.swing.LookAndFeel)}.
|
||||||
|
*
|
||||||
|
* @since 1.2
|
||||||
*/
|
*/
|
||||||
public static boolean setup() {
|
public static boolean setup() {
|
||||||
return setup( new FlatIntelliJLaf() );
|
return setup( new FlatIntelliJLaf() );
|
||||||
|
|||||||
@@ -30,6 +30,9 @@ import java.awt.image.ImageProducer;
|
|||||||
import java.beans.PropertyChangeEvent;
|
import java.beans.PropertyChangeEvent;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.lang.invoke.MethodHandle;
|
||||||
|
import java.lang.invoke.MethodHandles;
|
||||||
|
import java.lang.invoke.MethodType;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -63,6 +66,7 @@ import javax.swing.UIDefaults.LazyValue;
|
|||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import javax.swing.UnsupportedLookAndFeelException;
|
import javax.swing.UnsupportedLookAndFeelException;
|
||||||
import javax.swing.plaf.ColorUIResource;
|
import javax.swing.plaf.ColorUIResource;
|
||||||
|
import javax.swing.plaf.ComponentUI;
|
||||||
import javax.swing.plaf.FontUIResource;
|
import javax.swing.plaf.FontUIResource;
|
||||||
import javax.swing.plaf.IconUIResource;
|
import javax.swing.plaf.IconUIResource;
|
||||||
import javax.swing.plaf.UIResource;
|
import javax.swing.plaf.UIResource;
|
||||||
@@ -73,6 +77,7 @@ import com.formdev.flatlaf.ui.FlatNativeWindowBorder;
|
|||||||
import com.formdev.flatlaf.ui.FlatPopupFactory;
|
import com.formdev.flatlaf.ui.FlatPopupFactory;
|
||||||
import com.formdev.flatlaf.ui.FlatRootPaneUI;
|
import com.formdev.flatlaf.ui.FlatRootPaneUI;
|
||||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||||
|
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
|
||||||
import com.formdev.flatlaf.util.GrayFilter;
|
import com.formdev.flatlaf.util.GrayFilter;
|
||||||
import com.formdev.flatlaf.util.LoggingFacade;
|
import com.formdev.flatlaf.util.LoggingFacade;
|
||||||
import com.formdev.flatlaf.util.MultiResolutionImageSupport;
|
import com.formdev.flatlaf.util.MultiResolutionImageSupport;
|
||||||
@@ -111,6 +116,8 @@ public abstract class FlatLaf
|
|||||||
/**
|
/**
|
||||||
* Sets the application look and feel to the given LaF
|
* Sets the application look and feel to the given LaF
|
||||||
* using {@link UIManager#setLookAndFeel(javax.swing.LookAndFeel)}.
|
* using {@link UIManager#setLookAndFeel(javax.swing.LookAndFeel)}.
|
||||||
|
*
|
||||||
|
* @since 1.2
|
||||||
*/
|
*/
|
||||||
public static boolean setup( LookAndFeel newLookAndFeel ) {
|
public static boolean setup( LookAndFeel newLookAndFeel ) {
|
||||||
try {
|
try {
|
||||||
@@ -274,6 +281,9 @@ public abstract class FlatLaf
|
|||||||
}
|
}
|
||||||
if( desktopPropertyName != null ) {
|
if( desktopPropertyName != null ) {
|
||||||
desktopPropertyListener = e -> {
|
desktopPropertyListener = e -> {
|
||||||
|
if( !FlatSystemProperties.getBoolean( FlatSystemProperties.UPDATE_UI_ON_SYSTEM_FONT_CHANGE, true ) )
|
||||||
|
return;
|
||||||
|
|
||||||
String propertyName = e.getPropertyName();
|
String propertyName = e.getPropertyName();
|
||||||
if( desktopPropertyName.equals( propertyName ) || propertyName.equals( desktopPropertyName2 ) )
|
if( desktopPropertyName.equals( propertyName ) || propertyName.equals( desktopPropertyName2 ) )
|
||||||
reSetLookAndFeel();
|
reSetLookAndFeel();
|
||||||
@@ -571,6 +581,7 @@ public abstract class FlatLaf
|
|||||||
|
|
||||||
// add fonts that are not set in BasicLookAndFeel
|
// add fonts that are not set in BasicLookAndFeel
|
||||||
defaults.put( "RootPane.font", activeFont );
|
defaults.put( "RootPane.font", activeFont );
|
||||||
|
defaults.put( "TitlePane.font", activeFont );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initDefaultFont( UIDefaults defaults ) {
|
private void initDefaultFont( UIDefaults defaults ) {
|
||||||
@@ -1225,6 +1236,62 @@ public abstract class FlatLaf
|
|||||||
*/
|
*/
|
||||||
public static final Object NULL_VALUE = new Object();
|
public static final Object NULL_VALUE = new Object();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns information about styleable values of a component.
|
||||||
|
* <p>
|
||||||
|
* This is equivalent to: {@code ((StyleableUI)c.getUI()).getStyleableInfos(c)}
|
||||||
|
*
|
||||||
|
* @since 2.5
|
||||||
|
*/
|
||||||
|
public static Map<String, Class<?>> getStyleableInfos( JComponent c ) {
|
||||||
|
StyleableUI ui = getStyleableUI( c );
|
||||||
|
return (ui != null) ? ui.getStyleableInfos( c ) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the (styled) value for the given key from the given component.
|
||||||
|
* <p>
|
||||||
|
* This is equivalent to: {@code ((StyleableUI)c.getUI()).getStyleableValue(c, key)}
|
||||||
|
*
|
||||||
|
* @since 2.5
|
||||||
|
*/
|
||||||
|
@SuppressWarnings( "unchecked" )
|
||||||
|
public static <T> T getStyleableValue( JComponent c, String key ) {
|
||||||
|
StyleableUI ui = getStyleableUI( c );
|
||||||
|
return (ui != null) ? (T) ui.getStyleableValue( c, key ) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static StyleableUI getStyleableUI( JComponent c ) {
|
||||||
|
if( !getUIMethodInitialized ) {
|
||||||
|
getUIMethodInitialized = true;
|
||||||
|
|
||||||
|
if( SystemInfo.isJava_9_orLater ) {
|
||||||
|
try {
|
||||||
|
// JComponent.getUI() is available since Java 9
|
||||||
|
getUIMethod = MethodHandles.lookup().findVirtual( JComponent.class, "getUI",
|
||||||
|
MethodType.methodType( ComponentUI.class ) );
|
||||||
|
} catch( Exception ex ) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
Object ui;
|
||||||
|
if( getUIMethod != null )
|
||||||
|
ui = getUIMethod.invoke( c );
|
||||||
|
else
|
||||||
|
ui = c.getClass().getMethod( "getUI" ).invoke( c );
|
||||||
|
return (ui instanceof StyleableUI) ? (StyleableUI) ui : null;
|
||||||
|
} catch( Throwable ex ) {
|
||||||
|
// ignore
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean getUIMethodInitialized;
|
||||||
|
private static MethodHandle getUIMethod;
|
||||||
|
|
||||||
//---- class FlatUIDefaults -----------------------------------------------
|
//---- class FlatUIDefaults -----------------------------------------------
|
||||||
|
|
||||||
private class FlatUIDefaults
|
private class FlatUIDefaults
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ public class FlatLightLaf
|
|||||||
/**
|
/**
|
||||||
* Sets the application look and feel to this LaF
|
* Sets the application look and feel to this LaF
|
||||||
* using {@link UIManager#setLookAndFeel(javax.swing.LookAndFeel)}.
|
* using {@link UIManager#setLookAndFeel(javax.swing.LookAndFeel)}.
|
||||||
|
*
|
||||||
|
* @since 1.2
|
||||||
*/
|
*/
|
||||||
public static boolean setup() {
|
public static boolean setup() {
|
||||||
return setup( new FlatLightLaf() );
|
return setup( new FlatLightLaf() );
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf;
|
package com.formdev.flatlaf;
|
||||||
|
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
import com.formdev.flatlaf.util.UIScale;
|
import com.formdev.flatlaf.util.UIScale;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -140,9 +141,33 @@ public interface FlatSystemProperties
|
|||||||
String USE_TEXT_Y_CORRECTION = "flatlaf.useTextYCorrection";
|
String USE_TEXT_Y_CORRECTION = "flatlaf.useTextYCorrection";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies a directory in which the native FlatLaf library have been extracted.
|
* Specifies whether FlatLaf updates the UI when the system font changes.
|
||||||
|
* If {@code true}, {@link SwingUtilities#updateComponentTreeUI(java.awt.Component)}
|
||||||
|
* gets invoked for all windows if the system font has changed.
|
||||||
|
* This is the similar to when switching to another look and feel (theme).
|
||||||
|
* Applications that do not work correctly when switching look and feel,
|
||||||
|
* should disable this option to avoid corrupted UI.
|
||||||
|
* <p>
|
||||||
|
* <strong>Allowed Values</strong> {@code false} and {@code true}<br>
|
||||||
|
* <strong>Default</strong> {@code true}
|
||||||
|
* @since 2.5
|
||||||
|
*/
|
||||||
|
String UPDATE_UI_ON_SYSTEM_FONT_CHANGE = "flatlaf.updateUIOnSystemFontChange";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies a directory in which the native FlatLaf libraries have been extracted.
|
||||||
* The path can be absolute or relative to current application working directory.
|
* The path can be absolute or relative to current application working directory.
|
||||||
* This can be used to avoid extraction of the native libraries to the temporary directory at runtime.
|
* This can be used to avoid extraction of the native libraries to the temporary directory at runtime.
|
||||||
|
* <p>
|
||||||
|
* If the value is {@code "system"}, then {@link System#loadLibrary(String)} is
|
||||||
|
* used to load the native library.
|
||||||
|
* Searches for the native library in classloader of caller
|
||||||
|
* (using {@link ClassLoader#findLibrary(String)}) and in paths specified
|
||||||
|
* in system properties {@code sun.boot.library.path} and {@code java.library.path}.
|
||||||
|
* (supported since FlatLaf 2.6)
|
||||||
|
* <p>
|
||||||
|
* If the native library can not loaded from the given path (or via {@link System#loadLibrary(String)}),
|
||||||
|
* then the embedded native library is extracted to the temporary directory and loaded from there.
|
||||||
*
|
*
|
||||||
* @since 2
|
* @since 2
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -73,6 +73,8 @@ public class IntelliJTheme
|
|||||||
*
|
*
|
||||||
* The input stream is automatically closed.
|
* The input stream is automatically closed.
|
||||||
* Using a buffered input stream is not necessary.
|
* Using a buffered input stream is not necessary.
|
||||||
|
*
|
||||||
|
* @since 1.2
|
||||||
*/
|
*/
|
||||||
public static boolean setup( InputStream in ) {
|
public static boolean setup( InputStream in ) {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -312,7 +312,7 @@ debug*/
|
|||||||
if( window instanceof RootPaneContainer ) {
|
if( window instanceof RootPaneContainer ) {
|
||||||
JLayeredPane layeredPane = ((RootPaneContainer)window).getLayeredPane();
|
JLayeredPane layeredPane = ((RootPaneContainer)window).getLayeredPane();
|
||||||
setSize( layeredPane.getSize() );
|
setSize( layeredPane.getSize() );
|
||||||
layeredPane.add( this, new Integer( JLayeredPane.POPUP_LAYER + 1 ) );
|
layeredPane.add( this, Integer.valueOf( JLayeredPane.POPUP_LAYER + 1 ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1052,7 +1052,7 @@ class UIDefaultsLoader
|
|||||||
* the alpha of this color is used as weight to mix the two colors
|
* the alpha of this color is used as weight to mix the two colors
|
||||||
* - background: a background color (e.g. #f00) or a color function
|
* - background: a background color (e.g. #f00) or a color function
|
||||||
*/
|
*/
|
||||||
private static Object parseColorOver( List<String> params, Function<String, String> resolver, boolean reportError ) {
|
private static ColorUIResource parseColorOver( List<String> params, Function<String, String> resolver, boolean reportError ) {
|
||||||
String foregroundStr = params.get( 0 );
|
String foregroundStr = params.get( 0 );
|
||||||
String backgroundStr = params.get( 1 );
|
String backgroundStr = params.get( 1 );
|
||||||
|
|
||||||
@@ -1061,7 +1061,8 @@ class UIDefaultsLoader
|
|||||||
if( foreground == null || foreground.getAlpha() == 255 )
|
if( foreground == null || foreground.getAlpha() == 255 )
|
||||||
return foreground;
|
return foreground;
|
||||||
|
|
||||||
Color foreground2 = new Color( foreground.getRGB() );
|
// foreground color without alpha
|
||||||
|
ColorUIResource foreground2 = new ColorUIResource( foreground.getRGB() );
|
||||||
|
|
||||||
// parse background color
|
// parse background color
|
||||||
ColorUIResource background = (ColorUIResource) parseColorOrFunction( resolver.apply( backgroundStr ), resolver, reportError );
|
ColorUIResource background = (ColorUIResource) parseColorOrFunction( resolver.apply( backgroundStr ), resolver, reportError );
|
||||||
|
|||||||
@@ -49,6 +49,14 @@ public class FlatCapsLockIcon
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
public Object getStyleableValue( String key ) {
|
||||||
|
switch( key ) {
|
||||||
|
case "capsLockIconColor": return color;
|
||||||
|
default: return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void paintIcon( Component c, Graphics2D g ) {
|
protected void paintIcon( Component c, Graphics2D g ) {
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -172,6 +172,11 @@ public class FlatCheckBoxIcon
|
|||||||
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
public Object getStyleableValue( String key ) {
|
||||||
|
return FlatStylingSupport.getAnnotatedStyleableValue( this, key );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void paintIcon( Component c, Graphics2D g ) {
|
protected void paintIcon( Component c, Graphics2D g ) {
|
||||||
boolean indeterminate = isIndeterminate( c );
|
boolean indeterminate = isIndeterminate( c );
|
||||||
|
|||||||
@@ -59,6 +59,11 @@ public class FlatCheckBoxMenuItemIcon
|
|||||||
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
public Object getStyleableValue( String key ) {
|
||||||
|
return FlatStylingSupport.getAnnotatedStyleableValue( this, key );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void paintIcon( Component c, Graphics2D g2 ) {
|
protected void paintIcon( Component c, Graphics2D g2 ) {
|
||||||
boolean selected = (c instanceof AbstractButton) && ((AbstractButton)c).isSelected();
|
boolean selected = (c instanceof AbstractButton) && ((AbstractButton)c).isSelected();
|
||||||
|
|||||||
@@ -69,6 +69,11 @@ public class FlatClearIcon
|
|||||||
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
public Object getStyleableValue( String key ) {
|
||||||
|
return FlatStylingSupport.getAnnotatedStyleableValue( this, key );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void paintIcon( Component c, Graphics2D g ) {
|
protected void paintIcon( Component c, Graphics2D g ) {
|
||||||
if( !ignoreButtonState && c instanceof AbstractButton ) {
|
if( !ignoreButtonState && c instanceof AbstractButton ) {
|
||||||
|
|||||||
@@ -84,6 +84,11 @@ public class FlatHelpButtonIcon
|
|||||||
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
public Object getStyleableValue( String key ) {
|
||||||
|
return FlatStylingSupport.getAnnotatedStyleableValue( this, key );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void paintIcon( Component c, Graphics2D g2 ) {
|
protected void paintIcon( Component c, Graphics2D g2 ) {
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -61,6 +61,11 @@ public class FlatMenuArrowIcon
|
|||||||
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
public Object getStyleableValue( String key ) {
|
||||||
|
return FlatStylingSupport.getAnnotatedStyleableValue( this, key );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void paintIcon( Component c, Graphics2D g ) {
|
protected void paintIcon( Component c, Graphics2D g ) {
|
||||||
if( c != null && !c.getComponentOrientation().isLeftToRight() )
|
if( c != null && !c.getComponentOrientation().isLeftToRight() )
|
||||||
|
|||||||
@@ -67,6 +67,11 @@ public class FlatSearchIcon
|
|||||||
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
public Object getStyleableValue( String key ) {
|
||||||
|
return FlatStylingSupport.getAnnotatedStyleableValue( this, key );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void paintIcon( Component c, Graphics2D g ) {
|
protected void paintIcon( Component c, Graphics2D g ) {
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -76,6 +76,11 @@ public class FlatTabbedPaneCloseIcon
|
|||||||
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
public Object getStyleableValue( String key ) {
|
||||||
|
return FlatStylingSupport.getAnnotatedStyleableValue( this, key );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void paintIcon( Component c, Graphics2D g ) {
|
protected void paintIcon( Component c, Graphics2D g ) {
|
||||||
// paint background
|
// paint background
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import java.awt.Graphics2D;
|
|||||||
import java.awt.event.MouseAdapter;
|
import java.awt.event.MouseAdapter;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.plaf.UIResource;
|
import javax.swing.plaf.UIResource;
|
||||||
import javax.swing.plaf.basic.BasicArrowButton;
|
import javax.swing.plaf.basic.BasicArrowButton;
|
||||||
|
|
||||||
@@ -82,14 +83,18 @@ public class FlatArrowButton
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mousePressed( MouseEvent e ) {
|
public void mousePressed( MouseEvent e ) {
|
||||||
pressed = true;
|
if( SwingUtilities.isLeftMouseButton( e ) ) {
|
||||||
repaint();
|
pressed = true;
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mouseReleased( MouseEvent e ) {
|
public void mouseReleased( MouseEvent e ) {
|
||||||
pressed = false;
|
if( SwingUtilities.isLeftMouseButton( e ) ) {
|
||||||
repaint();
|
pressed = false;
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,6 +101,12 @@ public class FlatBorder
|
|||||||
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
@Override
|
||||||
|
public Object getStyleableValue( String key ) {
|
||||||
|
return FlatStylingSupport.getAnnotatedStyleableValue( this, key );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
|
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
|
||||||
Graphics2D g2 = (Graphics2D) g.create();
|
Graphics2D g2 = (Graphics2D) g.create();
|
||||||
|
|||||||
@@ -181,7 +181,7 @@ public class FlatButtonUI
|
|||||||
private AtomicBoolean borderShared;
|
private AtomicBoolean borderShared;
|
||||||
|
|
||||||
public static ComponentUI createUI( JComponent c ) {
|
public static ComponentUI createUI( JComponent c ) {
|
||||||
return FlatUIUtils.canUseSharedUI( c )
|
return FlatUIUtils.canUseSharedUI( c ) && !FlatUIUtils.needsLightAWTPeer( c )
|
||||||
? FlatUIUtils.createSharedUI( FlatButtonUI.class, () -> new FlatButtonUI( true ) )
|
? FlatUIUtils.createSharedUI( FlatButtonUI.class, () -> new FlatButtonUI( true ) )
|
||||||
: new FlatButtonUI( false );
|
: new FlatButtonUI( false );
|
||||||
}
|
}
|
||||||
@@ -193,6 +193,13 @@ public class FlatButtonUI
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void installUI( JComponent c ) {
|
public void installUI( JComponent c ) {
|
||||||
|
if( FlatUIUtils.needsLightAWTPeer( c ) )
|
||||||
|
FlatUIUtils.runWithLightAWTPeerUIDefaults( () -> installUIImpl( c ) );
|
||||||
|
else
|
||||||
|
installUIImpl( c );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void installUIImpl( JComponent c ) {
|
||||||
super.installUI( c );
|
super.installUI( c );
|
||||||
|
|
||||||
installStyle( (AbstractButton) c );
|
installStyle( (AbstractButton) c );
|
||||||
@@ -366,6 +373,18 @@ public class FlatButtonUI
|
|||||||
return infos;
|
return infos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
@Override
|
||||||
|
public Object getStyleableValue( JComponent c, String key ) {
|
||||||
|
if( key.startsWith( "help." ) ) {
|
||||||
|
return (helpButtonIcon instanceof FlatHelpButtonIcon)
|
||||||
|
? ((FlatHelpButtonIcon)helpButtonIcon).getStyleableValue( key.substring( "help.".length() ) )
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FlatStylingSupport.getAnnotatedStyleableValue( this, c.getBorder(), key );
|
||||||
|
}
|
||||||
|
|
||||||
static boolean isContentAreaFilled( Component c ) {
|
static boolean isContentAreaFilled( Component c ) {
|
||||||
return !(c instanceof AbstractButton) || ((AbstractButton)c).isContentAreaFilled();
|
return !(c instanceof AbstractButton) || ((AbstractButton)c).isContentAreaFilled();
|
||||||
}
|
}
|
||||||
@@ -617,6 +636,9 @@ public class FlatButtonUI
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected Color getBackgroundBase( JComponent c, boolean def ) {
|
protected Color getBackgroundBase( JComponent c, boolean def ) {
|
||||||
|
if( FlatUIUtils.isAWTPeer( c ) )
|
||||||
|
return background;
|
||||||
|
|
||||||
// use component background if explicitly set
|
// use component background if explicitly set
|
||||||
Color bg = c.getBackground();
|
Color bg = c.getBackground();
|
||||||
if( isCustomBackground( bg ) )
|
if( isCustomBackground( bg ) )
|
||||||
|
|||||||
@@ -16,18 +16,20 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf.ui;
|
package com.formdev.flatlaf.ui;
|
||||||
|
|
||||||
import java.awt.Color;
|
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
|
import java.lang.invoke.MethodHandles;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import javax.swing.Icon;
|
import javax.swing.Icon;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
import javax.swing.LookAndFeel;
|
import javax.swing.LookAndFeel;
|
||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
import javax.swing.plaf.basic.BasicCheckBoxMenuItemUI;
|
import javax.swing.plaf.basic.BasicCheckBoxMenuItemUI;
|
||||||
|
import javax.swing.plaf.basic.BasicMenuItemUI;
|
||||||
|
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableField;
|
||||||
|
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableLookupProvider;
|
||||||
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
|
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
|
||||||
import com.formdev.flatlaf.ui.FlatStylingSupport.UnknownStyleException;
|
|
||||||
import com.formdev.flatlaf.util.LoggingFacade;
|
import com.formdev.flatlaf.util.LoggingFacade;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -58,9 +60,15 @@ import com.formdev.flatlaf.util.LoggingFacade;
|
|||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
|
@StyleableField( cls=BasicMenuItemUI.class, key="selectionBackground" )
|
||||||
|
@StyleableField( cls=BasicMenuItemUI.class, key="selectionForeground" )
|
||||||
|
@StyleableField( cls=BasicMenuItemUI.class, key="disabledForeground" )
|
||||||
|
@StyleableField( cls=BasicMenuItemUI.class, key="acceleratorForeground" )
|
||||||
|
@StyleableField( cls=BasicMenuItemUI.class, key="acceleratorSelectionForeground" )
|
||||||
|
|
||||||
public class FlatCheckBoxMenuItemUI
|
public class FlatCheckBoxMenuItemUI
|
||||||
extends BasicCheckBoxMenuItemUI
|
extends BasicCheckBoxMenuItemUI
|
||||||
implements StyleableUI
|
implements StyleableUI, StyleableLookupProvider
|
||||||
{
|
{
|
||||||
private FlatMenuItemRenderer renderer;
|
private FlatMenuItemRenderer renderer;
|
||||||
private Map<String, Object> oldStyleValues;
|
private Map<String, Object> oldStyleValues;
|
||||||
@@ -119,29 +127,27 @@ public class FlatCheckBoxMenuItemUI
|
|||||||
|
|
||||||
/** @since 2 */
|
/** @since 2 */
|
||||||
protected Object applyStyleProperty( String key, Object value ) {
|
protected Object applyStyleProperty( String key, Object value ) {
|
||||||
try {
|
return FlatMenuItemUI.applyStyleProperty( menuItem, this, renderer, key, value );
|
||||||
return renderer.applyStyleProperty( key, value );
|
|
||||||
} catch ( UnknownStyleException ex ) {
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
|
|
||||||
Object oldValue;
|
|
||||||
switch( key ) {
|
|
||||||
// BasicMenuItemUI
|
|
||||||
case "selectionBackground": oldValue = selectionBackground; selectionBackground = (Color) value; return oldValue;
|
|
||||||
case "selectionForeground": oldValue = selectionForeground; selectionForeground = (Color) value; return oldValue;
|
|
||||||
case "disabledForeground": oldValue = disabledForeground; disabledForeground = (Color) value; return oldValue;
|
|
||||||
case "acceleratorForeground": oldValue = acceleratorForeground; acceleratorForeground = (Color) value; return oldValue;
|
|
||||||
case "acceleratorSelectionForeground": oldValue = acceleratorSelectionForeground; acceleratorSelectionForeground = (Color) value; return oldValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FlatStylingSupport.applyToAnnotatedObjectOrComponent( this, menuItem, key, value );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @since 2 */
|
/** @since 2 */
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Class<?>> getStyleableInfos( JComponent c ) {
|
public Map<String, Class<?>> getStyleableInfos( JComponent c ) {
|
||||||
return FlatMenuItemUI.getStyleableInfos( renderer );
|
return FlatMenuItemUI.getStyleableInfos( this, renderer );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
@Override
|
||||||
|
public Object getStyleableValue( JComponent c, String key ) {
|
||||||
|
return FlatMenuItemUI.getStyleableValue( this, renderer, key );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
@Override
|
||||||
|
public MethodHandles.Lookup getLookupForStyling() {
|
||||||
|
// MethodHandles.lookup() is caller sensitive and must be invoked in this class,
|
||||||
|
// otherwise it is not possible to access protected fields in JRE superclass
|
||||||
|
return MethodHandles.lookup();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ public class FlatCheckBoxUI
|
|||||||
extends FlatRadioButtonUI
|
extends FlatRadioButtonUI
|
||||||
{
|
{
|
||||||
public static ComponentUI createUI( JComponent c ) {
|
public static ComponentUI createUI( JComponent c ) {
|
||||||
return FlatUIUtils.canUseSharedUI( c )
|
return FlatUIUtils.canUseSharedUI( c ) && !FlatUIUtils.needsLightAWTPeer( c )
|
||||||
? FlatUIUtils.createSharedUI( FlatCheckBoxUI.class, () -> new FlatCheckBoxUI( true ) )
|
? FlatUIUtils.createSharedUI( FlatCheckBoxUI.class, () -> new FlatCheckBoxUI( true ) )
|
||||||
: new FlatCheckBoxUI( false );
|
: new FlatCheckBoxUI( false );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ import java.awt.event.MouseEvent;
|
|||||||
import java.awt.event.MouseListener;
|
import java.awt.event.MouseListener;
|
||||||
import java.awt.geom.Rectangle2D;
|
import java.awt.geom.Rectangle2D;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
|
import java.lang.invoke.MethodHandles;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import javax.swing.AbstractAction;
|
import javax.swing.AbstractAction;
|
||||||
@@ -70,6 +71,8 @@ import javax.swing.plaf.basic.BasicComboPopup;
|
|||||||
import javax.swing.plaf.basic.ComboPopup;
|
import javax.swing.plaf.basic.ComboPopup;
|
||||||
import javax.swing.text.JTextComponent;
|
import javax.swing.text.JTextComponent;
|
||||||
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
||||||
|
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableField;
|
||||||
|
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableLookupProvider;
|
||||||
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
|
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
|
||||||
import com.formdev.flatlaf.util.LoggingFacade;
|
import com.formdev.flatlaf.util.LoggingFacade;
|
||||||
import com.formdev.flatlaf.util.SystemInfo;
|
import com.formdev.flatlaf.util.SystemInfo;
|
||||||
@@ -117,9 +120,11 @@ import com.formdev.flatlaf.util.SystemInfo;
|
|||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
|
@StyleableField( cls=BasicComboBoxUI.class, key="padding" )
|
||||||
|
|
||||||
public class FlatComboBoxUI
|
public class FlatComboBoxUI
|
||||||
extends BasicComboBoxUI
|
extends BasicComboBoxUI
|
||||||
implements StyleableUI
|
implements StyleableUI, StyleableLookupProvider
|
||||||
{
|
{
|
||||||
@Styleable protected int minimumWidth;
|
@Styleable protected int minimumWidth;
|
||||||
@Styleable protected int editorColumns;
|
@Styleable protected int editorColumns;
|
||||||
@@ -127,6 +132,7 @@ public class FlatComboBoxUI
|
|||||||
@Styleable protected String arrowType;
|
@Styleable protected String arrowType;
|
||||||
protected boolean isIntelliJTheme;
|
protected boolean isIntelliJTheme;
|
||||||
|
|
||||||
|
private Color background;
|
||||||
@Styleable protected Color editableBackground;
|
@Styleable protected Color editableBackground;
|
||||||
@Styleable protected Color focusedBackground;
|
@Styleable protected Color focusedBackground;
|
||||||
@Styleable protected Color disabledBackground;
|
@Styleable protected Color disabledBackground;
|
||||||
@@ -160,6 +166,13 @@ public class FlatComboBoxUI
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void installUI( JComponent c ) {
|
public void installUI( JComponent c ) {
|
||||||
|
if( FlatUIUtils.needsLightAWTPeer( c ) )
|
||||||
|
FlatUIUtils.runWithLightAWTPeerUIDefaults( () -> installUIImpl( c ) );
|
||||||
|
else
|
||||||
|
installUIImpl( c );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void installUIImpl( JComponent c ) {
|
||||||
super.installUI( c );
|
super.installUI( c );
|
||||||
|
|
||||||
installStyle();
|
installStyle();
|
||||||
@@ -222,6 +235,7 @@ public class FlatComboBoxUI
|
|||||||
arrowType = UIManager.getString( "Component.arrowType" );
|
arrowType = UIManager.getString( "Component.arrowType" );
|
||||||
isIntelliJTheme = UIManager.getBoolean( "Component.isIntelliJTheme" );
|
isIntelliJTheme = UIManager.getBoolean( "Component.isIntelliJTheme" );
|
||||||
|
|
||||||
|
background = UIManager.getColor( "ComboBox.background" );
|
||||||
editableBackground = UIManager.getColor( "ComboBox.editableBackground" );
|
editableBackground = UIManager.getColor( "ComboBox.editableBackground" );
|
||||||
focusedBackground = UIManager.getColor( "ComboBox.focusedBackground" );
|
focusedBackground = UIManager.getColor( "ComboBox.focusedBackground" );
|
||||||
disabledBackground = UIManager.getColor( "ComboBox.disabledBackground" );
|
disabledBackground = UIManager.getColor( "ComboBox.disabledBackground" );
|
||||||
@@ -254,6 +268,7 @@ public class FlatComboBoxUI
|
|||||||
protected void uninstallDefaults() {
|
protected void uninstallDefaults() {
|
||||||
super.uninstallDefaults();
|
super.uninstallDefaults();
|
||||||
|
|
||||||
|
background = null;
|
||||||
editableBackground = null;
|
editableBackground = null;
|
||||||
focusedBackground = null;
|
focusedBackground = null;
|
||||||
disabledBackground = null;
|
disabledBackground = null;
|
||||||
@@ -293,11 +308,14 @@ public class FlatComboBoxUI
|
|||||||
// limit button width to height of a raw combobox (without insets)
|
// limit button width to height of a raw combobox (without insets)
|
||||||
FontMetrics fm = comboBox.getFontMetrics( comboBox.getFont() );
|
FontMetrics fm = comboBox.getFontMetrics( comboBox.getFont() );
|
||||||
int maxButtonWidth = fm.getHeight() + scale( padding.top ) + scale( padding.bottom );
|
int maxButtonWidth = fm.getHeight() + scale( padding.top ) + scale( padding.bottom );
|
||||||
|
int minButtonWidth = (maxButtonWidth * 3) / 4;
|
||||||
|
|
||||||
|
// make button square (except if width is limited)
|
||||||
Insets insets = getInsets();
|
Insets insets = getInsets();
|
||||||
int buttonWidth = Math.min( parent.getPreferredSize().height - insets.top - insets.bottom, maxButtonWidth );
|
int buttonWidth = Math.min( Math.max( parent.getHeight() - insets.top - insets.bottom, minButtonWidth ), maxButtonWidth );
|
||||||
|
|
||||||
if( buttonWidth != arrowButton.getWidth() ) {
|
if( buttonWidth != arrowButton.getWidth() ) {
|
||||||
// set width of arrow button to preferred height of combobox
|
// set width of arrow button
|
||||||
int xOffset = comboBox.getComponentOrientation().isLeftToRight()
|
int xOffset = comboBox.getComponentOrientation().isLeftToRight()
|
||||||
? arrowButton.getWidth() - buttonWidth
|
? arrowButton.getWidth() - buttonWidth
|
||||||
: 0;
|
: 0;
|
||||||
@@ -491,13 +509,6 @@ public class FlatComboBoxUI
|
|||||||
|
|
||||||
/** @since 2 */
|
/** @since 2 */
|
||||||
protected Object applyStyleProperty( String key, Object value ) {
|
protected Object applyStyleProperty( String key, Object value ) {
|
||||||
// BasicComboBoxUI
|
|
||||||
if( key.equals( "padding" ) ) {
|
|
||||||
Object oldValue = padding;
|
|
||||||
padding = (Insets) value;
|
|
||||||
return oldValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( borderShared == null )
|
if( borderShared == null )
|
||||||
borderShared = new AtomicBoolean( true );
|
borderShared = new AtomicBoolean( true );
|
||||||
return FlatStylingSupport.applyToAnnotatedObjectOrBorder( this, key, value, comboBox, borderShared );
|
return FlatStylingSupport.applyToAnnotatedObjectOrBorder( this, key, value, comboBox, borderShared );
|
||||||
@@ -506,11 +517,21 @@ public class FlatComboBoxUI
|
|||||||
/** @since 2 */
|
/** @since 2 */
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Class<?>> getStyleableInfos( JComponent c ) {
|
public Map<String, Class<?>> getStyleableInfos( JComponent c ) {
|
||||||
Map<String, Class<?>> infos = new FlatStylingSupport.StyleableInfosMap<>();
|
return FlatStylingSupport.getAnnotatedStyleableInfos( this, comboBox.getBorder() );
|
||||||
infos.put( "padding", Insets.class );
|
}
|
||||||
FlatStylingSupport.collectAnnotatedStyleableInfos( this, infos );
|
|
||||||
FlatStylingSupport.collectStyleableInfos( comboBox.getBorder(), infos );
|
/** @since 2.5 */
|
||||||
return infos;
|
@Override
|
||||||
|
public Object getStyleableValue( JComponent c, String key ) {
|
||||||
|
return FlatStylingSupport.getAnnotatedStyleableValue( this, comboBox.getBorder(), key );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
@Override
|
||||||
|
public MethodHandles.Lookup getLookupForStyling() {
|
||||||
|
// MethodHandles.lookup() is caller sensitive and must be invoked in this class,
|
||||||
|
// otherwise it is not possible to access protected fields in JRE superclass
|
||||||
|
return MethodHandles.lookup();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -623,6 +644,9 @@ public class FlatComboBoxUI
|
|||||||
|
|
||||||
protected Color getBackground( boolean enabled ) {
|
protected Color getBackground( boolean enabled ) {
|
||||||
if( enabled ) {
|
if( enabled ) {
|
||||||
|
if( FlatUIUtils.isAWTPeer( comboBox ) )
|
||||||
|
return background;
|
||||||
|
|
||||||
Color background = comboBox.getBackground();
|
Color background = comboBox.getBackground();
|
||||||
|
|
||||||
// always use explicitly set color
|
// always use explicitly set color
|
||||||
|
|||||||
@@ -107,6 +107,12 @@ public class FlatDropShadowBorder
|
|||||||
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
@Override
|
||||||
|
public Object getStyleableValue( String key ) {
|
||||||
|
return FlatStylingSupport.getAnnotatedStyleableValue( this, key );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
|
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
|
||||||
if( shadowSize <= 0 )
|
if( shadowSize <= 0 )
|
||||||
|
|||||||
@@ -209,6 +209,12 @@ public class FlatEditorPaneUI
|
|||||||
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
@Override
|
||||||
|
public Object getStyleableValue( JComponent c, String key ) {
|
||||||
|
return FlatStylingSupport.getAnnotatedStyleableValue( this, key );
|
||||||
|
}
|
||||||
|
|
||||||
private void updateBackground() {
|
private void updateBackground() {
|
||||||
FlatTextFieldUI.updateBackground( getComponent(), background,
|
FlatTextFieldUI.updateBackground( getComponent(), background,
|
||||||
disabledBackground, inactiveBackground,
|
disabledBackground, inactiveBackground,
|
||||||
|
|||||||
@@ -76,4 +76,9 @@ public class FlatEmptyBorder
|
|||||||
right = insets.right;
|
right = insets.right;
|
||||||
return oldInsets;
|
return oldInsets;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
public Insets getStyleableValue() {
|
||||||
|
return new Insets( top, left, bottom, right );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -151,9 +151,9 @@ import com.formdev.flatlaf.util.UIScale;
|
|||||||
*
|
*
|
||||||
* @uiDefault FileChooser.shortcuts.buttonSize Dimension optional; default is 84,64
|
* @uiDefault FileChooser.shortcuts.buttonSize Dimension optional; default is 84,64
|
||||||
* @uiDefault FileChooser.shortcuts.iconSize Dimension optional; default is 32,32
|
* @uiDefault FileChooser.shortcuts.iconSize Dimension optional; default is 32,32
|
||||||
* @uiDefault FileChooser.shortcuts.filesFunction Function<File[], File[]>
|
* @uiDefault FileChooser.shortcuts.filesFunction Function<File[], File[]>
|
||||||
* @uiDefault FileChooser.shortcuts.displayNameFunction Function<File, String>
|
* @uiDefault FileChooser.shortcuts.displayNameFunction Function<File, String>
|
||||||
* @uiDefault FileChooser.shortcuts.iconFunction Function<File, Icon>
|
* @uiDefault FileChooser.shortcuts.iconFunction Function<File, Icon>
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -179,6 +179,12 @@ public class FlatInternalFrameUI
|
|||||||
return FlatStylingSupport.getAnnotatedStyleableInfos( this, frame.getBorder() );
|
return FlatStylingSupport.getAnnotatedStyleableInfos( this, frame.getBorder() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
@Override
|
||||||
|
public Object getStyleableValue( JComponent c, String key ) {
|
||||||
|
return FlatStylingSupport.getAnnotatedStyleableValue( this, frame.getBorder(), key );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update( Graphics g, JComponent c ) {
|
public void update( Graphics g, JComponent c ) {
|
||||||
// The internal frame actually should be opaque and fill its background,
|
// The internal frame actually should be opaque and fill its background,
|
||||||
@@ -253,6 +259,23 @@ public class FlatInternalFrameUI
|
|||||||
return infos;
|
return infos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
@Override
|
||||||
|
public Object getStyleableValue( String key ) {
|
||||||
|
switch( key ) {
|
||||||
|
case "borderMargins": return getStyleableValue();
|
||||||
|
|
||||||
|
case "activeDropShadowColor": return activeDropShadowBorder.getStyleableValue( "shadowColor" );
|
||||||
|
case "activeDropShadowInsets": return activeDropShadowBorder.getStyleableValue( "shadowInsets" );
|
||||||
|
case "activeDropShadowOpacity": return activeDropShadowBorder.getStyleableValue( "shadowOpacity" );
|
||||||
|
case "inactiveDropShadowColor": return inactiveDropShadowBorder.getStyleableValue( "shadowColor" );
|
||||||
|
case "inactiveDropShadowInsets": return inactiveDropShadowBorder.getStyleableValue( "shadowInsets" );
|
||||||
|
case "inactiveDropShadowOpacity": return inactiveDropShadowBorder.getStyleableValue( "shadowOpacity" );
|
||||||
|
}
|
||||||
|
|
||||||
|
return FlatStylingSupport.getAnnotatedStyleableValue( this, key );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Insets getBorderInsets( Component c, Insets insets ) {
|
public Insets getBorderInsets( Component c, Insets insets ) {
|
||||||
if( c instanceof JInternalFrame && ((JInternalFrame)c).isMaximum() ) {
|
if( c instanceof JInternalFrame && ((JInternalFrame)c).isMaximum() ) {
|
||||||
|
|||||||
@@ -158,6 +158,12 @@ public class FlatLabelUI
|
|||||||
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
@Override
|
||||||
|
public Object getStyleableValue( JComponent c, String key ) {
|
||||||
|
return FlatStylingSupport.getAnnotatedStyleableValue( this, key );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether text contains HTML tags that use "absolute-size" keywords
|
* Checks whether text contains HTML tags that use "absolute-size" keywords
|
||||||
* (e.g. "x-large") for font-size in default style sheet
|
* (e.g. "x-large") for font-size in default style sheet
|
||||||
|
|||||||
@@ -90,6 +90,13 @@ public class FlatListUI
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void installUI( JComponent c ) {
|
public void installUI( JComponent c ) {
|
||||||
|
if( FlatUIUtils.needsLightAWTPeer( c ) )
|
||||||
|
FlatUIUtils.runWithLightAWTPeerUIDefaults( () -> installUIImpl( c ) );
|
||||||
|
else
|
||||||
|
installUIImpl( c );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void installUIImpl( JComponent c ) {
|
||||||
super.installUI( c );
|
super.installUI( c );
|
||||||
|
|
||||||
installStyle();
|
installStyle();
|
||||||
@@ -209,6 +216,12 @@ public class FlatListUI
|
|||||||
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
@Override
|
||||||
|
public Object getStyleableValue( JComponent c, String key ) {
|
||||||
|
return FlatStylingSupport.getAnnotatedStyleableValue( this, key );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Toggle selection colors from focused to inactive and vice versa.
|
* Toggle selection colors from focused to inactive and vice versa.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -51,6 +51,12 @@ public class FlatMenuBarBorder
|
|||||||
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
@Override
|
||||||
|
public Object getStyleableValue( String key ) {
|
||||||
|
return FlatStylingSupport.getAnnotatedStyleableValue( this, key );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
|
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
|
||||||
if( !showBottomSeparator( c ) )
|
if( !showBottomSeparator( c ) )
|
||||||
|
|||||||
@@ -76,6 +76,8 @@ public class FlatMenuBarUI
|
|||||||
|
|
||||||
// used in FlatMenuUI
|
// used in FlatMenuUI
|
||||||
/** @since 2 */ @Styleable protected Color hoverBackground;
|
/** @since 2 */ @Styleable protected Color hoverBackground;
|
||||||
|
/** @since 2.5 */ @Styleable protected Color selectionBackground;
|
||||||
|
/** @since 2.5 */ @Styleable protected Color selectionForeground;
|
||||||
/** @since 2 */ @Styleable protected Color underlineSelectionBackground;
|
/** @since 2 */ @Styleable protected Color underlineSelectionBackground;
|
||||||
/** @since 2 */ @Styleable protected Color underlineSelectionColor;
|
/** @since 2 */ @Styleable protected Color underlineSelectionColor;
|
||||||
/** @since 2 */ @Styleable protected int underlineSelectionHeight = -1;
|
/** @since 2 */ @Styleable protected int underlineSelectionHeight = -1;
|
||||||
@@ -174,6 +176,12 @@ public class FlatMenuBarUI
|
|||||||
return FlatStylingSupport.getAnnotatedStyleableInfos( this, menuBar.getBorder() );
|
return FlatStylingSupport.getAnnotatedStyleableInfos( this, menuBar.getBorder() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
@Override
|
||||||
|
public Object getStyleableValue( JComponent c, String key ) {
|
||||||
|
return FlatStylingSupport.getAnnotatedStyleableValue( this, menuBar.getBorder(), key );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update( Graphics g, JComponent c ) {
|
public void update( Graphics g, JComponent c ) {
|
||||||
// paint background
|
// paint background
|
||||||
|
|||||||
@@ -97,6 +97,7 @@ public class FlatMenuItemRenderer
|
|||||||
@Styleable protected int underlineSelectionHeight = UIManager.getInt( "MenuItem.underlineSelectionHeight" );
|
@Styleable protected int underlineSelectionHeight = UIManager.getInt( "MenuItem.underlineSelectionHeight" );
|
||||||
|
|
||||||
private boolean iconsShared = true;
|
private boolean iconsShared = true;
|
||||||
|
private final Font menuFont = UIManager.getFont( "Menu.font" );
|
||||||
|
|
||||||
protected FlatMenuItemRenderer( JMenuItem menuItem, Icon checkIcon, Icon arrowIcon,
|
protected FlatMenuItemRenderer( JMenuItem menuItem, Icon checkIcon, Icon arrowIcon,
|
||||||
Font acceleratorFont, String acceleratorDelimiter )
|
Font acceleratorFont, String acceleratorDelimiter )
|
||||||
@@ -169,6 +170,19 @@ public class FlatMenuItemRenderer
|
|||||||
return infos;
|
return infos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
public Object getStyleableValue( String key ) {
|
||||||
|
if( key.startsWith( "icon." ) ) {
|
||||||
|
String key2 = key.substring( "icon.".length() );
|
||||||
|
if( checkIcon instanceof FlatCheckBoxMenuItemIcon )
|
||||||
|
return ((FlatCheckBoxMenuItemIcon)checkIcon).getStyleableValue( key2 );
|
||||||
|
if( arrowIcon instanceof FlatMenuArrowIcon )
|
||||||
|
return ((FlatMenuArrowIcon)arrowIcon).getStyleableValue( key2 );
|
||||||
|
}
|
||||||
|
|
||||||
|
return FlatStylingSupport.getAnnotatedStyleableValue( this, key );
|
||||||
|
}
|
||||||
|
|
||||||
protected Dimension getPreferredMenuItemSize() {
|
protected Dimension getPreferredMenuItemSize() {
|
||||||
int width = 0;
|
int width = 0;
|
||||||
int height = 0;
|
int height = 0;
|
||||||
@@ -180,7 +194,8 @@ public class FlatMenuItemRenderer
|
|||||||
|
|
||||||
// layout icon and text
|
// layout icon and text
|
||||||
SwingUtilities.layoutCompoundLabel( menuItem,
|
SwingUtilities.layoutCompoundLabel( menuItem,
|
||||||
menuItem.getFontMetrics( menuItem.getFont() ), menuItem.getText(), getIconForLayout(),
|
menuItem.getFontMetrics( isTopLevelMenu ? getTopLevelFont() : menuItem.getFont() ),
|
||||||
|
menuItem.getText(), getIconForLayout(),
|
||||||
menuItem.getVerticalAlignment(), menuItem.getHorizontalAlignment(),
|
menuItem.getVerticalAlignment(), menuItem.getHorizontalAlignment(),
|
||||||
menuItem.getVerticalTextPosition(), menuItem.getHorizontalTextPosition(),
|
menuItem.getVerticalTextPosition(), menuItem.getHorizontalTextPosition(),
|
||||||
viewRect, iconRect, textRect, scale( menuItem.getIconTextGap() ) );
|
viewRect, iconRect, textRect, scale( menuItem.getIconTextGap() ) );
|
||||||
@@ -282,7 +297,8 @@ public class FlatMenuItemRenderer
|
|||||||
|
|
||||||
// layout icon and text
|
// layout icon and text
|
||||||
SwingUtilities.layoutCompoundLabel( menuItem,
|
SwingUtilities.layoutCompoundLabel( menuItem,
|
||||||
menuItem.getFontMetrics( menuItem.getFont() ), menuItem.getText(), getIconForLayout(),
|
menuItem.getFontMetrics( isTopLevelMenu ? getTopLevelFont() : menuItem.getFont() ),
|
||||||
|
menuItem.getText(), getIconForLayout(),
|
||||||
menuItem.getVerticalAlignment(), menuItem.getHorizontalAlignment(),
|
menuItem.getVerticalAlignment(), menuItem.getHorizontalAlignment(),
|
||||||
menuItem.getVerticalTextPosition(), menuItem.getHorizontalTextPosition(),
|
menuItem.getVerticalTextPosition(), menuItem.getHorizontalTextPosition(),
|
||||||
labelRect, iconRect, textRect, scale( menuItem.getIconTextGap() ) );
|
labelRect, iconRect, textRect, scale( menuItem.getIconTextGap() ) );
|
||||||
@@ -392,9 +408,10 @@ debug*/
|
|||||||
}
|
}
|
||||||
|
|
||||||
int mnemonicIndex = FlatLaf.isShowMnemonics() ? menuItem.getDisplayedMnemonicIndex() : -1;
|
int mnemonicIndex = FlatLaf.isShowMnemonics() ? menuItem.getDisplayedMnemonicIndex() : -1;
|
||||||
Color foreground = (isTopLevelMenu( menuItem ) ? menuItem.getParent() : menuItem).getForeground();
|
boolean isTopLevelMenu = isTopLevelMenu( menuItem );
|
||||||
|
Color foreground = (isTopLevelMenu ? menuItem.getParent() : menuItem).getForeground();
|
||||||
|
|
||||||
paintText( g, menuItem, textRect, text, mnemonicIndex, menuItem.getFont(),
|
paintText( g, menuItem, textRect, text, mnemonicIndex, isTopLevelMenu ? getTopLevelFont() : menuItem.getFont(),
|
||||||
foreground, isUnderlineSelection() ? foreground : selectionForeground, disabledForeground );
|
foreground, isUnderlineSelection() ? foreground : selectionForeground, disabledForeground );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -481,6 +498,15 @@ debug*/
|
|||||||
return "underline".equals( UIManager.getString( "MenuItem.selectionType" ) );
|
return "underline".equals( UIManager.getString( "MenuItem.selectionType" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Font getTopLevelFont() {
|
||||||
|
Font font = menuItem.getFont();
|
||||||
|
// menu item parent may be null if JMenu.isTopLevelMenu() is overridden
|
||||||
|
// and does not check parent (e.g. com.jidesoft.swing.JideMenu.isTopLevelMenu())
|
||||||
|
return (font != menuFont || menuItem.getParent() == null)
|
||||||
|
? font
|
||||||
|
: menuItem.getParent().getFont();
|
||||||
|
}
|
||||||
|
|
||||||
private Icon getIconForPainting() {
|
private Icon getIconForPainting() {
|
||||||
Icon icon = menuItem.getIcon();
|
Icon icon = menuItem.getIcon();
|
||||||
|
|
||||||
|
|||||||
@@ -16,16 +16,19 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf.ui;
|
package com.formdev.flatlaf.ui;
|
||||||
|
|
||||||
import java.awt.Color;
|
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
|
import java.lang.invoke.MethodHandles;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import javax.swing.Icon;
|
import javax.swing.Icon;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
|
import javax.swing.JMenuItem;
|
||||||
import javax.swing.LookAndFeel;
|
import javax.swing.LookAndFeel;
|
||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
import javax.swing.plaf.basic.BasicMenuItemUI;
|
import javax.swing.plaf.basic.BasicMenuItemUI;
|
||||||
|
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableField;
|
||||||
|
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableLookupProvider;
|
||||||
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
|
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
|
||||||
import com.formdev.flatlaf.ui.FlatStylingSupport.UnknownStyleException;
|
import com.formdev.flatlaf.ui.FlatStylingSupport.UnknownStyleException;
|
||||||
import com.formdev.flatlaf.util.LoggingFacade;
|
import com.formdev.flatlaf.util.LoggingFacade;
|
||||||
@@ -58,9 +61,15 @@ import com.formdev.flatlaf.util.LoggingFacade;
|
|||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
|
@StyleableField( cls=BasicMenuItemUI.class, key="selectionBackground" )
|
||||||
|
@StyleableField( cls=BasicMenuItemUI.class, key="selectionForeground" )
|
||||||
|
@StyleableField( cls=BasicMenuItemUI.class, key="disabledForeground" )
|
||||||
|
@StyleableField( cls=BasicMenuItemUI.class, key="acceleratorForeground" )
|
||||||
|
@StyleableField( cls=BasicMenuItemUI.class, key="acceleratorSelectionForeground" )
|
||||||
|
|
||||||
public class FlatMenuItemUI
|
public class FlatMenuItemUI
|
||||||
extends BasicMenuItemUI
|
extends BasicMenuItemUI
|
||||||
implements StyleableUI
|
implements StyleableUI, StyleableLookupProvider
|
||||||
{
|
{
|
||||||
private FlatMenuItemRenderer renderer;
|
private FlatMenuItemRenderer renderer;
|
||||||
private Map<String, Object> oldStyleValues;
|
private Map<String, Object> oldStyleValues;
|
||||||
@@ -119,42 +128,54 @@ public class FlatMenuItemUI
|
|||||||
|
|
||||||
/** @since 2 */
|
/** @since 2 */
|
||||||
protected Object applyStyleProperty( String key, Object value ) {
|
protected Object applyStyleProperty( String key, Object value ) {
|
||||||
|
return applyStyleProperty( menuItem, this, renderer, key, value );
|
||||||
|
}
|
||||||
|
|
||||||
|
static Object applyStyleProperty( JMenuItem menuItem, BasicMenuItemUI ui,
|
||||||
|
FlatMenuItemRenderer renderer, String key, Object value )
|
||||||
|
{
|
||||||
try {
|
try {
|
||||||
return renderer.applyStyleProperty( key, value );
|
return renderer.applyStyleProperty( key, value );
|
||||||
} catch ( UnknownStyleException ex ) {
|
} catch ( UnknownStyleException ex ) {
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
|
|
||||||
Object oldValue;
|
return FlatStylingSupport.applyToAnnotatedObjectOrComponent( ui, menuItem, key, value );
|
||||||
switch( key ) {
|
|
||||||
// BasicMenuItemUI
|
|
||||||
case "selectionBackground": oldValue = selectionBackground; selectionBackground = (Color) value; return oldValue;
|
|
||||||
case "selectionForeground": oldValue = selectionForeground; selectionForeground = (Color) value; return oldValue;
|
|
||||||
case "disabledForeground": oldValue = disabledForeground; disabledForeground = (Color) value; return oldValue;
|
|
||||||
case "acceleratorForeground": oldValue = acceleratorForeground; acceleratorForeground = (Color) value; return oldValue;
|
|
||||||
case "acceleratorSelectionForeground": oldValue = acceleratorSelectionForeground; acceleratorSelectionForeground = (Color) value; return oldValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FlatStylingSupport.applyToAnnotatedObjectOrComponent( this, menuItem, key, value );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @since 2 */
|
/** @since 2 */
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Class<?>> getStyleableInfos( JComponent c ) {
|
public Map<String, Class<?>> getStyleableInfos( JComponent c ) {
|
||||||
return getStyleableInfos( renderer );
|
return getStyleableInfos( this, renderer );
|
||||||
}
|
}
|
||||||
|
|
||||||
static Map<String, Class<?>> getStyleableInfos( FlatMenuItemRenderer renderer ) {
|
static Map<String, Class<?>> getStyleableInfos( BasicMenuItemUI ui, FlatMenuItemRenderer renderer ) {
|
||||||
Map<String, Class<?>> infos = new FlatStylingSupport.StyleableInfosMap<>();
|
Map<String, Class<?>> infos = FlatStylingSupport.getAnnotatedStyleableInfos( ui );
|
||||||
infos.put( "selectionBackground", Color.class );
|
|
||||||
infos.put( "selectionForeground", Color.class );
|
|
||||||
infos.put( "disabledForeground", Color.class );
|
|
||||||
infos.put( "acceleratorForeground", Color.class );
|
|
||||||
infos.put( "acceleratorSelectionForeground", Color.class );
|
|
||||||
infos.putAll( renderer.getStyleableInfos() );
|
infos.putAll( renderer.getStyleableInfos() );
|
||||||
return infos;
|
return infos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
@Override
|
||||||
|
public Object getStyleableValue( JComponent c, String key ) {
|
||||||
|
return getStyleableValue( this, renderer, key );
|
||||||
|
}
|
||||||
|
|
||||||
|
static Object getStyleableValue( BasicMenuItemUI ui, FlatMenuItemRenderer renderer, String key ) {
|
||||||
|
Object value = renderer.getStyleableValue( key );
|
||||||
|
if( value == null )
|
||||||
|
value = FlatStylingSupport.getAnnotatedStyleableValue( ui, key );
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
@Override
|
||||||
|
public MethodHandles.Lookup getLookupForStyling() {
|
||||||
|
// MethodHandles.lookup() is caller sensitive and must be invoked in this class,
|
||||||
|
// otherwise it is not possible to access protected fields in JRE superclass
|
||||||
|
return MethodHandles.lookup();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Dimension getPreferredMenuItemSize( JComponent c, Icon checkIcon, Icon arrowIcon, int defaultTextIconGap ) {
|
protected Dimension getPreferredMenuItemSize( JComponent c, Icon checkIcon, Icon arrowIcon, int defaultTextIconGap ) {
|
||||||
return renderer.getPreferredMenuItemSize();
|
return renderer.getPreferredMenuItemSize();
|
||||||
|
|||||||
@@ -20,8 +20,10 @@ import java.awt.Color;
|
|||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.Font;
|
import java.awt.Font;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
|
import java.awt.Rectangle;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
|
import java.lang.invoke.MethodHandles;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import javax.swing.ButtonModel;
|
import javax.swing.ButtonModel;
|
||||||
@@ -35,9 +37,11 @@ import javax.swing.UIManager;
|
|||||||
import javax.swing.event.MouseInputListener;
|
import javax.swing.event.MouseInputListener;
|
||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
import javax.swing.plaf.MenuBarUI;
|
import javax.swing.plaf.MenuBarUI;
|
||||||
|
import javax.swing.plaf.basic.BasicMenuItemUI;
|
||||||
import javax.swing.plaf.basic.BasicMenuUI;
|
import javax.swing.plaf.basic.BasicMenuUI;
|
||||||
|
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableField;
|
||||||
|
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableLookupProvider;
|
||||||
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
|
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
|
||||||
import com.formdev.flatlaf.ui.FlatStylingSupport.UnknownStyleException;
|
|
||||||
import com.formdev.flatlaf.util.LoggingFacade;
|
import com.formdev.flatlaf.util.LoggingFacade;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -72,15 +76,23 @@ import com.formdev.flatlaf.util.LoggingFacade;
|
|||||||
* <!-- FlatMenuRenderer -->
|
* <!-- FlatMenuRenderer -->
|
||||||
*
|
*
|
||||||
* @uiDefault MenuBar.hoverBackground Color
|
* @uiDefault MenuBar.hoverBackground Color
|
||||||
|
* @uiDefault MenuBar.selectionBackground Color
|
||||||
|
* @uiDefault MenuBar.selectionForeground Color
|
||||||
* @uiDefault MenuBar.underlineSelectionBackground Color
|
* @uiDefault MenuBar.underlineSelectionBackground Color
|
||||||
* @uiDefault MenuBar.underlineSelectionColor Color
|
* @uiDefault MenuBar.underlineSelectionColor Color
|
||||||
* @uiDefault MenuBar.underlineSelectionHeight int
|
* @uiDefault MenuBar.underlineSelectionHeight int
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
|
@StyleableField( cls=BasicMenuItemUI.class, key="selectionBackground" )
|
||||||
|
@StyleableField( cls=BasicMenuItemUI.class, key="selectionForeground" )
|
||||||
|
@StyleableField( cls=BasicMenuItemUI.class, key="disabledForeground" )
|
||||||
|
@StyleableField( cls=BasicMenuItemUI.class, key="acceleratorForeground" )
|
||||||
|
@StyleableField( cls=BasicMenuItemUI.class, key="acceleratorSelectionForeground" )
|
||||||
|
|
||||||
public class FlatMenuUI
|
public class FlatMenuUI
|
||||||
extends BasicMenuUI
|
extends BasicMenuUI
|
||||||
implements StyleableUI
|
implements StyleableUI, StyleableLookupProvider
|
||||||
{
|
{
|
||||||
private FlatMenuItemRenderer renderer;
|
private FlatMenuItemRenderer renderer;
|
||||||
private Map<String, Object> oldStyleValues;
|
private Map<String, Object> oldStyleValues;
|
||||||
@@ -166,29 +178,27 @@ public class FlatMenuUI
|
|||||||
|
|
||||||
/** @since 2 */
|
/** @since 2 */
|
||||||
protected Object applyStyleProperty( String key, Object value ) {
|
protected Object applyStyleProperty( String key, Object value ) {
|
||||||
try {
|
return FlatMenuItemUI.applyStyleProperty( menuItem, this, renderer, key, value );
|
||||||
return renderer.applyStyleProperty( key, value );
|
|
||||||
} catch ( UnknownStyleException ex ) {
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
|
|
||||||
Object oldValue;
|
|
||||||
switch( key ) {
|
|
||||||
// BasicMenuItemUI
|
|
||||||
case "selectionBackground": oldValue = selectionBackground; selectionBackground = (Color) value; return oldValue;
|
|
||||||
case "selectionForeground": oldValue = selectionForeground; selectionForeground = (Color) value; return oldValue;
|
|
||||||
case "disabledForeground": oldValue = disabledForeground; disabledForeground = (Color) value; return oldValue;
|
|
||||||
case "acceleratorForeground": oldValue = acceleratorForeground; acceleratorForeground = (Color) value; return oldValue;
|
|
||||||
case "acceleratorSelectionForeground": oldValue = acceleratorSelectionForeground; acceleratorSelectionForeground = (Color) value; return oldValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FlatStylingSupport.applyToAnnotatedObjectOrComponent( this, menuItem, key, value );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @since 2 */
|
/** @since 2 */
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Class<?>> getStyleableInfos( JComponent c ) {
|
public Map<String, Class<?>> getStyleableInfos( JComponent c ) {
|
||||||
return FlatMenuItemUI.getStyleableInfos( renderer );
|
return FlatMenuItemUI.getStyleableInfos( this, renderer );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
@Override
|
||||||
|
public Object getStyleableValue( JComponent c, String key ) {
|
||||||
|
return FlatMenuItemUI.getStyleableValue( this, renderer, key );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
@Override
|
||||||
|
public MethodHandles.Lookup getLookupForStyling() {
|
||||||
|
// MethodHandles.lookup() is caller sensitive and must be invoked in this class,
|
||||||
|
// otherwise it is not possible to access protected fields in JRE superclass
|
||||||
|
return MethodHandles.lookup();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -216,6 +226,8 @@ public class FlatMenuUI
|
|||||||
extends FlatMenuItemRenderer
|
extends FlatMenuItemRenderer
|
||||||
{
|
{
|
||||||
protected Color hoverBackground = UIManager.getColor( "MenuBar.hoverBackground" );
|
protected Color hoverBackground = UIManager.getColor( "MenuBar.hoverBackground" );
|
||||||
|
protected Color menuBarSelectionBackground = UIManager.getColor( "MenuBar.selectionBackground" );
|
||||||
|
protected Color menuBarSelectionForeground = UIManager.getColor( "MenuBar.selectionForeground" );
|
||||||
protected Color menuBarUnderlineSelectionBackground = FlatUIUtils.getUIColor( "MenuBar.underlineSelectionBackground", underlineSelectionBackground );
|
protected Color menuBarUnderlineSelectionBackground = FlatUIUtils.getUIColor( "MenuBar.underlineSelectionBackground", underlineSelectionBackground );
|
||||||
protected Color menuBarUnderlineSelectionColor = FlatUIUtils.getUIColor( "MenuBar.underlineSelectionColor", underlineSelectionColor );
|
protected Color menuBarUnderlineSelectionColor = FlatUIUtils.getUIColor( "MenuBar.underlineSelectionColor", underlineSelectionColor );
|
||||||
protected int menuBarUnderlineSelectionHeight = FlatUIUtils.getUIInt( "MenuBar.underlineSelectionHeight", underlineSelectionHeight );
|
protected int menuBarUnderlineSelectionHeight = FlatUIUtils.getUIInt( "MenuBar.underlineSelectionHeight", underlineSelectionHeight );
|
||||||
@@ -231,6 +243,10 @@ public class FlatMenuUI
|
|||||||
if( ((JMenu)menuItem).isTopLevelMenu() ) {
|
if( ((JMenu)menuItem).isTopLevelMenu() ) {
|
||||||
if( isUnderlineSelection() )
|
if( isUnderlineSelection() )
|
||||||
selectionBackground = getStyleFromMenuBarUI( ui -> ui.underlineSelectionBackground, menuBarUnderlineSelectionBackground );
|
selectionBackground = getStyleFromMenuBarUI( ui -> ui.underlineSelectionBackground, menuBarUnderlineSelectionBackground );
|
||||||
|
else {
|
||||||
|
selectionBackground = getStyleFromMenuBarUI( ui -> ui.selectionBackground,
|
||||||
|
menuBarSelectionBackground != null ? menuBarSelectionBackground : selectionBackground );
|
||||||
|
}
|
||||||
|
|
||||||
ButtonModel model = menuItem.getModel();
|
ButtonModel model = menuItem.getModel();
|
||||||
if( model.isRollover() && !model.isArmed() && !model.isSelected() && model.isEnabled() ) {
|
if( model.isRollover() && !model.isArmed() && !model.isSelected() && model.isEnabled() ) {
|
||||||
@@ -243,6 +259,16 @@ public class FlatMenuUI
|
|||||||
super.paintBackground( g, selectionBackground );
|
super.paintBackground( g, selectionBackground );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void paintText( Graphics g, Rectangle textRect, String text, Color selectionForeground, Color disabledForeground ) {
|
||||||
|
if( ((JMenu)menuItem).isTopLevelMenu() && !isUnderlineSelection() ) {
|
||||||
|
selectionForeground = getStyleFromMenuBarUI( ui -> ui.selectionForeground,
|
||||||
|
menuBarSelectionForeground != null ? menuBarSelectionForeground : selectionForeground );
|
||||||
|
}
|
||||||
|
|
||||||
|
super.paintText( g, textRect, text, selectionForeground, disabledForeground );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void paintUnderlineSelection( Graphics g, Color underlineSelectionColor, int underlineSelectionHeight ) {
|
protected void paintUnderlineSelection( Graphics g, Color underlineSelectionColor, int underlineSelectionHeight ) {
|
||||||
if( ((JMenu)menuItem).isTopLevelMenu() ) {
|
if( ((JMenu)menuItem).isTopLevelMenu() ) {
|
||||||
|
|||||||
@@ -48,13 +48,29 @@ class FlatNativeLibrary
|
|||||||
|
|
||||||
String libraryName;
|
String libraryName;
|
||||||
if( SystemInfo.isWindows_10_orLater && (SystemInfo.isX86 || SystemInfo.isX86_64) ) {
|
if( SystemInfo.isWindows_10_orLater && (SystemInfo.isX86 || SystemInfo.isX86_64) ) {
|
||||||
// Windows: requires Windows 10 (x86 or x86_64)
|
// Windows: requires Windows 10/11 (x86 or x86_64)
|
||||||
|
|
||||||
libraryName = "flatlaf-windows-x86";
|
libraryName = "flatlaf-windows-x86";
|
||||||
if( SystemInfo.isX86_64 )
|
if( SystemInfo.isX86_64 )
|
||||||
libraryName += "_64";
|
libraryName += "_64";
|
||||||
|
|
||||||
// load jawt native library
|
// In Java 8, load jawt.dll (part of JRE) explicitly because it
|
||||||
|
// is not found when running application with <jdk>/bin/java.exe.
|
||||||
|
// When using <jdk>/jre/bin/java.exe, it is found.
|
||||||
|
// jawt.dll is located in <jdk>/jre/bin/.
|
||||||
|
// Java 9 and later do not have this problem,
|
||||||
|
// but load jawt.dll anyway to be on the safe side.
|
||||||
|
loadJAWT();
|
||||||
|
} else if( SystemInfo.isLinux && SystemInfo.isX86_64 ) {
|
||||||
|
// Linux: requires x86_64
|
||||||
|
|
||||||
|
libraryName = "flatlaf-linux-x86_64";
|
||||||
|
|
||||||
|
// Load libjawt.so (part of JRE) explicitly because it is not found
|
||||||
|
// in all Java versions/distributions.
|
||||||
|
// E.g. not found in Java 13 and later from openjdk.java.net.
|
||||||
|
// There seems to be also differences between distributions.
|
||||||
|
// E.g. Adoptium Java 17 does not need this, but Java 17 from openjdk.java.net does.
|
||||||
loadJAWT();
|
loadJAWT();
|
||||||
} else
|
} else
|
||||||
return; // no native library available for current OS or CPU architecture
|
return; // no native library available for current OS or CPU architecture
|
||||||
@@ -66,34 +82,34 @@ class FlatNativeLibrary
|
|||||||
private static NativeLibrary createNativeLibrary( String libraryName ) {
|
private static NativeLibrary createNativeLibrary( String libraryName ) {
|
||||||
String libraryPath = System.getProperty( FlatSystemProperties.NATIVE_LIBRARY_PATH );
|
String libraryPath = System.getProperty( FlatSystemProperties.NATIVE_LIBRARY_PATH );
|
||||||
if( libraryPath != null ) {
|
if( libraryPath != null ) {
|
||||||
File libraryFile = new File( libraryPath, System.mapLibraryName( libraryName ) );
|
if( "system".equals( libraryPath ) ) {
|
||||||
if( libraryFile.exists() )
|
NativeLibrary library = new NativeLibrary( libraryName, true );
|
||||||
return new NativeLibrary( libraryFile, true );
|
if( library.isLoaded() )
|
||||||
else
|
return library;
|
||||||
|
|
||||||
|
LoggingFacade.INSTANCE.logSevere( "Did not find library " + libraryName + " in java.library.path, using extracted library instead", null );
|
||||||
|
} else {
|
||||||
|
File libraryFile = new File( libraryPath, System.mapLibraryName( libraryName ) );
|
||||||
|
if( libraryFile.exists() )
|
||||||
|
return new NativeLibrary( libraryFile, true );
|
||||||
|
|
||||||
LoggingFacade.INSTANCE.logSevere( "Did not find external library " + libraryFile + ", using extracted library instead", null );
|
LoggingFacade.INSTANCE.logSevere( "Did not find external library " + libraryFile + ", using extracted library instead", null );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new NativeLibrary( "com/formdev/flatlaf/natives/" + libraryName, null, true );
|
return new NativeLibrary( "com/formdev/flatlaf/natives/" + libraryName, null, true );
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void loadJAWT() {
|
private static void loadJAWT() {
|
||||||
if( SystemInfo.isJava_9_orLater )
|
|
||||||
return;
|
|
||||||
|
|
||||||
// In Java 8, load jawt.dll (part of JRE) explicitly because it
|
|
||||||
// is not found when running application with <jdk>/bin/java.exe.
|
|
||||||
// When using <jdk>/jre/bin/java.exe, it is found.
|
|
||||||
// jawt.dll is located in <jdk>/jre/bin/.
|
|
||||||
// Java 9 and later do not have this problem.
|
|
||||||
try {
|
try {
|
||||||
System.loadLibrary( "jawt" );
|
System.loadLibrary( "jawt" );
|
||||||
} catch( UnsatisfiedLinkError ex ) {
|
} catch( UnsatisfiedLinkError ex ) {
|
||||||
// log error only if native library jawt.dll not already loaded
|
// log error only if native library jawt.dll not already loaded
|
||||||
String message = ex.getMessage();
|
String message = ex.getMessage();
|
||||||
if( message == null || !message.contains( "already loaded in another classloader" ) )
|
if( message == null || !message.contains( "already loaded in another classloader" ) )
|
||||||
LoggingFacade.INSTANCE.logSevere( null, ex );
|
LoggingFacade.INSTANCE.logSevere( message, ex );
|
||||||
} catch( Exception ex ) {
|
} catch( Exception ex ) {
|
||||||
LoggingFacade.INSTANCE.logSevere( null, ex );
|
LoggingFacade.INSTANCE.logSevere( ex.getMessage(), ex );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,104 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2022 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 java.awt.Point;
|
||||||
|
import java.awt.Toolkit;
|
||||||
|
import java.awt.Window;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.awt.geom.AffineTransform;
|
||||||
|
import javax.swing.JDialog;
|
||||||
|
import javax.swing.JFrame;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Native methods for Linux.
|
||||||
|
* <p>
|
||||||
|
* <b>Note</b>: This is private API. Do not use!
|
||||||
|
*
|
||||||
|
* @author Karl Tauber
|
||||||
|
* @since 2.5
|
||||||
|
*/
|
||||||
|
class FlatNativeLinuxLibrary
|
||||||
|
{
|
||||||
|
static boolean isLoaded() {
|
||||||
|
return FlatNativeLibrary.isLoaded();
|
||||||
|
}
|
||||||
|
|
||||||
|
// direction for _NET_WM_MOVERESIZE message
|
||||||
|
// see https://specifications.freedesktop.org/wm-spec/wm-spec-latest.html
|
||||||
|
static final int MOVE = 8;
|
||||||
|
|
||||||
|
private static Boolean isXWindowSystem;
|
||||||
|
|
||||||
|
private static boolean isXWindowSystem() {
|
||||||
|
if( isXWindowSystem == null )
|
||||||
|
isXWindowSystem = Toolkit.getDefaultToolkit().getClass().getName().endsWith( ".XToolkit" );
|
||||||
|
return isXWindowSystem;
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean isWMUtilsSupported( Window window ) {
|
||||||
|
return hasCustomDecoration( window ) && isXWindowSystem() && isLoaded();
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean moveOrResizeWindow( Window window, MouseEvent e, int direction ) {
|
||||||
|
Point pt = scale( window, e.getLocationOnScreen() );
|
||||||
|
return xMoveOrResizeWindow( window, pt.x, pt.y, direction );
|
||||||
|
|
||||||
|
/*
|
||||||
|
try {
|
||||||
|
Class<?> cls = Class.forName( "com.formdev.flatlaf.natives.jna.linux.X11WmUtils" );
|
||||||
|
java.lang.reflect.Method m = cls.getMethod( "xMoveOrResizeWindow", Window.class, int.class, int.class, int.class );
|
||||||
|
return (Boolean) m.invoke( null, window, pt.x, pt.y, direction );
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean showWindowMenu( Window window, MouseEvent e ) {
|
||||||
|
Point pt = scale( window, e.getLocationOnScreen() );
|
||||||
|
return xShowWindowMenu( window, pt.x, pt.y );
|
||||||
|
|
||||||
|
/*
|
||||||
|
try {
|
||||||
|
Class<?> cls = Class.forName( "com.formdev.flatlaf.natives.jna.linux.X11WmUtils" );
|
||||||
|
java.lang.reflect.Method m = cls.getMethod( "xShowWindowMenu", Window.class, int.class, int.class );
|
||||||
|
return (Boolean) m.invoke( null, window, pt.x, pt.y );
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Point scale( Window window, Point pt ) {
|
||||||
|
AffineTransform transform = window.getGraphicsConfiguration().getDefaultTransform();
|
||||||
|
int x = (int) Math.round( pt.x * transform.getScaleX() );
|
||||||
|
int y = (int) Math.round( pt.y * transform.getScaleY() );
|
||||||
|
return new Point( x, y );
|
||||||
|
}
|
||||||
|
|
||||||
|
// X Window System
|
||||||
|
private static native boolean xMoveOrResizeWindow( Window window, int x, int y, int direction );
|
||||||
|
private static native boolean xShowWindowMenu( Window window, int x, int y );
|
||||||
|
|
||||||
|
private static boolean hasCustomDecoration( Window window ) {
|
||||||
|
return (window instanceof JFrame && JFrame.isDefaultLookAndFeelDecorated() && ((JFrame)window).isUndecorated()) ||
|
||||||
|
(window instanceof JDialog && JDialog.isDefaultLookAndFeelDecorated() && ((JDialog)window).isUndecorated());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -127,6 +127,12 @@ public class FlatPanelUI
|
|||||||
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
@Override
|
||||||
|
public Object getStyleableValue( JComponent c, String key ) {
|
||||||
|
return FlatStylingSupport.getAnnotatedStyleableValue( this, key );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update( Graphics g, JComponent c ) {
|
public void update( Graphics g, JComponent c ) {
|
||||||
// fill background
|
// fill background
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import java.awt.Toolkit;
|
|||||||
import java.awt.event.KeyAdapter;
|
import java.awt.event.KeyAdapter;
|
||||||
import java.awt.event.KeyEvent;
|
import java.awt.event.KeyEvent;
|
||||||
import java.awt.event.KeyListener;
|
import java.awt.event.KeyListener;
|
||||||
|
import java.beans.PropertyChangeEvent;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import javax.swing.Action;
|
import javax.swing.Action;
|
||||||
import javax.swing.ActionMap;
|
import javax.swing.ActionMap;
|
||||||
@@ -233,6 +234,14 @@ public class FlatPasswordFieldUI
|
|||||||
return infos;
|
return infos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getStyleableValue( JComponent c, String key ) {
|
||||||
|
if( key.equals( "capsLockIconColor" ) && capsLockIcon instanceof FlatCapsLockIcon )
|
||||||
|
return ((FlatCapsLockIcon)capsLockIcon).getStyleableValue( key );
|
||||||
|
|
||||||
|
return super.getStyleableValue( c, key );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public View create( Element elem ) {
|
public View create( Element elem ) {
|
||||||
return new PasswordView( elem );
|
return new PasswordView( elem );
|
||||||
@@ -283,6 +292,7 @@ public class FlatPasswordFieldUI
|
|||||||
protected void installRevealButton() {
|
protected void installRevealButton() {
|
||||||
if( showRevealButton ) {
|
if( showRevealButton ) {
|
||||||
revealButton = createRevealButton();
|
revealButton = createRevealButton();
|
||||||
|
updateRevealButton();
|
||||||
installLayout();
|
installLayout();
|
||||||
getComponent().add( revealButton );
|
getComponent().add( revealButton );
|
||||||
}
|
}
|
||||||
@@ -290,28 +300,64 @@ public class FlatPasswordFieldUI
|
|||||||
|
|
||||||
/** @since 2 */
|
/** @since 2 */
|
||||||
protected JToggleButton createRevealButton() {
|
protected JToggleButton createRevealButton() {
|
||||||
JToggleButton button = new JToggleButton( revealIcon );
|
JPasswordField c = (JPasswordField) getComponent();
|
||||||
|
JToggleButton button = new JToggleButton( revealIcon, !c.echoCharIsSet() );
|
||||||
button.setName( "PasswordField.revealButton" );
|
button.setName( "PasswordField.revealButton" );
|
||||||
prepareLeadingOrTrailingComponent( button );
|
prepareLeadingOrTrailingComponent( button );
|
||||||
button.putClientProperty( FlatClientProperties.STYLE_CLASS, "inTextField revealButton" );
|
button.putClientProperty( FlatClientProperties.STYLE_CLASS, "inTextField revealButton" );
|
||||||
if( FlatClientProperties.clientPropertyBoolean( getComponent(), KEY_REVEAL_SELECTED, false ) ) {
|
if( FlatClientProperties.clientPropertyBoolean( c, KEY_REVEAL_SELECTED, false ) ) {
|
||||||
button.setSelected( true );
|
button.setSelected( true );
|
||||||
updateEchoChar( true );
|
updateEchoChar( true );
|
||||||
}
|
}
|
||||||
button.addActionListener( e -> {
|
button.addActionListener( e -> {
|
||||||
boolean selected = button.isSelected();
|
boolean selected = button.isSelected();
|
||||||
updateEchoChar( selected );
|
updateEchoChar( selected );
|
||||||
getComponent().putClientProperty( KEY_REVEAL_SELECTED, selected );
|
c.putClientProperty( KEY_REVEAL_SELECTED, selected );
|
||||||
} );
|
} );
|
||||||
return button;
|
return button;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
protected void updateRevealButton() {
|
||||||
|
if( revealButton == null )
|
||||||
|
return;
|
||||||
|
|
||||||
|
JTextComponent c = getComponent();
|
||||||
|
boolean visible = c.isEnabled();
|
||||||
|
if( visible != revealButton.isVisible() ) {
|
||||||
|
revealButton.setVisible( visible );
|
||||||
|
c.revalidate();
|
||||||
|
c.repaint();
|
||||||
|
|
||||||
|
if( !visible ) {
|
||||||
|
revealButton.setSelected( false );
|
||||||
|
updateEchoChar( false );
|
||||||
|
getComponent().putClientProperty( KEY_REVEAL_SELECTED, null );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void propertyChange( PropertyChangeEvent e ) {
|
||||||
|
super.propertyChange( e );
|
||||||
|
|
||||||
|
switch( e.getPropertyName() ) {
|
||||||
|
case "enabled":
|
||||||
|
updateRevealButton();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void updateEchoChar( boolean selected ) {
|
private void updateEchoChar( boolean selected ) {
|
||||||
char newEchoChar = selected
|
char newEchoChar = selected
|
||||||
? 0
|
? 0
|
||||||
: (echoChar != null ? echoChar : '*');
|
: (echoChar != null ? echoChar : '*');
|
||||||
|
|
||||||
JPasswordField c = (JPasswordField) getComponent();
|
JPasswordField c = (JPasswordField) getComponent();
|
||||||
|
if( newEchoChar == c.getEchoChar() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// set echo char
|
||||||
LookAndFeel.installProperty( c, "echoChar", newEchoChar );
|
LookAndFeel.installProperty( c, "echoChar", newEchoChar );
|
||||||
|
|
||||||
// check whether was able to set echo char via LookAndFeel.installProperty()
|
// check whether was able to set echo char via LookAndFeel.installProperty()
|
||||||
|
|||||||
@@ -36,7 +36,9 @@ import java.awt.Window;
|
|||||||
import java.awt.event.ComponentEvent;
|
import java.awt.event.ComponentEvent;
|
||||||
import java.awt.event.ComponentListener;
|
import java.awt.event.ComponentListener;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.invoke.MethodHandle;
|
||||||
|
import java.lang.invoke.MethodHandles;
|
||||||
|
import java.lang.invoke.MethodType;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
import javax.swing.JLayeredPane;
|
import javax.swing.JLayeredPane;
|
||||||
@@ -64,8 +66,8 @@ import com.formdev.flatlaf.util.UIScale;
|
|||||||
public class FlatPopupFactory
|
public class FlatPopupFactory
|
||||||
extends PopupFactory
|
extends PopupFactory
|
||||||
{
|
{
|
||||||
private Method java8getPopupMethod;
|
private MethodHandle java8getPopupMethod;
|
||||||
private Method java9getPopupMethod;
|
private MethodHandle java9getPopupMethod;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Popup getPopup( Component owner, Component contents, int x, int y )
|
public Popup getPopup( Component owner, Component contents, int x, int y )
|
||||||
@@ -192,23 +194,25 @@ public class FlatPopupFactory
|
|||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
if( SystemInfo.isJava_9_orLater ) {
|
if( SystemInfo.isJava_9_orLater ) {
|
||||||
|
// Java 9: protected Popup getPopup( Component owner, Component contents, int x, int y, boolean isHeavyWeightPopup )
|
||||||
if( java9getPopupMethod == null ) {
|
if( java9getPopupMethod == null ) {
|
||||||
java9getPopupMethod = PopupFactory.class.getDeclaredMethod(
|
MethodType mt = MethodType.methodType( Popup.class, Component.class, Component.class, int.class, int.class, boolean.class );
|
||||||
"getPopup", Component.class, Component.class, int.class, int.class, boolean.class );
|
java9getPopupMethod = MethodHandles.lookup().findVirtual( PopupFactory.class, "getPopup", mt );
|
||||||
}
|
}
|
||||||
return (Popup) java9getPopupMethod.invoke( this, owner, contents, x, y, true );
|
return (Popup) java9getPopupMethod.invoke( this, owner, contents, x, y, true );
|
||||||
} else {
|
} else {
|
||||||
// Java 8
|
// Java 8: private Popup getPopup( Component owner, Component contents, int ownerX, int ownerY, int popupType )
|
||||||
if( java8getPopupMethod == null ) {
|
if( java8getPopupMethod == null ) {
|
||||||
java8getPopupMethod = PopupFactory.class.getDeclaredMethod(
|
Method m = PopupFactory.class.getDeclaredMethod(
|
||||||
"getPopup", Component.class, Component.class, int.class, int.class, int.class );
|
"getPopup", Component.class, Component.class, int.class, int.class, int.class );
|
||||||
java8getPopupMethod.setAccessible( true );
|
m.setAccessible( true );
|
||||||
|
java8getPopupMethod = MethodHandles.lookup().unreflect( m );
|
||||||
}
|
}
|
||||||
return (Popup) java8getPopupMethod.invoke( this, owner, contents, x, y, /*HEAVY_WEIGHT_POPUP*/ 2 );
|
return (Popup) java8getPopupMethod.invoke( this, owner, contents, x, y, /*HEAVY_WEIGHT_POPUP*/ 2 );
|
||||||
}
|
}
|
||||||
} catch( NoSuchMethodException | SecurityException | IllegalAccessException | InvocationTargetException ex ) {
|
} catch( Throwable ex ) {
|
||||||
// ignore
|
// fallback
|
||||||
return null;
|
return super.getPopup( owner, contents, x, y );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -66,6 +66,16 @@ public class FlatPopupMenuBorder
|
|||||||
return infos;
|
return infos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
@Override
|
||||||
|
public Object getStyleableValue( String key ) {
|
||||||
|
switch( key ) {
|
||||||
|
case "borderInsets": return getStyleableValue();
|
||||||
|
case "borderColor": return borderColor;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Color getLineColor() {
|
public Color getLineColor() {
|
||||||
return (borderColor != null) ? borderColor : super.getLineColor();
|
return (borderColor != null) ? borderColor : super.getLineColor();
|
||||||
|
|||||||
@@ -184,6 +184,12 @@ public class FlatPopupMenuUI
|
|||||||
return FlatStylingSupport.getAnnotatedStyleableInfos( this, popupMenu.getBorder() );
|
return FlatStylingSupport.getAnnotatedStyleableInfos( this, popupMenu.getBorder() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
@Override
|
||||||
|
public Object getStyleableValue( JComponent c, String key ) {
|
||||||
|
return FlatStylingSupport.getAnnotatedStyleableValue( this, popupMenu.getBorder(), key );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Popup getPopup( JPopupMenu popup, int x, int y ) {
|
public Popup getPopup( JPopupMenu popup, int x, int y ) {
|
||||||
// do not add scroller to combobox popups or to popups that already have a scroll pane
|
// do not add scroller to combobox popups or to popups that already have a scroll pane
|
||||||
|
|||||||
@@ -160,6 +160,12 @@ public class FlatProgressBarUI
|
|||||||
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
@Override
|
||||||
|
public Object getStyleableValue( JComponent c, String key ) {
|
||||||
|
return FlatStylingSupport.getAnnotatedStyleableValue( this, key );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Dimension getPreferredSize( JComponent c ) {
|
public Dimension getPreferredSize( JComponent c ) {
|
||||||
Dimension size = super.getPreferredSize( c );
|
Dimension size = super.getPreferredSize( c );
|
||||||
|
|||||||
@@ -16,18 +16,20 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf.ui;
|
package com.formdev.flatlaf.ui;
|
||||||
|
|
||||||
import java.awt.Color;
|
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
|
import java.lang.invoke.MethodHandles;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import javax.swing.Icon;
|
import javax.swing.Icon;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
import javax.swing.LookAndFeel;
|
import javax.swing.LookAndFeel;
|
||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
|
import javax.swing.plaf.basic.BasicMenuItemUI;
|
||||||
import javax.swing.plaf.basic.BasicRadioButtonMenuItemUI;
|
import javax.swing.plaf.basic.BasicRadioButtonMenuItemUI;
|
||||||
|
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableField;
|
||||||
|
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableLookupProvider;
|
||||||
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
|
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
|
||||||
import com.formdev.flatlaf.ui.FlatStylingSupport.UnknownStyleException;
|
|
||||||
import com.formdev.flatlaf.util.LoggingFacade;
|
import com.formdev.flatlaf.util.LoggingFacade;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -58,9 +60,15 @@ import com.formdev.flatlaf.util.LoggingFacade;
|
|||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
|
@StyleableField( cls=BasicMenuItemUI.class, key="selectionBackground" )
|
||||||
|
@StyleableField( cls=BasicMenuItemUI.class, key="selectionForeground" )
|
||||||
|
@StyleableField( cls=BasicMenuItemUI.class, key="disabledForeground" )
|
||||||
|
@StyleableField( cls=BasicMenuItemUI.class, key="acceleratorForeground" )
|
||||||
|
@StyleableField( cls=BasicMenuItemUI.class, key="acceleratorSelectionForeground" )
|
||||||
|
|
||||||
public class FlatRadioButtonMenuItemUI
|
public class FlatRadioButtonMenuItemUI
|
||||||
extends BasicRadioButtonMenuItemUI
|
extends BasicRadioButtonMenuItemUI
|
||||||
implements StyleableUI
|
implements StyleableUI, StyleableLookupProvider
|
||||||
{
|
{
|
||||||
private FlatMenuItemRenderer renderer;
|
private FlatMenuItemRenderer renderer;
|
||||||
private Map<String, Object> oldStyleValues;
|
private Map<String, Object> oldStyleValues;
|
||||||
@@ -119,29 +127,27 @@ public class FlatRadioButtonMenuItemUI
|
|||||||
|
|
||||||
/** @since 2 */
|
/** @since 2 */
|
||||||
protected Object applyStyleProperty( String key, Object value ) {
|
protected Object applyStyleProperty( String key, Object value ) {
|
||||||
try {
|
return FlatMenuItemUI.applyStyleProperty( menuItem, this, renderer, key, value );
|
||||||
return renderer.applyStyleProperty( key, value );
|
|
||||||
} catch ( UnknownStyleException ex ) {
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
|
|
||||||
Object oldValue;
|
|
||||||
switch( key ) {
|
|
||||||
// BasicMenuItemUI
|
|
||||||
case "selectionBackground": oldValue = selectionBackground; selectionBackground = (Color) value; return oldValue;
|
|
||||||
case "selectionForeground": oldValue = selectionForeground; selectionForeground = (Color) value; return oldValue;
|
|
||||||
case "disabledForeground": oldValue = disabledForeground; disabledForeground = (Color) value; return oldValue;
|
|
||||||
case "acceleratorForeground": oldValue = acceleratorForeground; acceleratorForeground = (Color) value; return oldValue;
|
|
||||||
case "acceleratorSelectionForeground": oldValue = acceleratorSelectionForeground; acceleratorSelectionForeground = (Color) value; return oldValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FlatStylingSupport.applyToAnnotatedObjectOrComponent( this, menuItem, key, value );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @since 2 */
|
/** @since 2 */
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Class<?>> getStyleableInfos( JComponent c ) {
|
public Map<String, Class<?>> getStyleableInfos( JComponent c ) {
|
||||||
return FlatMenuItemUI.getStyleableInfos( renderer );
|
return FlatMenuItemUI.getStyleableInfos( this, renderer );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
@Override
|
||||||
|
public Object getStyleableValue( JComponent c, String key ) {
|
||||||
|
return FlatMenuItemUI.getStyleableValue( this, renderer, key );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
@Override
|
||||||
|
public MethodHandles.Lookup getLookupForStyling() {
|
||||||
|
// MethodHandles.lookup() is caller sensitive and must be invoked in this class,
|
||||||
|
// otherwise it is not possible to access protected fields in JRE superclass
|
||||||
|
return MethodHandles.lookup();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -18,12 +18,16 @@ package com.formdev.flatlaf.ui;
|
|||||||
|
|
||||||
import static com.formdev.flatlaf.util.UIScale.scale;
|
import static com.formdev.flatlaf.util.UIScale.scale;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
|
import java.awt.Component;
|
||||||
import java.awt.Container;
|
import java.awt.Container;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.awt.Insets;
|
import java.awt.Insets;
|
||||||
import java.awt.Rectangle;
|
import java.awt.Rectangle;
|
||||||
|
import java.awt.event.MouseAdapter;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
import java.beans.PropertyChangeEvent;
|
import java.beans.PropertyChangeEvent;
|
||||||
|
import java.beans.PropertyChangeListener;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import javax.swing.AbstractButton;
|
import javax.swing.AbstractButton;
|
||||||
@@ -31,6 +35,7 @@ import javax.swing.CellRendererPane;
|
|||||||
import javax.swing.Icon;
|
import javax.swing.Icon;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
import javax.swing.LookAndFeel;
|
import javax.swing.LookAndFeel;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
import javax.swing.plaf.basic.BasicButtonListener;
|
import javax.swing.plaf.basic.BasicButtonListener;
|
||||||
@@ -78,7 +83,7 @@ public class FlatRadioButtonUI
|
|||||||
private Map<String, Object> oldStyleValues;
|
private Map<String, Object> oldStyleValues;
|
||||||
|
|
||||||
public static ComponentUI createUI( JComponent c ) {
|
public static ComponentUI createUI( JComponent c ) {
|
||||||
return FlatUIUtils.canUseSharedUI( c )
|
return FlatUIUtils.canUseSharedUI( c ) && !FlatUIUtils.needsLightAWTPeer( c )
|
||||||
? FlatUIUtils.createSharedUI( FlatRadioButtonUI.class, () -> new FlatRadioButtonUI( true ) )
|
? FlatUIUtils.createSharedUI( FlatRadioButtonUI.class, () -> new FlatRadioButtonUI( true ) )
|
||||||
: new FlatRadioButtonUI( false );
|
: new FlatRadioButtonUI( false );
|
||||||
}
|
}
|
||||||
@@ -90,11 +95,29 @@ public class FlatRadioButtonUI
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void installUI( JComponent c ) {
|
public void installUI( JComponent c ) {
|
||||||
|
if( FlatUIUtils.needsLightAWTPeer( c ) )
|
||||||
|
FlatUIUtils.runWithLightAWTPeerUIDefaults( () -> installUIImpl( c ) );
|
||||||
|
else
|
||||||
|
installUIImpl( c );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void installUIImpl( JComponent c ) {
|
||||||
super.installUI( c );
|
super.installUI( c );
|
||||||
|
|
||||||
|
if( FlatUIUtils.isAWTPeer( c ) )
|
||||||
|
AWTPeerMouseExitedFix.install( c );
|
||||||
|
|
||||||
installStyle( (AbstractButton) c );
|
installStyle( (AbstractButton) c );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void uninstallUI( JComponent c ) {
|
||||||
|
super.uninstallUI( c );
|
||||||
|
|
||||||
|
if( FlatUIUtils.isAWTPeer( c ) )
|
||||||
|
AWTPeerMouseExitedFix.uninstall( c );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void installDefaults( AbstractButton b ) {
|
public void installDefaults( AbstractButton b ) {
|
||||||
super.installDefaults( b );
|
super.installDefaults( b );
|
||||||
@@ -199,6 +222,19 @@ public class FlatRadioButtonUI
|
|||||||
return infos;
|
return infos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
@Override
|
||||||
|
public Object getStyleableValue( JComponent c, String key ) {
|
||||||
|
// style icon
|
||||||
|
if( key.startsWith( "icon." ) ) {
|
||||||
|
return (icon instanceof FlatCheckBoxIcon)
|
||||||
|
? ((FlatCheckBoxIcon)icon).getStyleableValue( key.substring( "icon.".length() ) )
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FlatStylingSupport.getAnnotatedStyleableValue( this, key );
|
||||||
|
}
|
||||||
|
|
||||||
private static final Insets tempInsets = new Insets( 0, 0, 0, 0 );
|
private static final Insets tempInsets = new Insets( 0, 0, 0, 0 );
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -308,4 +344,69 @@ public class FlatRadioButtonUI
|
|||||||
FlatRadioButtonUI.this.propertyChange( b, e );
|
FlatRadioButtonUI.this.propertyChange( b, e );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---- class AWTPeerMouseExitedFix ----------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hack for missing mouse-exited event for java.awt.Checkbox on macOS (to fix hover effect).
|
||||||
|
*
|
||||||
|
* On macOS, AWT components internally use Swing components.
|
||||||
|
* This is implemented in class sun.lwawt.LWCheckboxPeer, which uses
|
||||||
|
* a container component CheckboxDelegate that has a JCheckBox and a JRadioButton
|
||||||
|
* as children. Only one of them is visible.
|
||||||
|
*
|
||||||
|
* The reason that mouse-exited event is not sent to the JCheckBox or JRadioButton
|
||||||
|
* is that sun.lwawt.LWComponentPeer.createDelegateEvent() uses
|
||||||
|
* SwingUtilities.getDeepestComponentAt() to find the event target,
|
||||||
|
* which finds the container component CheckboxDelegate,
|
||||||
|
* which receives the mouse-exited event.
|
||||||
|
*
|
||||||
|
* This class adds listeners and forwards the mouse-exited event
|
||||||
|
* from CheckboxDelegate to JCheckBox or JRadioButton.
|
||||||
|
*/
|
||||||
|
private static class AWTPeerMouseExitedFix
|
||||||
|
extends MouseAdapter
|
||||||
|
implements PropertyChangeListener
|
||||||
|
{
|
||||||
|
private final JComponent button;
|
||||||
|
|
||||||
|
static void install( JComponent button ) {
|
||||||
|
AWTPeerMouseExitedFix l = new AWTPeerMouseExitedFix( button );
|
||||||
|
button.addPropertyChangeListener( "ancestor", l );
|
||||||
|
Container parent = button.getParent();
|
||||||
|
if( parent != null )
|
||||||
|
parent.addMouseListener( l );
|
||||||
|
}
|
||||||
|
|
||||||
|
static void uninstall( JComponent button ) {
|
||||||
|
for( PropertyChangeListener l : button.getPropertyChangeListeners( "ancestor" ) ) {
|
||||||
|
if( l instanceof AWTPeerMouseExitedFix ) {
|
||||||
|
button.removePropertyChangeListener( "ancestor", l );
|
||||||
|
Container parent = button.getParent();
|
||||||
|
if( parent != null )
|
||||||
|
parent.removeMouseListener( (AWTPeerMouseExitedFix) l );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AWTPeerMouseExitedFix( JComponent button ) {
|
||||||
|
this.button = button;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void propertyChange( PropertyChangeEvent e ) {
|
||||||
|
if( e.getOldValue() instanceof Component )
|
||||||
|
((Component)e.getOldValue()).removeMouseListener( this );
|
||||||
|
if( e.getNewValue() instanceof Component ) {
|
||||||
|
((Component)e.getNewValue()).removeMouseListener( this ); // avoid duplicate listeners
|
||||||
|
((Component)e.getNewValue()).addMouseListener( this );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseExited( MouseEvent e ) {
|
||||||
|
button.dispatchEvent( SwingUtilities.convertMouseEvent( e.getComponent(), e, button ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
package com.formdev.flatlaf.ui;
|
package com.formdev.flatlaf.ui;
|
||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
|
import java.awt.Container;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.awt.Insets;
|
import java.awt.Insets;
|
||||||
@@ -24,6 +25,7 @@ import java.awt.Rectangle;
|
|||||||
import java.awt.event.MouseAdapter;
|
import java.awt.event.MouseAdapter;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
|
import java.lang.invoke.MethodHandles;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import javax.swing.InputMap;
|
import javax.swing.InputMap;
|
||||||
@@ -36,9 +38,13 @@ import javax.swing.UIManager;
|
|||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
import javax.swing.plaf.basic.BasicScrollBarUI;
|
import javax.swing.plaf.basic.BasicScrollBarUI;
|
||||||
import com.formdev.flatlaf.FlatClientProperties;
|
import com.formdev.flatlaf.FlatClientProperties;
|
||||||
|
import com.formdev.flatlaf.FlatLaf;
|
||||||
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
||||||
|
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableField;
|
||||||
|
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableLookupProvider;
|
||||||
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
|
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
|
||||||
import com.formdev.flatlaf.util.LoggingFacade;
|
import com.formdev.flatlaf.util.LoggingFacade;
|
||||||
|
import com.formdev.flatlaf.util.SystemInfo;
|
||||||
import com.formdev.flatlaf.util.UIScale;
|
import com.formdev.flatlaf.util.UIScale;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -77,9 +83,15 @@ import com.formdev.flatlaf.util.UIScale;
|
|||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
|
@StyleableField( cls=BasicScrollBarUI.class, key="track", fieldName="trackColor" )
|
||||||
|
@StyleableField( cls=BasicScrollBarUI.class, key="thumb", fieldName="thumbColor" )
|
||||||
|
@StyleableField( cls=BasicScrollBarUI.class, key="width", fieldName="scrollBarWidth" )
|
||||||
|
@StyleableField( cls=BasicScrollBarUI.class, key="minimumThumbSize" )
|
||||||
|
@StyleableField( cls=BasicScrollBarUI.class, key="maximumThumbSize" )
|
||||||
|
|
||||||
public class FlatScrollBarUI
|
public class FlatScrollBarUI
|
||||||
extends BasicScrollBarUI
|
extends BasicScrollBarUI
|
||||||
implements StyleableUI
|
implements StyleableUI, StyleableLookupProvider
|
||||||
{
|
{
|
||||||
// overrides BasicScrollBarUI.supportsAbsolutePositioning (which is private)
|
// overrides BasicScrollBarUI.supportsAbsolutePositioning (which is private)
|
||||||
@Styleable protected boolean allowsAbsolutePositioning;
|
@Styleable protected boolean allowsAbsolutePositioning;
|
||||||
@@ -108,6 +120,7 @@ public class FlatScrollBarUI
|
|||||||
protected boolean hoverThumb;
|
protected boolean hoverThumb;
|
||||||
|
|
||||||
private Map<String, Object> oldStyleValues;
|
private Map<String, Object> oldStyleValues;
|
||||||
|
private boolean isAWTPeer;
|
||||||
|
|
||||||
public static ComponentUI createUI( JComponent c ) {
|
public static ComponentUI createUI( JComponent c ) {
|
||||||
return new FlatScrollBarUI();
|
return new FlatScrollBarUI();
|
||||||
@@ -221,6 +234,37 @@ public class FlatScrollBarUI
|
|||||||
}
|
}
|
||||||
SwingUtilities.replaceUIInputMap( scrollbar, JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, inputMap );
|
SwingUtilities.replaceUIInputMap( scrollbar, JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, inputMap );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case "ancestor":
|
||||||
|
// check whether scroll bar is used as AWT peer on macOS
|
||||||
|
if( SystemInfo.isMacOS ) {
|
||||||
|
Container p = scrollbar.getParent();
|
||||||
|
for( int i = 0; i < 2 && p != null; i++, p = p.getParent() ) {
|
||||||
|
if( FlatUIUtils.isAWTPeer( p ) ) {
|
||||||
|
// Used to disable hover, which does not work correctly
|
||||||
|
// because scroll bars do not receive mouse exited event.
|
||||||
|
// The scroll pane, including its scroll bars, is not part
|
||||||
|
// of the component hierarchy and does not receive mouse events
|
||||||
|
// directly. Instead LWComponentPeer receives mouse events
|
||||||
|
// and delegates them to peers, but entered/exited events
|
||||||
|
// are sent only for the whole scroll pane.
|
||||||
|
// Exited event is only sent when mouse leaves scroll pane.
|
||||||
|
// If mouse enters/exits scroll bar, no entered/exited events are sent.
|
||||||
|
isAWTPeer = true;
|
||||||
|
|
||||||
|
// if dark theme is active, reinstall using light theme
|
||||||
|
if( FlatLaf.isLafDark() ) {
|
||||||
|
FlatUIUtils.runWithLightAWTPeerUIDefaults( () -> {
|
||||||
|
JScrollBar scrollbar = this.scrollbar;
|
||||||
|
uninstallUI( scrollbar );
|
||||||
|
installUI( scrollbar );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -246,30 +290,27 @@ public class FlatScrollBarUI
|
|||||||
|
|
||||||
/** @since 2 */
|
/** @since 2 */
|
||||||
protected Object applyStyleProperty( String key, Object value ) {
|
protected Object applyStyleProperty( String key, Object value ) {
|
||||||
Object oldValue;
|
|
||||||
switch( key ) {
|
|
||||||
// BasicScrollBarUI
|
|
||||||
case "track": oldValue = trackColor; trackColor = (Color) value; return oldValue;
|
|
||||||
case "thumb": oldValue = thumbColor; thumbColor = (Color) value; return oldValue;
|
|
||||||
case "width": oldValue = scrollBarWidth; scrollBarWidth = (int) value; return oldValue;
|
|
||||||
case "minimumThumbSize": oldValue = minimumThumbSize; minimumThumbSize = (Dimension) value; return oldValue;
|
|
||||||
case "maximumThumbSize": oldValue = maximumThumbSize; maximumThumbSize = (Dimension) value; return oldValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FlatStylingSupport.applyToAnnotatedObjectOrComponent( this, scrollbar, key, value );
|
return FlatStylingSupport.applyToAnnotatedObjectOrComponent( this, scrollbar, key, value );
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @since 2 */
|
/** @since 2 */
|
||||||
@Override
|
@Override
|
||||||
public Map<String, Class<?>> getStyleableInfos( JComponent c ) {
|
public Map<String, Class<?>> getStyleableInfos( JComponent c ) {
|
||||||
Map<String, Class<?>> infos = new FlatStylingSupport.StyleableInfosMap<>();
|
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
||||||
infos.put( "track", Color.class );
|
}
|
||||||
infos.put( "thumb", Color.class );
|
|
||||||
infos.put( "width", int.class );
|
/** @since 2.5 */
|
||||||
infos.put( "minimumThumbSize", Dimension.class );
|
@Override
|
||||||
infos.put( "maximumThumbSize", Dimension.class );
|
public Object getStyleableValue( JComponent c, String key ) {
|
||||||
FlatStylingSupport.collectAnnotatedStyleableInfos( this, infos );
|
return FlatStylingSupport.getAnnotatedStyleableValue( this, key );
|
||||||
return infos;
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
@Override
|
||||||
|
public MethodHandles.Lookup getLookupForStyling() {
|
||||||
|
// MethodHandles.lookup() is caller sensitive and must be invoked in this class,
|
||||||
|
// otherwise it is not possible to access protected fields in JRE superclass
|
||||||
|
return MethodHandles.lookup();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -311,6 +352,9 @@ public class FlatScrollBarUI
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void paintTrack( Graphics g, JComponent c, Rectangle trackBounds ) {
|
protected void paintTrack( Graphics g, JComponent c, Rectangle trackBounds ) {
|
||||||
|
if( trackBounds.isEmpty() || !scrollbar.isEnabled() )
|
||||||
|
return;
|
||||||
|
|
||||||
g.setColor( getTrackColor( c, hoverTrack, isPressed && hoverTrack && !hoverThumb ) );
|
g.setColor( getTrackColor( c, hoverTrack, isPressed && hoverTrack && !hoverThumb ) );
|
||||||
paintTrackOrThumb( g, c, trackBounds, trackInsets, trackArc );
|
paintTrackOrThumb( g, c, trackBounds, trackInsets, trackArc );
|
||||||
}
|
}
|
||||||
@@ -357,7 +401,7 @@ public class FlatScrollBarUI
|
|||||||
Color trackColor = FlatUIUtils.deriveColor( this.trackColor, c.getBackground() );
|
Color trackColor = FlatUIUtils.deriveColor( this.trackColor, c.getBackground() );
|
||||||
return (pressed && pressedTrackColor != null)
|
return (pressed && pressedTrackColor != null)
|
||||||
? FlatUIUtils.deriveColor( pressedTrackColor, trackColor )
|
? FlatUIUtils.deriveColor( pressedTrackColor, trackColor )
|
||||||
: ((hover && hoverTrackColor != null)
|
: ((hover && hoverTrackColor != null && !isAWTPeer)
|
||||||
? FlatUIUtils.deriveColor( hoverTrackColor, trackColor )
|
? FlatUIUtils.deriveColor( hoverTrackColor, trackColor )
|
||||||
: trackColor);
|
: trackColor);
|
||||||
}
|
}
|
||||||
@@ -367,7 +411,7 @@ public class FlatScrollBarUI
|
|||||||
Color thumbColor = FlatUIUtils.deriveColor( this.thumbColor, trackColor );
|
Color thumbColor = FlatUIUtils.deriveColor( this.thumbColor, trackColor );
|
||||||
return (pressed && pressedThumbColor != null)
|
return (pressed && pressedThumbColor != null)
|
||||||
? FlatUIUtils.deriveColor( pressedThumbColor, thumbColor )
|
? FlatUIUtils.deriveColor( pressedThumbColor, thumbColor )
|
||||||
: ((hover && hoverThumbColor != null)
|
: ((hover && hoverThumbColor != null && !isAWTPeer)
|
||||||
? FlatUIUtils.deriveColor( hoverThumbColor, thumbColor )
|
? FlatUIUtils.deriveColor( hoverThumbColor, thumbColor )
|
||||||
: thumbColor);
|
: thumbColor);
|
||||||
}
|
}
|
||||||
@@ -411,18 +455,31 @@ public class FlatScrollBarUI
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mousePressed( MouseEvent e ) {
|
public void mousePressed( MouseEvent e ) {
|
||||||
isPressed = true;
|
if( SwingUtilities.isLeftMouseButton( e ) || isAbsolutePositioning( e ) ) {
|
||||||
repaint();
|
isPressed = true;
|
||||||
|
repaint();
|
||||||
|
|
||||||
|
// update hover because BasicScrollBarUI.TrackListener.mousePressed()
|
||||||
|
// moves the track on middle-click (if absolute positioning is enabled)
|
||||||
|
if( isAbsolutePositioning( e ) )
|
||||||
|
update( e.getX(), e.getY() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mouseReleased( MouseEvent e ) {
|
public void mouseReleased( MouseEvent e ) {
|
||||||
isPressed = false;
|
if( SwingUtilities.isLeftMouseButton( e ) || isAbsolutePositioning( e ) ) {
|
||||||
repaint();
|
isPressed = false;
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
|
||||||
update( e.getX(), e.getY() );
|
update( e.getX(), e.getY() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isAbsolutePositioning( MouseEvent e ) {
|
||||||
|
return getSupportsAbsolutePositioning() && SwingUtilities.isMiddleMouseButton( e );
|
||||||
|
}
|
||||||
|
|
||||||
private void update( int x, int y ) {
|
private void update( int x, int y ) {
|
||||||
boolean inTrack = getTrackBounds().contains( x, y );
|
boolean inTrack = getTrackBounds().contains( x, y );
|
||||||
boolean inThumb = getThumbBounds().contains( x, y );
|
boolean inThumb = getThumbBounds().contains( x, y );
|
||||||
|
|||||||
@@ -87,6 +87,13 @@ public class FlatScrollPaneUI
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void installUI( JComponent c ) {
|
public void installUI( JComponent c ) {
|
||||||
|
if( FlatUIUtils.needsLightAWTPeer( c ) )
|
||||||
|
FlatUIUtils.runWithLightAWTPeerUIDefaults( () -> installUIImpl( c ) );
|
||||||
|
else
|
||||||
|
installUIImpl( c );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void installUIImpl( JComponent c ) {
|
||||||
super.installUI( c );
|
super.installUI( c );
|
||||||
|
|
||||||
int focusWidth = UIManager.getInt( "Component.focusWidth" );
|
int focusWidth = UIManager.getInt( "Component.focusWidth" );
|
||||||
@@ -343,6 +350,12 @@ public class FlatScrollPaneUI
|
|||||||
return FlatStylingSupport.getAnnotatedStyleableInfos( this, scrollpane.getBorder() );
|
return FlatStylingSupport.getAnnotatedStyleableInfos( this, scrollpane.getBorder() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
@Override
|
||||||
|
public Object getStyleableValue( JComponent c, String key ) {
|
||||||
|
return FlatStylingSupport.getAnnotatedStyleableValue( this, scrollpane.getBorder(), key );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void updateViewport( PropertyChangeEvent e ) {
|
protected void updateViewport( PropertyChangeEvent e ) {
|
||||||
super.updateViewport( e );
|
super.updateViewport( e );
|
||||||
|
|||||||
@@ -170,6 +170,12 @@ public class FlatSeparatorUI
|
|||||||
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
@Override
|
||||||
|
public Object getStyleableValue( JComponent c, String key ) {
|
||||||
|
return FlatStylingSupport.getAnnotatedStyleableValue( this, key );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void paint( Graphics g, JComponent c ) {
|
public void paint( Graphics g, JComponent c ) {
|
||||||
Graphics2D g2 = (Graphics2D) g.create();
|
Graphics2D g2 = (Graphics2D) g.create();
|
||||||
|
|||||||
@@ -222,6 +222,12 @@ public class FlatSliderUI
|
|||||||
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
@Override
|
||||||
|
public Object getStyleableValue( JComponent c, String key ) {
|
||||||
|
return FlatStylingSupport.getAnnotatedStyleableValue( this, key );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getBaseline( JComponent c, int width, int height ) {
|
public int getBaseline( JComponent c, int width, int height ) {
|
||||||
if( c == null )
|
if( c == null )
|
||||||
|
|||||||
@@ -223,6 +223,12 @@ public class FlatSpinnerUI
|
|||||||
return FlatStylingSupport.getAnnotatedStyleableInfos( this, spinner.getBorder() );
|
return FlatStylingSupport.getAnnotatedStyleableInfos( this, spinner.getBorder() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
@Override
|
||||||
|
public Object getStyleableValue( JComponent c, String key ) {
|
||||||
|
return FlatStylingSupport.getAnnotatedStyleableValue( this, spinner.getBorder(), key );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected JComponent createEditor() {
|
protected JComponent createEditor() {
|
||||||
JComponent editor = super.createEditor();
|
JComponent editor = super.createEditor();
|
||||||
@@ -477,9 +483,10 @@ public class FlatSpinnerUI
|
|||||||
// limit buttons width to height of a raw spinner (without insets)
|
// limit buttons width to height of a raw spinner (without insets)
|
||||||
FontMetrics fm = spinner.getFontMetrics( spinner.getFont() );
|
FontMetrics fm = spinner.getFontMetrics( spinner.getFont() );
|
||||||
int maxButtonWidth = fm.getHeight() + scale( padding.top ) + scale( padding.bottom );
|
int maxButtonWidth = fm.getHeight() + scale( padding.top ) + scale( padding.bottom );
|
||||||
|
int minButtonWidth = (maxButtonWidth * 3) / 4;
|
||||||
|
|
||||||
// make button area square (if spinner has preferred height)
|
// make button area square (except if width is limited)
|
||||||
int buttonsWidth = Math.min( parent.getPreferredSize().height - insets.top - insets.bottom, maxButtonWidth );
|
int buttonsWidth = Math.min( Math.max( buttonsRect.height, minButtonWidth ), maxButtonWidth );
|
||||||
buttonsRect.width = buttonsWidth;
|
buttonsRect.width = buttonsWidth;
|
||||||
|
|
||||||
if( parent.getComponentOrientation().isLeftToRight() ) {
|
if( parent.getComponentOrientation().isLeftToRight() ) {
|
||||||
|
|||||||
@@ -183,6 +183,17 @@ public class FlatSplitPaneUI
|
|||||||
return infos;
|
return infos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
@Override
|
||||||
|
public Object getStyleableValue( JComponent c, String key ) {
|
||||||
|
if( divider instanceof FlatSplitPaneDivider ) {
|
||||||
|
Object value = ((FlatSplitPaneDivider)divider).getStyleableValue( key );
|
||||||
|
if( value != null )
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
return FlatStylingSupport.getAnnotatedStyleableValue( this, key );
|
||||||
|
}
|
||||||
|
|
||||||
//---- class FlatSplitPaneDivider -----------------------------------------
|
//---- class FlatSplitPaneDivider -----------------------------------------
|
||||||
|
|
||||||
protected class FlatSplitPaneDivider
|
protected class FlatSplitPaneDivider
|
||||||
@@ -200,20 +211,21 @@ public class FlatSplitPaneUI
|
|||||||
setLayout( new FlatDividerLayout() );
|
setLayout( new FlatDividerLayout() );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** @since 2 */
|
||||||
* @since 2
|
|
||||||
*/
|
|
||||||
protected Object applyStyleProperty( String key, Object value ) {
|
protected Object applyStyleProperty( String key, Object value ) {
|
||||||
return FlatStylingSupport.applyToAnnotatedObject( this, key, value );
|
return FlatStylingSupport.applyToAnnotatedObject( this, key, value );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/** @since 2 */
|
||||||
* @since 2
|
|
||||||
*/
|
|
||||||
public Map<String, Class<?>> getStyleableInfos() {
|
public Map<String, Class<?>> getStyleableInfos() {
|
||||||
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
public Object getStyleableValue( String key ) {
|
||||||
|
return FlatStylingSupport.getAnnotatedStyleableValue( this, key );
|
||||||
|
}
|
||||||
|
|
||||||
void updateStyle() {
|
void updateStyle() {
|
||||||
if( leftButton instanceof FlatOneTouchButton )
|
if( leftButton instanceof FlatOneTouchButton )
|
||||||
((FlatOneTouchButton)leftButton).updateStyle();
|
((FlatOneTouchButton)leftButton).updateStyle();
|
||||||
|
|||||||
@@ -18,9 +18,11 @@ package com.formdev.flatlaf.ui;
|
|||||||
|
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
import java.lang.annotation.ElementType;
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Repeatable;
|
||||||
import java.lang.annotation.Retention;
|
import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.lang.annotation.Target;
|
import java.lang.annotation.Target;
|
||||||
|
import java.lang.invoke.MethodHandles;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
@@ -63,15 +65,55 @@ public class FlatStylingSupport
|
|||||||
Class<?> type() default Void.class;
|
Class<?> type() default Void.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates that a field in the specified (super) class
|
||||||
|
* is intended to be used by FlatLaf styling support.
|
||||||
|
* <p>
|
||||||
|
* Use this annotation, instead of {@link Styleable}, to style fields
|
||||||
|
* in superclasses, where it is not possible to use {@link Styleable}.
|
||||||
|
* <p>
|
||||||
|
* Classes using this annotation may implement {@link StyleableLookupProvider}
|
||||||
|
* to give access to protected fields (in JRE) in modular applications.
|
||||||
|
*
|
||||||
|
* @since 2.5
|
||||||
|
*/
|
||||||
|
@Target(ElementType.TYPE)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Repeatable(StyleableFields.class)
|
||||||
|
public @interface StyleableField {
|
||||||
|
Class<?> cls();
|
||||||
|
String key();
|
||||||
|
String fieldName() default "";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Container annotation for {@link StyleableField}.
|
||||||
|
*
|
||||||
|
* @since 2.5
|
||||||
|
*/
|
||||||
|
@Target(ElementType.TYPE)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface StyleableFields {
|
||||||
|
StyleableField[] value();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/** @since 2 */
|
/** @since 2 */
|
||||||
public interface StyleableUI {
|
public interface StyleableUI {
|
||||||
Map<String, Class<?>> getStyleableInfos( JComponent c );
|
Map<String, Class<?>> getStyleableInfos( JComponent c );
|
||||||
|
/** @since 2.5 */ Object getStyleableValue( JComponent c, String key );
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @since 2 */
|
/** @since 2 */
|
||||||
public interface StyleableBorder {
|
public interface StyleableBorder {
|
||||||
Object applyStyleProperty( String key, Object value );
|
Object applyStyleProperty( String key, Object value );
|
||||||
Map<String, Class<?>> getStyleableInfos();
|
Map<String, Class<?>> getStyleableInfos();
|
||||||
|
/** @since 2.5 */ Object getStyleableValue( String key );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
public interface StyleableLookupProvider {
|
||||||
|
MethodHandles.Lookup getLookupForStyling();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -365,21 +407,25 @@ public class FlatStylingSupport
|
|||||||
public static Object applyToAnnotatedObject( Object obj, String key, Object value )
|
public static Object applyToAnnotatedObject( Object obj, String key, Object value )
|
||||||
throws UnknownStyleException, IllegalArgumentException
|
throws UnknownStyleException, IllegalArgumentException
|
||||||
{
|
{
|
||||||
String fieldName = key;
|
String fieldName = keyToFieldName( key );
|
||||||
int dotIndex = key.indexOf( '.' );
|
|
||||||
if( dotIndex >= 0 ) {
|
|
||||||
// remove first dot in key and change subsequent character to uppercase
|
|
||||||
fieldName = key.substring( 0, dotIndex )
|
|
||||||
+ Character.toUpperCase( key.charAt( dotIndex + 1 ) )
|
|
||||||
+ key.substring( dotIndex + 2 );
|
|
||||||
}
|
|
||||||
|
|
||||||
return applyToField( obj, fieldName, key, value, field -> {
|
return applyToField( obj, fieldName, key, value, field -> {
|
||||||
Styleable styleable = field.getAnnotation( Styleable.class );
|
Styleable styleable = field.getAnnotation( Styleable.class );
|
||||||
return styleable != null && styleable.dot() == (dotIndex >= 0);
|
return styleable != null && styleable.dot() == (fieldName != key);
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String keyToFieldName( String key ) {
|
||||||
|
int dotIndex = key.indexOf( '.' );
|
||||||
|
if( dotIndex < 0 )
|
||||||
|
return key;
|
||||||
|
|
||||||
|
// remove first dot in key and change subsequent character to uppercase
|
||||||
|
return key.substring( 0, dotIndex )
|
||||||
|
+ Character.toUpperCase( key.charAt( dotIndex + 1 ) )
|
||||||
|
+ key.substring( dotIndex + 2 );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Applies the given value to a field of the given object.
|
* Applies the given value to a field of the given object.
|
||||||
*
|
*
|
||||||
@@ -405,26 +451,17 @@ public class FlatStylingSupport
|
|||||||
for(;;) {
|
for(;;) {
|
||||||
try {
|
try {
|
||||||
Field f = cls.getDeclaredField( fieldName );
|
Field f = cls.getDeclaredField( fieldName );
|
||||||
if( predicate == null || predicate.test( f ) ) {
|
if( predicate == null || predicate.test( f ) )
|
||||||
if( !isValidField( f ) )
|
return applyToField( f, obj, value, false );
|
||||||
throw new IllegalArgumentException( "field '" + cls.getName() + "." + fieldName + "' is final or static" );
|
|
||||||
|
|
||||||
try {
|
|
||||||
// necessary to access protected fields in other packages
|
|
||||||
f.setAccessible( true );
|
|
||||||
|
|
||||||
// get old value and set new value
|
|
||||||
Object oldValue = f.get( obj );
|
|
||||||
f.set( obj, convertToEnum( value, f.getType() ) );
|
|
||||||
return oldValue;
|
|
||||||
} catch( IllegalAccessException ex ) {
|
|
||||||
throw new IllegalArgumentException( "failed to access field '" + cls.getName() + "." + fieldName + "'", ex );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch( NoSuchFieldException ex ) {
|
} catch( NoSuchFieldException ex ) {
|
||||||
// field not found in class --> try superclass
|
// field not found in class --> try superclass
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for( StyleableField styleableField : cls.getAnnotationsByType( StyleableField.class ) ) {
|
||||||
|
if( key.equals( styleableField.key() ) )
|
||||||
|
return applyToField( getStyleableField( styleableField ), obj, value, true );
|
||||||
|
}
|
||||||
|
|
||||||
cls = cls.getSuperclass();
|
cls = cls.getSuperclass();
|
||||||
if( cls == null )
|
if( cls == null )
|
||||||
throw new UnknownStyleException( key );
|
throw new UnknownStyleException( key );
|
||||||
@@ -437,11 +474,83 @@ public class FlatStylingSupport
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Object applyToField( Field f, Object obj, Object value, boolean useMethodHandles ) {
|
||||||
|
checkValidField( f );
|
||||||
|
|
||||||
|
if( useMethodHandles && obj instanceof StyleableLookupProvider ) {
|
||||||
|
try {
|
||||||
|
// use method handles to access protected fields in JRE in modular applications
|
||||||
|
MethodHandles.Lookup lookup = ((StyleableLookupProvider)obj).getLookupForStyling();
|
||||||
|
|
||||||
|
// get old value and set new value
|
||||||
|
Object oldValue = lookup.unreflectGetter( f ).invoke( obj );
|
||||||
|
lookup.unreflectSetter( f ).invoke( obj, convertToEnum( value, f.getType() ) );
|
||||||
|
return oldValue;
|
||||||
|
} catch( Throwable ex ) {
|
||||||
|
throw newFieldAccessFailed( f, ex );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// necessary to access protected fields in other packages
|
||||||
|
f.setAccessible( true );
|
||||||
|
|
||||||
|
// get old value and set new value
|
||||||
|
Object oldValue = f.get( obj );
|
||||||
|
f.set( obj, convertToEnum( value, f.getType() ) );
|
||||||
|
return oldValue;
|
||||||
|
} catch( IllegalAccessException ex ) {
|
||||||
|
throw newFieldAccessFailed( f, ex );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Object getFieldValue( Field f, Object obj, boolean useMethodHandles ) {
|
||||||
|
checkValidField( f );
|
||||||
|
|
||||||
|
if( useMethodHandles && obj instanceof StyleableLookupProvider ) {
|
||||||
|
// use method handles to access protected fields in JRE in modular applications
|
||||||
|
try {
|
||||||
|
MethodHandles.Lookup lookup = ((StyleableLookupProvider)obj).getLookupForStyling();
|
||||||
|
return lookup.unreflectGetter( f ).invoke( obj );
|
||||||
|
} catch( Throwable ex ) {
|
||||||
|
throw newFieldAccessFailed( f, ex );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
f.setAccessible( true );
|
||||||
|
return f.get( obj );
|
||||||
|
} catch( IllegalAccessException ex ) {
|
||||||
|
throw newFieldAccessFailed( f, ex );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IllegalArgumentException newFieldAccessFailed( Field f, Throwable ex ) {
|
||||||
|
return new IllegalArgumentException( "failed to access field '" + f.getDeclaringClass().getName() + "." + f.getName() + "'", ex );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void checkValidField( Field f ) {
|
||||||
|
if( !isValidField( f ) )
|
||||||
|
throw new IllegalArgumentException( "field '" + f.getDeclaringClass().getName() + "." + f.getName() + "' is final or static" );
|
||||||
|
}
|
||||||
|
|
||||||
private static boolean isValidField( Field f ) {
|
private static boolean isValidField( Field f ) {
|
||||||
int modifiers = f.getModifiers();
|
int modifiers = f.getModifiers();
|
||||||
return (modifiers & (Modifier.FINAL|Modifier.STATIC)) == 0 && !f.isSynthetic();
|
return (modifiers & (Modifier.FINAL|Modifier.STATIC)) == 0 && !f.isSynthetic();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Field getStyleableField( StyleableField styleableField ) {
|
||||||
|
String fieldName = styleableField.fieldName();
|
||||||
|
if( fieldName.isEmpty() )
|
||||||
|
fieldName = styleableField.key();
|
||||||
|
|
||||||
|
try {
|
||||||
|
return styleableField.cls().getDeclaredField( fieldName );
|
||||||
|
} catch( NoSuchFieldException ex ) {
|
||||||
|
throw new IllegalArgumentException( "field '" + styleableField.cls().getName() + "." + fieldName + "' not found", ex );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Applies the given value to a property of the given object.
|
* Applies the given value to a property of the given object.
|
||||||
* Works only for properties that have public getter and setter methods.
|
* Works only for properties that have public getter and setter methods.
|
||||||
@@ -628,6 +737,7 @@ public class FlatStylingSupport
|
|||||||
Class<?> cls = obj.getClass();
|
Class<?> cls = obj.getClass();
|
||||||
|
|
||||||
for(;;) {
|
for(;;) {
|
||||||
|
// find fields annotated with 'Styleable'
|
||||||
for( Field f : cls.getDeclaredFields() ) {
|
for( Field f : cls.getDeclaredFields() ) {
|
||||||
if( !isValidField( f ) )
|
if( !isValidField( f ) )
|
||||||
continue;
|
continue;
|
||||||
@@ -666,6 +776,20 @@ public class FlatStylingSupport
|
|||||||
infos.put( name, type );
|
infos.put( name, type );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// get fields specified in 'StyleableField' annotation
|
||||||
|
for( StyleableField styleableField : cls.getAnnotationsByType( StyleableField.class ) ) {
|
||||||
|
String name = styleableField.key();
|
||||||
|
|
||||||
|
// for the case that the same field name is used in a class and in
|
||||||
|
// one of its superclasses, do not process field in superclass
|
||||||
|
if( processedFields.contains( name ) )
|
||||||
|
continue;
|
||||||
|
processedFields.add( name );
|
||||||
|
|
||||||
|
Field f = getStyleableField( styleableField );
|
||||||
|
infos.put( name, f.getType() );
|
||||||
|
}
|
||||||
|
|
||||||
cls = cls.getSuperclass();
|
cls = cls.getSuperclass();
|
||||||
if( cls == null )
|
if( cls == null )
|
||||||
return;
|
return;
|
||||||
@@ -686,6 +810,52 @@ public class FlatStylingSupport
|
|||||||
infos.put( keyPrefix.concat( e.getKey() ), e.getValue() );
|
infos.put( keyPrefix.concat( e.getKey() ), e.getValue() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Object getAnnotatedStyleableValue( Object obj, String key ) {
|
||||||
|
String fieldName = keyToFieldName( key );
|
||||||
|
Class<?> cls = obj.getClass();
|
||||||
|
|
||||||
|
for(;;) {
|
||||||
|
try {
|
||||||
|
// find field annotated with 'Styleable'
|
||||||
|
Field f = cls.getDeclaredField( fieldName );
|
||||||
|
Styleable styleable = f.getAnnotation( Styleable.class );
|
||||||
|
if( styleable != null ) {
|
||||||
|
if( styleable.dot() != (fieldName != key) )
|
||||||
|
throw new IllegalArgumentException( "'Styleable.dot' on field '" + fieldName + "' does not match key '" + key + "'" );
|
||||||
|
if( styleable.type() != Void.class )
|
||||||
|
throw new IllegalArgumentException( "'Styleable.type' on field '" + fieldName + "' not supported" );
|
||||||
|
|
||||||
|
return getFieldValue( f, obj, false );
|
||||||
|
}
|
||||||
|
} catch( NoSuchFieldException ex ) {
|
||||||
|
// field not found in class --> try superclass
|
||||||
|
}
|
||||||
|
|
||||||
|
// find field specified in 'StyleableField' annotation
|
||||||
|
for( StyleableField styleableField : cls.getAnnotationsByType( StyleableField.class ) ) {
|
||||||
|
if( key.equals( styleableField.key() ) )
|
||||||
|
return getFieldValue( getStyleableField( styleableField ), obj, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
cls = cls.getSuperclass();
|
||||||
|
if( cls == null )
|
||||||
|
return null;
|
||||||
|
|
||||||
|
String superclassName = cls.getName();
|
||||||
|
if( superclassName.startsWith( "java." ) || superclassName.startsWith( "javax." ) )
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Object getAnnotatedStyleableValue( Object obj, Border border, String key ) {
|
||||||
|
if( border instanceof StyleableBorder ) {
|
||||||
|
Object value = ((StyleableBorder)border).getStyleableValue( key );
|
||||||
|
if( value != null )
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
return getAnnotatedStyleableValue( obj, key );
|
||||||
|
}
|
||||||
|
|
||||||
//---- class UnknownStyleException ----------------------------------------
|
//---- class UnknownStyleException ----------------------------------------
|
||||||
|
|
||||||
public static class UnknownStyleException
|
public static class UnknownStyleException
|
||||||
|
|||||||
@@ -145,7 +145,7 @@ import com.formdev.flatlaf.util.UIScale;
|
|||||||
* @uiDefault TabbedPane.showTabSeparators boolean
|
* @uiDefault TabbedPane.showTabSeparators boolean
|
||||||
* @uiDefault TabbedPane.tabSeparatorsFullHeight boolean
|
* @uiDefault TabbedPane.tabSeparatorsFullHeight boolean
|
||||||
* @uiDefault TabbedPane.hasFullBorder boolean
|
* @uiDefault TabbedPane.hasFullBorder boolean
|
||||||
* @uiDefault TabbedPane.activeTabBorder boolean
|
* @uiDefault TabbedPane.rotateTabRuns boolean
|
||||||
*
|
*
|
||||||
* @uiDefault TabbedPane.tabLayoutPolicy String wrap (default) or scroll
|
* @uiDefault TabbedPane.tabLayoutPolicy String wrap (default) or scroll
|
||||||
* @uiDefault TabbedPane.tabType String underlined (default) or card
|
* @uiDefault TabbedPane.tabType String underlined (default) or card
|
||||||
@@ -220,6 +220,7 @@ public class FlatTabbedPaneUI
|
|||||||
@Styleable protected boolean tabSeparatorsFullHeight;
|
@Styleable protected boolean tabSeparatorsFullHeight;
|
||||||
@Styleable protected boolean hasFullBorder;
|
@Styleable protected boolean hasFullBorder;
|
||||||
@Styleable protected boolean tabsOpaque = true;
|
@Styleable protected boolean tabsOpaque = true;
|
||||||
|
/** @since 2.5 */ @Styleable protected boolean rotateTabRuns = true;
|
||||||
|
|
||||||
@Styleable(type=String.class) private int tabType;
|
@Styleable(type=String.class) private int tabType;
|
||||||
@Styleable(type=String.class) private int tabsPopupPolicy;
|
@Styleable(type=String.class) private int tabsPopupPolicy;
|
||||||
@@ -342,6 +343,7 @@ public class FlatTabbedPaneUI
|
|||||||
tabSeparatorsFullHeight = UIManager.getBoolean( "TabbedPane.tabSeparatorsFullHeight" );
|
tabSeparatorsFullHeight = UIManager.getBoolean( "TabbedPane.tabSeparatorsFullHeight" );
|
||||||
hasFullBorder = UIManager.getBoolean( "TabbedPane.hasFullBorder" );
|
hasFullBorder = UIManager.getBoolean( "TabbedPane.hasFullBorder" );
|
||||||
tabsOpaque = UIManager.getBoolean( "TabbedPane.tabsOpaque" );
|
tabsOpaque = UIManager.getBoolean( "TabbedPane.tabsOpaque" );
|
||||||
|
rotateTabRuns = FlatUIUtils.getUIBoolean( "TabbedPane.rotateTabRuns", true );
|
||||||
|
|
||||||
tabType = parseTabType( UIManager.getString( "TabbedPane.tabType" ) );
|
tabType = parseTabType( UIManager.getString( "TabbedPane.tabType" ) );
|
||||||
tabsPopupPolicy = parseTabsPopupPolicy( UIManager.getString( "TabbedPane.tabsPopupPolicy" ) );
|
tabsPopupPolicy = parseTabsPopupPolicy( UIManager.getString( "TabbedPane.tabsPopupPolicy" ) );
|
||||||
@@ -687,6 +689,76 @@ public class FlatTabbedPaneUI
|
|||||||
return infos;
|
return infos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
@Override
|
||||||
|
public Object getStyleableValue( JComponent c, String key ) {
|
||||||
|
// close icon
|
||||||
|
if( key.startsWith( "close" ) ) {
|
||||||
|
return (closeIcon instanceof FlatTabbedPaneCloseIcon)
|
||||||
|
? ((FlatTabbedPaneCloseIcon)closeIcon).getStyleableValue( key )
|
||||||
|
: null;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch( key ) {
|
||||||
|
// BasicTabbedPaneUI
|
||||||
|
case "tabInsets": return tabInsets;
|
||||||
|
case "tabAreaInsets": return tabAreaInsets;
|
||||||
|
case "textIconGap": return textIconGapUnscaled;
|
||||||
|
|
||||||
|
// FlatTabbedPaneUI
|
||||||
|
case "tabType":
|
||||||
|
switch( tabType ) {
|
||||||
|
default:
|
||||||
|
case TAB_TYPE_UNDERLINED: return TABBED_PANE_TAB_TYPE_UNDERLINED;
|
||||||
|
case TAB_TYPE_CARD: return TABBED_PANE_TAB_TYPE_CARD;
|
||||||
|
}
|
||||||
|
|
||||||
|
case "tabsPopupPolicy":
|
||||||
|
switch( tabsPopupPolicy ) {
|
||||||
|
default:
|
||||||
|
case AS_NEEDED: return TABBED_PANE_POLICY_AS_NEEDED;
|
||||||
|
case NEVER: return TABBED_PANE_POLICY_NEVER;
|
||||||
|
}
|
||||||
|
|
||||||
|
case "scrollButtonsPolicy":
|
||||||
|
switch( scrollButtonsPolicy ) {
|
||||||
|
default:
|
||||||
|
case AS_NEEDED_SINGLE: return TABBED_PANE_POLICY_AS_NEEDED_SINGLE;
|
||||||
|
case AS_NEEDED: return TABBED_PANE_POLICY_AS_NEEDED;
|
||||||
|
case NEVER: return TABBED_PANE_POLICY_NEVER;
|
||||||
|
}
|
||||||
|
|
||||||
|
case "scrollButtonsPlacement":
|
||||||
|
switch( scrollButtonsPlacement ) {
|
||||||
|
default:
|
||||||
|
case BOTH: return TABBED_PANE_PLACEMENT_BOTH;
|
||||||
|
case TRAILING: return TABBED_PANE_PLACEMENT_TRAILING;
|
||||||
|
}
|
||||||
|
|
||||||
|
case "tabAreaAlignment": return alignmentToString( tabAreaAlignment, TABBED_PANE_ALIGN_LEADING );
|
||||||
|
case "tabAlignment": return alignmentToString( tabAlignment, TABBED_PANE_ALIGN_CENTER );
|
||||||
|
|
||||||
|
case "tabWidthMode":
|
||||||
|
switch( tabWidthMode ) {
|
||||||
|
default:
|
||||||
|
case WIDTH_MODE_PREFERRED: return TABBED_PANE_TAB_WIDTH_MODE_PREFERRED;
|
||||||
|
case WIDTH_MODE_EQUAL: return TABBED_PANE_TAB_WIDTH_MODE_EQUAL;
|
||||||
|
case WIDTH_MODE_COMPACT: return TABBED_PANE_TAB_WIDTH_MODE_COMPACT;
|
||||||
|
}
|
||||||
|
|
||||||
|
case "tabIconPlacement":
|
||||||
|
switch( tabIconPlacement ) {
|
||||||
|
default:
|
||||||
|
case LEADING: return "leading";
|
||||||
|
case TRAILING: return "trailing";
|
||||||
|
case TOP: return "top";
|
||||||
|
case BOTTOM: return "bottom";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FlatStylingSupport.getAnnotatedStyleableValue( this, key );
|
||||||
|
}
|
||||||
|
|
||||||
protected void setRolloverTab( int x, int y ) {
|
protected void setRolloverTab( int x, int y ) {
|
||||||
setRolloverTab( tabForCoordinate( tabPane, x, y ) );
|
setRolloverTab( tabForCoordinate( tabPane, x, y ) );
|
||||||
}
|
}
|
||||||
@@ -1022,7 +1094,7 @@ public class FlatTabbedPaneUI
|
|||||||
|
|
||||||
// paint selection indicator
|
// paint selection indicator
|
||||||
if( isSelected )
|
if( isSelected )
|
||||||
paintTabSelection( g, tabPlacement, x, y, w, h );
|
paintTabSelection( g, tabPlacement, tabIndex, x, y, w, h );
|
||||||
|
|
||||||
if( tabPane.getTabComponentAt( tabIndex ) != null )
|
if( tabPane.getTabComponentAt( tabIndex ) != null )
|
||||||
return;
|
return;
|
||||||
@@ -1211,14 +1283,19 @@ public class FlatTabbedPaneUI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void paintTabSelection( Graphics g, int tabPlacement, int x, int y, int w, int h ) {
|
protected void paintTabSelection( Graphics g, int tabPlacement, int tabIndex, int x, int y, int w, int h ) {
|
||||||
g.setColor( tabPane.isEnabled()
|
g.setColor( tabPane.isEnabled()
|
||||||
? (isTabbedPaneOrChildFocused() ? underlineColor : inactiveUnderlineColor)
|
? (isTabbedPaneOrChildFocused() ? underlineColor : inactiveUnderlineColor)
|
||||||
: disabledUnderlineColor );
|
: disabledUnderlineColor );
|
||||||
|
|
||||||
// paint underline selection
|
// paint underline selection
|
||||||
boolean atBottom = (getTabType() != TAB_TYPE_CARD);
|
boolean atBottom = (getTabType() != TAB_TYPE_CARD);
|
||||||
Insets contentInsets = getContentBorderInsets( tabPlacement );
|
Insets contentInsets = atBottom
|
||||||
|
? ((!rotateTabRuns && runCount > 1 && !isScrollTabLayout() && getRunForTab( tabPane.getTabCount(), tabIndex ) > 0)
|
||||||
|
? new Insets( 0, 0, 0, 0 )
|
||||||
|
: getContentBorderInsets( tabPlacement ))
|
||||||
|
: null;
|
||||||
|
|
||||||
int tabSelectionHeight = scale( atBottom ? this.tabSelectionHeight : cardTabSelectionHeight );
|
int tabSelectionHeight = scale( atBottom ? this.tabSelectionHeight : cardTabSelectionHeight );
|
||||||
int sx, sy;
|
int sx, sy;
|
||||||
switch( tabPlacement ) {
|
switch( tabPlacement ) {
|
||||||
@@ -1377,7 +1454,7 @@ public class FlatTabbedPaneUI
|
|||||||
else
|
else
|
||||||
g.clipRect( 0, vr.y, tabPane.getWidth(), vr.height );
|
g.clipRect( 0, vr.y, tabPane.getWidth(), vr.height );
|
||||||
|
|
||||||
paintTabSelection( g, tabPlacement, tabRect.x, tabRect.y, tabRect.width, tabRect.height );
|
paintTabSelection( g, tabPlacement, selectedIndex, tabRect.x, tabRect.y, tabRect.width, tabRect.height );
|
||||||
g.setClip( oldClip );
|
g.setClip( oldClip );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1530,6 +1607,11 @@ public class FlatTabbedPaneUI
|
|||||||
super.getTabRunCount( tabPane );
|
super.getTabRunCount( tabPane );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean shouldRotateTabRuns( int tabPlacement ) {
|
||||||
|
return rotateTabRuns;
|
||||||
|
}
|
||||||
|
|
||||||
private boolean isLastInRun( int tabIndex ) {
|
private boolean isLastInRun( int tabIndex ) {
|
||||||
int run = getRunForTab( tabPane.getTabCount(), tabIndex );
|
int run = getRunForTab( tabPane.getTabCount(), tabIndex );
|
||||||
return lastTabInRun( tabPane.getTabCount(), run ) == tabIndex;
|
return lastTabInRun( tabPane.getTabCount(), run ) == tabIndex;
|
||||||
@@ -1685,6 +1767,16 @@ public class FlatTabbedPaneUI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String alignmentToString( int value, String defaultValue ) {
|
||||||
|
switch( value ) {
|
||||||
|
case LEADING: return TABBED_PANE_ALIGN_LEADING;
|
||||||
|
case TRAILING: return TABBED_PANE_ALIGN_TRAILING;
|
||||||
|
case CENTER: return TABBED_PANE_ALIGN_CENTER;
|
||||||
|
case FILL: return TABBED_PANE_ALIGN_FILL;
|
||||||
|
default: return defaultValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected static int parseTabWidthMode( String str ) {
|
protected static int parseTabWidthMode( String str ) {
|
||||||
if( str == null )
|
if( str == null )
|
||||||
return WIDTH_MODE_PREFERRED;
|
return WIDTH_MODE_PREFERRED;
|
||||||
@@ -2497,7 +2589,7 @@ public class FlatTabbedPaneUI
|
|||||||
public void mousePressed( MouseEvent e ) {
|
public void mousePressed( MouseEvent e ) {
|
||||||
updateRollover( e );
|
updateRollover( e );
|
||||||
|
|
||||||
if( !isPressedTabClose() )
|
if( !isPressedTabClose() && SwingUtilities.isLeftMouseButton( e ) )
|
||||||
mouseDelegate.mousePressed( e );
|
mouseDelegate.mousePressed( e );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2552,7 +2644,7 @@ public class FlatTabbedPaneUI
|
|||||||
|
|
||||||
// check whether mouse hit tab close area
|
// check whether mouse hit tab close area
|
||||||
boolean hitClose = isTabClosable( tabIndex ) && getTabCloseHitArea( tabIndex ).contains( x, y );
|
boolean hitClose = isTabClosable( tabIndex ) && getTabCloseHitArea( tabIndex ).contains( x, y );
|
||||||
if( e.getID() == MouseEvent.MOUSE_PRESSED )
|
if( e.getID() == MouseEvent.MOUSE_PRESSED && SwingUtilities.isLeftMouseButton( e ) )
|
||||||
pressedTabIndex = hitClose ? tabIndex : -1;
|
pressedTabIndex = hitClose ? tabIndex : -1;
|
||||||
setRolloverTabClose( hitClose );
|
setRolloverTabClose( hitClose );
|
||||||
setPressedTabClose( hitClose && tabIndex == pressedTabIndex );
|
setPressedTabClose( hitClose && tabIndex == pressedTabIndex );
|
||||||
|
|||||||
@@ -171,6 +171,22 @@ public class FlatTableHeaderUI
|
|||||||
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
@Override
|
||||||
|
public Object getStyleableValue( JComponent c, String key ) {
|
||||||
|
if( key.equals( "sortIconPosition" ) ) {
|
||||||
|
switch( sortIconPosition ) {
|
||||||
|
default:
|
||||||
|
case SwingConstants.RIGHT: return "right";
|
||||||
|
case SwingConstants.LEFT: return "left";
|
||||||
|
case SwingConstants.TOP: return "top";
|
||||||
|
case SwingConstants.BOTTOM: return "bottom";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FlatStylingSupport.getAnnotatedStyleableValue( this, key );
|
||||||
|
}
|
||||||
|
|
||||||
private static int parseSortIconPosition( String str ) {
|
private static int parseSortIconPosition( String str ) {
|
||||||
if( str == null )
|
if( str == null )
|
||||||
str = "";
|
str = "";
|
||||||
|
|||||||
@@ -286,6 +286,12 @@ public class FlatTableUI
|
|||||||
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
@Override
|
||||||
|
public Object getStyleableValue( JComponent c, String key ) {
|
||||||
|
return FlatStylingSupport.getAnnotatedStyleableValue( this, key );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Toggle selection colors from focused to inactive and vice versa.
|
* Toggle selection colors from focused to inactive and vice versa.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -86,6 +86,13 @@ public class FlatTextAreaUI
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void installUI( JComponent c ) {
|
public void installUI( JComponent c ) {
|
||||||
|
if( FlatUIUtils.needsLightAWTPeer( c ) )
|
||||||
|
FlatUIUtils.runWithLightAWTPeerUIDefaults( () -> installUIImpl( c ) );
|
||||||
|
else
|
||||||
|
installUIImpl( c );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void installUIImpl( JComponent c ) {
|
||||||
super.installUI( c );
|
super.installUI( c );
|
||||||
|
|
||||||
installStyle();
|
installStyle();
|
||||||
@@ -183,6 +190,12 @@ public class FlatTextAreaUI
|
|||||||
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
@Override
|
||||||
|
public Object getStyleableValue( JComponent c, String key ) {
|
||||||
|
return FlatStylingSupport.getAnnotatedStyleableValue( this, key );
|
||||||
|
}
|
||||||
|
|
||||||
private void updateBackground() {
|
private void updateBackground() {
|
||||||
FlatTextFieldUI.updateBackground( getComponent(), background,
|
FlatTextFieldUI.updateBackground( getComponent(), background,
|
||||||
disabledBackground, inactiveBackground,
|
disabledBackground, inactiveBackground,
|
||||||
|
|||||||
@@ -128,6 +128,13 @@ public class FlatTextFieldUI
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void installUI( JComponent c ) {
|
public void installUI( JComponent c ) {
|
||||||
|
if( FlatUIUtils.needsLightAWTPeer( c ) )
|
||||||
|
FlatUIUtils.runWithLightAWTPeerUIDefaults( () -> installUIImpl( c ) );
|
||||||
|
else
|
||||||
|
installUIImpl( c );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void installUIImpl( JComponent c ) {
|
||||||
super.installUI( c );
|
super.installUI( c );
|
||||||
|
|
||||||
leadingIcon = clientProperty( c, TEXT_FIELD_LEADING_ICON, null, Icon.class );
|
leadingIcon = clientProperty( c, TEXT_FIELD_LEADING_ICON, null, Icon.class );
|
||||||
@@ -354,6 +361,12 @@ public class FlatTextFieldUI
|
|||||||
return FlatStylingSupport.getAnnotatedStyleableInfos( this, getComponent().getBorder() );
|
return FlatStylingSupport.getAnnotatedStyleableInfos( this, getComponent().getBorder() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
@Override
|
||||||
|
public Object getStyleableValue( JComponent c, String key ) {
|
||||||
|
return FlatStylingSupport.getAnnotatedStyleableValue( this, getComponent().getBorder(), key );
|
||||||
|
}
|
||||||
|
|
||||||
private void updateBackground() {
|
private void updateBackground() {
|
||||||
updateBackground( getComponent(), background,
|
updateBackground( getComponent(), background,
|
||||||
disabledBackground, inactiveBackground,
|
disabledBackground, inactiveBackground,
|
||||||
|
|||||||
@@ -191,6 +191,12 @@ public class FlatTextPaneUI
|
|||||||
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
@Override
|
||||||
|
public Object getStyleableValue( JComponent c, String key ) {
|
||||||
|
return FlatStylingSupport.getAnnotatedStyleableValue( this, key );
|
||||||
|
}
|
||||||
|
|
||||||
private void updateBackground() {
|
private void updateBackground() {
|
||||||
FlatTextFieldUI.updateBackground( getComponent(), background,
|
FlatTextFieldUI.updateBackground( getComponent(), background,
|
||||||
disabledBackground, inactiveBackground,
|
disabledBackground, inactiveBackground,
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import java.awt.Container;
|
|||||||
import java.awt.Dialog;
|
import java.awt.Dialog;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.EventQueue;
|
import java.awt.EventQueue;
|
||||||
|
import java.awt.Font;
|
||||||
import java.awt.FontMetrics;
|
import java.awt.FontMetrics;
|
||||||
import java.awt.Frame;
|
import java.awt.Frame;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
@@ -32,6 +33,7 @@ import java.awt.Image;
|
|||||||
import java.awt.Insets;
|
import java.awt.Insets;
|
||||||
import java.awt.Point;
|
import java.awt.Point;
|
||||||
import java.awt.Rectangle;
|
import java.awt.Rectangle;
|
||||||
|
import java.awt.Toolkit;
|
||||||
import java.awt.Window;
|
import java.awt.Window;
|
||||||
import java.awt.event.ActionListener;
|
import java.awt.event.ActionListener;
|
||||||
import java.awt.event.ComponentEvent;
|
import java.awt.event.ComponentEvent;
|
||||||
@@ -54,6 +56,7 @@ import javax.swing.BoxLayout;
|
|||||||
import javax.swing.Icon;
|
import javax.swing.Icon;
|
||||||
import javax.swing.JButton;
|
import javax.swing.JButton;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
|
import javax.swing.JDialog;
|
||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
import javax.swing.JMenuBar;
|
import javax.swing.JMenuBar;
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
@@ -71,6 +74,7 @@ import com.formdev.flatlaf.util.UIScale;
|
|||||||
/**
|
/**
|
||||||
* Provides the Flat LaF title bar.
|
* Provides the Flat LaF title bar.
|
||||||
*
|
*
|
||||||
|
* @uiDefault TitlePane.font Font
|
||||||
* @uiDefault TitlePane.background Color
|
* @uiDefault TitlePane.background Color
|
||||||
* @uiDefault TitlePane.inactiveBackground Color
|
* @uiDefault TitlePane.inactiveBackground Color
|
||||||
* @uiDefault TitlePane.foreground Color
|
* @uiDefault TitlePane.foreground Color
|
||||||
@@ -79,6 +83,7 @@ import com.formdev.flatlaf.util.UIScale;
|
|||||||
* @uiDefault TitlePane.borderColor Color optional
|
* @uiDefault TitlePane.borderColor Color optional
|
||||||
* @uiDefault TitlePane.unifiedBackground boolean
|
* @uiDefault TitlePane.unifiedBackground boolean
|
||||||
* @uiDefault TitlePane.showIcon boolean
|
* @uiDefault TitlePane.showIcon boolean
|
||||||
|
* @uiDefault TitlePane.showIconInDialogs boolean
|
||||||
* @uiDefault TitlePane.noIconLeftGap int
|
* @uiDefault TitlePane.noIconLeftGap int
|
||||||
* @uiDefault TitlePane.iconSize Dimension
|
* @uiDefault TitlePane.iconSize Dimension
|
||||||
* @uiDefault TitlePane.iconMargins Insets
|
* @uiDefault TitlePane.iconMargins Insets
|
||||||
@@ -102,6 +107,7 @@ import com.formdev.flatlaf.util.UIScale;
|
|||||||
public class FlatTitlePane
|
public class FlatTitlePane
|
||||||
extends JComponent
|
extends JComponent
|
||||||
{
|
{
|
||||||
|
/** @since 2.5 */ protected final Font titleFont = UIManager.getFont( "TitlePane.font" );
|
||||||
protected final Color activeBackground = UIManager.getColor( "TitlePane.background" );
|
protected final Color activeBackground = UIManager.getColor( "TitlePane.background" );
|
||||||
protected final Color inactiveBackground = UIManager.getColor( "TitlePane.inactiveBackground" );
|
protected final Color inactiveBackground = UIManager.getColor( "TitlePane.inactiveBackground" );
|
||||||
protected final Color activeForeground = UIManager.getColor( "TitlePane.foreground" );
|
protected final Color activeForeground = UIManager.getColor( "TitlePane.foreground" );
|
||||||
@@ -110,6 +116,7 @@ public class FlatTitlePane
|
|||||||
protected final Color borderColor = UIManager.getColor( "TitlePane.borderColor" );
|
protected final Color borderColor = UIManager.getColor( "TitlePane.borderColor" );
|
||||||
|
|
||||||
/** @since 2 */ protected final boolean showIcon = FlatUIUtils.getUIBoolean( "TitlePane.showIcon", true );
|
/** @since 2 */ protected final boolean showIcon = FlatUIUtils.getUIBoolean( "TitlePane.showIcon", true );
|
||||||
|
/** @since 2.5 */ protected final boolean showIconInDialogs = FlatUIUtils.getUIBoolean( "TitlePane.showIconInDialogs", true );
|
||||||
/** @since 2 */ protected final int noIconLeftGap = FlatUIUtils.getUIInt( "TitlePane.noIconLeftGap", 8 );
|
/** @since 2 */ protected final int noIconLeftGap = FlatUIUtils.getUIInt( "TitlePane.noIconLeftGap", 8 );
|
||||||
protected final Dimension iconSize = UIManager.getDimension( "TitlePane.iconSize" );
|
protected final Dimension iconSize = UIManager.getDimension( "TitlePane.iconSize" );
|
||||||
/** @since 2.4 */ protected final int titleMinimumWidth = FlatUIUtils.getUIInt( "TitlePane.titleMinimumWidth", 60 );
|
/** @since 2.4 */ protected final int titleMinimumWidth = FlatUIUtils.getUIInt( "TitlePane.titleMinimumWidth", 60 );
|
||||||
@@ -357,6 +364,7 @@ public class FlatTitlePane
|
|||||||
restoreButton.setVisible( resizable && maximized );
|
restoreButton.setVisible( resizable && maximized );
|
||||||
|
|
||||||
if( maximized &&
|
if( maximized &&
|
||||||
|
!(SystemInfo.isLinux && FlatNativeLinuxLibrary.isWMUtilsSupported( window )) &&
|
||||||
rootPane.getClientProperty( "_flatlaf.maximizedBoundsUpToDate" ) == null )
|
rootPane.getClientProperty( "_flatlaf.maximizedBoundsUpToDate" ) == null )
|
||||||
{
|
{
|
||||||
rootPane.putClientProperty( "_flatlaf.maximizedBoundsUpToDate", null );
|
rootPane.putClientProperty( "_flatlaf.maximizedBoundsUpToDate", null );
|
||||||
@@ -387,9 +395,13 @@ public class FlatTitlePane
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void updateIcon() {
|
protected void updateIcon() {
|
||||||
|
boolean defaultShowIcon = showIcon;
|
||||||
|
if( !showIconInDialogs && rootPane.getParent() instanceof JDialog )
|
||||||
|
defaultShowIcon = false;
|
||||||
|
|
||||||
// get window images
|
// get window images
|
||||||
List<Image> images = null;
|
List<Image> images = null;
|
||||||
if( clientPropertyBoolean( rootPane, TITLE_BAR_SHOW_ICON, showIcon ) ) {
|
if( clientPropertyBoolean( rootPane, TITLE_BAR_SHOW_ICON, defaultShowIcon ) ) {
|
||||||
images = window.getIconImages();
|
images = window.getIconImages();
|
||||||
if( images.isEmpty() ) {
|
if( images.isEmpty() ) {
|
||||||
// search in owners
|
// search in owners
|
||||||
@@ -737,6 +749,17 @@ debug*/
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void maximizeOrRestore() {
|
||||||
|
if( !(window instanceof Frame) || !((Frame)window).isResizable() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
Frame frame = (Frame) window;
|
||||||
|
if( (frame.getExtendedState() & Frame.MAXIMIZED_BOTH) != 0 )
|
||||||
|
restore();
|
||||||
|
else
|
||||||
|
maximize();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Closes the window.
|
* Closes the window.
|
||||||
*/
|
*/
|
||||||
@@ -861,26 +884,32 @@ debug*/
|
|||||||
r.height -= resizeHeight;
|
r.height -= resizeHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
Component horizontalGlue = findHorizontalGlue( menuBar );
|
int count = menuBar.getComponentCount();
|
||||||
if( horizontalGlue != null ) {
|
for( int i = count - 1; i >= 0; i-- ) {
|
||||||
// If menu bar is embedded and contains a horizontal glue component,
|
Component c = menuBar.getComponent( i );
|
||||||
// then split the hit test spot into two spots so that
|
if( c instanceof Box.Filler ||
|
||||||
// the glue component area can be used to move the window.
|
(c instanceof JComponent && clientPropertyBoolean( (JComponent) c, COMPONENT_TITLE_BAR_CAPTION, false ) ) )
|
||||||
|
{
|
||||||
|
// If menu bar is embedded and contains a horizontal glue or caption component,
|
||||||
|
// then split the hit test spot so that
|
||||||
|
// the glue/caption component area can be used to move the window.
|
||||||
|
|
||||||
Point glueLocation = SwingUtilities.convertPoint( horizontalGlue, 0, 0, window );
|
Point glueLocation = SwingUtilities.convertPoint( c, 0, 0, window );
|
||||||
int x2 = glueLocation.x + horizontalGlue.getWidth();
|
int x2 = glueLocation.x + c.getWidth();
|
||||||
Rectangle r2;
|
Rectangle r2;
|
||||||
if( getComponentOrientation().isLeftToRight() ) {
|
if( getComponentOrientation().isLeftToRight() ) {
|
||||||
r2 = new Rectangle( x2, r.y, (r.x + r.width) - x2, r.height );
|
r2 = new Rectangle( x2, r.y, (r.x + r.width) - x2, r.height );
|
||||||
|
|
||||||
r.width = glueLocation.x - r.x;
|
r.width = glueLocation.x - r.x;
|
||||||
} else {
|
} else {
|
||||||
r2 = new Rectangle( r.x, r.y, glueLocation.x - r.x, r.height );
|
r2 = new Rectangle( r.x, r.y, glueLocation.x - r.x, r.height );
|
||||||
|
|
||||||
r.width = (r.x + r.width) - x2;
|
r.width = (r.x + r.width) - x2;
|
||||||
r.x = x2;
|
r.x = x2;
|
||||||
|
}
|
||||||
|
if( r2.width > 0 )
|
||||||
|
hitTestSpots.add( r2 );
|
||||||
}
|
}
|
||||||
hitTestSpots.add( r2 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hitTestSpots.add( r );
|
hitTestSpots.add( r );
|
||||||
@@ -986,6 +1015,14 @@ debug*/
|
|||||||
super( false );
|
super( false );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void installDefaults( JLabel c ) {
|
||||||
|
super.installDefaults( c );
|
||||||
|
|
||||||
|
if( titleFont != null )
|
||||||
|
c.setFont( titleFont );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String layoutCL( JLabel label, FontMetrics fontMetrics, String text, Icon icon,
|
protected String layoutCL( JLabel label, FontMetrics fontMetrics, String text, Icon icon,
|
||||||
Rectangle viewR, Rectangle iconR, Rectangle textR )
|
Rectangle viewR, Rectangle iconR, Rectangle textR )
|
||||||
@@ -1148,23 +1185,30 @@ debug*/
|
|||||||
//---- interface MouseListener ----
|
//---- interface MouseListener ----
|
||||||
|
|
||||||
private Point dragOffset;
|
private Point dragOffset;
|
||||||
|
private boolean nativeMove;
|
||||||
|
private long lastSingleClickWhen;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mouseClicked( MouseEvent e ) {
|
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 thru for some reason
|
||||||
|
if( 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( e.getClickCount() == 2 && SwingUtilities.isLeftMouseButton( e ) ) {
|
||||||
if( e.getSource() == iconLabel ) {
|
if( e.getSource() == iconLabel ) {
|
||||||
// double-click on icon closes window
|
// double-click on icon closes window
|
||||||
close();
|
close();
|
||||||
} else if( !hasNativeCustomDecoration() &&
|
} else if( !hasNativeCustomDecoration() ) {
|
||||||
window instanceof Frame &&
|
|
||||||
((Frame)window).isResizable() )
|
|
||||||
{
|
|
||||||
// maximize/restore on double-click
|
// maximize/restore on double-click
|
||||||
Frame frame = (Frame) window;
|
maximizeOrRestore();
|
||||||
if( (frame.getExtendedState() & Frame.MAXIMIZED_BOTH) != 0 )
|
|
||||||
restore();
|
|
||||||
else
|
|
||||||
maximize();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1174,10 +1218,56 @@ debug*/
|
|||||||
if( window == null )
|
if( window == null )
|
||||||
return; // should newer occur
|
return; // should newer occur
|
||||||
|
|
||||||
|
// on Linux, show window menu
|
||||||
|
if( SwingUtilities.isRightMouseButton( e ) &&
|
||||||
|
SystemInfo.isLinux && FlatNativeLinuxLibrary.isWMUtilsSupported( window ) )
|
||||||
|
{
|
||||||
|
e.consume();
|
||||||
|
FlatNativeLinuxLibrary.showWindowMenu( window, e );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if( !SwingUtilities.isLeftMouseButton( e ) )
|
if( !SwingUtilities.isLeftMouseButton( e ) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
dragOffset = SwingUtilities.convertPoint( FlatTitlePane.this, e.getPoint(), window );
|
dragOffset = SwingUtilities.convertPoint( FlatTitlePane.this, e.getPoint(), window );
|
||||||
|
nativeMove = 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();
|
||||||
|
nativeMove = 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 ) {}
|
@Override public void mouseReleased( MouseEvent e ) {}
|
||||||
@@ -1188,9 +1278,12 @@ debug*/
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mouseDragged( MouseEvent e ) {
|
public void mouseDragged( MouseEvent e ) {
|
||||||
if( window == null )
|
if( window == null || dragOffset == null )
|
||||||
return; // should newer occur
|
return; // should newer occur
|
||||||
|
|
||||||
|
if( nativeMove )
|
||||||
|
return;
|
||||||
|
|
||||||
if( !SwingUtilities.isLeftMouseButton( e ) )
|
if( !SwingUtilities.isLeftMouseButton( e ) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
@@ -160,6 +160,12 @@ public class FlatToolBarSeparatorUI
|
|||||||
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
@Override
|
||||||
|
public Object getStyleableValue( JComponent c, String key ) {
|
||||||
|
return FlatStylingSupport.getAnnotatedStyleableValue( this, key );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Dimension getPreferredSize( JComponent c ) {
|
public Dimension getPreferredSize( JComponent c ) {
|
||||||
Dimension size = ((JToolBar.Separator)c).getSeparatorSize();
|
Dimension size = ((JToolBar.Separator)c).getSeparatorSize();
|
||||||
|
|||||||
@@ -201,6 +201,12 @@ public class FlatToolBarUI
|
|||||||
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
@Override
|
||||||
|
public Object getStyleableValue( JComponent c, String key ) {
|
||||||
|
return FlatStylingSupport.getAnnotatedStyleableValue( this, key );
|
||||||
|
}
|
||||||
|
|
||||||
/** @since 1.4 */
|
/** @since 1.4 */
|
||||||
protected void setButtonsFocusable( boolean focusable ) {
|
protected void setButtonsFocusable( boolean focusable ) {
|
||||||
for( Component c : toolBar.getComponents() )
|
for( Component c : toolBar.getComponents() )
|
||||||
|
|||||||
@@ -340,6 +340,12 @@ public class FlatTreeUI
|
|||||||
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 2.5 */
|
||||||
|
@Override
|
||||||
|
public Object getStyleableValue( JComponent c, String key ) {
|
||||||
|
return FlatStylingSupport.getAnnotatedStyleableValue( this, key );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Same as super.paintRow(), but supports wide selection and uses
|
* Same as super.paintRow(), but supports wide selection and uses
|
||||||
* inactive selection background/foreground if tree is not focused.
|
* inactive selection background/foreground if tree is not focused.
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ import java.awt.Rectangle;
|
|||||||
import java.awt.RenderingHints;
|
import java.awt.RenderingHints;
|
||||||
import java.awt.Shape;
|
import java.awt.Shape;
|
||||||
import java.awt.Stroke;
|
import java.awt.Stroke;
|
||||||
|
import java.awt.SystemColor;
|
||||||
import java.awt.Window;
|
import java.awt.Window;
|
||||||
import java.awt.event.FocusEvent;
|
import java.awt.event.FocusEvent;
|
||||||
import java.awt.event.FocusListener;
|
import java.awt.event.FocusListener;
|
||||||
@@ -45,20 +46,27 @@ import java.util.WeakHashMap;
|
|||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
|
import javax.swing.JScrollPane;
|
||||||
import javax.swing.JTable;
|
import javax.swing.JTable;
|
||||||
|
import javax.swing.JTextField;
|
||||||
import javax.swing.LookAndFeel;
|
import javax.swing.LookAndFeel;
|
||||||
import javax.swing.SwingConstants;
|
import javax.swing.SwingConstants;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
|
import javax.swing.UIDefaults;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import javax.swing.border.Border;
|
import javax.swing.border.Border;
|
||||||
import javax.swing.border.CompoundBorder;
|
import javax.swing.border.CompoundBorder;
|
||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
import javax.swing.plaf.UIResource;
|
import javax.swing.plaf.UIResource;
|
||||||
import com.formdev.flatlaf.FlatClientProperties;
|
import com.formdev.flatlaf.FlatClientProperties;
|
||||||
|
import com.formdev.flatlaf.FlatIntelliJLaf;
|
||||||
|
import com.formdev.flatlaf.FlatLaf;
|
||||||
|
import com.formdev.flatlaf.FlatLightLaf;
|
||||||
import com.formdev.flatlaf.FlatSystemProperties;
|
import com.formdev.flatlaf.FlatSystemProperties;
|
||||||
import com.formdev.flatlaf.util.DerivedColor;
|
import com.formdev.flatlaf.util.DerivedColor;
|
||||||
import com.formdev.flatlaf.util.Graphics2DProxy;
|
import com.formdev.flatlaf.util.Graphics2DProxy;
|
||||||
import com.formdev.flatlaf.util.HiDPIUtils;
|
import com.formdev.flatlaf.util.HiDPIUtils;
|
||||||
|
import com.formdev.flatlaf.util.SystemInfo;
|
||||||
import com.formdev.flatlaf.util.UIScale;
|
import com.formdev.flatlaf.util.UIScale;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -202,6 +210,9 @@ public class FlatUIUtils
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isCellEditor( Component c ) {
|
public static boolean isCellEditor( Component c ) {
|
||||||
|
if( c == null )
|
||||||
|
return false;
|
||||||
|
|
||||||
// check whether used in cell editor (check 3 levels up)
|
// check whether used in cell editor (check 3 levels up)
|
||||||
Component c2 = c;
|
Component c2 = c;
|
||||||
for( int i = 0; i <= 2 && c2 != null; i++ ) {
|
for( int i = 0; i <= 2 && c2 != null; i++ ) {
|
||||||
@@ -241,6 +252,11 @@ public class FlatUIUtils
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// invoke hasFocus() here because components may have overridden this method
|
||||||
|
// (e.g. Swing delegate components used for AWT components on macOS)
|
||||||
|
if( c.hasFocus() )
|
||||||
|
return true;
|
||||||
|
|
||||||
return keyboardFocusManager.getPermanentFocusOwner() == c &&
|
return keyboardFocusManager.getPermanentFocusOwner() == c &&
|
||||||
isInActiveWindow( c, keyboardFocusManager.getActiveWindow() );
|
isInActiveWindow( c, keyboardFocusManager.getActiveWindow() );
|
||||||
}
|
}
|
||||||
@@ -251,6 +267,38 @@ public class FlatUIUtils
|
|||||||
(window != null && window.getType() == Window.Type.POPUP && window.getOwner() == activeWindow);
|
(window != null && window.getType() == Window.Type.POPUP && window.getOwner() == activeWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static boolean isAWTPeer( Component c ) {
|
||||||
|
// on macOS, Swing components are used for AWT components
|
||||||
|
if( SystemInfo.isMacOS )
|
||||||
|
return c.getClass().getName().startsWith( "sun.lwawt.LW" );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether component is used as peer for AWT (on macOS) and
|
||||||
|
* whether a dark FlatLaf theme is active, which requires special handling
|
||||||
|
* because AWT always uses light colors.
|
||||||
|
*/
|
||||||
|
static boolean needsLightAWTPeer( JComponent c ) {
|
||||||
|
return FlatUIUtils.isAWTPeer( c ) && FlatLaf.isLafDark();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static UIDefaults lightAWTPeerDefaults;
|
||||||
|
|
||||||
|
static void runWithLightAWTPeerUIDefaults( Runnable runnable ) {
|
||||||
|
if( lightAWTPeerDefaults == null ) {
|
||||||
|
FlatLaf lightLaf = UIManager.getInt( "Component.focusWidth" ) >= 2
|
||||||
|
? new FlatIntelliJLaf()
|
||||||
|
: new FlatLightLaf();
|
||||||
|
lightAWTPeerDefaults = lightLaf.getDefaults();
|
||||||
|
}
|
||||||
|
|
||||||
|
FlatLaf.runWithUIDefaultsGetter( key -> {
|
||||||
|
Object value = lightAWTPeerDefaults.get( key );
|
||||||
|
return (value != null) ? value : FlatLaf.NULL_VALUE;
|
||||||
|
}, runnable );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether the given component is in a window that is in full-screen mode.
|
* Returns whether the given component is in a window that is in full-screen mode.
|
||||||
*/
|
*/
|
||||||
@@ -335,7 +383,7 @@ public class FlatUIUtils
|
|||||||
*/
|
*/
|
||||||
public static Object[] setRenderingHints( Graphics g ) {
|
public static Object[] setRenderingHints( Graphics g ) {
|
||||||
Graphics2D g2 = (Graphics2D) g;
|
Graphics2D g2 = (Graphics2D) g;
|
||||||
Object[] oldRenderingHints = new Object[] {
|
Object[] oldRenderingHints = {
|
||||||
g2.getRenderingHint( RenderingHints.KEY_ANTIALIASING ),
|
g2.getRenderingHint( RenderingHints.KEY_ANTIALIASING ),
|
||||||
g2.getRenderingHint( RenderingHints.KEY_STROKE_CONTROL ),
|
g2.getRenderingHint( RenderingHints.KEY_STROKE_CONTROL ),
|
||||||
};
|
};
|
||||||
@@ -352,8 +400,10 @@ public class FlatUIUtils
|
|||||||
*/
|
*/
|
||||||
public static void resetRenderingHints( Graphics g, Object[] oldRenderingHints ) {
|
public static void resetRenderingHints( Graphics g, Object[] oldRenderingHints ) {
|
||||||
Graphics2D g2 = (Graphics2D) g;
|
Graphics2D g2 = (Graphics2D) g;
|
||||||
g2.setRenderingHint( RenderingHints.KEY_ANTIALIASING, oldRenderingHints[0] );
|
if( oldRenderingHints[0] != null )
|
||||||
g2.setRenderingHint( RenderingHints.KEY_STROKE_CONTROL, oldRenderingHints[1] );
|
g2.setRenderingHint( RenderingHints.KEY_ANTIALIASING, oldRenderingHints[0] );
|
||||||
|
if( oldRenderingHints[1] != null )
|
||||||
|
g2.setRenderingHint( RenderingHints.KEY_STROKE_CONTROL, oldRenderingHints[1] );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -376,7 +426,7 @@ public class FlatUIUtils
|
|||||||
}
|
}
|
||||||
|
|
||||||
Graphics2D g2 = (Graphics2D) g;
|
Graphics2D g2 = (Graphics2D) g;
|
||||||
Object[] oldRenderingHints2 = new Object[] {
|
Object[] oldRenderingHints2 = {
|
||||||
g2.getRenderingHint( RenderingHints.KEY_ANTIALIASING ),
|
g2.getRenderingHint( RenderingHints.KEY_ANTIALIASING ),
|
||||||
g2.getRenderingHint( RenderingHints.KEY_STROKE_CONTROL ),
|
g2.getRenderingHint( RenderingHints.KEY_STROKE_CONTROL ),
|
||||||
};
|
};
|
||||||
@@ -664,9 +714,9 @@ public class FlatUIUtils
|
|||||||
* is smaller than its bounds (for the focus decoration).
|
* is smaller than its bounds (for the focus decoration).
|
||||||
*/
|
*/
|
||||||
public static void paintParentBackground( Graphics g, JComponent c ) {
|
public static void paintParentBackground( Graphics g, JComponent c ) {
|
||||||
Container parent = findOpaqueParent( c );
|
Color background = getParentBackground( c );
|
||||||
if( parent != null ) {
|
if( background != null ) {
|
||||||
g.setColor( parent.getBackground() );
|
g.setColor( background );
|
||||||
g.fillRect( 0, 0, c.getWidth(), c.getHeight() );
|
g.fillRect( 0, 0, c.getWidth(), c.getHeight() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -676,9 +726,20 @@ public class FlatUIUtils
|
|||||||
*/
|
*/
|
||||||
public static Color getParentBackground( JComponent c ) {
|
public static Color getParentBackground( JComponent c ) {
|
||||||
Container parent = findOpaqueParent( c );
|
Container parent = findOpaqueParent( c );
|
||||||
return (parent != null)
|
// parent.getBackground() may return null
|
||||||
? parent.getBackground()
|
// (e.g. for Swing delegate components used for AWT components on macOS)
|
||||||
: UIManager.getColor( "Panel.background" ); // fallback, probably never used
|
Color background = (parent != null) ? parent.getBackground() : null;
|
||||||
|
if( background != null )
|
||||||
|
return background;
|
||||||
|
|
||||||
|
if( isAWTPeer( c ) ) {
|
||||||
|
// AWT peers usually use component background, except for TextField and ScrollPane
|
||||||
|
return c instanceof JTextField || c instanceof JScrollPane || c.getBackground() == null
|
||||||
|
? SystemColor.window
|
||||||
|
: c.getBackground();
|
||||||
|
}
|
||||||
|
|
||||||
|
return UIManager.getColor( "Panel.background" );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -19,8 +19,9 @@ package com.formdev.flatlaf.util;
|
|||||||
import java.awt.FontMetrics;
|
import java.awt.FontMetrics;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.invoke.MethodHandle;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.invoke.MethodHandles;
|
||||||
|
import java.lang.invoke.MethodType;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -32,8 +33,8 @@ import javax.swing.JComponent;
|
|||||||
*/
|
*/
|
||||||
public class JavaCompatibility
|
public class JavaCompatibility
|
||||||
{
|
{
|
||||||
private static Method drawStringUnderlineCharAtMethod;
|
private static MethodHandle drawStringUnderlineCharAtMethod;
|
||||||
private static Method getClippedStringMethod;
|
private static MethodHandle getClippedStringMethod;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Java 8: sun.swing.SwingUtilities2.drawStringUnderlineCharAt( JComponent c,
|
* Java 8: sun.swing.SwingUtilities2.drawStringUnderlineCharAt( JComponent c,
|
||||||
@@ -51,9 +52,10 @@ public class JavaCompatibility
|
|||||||
Class<?> cls = Class.forName( SystemInfo.isJava_9_orLater
|
Class<?> cls = Class.forName( SystemInfo.isJava_9_orLater
|
||||||
? "javax.swing.plaf.basic.BasicGraphicsUtils"
|
? "javax.swing.plaf.basic.BasicGraphicsUtils"
|
||||||
: "sun.swing.SwingUtilities2" );
|
: "sun.swing.SwingUtilities2" );
|
||||||
drawStringUnderlineCharAtMethod = cls.getMethod( "drawStringUnderlineCharAt", SystemInfo.isJava_9_orLater
|
MethodType mt = MethodType.methodType( void.class, SystemInfo.isJava_9_orLater
|
||||||
? new Class[] { JComponent.class, Graphics2D.class, String.class, int.class, float.class, float.class }
|
? new Class[] { JComponent.class, Graphics2D.class, String.class, int.class, float.class, float.class }
|
||||||
: new Class[] { JComponent.class, Graphics.class, String.class, int.class, int.class, int.class } );
|
: new Class[] { JComponent.class, Graphics.class, String.class, int.class, int.class, int.class } );
|
||||||
|
drawStringUnderlineCharAtMethod = MethodHandles.publicLookup().findStatic( cls, "drawStringUnderlineCharAt", mt );
|
||||||
} catch( Exception ex ) {
|
} catch( Exception ex ) {
|
||||||
LoggingFacade.INSTANCE.logSevere( null, ex );
|
LoggingFacade.INSTANCE.logSevere( null, ex );
|
||||||
throw new RuntimeException( ex );
|
throw new RuntimeException( ex );
|
||||||
@@ -63,10 +65,10 @@ public class JavaCompatibility
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
if( SystemInfo.isJava_9_orLater )
|
if( SystemInfo.isJava_9_orLater )
|
||||||
drawStringUnderlineCharAtMethod.invoke( null, c, g, text, underlinedIndex, (float) x, (float) y );
|
drawStringUnderlineCharAtMethod.invoke( c, (Graphics2D) g, text, underlinedIndex, (float) x, (float) y );
|
||||||
else
|
else
|
||||||
drawStringUnderlineCharAtMethod.invoke( null, c, g, text, underlinedIndex, x, y );
|
drawStringUnderlineCharAtMethod.invoke( c, g, text, underlinedIndex, x, y );
|
||||||
} catch( IllegalAccessException | IllegalArgumentException | InvocationTargetException ex ) {
|
} catch( Throwable ex ) {
|
||||||
LoggingFacade.INSTANCE.logSevere( null, ex );
|
LoggingFacade.INSTANCE.logSevere( null, ex );
|
||||||
throw new RuntimeException( ex );
|
throw new RuntimeException( ex );
|
||||||
}
|
}
|
||||||
@@ -86,10 +88,11 @@ public class JavaCompatibility
|
|||||||
Class<?> cls = Class.forName( SystemInfo.isJava_9_orLater
|
Class<?> cls = Class.forName( SystemInfo.isJava_9_orLater
|
||||||
? "javax.swing.plaf.basic.BasicGraphicsUtils"
|
? "javax.swing.plaf.basic.BasicGraphicsUtils"
|
||||||
: "sun.swing.SwingUtilities2" );
|
: "sun.swing.SwingUtilities2" );
|
||||||
getClippedStringMethod = cls.getMethod( SystemInfo.isJava_9_orLater
|
MethodType mt = MethodType.methodType( String.class, JComponent.class, FontMetrics.class, String.class, int.class );
|
||||||
|
getClippedStringMethod = MethodHandles.publicLookup().findStatic( cls, SystemInfo.isJava_9_orLater
|
||||||
? "getClippedString"
|
? "getClippedString"
|
||||||
: "clipStringIfNecessary",
|
: "clipStringIfNecessary",
|
||||||
JComponent.class, FontMetrics.class, String.class, int.class );
|
mt );
|
||||||
} catch( Exception ex ) {
|
} catch( Exception ex ) {
|
||||||
LoggingFacade.INSTANCE.logSevere( null, ex );
|
LoggingFacade.INSTANCE.logSevere( null, ex );
|
||||||
throw new RuntimeException( ex );
|
throw new RuntimeException( ex );
|
||||||
@@ -98,8 +101,8 @@ public class JavaCompatibility
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return (String) getClippedStringMethod.invoke( null, c, fm, string, availTextWidth );
|
return (String) getClippedStringMethod.invoke( c, fm, string, availTextWidth );
|
||||||
} catch( IllegalAccessException | IllegalArgumentException | InvocationTargetException ex ) {
|
} catch( Throwable ex ) {
|
||||||
LoggingFacade.INSTANCE.logSevere( null, ex );
|
LoggingFacade.INSTANCE.logSevere( null, ex );
|
||||||
throw new RuntimeException( ex );
|
throw new RuntimeException( ex );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -73,6 +73,22 @@ public class NativeLibrary
|
|||||||
: false;
|
: false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load native library using {@link System#loadLibrary(String)}.
|
||||||
|
* Searches for the library in classloader of caller
|
||||||
|
* (using {@link ClassLoader#findLibrary(String)}) and in paths specified
|
||||||
|
* in system properties {@code sun.boot.library.path} and {@code java.library.path}.
|
||||||
|
*
|
||||||
|
* @param libraryName name of the native library (without "lib" prefix and without extension)
|
||||||
|
* @param supported whether the native library is supported on the current platform
|
||||||
|
* @since 2.6
|
||||||
|
*/
|
||||||
|
public NativeLibrary( String libraryName, boolean supported ) {
|
||||||
|
this.loaded = supported
|
||||||
|
? loadLibraryFromSystem( libraryName )
|
||||||
|
: false;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether the native library is loaded.
|
* Returns whether the native library is loaded.
|
||||||
* <p>
|
* <p>
|
||||||
@@ -92,7 +108,7 @@ public class NativeLibrary
|
|||||||
? classLoader.getResource( libraryName )
|
? classLoader.getResource( libraryName )
|
||||||
: NativeLibrary.class.getResource( "/" + libraryName );
|
: NativeLibrary.class.getResource( "/" + libraryName );
|
||||||
if( libraryUrl == null ) {
|
if( libraryUrl == null ) {
|
||||||
log( "Library '" + libraryName + "' not found", null );
|
LoggingFacade.INSTANCE.logSevere( "Library '" + libraryName + "' not found", null );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,7 +141,7 @@ public class NativeLibrary
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch( Throwable ex ) {
|
} catch( Throwable ex ) {
|
||||||
log( null, ex );
|
LoggingFacade.INSTANCE.logSevere( ex.getMessage(), ex );
|
||||||
|
|
||||||
if( tempFile != null )
|
if( tempFile != null )
|
||||||
deleteOrMarkForDeletion( tempFile );
|
deleteOrMarkForDeletion( tempFile );
|
||||||
@@ -138,7 +154,24 @@ public class NativeLibrary
|
|||||||
System.load( libraryFile.getAbsolutePath() );
|
System.load( libraryFile.getAbsolutePath() );
|
||||||
return true;
|
return true;
|
||||||
} catch( Throwable ex ) {
|
} catch( Throwable ex ) {
|
||||||
log( null, ex );
|
LoggingFacade.INSTANCE.logSevere( ex.getMessage(), ex );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean loadLibraryFromSystem( String libraryName ) {
|
||||||
|
try {
|
||||||
|
System.loadLibrary( libraryName );
|
||||||
|
return true;
|
||||||
|
} catch( Throwable ex ) {
|
||||||
|
String message = ex.getMessage();
|
||||||
|
|
||||||
|
// do not log error if library was not found
|
||||||
|
// thrown in ClassLoader.loadLibrary(Class<?> fromClass, String name, boolean isAbsolute)
|
||||||
|
if( ex instanceof UnsatisfiedLinkError && message != null && message.contains( "java.library.path" ) )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
LoggingFacade.INSTANCE.logSevere( message, ex );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -158,10 +191,6 @@ public class NativeLibrary
|
|||||||
: System.mapLibraryName( libraryName );
|
: System.mapLibraryName( libraryName );
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void log( String msg, Throwable thrown ) {
|
|
||||||
LoggingFacade.INSTANCE.logSevere( msg, thrown );
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Path createTempFile( String libraryName ) throws IOException {
|
private static Path createTempFile( String libraryName ) throws IOException {
|
||||||
int sep = libraryName.lastIndexOf( '/' );
|
int sep = libraryName.lastIndexOf( '/' );
|
||||||
String name = (sep >= 0) ? libraryName.substring( sep + 1 ) : libraryName;
|
String name = (sep >= 0) ? libraryName.substring( sep + 1 ) : libraryName;
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf.util;
|
package com.formdev.flatlaf.util;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
@@ -102,6 +103,13 @@ debug*/
|
|||||||
int imageWidth = image.getWidth( null );
|
int imageWidth = image.getWidth( null );
|
||||||
int imageHeight = image.getHeight( null );
|
int imageHeight = image.getHeight( null );
|
||||||
|
|
||||||
|
// paint red rectangle if image has invalid size (e.g. not found)
|
||||||
|
if( imageWidth < 0 || imageHeight < 0 ) {
|
||||||
|
g.setColor( Color.red );
|
||||||
|
g.fillRect( x, y, getIconWidth(), getIconHeight() );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// scale image if necessary to destination size
|
// scale image if necessary to destination size
|
||||||
if( imageWidth != destImageWidth || imageHeight != destImageHeight ) {
|
if( imageWidth != destImageWidth || imageHeight != destImageHeight ) {
|
||||||
// determine scaling method; default is "quality"
|
// determine scaling method; default is "quality"
|
||||||
|
|||||||
@@ -442,8 +442,8 @@ MenuItem.iconTextGap = 6
|
|||||||
MenuItem.textAcceleratorGap = 24
|
MenuItem.textAcceleratorGap = 24
|
||||||
MenuItem.textNoAcceleratorGap = 6
|
MenuItem.textNoAcceleratorGap = 6
|
||||||
MenuItem.acceleratorArrowGap = 2
|
MenuItem.acceleratorArrowGap = 2
|
||||||
MenuItem.acceleratorDelimiter = +
|
MenuItem.acceleratorDelimiter = "+"
|
||||||
[mac]MenuItem.acceleratorDelimiter =
|
[mac]MenuItem.acceleratorDelimiter = ""
|
||||||
|
|
||||||
# for MenuItem.selectionType = underline
|
# for MenuItem.selectionType = underline
|
||||||
MenuItem.underlineSelectionBackground = @menuHoverBackground
|
MenuItem.underlineSelectionBackground = @menuHoverBackground
|
||||||
@@ -785,6 +785,7 @@ TitlePane.useWindowDecorations = true
|
|||||||
TitlePane.menuBarEmbedded = true
|
TitlePane.menuBarEmbedded = true
|
||||||
TitlePane.unifiedBackground = true
|
TitlePane.unifiedBackground = true
|
||||||
TitlePane.showIcon = true
|
TitlePane.showIcon = true
|
||||||
|
TitlePane.showIconInDialogs = true
|
||||||
TitlePane.noIconLeftGap = 8
|
TitlePane.noIconLeftGap = 8
|
||||||
TitlePane.iconSize = 16,16
|
TitlePane.iconSize = 16,16
|
||||||
TitlePane.iconMargins = 3,8,3,8
|
TitlePane.iconMargins = 3,8,3,8
|
||||||
|
|||||||
@@ -284,6 +284,8 @@ public class TestFlatStyleableInfo
|
|||||||
Map<String, Class<?>> expected = expectedMap(
|
Map<String, Class<?>> expected = expectedMap(
|
||||||
"itemMargins", Insets.class,
|
"itemMargins", Insets.class,
|
||||||
"hoverBackground", Color.class,
|
"hoverBackground", Color.class,
|
||||||
|
"selectionBackground", Color.class,
|
||||||
|
"selectionForeground", Color.class,
|
||||||
"underlineSelectionBackground", Color.class,
|
"underlineSelectionBackground", Color.class,
|
||||||
"underlineSelectionColor", Color.class,
|
"underlineSelectionColor", Color.class,
|
||||||
"underlineSelectionHeight", int.class,
|
"underlineSelectionHeight", int.class,
|
||||||
@@ -722,6 +724,7 @@ public class TestFlatStyleableInfo
|
|||||||
"tabSeparatorsFullHeight", boolean.class,
|
"tabSeparatorsFullHeight", boolean.class,
|
||||||
"hasFullBorder", boolean.class,
|
"hasFullBorder", boolean.class,
|
||||||
"tabsOpaque", boolean.class,
|
"tabsOpaque", boolean.class,
|
||||||
|
"rotateTabRuns", boolean.class,
|
||||||
|
|
||||||
"tabType", String.class,
|
"tabType", String.class,
|
||||||
"tabsPopupPolicy", String.class,
|
"tabsPopupPolicy", String.class,
|
||||||
|
|||||||
@@ -436,6 +436,8 @@ public class TestFlatStyling
|
|||||||
|
|
||||||
ui.applyStyle( "itemMargins: 1,2,3,4" );
|
ui.applyStyle( "itemMargins: 1,2,3,4" );
|
||||||
ui.applyStyle( "hoverBackground: #fff" );
|
ui.applyStyle( "hoverBackground: #fff" );
|
||||||
|
ui.applyStyle( "selectionBackground: #fff" );
|
||||||
|
ui.applyStyle( "selectionForeground: #fff" );
|
||||||
ui.applyStyle( "underlineSelectionBackground: #fff" );
|
ui.applyStyle( "underlineSelectionBackground: #fff" );
|
||||||
ui.applyStyle( "underlineSelectionColor: #fff" );
|
ui.applyStyle( "underlineSelectionColor: #fff" );
|
||||||
ui.applyStyle( "underlineSelectionHeight: 3" );
|
ui.applyStyle( "underlineSelectionHeight: 3" );
|
||||||
@@ -891,6 +893,7 @@ public class TestFlatStyling
|
|||||||
ui.applyStyle( "tabSeparatorsFullHeight: false" );
|
ui.applyStyle( "tabSeparatorsFullHeight: false" );
|
||||||
ui.applyStyle( "hasFullBorder: false" );
|
ui.applyStyle( "hasFullBorder: false" );
|
||||||
ui.applyStyle( "tabsOpaque: false" );
|
ui.applyStyle( "tabsOpaque: false" );
|
||||||
|
ui.applyStyle( "rotateTabRuns: false" );
|
||||||
|
|
||||||
ui.applyStyle( "tabType: card" );
|
ui.applyStyle( "tabType: card" );
|
||||||
ui.applyStyle( "tabsPopupPolicy: asNeeded" );
|
ui.applyStyle( "tabsPopupPolicy: asNeeded" );
|
||||||
|
|||||||
3
flatlaf-core/svg/ArrowButton-chevron.svg
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="8" height="4" viewBox="0 0 8 4">
|
||||||
|
<polyline fill="none" stroke="#6E6E6E" points="0 4 4 0 8 4"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 151 B |
3
flatlaf-core/svg/ArrowButton-triangle.svg
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="9" height="5" viewBox="0 0 9 5">
|
||||||
|
<polygon fill="#6E6E6E" fill-rule="evenodd" points="0 5 4.5 0 9 5"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 158 B |
3
flatlaf-core/svg/AscendingSortIcon-chevron.svg
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="10" height="5" viewBox="0 0 10 5">
|
||||||
|
<polyline fill="none" stroke="#6E6E6E" points="1 4 5 0 9 4"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 153 B |
3
flatlaf-core/svg/AscendingSortIcon-triangle.svg
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="10" height="5" viewBox="0 0 10 5">
|
||||||
|
<polygon fill="#6E6E6E" fill-rule="evenodd" points=".5 5 5 0 9.5 5"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 161 B |
3
flatlaf-core/svg/MenuArrowIcon-chevron.svg
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="6" height="10" viewBox="0 0 6 10">
|
||||||
|
<polyline fill="none" stroke="#6E6E6E" points="1 1 5 5 1 9"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 153 B |
3
flatlaf-core/svg/MenuArrowIcon-triangle.svg
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="6" height="10" viewBox="0 0 6 10">
|
||||||
|
<polygon fill="#6E6E6E" fill-rule="evenodd" points="0 .5 5 5 0 9.5"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 161 B |
3
flatlaf-core/svg/TreeCollapsedIcon-chevron.svg
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="11" height="11" viewBox="0 0 11 11">
|
||||||
|
<polygon fill="#6E6E6E" fill-rule="evenodd" points="3 1 3 2.5 6 5.5 3 8.5 3 10 4.5 10 9 5.5 4.5 1"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 194 B |
3
flatlaf-core/svg/TreeCollapsedIcon-triangle.svg
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="11" height="11" viewBox="0 0 11 11">
|
||||||
|
<polygon fill="#6E6E6E" fill-rule="evenodd" points="2 1 2 10 10 5.5"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 164 B |
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
`java-library`
|
`java-library`
|
||||||
|
`flatlaf-toolchain`
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
`java-library`
|
`java-library`
|
||||||
|
`flatlaf-toolchain`
|
||||||
`flatlaf-module-info`
|
`flatlaf-module-info`
|
||||||
`flatlaf-publish`
|
`flatlaf-publish`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
`java-library`
|
`java-library`
|
||||||
|
`flatlaf-toolchain`
|
||||||
`flatlaf-module-info`
|
`flatlaf-module-info`
|
||||||
`flatlaf-publish`
|
`flatlaf-publish`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,23 @@
|
|||||||
"name": "Hiberbee Dark",
|
"name": "Hiberbee Dark",
|
||||||
"author": "Vlad Volkov",
|
"author": "Vlad Volkov",
|
||||||
"dark": true,
|
"dark": true,
|
||||||
|
"icons": {
|
||||||
|
"ColorPalette": {
|
||||||
|
"Actions.Blue": "#78dce8",
|
||||||
|
"Actions.Green": "#92d923",
|
||||||
|
"Actions.Grey": "#93918c",
|
||||||
|
"Actions.Red": "#fb3b45",
|
||||||
|
"Actions.Yellow": "#FFD866",
|
||||||
|
"Objects.Blue": "#78dce8",
|
||||||
|
"Objects.Green": "#92d923",
|
||||||
|
"Objects.Pink": "#ff6188",
|
||||||
|
"Objects.Purple": "#ab9df2",
|
||||||
|
"Objects.Red": "#fb3b45",
|
||||||
|
"Objects.RedStatus": "#fb3b45",
|
||||||
|
"Objects.Yellow": "#FFD866",
|
||||||
|
"Objects.YellowDark": "#FFB900"
|
||||||
|
}
|
||||||
|
},
|
||||||
"editorScheme": "/colors/Dark.xml",
|
"editorScheme": "/colors/Dark.xml",
|
||||||
"colors": {
|
"colors": {
|
||||||
"black": "#000000",
|
"black": "#000000",
|
||||||
@@ -22,7 +39,7 @@
|
|||||||
"deepBlue": "#3199b3",
|
"deepBlue": "#3199b3",
|
||||||
"orangeMonokaiPro": "#fc9867",
|
"orangeMonokaiPro": "#fc9867",
|
||||||
"greenMonokaiPro": "#a9dc76",
|
"greenMonokaiPro": "#a9dc76",
|
||||||
"yellow": "#FFB900",
|
"yellow": "#ffd64c",
|
||||||
"purpleWinPalette": "#b4a0ff",
|
"purpleWinPalette": "#b4a0ff",
|
||||||
"purpleMonokaiPro": "#ab9df2",
|
"purpleMonokaiPro": "#ab9df2",
|
||||||
"greenWinPalette": "#40c5af",
|
"greenWinPalette": "#40c5af",
|
||||||
@@ -49,7 +66,7 @@
|
|||||||
"transparentGreen": "#5B80217f",
|
"transparentGreen": "#5B80217f",
|
||||||
"transparentRed": "#F250227f",
|
"transparentRed": "#F250227f",
|
||||||
"transparentViolet": "#242221ff",
|
"transparentViolet": "#242221ff",
|
||||||
"transparentYellow": "#FFB9007f"
|
"transparentYellow": "#FFB9007a"
|
||||||
},
|
},
|
||||||
"ui": {
|
"ui": {
|
||||||
"*": {
|
"*": {
|
||||||
@@ -78,7 +95,6 @@
|
|||||||
"color": "border"
|
"color": "border"
|
||||||
},
|
},
|
||||||
"Button": {
|
"Button": {
|
||||||
"arc": 5,
|
|
||||||
"default": {
|
"default": {
|
||||||
"endBackground": "greyDot80",
|
"endBackground": "greyDot80",
|
||||||
"endBorderColor": "greyDot70",
|
"endBorderColor": "greyDot70",
|
||||||
@@ -125,7 +141,6 @@
|
|||||||
"selectionInactiveBackground": "greyDot85"
|
"selectionInactiveBackground": "greyDot85"
|
||||||
},
|
},
|
||||||
"Component": {
|
"Component": {
|
||||||
"arc": "4",
|
|
||||||
"iconColor": "yellow",
|
"iconColor": "yellow",
|
||||||
"disabledBorderColor": "greyDot75",
|
"disabledBorderColor": "greyDot75",
|
||||||
"infoForeground": "greyDot50",
|
"infoForeground": "greyDot50",
|
||||||
@@ -160,22 +175,25 @@
|
|||||||
},
|
},
|
||||||
"EditorTabs": {
|
"EditorTabs": {
|
||||||
"underlineHeight": 1,
|
"underlineHeight": 1,
|
||||||
"borderColor": "editorDarkerBg",
|
"hoverBackground": "greyDot95",
|
||||||
"hoverBackground": "editorBg",
|
"borderColor": "border",
|
||||||
"background": "editorPaneBg",
|
"background": "editorPaneBg",
|
||||||
|
"inactiveColoredFileBackground": "editorPaneBg",
|
||||||
"inactiveUnderlineColor": "editorPaneBg",
|
"inactiveUnderlineColor": "editorPaneBg",
|
||||||
"underlinedTabForeground": "textColor"
|
"underlinedTabBackground": "editorPaneBg",
|
||||||
|
"underlinedTabForeground": "yellow"
|
||||||
},
|
},
|
||||||
"EditorTabs.inactiveColoredFileBackground": true,
|
|
||||||
"FileColor": {
|
"FileColor": {
|
||||||
|
"Gray": "greyDot70",
|
||||||
"Blue": "#23282d",
|
"Blue": "#23282d",
|
||||||
"Green": "#232d28",
|
"Green": "#232d28",
|
||||||
"Orange": "#2d2823",
|
"Orange": "#2d2823",
|
||||||
"Rose": "#2d2323",
|
"Rose": "#2d2323",
|
||||||
"Violet": "#2D232D",
|
"Violet": "#2D232D",
|
||||||
"Yellow": "#2d2d23"
|
"Yellow": "#3b3b19"
|
||||||
},
|
},
|
||||||
"FormattedTextField": {
|
"FormattedTextField": {
|
||||||
|
"caretForeground": "yellow",
|
||||||
"foreground": "textColor",
|
"foreground": "textColor",
|
||||||
"selectionBackground": "greyDot95",
|
"selectionBackground": "greyDot95",
|
||||||
"inactiveBackground": "greyDot80",
|
"inactiveBackground": "greyDot80",
|
||||||
@@ -186,14 +204,23 @@
|
|||||||
"infoForeground": "greyDot33",
|
"infoForeground": "greyDot33",
|
||||||
"lineSeparatorColor": "greyDot70"
|
"lineSeparatorColor": "greyDot70"
|
||||||
},
|
},
|
||||||
"InformationHint.borderColor": "greyDot75",
|
"InformationHint": {
|
||||||
"InplaceRefactoringPopup.borderColor": "greyDot75",
|
"borderColor": "border"
|
||||||
|
},
|
||||||
|
"InplaceRefactoringPopup.borderColor": "border",
|
||||||
"Label": {
|
"Label": {
|
||||||
"disabledForeground": "greyDot33",
|
"disabledForeground": "greyDot33",
|
||||||
"disabledText": "greyDot33",
|
"disabledText": "greyDot33",
|
||||||
"foreground": "greyDot20",
|
"foreground": "greyDot20",
|
||||||
"infoForeground": "greyDot50"
|
"infoForeground": "greyDot50"
|
||||||
},
|
},
|
||||||
|
"Link": {
|
||||||
|
"activeForeground": "blue",
|
||||||
|
"hoverForeground": "yellow",
|
||||||
|
"secondaryForeground": "lightBlue",
|
||||||
|
"visitedForeground": "purpleMonokaiPro",
|
||||||
|
"pressedForeground": "deepBlue"
|
||||||
|
},
|
||||||
"Link.hoverForeground": "yellow",
|
"Link.hoverForeground": "yellow",
|
||||||
"MemoryIndicator.allocatedBackground": "green",
|
"MemoryIndicator.allocatedBackground": "green",
|
||||||
"MemoryIndicator.usedBackground": "red",
|
"MemoryIndicator.usedBackground": "red",
|
||||||
@@ -209,16 +236,20 @@
|
|||||||
"Notification.ToolWindow.errorBackground": "greyDot95",
|
"Notification.ToolWindow.errorBackground": "greyDot95",
|
||||||
"Notification.ToolWindow.errorBorderColor": "red",
|
"Notification.ToolWindow.errorBorderColor": "red",
|
||||||
"Notification.ToolWindow.errorForeground": "#EE7762",
|
"Notification.ToolWindow.errorForeground": "#EE7762",
|
||||||
"Notification.ToolWindow.informativeBackground": "greyDot95",
|
"Notification.ToolWindow.informativeBackground": "editorPaneBg",
|
||||||
"Notification.ToolWindow.informativeBorderColor": "#92D923",
|
"Notification.ToolWindow.informativeBorderColor": "border",
|
||||||
"Notification.ToolWindow.informativeForeground": "#92D923",
|
"Notification.ToolWindow.informativeForeground": "textColor",
|
||||||
"Notification.ToolWindow.warningBackground": "greyDot95",
|
"Notification.ToolWindow.warningBackground": "greyDot95",
|
||||||
"Notification.ToolWindow.warningBorderColor": "yellow",
|
"Notification.ToolWindow.warningBorderColor": "yellow",
|
||||||
"Notification.ToolWindow.warningForeground": "yellow",
|
"Notification.ToolWindow.warningForeground": "yellow",
|
||||||
"Notification.background": "greyDot95",
|
"Notification.background": "editorPaneBg",
|
||||||
|
"Notification.borderColor": "border",
|
||||||
"Notification.errorBackground": "greyDot95",
|
"Notification.errorBackground": "greyDot95",
|
||||||
"Notification.errorBorderColor": "red",
|
"Notification.errorBorderColor": "red",
|
||||||
"Notification.errorForeground": "#EE7762",
|
"Notification.errorForeground": "#EE7762",
|
||||||
|
"Notification.foreground": "textColor",
|
||||||
|
"NotificationsToolwindow.newNotification.background": "editorPaneBg",
|
||||||
|
"NotificationsToolwindow.newNotification.hoverBackground": "greyDot95",
|
||||||
"OptionPane": {
|
"OptionPane": {
|
||||||
"background": "editorPaneBg",
|
"background": "editorPaneBg",
|
||||||
"foreground": "greyDot20"
|
"foreground": "greyDot20"
|
||||||
@@ -245,11 +276,11 @@
|
|||||||
"Plugins.Tab.hoverBackground": "editorBg",
|
"Plugins.Tab.hoverBackground": "editorBg",
|
||||||
"Plugins.Tab.selectedBackground": "editorPaneBg",
|
"Plugins.Tab.selectedBackground": "editorPaneBg",
|
||||||
"Plugins.background": "editorPaneBg",
|
"Plugins.background": "editorPaneBg",
|
||||||
"Plugins.lightSelectionBackground": "#242220",
|
|
||||||
"Plugins.disabledForeground": "greyDot50",
|
"Plugins.disabledForeground": "greyDot50",
|
||||||
|
"Plugins.hoverBackground": "editorBg",
|
||||||
|
"Plugins.lightSelectionBackground": "#242220",
|
||||||
"Plugins.tagBackground": "editorBg",
|
"Plugins.tagBackground": "editorBg",
|
||||||
"Plugins.tagForeground": "greyDot33",
|
"Plugins.tagForeground": "greyDot33",
|
||||||
"Plugins.hoverBackground": "editorBg",
|
|
||||||
"Popup.Advertiser.background": "greyDot85",
|
"Popup.Advertiser.background": "greyDot85",
|
||||||
"Popup.Advertiser.foreground": "greyDot50",
|
"Popup.Advertiser.foreground": "greyDot50",
|
||||||
"Popup.Header.activeBackground": "greyDot75",
|
"Popup.Header.activeBackground": "greyDot75",
|
||||||
|
|||||||
@@ -97,9 +97,10 @@
|
|||||||
},
|
},
|
||||||
"EditorPane.inactiveBackground": "#2b303b",
|
"EditorPane.inactiveBackground": "#2b303b",
|
||||||
"EditorTabs": {
|
"EditorTabs": {
|
||||||
"underlinedTabBackground": "#2b303b",
|
"borderColor": "#2b303b",
|
||||||
"underlineHeight": "0",
|
"underlinedTabBackground": "2b303b",
|
||||||
"borderColor": "#2b303b"
|
"background": "#1c1f26",
|
||||||
|
"underlineHeight": "2"
|
||||||
},
|
},
|
||||||
"Link": {
|
"Link": {
|
||||||
"activeForeground": "#7FA1B3",
|
"activeForeground": "#7FA1B3",
|
||||||
|
|||||||
@@ -7,23 +7,23 @@
|
|||||||
"bg30": "#2f343f30",
|
"bg30": "#2f343f30",
|
||||||
"fg": "#D3DAE3",
|
"fg": "#D3DAE3",
|
||||||
"text": "#8b9eb5",
|
"text": "#8b9eb5",
|
||||||
"selBg": "#8888FF",
|
"selBg": "#414181",
|
||||||
"selBg20": "#8888FF20",
|
"selBg20": "#41418120",
|
||||||
"selFg": "#FFFFFF",
|
"selFg": "#FFFFFF",
|
||||||
"activeFg": "#FFFFFF",
|
"activeFg": "#FFFFFF",
|
||||||
"border": "#404552",
|
"border": "#404552",
|
||||||
"excl": "#37373d",
|
"excl": "#37373d",
|
||||||
"second": "#393f4c45",
|
"second": "#393f4c",
|
||||||
"dis": "#D3DAE3",
|
"dis": "#a2a2a2",
|
||||||
"accent": "#42A5F5",
|
"accent": "#5294E2",
|
||||||
"accent2": "#42A5F52",
|
"accent2": "#5294E22",
|
||||||
"accent50": "#42A5F550",
|
"accent50": "#5294E250",
|
||||||
"accent70": "#42A5F570",
|
"accent70": "#5294E270",
|
||||||
"cs": "#262b33",
|
"cs": "#262b33",
|
||||||
"button": "#383C4A",
|
"button": "#383C4A",
|
||||||
"table": "#41416A",
|
"table": "#41416A",
|
||||||
"tree": "#09477170",
|
"tree": "#09477170",
|
||||||
"hl": "#393f4c",
|
"hl": "#444A58",
|
||||||
"notif": "#262a33",
|
"notif": "#262a33",
|
||||||
"hc": "#262b33",
|
"hc": "#262b33",
|
||||||
"shadow": "undefined",
|
"shadow": "undefined",
|
||||||
@@ -76,6 +76,11 @@
|
|||||||
"ActionToolbar": {
|
"ActionToolbar": {
|
||||||
"background": "hc"
|
"background": "hc"
|
||||||
},
|
},
|
||||||
|
"AppInspector.GraphNode": {
|
||||||
|
"background": "second",
|
||||||
|
"borderColor": "border",
|
||||||
|
"focusedBorderColor": "accent"
|
||||||
|
},
|
||||||
"AssignedMnemonic": {
|
"AssignedMnemonic": {
|
||||||
"background": "hl",
|
"background": "hl",
|
||||||
"borderColor": "selBg",
|
"borderColor": "selBg",
|
||||||
@@ -599,7 +604,7 @@
|
|||||||
"link.pressed.foreground": "accent",
|
"link.pressed.foreground": "accent",
|
||||||
"link.visited.foreground": "accent",
|
"link.visited.foreground": "accent",
|
||||||
"List": {
|
"List": {
|
||||||
"background": "second",
|
"background": "bg",
|
||||||
"foreground": "fg",
|
"foreground": "fg",
|
||||||
"hoverBackground": "hl",
|
"hoverBackground": "hl",
|
||||||
"hoverInactiveBackground": "table",
|
"hoverInactiveBackground": "table",
|
||||||
@@ -884,6 +889,9 @@
|
|||||||
"selectionBackground": "hl",
|
"selectionBackground": "hl",
|
||||||
"trackColor": "hl"
|
"trackColor": "hl"
|
||||||
},
|
},
|
||||||
|
"ProgressIcon": {
|
||||||
|
"color": "accent"
|
||||||
|
},
|
||||||
"PsiViewer": {
|
"PsiViewer": {
|
||||||
"referenceHighlightColor": "accent"
|
"referenceHighlightColor": "accent"
|
||||||
},
|
},
|
||||||
@@ -914,6 +922,13 @@
|
|||||||
"selectionBackground": "selBg",
|
"selectionBackground": "selBg",
|
||||||
"selectionForeground": "selFg"
|
"selectionForeground": "selFg"
|
||||||
},
|
},
|
||||||
|
"RunWidget": {
|
||||||
|
"Running": {
|
||||||
|
"background": "accent",
|
||||||
|
"leftHoverBackground": "accent70",
|
||||||
|
"leftPressedBackground": "accent"
|
||||||
|
}
|
||||||
|
},
|
||||||
"ScreenView.borderColor": "border",
|
"ScreenView.borderColor": "border",
|
||||||
"scrollbar": "bg",
|
"scrollbar": "bg",
|
||||||
"ScrollBar": {
|
"ScrollBar": {
|
||||||
@@ -1008,6 +1023,8 @@
|
|||||||
"Repeated.File.Foreground": "fg"
|
"Repeated.File.Foreground": "fg"
|
||||||
},
|
},
|
||||||
"SegmentedButton": {
|
"SegmentedButton": {
|
||||||
|
"focusedSelectedButtonColor": "hl",
|
||||||
|
"selectedButtonColor": "button",
|
||||||
"selectedStartBorderColor": "border",
|
"selectedStartBorderColor": "border",
|
||||||
"selectedEndBorderColor": "border"
|
"selectedEndBorderColor": "border"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -7,23 +7,23 @@
|
|||||||
"bg30": "#2f343f30",
|
"bg30": "#2f343f30",
|
||||||
"fg": "#D3DAE3",
|
"fg": "#D3DAE3",
|
||||||
"text": "#8b9eb5",
|
"text": "#8b9eb5",
|
||||||
"selBg": "#8888FF",
|
"selBg": "#414181",
|
||||||
"selBg20": "#8888FF20",
|
"selBg20": "#41418120",
|
||||||
"selFg": "#FFFFFF",
|
"selFg": "#FFFFFF",
|
||||||
"activeFg": "#FFFFFF",
|
"activeFg": "#FFFFFF",
|
||||||
"border": "#404552",
|
"border": "#404552",
|
||||||
"excl": "#37373d",
|
"excl": "#37373d",
|
||||||
"second": "#393f4c45",
|
"second": "#393f4c",
|
||||||
"dis": "#D3DAE3",
|
"dis": "#a2a2a2",
|
||||||
"accent": "#42A5F5",
|
"accent": "#5294E2",
|
||||||
"accent2": "#42A5F52",
|
"accent2": "#5294E22",
|
||||||
"accent50": "#42A5F550",
|
"accent50": "#5294E250",
|
||||||
"accent70": "#42A5F570",
|
"accent70": "#5294E270",
|
||||||
"cs": "#262b33",
|
"cs": "#262b33",
|
||||||
"button": "#383C4A",
|
"button": "#383C4A",
|
||||||
"table": "#41416A",
|
"table": "#41416A",
|
||||||
"tree": "#09477170",
|
"tree": "#09477170",
|
||||||
"hl": "#393f4c",
|
"hl": "#444A58",
|
||||||
"notif": "#262a33",
|
"notif": "#262a33",
|
||||||
"hc": "#2f343f",
|
"hc": "#2f343f",
|
||||||
"shadow": "undefined",
|
"shadow": "undefined",
|
||||||
@@ -76,6 +76,11 @@
|
|||||||
"ActionToolbar": {
|
"ActionToolbar": {
|
||||||
"background": "hc"
|
"background": "hc"
|
||||||
},
|
},
|
||||||
|
"AppInspector.GraphNode": {
|
||||||
|
"background": "second",
|
||||||
|
"borderColor": "border",
|
||||||
|
"focusedBorderColor": "accent"
|
||||||
|
},
|
||||||
"AssignedMnemonic": {
|
"AssignedMnemonic": {
|
||||||
"background": "hl",
|
"background": "hl",
|
||||||
"borderColor": "selBg",
|
"borderColor": "selBg",
|
||||||
@@ -599,7 +604,7 @@
|
|||||||
"link.pressed.foreground": "accent",
|
"link.pressed.foreground": "accent",
|
||||||
"link.visited.foreground": "accent",
|
"link.visited.foreground": "accent",
|
||||||
"List": {
|
"List": {
|
||||||
"background": "second",
|
"background": "bg",
|
||||||
"foreground": "fg",
|
"foreground": "fg",
|
||||||
"hoverBackground": "hl",
|
"hoverBackground": "hl",
|
||||||
"hoverInactiveBackground": "table",
|
"hoverInactiveBackground": "table",
|
||||||
@@ -884,6 +889,9 @@
|
|||||||
"selectionBackground": "hl",
|
"selectionBackground": "hl",
|
||||||
"trackColor": "hl"
|
"trackColor": "hl"
|
||||||
},
|
},
|
||||||
|
"ProgressIcon": {
|
||||||
|
"color": "accent"
|
||||||
|
},
|
||||||
"PsiViewer": {
|
"PsiViewer": {
|
||||||
"referenceHighlightColor": "accent"
|
"referenceHighlightColor": "accent"
|
||||||
},
|
},
|
||||||
@@ -914,6 +922,13 @@
|
|||||||
"selectionBackground": "selBg",
|
"selectionBackground": "selBg",
|
||||||
"selectionForeground": "selFg"
|
"selectionForeground": "selFg"
|
||||||
},
|
},
|
||||||
|
"RunWidget": {
|
||||||
|
"Running": {
|
||||||
|
"background": "accent",
|
||||||
|
"leftHoverBackground": "accent70",
|
||||||
|
"leftPressedBackground": "accent"
|
||||||
|
}
|
||||||
|
},
|
||||||
"ScreenView.borderColor": "border",
|
"ScreenView.borderColor": "border",
|
||||||
"scrollbar": "bg",
|
"scrollbar": "bg",
|
||||||
"ScrollBar": {
|
"ScrollBar": {
|
||||||
@@ -1008,6 +1023,8 @@
|
|||||||
"Repeated.File.Foreground": "fg"
|
"Repeated.File.Foreground": "fg"
|
||||||
},
|
},
|
||||||
"SegmentedButton": {
|
"SegmentedButton": {
|
||||||
|
"focusedSelectedButtonColor": "hl",
|
||||||
|
"selectedButtonColor": "button",
|
||||||
"selectedStartBorderColor": "border",
|
"selectedStartBorderColor": "border",
|
||||||
"selectedEndBorderColor": "border"
|
"selectedEndBorderColor": "border"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -76,6 +76,11 @@
|
|||||||
"ActionToolbar": {
|
"ActionToolbar": {
|
||||||
"background": "hc"
|
"background": "hc"
|
||||||
},
|
},
|
||||||
|
"AppInspector.GraphNode": {
|
||||||
|
"background": "second",
|
||||||
|
"borderColor": "border",
|
||||||
|
"focusedBorderColor": "accent"
|
||||||
|
},
|
||||||
"AssignedMnemonic": {
|
"AssignedMnemonic": {
|
||||||
"background": "hl",
|
"background": "hl",
|
||||||
"borderColor": "selBg",
|
"borderColor": "selBg",
|
||||||
@@ -599,7 +604,7 @@
|
|||||||
"link.pressed.foreground": "accent",
|
"link.pressed.foreground": "accent",
|
||||||
"link.visited.foreground": "accent",
|
"link.visited.foreground": "accent",
|
||||||
"List": {
|
"List": {
|
||||||
"background": "second",
|
"background": "bg",
|
||||||
"foreground": "fg",
|
"foreground": "fg",
|
||||||
"hoverBackground": "hl",
|
"hoverBackground": "hl",
|
||||||
"hoverInactiveBackground": "table",
|
"hoverInactiveBackground": "table",
|
||||||
@@ -884,6 +889,9 @@
|
|||||||
"selectionBackground": "hl",
|
"selectionBackground": "hl",
|
||||||
"trackColor": "hl"
|
"trackColor": "hl"
|
||||||
},
|
},
|
||||||
|
"ProgressIcon": {
|
||||||
|
"color": "accent"
|
||||||
|
},
|
||||||
"PsiViewer": {
|
"PsiViewer": {
|
||||||
"referenceHighlightColor": "accent"
|
"referenceHighlightColor": "accent"
|
||||||
},
|
},
|
||||||
@@ -914,6 +922,13 @@
|
|||||||
"selectionBackground": "selBg",
|
"selectionBackground": "selBg",
|
||||||
"selectionForeground": "selFg"
|
"selectionForeground": "selFg"
|
||||||
},
|
},
|
||||||
|
"RunWidget": {
|
||||||
|
"Running": {
|
||||||
|
"background": "accent",
|
||||||
|
"leftHoverBackground": "accent70",
|
||||||
|
"leftPressedBackground": "accent"
|
||||||
|
}
|
||||||
|
},
|
||||||
"ScreenView.borderColor": "border",
|
"ScreenView.borderColor": "border",
|
||||||
"scrollbar": "bg",
|
"scrollbar": "bg",
|
||||||
"ScrollBar": {
|
"ScrollBar": {
|
||||||
@@ -1008,6 +1023,8 @@
|
|||||||
"Repeated.File.Foreground": "fg"
|
"Repeated.File.Foreground": "fg"
|
||||||
},
|
},
|
||||||
"SegmentedButton": {
|
"SegmentedButton": {
|
||||||
|
"focusedSelectedButtonColor": "hl",
|
||||||
|
"selectedButtonColor": "button",
|
||||||
"selectedStartBorderColor": "border",
|
"selectedStartBorderColor": "border",
|
||||||
"selectedEndBorderColor": "border"
|
"selectedEndBorderColor": "border"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -76,6 +76,11 @@
|
|||||||
"ActionToolbar": {
|
"ActionToolbar": {
|
||||||
"background": "hc"
|
"background": "hc"
|
||||||
},
|
},
|
||||||
|
"AppInspector.GraphNode": {
|
||||||
|
"background": "second",
|
||||||
|
"borderColor": "border",
|
||||||
|
"focusedBorderColor": "accent"
|
||||||
|
},
|
||||||
"AssignedMnemonic": {
|
"AssignedMnemonic": {
|
||||||
"background": "hl",
|
"background": "hl",
|
||||||
"borderColor": "selBg",
|
"borderColor": "selBg",
|
||||||
@@ -599,7 +604,7 @@
|
|||||||
"link.pressed.foreground": "accent",
|
"link.pressed.foreground": "accent",
|
||||||
"link.visited.foreground": "accent",
|
"link.visited.foreground": "accent",
|
||||||
"List": {
|
"List": {
|
||||||
"background": "second",
|
"background": "bg",
|
||||||
"foreground": "fg",
|
"foreground": "fg",
|
||||||
"hoverBackground": "hl",
|
"hoverBackground": "hl",
|
||||||
"hoverInactiveBackground": "table",
|
"hoverInactiveBackground": "table",
|
||||||
@@ -884,6 +889,9 @@
|
|||||||
"selectionBackground": "hl",
|
"selectionBackground": "hl",
|
||||||
"trackColor": "hl"
|
"trackColor": "hl"
|
||||||
},
|
},
|
||||||
|
"ProgressIcon": {
|
||||||
|
"color": "accent"
|
||||||
|
},
|
||||||
"PsiViewer": {
|
"PsiViewer": {
|
||||||
"referenceHighlightColor": "accent"
|
"referenceHighlightColor": "accent"
|
||||||
},
|
},
|
||||||
@@ -914,6 +922,13 @@
|
|||||||
"selectionBackground": "selBg",
|
"selectionBackground": "selBg",
|
||||||
"selectionForeground": "selFg"
|
"selectionForeground": "selFg"
|
||||||
},
|
},
|
||||||
|
"RunWidget": {
|
||||||
|
"Running": {
|
||||||
|
"background": "accent",
|
||||||
|
"leftHoverBackground": "accent70",
|
||||||
|
"leftPressedBackground": "accent"
|
||||||
|
}
|
||||||
|
},
|
||||||
"ScreenView.borderColor": "border",
|
"ScreenView.borderColor": "border",
|
||||||
"scrollbar": "bg",
|
"scrollbar": "bg",
|
||||||
"ScrollBar": {
|
"ScrollBar": {
|
||||||
@@ -1008,6 +1023,8 @@
|
|||||||
"Repeated.File.Foreground": "fg"
|
"Repeated.File.Foreground": "fg"
|
||||||
},
|
},
|
||||||
"SegmentedButton": {
|
"SegmentedButton": {
|
||||||
|
"focusedSelectedButtonColor": "hl",
|
||||||
|
"selectedButtonColor": "button",
|
||||||
"selectedStartBorderColor": "border",
|
"selectedStartBorderColor": "border",
|
||||||
"selectedEndBorderColor": "border"
|
"selectedEndBorderColor": "border"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -19,13 +19,13 @@
|
|||||||
"accent2": "#2979ff2",
|
"accent2": "#2979ff2",
|
||||||
"accent50": "#2979ff50",
|
"accent50": "#2979ff50",
|
||||||
"accent70": "#2979ff70",
|
"accent70": "#2979ff70",
|
||||||
"cs": "#eaeae",
|
"cs": "#eaeaeb",
|
||||||
"button": "#DBDBDC",
|
"button": "#DBDBDC",
|
||||||
"table": "#DBDBDC",
|
"table": "#DBDBDC",
|
||||||
"tree": "#DBDBDC80",
|
"tree": "#DBDBDC80",
|
||||||
"hl": "#FFFFFF",
|
"hl": "#FFFFFF",
|
||||||
"notif": "#F2F2F2",
|
"notif": "#F2F2F2",
|
||||||
"hc": "#eaeae",
|
"hc": "#eaeaeb",
|
||||||
"shadow": "undefined",
|
"shadow": "undefined",
|
||||||
"white": "#986801",
|
"white": "#986801",
|
||||||
"blue": "#4078F2",
|
"blue": "#4078F2",
|
||||||
@@ -76,6 +76,11 @@
|
|||||||
"ActionToolbar": {
|
"ActionToolbar": {
|
||||||
"background": "hc"
|
"background": "hc"
|
||||||
},
|
},
|
||||||
|
"AppInspector.GraphNode": {
|
||||||
|
"background": "second",
|
||||||
|
"borderColor": "border",
|
||||||
|
"focusedBorderColor": "accent"
|
||||||
|
},
|
||||||
"AssignedMnemonic": {
|
"AssignedMnemonic": {
|
||||||
"background": "hl",
|
"background": "hl",
|
||||||
"borderColor": "selBg",
|
"borderColor": "selBg",
|
||||||
@@ -599,7 +604,7 @@
|
|||||||
"link.pressed.foreground": "accent",
|
"link.pressed.foreground": "accent",
|
||||||
"link.visited.foreground": "accent",
|
"link.visited.foreground": "accent",
|
||||||
"List": {
|
"List": {
|
||||||
"background": "second",
|
"background": "bg",
|
||||||
"foreground": "fg",
|
"foreground": "fg",
|
||||||
"hoverBackground": "hl",
|
"hoverBackground": "hl",
|
||||||
"hoverInactiveBackground": "table",
|
"hoverInactiveBackground": "table",
|
||||||
@@ -884,6 +889,9 @@
|
|||||||
"selectionBackground": "hl",
|
"selectionBackground": "hl",
|
||||||
"trackColor": "hl"
|
"trackColor": "hl"
|
||||||
},
|
},
|
||||||
|
"ProgressIcon": {
|
||||||
|
"color": "accent"
|
||||||
|
},
|
||||||
"PsiViewer": {
|
"PsiViewer": {
|
||||||
"referenceHighlightColor": "accent"
|
"referenceHighlightColor": "accent"
|
||||||
},
|
},
|
||||||
@@ -914,6 +922,13 @@
|
|||||||
"selectionBackground": "selBg",
|
"selectionBackground": "selBg",
|
||||||
"selectionForeground": "selFg"
|
"selectionForeground": "selFg"
|
||||||
},
|
},
|
||||||
|
"RunWidget": {
|
||||||
|
"Running": {
|
||||||
|
"background": "accent",
|
||||||
|
"leftHoverBackground": "accent70",
|
||||||
|
"leftPressedBackground": "accent"
|
||||||
|
}
|
||||||
|
},
|
||||||
"ScreenView.borderColor": "border",
|
"ScreenView.borderColor": "border",
|
||||||
"scrollbar": "bg",
|
"scrollbar": "bg",
|
||||||
"ScrollBar": {
|
"ScrollBar": {
|
||||||
@@ -1008,6 +1023,8 @@
|
|||||||
"Repeated.File.Foreground": "fg"
|
"Repeated.File.Foreground": "fg"
|
||||||
},
|
},
|
||||||
"SegmentedButton": {
|
"SegmentedButton": {
|
||||||
|
"focusedSelectedButtonColor": "hl",
|
||||||
|
"selectedButtonColor": "button",
|
||||||
"selectedStartBorderColor": "border",
|
"selectedStartBorderColor": "border",
|
||||||
"selectedEndBorderColor": "border"
|
"selectedEndBorderColor": "border"
|
||||||
},
|
},
|
||||||
|
|||||||