mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2026-02-12 06:57:13 -06:00
Compare commits
41 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bfbd25012a | ||
|
|
063fff2ab4 | ||
|
|
fbdc8d5b99 | ||
|
|
625c0a3321 | ||
|
|
2972300112 | ||
|
|
a8e71895ee | ||
|
|
d7a76081e3 | ||
|
|
fd925a6718 | ||
|
|
4fc890a77c | ||
|
|
b804463b73 | ||
|
|
8f161b4b5a | ||
|
|
c6338169f3 | ||
|
|
6cea24ed9e | ||
|
|
3d8eb9eb66 | ||
|
|
a84aceb1ba | ||
|
|
8adb7e3021 | ||
|
|
bc0d5dc9b5 | ||
|
|
1d935d6659 | ||
|
|
445466acd0 | ||
|
|
30af74f806 | ||
|
|
16ddd100d3 | ||
|
|
c946ec170d | ||
|
|
ca514dd76e | ||
|
|
cf44a5c50b | ||
|
|
91b8c02c7f | ||
|
|
ca3b2b4b07 | ||
|
|
722dde63df | ||
|
|
c85baf4dc6 | ||
|
|
96b7770ab2 | ||
|
|
0c00117820 | ||
|
|
3465fa68b4 | ||
|
|
28278a75a7 | ||
|
|
f68a871dd6 | ||
|
|
93d424cfe1 | ||
|
|
a1adde0888 | ||
|
|
13528b49cb | ||
|
|
f3be3f2d1c | ||
|
|
241fe855cc | ||
|
|
ea2447dcb7 | ||
|
|
f40baed65e | ||
|
|
eed11d211b |
24
.github/workflows/ci.yml
vendored
24
.github/workflows/ci.yml
vendored
@@ -9,6 +9,14 @@ on:
|
|||||||
- '*'
|
- '*'
|
||||||
tags:
|
tags:
|
||||||
- '[0-9]*'
|
- '[0-9]*'
|
||||||
|
paths-ignore:
|
||||||
|
- '**.md'
|
||||||
|
- '.*'
|
||||||
|
- '**/.settings/**'
|
||||||
|
- 'flatlaf-core/svg/**'
|
||||||
|
- 'flatlaf-testing/dumps/**'
|
||||||
|
- 'flatlaf-testing/misc/**'
|
||||||
|
- 'images/**'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
@@ -30,13 +38,13 @@ jobs:
|
|||||||
toolchain: 21 # latest
|
toolchain: 21 # latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- uses: gradle/wrapper-validation-action@v1
|
- uses: gradle/wrapper-validation-action@v2
|
||||||
if: matrix.java == '8'
|
if: matrix.java == '8'
|
||||||
|
|
||||||
- name: Setup Java ${{ matrix.java }}
|
- name: Setup Java ${{ matrix.java }}
|
||||||
uses: actions/setup-java@v3
|
uses: actions/setup-java@v4
|
||||||
with:
|
with:
|
||||||
java-version: ${{ matrix.java }}
|
java-version: ${{ matrix.java }}
|
||||||
distribution: temurin # Java 8, 11 and 17 are pre-installed on ubuntu-latest
|
distribution: temurin # Java 8, 11 and 17 are pre-installed on ubuntu-latest
|
||||||
@@ -50,7 +58,7 @@ jobs:
|
|||||||
run: ./gradlew build -Dtoolchain=${{ matrix.toolchain }}
|
run: ./gradlew build -Dtoolchain=${{ matrix.toolchain }}
|
||||||
|
|
||||||
- name: Upload artifacts
|
- name: Upload artifacts
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v4
|
||||||
if: matrix.java == '11'
|
if: matrix.java == '11'
|
||||||
with:
|
with:
|
||||||
name: FlatLaf-build-artifacts
|
name: FlatLaf-build-artifacts
|
||||||
@@ -70,10 +78,10 @@ jobs:
|
|||||||
github.repository == 'JFormDesigner/FlatLaf'
|
github.repository == 'JFormDesigner/FlatLaf'
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Setup Java 11
|
- name: Setup Java 11
|
||||||
uses: actions/setup-java@v3
|
uses: actions/setup-java@v4
|
||||||
with:
|
with:
|
||||||
java-version: 11
|
java-version: 11
|
||||||
distribution: temurin # pre-installed on ubuntu-latest
|
distribution: temurin # pre-installed on ubuntu-latest
|
||||||
@@ -106,10 +114,10 @@ jobs:
|
|||||||
github.repository == 'JFormDesigner/FlatLaf'
|
github.repository == 'JFormDesigner/FlatLaf'
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Setup Java 11
|
- name: Setup Java 11
|
||||||
uses: actions/setup-java@v3
|
uses: actions/setup-java@v4
|
||||||
with:
|
with:
|
||||||
java-version: 11
|
java-version: 11
|
||||||
distribution: temurin # pre-installed on ubuntu-latest
|
distribution: temurin # pre-installed on ubuntu-latest
|
||||||
|
|||||||
6
.github/workflows/fonts.yml
vendored
6
.github/workflows/fonts.yml
vendored
@@ -13,6 +13,8 @@ on:
|
|||||||
- 'flatlaf-fonts/**'
|
- 'flatlaf-fonts/**'
|
||||||
- '.github/workflows/fonts.yml'
|
- '.github/workflows/fonts.yml'
|
||||||
- 'gradle/wrapper/gradle-wrapper.properties'
|
- 'gradle/wrapper/gradle-wrapper.properties'
|
||||||
|
- '!**.md'
|
||||||
|
- '!**/.settings/**'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
Fonts:
|
Fonts:
|
||||||
@@ -30,10 +32,10 @@ jobs:
|
|||||||
github.repository == 'JFormDesigner/FlatLaf'
|
github.repository == 'JFormDesigner/FlatLaf'
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Setup Java 11
|
- name: Setup Java 11
|
||||||
uses: actions/setup-java@v3
|
uses: actions/setup-java@v4
|
||||||
with:
|
with:
|
||||||
java-version: 11
|
java-version: 11
|
||||||
distribution: temurin # pre-installed on ubuntu-latest
|
distribution: temurin # pre-installed on ubuntu-latest
|
||||||
|
|||||||
10
.github/workflows/natives.yml
vendored
10
.github/workflows/natives.yml
vendored
@@ -13,6 +13,8 @@ on:
|
|||||||
- 'flatlaf-natives/**'
|
- 'flatlaf-natives/**'
|
||||||
- '.github/workflows/natives.yml'
|
- '.github/workflows/natives.yml'
|
||||||
- 'gradle/wrapper/gradle-wrapper.properties'
|
- 'gradle/wrapper/gradle-wrapper.properties'
|
||||||
|
- '!**.md'
|
||||||
|
- '!**/.settings/**'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
Natives:
|
Natives:
|
||||||
@@ -26,12 +28,12 @@ jobs:
|
|||||||
runs-on: ${{ matrix.os }}-latest
|
runs-on: ${{ matrix.os }}-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
- uses: gradle/wrapper-validation-action@v1
|
- uses: gradle/wrapper-validation-action@v2
|
||||||
|
|
||||||
- name: Setup Java 11
|
- name: Setup Java 11
|
||||||
uses: actions/setup-java@v3
|
uses: actions/setup-java@v4
|
||||||
with:
|
with:
|
||||||
java-version: 11
|
java-version: 11
|
||||||
distribution: temurin
|
distribution: temurin
|
||||||
@@ -43,7 +45,7 @@ jobs:
|
|||||||
run: ./gradlew 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@v4
|
||||||
with:
|
with:
|
||||||
name: FlatLaf-natives-build-artifacts-${{ matrix.os }}
|
name: FlatLaf-natives-build-artifacts-${{ matrix.os }}
|
||||||
path: |
|
path: |
|
||||||
|
|||||||
37
.github/workflows/pr-snapshots.yml
vendored
Normal file
37
.github/workflows/pr-snapshots.yml
vendored
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
# https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions
|
||||||
|
|
||||||
|
name: PR Snapshots
|
||||||
|
|
||||||
|
on:
|
||||||
|
pull_request:
|
||||||
|
paths-ignore:
|
||||||
|
- '**.md'
|
||||||
|
- '.*'
|
||||||
|
- '**/.settings/**'
|
||||||
|
- 'flatlaf-core/svg/**'
|
||||||
|
- 'flatlaf-testing/dumps/**'
|
||||||
|
- 'flatlaf-testing/misc/**'
|
||||||
|
- 'images/**'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
snapshot:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: github.repository == 'JFormDesigner/FlatLaf'
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Setup Java 11
|
||||||
|
uses: actions/setup-java@v4
|
||||||
|
with:
|
||||||
|
java-version: 11
|
||||||
|
distribution: temurin # pre-installed on ubuntu-latest
|
||||||
|
cache: gradle
|
||||||
|
|
||||||
|
- name: Publish PR snapshot to oss.sonatype.org
|
||||||
|
run: >
|
||||||
|
./gradlew publish -PskipFonts -Dorg.gradle.internal.publish.checksums.insecure=true -Dorg.gradle.parallel=false
|
||||||
|
-Pgithub.event.pull_request.number=${{ github.event.pull_request.number }}
|
||||||
|
env:
|
||||||
|
OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }}
|
||||||
|
OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }}
|
||||||
33
CHANGELOG.md
33
CHANGELOG.md
@@ -1,6 +1,39 @@
|
|||||||
FlatLaf Change Log
|
FlatLaf Change Log
|
||||||
==================
|
==================
|
||||||
|
|
||||||
|
## 3.4
|
||||||
|
|
||||||
|
#### New features and improvements
|
||||||
|
|
||||||
|
- FlatLaf window decorations (Windows 10/11 and Linux): Support "full window
|
||||||
|
content" mode, which allows you to extend the content into the window title
|
||||||
|
bar. (PR #801)
|
||||||
|
- macOS: Support larger window title bar close/minimize/zoom buttons spacing in
|
||||||
|
[full window content](https://www.formdev.com/flatlaf/macos/#full_window_content)
|
||||||
|
mode and introduced "buttons placeholder". (PR #779)
|
||||||
|
- Native libraries:
|
||||||
|
- System property `flatlaf.nativeLibraryPath` now supports loading native
|
||||||
|
libraries named the same as on Maven central.
|
||||||
|
- Published `flatlaf-<version>-no-natives.jar` to Maven Central. This JAR is
|
||||||
|
equal to `flatlaf-<version>.jar`, except that it does not contain the
|
||||||
|
FlatLaf native libraries. The Maven "classifier" to use this JAR is
|
||||||
|
`no-natives`. You need to distribute the FlatLaf native libraries with your
|
||||||
|
application.
|
||||||
|
See https://www.formdev.com/flatlaf/native-libraries/ for more details.
|
||||||
|
- Improved log messages for loading fails.
|
||||||
|
- Fonts: Updated **Inter** to
|
||||||
|
[v4.0](https://github.com/rsms/inter/releases/tag/v4.0).
|
||||||
|
- Table: Select all text in cell editor when starting editing using `F2` key.
|
||||||
|
(issue 652)
|
||||||
|
|
||||||
|
#### Fixed bugs
|
||||||
|
|
||||||
|
- macOS: Setting window background (of undecorated window) to translucent color
|
||||||
|
(alpha < 255) did not show the window translucent. (issue #705)
|
||||||
|
- JIDE CommandMenuBar: Fixed `ClassCastException` when JIDE command bar displays
|
||||||
|
`JideMenu` in popup. (PR #794)
|
||||||
|
|
||||||
|
|
||||||
## 3.3
|
## 3.3
|
||||||
|
|
||||||
#### New features and improvements
|
#### New features and improvements
|
||||||
|
|||||||
@@ -18,6 +18,12 @@ import net.ltgt.gradle.errorprone.errorprone
|
|||||||
|
|
||||||
version = property( if( hasProperty( "release" ) ) "flatlaf.releaseVersion" else "flatlaf.developmentVersion" ) as String
|
version = property( if( hasProperty( "release" ) ) "flatlaf.releaseVersion" else "flatlaf.developmentVersion" ) as String
|
||||||
|
|
||||||
|
// for PR snapshots change version to 'PR-<pr_number>-SNAPSHOT'
|
||||||
|
val pullRequestNumber = findProperty( "github.event.pull_request.number" )
|
||||||
|
if( pullRequestNumber != null )
|
||||||
|
version = "PR-${pullRequestNumber}-SNAPSHOT"
|
||||||
|
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
version = rootProject.version
|
version = rootProject.version
|
||||||
|
|
||||||
|
|||||||
@@ -124,7 +124,7 @@ tasks.withType<Sign>().configureEach {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check whether parallel build is enabled
|
// check whether parallel build is enabled
|
||||||
tasks.withType<PublishToMavenRepository>().configureEach {
|
tasks.withType<AbstractPublishToMaven>().configureEach {
|
||||||
doFirst {
|
doFirst {
|
||||||
if( System.getProperty( "org.gradle.parallel" ) == "true" )
|
if( System.getProperty( "org.gradle.parallel" ) == "true" )
|
||||||
throw RuntimeException( "Publishing does not work correctly with enabled parallel build. Disable parallel build with VM option '-Dorg.gradle.parallel=false'." )
|
throw RuntimeException( "Publishing does not work correctly with enabled parallel build. Disable parallel build with VM option '-Dorg.gradle.parallel=false'." )
|
||||||
|
|||||||
@@ -61,6 +61,27 @@ tasks {
|
|||||||
archiveBaseName.set( "flatlaf" )
|
archiveBaseName.set( "flatlaf" )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
register<Zip>( "jarNoNatives" ) {
|
||||||
|
group = "build"
|
||||||
|
dependsOn( "jar" )
|
||||||
|
|
||||||
|
archiveBaseName.set( "flatlaf" )
|
||||||
|
archiveClassifier.set( "no-natives" )
|
||||||
|
archiveExtension.set( "jar" )
|
||||||
|
destinationDirectory = layout.buildDirectory.dir( "libs" )
|
||||||
|
|
||||||
|
from( zipTree( jar.get().archiveFile.get().asFile ) )
|
||||||
|
exclude( "com/formdev/flatlaf/natives/**" )
|
||||||
|
}
|
||||||
|
|
||||||
|
withType<AbstractPublishToMaven>().configureEach {
|
||||||
|
dependsOn( "jarNoNatives" )
|
||||||
|
}
|
||||||
|
|
||||||
|
withType<Sign>().configureEach {
|
||||||
|
dependsOn( "jarNoNatives" )
|
||||||
|
}
|
||||||
|
|
||||||
check {
|
check {
|
||||||
dependsOn( "sigtestCheck" )
|
dependsOn( "sigtestCheck" )
|
||||||
}
|
}
|
||||||
@@ -127,6 +148,8 @@ flatlafPublish {
|
|||||||
|
|
||||||
val natives = "src/main/resources/com/formdev/flatlaf/natives"
|
val natives = "src/main/resources/com/formdev/flatlaf/natives"
|
||||||
nativeArtifacts = listOf(
|
nativeArtifacts = listOf(
|
||||||
|
NativeArtifact( tasks.getByName( "jarNoNatives" ).outputs.files.asPath, "no-natives", "jar" ),
|
||||||
|
|
||||||
NativeArtifact( "${natives}/flatlaf-windows-x86.dll", "windows-x86", "dll" ),
|
NativeArtifact( "${natives}/flatlaf-windows-x86.dll", "windows-x86", "dll" ),
|
||||||
NativeArtifact( "${natives}/flatlaf-windows-x86_64.dll", "windows-x86_64", "dll" ),
|
NativeArtifact( "${natives}/flatlaf-windows-x86_64.dll", "windows-x86_64", "dll" ),
|
||||||
NativeArtifact( "${natives}/flatlaf-windows-arm64.dll", "windows-arm64", "dll" ),
|
NativeArtifact( "${natives}/flatlaf-windows-arm64.dll", "windows-arm64", "dll" ),
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#Signature file v4.1
|
#Signature file v4.1
|
||||||
#Version 3.3
|
#Version 3.4
|
||||||
|
|
||||||
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"
|
||||||
@@ -12,7 +12,13 @@ fld public final static java.lang.String BUTTON_TYPE_TOOLBAR_BUTTON = "toolBarBu
|
|||||||
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 COMPONENT_TITLE_BAR_CAPTION = "JComponent.titleBarCaption"
|
||||||
|
fld public final static java.lang.String FULL_WINDOW_CONTENT = "FlatLaf.fullWindowContent"
|
||||||
|
fld public final static java.lang.String FULL_WINDOW_CONTENT_BUTTONS_BOUNDS = "FlatLaf.fullWindowContent.buttonsBounds"
|
||||||
|
fld public final static java.lang.String FULL_WINDOW_CONTENT_BUTTONS_PLACEHOLDER = "FlatLaf.fullWindowContent.buttonsPlaceholder"
|
||||||
fld public final static java.lang.String GLASS_PANE_FULL_HEIGHT = "JRootPane.glassPaneFullHeight"
|
fld public final static java.lang.String GLASS_PANE_FULL_HEIGHT = "JRootPane.glassPaneFullHeight"
|
||||||
|
fld public final static java.lang.String MACOS_WINDOW_BUTTONS_SPACING = "FlatLaf.macOS.windowButtonsSpacing"
|
||||||
|
fld public final static java.lang.String MACOS_WINDOW_BUTTONS_SPACING_LARGE = "large"
|
||||||
|
fld public final static java.lang.String MACOS_WINDOW_BUTTONS_SPACING_MEDIUM = "medium"
|
||||||
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"
|
||||||
|
|||||||
@@ -257,19 +257,116 @@ 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
|
* Specifies whether a component shown in a window title bar area should behave as caption
|
||||||
* (left-click allows moving window, right-click shows window system menu).
|
* (left-click allows moving window, right-click shows window system menu).
|
||||||
* The component does not receive mouse pressed/released/clicked/dragged events,
|
* The caption component does not receive mouse pressed/released/clicked/dragged events,
|
||||||
* but it gets mouse entered/exited/moved events.
|
* but it gets mouse entered/exited/moved events.
|
||||||
* <p>
|
* <p>
|
||||||
|
* Since 3.4, this client property also supports using a function that can check
|
||||||
|
* whether a given location in the component should behave as caption.
|
||||||
|
* Useful for components that do not use mouse input on whole component bounds.
|
||||||
|
*
|
||||||
|
* <pre>{@code
|
||||||
|
* myComponent.putClientProperty( "JComponent.titleBarCaption",
|
||||||
|
* (Function<Point, Boolean>) pt -> {
|
||||||
|
* // parameter pt contains mouse location (in myComponent coordinates)
|
||||||
|
* // return true if the component is not interested in mouse input at the given location
|
||||||
|
* // return false if the component wants process mouse input at the given location
|
||||||
|
* // return null if the component children should be checked
|
||||||
|
* return ...; // check here
|
||||||
|
* } );
|
||||||
|
* }</pre>
|
||||||
|
* <b>Warning</b>:
|
||||||
|
* <ul>
|
||||||
|
* <li>This function is invoked often when mouse is moved over window title bar area
|
||||||
|
* and should therefore return quickly.
|
||||||
|
* <li>This function is invoked on 'AWT-Windows' thread (not 'AWT-EventQueue' thread)
|
||||||
|
* while processing Windows messages.
|
||||||
|
* It <b>must not</b> change any component property or layout because this could cause a dead lock.
|
||||||
|
* </ul>
|
||||||
|
* <p>
|
||||||
* <strong>Component</strong> {@link javax.swing.JComponent}<br>
|
* <strong>Component</strong> {@link javax.swing.JComponent}<br>
|
||||||
* <strong>Value type</strong> {@link java.lang.Boolean}
|
* <strong>Value type</strong> {@link java.lang.Boolean} or {@link java.util.function.Function}<Point, Boolean>
|
||||||
*
|
*
|
||||||
* @since 2.5
|
* @since 2.5
|
||||||
*/
|
*/
|
||||||
String COMPONENT_TITLE_BAR_CAPTION = "JComponent.titleBarCaption";
|
String COMPONENT_TITLE_BAR_CAPTION = "JComponent.titleBarCaption";
|
||||||
|
|
||||||
|
|
||||||
|
//---- Panel --------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Marks the panel as placeholder for the iconfify/maximize/close buttons
|
||||||
|
* in fullWindowContent mode. See {@link #FULL_WINDOW_CONTENT}.
|
||||||
|
* <p>
|
||||||
|
* If fullWindowContent mode is enabled, the preferred size of the panel is equal
|
||||||
|
* to the size of the iconfify/maximize/close buttons. Otherwise is is {@code 0,0}.
|
||||||
|
* <p>
|
||||||
|
* You're responsible to layout that panel at the top-left or top-right corner,
|
||||||
|
* depending on platform, where the iconfify/maximize/close buttons are located.
|
||||||
|
* <p>
|
||||||
|
* Syntax of the value string is: {@code "win|mac [horizontal|vertical] [zeroInFullScreen] [leftToRight|rightToLeft]"}.
|
||||||
|
* <p>
|
||||||
|
* The string must start with {@code "win"} (for Windows or Linux) or
|
||||||
|
* with {@code "mac"} (for macOS) and specifies the platform where the placeholder
|
||||||
|
* should be used. On macOS, you need the placeholder in the top-left corner,
|
||||||
|
* but on Windows/Linux you need it in the top-right corner. So if your application supports
|
||||||
|
* fullWindowContent mode on both platforms, you can add two placeholders to your layout
|
||||||
|
* and FlatLaf automatically uses only one of them. The other gets size {@code 0,0}.
|
||||||
|
* <p>
|
||||||
|
* Optionally, you can append following options to the value string (separated by space characters):
|
||||||
|
* <ul>
|
||||||
|
* <li>{@code "horizontal"} - preferred height is zero
|
||||||
|
* <li>{@code "vertical"} - preferred width is zero
|
||||||
|
* <li>{@code "zeroInFullScreen"} - in full-screen mode on macOS, preferred size is {@code 0,0}
|
||||||
|
* <li>{@code "leftToRight"} - in right-to-left component orientation, preferred size is {@code 0,0}
|
||||||
|
* <li>{@code "rightToLeft"} - in left-to-right component orientation, preferred size is {@code 0,0}
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* Example for adding placeholder to top-left corner on macOS:
|
||||||
|
* <pre>{@code
|
||||||
|
* JPanel placeholder = new JPanel();
|
||||||
|
* placeholder.putClientProperty( FlatClientProperties.FULL_WINDOW_CONTENT_BUTTONS_PLACEHOLDER, "mac" );
|
||||||
|
*
|
||||||
|
* JToolBar toolBar = new JToolBar();
|
||||||
|
* // add tool bar items
|
||||||
|
*
|
||||||
|
* JPanel toolBarPanel = new JPanel( new BorderLayout() );
|
||||||
|
* toolBarPanel.add( placeholder, BorderLayout.WEST );
|
||||||
|
* toolBarPanel.add( toolBar, BorderLayout.CENTER );
|
||||||
|
*
|
||||||
|
* frame.getContentPane().add( toolBarPanel, BorderLayout.NORTH );
|
||||||
|
* }</pre>
|
||||||
|
*
|
||||||
|
* Or add placeholder as first item to the tool bar:
|
||||||
|
* <pre>{@code
|
||||||
|
* JPanel placeholder = new JPanel();
|
||||||
|
* placeholder.putClientProperty( FlatClientProperties.FULL_WINDOW_CONTENT_BUTTONS_PLACEHOLDER, "mac" );
|
||||||
|
*
|
||||||
|
* JToolBar toolBar = new JToolBar();
|
||||||
|
* toolBar.add( placeholder );
|
||||||
|
* // add tool bar items
|
||||||
|
*
|
||||||
|
* frame.getContentPane().add( toolBar, BorderLayout.NORTH );
|
||||||
|
* }</pre>
|
||||||
|
*
|
||||||
|
* If a tabbed pane is located at the top, you can add the placeholder
|
||||||
|
* as leading component to that tabbed pane:
|
||||||
|
* <pre>{@code
|
||||||
|
* JPanel placeholder = new JPanel();
|
||||||
|
* placeholder.putClientProperty( FlatClientProperties.FULL_WINDOW_CONTENT_BUTTONS_PLACEHOLDER, "mac" );
|
||||||
|
*
|
||||||
|
* tabbedPane.putClientProperty( FlatClientProperties.TABBED_PANE_LEADING_COMPONENT, placeholder );
|
||||||
|
* }</pre>
|
||||||
|
* <p>
|
||||||
|
* <strong>Component</strong> {@link javax.swing.JPanel}<br>
|
||||||
|
* <strong>Value type</strong> {@link java.lang.String}
|
||||||
|
*
|
||||||
|
* @since 3.4
|
||||||
|
*/
|
||||||
|
String FULL_WINDOW_CONTENT_BUTTONS_PLACEHOLDER = "FlatLaf.fullWindowContent.buttonsPlaceholder";
|
||||||
|
|
||||||
|
|
||||||
//---- Popup --------------------------------------------------------------
|
//---- Popup --------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -388,6 +485,46 @@ public interface FlatClientProperties
|
|||||||
*/
|
*/
|
||||||
String MENU_BAR_EMBEDDED = "JRootPane.menuBarEmbedded";
|
String MENU_BAR_EMBEDDED = "JRootPane.menuBarEmbedded";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies whether the content pane (and the glass pane) should be extended
|
||||||
|
* into the window title bar area
|
||||||
|
* (requires enabled window decorations). Default is {@code false}.
|
||||||
|
* <p>
|
||||||
|
* On macOS, use client property {@code apple.awt.fullWindowContent}
|
||||||
|
* (see <a href="https://www.formdev.com/flatlaf/macos/#full_window_content">macOS Full window content</a>).
|
||||||
|
* <p>
|
||||||
|
* Setting this enables/disables full window content
|
||||||
|
* for the {@code JFrame} or {@code JDialog} that contains the root pane.
|
||||||
|
* <p>
|
||||||
|
* If {@code true}, the content pane (and the glass pane) is extended into
|
||||||
|
* the title bar area. The window icon and title are hidden.
|
||||||
|
* Only the iconfify/maximize/close buttons stay visible in the upper right corner
|
||||||
|
* (and overlap the content pane).
|
||||||
|
* <p>
|
||||||
|
* The user can left-click-and-drag on the title bar area to move the window,
|
||||||
|
* except when clicking on a component that processes mouse events (e.g. buttons or menus).
|
||||||
|
* <p>
|
||||||
|
* <strong>Component</strong> {@link javax.swing.JRootPane}<br>
|
||||||
|
* <strong>Value type</strong> {@link java.lang.Boolean}
|
||||||
|
*
|
||||||
|
* @since 3.4
|
||||||
|
*/
|
||||||
|
String FULL_WINDOW_CONTENT = "FlatLaf.fullWindowContent";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contains the current bounds of the iconfify/maximize/close buttons
|
||||||
|
* (in root pane coordinates) if fullWindowContent mode is enabled.
|
||||||
|
* Otherwise its value is {@code null}.
|
||||||
|
* <p>
|
||||||
|
* <b>Note</b>: Do not set this client property. It is set by FlatLaf.
|
||||||
|
* <p>
|
||||||
|
* <strong>Component</strong> {@link javax.swing.JRootPane}<br>
|
||||||
|
* <strong>Value type</strong> {@link java.awt.Rectangle}
|
||||||
|
*
|
||||||
|
* @since 3.4
|
||||||
|
*/
|
||||||
|
String FULL_WINDOW_CONTENT_BUTTONS_BOUNDS = "FlatLaf.fullWindowContent.buttonsBounds";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies whether the window icon should be shown in the window title bar
|
* Specifies whether the window icon should be shown in the window title bar
|
||||||
* (requires enabled window decorations). Default is UI property {@code TitlePane.showIcon}.
|
* (requires enabled window decorations). Default is UI property {@code TitlePane.showIcon}.
|
||||||
@@ -1263,6 +1400,44 @@ public interface FlatClientProperties
|
|||||||
String TREE_PAINT_SELECTION = "JTree.paintSelection";
|
String TREE_PAINT_SELECTION = "JTree.paintSelection";
|
||||||
|
|
||||||
|
|
||||||
|
//---- macOS --------------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies the spacing around the macOS window close/minimize/zoom buttons.
|
||||||
|
* Useful if <a href="https://www.formdev.com/flatlaf/macos/#full_window_content">full window content</a>
|
||||||
|
* is enabled.
|
||||||
|
* <p>
|
||||||
|
* (requires macOS 10.14+ for "medium" spacing and macOS 11+ for "large" spacing, requires Java 17+)
|
||||||
|
* <p>
|
||||||
|
* <strong>Component</strong> {@link javax.swing.JRootPane}<br>
|
||||||
|
* <strong>Value type</strong> {@link java.lang.String}<br>
|
||||||
|
* <strong>Allowed Values</strong>
|
||||||
|
* {@link #MACOS_WINDOW_BUTTONS_SPACING_MEDIUM} or
|
||||||
|
* {@link #MACOS_WINDOW_BUTTONS_SPACING_LARGE} (requires macOS 11+)
|
||||||
|
*
|
||||||
|
* @since 3.4
|
||||||
|
*/
|
||||||
|
String MACOS_WINDOW_BUTTONS_SPACING = "FlatLaf.macOS.windowButtonsSpacing";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add medium spacing around the macOS window close/minimize/zoom buttons.
|
||||||
|
*
|
||||||
|
* @see #MACOS_WINDOW_BUTTONS_SPACING
|
||||||
|
* @since 3.4
|
||||||
|
*/
|
||||||
|
String MACOS_WINDOW_BUTTONS_SPACING_MEDIUM = "medium";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add large spacing around the macOS window close/minimize/zoom buttons.
|
||||||
|
* <p>
|
||||||
|
* (requires macOS 11+; "medium" is used on older systems)
|
||||||
|
*
|
||||||
|
* @see #MACOS_WINDOW_BUTTONS_SPACING
|
||||||
|
* @since 3.4
|
||||||
|
*/
|
||||||
|
String MACOS_WINDOW_BUTTONS_SPACING_LARGE = "large";
|
||||||
|
|
||||||
|
|
||||||
//---- helper methods -----------------------------------------------------
|
//---- helper methods -----------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -172,19 +172,33 @@ public interface FlatSystemProperties
|
|||||||
String USE_NATIVE_LIBRARY = "flatlaf.useNativeLibrary";
|
String USE_NATIVE_LIBRARY = "flatlaf.useNativeLibrary";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies a directory in which the native FlatLaf libraries have been extracted.
|
* Specifies a directory in which the FlatLaf native libraries are searched for.
|
||||||
* 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>
|
* <p>
|
||||||
* If the value is {@code "system"}, then {@link System#loadLibrary(String)} is
|
* If the value is {@code "system"} (supported since FlatLaf 2.6),
|
||||||
* used to load the native library.
|
* then {@link System#loadLibrary(String)} is used to load the native library.
|
||||||
* Searches for the native library in classloader of caller
|
* This searches for the native library in classloader of caller
|
||||||
* (using {@link ClassLoader#findLibrary(String)}) and in paths specified
|
* (using {@link ClassLoader#findLibrary(String)}) and in paths specified
|
||||||
* in system properties {@code sun.boot.library.path} and {@code java.library.path}.
|
* in system properties {@code sun.boot.library.path} and {@code java.library.path}.
|
||||||
* (supported since FlatLaf 2.6)
|
|
||||||
* <p>
|
* <p>
|
||||||
* If the native library can not be loaded from the given path (or via {@link System#loadLibrary(String)}),
|
* If the native library can not be 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.
|
* then the embedded native library is extracted to the temporary directory and loaded from there.
|
||||||
|
* <p>
|
||||||
|
* The file names of the native libraries must be either:
|
||||||
|
* <ul>
|
||||||
|
* <li>the same as in flatlaf.jar in package 'com/formdev/flatlaf/natives' (required for "system") or
|
||||||
|
* <li>when downloaded from Maven central then as described here:
|
||||||
|
* <a href="https://www.formdev.com/flatlaf/native-libraries/">https://www.formdev.com/flatlaf/native-libraries/</a>
|
||||||
|
* (requires FlatLaf 3.4)
|
||||||
|
* </ul>
|
||||||
|
* <p>
|
||||||
|
* <strong>Note</strong>: Since FlatLaf 3.1 it is recommended to download the
|
||||||
|
* FlatLaf native libraries from Maven central and distribute them with your
|
||||||
|
* application in the same directory as flatlaf.jar.
|
||||||
|
* Then it is <strong>not necessary</strong> to set this system property.
|
||||||
|
* See <a href="https://www.formdev.com/flatlaf/native-libraries/">https://www.formdev.com/flatlaf/native-libraries/</a>
|
||||||
|
* for details.
|
||||||
*
|
*
|
||||||
* @since 2
|
* @since 2
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -429,7 +429,7 @@ public class FlatFileChooserUI
|
|||||||
iconFunction = (Function<File, Icon>) UIManager.get( "FileChooser.shortcuts.iconFunction" );
|
iconFunction = (Function<File, Icon>) UIManager.get( "FileChooser.shortcuts.iconFunction" );
|
||||||
|
|
||||||
FileSystemView fsv = fc.getFileSystemView();
|
FileSystemView fsv = fc.getFileSystemView();
|
||||||
File[] files = getChooserShortcutPanelFiles( fsv );
|
File[] files = JavaCompatibility2.getChooserShortcutPanelFiles( fsv );
|
||||||
if( filesFunction != null )
|
if( filesFunction != null )
|
||||||
files = filesFunction.apply( files );
|
files = filesFunction.apply( files );
|
||||||
|
|
||||||
@@ -498,32 +498,6 @@ public class FlatFileChooserUI
|
|||||||
return button;
|
return button;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected File[] getChooserShortcutPanelFiles( FileSystemView fsv ) {
|
|
||||||
try {
|
|
||||||
if( SystemInfo.isJava_12_orLater ) {
|
|
||||||
Method m = fsv.getClass().getMethod( "getChooserShortcutPanelFiles" );
|
|
||||||
File[] files = (File[]) m.invoke( fsv );
|
|
||||||
|
|
||||||
// on macOS and Linux, files consists only of the user home directory
|
|
||||||
if( files.length == 1 && files[0].equals( new File( System.getProperty( "user.home" ) ) ) )
|
|
||||||
files = new File[0];
|
|
||||||
|
|
||||||
return files;
|
|
||||||
} else if( SystemInfo.isWindows ) {
|
|
||||||
Class<?> cls = Class.forName( "sun.awt.shell.ShellFolder" );
|
|
||||||
Method m = cls.getMethod( "get", String.class );
|
|
||||||
return (File[]) m.invoke( null, "fileChooserShortcutPanelFolders" );
|
|
||||||
}
|
|
||||||
} catch( IllegalAccessException ex ) {
|
|
||||||
// do not log because access may be denied via VM option '--illegal-access=deny'
|
|
||||||
} catch( Exception ex ) {
|
|
||||||
LoggingFacade.INSTANCE.logSevere( null, ex );
|
|
||||||
}
|
|
||||||
|
|
||||||
// fallback
|
|
||||||
return new File[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
protected String getDisplayName( FileSystemView fsv, File file ) {
|
protected String getDisplayName( FileSystemView fsv, File file ) {
|
||||||
if( displayNameFunction != null ) {
|
if( displayNameFunction != null ) {
|
||||||
String name = displayNameFunction.apply( file );
|
String name = displayNameFunction.apply( file );
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ import java.awt.event.ActionEvent;
|
|||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
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.ActionMap;
|
import javax.swing.ActionMap;
|
||||||
import javax.swing.BoxLayout;
|
import javax.swing.BoxLayout;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
@@ -39,7 +38,6 @@ import javax.swing.MenuElement;
|
|||||||
import javax.swing.MenuSelectionManager;
|
import javax.swing.MenuSelectionManager;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import javax.swing.plaf.ActionMapUIResource;
|
|
||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
import javax.swing.plaf.UIResource;
|
import javax.swing.plaf.UIResource;
|
||||||
import javax.swing.plaf.basic.BasicMenuBarUI;
|
import javax.swing.plaf.basic.BasicMenuBarUI;
|
||||||
@@ -144,12 +142,10 @@ public class FlatMenuBarUI
|
|||||||
protected void installKeyboardActions() {
|
protected void installKeyboardActions() {
|
||||||
super.installKeyboardActions();
|
super.installKeyboardActions();
|
||||||
|
|
||||||
|
// get shared action map, used for all menu bars
|
||||||
ActionMap map = SwingUtilities.getUIActionMap( menuBar );
|
ActionMap map = SwingUtilities.getUIActionMap( menuBar );
|
||||||
if( map == null ) {
|
if( map != null && !(map.get( "takeFocus" ) instanceof TakeFocusAction) )
|
||||||
map = new ActionMapUIResource();
|
map.put( "takeFocus", new TakeFocusAction( "takeFocus" ) );
|
||||||
SwingUtilities.replaceUIActionMap( menuBar, map );
|
|
||||||
}
|
|
||||||
map.put( "takeFocus", new TakeFocus() );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @since 2 */
|
/** @since 2 */
|
||||||
@@ -365,16 +361,20 @@ public class FlatMenuBarUI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//---- class TakeFocus ----------------------------------------------------
|
//---- class TakeFocusAction ----------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Activates the menu bar and shows mnemonics.
|
* Activates the menu bar and shows mnemonics.
|
||||||
* On Windows, the popup of the first menu is not shown.
|
* On Windows, the popup of the first menu is not shown.
|
||||||
* On other platforms, the popup of the first menu is shown.
|
* On other platforms, the popup of the first menu is shown.
|
||||||
*/
|
*/
|
||||||
private static class TakeFocus
|
private static class TakeFocusAction
|
||||||
extends AbstractAction
|
extends FlatUIAction
|
||||||
{
|
{
|
||||||
|
TakeFocusAction( String name ) {
|
||||||
|
super( name );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed( ActionEvent e ) {
|
public void actionPerformed( ActionEvent e ) {
|
||||||
JMenuBar menuBar = (JMenuBar) e.getSource();
|
JMenuBar menuBar = (JMenuBar) e.getSource();
|
||||||
|
|||||||
@@ -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.Font;
|
import java.awt.Font;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
@@ -271,7 +272,7 @@ public class FlatMenuUI
|
|||||||
if( !isHover() )
|
if( !isHover() )
|
||||||
selectionBackground = getStyleFromMenuBarUI( ui -> ui.selectionBackground, menuBarSelectionBackground, selectionBackground );
|
selectionBackground = getStyleFromMenuBarUI( ui -> ui.selectionBackground, menuBarSelectionBackground, selectionBackground );
|
||||||
|
|
||||||
JMenuBar menuBar = (JMenuBar) menuItem.getParent();
|
Container menuBar = menuItem.getParent();
|
||||||
JRootPane rootPane = SwingUtilities.getRootPane( menuBar );
|
JRootPane rootPane = SwingUtilities.getRootPane( menuBar );
|
||||||
if( rootPane != null && rootPane.getParent() instanceof Window &&
|
if( rootPane != null && rootPane.getParent() instanceof Window &&
|
||||||
rootPane.getJMenuBar() == menuBar &&
|
rootPane.getJMenuBar() == menuBar &&
|
||||||
@@ -321,12 +322,17 @@ public class FlatMenuUI
|
|||||||
}
|
}
|
||||||
|
|
||||||
private <T> T getStyleFromMenuBarUI( Function<FlatMenuBarUI, T> f, T defaultValue ) {
|
private <T> T getStyleFromMenuBarUI( Function<FlatMenuBarUI, T> f, T defaultValue ) {
|
||||||
MenuBarUI ui = ((JMenuBar)menuItem.getParent()).getUI();
|
Container menuItemParent = menuItem.getParent();
|
||||||
if( !(ui instanceof FlatMenuBarUI) )
|
if( menuItemParent instanceof JMenuBar ) {
|
||||||
return defaultValue;
|
MenuBarUI ui = ((JMenuBar) menuItemParent).getUI();
|
||||||
|
if( ui instanceof FlatMenuBarUI ) {
|
||||||
T value = f.apply( (FlatMenuBarUI) ui );
|
T value = f.apply( (FlatMenuBarUI) ui );
|
||||||
return (value != null) ? value : defaultValue;
|
if( value != null ) {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import java.security.CodeSource;
|
|||||||
import com.formdev.flatlaf.FlatSystemProperties;
|
import com.formdev.flatlaf.FlatSystemProperties;
|
||||||
import com.formdev.flatlaf.util.LoggingFacade;
|
import com.formdev.flatlaf.util.LoggingFacade;
|
||||||
import com.formdev.flatlaf.util.NativeLibrary;
|
import com.formdev.flatlaf.util.NativeLibrary;
|
||||||
|
import com.formdev.flatlaf.util.StringUtils;
|
||||||
import com.formdev.flatlaf.util.SystemInfo;
|
import com.formdev.flatlaf.util.SystemInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -117,13 +118,32 @@ class FlatNativeLibrary
|
|||||||
if( library.isLoaded() )
|
if( library.isLoaded() )
|
||||||
return library;
|
return library;
|
||||||
|
|
||||||
LoggingFacade.INSTANCE.logSevere( "Did not find library " + libraryName + " in java.library.path, using extracted library instead", null );
|
LoggingFacade.INSTANCE.logSevere( "Did not find library '" + System.mapLibraryName( libraryName )
|
||||||
|
+ "' in java.library.path '" + System.getProperty( "java.library.path" )
|
||||||
|
+ "', using extracted library instead", null );
|
||||||
} else {
|
} else {
|
||||||
|
// try standard library naming scheme
|
||||||
|
// (same as in flatlaf.jar in package 'com/formdev/flatlaf/natives')
|
||||||
File libraryFile = new File( libraryPath, System.mapLibraryName( libraryName ) );
|
File libraryFile = new File( libraryPath, System.mapLibraryName( libraryName ) );
|
||||||
if( libraryFile.exists() )
|
if( libraryFile.exists() )
|
||||||
return new NativeLibrary( libraryFile, true );
|
return new NativeLibrary( libraryFile, true );
|
||||||
|
|
||||||
LoggingFacade.INSTANCE.logSevere( "Did not find external library " + libraryFile + ", using extracted library instead", null );
|
// try Maven naming scheme
|
||||||
|
// (see https://www.formdev.com/flatlaf/native-libraries/)
|
||||||
|
String libraryName2 = null;
|
||||||
|
File jarFile = getJarFile();
|
||||||
|
if( jarFile != null ) {
|
||||||
|
libraryName2 = buildLibraryName( jarFile, classifier, ext );
|
||||||
|
File libraryFile2 = new File( libraryPath, libraryName2 );
|
||||||
|
if( libraryFile2.exists() )
|
||||||
|
return new NativeLibrary( libraryFile2, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
LoggingFacade.INSTANCE.logSevere( "Did not find library '"
|
||||||
|
+ libraryFile.getName()
|
||||||
|
+ (libraryName2 != null ? ("' or '" + libraryName2) : "")
|
||||||
|
+ "' in '" + libraryFile.getParentFile().getAbsolutePath()
|
||||||
|
+ "', using extracted library instead", null );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,6 +171,51 @@ class FlatNativeLibrary
|
|||||||
* flatlaf-3.1-linux-x86_64.so
|
* flatlaf-3.1-linux-x86_64.so
|
||||||
*/
|
*/
|
||||||
private static File findLibraryBesideJar( String classifier, String ext ) {
|
private static File findLibraryBesideJar( String classifier, String ext ) {
|
||||||
|
// get location of FlatLaf jar (or fat/uber application jar)
|
||||||
|
File jarFile = getJarFile();
|
||||||
|
if( jarFile == null )
|
||||||
|
return null;
|
||||||
|
|
||||||
|
// build library file
|
||||||
|
String libraryName = buildLibraryName( jarFile, classifier, ext );
|
||||||
|
File jarDir = jarFile.getParentFile();
|
||||||
|
|
||||||
|
// check whether native library exists in same directory as jar
|
||||||
|
File libraryFile = new File( jarDir, libraryName );
|
||||||
|
if( libraryFile.isFile() )
|
||||||
|
return libraryFile;
|
||||||
|
|
||||||
|
// if jar is in "lib" directory, then also check whether native library exists
|
||||||
|
// in "../bin" directory
|
||||||
|
if( jarDir.getName().equalsIgnoreCase( "lib" ) ) {
|
||||||
|
libraryFile = new File( jarDir.getParentFile(), "bin/" + libraryName );
|
||||||
|
if( libraryFile.isFile() )
|
||||||
|
return libraryFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
// special case: support Gradle cache when running in development environment
|
||||||
|
// <user-home>/.gradle/caches/modules-2/files-2.1/com.formdev/flatlaf/<version>/<hash-1>/flatlaf-<version>.jar
|
||||||
|
// <user-home>/.gradle/caches/modules-2/files-2.1/com.formdev/flatlaf/<version>/<hash-2>/flatlaf-<version>-windows-x86_64.dll
|
||||||
|
String path = jarDir.getAbsolutePath().replace( '\\', '/' );
|
||||||
|
if( path.contains( "/.gradle/caches/" ) ) {
|
||||||
|
File versionDir = jarDir.getParentFile();
|
||||||
|
if( libraryName.contains( versionDir.getName() ) ) {
|
||||||
|
File[] dirs = versionDir.listFiles();
|
||||||
|
if( dirs != null ) {
|
||||||
|
for( File dir : dirs ) {
|
||||||
|
libraryFile = new File( dir, libraryName );
|
||||||
|
if( libraryFile.isFile() )
|
||||||
|
return libraryFile;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// native library not found
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static File getJarFile() {
|
||||||
try {
|
try {
|
||||||
// get location of FlatLaf jar
|
// get location of FlatLaf jar
|
||||||
CodeSource codeSource = FlatNativeLibrary.class.getProtectionDomain().getCodeSource();
|
CodeSource codeSource = FlatNativeLibrary.class.getProtectionDomain().getCodeSource();
|
||||||
@@ -168,31 +233,23 @@ class FlatNativeLibrary
|
|||||||
if( !jarFile.isFile() )
|
if( !jarFile.isFile() )
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
// build library file
|
return jarFile;
|
||||||
String jarName = jarFile.getName();
|
|
||||||
String jarBasename = jarName.substring( 0, jarName.lastIndexOf( '.' ) );
|
|
||||||
File parent = jarFile.getParentFile();
|
|
||||||
String libraryName = jarBasename
|
|
||||||
+ (jarBasename.contains( "flatlaf" ) ? "" : "-flatlaf")
|
|
||||||
+ '-' + classifier + '.' + ext;
|
|
||||||
|
|
||||||
// check whether native library exists in same directory as jar
|
|
||||||
File libraryFile = new File( parent, libraryName );
|
|
||||||
if( libraryFile.isFile() )
|
|
||||||
return libraryFile;
|
|
||||||
|
|
||||||
// if jar is in "lib" directory, then also check whether library exists
|
|
||||||
// in "../bin" directory
|
|
||||||
if( parent.getName().equalsIgnoreCase( "lib" ) ) {
|
|
||||||
libraryFile = new File( parent.getParentFile(), "bin/" + libraryName );
|
|
||||||
if( libraryFile.isFile() )
|
|
||||||
return libraryFile;
|
|
||||||
}
|
|
||||||
} catch( Exception ex ) {
|
} catch( Exception ex ) {
|
||||||
LoggingFacade.INSTANCE.logSevere( ex.getMessage(), ex );
|
LoggingFacade.INSTANCE.logSevere( ex.getMessage(), ex );
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
private static String buildLibraryName( File jarFile, String classifier, String ext ) {
|
||||||
|
String jarName = jarFile.getName();
|
||||||
|
String jarBasename = jarName.substring( 0, jarName.lastIndexOf( '.' ) );
|
||||||
|
|
||||||
|
// remove classifier "no-natives" (if used)
|
||||||
|
jarBasename = StringUtils.removeTrailing( jarBasename, "-no-natives" );
|
||||||
|
|
||||||
|
return jarBasename
|
||||||
|
+ (jarBasename.contains( "flatlaf" ) ? "" : "-flatlaf")
|
||||||
|
+ '-' + classifier + '.' + ext;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void loadJAWT() {
|
private static void loadJAWT() {
|
||||||
|
|||||||
@@ -16,7 +16,9 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf.ui;
|
package com.formdev.flatlaf.ui;
|
||||||
|
|
||||||
|
import java.awt.Rectangle;
|
||||||
import java.awt.Window;
|
import java.awt.Window;
|
||||||
|
import com.formdev.flatlaf.util.SystemInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Native methods for macOS.
|
* Native methods for macOS.
|
||||||
@@ -49,8 +51,19 @@ public class FlatNativeMacLibrary
|
|||||||
* method of this class. Otherwise, the native library may not be loaded.
|
* method of this class. Otherwise, the native library may not be loaded.
|
||||||
*/
|
*/
|
||||||
public static boolean isLoaded() {
|
public static boolean isLoaded() {
|
||||||
return FlatNativeLibrary.isLoaded();
|
return SystemInfo.isMacOS && FlatNativeLibrary.isLoaded();
|
||||||
}
|
}
|
||||||
|
|
||||||
public native static boolean setWindowRoundedBorder( Window window, float radius, float borderWidth, int borderColor );
|
public native static boolean setWindowRoundedBorder( Window window, float radius, float borderWidth, int borderColor );
|
||||||
|
|
||||||
|
/** @since 3.4 */
|
||||||
|
public static final int
|
||||||
|
BUTTONS_SPACING_DEFAULT = 0,
|
||||||
|
BUTTONS_SPACING_MEDIUM = 1,
|
||||||
|
BUTTONS_SPACING_LARGE = 2;
|
||||||
|
|
||||||
|
/** @since 3.4 */ public native static boolean setWindowButtonsSpacing( Window window, int buttonsSpacing );
|
||||||
|
/** @since 3.4 */ public native static Rectangle getWindowButtonsBounds( Window window );
|
||||||
|
/** @since 3.4 */ public native static boolean isWindowFullScreen( Window window );
|
||||||
|
/** @since 3.4 */ public native static boolean toggleWindowFullScreen( Window window );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,11 +21,12 @@ import java.awt.Component;
|
|||||||
import java.awt.Container;
|
import java.awt.Container;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.Point;
|
||||||
import java.awt.Rectangle;
|
import java.awt.Rectangle;
|
||||||
import java.awt.Toolkit;
|
import java.awt.Toolkit;
|
||||||
import java.awt.Window;
|
import java.awt.Window;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
import java.util.List;
|
import java.util.function.Predicate;
|
||||||
import javax.swing.JDialog;
|
import javax.swing.JDialog;
|
||||||
import javax.swing.JFrame;
|
import javax.swing.JFrame;
|
||||||
import javax.swing.JRootPane;
|
import javax.swing.JRootPane;
|
||||||
@@ -218,13 +219,13 @@ public class FlatNativeWindowBorder
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void setTitleBarHeightAndHitTestSpots( Window window, int titleBarHeight,
|
static void setTitleBarHeightAndHitTestSpots( Window window, int titleBarHeight,
|
||||||
List<Rectangle> hitTestSpots, Rectangle appIconBounds, Rectangle minimizeButtonBounds,
|
Predicate<Point> captionHitTestCallback, Rectangle appIconBounds, Rectangle minimizeButtonBounds,
|
||||||
Rectangle maximizeButtonBounds, Rectangle closeButtonBounds )
|
Rectangle maximizeButtonBounds, Rectangle closeButtonBounds )
|
||||||
{
|
{
|
||||||
if( !isSupported() )
|
if( !isSupported() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
nativeProvider.updateTitleBarInfo( window, titleBarHeight, hitTestSpots,
|
nativeProvider.updateTitleBarInfo( window, titleBarHeight, captionHitTestCallback,
|
||||||
appIconBounds, minimizeButtonBounds, maximizeButtonBounds, closeButtonBounds );
|
appIconBounds, minimizeButtonBounds, maximizeButtonBounds, closeButtonBounds );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -270,7 +271,7 @@ public class FlatNativeWindowBorder
|
|||||||
{
|
{
|
||||||
boolean hasCustomDecoration( Window window );
|
boolean hasCustomDecoration( Window window );
|
||||||
void setHasCustomDecoration( Window window, boolean hasCustomDecoration );
|
void setHasCustomDecoration( Window window, boolean hasCustomDecoration );
|
||||||
void updateTitleBarInfo( Window window, int titleBarHeight, List<Rectangle> hitTestSpots,
|
void updateTitleBarInfo( Window window, int titleBarHeight, Predicate<Point> captionHitTestCallback,
|
||||||
Rectangle appIconBounds, Rectangle minimizeButtonBounds, Rectangle maximizeButtonBounds,
|
Rectangle appIconBounds, Rectangle minimizeButtonBounds, Rectangle maximizeButtonBounds,
|
||||||
Rectangle closeButtonBounds );
|
Rectangle closeButtonBounds );
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf.ui;
|
package com.formdev.flatlaf.ui;
|
||||||
|
|
||||||
|
import java.awt.Dimension;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.beans.PropertyChangeEvent;
|
import java.beans.PropertyChangeEvent;
|
||||||
@@ -23,6 +24,7 @@ import java.beans.PropertyChangeListener;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.LookAndFeel;
|
||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
import javax.swing.plaf.basic.BasicPanelUI;
|
import javax.swing.plaf.basic.BasicPanelUI;
|
||||||
import com.formdev.flatlaf.FlatClientProperties;
|
import com.formdev.flatlaf.FlatClientProperties;
|
||||||
@@ -69,6 +71,8 @@ public class FlatPanelUI
|
|||||||
super.installUI( c );
|
super.installUI( c );
|
||||||
|
|
||||||
c.addPropertyChangeListener( this );
|
c.addPropertyChangeListener( this );
|
||||||
|
if( c.getClientProperty( FlatClientProperties.FULL_WINDOW_CONTENT_BUTTONS_PLACEHOLDER ) != null )
|
||||||
|
FullWindowContentSupport.registerPlaceholder( c );
|
||||||
|
|
||||||
installStyle( (JPanel) c );
|
installStyle( (JPanel) c );
|
||||||
}
|
}
|
||||||
@@ -78,10 +82,20 @@ public class FlatPanelUI
|
|||||||
super.uninstallUI( c );
|
super.uninstallUI( c );
|
||||||
|
|
||||||
c.removePropertyChangeListener( this );
|
c.removePropertyChangeListener( this );
|
||||||
|
if( c.getClientProperty( FlatClientProperties.FULL_WINDOW_CONTENT_BUTTONS_PLACEHOLDER ) != null )
|
||||||
|
FullWindowContentSupport.unregisterPlaceholder( c );
|
||||||
|
|
||||||
oldStyleValues = null;
|
oldStyleValues = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void installDefaults( JPanel p ) {
|
||||||
|
super.installDefaults( p );
|
||||||
|
|
||||||
|
if( p.getClientProperty( FlatClientProperties.FULL_WINDOW_CONTENT_BUTTONS_PLACEHOLDER ) != null )
|
||||||
|
LookAndFeel.installProperty( p, "opaque", false );
|
||||||
|
}
|
||||||
|
|
||||||
/** @since 2.0.1 */
|
/** @since 2.0.1 */
|
||||||
@Override
|
@Override
|
||||||
public void propertyChange( PropertyChangeEvent e ) {
|
public void propertyChange( PropertyChangeEvent e ) {
|
||||||
@@ -98,6 +112,17 @@ public class FlatPanelUI
|
|||||||
c.revalidate();
|
c.revalidate();
|
||||||
c.repaint();
|
c.repaint();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case FlatClientProperties.FULL_WINDOW_CONTENT_BUTTONS_PLACEHOLDER:
|
||||||
|
JPanel p = (JPanel) e.getSource();
|
||||||
|
if( e.getOldValue() != null )
|
||||||
|
FullWindowContentSupport.unregisterPlaceholder( p );
|
||||||
|
if( e.getNewValue() != null )
|
||||||
|
FullWindowContentSupport.registerPlaceholder( p );
|
||||||
|
|
||||||
|
// make panel non-opaque for placeholders
|
||||||
|
LookAndFeel.installProperty( p, "opaque", e.getNewValue() == null );
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,4 +187,19 @@ public class FlatPanelUI
|
|||||||
|
|
||||||
paint( g, c );
|
paint( g, c );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dimension getPreferredSize( JComponent c ) {
|
||||||
|
Object value = c.getClientProperty( FlatClientProperties.FULL_WINDOW_CONTENT_BUTTONS_PLACEHOLDER );
|
||||||
|
if( value != null )
|
||||||
|
return FullWindowContentSupport.getPlaceholderPreferredSize( c, (String) value );
|
||||||
|
|
||||||
|
return super.getPreferredSize( c );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void paint( Graphics g, JComponent c ) {
|
||||||
|
if( c.getClientProperty( FlatClientProperties.FULL_WINDOW_CONTENT_BUTTONS_PLACEHOLDER ) != null )
|
||||||
|
FullWindowContentSupport.debugPaint( g, c );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,8 +28,6 @@ import java.awt.Insets;
|
|||||||
import java.awt.LayoutManager;
|
import java.awt.LayoutManager;
|
||||||
import java.awt.LayoutManager2;
|
import java.awt.LayoutManager2;
|
||||||
import java.awt.Window;
|
import java.awt.Window;
|
||||||
import java.awt.event.ComponentAdapter;
|
|
||||||
import java.awt.event.ComponentEvent;
|
|
||||||
import java.awt.event.ComponentListener;
|
import java.awt.event.ComponentListener;
|
||||||
import java.beans.PropertyChangeEvent;
|
import java.beans.PropertyChangeEvent;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
@@ -41,7 +39,6 @@ import javax.swing.JLayeredPane;
|
|||||||
import javax.swing.JMenuBar;
|
import javax.swing.JMenuBar;
|
||||||
import javax.swing.JRootPane;
|
import javax.swing.JRootPane;
|
||||||
import javax.swing.LookAndFeel;
|
import javax.swing.LookAndFeel;
|
||||||
import javax.swing.SwingUtilities;
|
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import javax.swing.border.Border;
|
import javax.swing.border.Border;
|
||||||
import javax.swing.plaf.BorderUIResource;
|
import javax.swing.plaf.BorderUIResource;
|
||||||
@@ -50,6 +47,7 @@ import javax.swing.plaf.RootPaneUI;
|
|||||||
import javax.swing.plaf.UIResource;
|
import javax.swing.plaf.UIResource;
|
||||||
import javax.swing.plaf.basic.BasicRootPaneUI;
|
import javax.swing.plaf.basic.BasicRootPaneUI;
|
||||||
import com.formdev.flatlaf.FlatClientProperties;
|
import com.formdev.flatlaf.FlatClientProperties;
|
||||||
|
import com.formdev.flatlaf.FlatLaf;
|
||||||
import com.formdev.flatlaf.util.HiDPIUtils;
|
import com.formdev.flatlaf.util.HiDPIUtils;
|
||||||
import com.formdev.flatlaf.util.SystemInfo;
|
import com.formdev.flatlaf.util.SystemInfo;
|
||||||
import com.formdev.flatlaf.util.UIScale;
|
import com.formdev.flatlaf.util.UIScale;
|
||||||
@@ -87,8 +85,8 @@ public class FlatRootPaneUI
|
|||||||
|
|
||||||
private Object nativeWindowBorderData;
|
private Object nativeWindowBorderData;
|
||||||
private LayoutManager oldLayout;
|
private LayoutManager oldLayout;
|
||||||
private PropertyChangeListener ancestorListener;
|
private ComponentListener macFullWindowContentListener;
|
||||||
private ComponentListener componentListener;
|
private PropertyChangeListener macWindowBackgroundListener;
|
||||||
|
|
||||||
public static ComponentUI createUI( JComponent c ) {
|
public static ComponentUI createUI( JComponent c ) {
|
||||||
return new FlatRootPaneUI();
|
return new FlatRootPaneUI();
|
||||||
@@ -106,6 +104,7 @@ public class FlatRootPaneUI
|
|||||||
installBorder();
|
installBorder();
|
||||||
|
|
||||||
installNativeWindowBorder();
|
installNativeWindowBorder();
|
||||||
|
macInstallFullWindowContentSupport();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void installBorder() {
|
protected void installBorder() {
|
||||||
@@ -122,6 +121,7 @@ public class FlatRootPaneUI
|
|||||||
|
|
||||||
uninstallNativeWindowBorder();
|
uninstallNativeWindowBorder();
|
||||||
uninstallClientDecorations();
|
uninstallClientDecorations();
|
||||||
|
macUninstallFullWindowContentSupport();
|
||||||
rootPane = null;
|
rootPane = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,6 +155,8 @@ public class FlatRootPaneUI
|
|||||||
if( background == null || background instanceof UIResource )
|
if( background == null || background instanceof UIResource )
|
||||||
parent.setBackground( UIManager.getColor( "control" ) );
|
parent.setBackground( UIManager.getColor( "control" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macClearBackgroundForTranslucentWindow( c );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -174,55 +176,20 @@ public class FlatRootPaneUI
|
|||||||
protected void installListeners( JRootPane root ) {
|
protected void installListeners( JRootPane root ) {
|
||||||
super.installListeners( root );
|
super.installListeners( root );
|
||||||
|
|
||||||
if( SystemInfo.isJava_9_orLater ) {
|
if( SystemInfo.isMacFullWindowContentSupported )
|
||||||
// On HiDPI screens, where scaling is used, there may be white lines on the
|
macFullWindowContentListener = FullWindowContentSupport.macInstallListeners( root );
|
||||||
// bottom and on the right side of the window when it is initially shown.
|
macInstallWindowBackgroundListener( root );
|
||||||
// This is very disturbing in dark themes, but hard to notice in light themes.
|
|
||||||
// Seems to be a rounding issue when Swing adds dirty region of window
|
|
||||||
// using RepaintManager.nativeAddDirtyRegion().
|
|
||||||
//
|
|
||||||
// Note: Not using a HierarchyListener here, which would be much easier,
|
|
||||||
// because this causes problems with mouse clicks in heavy-weight popups.
|
|
||||||
// Instead, add a listener to the root pane that waits until it is added
|
|
||||||
// to a window, then add a component listener to the window.
|
|
||||||
// See: https://github.com/JFormDesigner/FlatLaf/issues/371
|
|
||||||
ancestorListener = e -> {
|
|
||||||
Object oldValue = e.getOldValue();
|
|
||||||
Object newValue = e.getNewValue();
|
|
||||||
if( newValue instanceof Window ) {
|
|
||||||
if( componentListener == null ) {
|
|
||||||
componentListener = new ComponentAdapter() {
|
|
||||||
@Override
|
|
||||||
public void componentShown( ComponentEvent e ) {
|
|
||||||
// add whole root pane to dirty regions when window is initially shown
|
|
||||||
root.getParent().repaint( root.getX(), root.getY(), root.getWidth(), root.getHeight() );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
((Window)newValue).addComponentListener( componentListener );
|
|
||||||
} else if( newValue == null && oldValue instanceof Window ) {
|
|
||||||
if( componentListener != null )
|
|
||||||
((Window)oldValue).removeComponentListener( componentListener );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
root.addPropertyChangeListener( "ancestor", ancestorListener );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void uninstallListeners( JRootPane root ) {
|
protected void uninstallListeners( JRootPane root ) {
|
||||||
super.uninstallListeners( root );
|
super.uninstallListeners( root );
|
||||||
|
|
||||||
if( SystemInfo.isJava_9_orLater ) {
|
if( SystemInfo.isMacFullWindowContentSupported ) {
|
||||||
if( componentListener != null ) {
|
FullWindowContentSupport.macUninstallListeners( root, macFullWindowContentListener );
|
||||||
Window window = SwingUtilities.windowForComponent( root );
|
macFullWindowContentListener = null;
|
||||||
if( window != null )
|
|
||||||
window.removeComponentListener( componentListener );
|
|
||||||
componentListener = null;
|
|
||||||
}
|
|
||||||
root.removePropertyChangeListener( "ancestor", ancestorListener );
|
|
||||||
ancestorListener = null;
|
|
||||||
}
|
}
|
||||||
|
macUninstallWindowBackgroundListener( root );
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @since 1.1.2 */
|
/** @since 1.1.2 */
|
||||||
@@ -302,19 +269,136 @@ public class FlatRootPaneUI
|
|||||||
|
|
||||||
// layer title pane under frame content layer to allow placing menu bar over title pane
|
// layer title pane under frame content layer to allow placing menu bar over title pane
|
||||||
protected final static Integer TITLE_PANE_LAYER = JLayeredPane.FRAME_CONTENT_LAYER - 1;
|
protected final static Integer TITLE_PANE_LAYER = JLayeredPane.FRAME_CONTENT_LAYER - 1;
|
||||||
|
private final static Integer TITLE_PANE_MOUSE_LAYER = JLayeredPane.FRAME_CONTENT_LAYER - 2;
|
||||||
|
|
||||||
|
// for fullWindowContent mode, layer title pane over frame content layer to allow placing title bar buttons over content
|
||||||
|
/** @since 3.4 */
|
||||||
|
protected final static Integer TITLE_PANE_FULL_WINDOW_CONTENT_LAYER = JLayeredPane.FRAME_CONTENT_LAYER + 1;
|
||||||
|
|
||||||
|
private Integer getLayerForTitlePane() {
|
||||||
|
return isFullWindowContent( rootPane ) ? TITLE_PANE_FULL_WINDOW_CONTENT_LAYER : TITLE_PANE_LAYER;
|
||||||
|
}
|
||||||
|
|
||||||
protected void setTitlePane( FlatTitlePane newTitlePane ) {
|
protected void setTitlePane( FlatTitlePane newTitlePane ) {
|
||||||
JLayeredPane layeredPane = rootPane.getLayeredPane();
|
JLayeredPane layeredPane = rootPane.getLayeredPane();
|
||||||
|
|
||||||
if( titlePane != null )
|
if( titlePane != null ) {
|
||||||
layeredPane.remove( titlePane );
|
layeredPane.remove( titlePane );
|
||||||
|
layeredPane.remove( titlePane.mouseLayer );
|
||||||
|
}
|
||||||
|
|
||||||
if( newTitlePane != null )
|
if( newTitlePane != null ) {
|
||||||
layeredPane.add( newTitlePane, TITLE_PANE_LAYER );
|
layeredPane.add( newTitlePane, getLayerForTitlePane() );
|
||||||
|
layeredPane.add( newTitlePane.mouseLayer, TITLE_PANE_MOUSE_LAYER );
|
||||||
|
}
|
||||||
|
|
||||||
titlePane = newTitlePane;
|
titlePane = newTitlePane;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void macInstallFullWindowContentSupport() {
|
||||||
|
if( !SystemInfo.isMacOS )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// set window buttons spacing
|
||||||
|
if( isMacButtonsSpacingSupported() && rootPane.isDisplayable() ) {
|
||||||
|
int buttonsSpacing = FlatNativeMacLibrary.BUTTONS_SPACING_DEFAULT;
|
||||||
|
String value = (String) rootPane.getClientProperty( FlatClientProperties.MACOS_WINDOW_BUTTONS_SPACING );
|
||||||
|
if( value != null ) {
|
||||||
|
switch( value ) {
|
||||||
|
case FlatClientProperties.MACOS_WINDOW_BUTTONS_SPACING_MEDIUM:
|
||||||
|
buttonsSpacing = FlatNativeMacLibrary.BUTTONS_SPACING_MEDIUM;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FlatClientProperties.MACOS_WINDOW_BUTTONS_SPACING_LARGE:
|
||||||
|
buttonsSpacing = FlatNativeMacLibrary.BUTTONS_SPACING_LARGE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FlatNativeMacLibrary.setWindowButtonsSpacing( getParentWindow( rootPane ), buttonsSpacing );
|
||||||
|
}
|
||||||
|
|
||||||
|
// update buttons bounds client property
|
||||||
|
FullWindowContentSupport.macUpdateFullWindowContentButtonsBoundsProperty( rootPane );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void macUninstallFullWindowContentSupport() {
|
||||||
|
if( !SystemInfo.isMacOS )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// do not uninstall when switching to another FlatLaf theme
|
||||||
|
if( UIManager.getLookAndFeel() instanceof FlatLaf )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// reset window buttons spacing
|
||||||
|
if( isMacButtonsSpacingSupported() )
|
||||||
|
FlatNativeMacLibrary.setWindowButtonsSpacing( getParentWindow( rootPane ), FlatNativeMacLibrary.BUTTONS_SPACING_DEFAULT );
|
||||||
|
|
||||||
|
// remove buttons bounds client property
|
||||||
|
FullWindowContentSupport.macUninstallFullWindowContentButtonsBoundsProperty( rootPane );
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isMacButtonsSpacingSupported() {
|
||||||
|
return SystemInfo.isMacOS && SystemInfo.isJava_17_orLater && FlatNativeMacLibrary.isLoaded();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void macInstallWindowBackgroundListener( JRootPane c ) {
|
||||||
|
if( !SystemInfo.isMacOS )
|
||||||
|
return;
|
||||||
|
|
||||||
|
Window window = getParentWindow( c );
|
||||||
|
if( window != null && macWindowBackgroundListener == null ) {
|
||||||
|
macWindowBackgroundListener = e -> macClearBackgroundForTranslucentWindow( c );
|
||||||
|
window.addPropertyChangeListener( "background", macWindowBackgroundListener );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void macUninstallWindowBackgroundListener( JRootPane c ) {
|
||||||
|
if( !SystemInfo.isMacOS )
|
||||||
|
return;
|
||||||
|
|
||||||
|
Window window = getParentWindow( c );
|
||||||
|
if( window != null && macWindowBackgroundListener != null ) {
|
||||||
|
window.removePropertyChangeListener( "background", macWindowBackgroundListener );
|
||||||
|
macWindowBackgroundListener = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* When setting window background to translucent color (alpha < 255),
|
||||||
|
* Swing paints that window translucent on Windows and Linux, but not on macOS.
|
||||||
|
* The reason for this is that FlatLaf sets the background color of the root pane,
|
||||||
|
* and Swing behaves a bit differently on macOS than on other platforms in that case.
|
||||||
|
* Other L&Fs do not set root pane background, which is {@code null} by default.
|
||||||
|
* <p>
|
||||||
|
* To fix this problem, set the root pane background to {@code null}
|
||||||
|
* if windows uses a translucent background.
|
||||||
|
*/
|
||||||
|
private void macClearBackgroundForTranslucentWindow( JRootPane c ) {
|
||||||
|
if( !SystemInfo.isMacOS )
|
||||||
|
return;
|
||||||
|
|
||||||
|
Window window = getParentWindow( c );
|
||||||
|
if( window != null ) {
|
||||||
|
Color windowBackground = window.getBackground();
|
||||||
|
if( windowBackground != null &&
|
||||||
|
windowBackground.getAlpha() < 255 &&
|
||||||
|
c.getBackground() instanceof UIResource )
|
||||||
|
{
|
||||||
|
// clear root pane background
|
||||||
|
c.setBackground( null );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Window getParentWindow( JRootPane c ) {
|
||||||
|
// not using SwingUtilities.windowForComponent() or SwingUtilities.getWindowAncestor()
|
||||||
|
// here because root panes may be nested and used anywhere (e.g. in JInternalFrame)
|
||||||
|
// but we're only interested in the "root" root pane, which is a direct child of the window
|
||||||
|
Container parent = c.getParent();
|
||||||
|
return (parent instanceof Window) ? (Window) parent : null;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void propertyChange( PropertyChangeEvent e ) {
|
public void propertyChange( PropertyChangeEvent e ) {
|
||||||
super.propertyChange( e );
|
super.propertyChange( e );
|
||||||
@@ -359,6 +443,21 @@ public class FlatRootPaneUI
|
|||||||
titlePane.titleBarColorsChanged();
|
titlePane.titleBarColorsChanged();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case FlatClientProperties.FULL_WINDOW_CONTENT:
|
||||||
|
if( titlePane != null ) {
|
||||||
|
rootPane.getLayeredPane().setLayer( titlePane, getLayerForTitlePane() );
|
||||||
|
titlePane.updateIcon();
|
||||||
|
titlePane.updateVisibility();
|
||||||
|
titlePane.updateFullWindowContentButtonsBoundsProperty();
|
||||||
|
}
|
||||||
|
FullWindowContentSupport.revalidatePlaceholders( rootPane );
|
||||||
|
rootPane.revalidate();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FlatClientProperties.FULL_WINDOW_CONTENT_BUTTONS_BOUNDS:
|
||||||
|
FullWindowContentSupport.revalidatePlaceholders( rootPane );
|
||||||
|
break;
|
||||||
|
|
||||||
case FlatClientProperties.GLASS_PANE_FULL_HEIGHT:
|
case FlatClientProperties.GLASS_PANE_FULL_HEIGHT:
|
||||||
rootPane.revalidate();
|
rootPane.revalidate();
|
||||||
break;
|
break;
|
||||||
@@ -367,14 +466,43 @@ public class FlatRootPaneUI
|
|||||||
if( rootPane.isDisplayable() )
|
if( rootPane.isDisplayable() )
|
||||||
throw new IllegalComponentStateException( "The client property 'Window.style' must be set before the window becomes displayable." );
|
throw new IllegalComponentStateException( "The client property 'Window.style' must be set before the window becomes displayable." );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case "ancestor":
|
||||||
|
if( e.getNewValue() instanceof Window )
|
||||||
|
macClearBackgroundForTranslucentWindow( rootPane );
|
||||||
|
|
||||||
|
macUninstallWindowBackgroundListener( rootPane );
|
||||||
|
macInstallWindowBackgroundListener( rootPane );
|
||||||
|
|
||||||
|
// FlatNativeMacLibrary.setWindowButtonsSpacing() and
|
||||||
|
// FullWindowContentSupport.macUpdateFullWindowContentButtonsBoundsProperty()
|
||||||
|
// require a native window, but setting the client properties
|
||||||
|
// "apple.awt.fullWindowContent" or FlatClientProperties.MACOS_WINDOW_BUTTONS_SPACING
|
||||||
|
// is usually done before the native window is created
|
||||||
|
// --> try again when native window is created
|
||||||
|
if( e.getNewValue() instanceof Window )
|
||||||
|
macInstallFullWindowContentSupport();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FlatClientProperties.MACOS_WINDOW_BUTTONS_SPACING:
|
||||||
|
macInstallFullWindowContentSupport();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "apple.awt.fullWindowContent":
|
||||||
|
if( SystemInfo.isMacFullWindowContentSupported )
|
||||||
|
FullWindowContentSupport.macUpdateFullWindowContentButtonsBoundsProperty( rootPane );
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 3.4 */
|
||||||
|
protected static boolean isFullWindowContent( JRootPane rootPane ) {
|
||||||
|
return FlatClientProperties.clientPropertyBoolean( rootPane, FlatClientProperties.FULL_WINDOW_CONTENT, false );
|
||||||
|
}
|
||||||
|
|
||||||
protected static boolean isMenuBarEmbedded( JRootPane rootPane ) {
|
protected static boolean isMenuBarEmbedded( JRootPane rootPane ) {
|
||||||
RootPaneUI ui = rootPane.getUI();
|
FlatTitlePane titlePane = getTitlePane( rootPane );
|
||||||
return ui instanceof FlatRootPaneUI &&
|
return titlePane != null && titlePane.isMenuBarEmbedded();
|
||||||
((FlatRootPaneUI)ui).titlePane != null &&
|
|
||||||
((FlatRootPaneUI)ui).titlePane.isMenuBarEmbedded();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @since 2.4 */
|
/** @since 2.4 */
|
||||||
@@ -410,23 +538,21 @@ public class FlatRootPaneUI
|
|||||||
private Dimension computeLayoutSize( Container parent, Function<Component, Dimension> getSizeFunc ) {
|
private Dimension computeLayoutSize( Container parent, Function<Component, Dimension> getSizeFunc ) {
|
||||||
JRootPane rootPane = (JRootPane) parent;
|
JRootPane rootPane = (JRootPane) parent;
|
||||||
|
|
||||||
Dimension titlePaneSize = (titlePane != null)
|
|
||||||
? getSizeFunc.apply( titlePane )
|
|
||||||
: new Dimension();
|
|
||||||
Dimension contentSize = (rootPane.getContentPane() != null)
|
Dimension contentSize = (rootPane.getContentPane() != null)
|
||||||
? getSizeFunc.apply( rootPane.getContentPane() )
|
? getSizeFunc.apply( rootPane.getContentPane() )
|
||||||
: rootPane.getSize();
|
: rootPane.getSize(); // same as in JRootPane.RootLayout.preferredLayoutSize()
|
||||||
|
|
||||||
int width = contentSize.width; // title pane width is not considered here
|
int width = contentSize.width; // title pane width is not considered here
|
||||||
int height = titlePaneSize.height + contentSize.height;
|
int height = contentSize.height;
|
||||||
|
if( titlePane != null && !isFullWindowContent( rootPane ) )
|
||||||
|
height += getSizeFunc.apply( titlePane ).height;
|
||||||
if( titlePane == null || !titlePane.isMenuBarEmbedded() ) {
|
if( titlePane == null || !titlePane.isMenuBarEmbedded() ) {
|
||||||
JMenuBar menuBar = rootPane.getJMenuBar();
|
JMenuBar menuBar = rootPane.getJMenuBar();
|
||||||
Dimension menuBarSize = (menuBar != null && menuBar.isVisible())
|
if( menuBar != null && menuBar.isVisible() ) {
|
||||||
? getSizeFunc.apply( menuBar )
|
Dimension menuBarSize = getSizeFunc.apply( menuBar );
|
||||||
: new Dimension();
|
width = Math.max( width, menuBarSize.width );
|
||||||
|
height += menuBarSize.height;
|
||||||
width = Math.max( width, menuBarSize.width );
|
}
|
||||||
height += menuBarSize.height;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Insets insets = rootPane.getInsets();
|
Insets insets = rootPane.getInsets();
|
||||||
@@ -451,12 +577,23 @@ public class FlatRootPaneUI
|
|||||||
if( rootPane.getLayeredPane() != null )
|
if( rootPane.getLayeredPane() != null )
|
||||||
rootPane.getLayeredPane().setBounds( x, y, width, height );
|
rootPane.getLayeredPane().setBounds( x, y, width, height );
|
||||||
|
|
||||||
// title pane
|
// title pane (is a child of layered pane)
|
||||||
int nextY = 0;
|
int nextY = 0;
|
||||||
if( titlePane != null ) {
|
if( titlePane != null ) {
|
||||||
int prefHeight = !isFullScreen ? titlePane.getPreferredSize().height : 0;
|
int prefHeight = !isFullScreen ? titlePane.getPreferredSize().height : 0;
|
||||||
titlePane.setBounds( 0, 0, width, prefHeight );
|
boolean isFullWindowContent = isFullWindowContent( rootPane );
|
||||||
nextY += prefHeight;
|
if( isFullWindowContent && !UIManager.getBoolean( FlatTitlePane.KEY_DEBUG_SHOW_RECTANGLES ) ) {
|
||||||
|
// place title bar into top-right corner
|
||||||
|
int tw = Math.min( titlePane.getPreferredSize().width, width );
|
||||||
|
int tx = titlePane.getComponentOrientation().isLeftToRight() ? width - tw : 0;
|
||||||
|
titlePane.setBounds( tx, 0, tw, prefHeight );
|
||||||
|
} else
|
||||||
|
titlePane.setBounds( 0, 0, width, prefHeight );
|
||||||
|
|
||||||
|
titlePane.mouseLayer.setBounds( 0, 0, width, prefHeight );
|
||||||
|
|
||||||
|
if( !isFullWindowContent )
|
||||||
|
nextY += prefHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
// glass pane
|
// glass pane
|
||||||
@@ -467,7 +604,7 @@ public class FlatRootPaneUI
|
|||||||
rootPane.getGlassPane().setBounds( x, y + offset, width, height - offset );
|
rootPane.getGlassPane().setBounds( x, y + offset, width, height - offset );
|
||||||
}
|
}
|
||||||
|
|
||||||
// menu bar
|
// menu bar (is a child of layered pane)
|
||||||
JMenuBar menuBar = rootPane.getJMenuBar();
|
JMenuBar menuBar = rootPane.getJMenuBar();
|
||||||
if( menuBar != null && menuBar.isVisible() ) {
|
if( menuBar != null && menuBar.isVisible() ) {
|
||||||
boolean embedded = !isFullScreen && titlePane != null && titlePane.isMenuBarEmbedded();
|
boolean embedded = !isFullScreen && titlePane != null && titlePane.isMenuBarEmbedded();
|
||||||
@@ -475,13 +612,23 @@ public class FlatRootPaneUI
|
|||||||
titlePane.validate();
|
titlePane.validate();
|
||||||
menuBar.setBounds( titlePane.getMenuBarBounds() );
|
menuBar.setBounds( titlePane.getMenuBarBounds() );
|
||||||
} else {
|
} else {
|
||||||
|
int mx = 0;
|
||||||
|
int mw = width;
|
||||||
|
if( titlePane != null && isFullWindowContent( rootPane ) ) {
|
||||||
|
// make menu bar width smaller to avoid that it overlaps title bar buttons
|
||||||
|
int tw = Math.min( titlePane.getPreferredSize().width, width );
|
||||||
|
mw -= tw;
|
||||||
|
if( !titlePane.getComponentOrientation().isLeftToRight() )
|
||||||
|
mx = tw;
|
||||||
|
}
|
||||||
|
|
||||||
Dimension prefSize = menuBar.getPreferredSize();
|
Dimension prefSize = menuBar.getPreferredSize();
|
||||||
menuBar.setBounds( 0, nextY, width, prefSize.height );
|
menuBar.setBounds( mx, nextY, mw, prefSize.height );
|
||||||
nextY += prefSize.height;
|
nextY += prefSize.height;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// content pane
|
// content pane (is a child of layered pane)
|
||||||
Container contentPane = rootPane.getContentPane();
|
Container contentPane = rootPane.getContentPane();
|
||||||
if( contentPane != null )
|
if( contentPane != null )
|
||||||
contentPane.setBounds( 0, nextY, width, Math.max( height - nextY, 0 ) );
|
contentPane.setBounds( 0, nextY, width, Math.max( height - nextY, 0 ) );
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ import com.formdev.flatlaf.util.UIScale;
|
|||||||
*/
|
*/
|
||||||
public class FlatSplitPaneUI
|
public class FlatSplitPaneUI
|
||||||
extends BasicSplitPaneUI
|
extends BasicSplitPaneUI
|
||||||
implements StyleableUI
|
implements StyleableUI, FlatTitlePane.TitleBarCaptionHitTest
|
||||||
{
|
{
|
||||||
@Styleable protected String arrowType;
|
@Styleable protected String arrowType;
|
||||||
/** @since 3.3 */ @Styleable protected Color draggingColor;
|
/** @since 3.3 */ @Styleable protected Color draggingColor;
|
||||||
@@ -227,6 +227,15 @@ public class FlatSplitPaneUI
|
|||||||
((FlatSplitPaneDivider)divider).paintStyle( g, x, y, width, height );
|
((FlatSplitPaneDivider)divider).paintStyle( g, x, y, width, height );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---- interface FlatTitlePane.TitleBarCaptionHitTest ----
|
||||||
|
|
||||||
|
/** @since 3.4 */
|
||||||
|
@Override
|
||||||
|
public Boolean isTitleBarCaptionAt( int x, int y ) {
|
||||||
|
// necessary because BasicSplitPaneDivider adds some mouse listeners for dragging divider
|
||||||
|
return null; // check children
|
||||||
|
}
|
||||||
|
|
||||||
//---- class FlatSplitPaneDivider -----------------------------------------
|
//---- class FlatSplitPaneDivider -----------------------------------------
|
||||||
|
|
||||||
protected class FlatSplitPaneDivider
|
protected class FlatSplitPaneDivider
|
||||||
|
|||||||
@@ -182,7 +182,7 @@ import com.formdev.flatlaf.util.UIScale;
|
|||||||
*/
|
*/
|
||||||
public class FlatTabbedPaneUI
|
public class FlatTabbedPaneUI
|
||||||
extends BasicTabbedPaneUI
|
extends BasicTabbedPaneUI
|
||||||
implements StyleableUI
|
implements StyleableUI, FlatTitlePane.TitleBarCaptionHitTest
|
||||||
{
|
{
|
||||||
// tab type
|
// tab type
|
||||||
/** @since 2 */ protected static final int TAB_TYPE_UNDERLINED = 0;
|
/** @since 2 */ protected static final int TAB_TYPE_UNDERLINED = 0;
|
||||||
@@ -2300,6 +2300,17 @@ debug*/
|
|||||||
return (rects[last].y + rects[last].height) - rects[0].y;
|
return (rects[last].y + rects[last].height) - rects[0].y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---- interface FlatTitlePane.TitleBarCaptionHitTest ----
|
||||||
|
|
||||||
|
/** @since 3.4 */
|
||||||
|
@Override
|
||||||
|
public Boolean isTitleBarCaptionAt( int x, int y ) {
|
||||||
|
if( tabForCoordinate( tabPane, x, y ) >= 0 )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return null; // check children
|
||||||
|
}
|
||||||
|
|
||||||
//---- class TabCloseButton -----------------------------------------------
|
//---- class TabCloseButton -----------------------------------------------
|
||||||
|
|
||||||
private static class TabCloseButton
|
private static class TabCloseButton
|
||||||
@@ -3985,10 +3996,8 @@ debug*/
|
|||||||
//---- class RunWithOriginalLayoutManagerDelegateAction -------------------
|
//---- class RunWithOriginalLayoutManagerDelegateAction -------------------
|
||||||
|
|
||||||
private static class RunWithOriginalLayoutManagerDelegateAction
|
private static class RunWithOriginalLayoutManagerDelegateAction
|
||||||
implements Action
|
extends FlatUIAction
|
||||||
{
|
{
|
||||||
private final Action delegate;
|
|
||||||
|
|
||||||
static void install( ActionMap map, String key ) {
|
static void install( ActionMap map, String key ) {
|
||||||
Action oldAction = map.get( key );
|
Action oldAction = map.get( key );
|
||||||
if( oldAction == null || oldAction instanceof RunWithOriginalLayoutManagerDelegateAction )
|
if( oldAction == null || oldAction instanceof RunWithOriginalLayoutManagerDelegateAction )
|
||||||
@@ -3998,24 +4007,9 @@ debug*/
|
|||||||
}
|
}
|
||||||
|
|
||||||
private RunWithOriginalLayoutManagerDelegateAction( Action delegate ) {
|
private RunWithOriginalLayoutManagerDelegateAction( Action delegate ) {
|
||||||
this.delegate = delegate;
|
super( delegate );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Object getValue( String key ) {
|
|
||||||
return delegate.getValue( key );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isEnabled() {
|
|
||||||
return delegate.isEnabled();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override public void putValue( String key, Object value ) {}
|
|
||||||
@Override public void setEnabled( boolean b ) {}
|
|
||||||
@Override public void addPropertyChangeListener( PropertyChangeListener listener ) {}
|
|
||||||
@Override public void removePropertyChangeListener( PropertyChangeListener listener ) {}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed( ActionEvent e ) {
|
public void actionPerformed( ActionEvent e ) {
|
||||||
JTabbedPane tabbedPane = (JTabbedPane) e.getSource();
|
JTabbedPane tabbedPane = (JTabbedPane) e.getSource();
|
||||||
|
|||||||
@@ -24,15 +24,19 @@ import java.awt.EventQueue;
|
|||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.awt.Insets;
|
import java.awt.Insets;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.FocusEvent;
|
import java.awt.event.FocusEvent;
|
||||||
import java.awt.event.FocusListener;
|
import java.awt.event.FocusListener;
|
||||||
import java.awt.geom.Rectangle2D;
|
import java.awt.geom.Rectangle2D;
|
||||||
import java.beans.PropertyChangeEvent;
|
import java.beans.PropertyChangeEvent;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import javax.swing.Action;
|
||||||
|
import javax.swing.ActionMap;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
import javax.swing.JScrollPane;
|
import javax.swing.JScrollPane;
|
||||||
import javax.swing.JTable;
|
import javax.swing.JTable;
|
||||||
|
import javax.swing.JTextField;
|
||||||
import javax.swing.JViewport;
|
import javax.swing.JViewport;
|
||||||
import javax.swing.LookAndFeel;
|
import javax.swing.LookAndFeel;
|
||||||
import javax.swing.SwingConstants;
|
import javax.swing.SwingConstants;
|
||||||
@@ -89,6 +93,7 @@ import com.formdev.flatlaf.util.UIScale;
|
|||||||
* @uiDefault Table.selectionInactiveBackground Color
|
* @uiDefault Table.selectionInactiveBackground Color
|
||||||
* @uiDefault Table.selectionInactiveForeground Color
|
* @uiDefault Table.selectionInactiveForeground Color
|
||||||
* @uiDefault Table.paintOutsideAlternateRows boolean
|
* @uiDefault Table.paintOutsideAlternateRows boolean
|
||||||
|
* @uiDefault Table.editorSelectAllOnStartEditing boolean
|
||||||
*
|
*
|
||||||
* <!-- FlatTableCellBorder -->
|
* <!-- FlatTableCellBorder -->
|
||||||
*
|
*
|
||||||
@@ -284,6 +289,18 @@ public class FlatTableUI
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void installKeyboardActions() {
|
||||||
|
super.installKeyboardActions();
|
||||||
|
|
||||||
|
if( UIManager.getBoolean( "Table.editorSelectAllOnStartEditing" ) ) {
|
||||||
|
// get shared action map, used for all tables
|
||||||
|
ActionMap map = SwingUtilities.getUIActionMap( table );
|
||||||
|
if( map != null )
|
||||||
|
StartEditingAction.install( map, "startEditing" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** @since 2 */
|
/** @since 2 */
|
||||||
protected void installStyle() {
|
protected void installStyle() {
|
||||||
try {
|
try {
|
||||||
@@ -579,4 +596,36 @@ public class FlatTableUI
|
|||||||
selected = (value != null && (Boolean) value);
|
selected = (value != null && (Boolean) value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---- class StartEditingAction -------------------------------------------
|
||||||
|
|
||||||
|
private static class StartEditingAction
|
||||||
|
extends FlatUIAction
|
||||||
|
{
|
||||||
|
static void install( ActionMap map, String key ) {
|
||||||
|
Action oldAction = map.get( key );
|
||||||
|
if( oldAction == null || oldAction instanceof StartEditingAction )
|
||||||
|
return; // not found or already installed
|
||||||
|
|
||||||
|
map.put( key, new StartEditingAction( oldAction ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
private StartEditingAction( Action delegate ) {
|
||||||
|
super( delegate );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed( ActionEvent e ) {
|
||||||
|
JTable table = (JTable) e.getSource();
|
||||||
|
|
||||||
|
Component oldEditorComp = table.getEditorComponent();
|
||||||
|
|
||||||
|
delegate.actionPerformed( e );
|
||||||
|
|
||||||
|
// select all text in editor if editing starts with F2 key
|
||||||
|
Component editorComp = table.getEditorComponent();
|
||||||
|
if( oldEditorComp == null && editorComp instanceof JTextField )
|
||||||
|
((JTextField)editorComp).selectAll();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ import java.awt.Rectangle;
|
|||||||
import java.awt.Toolkit;
|
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.ComponentAdapter;
|
||||||
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;
|
||||||
@@ -46,9 +47,9 @@ import java.awt.event.WindowEvent;
|
|||||||
import java.awt.geom.AffineTransform;
|
import java.awt.geom.AffineTransform;
|
||||||
import java.beans.PropertyChangeEvent;
|
import java.beans.PropertyChangeEvent;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
import java.util.function.Function;
|
||||||
import javax.accessibility.AccessibleContext;
|
import javax.accessibility.AccessibleContext;
|
||||||
import javax.swing.BorderFactory;
|
import javax.swing.BorderFactory;
|
||||||
import javax.swing.Box;
|
import javax.swing.Box;
|
||||||
@@ -57,7 +58,6 @@ import javax.swing.Icon;
|
|||||||
import javax.swing.JButton;
|
import javax.swing.JButton;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
import javax.swing.JDialog;
|
import javax.swing.JDialog;
|
||||||
import javax.swing.JInternalFrame;
|
|
||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
import javax.swing.JMenuBar;
|
import javax.swing.JMenuBar;
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
@@ -66,6 +66,7 @@ import javax.swing.SwingUtilities;
|
|||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import javax.swing.border.AbstractBorder;
|
import javax.swing.border.AbstractBorder;
|
||||||
import javax.swing.border.Border;
|
import javax.swing.border.Border;
|
||||||
|
import javax.swing.plaf.ComponentUI;
|
||||||
import com.formdev.flatlaf.FlatClientProperties;
|
import com.formdev.flatlaf.FlatClientProperties;
|
||||||
import com.formdev.flatlaf.FlatSystemProperties;
|
import com.formdev.flatlaf.FlatSystemProperties;
|
||||||
import com.formdev.flatlaf.ui.FlatNativeWindowBorder.WindowTopBorder;
|
import com.formdev.flatlaf.ui.FlatNativeWindowBorder.WindowTopBorder;
|
||||||
@@ -98,7 +99,6 @@ import com.formdev.flatlaf.util.UIScale;
|
|||||||
* @uiDefault TitlePane.showIconBesideTitle boolean
|
* @uiDefault TitlePane.showIconBesideTitle boolean
|
||||||
* @uiDefault TitlePane.menuBarTitleGap int
|
* @uiDefault TitlePane.menuBarTitleGap int
|
||||||
* @uiDefault TitlePane.menuBarTitleMinimumGap int
|
* @uiDefault TitlePane.menuBarTitleMinimumGap int
|
||||||
* @uiDefault TitlePane.menuBarResizeHeight int
|
|
||||||
* @uiDefault TitlePane.closeIcon Icon
|
* @uiDefault TitlePane.closeIcon Icon
|
||||||
* @uiDefault TitlePane.iconifyIcon Icon
|
* @uiDefault TitlePane.iconifyIcon Icon
|
||||||
* @uiDefault TitlePane.maximizeIcon Icon
|
* @uiDefault TitlePane.maximizeIcon Icon
|
||||||
@@ -109,7 +109,7 @@ import com.formdev.flatlaf.util.UIScale;
|
|||||||
public class FlatTitlePane
|
public class FlatTitlePane
|
||||||
extends JComponent
|
extends JComponent
|
||||||
{
|
{
|
||||||
private static final String KEY_DEBUG_SHOW_RECTANGLES = "FlatLaf.debug.titlebar.showRectangles";
|
static final String KEY_DEBUG_SHOW_RECTANGLES = "FlatLaf.debug.titlebar.showRectangles";
|
||||||
|
|
||||||
/** @since 2.5 */ protected final Font titleFont;
|
/** @since 2.5 */ protected final Font titleFont;
|
||||||
protected final Color activeBackground;
|
protected final Color activeBackground;
|
||||||
@@ -131,7 +131,6 @@ public class FlatTitlePane
|
|||||||
/** @since 2.4 */ protected final boolean showIconBesideTitle;
|
/** @since 2.4 */ protected final boolean showIconBesideTitle;
|
||||||
protected final int menuBarTitleGap;
|
protected final int menuBarTitleGap;
|
||||||
/** @since 2.4 */ protected final int menuBarTitleMinimumGap;
|
/** @since 2.4 */ protected final int menuBarTitleMinimumGap;
|
||||||
/** @since 2.4 */ protected final int menuBarResizeHeight;
|
|
||||||
|
|
||||||
protected final JRootPane rootPane;
|
protected final JRootPane rootPane;
|
||||||
protected final String windowStyle;
|
protected final String windowStyle;
|
||||||
@@ -150,6 +149,23 @@ public class FlatTitlePane
|
|||||||
|
|
||||||
private final Handler handler;
|
private final Handler handler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This panel handles mouse events if FlatLaf window decorations are used
|
||||||
|
* without native window border. E.g. on Linux.
|
||||||
|
* <p>
|
||||||
|
* This panel usually has same bounds as the title pane,
|
||||||
|
* except if fullWindowContent mode is enabled.
|
||||||
|
* <p>
|
||||||
|
* This panel is not a child of the title pane.
|
||||||
|
* Instead it is added by FlatRootPaneUI to the layered pane at a layer
|
||||||
|
* under the title pane and under the frame content.
|
||||||
|
* The separation is necessary for fullWindowContent mode, where the title pane
|
||||||
|
* is layered over the frame content (for title pane buttons), but the mousePanel
|
||||||
|
* needs to be layered under the frame content so that components on content pane
|
||||||
|
* can receive mouse events when located in title area.
|
||||||
|
*/
|
||||||
|
final JPanel mouseLayer;
|
||||||
|
|
||||||
public FlatTitlePane( JRootPane rootPane ) {
|
public FlatTitlePane( JRootPane rootPane ) {
|
||||||
this.rootPane = rootPane;
|
this.rootPane = rootPane;
|
||||||
|
|
||||||
@@ -178,7 +194,6 @@ public class FlatTitlePane
|
|||||||
showIconBesideTitle = FlatUIUtils.getSubUIBoolean( "TitlePane.showIconBesideTitle", windowStyle, false );
|
showIconBesideTitle = FlatUIUtils.getSubUIBoolean( "TitlePane.showIconBesideTitle", windowStyle, false );
|
||||||
menuBarTitleGap = FlatUIUtils.getSubUIInt( "TitlePane.menuBarTitleGap", windowStyle, 40 );
|
menuBarTitleGap = FlatUIUtils.getSubUIInt( "TitlePane.menuBarTitleGap", windowStyle, 40 );
|
||||||
menuBarTitleMinimumGap = FlatUIUtils.getSubUIInt( "TitlePane.menuBarTitleMinimumGap", windowStyle, 12 );
|
menuBarTitleMinimumGap = FlatUIUtils.getSubUIInt( "TitlePane.menuBarTitleMinimumGap", windowStyle, 12 );
|
||||||
menuBarResizeHeight = FlatUIUtils.getSubUIInt( "TitlePane.menuBarResizeHeight", windowStyle, 4 );
|
|
||||||
|
|
||||||
|
|
||||||
handler = createHandler();
|
handler = createHandler();
|
||||||
@@ -187,11 +202,10 @@ public class FlatTitlePane
|
|||||||
addSubComponents();
|
addSubComponents();
|
||||||
activeChanged( true );
|
activeChanged( true );
|
||||||
|
|
||||||
addMouseListener( handler );
|
mouseLayer = new JPanel();
|
||||||
addMouseMotionListener( handler );
|
mouseLayer.setOpaque( false );
|
||||||
|
mouseLayer.addMouseListener( handler );
|
||||||
// necessary for closing window with double-click on icon
|
mouseLayer.addMouseMotionListener( handler );
|
||||||
iconLabel.addMouseListener( handler );
|
|
||||||
|
|
||||||
applyComponentOrientation( rootPane.getComponentOrientation() );
|
applyComponentOrientation( rootPane.getComponentOrientation() );
|
||||||
}
|
}
|
||||||
@@ -234,6 +248,11 @@ public class FlatTitlePane
|
|||||||
setLayout( new BorderLayout() {
|
setLayout( new BorderLayout() {
|
||||||
@Override
|
@Override
|
||||||
public void layoutContainer( Container target ) {
|
public void layoutContainer( Container target ) {
|
||||||
|
if( isFullWindowContent() ) {
|
||||||
|
super.layoutContainer( target );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// compute available bounds
|
// compute available bounds
|
||||||
Insets insets = target.getInsets();
|
Insets insets = target.getInsets();
|
||||||
int x = insets.left;
|
int x = insets.left;
|
||||||
@@ -247,7 +266,7 @@ public class FlatTitlePane
|
|||||||
int titleWidth = w - leftWidth - buttonsWidth;
|
int titleWidth = w - leftWidth - buttonsWidth;
|
||||||
int minTitleWidth = UIScale.scale( titleMinimumWidth );
|
int minTitleWidth = UIScale.scale( titleMinimumWidth );
|
||||||
|
|
||||||
// increase minimum width if icon is show besides the title
|
// increase minimum width if icon is shown besides the title
|
||||||
Icon icon = titleLabel.getIcon();
|
Icon icon = titleLabel.getIcon();
|
||||||
if( icon != null ) {
|
if( icon != null ) {
|
||||||
Insets iconInsets = iconLabel.getInsets();
|
Insets iconInsets = iconLabel.getInsets();
|
||||||
@@ -295,6 +314,9 @@ public class FlatTitlePane
|
|||||||
horizontalGlue.getWidth(), titleLabel.getHeight() );
|
horizontalGlue.getWidth(), titleLabel.getHeight() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// clear hit-test cache
|
||||||
|
lastCaptionHitTestTime = 0;
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
|
|
||||||
@@ -338,6 +360,13 @@ public class FlatTitlePane
|
|||||||
buttonPanel.add( restoreButton );
|
buttonPanel.add( restoreButton );
|
||||||
}
|
}
|
||||||
buttonPanel.add( closeButton );
|
buttonPanel.add( closeButton );
|
||||||
|
|
||||||
|
ComponentListener l = new ComponentAdapter() {
|
||||||
|
@Override public void componentResized( ComponentEvent e ) { updateFullWindowContentButtonsBoundsProperty(); }
|
||||||
|
@Override public void componentMoved( ComponentEvent e ) { updateFullWindowContentButtonsBoundsProperty(); }
|
||||||
|
};
|
||||||
|
buttonPanel.addComponentListener( l );
|
||||||
|
addComponentListener( l );
|
||||||
}
|
}
|
||||||
|
|
||||||
protected JButton createButton( String iconKey, String accessibleName, ActionListener action ) {
|
protected JButton createButton( String iconKey, String accessibleName, ActionListener action ) {
|
||||||
@@ -417,7 +446,9 @@ public class FlatTitlePane
|
|||||||
|
|
||||||
/** @since 3 */
|
/** @since 3 */
|
||||||
protected void updateVisibility() {
|
protected void updateVisibility() {
|
||||||
titleLabel.setVisible( clientPropertyBoolean( rootPane, TITLE_BAR_SHOW_TITLE, true ) );
|
boolean isFullWindowContent = isFullWindowContent();
|
||||||
|
leftPanel.setVisible( !isFullWindowContent );
|
||||||
|
titleLabel.setVisible( clientPropertyBoolean( rootPane, TITLE_BAR_SHOW_TITLE, true ) && !isFullWindowContent );
|
||||||
closeButton.setVisible( clientPropertyBoolean( rootPane, TITLE_BAR_SHOW_CLOSE, true ) );
|
closeButton.setVisible( clientPropertyBoolean( rootPane, TITLE_BAR_SHOW_CLOSE, true ) );
|
||||||
|
|
||||||
if( window instanceof Frame ) {
|
if( window instanceof Frame ) {
|
||||||
@@ -443,7 +474,7 @@ public class FlatTitlePane
|
|||||||
|
|
||||||
// get window images
|
// get window images
|
||||||
List<Image> images = null;
|
List<Image> images = null;
|
||||||
if( clientPropertyBoolean( rootPane, TITLE_BAR_SHOW_ICON, defaultShowIcon ) ) {
|
if( clientPropertyBoolean( rootPane, TITLE_BAR_SHOW_ICON, defaultShowIcon ) && !isFullWindowContent() ) {
|
||||||
images = window.getIconImages();
|
images = window.getIconImages();
|
||||||
if( images.isEmpty() ) {
|
if( images.isEmpty() ) {
|
||||||
// search in owners
|
// search in owners
|
||||||
@@ -468,6 +499,13 @@ public class FlatTitlePane
|
|||||||
updateNativeTitleBarHeightAndHitTestSpotsLater();
|
updateNativeTitleBarHeightAndHitTestSpotsLater();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void updateFullWindowContentButtonsBoundsProperty() {
|
||||||
|
Rectangle bounds = isFullWindowContent()
|
||||||
|
? new Rectangle( SwingUtilities.convertPoint( buttonPanel, 0, 0, rootPane ), buttonPanel.getSize() )
|
||||||
|
: null;
|
||||||
|
rootPane.putClientProperty( FlatClientProperties.FULL_WINDOW_CONTENT_BUTTONS_BOUNDS, bounds );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addNotify() {
|
public void addNotify() {
|
||||||
super.addNotify();
|
super.addNotify();
|
||||||
@@ -522,6 +560,11 @@ public class FlatTitlePane
|
|||||||
window.removeComponentListener( handler );
|
window.removeComponentListener( handler );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 3.4 */
|
||||||
|
protected boolean isFullWindowContent() {
|
||||||
|
return FlatRootPaneUI.isFullWindowContent( rootPane );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether this title pane currently has a visible and embedded menubar.
|
* Returns whether this title pane currently has a visible and embedded menubar.
|
||||||
*/
|
*/
|
||||||
@@ -533,6 +576,9 @@ public class FlatTitlePane
|
|||||||
* Returns whether the menubar should be embedded into the title pane.
|
* Returns whether the menubar should be embedded into the title pane.
|
||||||
*/
|
*/
|
||||||
protected boolean isMenuBarEmbedded() {
|
protected boolean isMenuBarEmbedded() {
|
||||||
|
if( isFullWindowContent() )
|
||||||
|
return false;
|
||||||
|
|
||||||
// not storing value of "TitlePane.menuBarEmbedded" in class to allow changing at runtime
|
// not storing value of "TitlePane.menuBarEmbedded" in class to allow changing at runtime
|
||||||
return FlatUIUtils.getBoolean( rootPane,
|
return FlatUIUtils.getBoolean( rootPane,
|
||||||
FlatSystemProperties.MENUBAR_EMBEDDED,
|
FlatSystemProperties.MENUBAR_EMBEDDED,
|
||||||
@@ -620,21 +666,45 @@ public class FlatTitlePane
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if( debugTitleBarHeight > 0 ) {
|
if( debugTitleBarHeight > 0 ) {
|
||||||
|
// title bar height is measured from window top edge
|
||||||
|
int y = SwingUtilities.convertPoint( window, 0, debugTitleBarHeight, this ).y;
|
||||||
g.setColor( Color.green );
|
g.setColor( Color.green );
|
||||||
g.drawLine( 0, debugTitleBarHeight, getWidth(), debugTitleBarHeight );
|
g.drawLine( 0, y, getWidth(), y );
|
||||||
}
|
}
|
||||||
if( debugHitTestSpots != null ) {
|
|
||||||
for( Rectangle r : debugHitTestSpots )
|
g.setColor( Color.red );
|
||||||
paintRect( g, Color.red, r );
|
debugPaintComponentWithMouseListener( g, Color.red, rootPane.getLayeredPane(), 0, 0 );
|
||||||
}
|
|
||||||
paintRect( g, Color.cyan, debugCloseButtonBounds );
|
debugPaintRect( g, Color.blue, debugAppIconBounds );
|
||||||
paintRect( g, Color.blue, debugAppIconBounds );
|
debugPaintRect( g, Color.blue, debugMinimizeButtonBounds );
|
||||||
paintRect( g, Color.blue, debugMinimizeButtonBounds );
|
debugPaintRect( g, Color.magenta, debugMaximizeButtonBounds );
|
||||||
paintRect( g, Color.magenta, debugMaximizeButtonBounds );
|
debugPaintRect( g, Color.cyan, debugCloseButtonBounds );
|
||||||
paintRect( g, Color.cyan, debugCloseButtonBounds );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void paintRect( Graphics g, Color color, Rectangle r ) {
|
private void debugPaintComponentWithMouseListener( Graphics g, Color color, Component c, int x, int y ) {
|
||||||
|
if( !c.isDisplayable() || !c.isVisible() || c == mouseLayer ||
|
||||||
|
c == iconifyButton || c == maximizeButton || c == restoreButton || c == closeButton )
|
||||||
|
return;
|
||||||
|
|
||||||
|
if( c.getMouseListeners().length > 0 ||
|
||||||
|
c.getMouseMotionListeners().length > 0 ||
|
||||||
|
c.getMouseWheelListeners().length > 0 )
|
||||||
|
{
|
||||||
|
g.drawRect( x, y, c.getWidth(), c.getHeight() );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( c instanceof Container ) {
|
||||||
|
Rectangle titlePaneBoundsOnWindow = SwingUtilities.convertRectangle( this, new Rectangle( getSize() ), window );
|
||||||
|
for( Component child : ((Container)c).getComponents() ) {
|
||||||
|
Rectangle compBoundsOnWindow = SwingUtilities.convertRectangle( c, new Rectangle( c.getSize() ), window );
|
||||||
|
if( compBoundsOnWindow.intersects( titlePaneBoundsOnWindow ) )
|
||||||
|
debugPaintComponentWithMouseListener( g, color, child, x + child.getX(), y + child.getY() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void debugPaintRect( Graphics g, Color color, Rectangle r ) {
|
||||||
if( r == null )
|
if( r == null )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -645,6 +715,9 @@ public class FlatTitlePane
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void paintComponent( Graphics g ) {
|
protected void paintComponent( Graphics g ) {
|
||||||
|
if( isFullWindowContent() )
|
||||||
|
return;
|
||||||
|
|
||||||
// not storing value of "TitlePane.unifiedBackground" in class to allow changing at runtime
|
// not storing value of "TitlePane.unifiedBackground" in class to allow changing at runtime
|
||||||
g.setColor( (UIManager.getBoolean( "TitlePane.unifiedBackground" ) &&
|
g.setColor( (UIManager.getBoolean( "TitlePane.unifiedBackground" ) &&
|
||||||
clientPropertyColor( rootPane, TITLE_BAR_BACKGROUND, null ) == null)
|
clientPropertyColor( rootPane, TITLE_BAR_BACKGROUND, null ) == null)
|
||||||
@@ -866,11 +939,14 @@ public class FlatTitlePane
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
int titleBarHeight = getHeight();
|
int titleBarHeight = getHeight();
|
||||||
|
// title bar height must be measured from window top edge
|
||||||
|
// (when window is maximized, window y location is e.g. -11 and window top inset is 11)
|
||||||
|
for( Component c = this; c != window && c != null; c = c.getParent() )
|
||||||
|
titleBarHeight += c.getY();
|
||||||
// slightly reduce height so that component receives mouseExit events
|
// slightly reduce height so that component receives mouseExit events
|
||||||
if( titleBarHeight > 0 )
|
if( titleBarHeight > 0 )
|
||||||
titleBarHeight--;
|
titleBarHeight--;
|
||||||
|
|
||||||
List<Rectangle> hitTestSpots = new ArrayList<>();
|
|
||||||
Rectangle appIconBounds = null;
|
Rectangle appIconBounds = null;
|
||||||
|
|
||||||
if( !showIconBesideTitle && iconLabel.isVisible() ) {
|
if( !showIconBesideTitle && iconLabel.isVisible() ) {
|
||||||
@@ -928,71 +1004,17 @@ public class FlatTitlePane
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle r = getNativeHitTestSpot( buttonPanel );
|
|
||||||
if( r != null )
|
|
||||||
hitTestSpots.add( r );
|
|
||||||
|
|
||||||
JMenuBar menuBar = rootPane.getJMenuBar();
|
|
||||||
if( hasVisibleEmbeddedMenuBar( menuBar ) ) {
|
|
||||||
r = getNativeHitTestSpot( menuBar );
|
|
||||||
if( r != null ) {
|
|
||||||
// if frame is resizable and not maximized, make menu bar hit test spot smaller at top
|
|
||||||
// to have a small area above the menu bar to resize the window
|
|
||||||
if( window instanceof Frame && ((Frame)window).isResizable() && !isWindowMaximized() ) {
|
|
||||||
// limit to 8, because Windows does not use a larger height
|
|
||||||
int resizeHeight = UIScale.scale( Math.min( menuBarResizeHeight, 8 ) );
|
|
||||||
r.y += resizeHeight;
|
|
||||||
r.height -= resizeHeight;
|
|
||||||
}
|
|
||||||
|
|
||||||
int count = menuBar.getComponentCount();
|
|
||||||
for( int i = count - 1; i >= 0; i-- ) {
|
|
||||||
Component c = menuBar.getComponent( i );
|
|
||||||
if( c instanceof Box.Filler ||
|
|
||||||
(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( c, 0, 0, window );
|
|
||||||
int x2 = glueLocation.x + c.getWidth();
|
|
||||||
Rectangle r2;
|
|
||||||
if( getComponentOrientation().isLeftToRight() ) {
|
|
||||||
r2 = new Rectangle( x2, r.y, (r.x + r.width) - x2, r.height );
|
|
||||||
|
|
||||||
r.width = glueLocation.x - r.x;
|
|
||||||
} else {
|
|
||||||
r2 = new Rectangle( r.x, r.y, glueLocation.x - r.x, r.height );
|
|
||||||
|
|
||||||
r.width = (r.x + r.width) - x2;
|
|
||||||
r.x = x2;
|
|
||||||
}
|
|
||||||
if( r2.width > 0 )
|
|
||||||
hitTestSpots.add( r2 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
hitTestSpots.add( r );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// allow internal frames in layered pane to be moved/resized when placed over title bar
|
|
||||||
for( Component c : rootPane.getLayeredPane().getComponents() ) {
|
|
||||||
r = (c instanceof JInternalFrame) ? getNativeHitTestSpot( (JInternalFrame) c ) : null;
|
|
||||||
if( r != null )
|
|
||||||
hitTestSpots.add( r );
|
|
||||||
}
|
|
||||||
|
|
||||||
Rectangle minimizeButtonBounds = boundsInWindow( iconifyButton );
|
Rectangle minimizeButtonBounds = boundsInWindow( iconifyButton );
|
||||||
Rectangle maximizeButtonBounds = boundsInWindow( maximizeButton.isVisible() ? maximizeButton : restoreButton );
|
Rectangle maximizeButtonBounds = boundsInWindow( maximizeButton.isVisible() ? maximizeButton : restoreButton );
|
||||||
Rectangle closeButtonBounds = boundsInWindow( closeButton );
|
Rectangle closeButtonBounds = boundsInWindow( closeButton );
|
||||||
|
|
||||||
|
// clear hit-test cache
|
||||||
|
lastCaptionHitTestTime = 0;
|
||||||
|
|
||||||
FlatNativeWindowBorder.setTitleBarHeightAndHitTestSpots( window, titleBarHeight,
|
FlatNativeWindowBorder.setTitleBarHeightAndHitTestSpots( window, titleBarHeight,
|
||||||
hitTestSpots, appIconBounds, minimizeButtonBounds, maximizeButtonBounds, closeButtonBounds );
|
this::captionHitTest, appIconBounds, minimizeButtonBounds, maximizeButtonBounds, closeButtonBounds );
|
||||||
|
|
||||||
debugTitleBarHeight = titleBarHeight;
|
debugTitleBarHeight = titleBarHeight;
|
||||||
debugHitTestSpots = hitTestSpots;
|
|
||||||
debugAppIconBounds = appIconBounds;
|
debugAppIconBounds = appIconBounds;
|
||||||
debugMinimizeButtonBounds = minimizeButtonBounds;
|
debugMinimizeButtonBounds = minimizeButtonBounds;
|
||||||
debugMaximizeButtonBounds = maximizeButtonBounds;
|
debugMaximizeButtonBounds = maximizeButtonBounds;
|
||||||
@@ -1007,18 +1029,101 @@ public class FlatTitlePane
|
|||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Rectangle getNativeHitTestSpot( JComponent c ) {
|
/**
|
||||||
Dimension size = c.getSize();
|
* Returns whether there is a component at the given location, that processes
|
||||||
if( size.width <= 0 || size.height <= 0 )
|
* mouse events. E.g. buttons, menus, etc.
|
||||||
return null;
|
* <p>
|
||||||
|
* Note:
|
||||||
|
* <ul>
|
||||||
|
* <li>This method is invoked often when mouse is moved over title bar
|
||||||
|
* and should therefore return quickly.
|
||||||
|
* <li>This method is invoked on 'AWT-Windows' thread (not 'AWT-EventQueue' thread)
|
||||||
|
* while processing Windows messages.
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
private boolean captionHitTest( Point pt ) {
|
||||||
|
// Windows invokes this method every ~200ms, even if the mouse has not moved
|
||||||
|
long time = System.currentTimeMillis();
|
||||||
|
if( pt.x == lastCaptionHitTestX && pt.y == lastCaptionHitTestY && time < lastCaptionHitTestTime + 300 ) {
|
||||||
|
lastCaptionHitTestTime = time;
|
||||||
|
return lastCaptionHitTestResult;
|
||||||
|
}
|
||||||
|
|
||||||
Point location = SwingUtilities.convertPoint( c, 0, 0, window );
|
// convert pt from window coordinates to layeredPane coordinates
|
||||||
Rectangle r = new Rectangle( location, size );
|
Component layeredPane = rootPane.getLayeredPane();
|
||||||
return r;
|
int x = pt.x;
|
||||||
|
int y = pt.y;
|
||||||
|
for( Component c = layeredPane; c != window && c != null; c = c.getParent() ) {
|
||||||
|
x -= c.getX();
|
||||||
|
y -= c.getY();
|
||||||
|
}
|
||||||
|
|
||||||
|
lastCaptionHitTestX = pt.x;
|
||||||
|
lastCaptionHitTestY = pt.y;
|
||||||
|
lastCaptionHitTestTime = time;
|
||||||
|
lastCaptionHitTestResult = isTitleBarCaptionAt( layeredPane, x, y );
|
||||||
|
return lastCaptionHitTestResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isTitleBarCaptionAt( Component c, int x, int y ) {
|
||||||
|
if( !c.isDisplayable() || !c.isVisible() || !c.contains( x, y ) || c == mouseLayer )
|
||||||
|
return true; // continue checking with next component
|
||||||
|
|
||||||
|
if( c.isEnabled() &&
|
||||||
|
(c.getMouseListeners().length > 0 ||
|
||||||
|
c.getMouseMotionListeners().length > 0) )
|
||||||
|
{
|
||||||
|
if( !(c instanceof JComponent) )
|
||||||
|
return false; // assume that this is not a caption because the component has mouse listeners
|
||||||
|
|
||||||
|
// check client property boolean value
|
||||||
|
Object caption = ((JComponent)c).getClientProperty( COMPONENT_TITLE_BAR_CAPTION );
|
||||||
|
if( caption instanceof Boolean )
|
||||||
|
return (boolean) caption;
|
||||||
|
|
||||||
|
// if component is not fully layouted, do not invoke function
|
||||||
|
// because it is too dangerous that the function tries to layout the component,
|
||||||
|
// which could cause a dead lock
|
||||||
|
if( !c.isValid() )
|
||||||
|
return false; // assume that this is not a caption because the component has mouse listeners
|
||||||
|
|
||||||
|
if( caption instanceof Function ) {
|
||||||
|
// check client property function value
|
||||||
|
@SuppressWarnings( "unchecked" )
|
||||||
|
Function<Point, Boolean> hitTest = (Function<Point, Boolean>) caption;
|
||||||
|
Boolean result = hitTest.apply( new Point( x, y ) );
|
||||||
|
if( result != null )
|
||||||
|
return result;
|
||||||
|
} else {
|
||||||
|
// check component UI
|
||||||
|
ComponentUI ui = JavaCompatibility2.getUI( (JComponent) c );
|
||||||
|
if( !(ui instanceof TitleBarCaptionHitTest) )
|
||||||
|
return false; // assume that this is not a caption because the component has mouse listeners
|
||||||
|
|
||||||
|
Boolean result = ((TitleBarCaptionHitTest)ui).isTitleBarCaptionAt( x, y );
|
||||||
|
if( result != null )
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// else continue checking children
|
||||||
|
}
|
||||||
|
|
||||||
|
// check children
|
||||||
|
if( c instanceof Container ) {
|
||||||
|
for( Component child : ((Container)c).getComponents() ) {
|
||||||
|
if( !isTitleBarCaptionAt( child, x - child.getX(), y - child.getY() ) )
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int lastCaptionHitTestX;
|
||||||
|
private int lastCaptionHitTestY;
|
||||||
|
private long lastCaptionHitTestTime;
|
||||||
|
private boolean lastCaptionHitTestResult;
|
||||||
|
|
||||||
private int debugTitleBarHeight;
|
private int debugTitleBarHeight;
|
||||||
private List<Rectangle> debugHitTestSpots;
|
|
||||||
private Rectangle debugAppIconBounds;
|
private Rectangle debugAppIconBounds;
|
||||||
private Rectangle debugMinimizeButtonBounds;
|
private Rectangle debugMinimizeButtonBounds;
|
||||||
private Rectangle debugMaximizeButtonBounds;
|
private Rectangle debugMaximizeButtonBounds;
|
||||||
@@ -1116,7 +1221,7 @@ public class FlatTitlePane
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// compute icon width and gap (if icon is show besides the title)
|
// compute icon width and gap (if icon is shown besides the title)
|
||||||
int iconTextGap = 0;
|
int iconTextGap = 0;
|
||||||
int iconWidthAndGap = 0;
|
int iconWidthAndGap = 0;
|
||||||
if( icon != null ) {
|
if( icon != null ) {
|
||||||
@@ -1125,7 +1230,7 @@ public class FlatTitlePane
|
|||||||
iconWidthAndGap = icon.getIconWidth() + iconTextGap;
|
iconWidthAndGap = icon.getIconWidth() + iconTextGap;
|
||||||
}
|
}
|
||||||
|
|
||||||
// layout title and icon (if show besides the title)
|
// layout title and icon (if shown besides the title)
|
||||||
String clippedText = SwingUtilities.layoutCompoundLabel( label, fontMetrics, text, icon,
|
String clippedText = SwingUtilities.layoutCompoundLabel( label, fontMetrics, text, icon,
|
||||||
label.getVerticalAlignment(), label.getHorizontalAlignment(),
|
label.getVerticalAlignment(), label.getHorizontalAlignment(),
|
||||||
label.getVerticalTextPosition(), label.getHorizontalTextPosition(),
|
label.getVerticalTextPosition(), label.getHorizontalTextPosition(),
|
||||||
@@ -1275,7 +1380,7 @@ debug*/
|
|||||||
}
|
}
|
||||||
|
|
||||||
if( e.getClickCount() == 2 && SwingUtilities.isLeftMouseButton( e ) ) {
|
if( e.getClickCount() == 2 && SwingUtilities.isLeftMouseButton( e ) ) {
|
||||||
if( e.getSource() == iconLabel ) {
|
if( SwingUtilities.getDeepestComponentAt( FlatTitlePane.this, e.getX(), e.getY() ) == iconLabel ) {
|
||||||
// double-click on icon closes window
|
// double-click on icon closes window
|
||||||
close();
|
close();
|
||||||
} else if( !hasNativeCustomDecoration() ) {
|
} else if( !hasNativeCustomDecoration() ) {
|
||||||
@@ -1302,7 +1407,7 @@ debug*/
|
|||||||
if( !SwingUtilities.isLeftMouseButton( e ) )
|
if( !SwingUtilities.isLeftMouseButton( e ) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
dragOffset = SwingUtilities.convertPoint( FlatTitlePane.this, e.getPoint(), window );
|
dragOffset = SwingUtilities.convertPoint( mouseLayer, e.getPoint(), window );
|
||||||
linuxNativeMove = false;
|
linuxNativeMove = false;
|
||||||
|
|
||||||
// on Linux, move or maximize/restore window
|
// on Linux, move or maximize/restore window
|
||||||
@@ -1415,4 +1520,27 @@ debug*/
|
|||||||
@Override public void componentMoved( ComponentEvent e ) {}
|
@Override public void componentMoved( ComponentEvent e ) {}
|
||||||
@Override public void componentHidden( ComponentEvent e ) {}
|
@Override public void componentHidden( ComponentEvent e ) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---- interface TitleBarCaptionHitTest -----------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For custom components use {@link FlatClientProperties#COMPONENT_TITLE_BAR_CAPTION}
|
||||||
|
* instead of this interface.
|
||||||
|
*
|
||||||
|
* @since 3.4
|
||||||
|
*/
|
||||||
|
public interface TitleBarCaptionHitTest {
|
||||||
|
/**
|
||||||
|
* Invoked for a component that is enabled and has mouse listeners,
|
||||||
|
* to check whether it processes mouse input at the given x/y location.
|
||||||
|
* Useful for components that do not use mouse input on whole component bounds.
|
||||||
|
* E.g. a tabbed pane with a few tabs has some empty space beside the tabs
|
||||||
|
* that can be used to move the window.
|
||||||
|
*
|
||||||
|
* @return {@code true} if the component is not interested in mouse input at the given location
|
||||||
|
* {@code false} if the component wants process mouse input at the given location
|
||||||
|
* {@code null} if the component children should be checked
|
||||||
|
*/
|
||||||
|
Boolean isTitleBarCaptionAt( int x, int y );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ import com.formdev.flatlaf.util.UIScale;
|
|||||||
*/
|
*/
|
||||||
public class FlatToolBarUI
|
public class FlatToolBarUI
|
||||||
extends BasicToolBarUI
|
extends BasicToolBarUI
|
||||||
implements StyleableUI
|
implements StyleableUI, FlatTitlePane.TitleBarCaptionHitTest
|
||||||
{
|
{
|
||||||
/** @since 1.4 */ @Styleable protected boolean focusableButtons;
|
/** @since 1.4 */ @Styleable protected boolean focusableButtons;
|
||||||
/** @since 2 */ @Styleable protected boolean arrowKeysOnlyNavigation;
|
/** @since 2 */ @Styleable protected boolean arrowKeysOnlyNavigation;
|
||||||
@@ -453,6 +453,15 @@ public class FlatToolBarUI
|
|||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---- interface FlatTitlePane.TitleBarCaptionHitTest ----
|
||||||
|
|
||||||
|
/** @since 3.4 */
|
||||||
|
@Override
|
||||||
|
public Boolean isTitleBarCaptionAt( int x, int y ) {
|
||||||
|
// necessary because BasicToolBarUI adds some mouse listeners for dragging when toolbar is floatable
|
||||||
|
return null; // check children
|
||||||
|
}
|
||||||
|
|
||||||
//---- class FlatToolBarFocusTraversalPolicy ------------------------------
|
//---- class FlatToolBarFocusTraversalPolicy ------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2024 FormDev Software GmbH
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://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.beans.PropertyChangeListener;
|
||||||
|
import javax.swing.Action;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Base class for UI actions used in ActionMap.
|
||||||
|
* (similar to class sun.swing.UIAction)
|
||||||
|
*
|
||||||
|
* @author Karl Tauber
|
||||||
|
* @since 3.4
|
||||||
|
*/
|
||||||
|
public abstract class FlatUIAction
|
||||||
|
implements Action
|
||||||
|
{
|
||||||
|
protected final String name;
|
||||||
|
protected final Action delegate;
|
||||||
|
|
||||||
|
protected FlatUIAction( String name ) {
|
||||||
|
this.name = name;
|
||||||
|
this.delegate = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected FlatUIAction( Action delegate ) {
|
||||||
|
this.name = null;
|
||||||
|
this.delegate = delegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getValue( String key ) {
|
||||||
|
if( key == NAME && delegate == null )
|
||||||
|
return name;
|
||||||
|
return (delegate != null) ? delegate.getValue( key ) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnabled() {
|
||||||
|
return (delegate != null) ? delegate.isEnabled() : true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// do nothing in following methods because this class is immutable
|
||||||
|
@Override public void putValue( String key, Object value ) {}
|
||||||
|
@Override public void setEnabled( boolean b ) {}
|
||||||
|
@Override public void addPropertyChangeListener( PropertyChangeListener listener ) {}
|
||||||
|
@Override public void removePropertyChangeListener( PropertyChangeListener listener ) {}
|
||||||
|
}
|
||||||
@@ -60,6 +60,7 @@ 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 javax.swing.tree.DefaultTreeCellEditor;
|
||||||
import com.formdev.flatlaf.FlatClientProperties;
|
import com.formdev.flatlaf.FlatClientProperties;
|
||||||
import com.formdev.flatlaf.FlatIntelliJLaf;
|
import com.formdev.flatlaf.FlatIntelliJLaf;
|
||||||
import com.formdev.flatlaf.FlatLaf;
|
import com.formdev.flatlaf.FlatLaf;
|
||||||
@@ -304,6 +305,10 @@ public class FlatUIUtils
|
|||||||
if( parent instanceof JTable && ((JTable)parent).getEditorComponent() == c )
|
if( parent instanceof JTable && ((JTable)parent).getEditorComponent() == c )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
// check whether used as tree cell editor
|
||||||
|
if( parent instanceof DefaultTreeCellEditor.EditorContainer )
|
||||||
|
return true;
|
||||||
|
|
||||||
// check whether used as cell editor
|
// check whether used as cell editor
|
||||||
// Table.editor is set in JTable.GenericEditor constructor
|
// Table.editor is set in JTable.GenericEditor constructor
|
||||||
// Tree.cellEditor is set in sun.swing.FilePane.editFileName()
|
// Tree.cellEditor is set in sun.swing.FilePane.editFileName()
|
||||||
|
|||||||
@@ -29,8 +29,8 @@ import java.beans.PropertyChangeEvent;
|
|||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.IdentityHashMap;
|
import java.util.IdentityHashMap;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.function.Predicate;
|
||||||
import javax.swing.JDialog;
|
import javax.swing.JDialog;
|
||||||
import javax.swing.JFrame;
|
import javax.swing.JFrame;
|
||||||
import javax.swing.Timer;
|
import javax.swing.Timer;
|
||||||
@@ -159,7 +159,7 @@ class FlatWindowsNativeWindowBorder
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateTitleBarInfo( Window window, int titleBarHeight, List<Rectangle> hitTestSpots,
|
public void updateTitleBarInfo( Window window, int titleBarHeight, Predicate<Point> captionHitTestCallback,
|
||||||
Rectangle appIconBounds, Rectangle minimizeButtonBounds, Rectangle maximizeButtonBounds,
|
Rectangle appIconBounds, Rectangle minimizeButtonBounds, Rectangle maximizeButtonBounds,
|
||||||
Rectangle closeButtonBounds )
|
Rectangle closeButtonBounds )
|
||||||
{
|
{
|
||||||
@@ -168,7 +168,7 @@ class FlatWindowsNativeWindowBorder
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
wndProc.titleBarHeight = titleBarHeight;
|
wndProc.titleBarHeight = titleBarHeight;
|
||||||
wndProc.hitTestSpots = hitTestSpots.toArray( new Rectangle[hitTestSpots.size()] );
|
wndProc.captionHitTestCallback = captionHitTestCallback;
|
||||||
wndProc.appIconBounds = cloneRectange( appIconBounds );
|
wndProc.appIconBounds = cloneRectange( appIconBounds );
|
||||||
wndProc.minimizeButtonBounds = cloneRectange( minimizeButtonBounds );
|
wndProc.minimizeButtonBounds = cloneRectange( minimizeButtonBounds );
|
||||||
wndProc.maximizeButtonBounds = cloneRectange( maximizeButtonBounds );
|
wndProc.maximizeButtonBounds = cloneRectange( maximizeButtonBounds );
|
||||||
@@ -288,8 +288,8 @@ class FlatWindowsNativeWindowBorder
|
|||||||
private final long hwnd;
|
private final long hwnd;
|
||||||
|
|
||||||
// Swing coordinates/values may be scaled on a HiDPI screen
|
// Swing coordinates/values may be scaled on a HiDPI screen
|
||||||
private int titleBarHeight;
|
private int titleBarHeight; // measured from window top edge, which may be out-of-screen if maximized
|
||||||
private Rectangle[] hitTestSpots;
|
private Predicate<Point> captionHitTestCallback;
|
||||||
private Rectangle appIconBounds;
|
private Rectangle appIconBounds;
|
||||||
private Rectangle minimizeButtonBounds;
|
private Rectangle minimizeButtonBounds;
|
||||||
private Rectangle maximizeButtonBounds;
|
private Rectangle maximizeButtonBounds;
|
||||||
@@ -340,50 +340,61 @@ class FlatWindowsNativeWindowBorder
|
|||||||
private int onNcHitTest( int x, int y, boolean isOnResizeBorder ) {
|
private int onNcHitTest( int x, int y, boolean isOnResizeBorder ) {
|
||||||
// scale-down mouse x/y because Swing coordinates/values may be scaled on a HiDPI screen
|
// scale-down mouse x/y because Swing coordinates/values may be scaled on a HiDPI screen
|
||||||
Point pt = scaleDown( x, y );
|
Point pt = scaleDown( x, y );
|
||||||
int sx = pt.x;
|
|
||||||
int sy = pt.y;
|
|
||||||
|
|
||||||
// return HTSYSMENU if mouse is over application icon
|
// return HTSYSMENU if mouse is over application icon
|
||||||
// - left-click on HTSYSMENU area shows system menu
|
// - left-click on HTSYSMENU area shows system menu
|
||||||
// - double-left-click sends WM_CLOSE
|
// - double-left-click sends WM_CLOSE
|
||||||
if( contains( appIconBounds, sx, sy ) )
|
if( contains( appIconBounds, pt ) )
|
||||||
return HTSYSMENU;
|
return HTSYSMENU;
|
||||||
|
|
||||||
// return HTMINBUTTON if mouse is over minimize button
|
// return HTMINBUTTON if mouse is over minimize button
|
||||||
// - hovering mouse over HTMINBUTTON area shows tooltip on Windows 10/11
|
// - hovering mouse over HTMINBUTTON area shows tooltip on Windows 10/11
|
||||||
if( contains( minimizeButtonBounds, sx, sy ) )
|
if( contains( minimizeButtonBounds, pt ) )
|
||||||
return HTMINBUTTON;
|
return HTMINBUTTON;
|
||||||
|
|
||||||
// return HTMAXBUTTON if mouse is over maximize/restore button
|
// return HTMAXBUTTON if mouse is over maximize/restore button
|
||||||
// - hovering mouse over HTMAXBUTTON area shows tooltip on Windows 10
|
// - hovering mouse over HTMAXBUTTON area shows tooltip on Windows 10
|
||||||
// - hovering mouse over HTMAXBUTTON area shows snap layouts menu on Windows 11
|
// - hovering mouse over HTMAXBUTTON area shows snap layouts menu on Windows 11
|
||||||
// https://docs.microsoft.com/en-us/windows/apps/desktop/modernize/apply-snap-layout-menu
|
// https://docs.microsoft.com/en-us/windows/apps/desktop/modernize/apply-snap-layout-menu
|
||||||
if( contains( maximizeButtonBounds, sx, sy ) )
|
if( contains( maximizeButtonBounds, pt ) )
|
||||||
return HTMAXBUTTON;
|
return HTMAXBUTTON;
|
||||||
|
|
||||||
// return HTCLOSE if mouse is over close button
|
// return HTCLOSE if mouse is over close button
|
||||||
// - hovering mouse over HTCLOSE area shows tooltip on Windows 10/11
|
// - hovering mouse over HTCLOSE area shows tooltip on Windows 10/11
|
||||||
if( contains( closeButtonBounds, sx, sy ) )
|
if( contains( closeButtonBounds, pt ) )
|
||||||
return HTCLOSE;
|
return HTCLOSE;
|
||||||
|
|
||||||
boolean isOnTitleBar = (sy < titleBarHeight);
|
// return HTTOP if mouse is over top resize border
|
||||||
|
// - hovering mouse shows vertical resize cursor
|
||||||
|
// - left-click and drag vertically resizes window
|
||||||
|
if( isOnResizeBorder )
|
||||||
|
return HTTOP;
|
||||||
|
|
||||||
|
boolean isOnTitleBar = (pt.y < titleBarHeight);
|
||||||
if( isOnTitleBar ) {
|
if( isOnTitleBar ) {
|
||||||
// use a second reference to the array to avoid that it can be changed
|
// return HTCLIENT if mouse is over any Swing component in title bar
|
||||||
// in another thread while processing the array
|
// that processes mouse events (e.g. buttons, menus, etc)
|
||||||
Rectangle[] hitTestSpots2 = hitTestSpots;
|
// - Windows ignores mouse events in this area
|
||||||
for( Rectangle spot : hitTestSpots2 ) {
|
try {
|
||||||
if( spot.contains( sx, sy ) )
|
if( captionHitTestCallback != null && !captionHitTestCallback.test( pt ) )
|
||||||
return HTCLIENT;
|
return HTCLIENT;
|
||||||
|
} catch( Throwable ex ) {
|
||||||
|
// ignore
|
||||||
}
|
}
|
||||||
return isOnResizeBorder ? HTTOP : HTCAPTION;
|
|
||||||
|
// return HTCAPTION if mouse is over title bar
|
||||||
|
// - right-click shows system menu
|
||||||
|
// - double-left-click maximizes/restores window size
|
||||||
|
return HTCAPTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
return isOnResizeBorder ? HTTOP : HTCLIENT;
|
// return HTCLIENT
|
||||||
|
// - Windows ignores mouse events in this area
|
||||||
|
return HTCLIENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean contains( Rectangle rect, int x, int y ) {
|
private boolean contains( Rectangle rect, Point pt ) {
|
||||||
return (rect != null && rect.contains( x, y ) );
|
return (rect != null && rect.contains( pt ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,219 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2024 FormDev Software GmbH
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.formdev.flatlaf.ui;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Component;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import java.awt.Rectangle;
|
||||||
|
import java.awt.Window;
|
||||||
|
import java.awt.event.ComponentAdapter;
|
||||||
|
import java.awt.event.ComponentEvent;
|
||||||
|
import java.awt.event.ComponentListener;
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import javax.swing.JComponent;
|
||||||
|
import javax.swing.JRootPane;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
|
import javax.swing.UIManager;
|
||||||
|
import com.formdev.flatlaf.FlatClientProperties;
|
||||||
|
import com.formdev.flatlaf.util.SystemInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Karl Tauber
|
||||||
|
*/
|
||||||
|
class FullWindowContentSupport
|
||||||
|
{
|
||||||
|
private static final String KEY_DEBUG_SHOW_PLACEHOLDERS = "FlatLaf.debug.panel.showPlaceholders";
|
||||||
|
|
||||||
|
private static ArrayList<WeakReference<JComponent>> placeholders = new ArrayList<>();
|
||||||
|
|
||||||
|
static Dimension getPlaceholderPreferredSize( JComponent c, String options ) {
|
||||||
|
JRootPane rootPane;
|
||||||
|
Rectangle bounds;
|
||||||
|
|
||||||
|
if( !options.startsWith( SystemInfo.isMacOS ? "mac" : "win" ) ||
|
||||||
|
!c.isDisplayable() ||
|
||||||
|
(rootPane = SwingUtilities.getRootPane( c )) == null ||
|
||||||
|
(bounds = (Rectangle) rootPane.getClientProperty( FlatClientProperties.FULL_WINDOW_CONTENT_BUTTONS_BOUNDS )) == null )
|
||||||
|
return new Dimension( 0, 0 );
|
||||||
|
|
||||||
|
if( options.length() > 3 ) {
|
||||||
|
if( (options.contains( "leftToRight" ) && !c.getComponentOrientation().isLeftToRight()) ||
|
||||||
|
(options.contains( "rightToLeft" ) && c.getComponentOrientation().isLeftToRight()) )
|
||||||
|
return new Dimension( 0, 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
// On macOS, the client property is updated very late when toggling full screen,
|
||||||
|
// which results in "jumping" layout after full screen toggle finished.
|
||||||
|
// To avoid that, get up-to-date buttons bounds from macOS.
|
||||||
|
if( SystemInfo.isMacFullWindowContentSupported && FlatNativeMacLibrary.isLoaded() ) {
|
||||||
|
Rectangle r = FlatNativeMacLibrary.getWindowButtonsBounds( SwingUtilities.windowForComponent( c ) );
|
||||||
|
if( r != null )
|
||||||
|
bounds = r;
|
||||||
|
}
|
||||||
|
|
||||||
|
int width = bounds.width;
|
||||||
|
int height = bounds.height;
|
||||||
|
|
||||||
|
if( options.length() > 3 ) {
|
||||||
|
if( width == 0 && options.contains( "zeroInFullScreen" ) )
|
||||||
|
height = 0;
|
||||||
|
|
||||||
|
if( options.contains( "horizontal" ) )
|
||||||
|
height = 0;
|
||||||
|
if( options.contains( "vertical" ) )
|
||||||
|
width = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Dimension( width, height );
|
||||||
|
}
|
||||||
|
|
||||||
|
static void registerPlaceholder( JComponent c ) {
|
||||||
|
synchronized( placeholders ) {
|
||||||
|
if( indexOfPlaceholder( c ) < 0 )
|
||||||
|
placeholders.add( new WeakReference<>( c ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void unregisterPlaceholder( JComponent c ) {
|
||||||
|
synchronized( placeholders ) {
|
||||||
|
int index = indexOfPlaceholder( c );
|
||||||
|
if( index >= 0 )
|
||||||
|
placeholders.remove( index );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int indexOfPlaceholder( JComponent c ) {
|
||||||
|
int size = placeholders.size();
|
||||||
|
for( int i = 0; i < size; i++ ) {
|
||||||
|
if( placeholders.get( i ).get() == c )
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void revalidatePlaceholders( Component container ) {
|
||||||
|
synchronized( placeholders ) {
|
||||||
|
if( placeholders.isEmpty() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
for( Iterator<WeakReference<JComponent>> it = placeholders.iterator(); it.hasNext(); ) {
|
||||||
|
WeakReference<JComponent> ref = it.next();
|
||||||
|
JComponent c = ref.get();
|
||||||
|
|
||||||
|
// remove already released placeholder
|
||||||
|
if( c == null ) {
|
||||||
|
it.remove();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// revalidate placeholder if is in given container
|
||||||
|
if( SwingUtilities.isDescendingFrom( c, container ) )
|
||||||
|
c.revalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static ComponentListener macInstallListeners( JRootPane rootPane ) {
|
||||||
|
ComponentListener l = new ComponentAdapter() {
|
||||||
|
boolean lastFullScreen;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void componentResized( ComponentEvent e ) {
|
||||||
|
Window window = SwingUtilities.windowForComponent( rootPane );
|
||||||
|
if( window == null )
|
||||||
|
return;
|
||||||
|
|
||||||
|
boolean fullScreen = FlatNativeMacLibrary.isLoaded() && FlatNativeMacLibrary.isWindowFullScreen( window );
|
||||||
|
if( fullScreen == lastFullScreen )
|
||||||
|
return;
|
||||||
|
|
||||||
|
lastFullScreen = fullScreen;
|
||||||
|
macUpdateFullWindowContentButtonsBoundsProperty( rootPane );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
rootPane.addComponentListener( l );
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void macUninstallListeners( JRootPane rootPane, ComponentListener l ) {
|
||||||
|
if( l != null )
|
||||||
|
rootPane.removeComponentListener( l );
|
||||||
|
}
|
||||||
|
|
||||||
|
static void macUpdateFullWindowContentButtonsBoundsProperty( JRootPane rootPane ) {
|
||||||
|
if( !SystemInfo.isMacFullWindowContentSupported || !rootPane.isDisplayable() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
Rectangle bounds = null;
|
||||||
|
if( FlatClientProperties.clientPropertyBoolean( rootPane, "apple.awt.fullWindowContent", false ) ) {
|
||||||
|
bounds = FlatNativeMacLibrary.isLoaded()
|
||||||
|
? FlatNativeMacLibrary.getWindowButtonsBounds( SwingUtilities.windowForComponent( rootPane ) )
|
||||||
|
: new Rectangle( 68, 28 ); // default size
|
||||||
|
}
|
||||||
|
rootPane.putClientProperty( FlatClientProperties.FULL_WINDOW_CONTENT_BUTTONS_BOUNDS, bounds );
|
||||||
|
}
|
||||||
|
|
||||||
|
static void macUninstallFullWindowContentButtonsBoundsProperty( JRootPane rootPane ) {
|
||||||
|
if( !SystemInfo.isMacFullWindowContentSupported )
|
||||||
|
return;
|
||||||
|
|
||||||
|
rootPane.putClientProperty( FlatClientProperties.FULL_WINDOW_CONTENT_BUTTONS_BOUNDS, null );
|
||||||
|
}
|
||||||
|
|
||||||
|
static void debugPaint( Graphics g, JComponent c ) {
|
||||||
|
if( !UIManager.getBoolean( KEY_DEBUG_SHOW_PLACEHOLDERS ) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
int width = c.getWidth();
|
||||||
|
int height = c.getHeight();
|
||||||
|
if( width <= 0 || height <= 0 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// draw red figure
|
||||||
|
g.setColor( Color.red );
|
||||||
|
debugPaintRect( g, new Rectangle( width, height ) );
|
||||||
|
|
||||||
|
// draw magenta figure if buttons bounds are not equal to placeholder bounds
|
||||||
|
JRootPane rootPane;
|
||||||
|
Rectangle bounds;
|
||||||
|
if( (rootPane = SwingUtilities.getRootPane( c )) != null &&
|
||||||
|
(bounds = (Rectangle) rootPane.getClientProperty( FlatClientProperties.FULL_WINDOW_CONTENT_BUTTONS_BOUNDS )) != null &&
|
||||||
|
(bounds.width != width || bounds.height != height) )
|
||||||
|
{
|
||||||
|
g.setColor( Color.magenta );
|
||||||
|
debugPaintRect( g, SwingUtilities.convertRectangle( rootPane, bounds, c ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void debugPaintRect( Graphics g, Rectangle r ) {
|
||||||
|
// draw rectangle
|
||||||
|
g.drawRect( r.x, r.y, r.width - 1, r.height - 1 );
|
||||||
|
|
||||||
|
// draw diagonal cross
|
||||||
|
int x2 = r.x + r.width - 1;
|
||||||
|
int y2 = r.y + r.height - 1;
|
||||||
|
Object[] oldRenderingHints = FlatUIUtils.setRenderingHints( g );
|
||||||
|
g.drawLine( r.x, r.y, x2, y2 );
|
||||||
|
g.drawLine( r.x, y2, x2, r.y );
|
||||||
|
FlatUIUtils.resetRenderingHints( g, oldRenderingHints );
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf.ui;
|
package com.formdev.flatlaf.ui;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.lang.invoke.MethodHandle;
|
import java.lang.invoke.MethodHandle;
|
||||||
import java.lang.invoke.MethodHandles;
|
import java.lang.invoke.MethodHandles;
|
||||||
import java.lang.invoke.MethodType;
|
import java.lang.invoke.MethodType;
|
||||||
@@ -25,6 +26,7 @@ import javax.swing.JList;
|
|||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
import javax.swing.JTable;
|
import javax.swing.JTable;
|
||||||
import javax.swing.JTree;
|
import javax.swing.JTree;
|
||||||
|
import javax.swing.filechooser.FileSystemView;
|
||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
import javax.swing.text.JTextComponent;
|
import javax.swing.text.JTextComponent;
|
||||||
import com.formdev.flatlaf.util.LoggingFacade;
|
import com.formdev.flatlaf.util.LoggingFacade;
|
||||||
@@ -88,4 +90,64 @@ public class JavaCompatibility2
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Java 8 - 11 on Windows: sun.awt.shell.ShellFolder.get( "fileChooserShortcutPanelFolders" )
|
||||||
|
* <br>
|
||||||
|
* Java 12: javax.swing.filechooser.FileSystemView.getChooserShortcutPanelFiles()
|
||||||
|
*
|
||||||
|
* @since 3.4
|
||||||
|
*/
|
||||||
|
public static File[] getChooserShortcutPanelFiles( FileSystemView fsv ) {
|
||||||
|
try {
|
||||||
|
if( SystemInfo.isJava_12_orLater ) {
|
||||||
|
Method m = fsv.getClass().getMethod( "getChooserShortcutPanelFiles" );
|
||||||
|
File[] files = (File[]) m.invoke( fsv );
|
||||||
|
|
||||||
|
// on macOS and Linux, files consists only of the user home directory
|
||||||
|
if( files.length == 1 && files[0].equals( new File( System.getProperty( "user.home" ) ) ) )
|
||||||
|
files = new File[0];
|
||||||
|
|
||||||
|
return files;
|
||||||
|
} else if( SystemInfo.isWindows ) {
|
||||||
|
Class<?> cls = Class.forName( "sun.awt.shell.ShellFolder" );
|
||||||
|
Method m = cls.getMethod( "get", String.class );
|
||||||
|
return (File[]) m.invoke( null, "fileChooserShortcutPanelFolders" );
|
||||||
|
}
|
||||||
|
} catch( IllegalAccessException ex ) {
|
||||||
|
// do not log because access may be denied via VM option '--illegal-access=deny'
|
||||||
|
} catch( Exception ex ) {
|
||||||
|
LoggingFacade.INSTANCE.logSevere( null, ex );
|
||||||
|
}
|
||||||
|
|
||||||
|
// fallback
|
||||||
|
return new File[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Java 8: sun.awt.shell.ShellFolder.get( "fileChooserComboBoxFolders" )
|
||||||
|
* <br>
|
||||||
|
* Java 9: javax.swing.filechooser.FileSystemView.getChooserComboBoxFiles()
|
||||||
|
*
|
||||||
|
* @since 3.4
|
||||||
|
*/
|
||||||
|
public static File[] getChooserComboBoxFiles( FileSystemView fsv ) {
|
||||||
|
try {
|
||||||
|
if( SystemInfo.isJava_9_orLater ) {
|
||||||
|
Method m = fsv.getClass().getMethod( "getChooserComboBoxFiles" );
|
||||||
|
return (File[]) m.invoke( fsv );
|
||||||
|
} else {
|
||||||
|
Class<?> cls = Class.forName( "sun.awt.shell.ShellFolder" );
|
||||||
|
Method m = cls.getMethod( "get", String.class );
|
||||||
|
return (File[]) m.invoke( null, "fileChooserComboBoxFolders" );
|
||||||
|
}
|
||||||
|
} catch( IllegalAccessException ex ) {
|
||||||
|
// do not log because access may be denied via VM option '--illegal-access=deny'
|
||||||
|
} catch( Exception ex ) {
|
||||||
|
LoggingFacade.INSTANCE.logSevere( null, ex );
|
||||||
|
}
|
||||||
|
|
||||||
|
// fallback
|
||||||
|
return new File[0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -192,7 +192,8 @@ public class HiDPIUtils
|
|||||||
|
|
||||||
case "Inter":
|
case "Inter":
|
||||||
case "Inter Light":
|
case "Inter Light":
|
||||||
case "Inter Semi Bold":
|
case "Inter Semi Bold": // Inter v3
|
||||||
|
case "Inter SemiBold": // Inter v4
|
||||||
case "Roboto":
|
case "Roboto":
|
||||||
case "Roboto Light":
|
case "Roboto Light":
|
||||||
case "Roboto Medium":
|
case "Roboto Medium":
|
||||||
|
|||||||
@@ -739,6 +739,8 @@ Table.rowHeight = 20
|
|||||||
Table.showHorizontalLines = false
|
Table.showHorizontalLines = false
|
||||||
Table.showVerticalLines = false
|
Table.showVerticalLines = false
|
||||||
Table.showTrailingVerticalLine = false
|
Table.showTrailingVerticalLine = false
|
||||||
|
Table.paintOutsideAlternateRows = false
|
||||||
|
Table.editorSelectAllOnStartEditing = true
|
||||||
Table.consistentHomeEndKeyBehavior = true
|
Table.consistentHomeEndKeyBehavior = true
|
||||||
Table.intercellSpacing = 0,0
|
Table.intercellSpacing = 0,0
|
||||||
Table.scrollPaneBorder = com.formdev.flatlaf.ui.FlatScrollPaneBorder
|
Table.scrollPaneBorder = com.formdev.flatlaf.ui.FlatScrollPaneBorder
|
||||||
@@ -829,7 +831,6 @@ TitlePane.centerTitleIfMenuBarEmbedded = true
|
|||||||
TitlePane.showIconBesideTitle = false
|
TitlePane.showIconBesideTitle = false
|
||||||
TitlePane.menuBarTitleGap = 40
|
TitlePane.menuBarTitleGap = 40
|
||||||
TitlePane.menuBarTitleMinimumGap = 12
|
TitlePane.menuBarTitleMinimumGap = 12
|
||||||
TitlePane.menuBarResizeHeight = 4
|
|
||||||
TitlePane.closeIcon = com.formdev.flatlaf.icons.FlatWindowCloseIcon
|
TitlePane.closeIcon = com.formdev.flatlaf.icons.FlatWindowCloseIcon
|
||||||
TitlePane.iconifyIcon = com.formdev.flatlaf.icons.FlatWindowIconifyIcon
|
TitlePane.iconifyIcon = com.formdev.flatlaf.icons.FlatWindowIconifyIcon
|
||||||
TitlePane.maximizeIcon = com.formdev.flatlaf.icons.FlatWindowMaximizeIcon
|
TitlePane.maximizeIcon = com.formdev.flatlaf.icons.FlatWindowMaximizeIcon
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -73,6 +73,7 @@ class DemoFrame
|
|||||||
initComponents();
|
initComponents();
|
||||||
updateFontMenuItems();
|
updateFontMenuItems();
|
||||||
initAccentColors();
|
initAccentColors();
|
||||||
|
initFullWindowContent();
|
||||||
controlBar.initialize( this, tabbedPane );
|
controlBar.initialize( this, tabbedPane );
|
||||||
|
|
||||||
setIconImages( FlatSVGUtils.createWindowIconImages( "/com/formdev/flatlaf/demo/FlatLaf.svg" ) );
|
setIconImages( FlatSVGUtils.createWindowIconImages( "/com/formdev/flatlaf/demo/FlatLaf.svg" ) );
|
||||||
@@ -89,24 +90,23 @@ class DemoFrame
|
|||||||
// do not use HTML text in menu items because this is not supported in macOS screen menu
|
// do not use HTML text in menu items because this is not supported in macOS screen menu
|
||||||
htmlMenuItem.setText( "some text" );
|
htmlMenuItem.setText( "some text" );
|
||||||
|
|
||||||
|
JRootPane rootPane = getRootPane();
|
||||||
if( SystemInfo.isMacFullWindowContentSupported ) {
|
if( SystemInfo.isMacFullWindowContentSupported ) {
|
||||||
// expand window content into window title bar and make title bar transparent
|
// expand window content into window title bar and make title bar transparent
|
||||||
getRootPane().putClientProperty( "apple.awt.fullWindowContent", true );
|
rootPane.putClientProperty( "apple.awt.fullWindowContent", true );
|
||||||
getRootPane().putClientProperty( "apple.awt.transparentTitleBar", true );
|
rootPane.putClientProperty( "apple.awt.transparentTitleBar", true );
|
||||||
|
rootPane.putClientProperty( FlatClientProperties.MACOS_WINDOW_BUTTONS_SPACING, FlatClientProperties.MACOS_WINDOW_BUTTONS_SPACING_LARGE );
|
||||||
|
|
||||||
// hide window title
|
// hide window title
|
||||||
if( SystemInfo.isJava_17_orLater )
|
if( SystemInfo.isJava_17_orLater )
|
||||||
getRootPane().putClientProperty( "apple.awt.windowTitleVisible", false );
|
rootPane.putClientProperty( "apple.awt.windowTitleVisible", false );
|
||||||
else
|
else
|
||||||
setTitle( null );
|
setTitle( null );
|
||||||
|
|
||||||
// add gap to left side of toolbar
|
|
||||||
toolBar.add( Box.createHorizontalStrut( 70 ), 0 );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// enable full screen mode for this window (for Java 8 - 10; not necessary for Java 11+)
|
// enable full screen mode for this window (for Java 8 - 10; not necessary for Java 11+)
|
||||||
if( !SystemInfo.isJava_11_orLater )
|
if( !SystemInfo.isJava_11_orLater )
|
||||||
getRootPane().putClientProperty( "apple.awt.fullscreenable", true );
|
rootPane.putClientProperty( "apple.awt.fullscreenable", true );
|
||||||
}
|
}
|
||||||
|
|
||||||
// integrate into macOS screen menu
|
// integrate into macOS screen menu
|
||||||
@@ -461,9 +461,37 @@ class DemoFrame
|
|||||||
accentColorButtons[i].setVisible( isAccentColorSupported );
|
accentColorButtons[i].setVisible( isAccentColorSupported );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void initFullWindowContent() {
|
||||||
|
if( !supportsFlatLafWindowDecorations() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// create fullWindowContent mode toggle button
|
||||||
|
Icon expandIcon = new FlatSVGIcon( "com/formdev/flatlaf/demo/icons/expand.svg" );
|
||||||
|
Icon collapseIcon = new FlatSVGIcon( "com/formdev/flatlaf/demo/icons/collapse.svg" );
|
||||||
|
JToggleButton fullWindowContentButton = new JToggleButton( expandIcon );
|
||||||
|
fullWindowContentButton.setToolTipText( "Toggle full window content" );
|
||||||
|
fullWindowContentButton.addActionListener( e -> {
|
||||||
|
boolean fullWindowContent = fullWindowContentButton.isSelected();
|
||||||
|
fullWindowContentButton.setIcon( fullWindowContent ? collapseIcon : expandIcon );
|
||||||
|
menuBar.setVisible( !fullWindowContent );
|
||||||
|
toolBar.setVisible( !fullWindowContent );
|
||||||
|
getRootPane().putClientProperty( FlatClientProperties.FULL_WINDOW_CONTENT, fullWindowContent );
|
||||||
|
} );
|
||||||
|
|
||||||
|
// add fullWindowContent mode toggle button to tabbed pane
|
||||||
|
JToolBar trailingToolBar = new JToolBar();
|
||||||
|
trailingToolBar.add( Box.createGlue() );
|
||||||
|
trailingToolBar.add( fullWindowContentButton );
|
||||||
|
tabbedPane.putClientProperty( FlatClientProperties.TABBED_PANE_TRAILING_COMPONENT, trailingToolBar );
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean supportsFlatLafWindowDecorations() {
|
||||||
|
return FlatLaf.supportsNativeWindowDecorations() || (SystemInfo.isLinux && JFrame.isDefaultLookAndFeelDecorated());
|
||||||
|
}
|
||||||
|
|
||||||
private void initComponents() {
|
private void initComponents() {
|
||||||
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
|
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
|
||||||
JMenuBar menuBar1 = new JMenuBar();
|
menuBar = new JMenuBar();
|
||||||
JMenu fileMenu = new JMenu();
|
JMenu fileMenu = new JMenu();
|
||||||
JMenuItem newMenuItem = new JMenuItem();
|
JMenuItem newMenuItem = new JMenuItem();
|
||||||
JMenuItem openMenuItem = new JMenuItem();
|
JMenuItem openMenuItem = new JMenuItem();
|
||||||
@@ -509,6 +537,8 @@ class DemoFrame
|
|||||||
JMenuItem showUIDefaultsInspectorMenuItem = new JMenuItem();
|
JMenuItem showUIDefaultsInspectorMenuItem = new JMenuItem();
|
||||||
JMenu helpMenu = new JMenu();
|
JMenu helpMenu = new JMenu();
|
||||||
aboutMenuItem = new JMenuItem();
|
aboutMenuItem = new JMenuItem();
|
||||||
|
JPanel toolBarPanel = new JPanel();
|
||||||
|
JPanel macFullWindowContentButtonsPlaceholder = new JPanel();
|
||||||
toolBar = new JToolBar();
|
toolBar = new JToolBar();
|
||||||
JButton backButton = new JButton();
|
JButton backButton = new JButton();
|
||||||
JButton forwardButton = new JButton();
|
JButton forwardButton = new JButton();
|
||||||
@@ -524,8 +554,10 @@ class DemoFrame
|
|||||||
DataComponentsPanel dataComponentsPanel = new DataComponentsPanel();
|
DataComponentsPanel dataComponentsPanel = new DataComponentsPanel();
|
||||||
TabsPanel tabsPanel = new TabsPanel();
|
TabsPanel tabsPanel = new TabsPanel();
|
||||||
OptionPanePanel optionPanePanel = new OptionPanePanel();
|
OptionPanePanel optionPanePanel = new OptionPanePanel();
|
||||||
ExtrasPanel extrasPanel1 = new ExtrasPanel();
|
ExtrasPanel extrasPanel = new ExtrasPanel();
|
||||||
controlBar = new ControlBar();
|
controlBar = new ControlBar();
|
||||||
|
JPanel themesPanelPanel = new JPanel();
|
||||||
|
JPanel winFullWindowContentButtonsPlaceholder = new JPanel();
|
||||||
themesPanel = new IJThemesPanel();
|
themesPanel = new IJThemesPanel();
|
||||||
|
|
||||||
//======== this ========
|
//======== this ========
|
||||||
@@ -534,7 +566,7 @@ class DemoFrame
|
|||||||
Container contentPane = getContentPane();
|
Container contentPane = getContentPane();
|
||||||
contentPane.setLayout(new BorderLayout());
|
contentPane.setLayout(new BorderLayout());
|
||||||
|
|
||||||
//======== menuBar1 ========
|
//======== menuBar ========
|
||||||
{
|
{
|
||||||
|
|
||||||
//======== fileMenu ========
|
//======== fileMenu ========
|
||||||
@@ -579,7 +611,7 @@ class DemoFrame
|
|||||||
exitMenuItem.addActionListener(e -> exitActionPerformed());
|
exitMenuItem.addActionListener(e -> exitActionPerformed());
|
||||||
fileMenu.add(exitMenuItem);
|
fileMenu.add(exitMenuItem);
|
||||||
}
|
}
|
||||||
menuBar1.add(fileMenu);
|
menuBar.add(fileMenu);
|
||||||
|
|
||||||
//======== editMenu ========
|
//======== editMenu ========
|
||||||
{
|
{
|
||||||
@@ -632,7 +664,7 @@ class DemoFrame
|
|||||||
deleteMenuItem.addActionListener(e -> menuItemActionPerformed(e));
|
deleteMenuItem.addActionListener(e -> menuItemActionPerformed(e));
|
||||||
editMenu.add(deleteMenuItem);
|
editMenu.add(deleteMenuItem);
|
||||||
}
|
}
|
||||||
menuBar1.add(editMenu);
|
menuBar.add(editMenu);
|
||||||
|
|
||||||
//======== viewMenu ========
|
//======== viewMenu ========
|
||||||
{
|
{
|
||||||
@@ -732,7 +764,7 @@ class DemoFrame
|
|||||||
radioButtonMenuItem3.addActionListener(e -> menuItemActionPerformed(e));
|
radioButtonMenuItem3.addActionListener(e -> menuItemActionPerformed(e));
|
||||||
viewMenu.add(radioButtonMenuItem3);
|
viewMenu.add(radioButtonMenuItem3);
|
||||||
}
|
}
|
||||||
menuBar1.add(viewMenu);
|
menuBar.add(viewMenu);
|
||||||
|
|
||||||
//======== fontMenu ========
|
//======== fontMenu ========
|
||||||
{
|
{
|
||||||
@@ -756,7 +788,7 @@ class DemoFrame
|
|||||||
decrFontMenuItem.addActionListener(e -> decrFont());
|
decrFontMenuItem.addActionListener(e -> decrFont());
|
||||||
fontMenu.add(decrFontMenuItem);
|
fontMenu.add(decrFontMenuItem);
|
||||||
}
|
}
|
||||||
menuBar1.add(fontMenu);
|
menuBar.add(fontMenu);
|
||||||
|
|
||||||
//======== optionsMenu ========
|
//======== optionsMenu ========
|
||||||
{
|
{
|
||||||
@@ -808,7 +840,7 @@ class DemoFrame
|
|||||||
showUIDefaultsInspectorMenuItem.addActionListener(e -> showUIDefaultsInspector());
|
showUIDefaultsInspectorMenuItem.addActionListener(e -> showUIDefaultsInspector());
|
||||||
optionsMenu.add(showUIDefaultsInspectorMenuItem);
|
optionsMenu.add(showUIDefaultsInspectorMenuItem);
|
||||||
}
|
}
|
||||||
menuBar1.add(optionsMenu);
|
menuBar.add(optionsMenu);
|
||||||
|
|
||||||
//======== helpMenu ========
|
//======== helpMenu ========
|
||||||
{
|
{
|
||||||
@@ -821,54 +853,66 @@ class DemoFrame
|
|||||||
aboutMenuItem.addActionListener(e -> aboutActionPerformed());
|
aboutMenuItem.addActionListener(e -> aboutActionPerformed());
|
||||||
helpMenu.add(aboutMenuItem);
|
helpMenu.add(aboutMenuItem);
|
||||||
}
|
}
|
||||||
menuBar1.add(helpMenu);
|
menuBar.add(helpMenu);
|
||||||
}
|
}
|
||||||
setJMenuBar(menuBar1);
|
setJMenuBar(menuBar);
|
||||||
|
|
||||||
//======== toolBar ========
|
//======== toolBarPanel ========
|
||||||
{
|
{
|
||||||
toolBar.setMargin(new Insets(3, 3, 3, 3));
|
toolBarPanel.setLayout(new BorderLayout());
|
||||||
|
|
||||||
//---- backButton ----
|
//======== macFullWindowContentButtonsPlaceholder ========
|
||||||
backButton.setToolTipText("Back");
|
{
|
||||||
backButton.setIcon(new FlatSVGIcon("com/formdev/flatlaf/demo/icons/back.svg"));
|
macFullWindowContentButtonsPlaceholder.setLayout(new FlowLayout());
|
||||||
toolBar.add(backButton);
|
}
|
||||||
|
toolBarPanel.add(macFullWindowContentButtonsPlaceholder, BorderLayout.WEST);
|
||||||
|
|
||||||
//---- forwardButton ----
|
//======== toolBar ========
|
||||||
forwardButton.setToolTipText("Forward");
|
{
|
||||||
forwardButton.setIcon(new FlatSVGIcon("com/formdev/flatlaf/demo/icons/forward.svg"));
|
toolBar.setMargin(new Insets(3, 3, 3, 3));
|
||||||
toolBar.add(forwardButton);
|
|
||||||
toolBar.addSeparator();
|
|
||||||
|
|
||||||
//---- cutButton ----
|
//---- backButton ----
|
||||||
cutButton.setToolTipText("Cut");
|
backButton.setToolTipText("Back");
|
||||||
cutButton.setIcon(new FlatSVGIcon("com/formdev/flatlaf/demo/icons/menu-cut.svg"));
|
backButton.setIcon(new FlatSVGIcon("com/formdev/flatlaf/demo/icons/back.svg"));
|
||||||
toolBar.add(cutButton);
|
toolBar.add(backButton);
|
||||||
|
|
||||||
//---- copyButton ----
|
//---- forwardButton ----
|
||||||
copyButton.setToolTipText("Copy");
|
forwardButton.setToolTipText("Forward");
|
||||||
copyButton.setIcon(new FlatSVGIcon("com/formdev/flatlaf/demo/icons/copy.svg"));
|
forwardButton.setIcon(new FlatSVGIcon("com/formdev/flatlaf/demo/icons/forward.svg"));
|
||||||
toolBar.add(copyButton);
|
toolBar.add(forwardButton);
|
||||||
|
toolBar.addSeparator();
|
||||||
|
|
||||||
//---- pasteButton ----
|
//---- cutButton ----
|
||||||
pasteButton.setToolTipText("Paste");
|
cutButton.setToolTipText("Cut");
|
||||||
pasteButton.setIcon(new FlatSVGIcon("com/formdev/flatlaf/demo/icons/menu-paste.svg"));
|
cutButton.setIcon(new FlatSVGIcon("com/formdev/flatlaf/demo/icons/menu-cut.svg"));
|
||||||
toolBar.add(pasteButton);
|
toolBar.add(cutButton);
|
||||||
toolBar.addSeparator();
|
|
||||||
|
|
||||||
//---- refreshButton ----
|
//---- copyButton ----
|
||||||
refreshButton.setToolTipText("Refresh");
|
copyButton.setToolTipText("Copy");
|
||||||
refreshButton.setIcon(new FlatSVGIcon("com/formdev/flatlaf/demo/icons/refresh.svg"));
|
copyButton.setIcon(new FlatSVGIcon("com/formdev/flatlaf/demo/icons/copy.svg"));
|
||||||
toolBar.add(refreshButton);
|
toolBar.add(copyButton);
|
||||||
toolBar.addSeparator();
|
|
||||||
|
|
||||||
//---- showToggleButton ----
|
//---- pasteButton ----
|
||||||
showToggleButton.setSelected(true);
|
pasteButton.setToolTipText("Paste");
|
||||||
showToggleButton.setToolTipText("Show Details");
|
pasteButton.setIcon(new FlatSVGIcon("com/formdev/flatlaf/demo/icons/menu-paste.svg"));
|
||||||
showToggleButton.setIcon(new FlatSVGIcon("com/formdev/flatlaf/demo/icons/show.svg"));
|
toolBar.add(pasteButton);
|
||||||
toolBar.add(showToggleButton);
|
toolBar.addSeparator();
|
||||||
|
|
||||||
|
//---- refreshButton ----
|
||||||
|
refreshButton.setToolTipText("Refresh");
|
||||||
|
refreshButton.setIcon(new FlatSVGIcon("com/formdev/flatlaf/demo/icons/refresh.svg"));
|
||||||
|
toolBar.add(refreshButton);
|
||||||
|
toolBar.addSeparator();
|
||||||
|
|
||||||
|
//---- showToggleButton ----
|
||||||
|
showToggleButton.setSelected(true);
|
||||||
|
showToggleButton.setToolTipText("Show Details");
|
||||||
|
showToggleButton.setIcon(new FlatSVGIcon("com/formdev/flatlaf/demo/icons/show.svg"));
|
||||||
|
toolBar.add(showToggleButton);
|
||||||
|
}
|
||||||
|
toolBarPanel.add(toolBar, BorderLayout.CENTER);
|
||||||
}
|
}
|
||||||
contentPane.add(toolBar, BorderLayout.NORTH);
|
contentPane.add(toolBarPanel, BorderLayout.PAGE_START);
|
||||||
|
|
||||||
//======== contentPanel ========
|
//======== contentPanel ========
|
||||||
{
|
{
|
||||||
@@ -888,13 +932,25 @@ class DemoFrame
|
|||||||
tabbedPane.addTab("Data Components", dataComponentsPanel);
|
tabbedPane.addTab("Data Components", dataComponentsPanel);
|
||||||
tabbedPane.addTab("Tabs", tabsPanel);
|
tabbedPane.addTab("Tabs", tabsPanel);
|
||||||
tabbedPane.addTab("Option Pane", optionPanePanel);
|
tabbedPane.addTab("Option Pane", optionPanePanel);
|
||||||
tabbedPane.addTab("Extras", extrasPanel1);
|
tabbedPane.addTab("Extras", extrasPanel);
|
||||||
}
|
}
|
||||||
contentPanel.add(tabbedPane, "cell 0 0");
|
contentPanel.add(tabbedPane, "cell 0 0");
|
||||||
}
|
}
|
||||||
contentPane.add(contentPanel, BorderLayout.CENTER);
|
contentPane.add(contentPanel, BorderLayout.CENTER);
|
||||||
contentPane.add(controlBar, BorderLayout.SOUTH);
|
contentPane.add(controlBar, BorderLayout.PAGE_END);
|
||||||
contentPane.add(themesPanel, BorderLayout.EAST);
|
|
||||||
|
//======== themesPanelPanel ========
|
||||||
|
{
|
||||||
|
themesPanelPanel.setLayout(new BorderLayout());
|
||||||
|
|
||||||
|
//======== winFullWindowContentButtonsPlaceholder ========
|
||||||
|
{
|
||||||
|
winFullWindowContentButtonsPlaceholder.setLayout(new FlowLayout());
|
||||||
|
}
|
||||||
|
themesPanelPanel.add(winFullWindowContentButtonsPlaceholder, BorderLayout.NORTH);
|
||||||
|
themesPanelPanel.add(themesPanel, BorderLayout.CENTER);
|
||||||
|
}
|
||||||
|
contentPane.add(themesPanelPanel, BorderLayout.LINE_END);
|
||||||
|
|
||||||
//---- buttonGroup1 ----
|
//---- buttonGroup1 ----
|
||||||
ButtonGroup buttonGroup1 = new ButtonGroup();
|
ButtonGroup buttonGroup1 = new ButtonGroup();
|
||||||
@@ -909,8 +965,8 @@ class DemoFrame
|
|||||||
usersButton.setButtonType( ButtonType.toolBarButton );
|
usersButton.setButtonType( ButtonType.toolBarButton );
|
||||||
usersButton.setFocusable( false );
|
usersButton.setFocusable( false );
|
||||||
usersButton.addActionListener( e -> JOptionPane.showMessageDialog( null, "Hello User! How are you?", "User", JOptionPane.INFORMATION_MESSAGE ) );
|
usersButton.addActionListener( e -> JOptionPane.showMessageDialog( null, "Hello User! How are you?", "User", JOptionPane.INFORMATION_MESSAGE ) );
|
||||||
menuBar1.add( Box.createGlue() );
|
menuBar.add( Box.createGlue() );
|
||||||
menuBar1.add( usersButton );
|
menuBar.add( usersButton );
|
||||||
|
|
||||||
cutMenuItem.addActionListener( new DefaultEditorKit.CutAction() );
|
cutMenuItem.addActionListener( new DefaultEditorKit.CutAction() );
|
||||||
copyMenuItem.addActionListener( new DefaultEditorKit.CopyAction() );
|
copyMenuItem.addActionListener( new DefaultEditorKit.CopyAction() );
|
||||||
@@ -922,7 +978,7 @@ class DemoFrame
|
|||||||
for( int i = 1; i <= 100; i++ )
|
for( int i = 1; i <= 100; i++ )
|
||||||
scrollingPopupMenu.add( "Item " + i );
|
scrollingPopupMenu.add( "Item " + i );
|
||||||
|
|
||||||
if( FlatLaf.supportsNativeWindowDecorations() || (SystemInfo.isLinux && JFrame.isDefaultLookAndFeelDecorated()) ) {
|
if( supportsFlatLafWindowDecorations() ) {
|
||||||
if( SystemInfo.isLinux )
|
if( SystemInfo.isLinux )
|
||||||
unsupported( windowDecorationsCheckBoxMenuItem );
|
unsupported( windowDecorationsCheckBoxMenuItem );
|
||||||
else
|
else
|
||||||
@@ -943,6 +999,17 @@ class DemoFrame
|
|||||||
if( "false".equals( System.getProperty( "flatlaf.animatedLafChange" ) ) )
|
if( "false".equals( System.getProperty( "flatlaf.animatedLafChange" ) ) )
|
||||||
animatedLafChangeMenuItem.setSelected( false );
|
animatedLafChangeMenuItem.setSelected( false );
|
||||||
|
|
||||||
|
|
||||||
|
// on macOS, panel left to toolBar is a placeholder for title bar buttons in fullWindowContent mode
|
||||||
|
macFullWindowContentButtonsPlaceholder.putClientProperty( FlatClientProperties.FULL_WINDOW_CONTENT_BUTTONS_PLACEHOLDER, "mac zeroInFullScreen" );
|
||||||
|
|
||||||
|
// on Windows/Linux, panel above themesPanel is a placeholder for title bar buttons in fullWindowContent mode
|
||||||
|
winFullWindowContentButtonsPlaceholder.putClientProperty( FlatClientProperties.FULL_WINDOW_CONTENT_BUTTONS_PLACEHOLDER, "win" );
|
||||||
|
|
||||||
|
// uncomment this line to see title bar buttons placeholders in fullWindowContent mode
|
||||||
|
// UIManager.put( "FlatLaf.debug.panel.showPlaceholders", true );
|
||||||
|
|
||||||
|
|
||||||
// remove contentPanel bottom insets
|
// remove contentPanel bottom insets
|
||||||
MigLayout layout = (MigLayout) contentPanel.getLayout();
|
MigLayout layout = (MigLayout) contentPanel.getLayout();
|
||||||
LC lc = ConstraintParser.parseLayoutConstraint( (String) layout.getLayoutConstraints() );
|
LC lc = ConstraintParser.parseLayoutConstraint( (String) layout.getLayoutConstraints() );
|
||||||
@@ -963,6 +1030,7 @@ class DemoFrame
|
|||||||
}
|
}
|
||||||
|
|
||||||
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
|
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
|
||||||
|
private JMenuBar menuBar;
|
||||||
private JMenuItem exitMenuItem;
|
private JMenuItem exitMenuItem;
|
||||||
private JMenu scrollingPopupMenu;
|
private JMenu scrollingPopupMenu;
|
||||||
private JMenuItem htmlMenuItem;
|
private JMenuItem htmlMenuItem;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
JFDML JFormDesigner: "8.1.0.0.283" Java: "19.0.2" encoding: "UTF-8"
|
JFDML JFormDesigner: "8.2.1.0.348" Java: "21.0.1" encoding: "UTF-8"
|
||||||
|
|
||||||
new FormModel {
|
new FormModel {
|
||||||
contentType: "form/swing"
|
contentType: "form/swing"
|
||||||
@@ -12,59 +12,69 @@ new FormModel {
|
|||||||
"defaultCloseOperation": 2
|
"defaultCloseOperation": 2
|
||||||
"$locationPolicy": 2
|
"$locationPolicy": 2
|
||||||
"$sizePolicy": 2
|
"$sizePolicy": 2
|
||||||
add( new FormContainer( "javax.swing.JToolBar", new FormLayoutManager( class javax.swing.JToolBar ) ) {
|
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class java.awt.BorderLayout ) ) {
|
||||||
name: "toolBar"
|
name: "toolBarPanel"
|
||||||
"margin": new java.awt.Insets( 3, 3, 3, 3 )
|
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class java.awt.FlowLayout ) ) {
|
||||||
auxiliary() {
|
name: "macFullWindowContentButtonsPlaceholder"
|
||||||
"JavaCodeGenerator.variableLocal": false
|
}, new FormLayoutConstraints( class java.lang.String ) {
|
||||||
}
|
"value": "West"
|
||||||
add( new FormComponent( "javax.swing.JButton" ) {
|
|
||||||
name: "backButton"
|
|
||||||
"toolTipText": "Back"
|
|
||||||
"icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/demo/icons/back.svg" )
|
|
||||||
} )
|
} )
|
||||||
add( new FormComponent( "javax.swing.JButton" ) {
|
add( new FormContainer( "javax.swing.JToolBar", new FormLayoutManager( class javax.swing.JToolBar ) ) {
|
||||||
name: "forwardButton"
|
name: "toolBar"
|
||||||
"toolTipText": "Forward"
|
"margin": new java.awt.Insets( 3, 3, 3, 3 )
|
||||||
"icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/demo/icons/forward.svg" )
|
auxiliary() {
|
||||||
} )
|
"JavaCodeGenerator.variableLocal": false
|
||||||
add( new FormComponent( "javax.swing.JToolBar$Separator" ) {
|
}
|
||||||
name: "separator5"
|
add( new FormComponent( "javax.swing.JButton" ) {
|
||||||
} )
|
name: "backButton"
|
||||||
add( new FormComponent( "javax.swing.JButton" ) {
|
"toolTipText": "Back"
|
||||||
name: "cutButton"
|
"icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/demo/icons/back.svg" )
|
||||||
"toolTipText": "Cut"
|
} )
|
||||||
"icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/demo/icons/menu-cut.svg" )
|
add( new FormComponent( "javax.swing.JButton" ) {
|
||||||
} )
|
name: "forwardButton"
|
||||||
add( new FormComponent( "javax.swing.JButton" ) {
|
"toolTipText": "Forward"
|
||||||
name: "copyButton"
|
"icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/demo/icons/forward.svg" )
|
||||||
"toolTipText": "Copy"
|
} )
|
||||||
"icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/demo/icons/copy.svg" )
|
add( new FormComponent( "javax.swing.JToolBar$Separator" ) {
|
||||||
} )
|
name: "separator5"
|
||||||
add( new FormComponent( "javax.swing.JButton" ) {
|
} )
|
||||||
name: "pasteButton"
|
add( new FormComponent( "javax.swing.JButton" ) {
|
||||||
"toolTipText": "Paste"
|
name: "cutButton"
|
||||||
"icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/demo/icons/menu-paste.svg" )
|
"toolTipText": "Cut"
|
||||||
} )
|
"icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/demo/icons/menu-cut.svg" )
|
||||||
add( new FormComponent( "javax.swing.JToolBar$Separator" ) {
|
} )
|
||||||
name: "separator6"
|
add( new FormComponent( "javax.swing.JButton" ) {
|
||||||
} )
|
name: "copyButton"
|
||||||
add( new FormComponent( "javax.swing.JButton" ) {
|
"toolTipText": "Copy"
|
||||||
name: "refreshButton"
|
"icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/demo/icons/copy.svg" )
|
||||||
"toolTipText": "Refresh"
|
} )
|
||||||
"icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/demo/icons/refresh.svg" )
|
add( new FormComponent( "javax.swing.JButton" ) {
|
||||||
} )
|
name: "pasteButton"
|
||||||
add( new FormComponent( "javax.swing.JToolBar$Separator" ) {
|
"toolTipText": "Paste"
|
||||||
name: "separator7"
|
"icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/demo/icons/menu-paste.svg" )
|
||||||
} )
|
} )
|
||||||
add( new FormComponent( "javax.swing.JToggleButton" ) {
|
add( new FormComponent( "javax.swing.JToolBar$Separator" ) {
|
||||||
name: "showToggleButton"
|
name: "separator6"
|
||||||
"selected": true
|
} )
|
||||||
"toolTipText": "Show Details"
|
add( new FormComponent( "javax.swing.JButton" ) {
|
||||||
"icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/demo/icons/show.svg" )
|
name: "refreshButton"
|
||||||
|
"toolTipText": "Refresh"
|
||||||
|
"icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/demo/icons/refresh.svg" )
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JToolBar$Separator" ) {
|
||||||
|
name: "separator7"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JToggleButton" ) {
|
||||||
|
name: "showToggleButton"
|
||||||
|
"selected": true
|
||||||
|
"toolTipText": "Show Details"
|
||||||
|
"icon": new com.jformdesigner.model.SwingIcon( 0, "/com/formdev/flatlaf/demo/icons/show.svg" )
|
||||||
|
} )
|
||||||
|
}, new FormLayoutConstraints( class java.lang.String ) {
|
||||||
|
"value": "Center"
|
||||||
} )
|
} )
|
||||||
}, new FormLayoutConstraints( class java.lang.String ) {
|
}, new FormLayoutConstraints( class java.lang.String ) {
|
||||||
"value": "North"
|
"value": "First"
|
||||||
} )
|
} )
|
||||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
||||||
"$layoutConstraints": "insets dialog,hidemode 3"
|
"$layoutConstraints": "insets dialog,hidemode 3"
|
||||||
@@ -105,7 +115,7 @@ new FormModel {
|
|||||||
"title": "Option Pane"
|
"title": "Option Pane"
|
||||||
} )
|
} )
|
||||||
add( new FormComponent( "com.formdev.flatlaf.demo.extras.ExtrasPanel" ) {
|
add( new FormComponent( "com.formdev.flatlaf.demo.extras.ExtrasPanel" ) {
|
||||||
name: "extrasPanel1"
|
name: "extrasPanel"
|
||||||
}, new FormLayoutConstraints( null ) {
|
}, new FormLayoutConstraints( null ) {
|
||||||
"title": "Extras"
|
"title": "Extras"
|
||||||
} )
|
} )
|
||||||
@@ -121,19 +131,32 @@ new FormModel {
|
|||||||
"JavaCodeGenerator.variableLocal": false
|
"JavaCodeGenerator.variableLocal": false
|
||||||
}
|
}
|
||||||
}, new FormLayoutConstraints( class java.lang.String ) {
|
}, new FormLayoutConstraints( class java.lang.String ) {
|
||||||
"value": "South"
|
"value": "Last"
|
||||||
} )
|
} )
|
||||||
add( new FormComponent( "com.formdev.flatlaf.demo.intellijthemes.IJThemesPanel" ) {
|
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class java.awt.BorderLayout ) ) {
|
||||||
name: "themesPanel"
|
name: "themesPanelPanel"
|
||||||
auxiliary() {
|
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class java.awt.FlowLayout ) ) {
|
||||||
"JavaCodeGenerator.variableLocal": false
|
name: "winFullWindowContentButtonsPlaceholder"
|
||||||
"JavaCodeGenerator.variableModifiers": 0
|
}, new FormLayoutConstraints( class java.lang.String ) {
|
||||||
}
|
"value": "North"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "com.formdev.flatlaf.demo.intellijthemes.IJThemesPanel" ) {
|
||||||
|
name: "themesPanel"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
"JavaCodeGenerator.variableModifiers": 0
|
||||||
|
}
|
||||||
|
}, new FormLayoutConstraints( class java.lang.String ) {
|
||||||
|
"value": "Center"
|
||||||
|
} )
|
||||||
}, new FormLayoutConstraints( class java.lang.String ) {
|
}, new FormLayoutConstraints( class java.lang.String ) {
|
||||||
"value": "East"
|
"value": "After"
|
||||||
} )
|
} )
|
||||||
menuBar: new FormContainer( "javax.swing.JMenuBar", new FormLayoutManager( class javax.swing.JMenuBar ) ) {
|
menuBar: new FormContainer( "javax.swing.JMenuBar", new FormLayoutManager( class javax.swing.JMenuBar ) ) {
|
||||||
name: "menuBar1"
|
name: "menuBar"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
add( new FormContainer( "javax.swing.JMenu", new FormLayoutManager( class javax.swing.JMenu ) ) {
|
add( new FormContainer( "javax.swing.JMenu", new FormLayoutManager( class javax.swing.JMenu ) ) {
|
||||||
name: "fileMenu"
|
name: "fileMenu"
|
||||||
"text": "File"
|
"text": "File"
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
<!-- Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -->
|
||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M1.5 14.5L6 10M14.5 1.5L9.99998 6.00001M2.5 9.50001H6.5L6.5 13.5M13.5 6.5L9.5 6.50003V2.5" stroke="#6E6E6E" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 396 B |
@@ -0,0 +1,4 @@
|
|||||||
|
<!-- Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. -->
|
||||||
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<path d="M6.5 9.5L2 14M9.50003 6.50004L14 2.00001M5.5 14.5H1.5V10.5M10.5 1.5L14.5 1.50002V5.5" stroke="#6E6E6E" stroke-linecap="round" stroke-linejoin="round"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 391 B |
@@ -18,7 +18,7 @@
|
|||||||
// For maven compatibility, <font-version> should be in format <major>.<minor>[.<micro>].
|
// For maven compatibility, <font-version> should be in format <major>.<minor>[.<micro>].
|
||||||
// <build-number> is optional and should be incremented only if a new release is
|
// <build-number> is optional and should be incremented only if a new release is
|
||||||
// necessary, but the <font-version> has not changed.
|
// necessary, but the <font-version> has not changed.
|
||||||
version = "3.19"
|
version = "4.0"
|
||||||
|
|
||||||
if( !rootProject.hasProperty( "release" ) )
|
if( !rootProject.hasProperty( "release" ) )
|
||||||
version = version.toString() + "-SNAPSHOT"
|
version = version.toString() + "-SNAPSHOT"
|
||||||
@@ -56,7 +56,7 @@ tasks {
|
|||||||
testLogging.exceptionFormat = org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL
|
testLogging.exceptionFormat = org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL
|
||||||
}
|
}
|
||||||
|
|
||||||
withType<PublishToMavenRepository>().configureEach {
|
withType<AbstractPublishToMaven>().configureEach {
|
||||||
onlyIf { !rootProject.hasProperty( "skipFonts" ) }
|
onlyIf { !rootProject.hasProperty( "skipFonts" ) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ public class FlatInterFont
|
|||||||
* new Font( FlatInterFont.FAMILY_SEMIBOLD, Font.ITALIC, 12 );
|
* new Font( FlatInterFont.FAMILY_SEMIBOLD, Font.ITALIC, 12 );
|
||||||
* }</pre>
|
* }</pre>
|
||||||
*/
|
*/
|
||||||
public static final String FAMILY_SEMIBOLD = "Inter Semi Bold";
|
public static final String FAMILY_SEMIBOLD = "Inter SemiBold";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Use for {@link #installStyle(String)} to install single font style.
|
* Use for {@link #installStyle(String)} to install single font style.
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,6 +1,4 @@
|
|||||||
Copyright (c) 2016-2020 The Inter Project Authors.
|
Copyright (c) 2016 The Inter Project Authors (https://github.com/rsms/inter)
|
||||||
"Inter" is trademark of Rasmus Andersson.
|
|
||||||
https://github.com/rsms/inter
|
|
||||||
|
|
||||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||||
This license is copied below, and is also available with a FAQ at:
|
This license is copied below, and is also available with a FAQ at:
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ tasks {
|
|||||||
testLogging.exceptionFormat = org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL
|
testLogging.exceptionFormat = org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL
|
||||||
}
|
}
|
||||||
|
|
||||||
withType<PublishToMavenRepository>().configureEach {
|
withType<AbstractPublishToMaven>().configureEach {
|
||||||
onlyIf { !rootProject.hasProperty( "skipFonts" ) }
|
onlyIf { !rootProject.hasProperty( "skipFonts" ) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ tasks {
|
|||||||
testLogging.exceptionFormat = org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL
|
testLogging.exceptionFormat = org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL
|
||||||
}
|
}
|
||||||
|
|
||||||
withType<PublishToMavenRepository>().configureEach {
|
withType<AbstractPublishToMaven>().configureEach {
|
||||||
onlyIf { !rootProject.hasProperty( "skipFonts" ) }
|
onlyIf { !rootProject.hasProperty( "skipFonts" ) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ tasks {
|
|||||||
testLogging.exceptionFormat = org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL
|
testLogging.exceptionFormat = org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL
|
||||||
}
|
}
|
||||||
|
|
||||||
withType<PublishToMavenRepository>().configureEach {
|
withType<AbstractPublishToMaven>().configureEach {
|
||||||
onlyIf { !rootProject.hasProperty( "skipFonts" ) }
|
onlyIf { !rootProject.hasProperty( "skipFonts" ) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf.jideoss.ui;
|
package com.formdev.flatlaf.jideoss.ui;
|
||||||
|
|
||||||
|
import static com.formdev.flatlaf.FlatClientProperties.COMPONENT_TITLE_BAR_CAPTION;
|
||||||
import static com.formdev.flatlaf.FlatClientProperties.TABBED_PANE_HAS_FULL_BORDER;
|
import static com.formdev.flatlaf.FlatClientProperties.TABBED_PANE_HAS_FULL_BORDER;
|
||||||
import static com.formdev.flatlaf.FlatClientProperties.TABBED_PANE_SHOW_TAB_SEPARATORS;
|
import static com.formdev.flatlaf.FlatClientProperties.TABBED_PANE_SHOW_TAB_SEPARATORS;
|
||||||
import static com.formdev.flatlaf.FlatClientProperties.clientPropertyBoolean;
|
import static com.formdev.flatlaf.FlatClientProperties.clientPropertyBoolean;
|
||||||
@@ -30,6 +31,7 @@ import java.awt.Graphics;
|
|||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.awt.Insets;
|
import java.awt.Insets;
|
||||||
import java.awt.LayoutManager;
|
import java.awt.LayoutManager;
|
||||||
|
import java.awt.Point;
|
||||||
import java.awt.Rectangle;
|
import java.awt.Rectangle;
|
||||||
import java.awt.Shape;
|
import java.awt.Shape;
|
||||||
import java.awt.event.MouseListener;
|
import java.awt.event.MouseListener;
|
||||||
@@ -37,6 +39,7 @@ import java.awt.event.MouseMotionListener;
|
|||||||
import java.awt.geom.Path2D;
|
import java.awt.geom.Path2D;
|
||||||
import java.awt.geom.Rectangle2D;
|
import java.awt.geom.Rectangle2D;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
|
import java.util.function.Function;
|
||||||
import javax.swing.Icon;
|
import javax.swing.Icon;
|
||||||
import javax.swing.JButton;
|
import javax.swing.JButton;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
@@ -100,6 +103,25 @@ public class FlatJideTabbedPaneUI
|
|||||||
return new FlatJideTabbedPaneUI();
|
return new FlatJideTabbedPaneUI();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void installUI( JComponent c ) {
|
||||||
|
super.installUI( c );
|
||||||
|
|
||||||
|
c.putClientProperty( COMPONENT_TITLE_BAR_CAPTION,
|
||||||
|
(Function<Point, Boolean>) pt -> {
|
||||||
|
if( tabForCoordinate( _tabPane, pt.x, pt.y ) >= 0 )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return null; // check children
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void uninstallUI( JComponent c ) {
|
||||||
|
super.uninstallUI( c );
|
||||||
|
c.putClientProperty( COMPONENT_TITLE_BAR_CAPTION, null );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void installDefaults() {
|
protected void installDefaults() {
|
||||||
super.installDefaults();
|
super.installDefaults();
|
||||||
|
|||||||
@@ -32,8 +32,8 @@ import java.beans.PropertyChangeEvent;
|
|||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.IdentityHashMap;
|
import java.util.IdentityHashMap;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.function.Predicate;
|
||||||
import javax.swing.JDialog;
|
import javax.swing.JDialog;
|
||||||
import javax.swing.JFrame;
|
import javax.swing.JFrame;
|
||||||
import javax.swing.Timer;
|
import javax.swing.Timer;
|
||||||
@@ -164,7 +164,7 @@ public class FlatWindowsNativeWindowBorder
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateTitleBarInfo( Window window, int titleBarHeight, List<Rectangle> hitTestSpots,
|
public void updateTitleBarInfo( Window window, int titleBarHeight, Predicate<Point> captionHitTestCallback,
|
||||||
Rectangle appIconBounds, Rectangle minimizeButtonBounds, Rectangle maximizeButtonBounds,
|
Rectangle appIconBounds, Rectangle minimizeButtonBounds, Rectangle maximizeButtonBounds,
|
||||||
Rectangle closeButtonBounds )
|
Rectangle closeButtonBounds )
|
||||||
{
|
{
|
||||||
@@ -173,7 +173,7 @@ public class FlatWindowsNativeWindowBorder
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
wndProc.titleBarHeight = titleBarHeight;
|
wndProc.titleBarHeight = titleBarHeight;
|
||||||
wndProc.hitTestSpots = hitTestSpots.toArray( new Rectangle[hitTestSpots.size()] );
|
wndProc.captionHitTestCallback = captionHitTestCallback;
|
||||||
wndProc.appIconBounds = cloneRectange( appIconBounds );
|
wndProc.appIconBounds = cloneRectange( appIconBounds );
|
||||||
wndProc.minimizeButtonBounds = cloneRectange( minimizeButtonBounds );
|
wndProc.minimizeButtonBounds = cloneRectange( minimizeButtonBounds );
|
||||||
wndProc.maximizeButtonBounds = cloneRectange( maximizeButtonBounds );
|
wndProc.maximizeButtonBounds = cloneRectange( maximizeButtonBounds );
|
||||||
@@ -351,7 +351,7 @@ public class FlatWindowsNativeWindowBorder
|
|||||||
|
|
||||||
// Swing coordinates/values may be scaled on a HiDPI screen
|
// Swing coordinates/values may be scaled on a HiDPI screen
|
||||||
private int titleBarHeight;
|
private int titleBarHeight;
|
||||||
private Rectangle[] hitTestSpots;
|
private Predicate<Point> captionHitTestCallback;
|
||||||
private Rectangle appIconBounds;
|
private Rectangle appIconBounds;
|
||||||
private Rectangle minimizeButtonBounds;
|
private Rectangle minimizeButtonBounds;
|
||||||
private Rectangle maximizeButtonBounds;
|
private Rectangle maximizeButtonBounds;
|
||||||
@@ -644,53 +644,65 @@ public class FlatWindowsNativeWindowBorder
|
|||||||
|
|
||||||
// scale-down mouse x/y because Swing coordinates/values may be scaled on a HiDPI screen
|
// scale-down mouse x/y because Swing coordinates/values may be scaled on a HiDPI screen
|
||||||
Point pt = scaleDown( x, y );
|
Point pt = scaleDown( x, y );
|
||||||
int sx = pt.x;
|
|
||||||
int sy = pt.y;
|
|
||||||
|
|
||||||
// return HTSYSMENU if mouse is over application icon
|
// return HTSYSMENU if mouse is over application icon
|
||||||
// - left-click on HTSYSMENU area shows system menu
|
// - left-click on HTSYSMENU area shows system menu
|
||||||
// - double-left-click sends WM_CLOSE
|
// - double-left-click sends WM_CLOSE
|
||||||
if( contains( appIconBounds, sx, sy ) )
|
if( contains( appIconBounds, pt ) )
|
||||||
return new LRESULT( HTSYSMENU );
|
return new LRESULT( HTSYSMENU );
|
||||||
|
|
||||||
// return HTMINBUTTON if mouse is over minimize button
|
// return HTMINBUTTON if mouse is over minimize button
|
||||||
// - hovering mouse over HTMINBUTTON area shows tooltip on Windows 10/11
|
// - hovering mouse over HTMINBUTTON area shows tooltip on Windows 10/11
|
||||||
if( contains( minimizeButtonBounds, sx, sy ) )
|
if( contains( minimizeButtonBounds, pt ) )
|
||||||
return new LRESULT( HTMINBUTTON );
|
return new LRESULT( HTMINBUTTON );
|
||||||
|
|
||||||
// return HTMAXBUTTON if mouse is over maximize/restore button
|
// return HTMAXBUTTON if mouse is over maximize/restore button
|
||||||
// - hovering mouse over HTMAXBUTTON area shows tooltip on Windows 10
|
// - hovering mouse over HTMAXBUTTON area shows tooltip on Windows 10
|
||||||
// - hovering mouse over HTMAXBUTTON area shows snap layouts menu on Windows 11
|
// - hovering mouse over HTMAXBUTTON area shows snap layouts menu on Windows 11
|
||||||
// https://docs.microsoft.com/en-us/windows/apps/desktop/modernize/apply-snap-layout-menu
|
// https://docs.microsoft.com/en-us/windows/apps/desktop/modernize/apply-snap-layout-menu
|
||||||
if( contains( maximizeButtonBounds, sx, sy ) )
|
if( contains( maximizeButtonBounds, pt ) )
|
||||||
return new LRESULT( HTMAXBUTTON );
|
return new LRESULT( HTMAXBUTTON );
|
||||||
|
|
||||||
// return HTCLOSE if mouse is over close button
|
// return HTCLOSE if mouse is over close button
|
||||||
// - hovering mouse over HTCLOSE area shows tooltip on Windows 10/11
|
// - hovering mouse over HTCLOSE area shows tooltip on Windows 10/11
|
||||||
if( contains( closeButtonBounds, sx, sy ) )
|
if( contains( closeButtonBounds, pt ) )
|
||||||
return new LRESULT( HTCLOSE );
|
return new LRESULT( HTCLOSE );
|
||||||
|
|
||||||
int resizeBorderHeight = getResizeHandleHeight();
|
int resizeBorderHeight = getResizeHandleHeight();
|
||||||
boolean isOnResizeBorder = (y < resizeBorderHeight) &&
|
boolean isOnResizeBorder = (y < resizeBorderHeight) &&
|
||||||
(User32.INSTANCE.GetWindowLong( hwnd, GWL_STYLE ) & WS_THICKFRAME) != 0;
|
(User32.INSTANCE.GetWindowLong( hwnd, GWL_STYLE ) & WS_THICKFRAME) != 0;
|
||||||
boolean isOnTitleBar = (sy < titleBarHeight);
|
|
||||||
|
|
||||||
|
// return HTTOP if mouse is over top resize border
|
||||||
|
// - hovering mouse shows vertical resize cursor
|
||||||
|
// - left-click and drag vertically resizes window
|
||||||
|
if( isOnResizeBorder )
|
||||||
|
return new LRESULT( HTTOP );
|
||||||
|
|
||||||
|
boolean isOnTitleBar = (pt.y < titleBarHeight);
|
||||||
if( isOnTitleBar ) {
|
if( isOnTitleBar ) {
|
||||||
// use a second reference to the array to avoid that it can be changed
|
// return HTCLIENT if mouse is over any Swing component in title bar
|
||||||
// in another thread while processing the array
|
// that processes mouse events (e.g. buttons, menus, etc)
|
||||||
Rectangle[] hitTestSpots2 = hitTestSpots;
|
// - Windows ignores mouse events in this area
|
||||||
for( Rectangle spot : hitTestSpots2 ) {
|
try {
|
||||||
if( spot.contains( sx, sy ) )
|
if( captionHitTestCallback != null && !captionHitTestCallback.test( pt ) )
|
||||||
return new LRESULT( HTCLIENT );
|
return new LRESULT( HTCLIENT );
|
||||||
|
} catch( Throwable ex ) {
|
||||||
|
// ignore
|
||||||
}
|
}
|
||||||
return new LRESULT( isOnResizeBorder ? HTTOP : HTCAPTION );
|
|
||||||
|
// return HTCAPTION if mouse is over title bar
|
||||||
|
// - right-click shows system menu
|
||||||
|
// - double-left-click maximizes/restores window size
|
||||||
|
return new LRESULT( HTCAPTION );
|
||||||
}
|
}
|
||||||
|
|
||||||
return new LRESULT( isOnResizeBorder ? HTTOP : HTCLIENT );
|
// return HTCLIENT
|
||||||
|
// - Windows ignores mouse events in this area
|
||||||
|
return new LRESULT( HTCLIENT );
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean contains( Rectangle rect, int x, int y ) {
|
private boolean contains( Rectangle rect, Point pt ) {
|
||||||
return (rect != null && rect.contains( x, y ) );
|
return (rect != null && rect.contains( pt ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -41,4 +41,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
jfieldID getFieldID( JNIEnv *env, const char* className, const char* fieldName, const char* fieldSignature );
|
jclass findClass( JNIEnv *env, const char* className, bool globalRef );
|
||||||
|
jfieldID getFieldID( JNIEnv *env, const char* className, const char* fieldName, const char* fieldSignature, bool staticField );
|
||||||
|
jmethodID getMethodID( JNIEnv *env, jclass cls, const char* methodName, const char* methodSignature, bool staticMethod );
|
||||||
|
|||||||
@@ -7,6 +7,12 @@
|
|||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
#undef com_formdev_flatlaf_ui_FlatNativeMacLibrary_BUTTONS_SPACING_DEFAULT
|
||||||
|
#define com_formdev_flatlaf_ui_FlatNativeMacLibrary_BUTTONS_SPACING_DEFAULT 0L
|
||||||
|
#undef com_formdev_flatlaf_ui_FlatNativeMacLibrary_BUTTONS_SPACING_MEDIUM
|
||||||
|
#define com_formdev_flatlaf_ui_FlatNativeMacLibrary_BUTTONS_SPACING_MEDIUM 1L
|
||||||
|
#undef com_formdev_flatlaf_ui_FlatNativeMacLibrary_BUTTONS_SPACING_LARGE
|
||||||
|
#define com_formdev_flatlaf_ui_FlatNativeMacLibrary_BUTTONS_SPACING_LARGE 2L
|
||||||
/*
|
/*
|
||||||
* Class: com_formdev_flatlaf_ui_FlatNativeMacLibrary
|
* Class: com_formdev_flatlaf_ui_FlatNativeMacLibrary
|
||||||
* Method: setWindowRoundedBorder
|
* Method: setWindowRoundedBorder
|
||||||
@@ -15,6 +21,38 @@ extern "C" {
|
|||||||
JNIEXPORT jboolean JNICALL Java_com_formdev_flatlaf_ui_FlatNativeMacLibrary_setWindowRoundedBorder
|
JNIEXPORT jboolean JNICALL Java_com_formdev_flatlaf_ui_FlatNativeMacLibrary_setWindowRoundedBorder
|
||||||
(JNIEnv *, jclass, jobject, jfloat, jfloat, jint);
|
(JNIEnv *, jclass, jobject, jfloat, jfloat, jint);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: com_formdev_flatlaf_ui_FlatNativeMacLibrary
|
||||||
|
* Method: setWindowButtonsSpacing
|
||||||
|
* Signature: (Ljava/awt/Window;I)Z
|
||||||
|
*/
|
||||||
|
JNIEXPORT jboolean JNICALL Java_com_formdev_flatlaf_ui_FlatNativeMacLibrary_setWindowButtonsSpacing
|
||||||
|
(JNIEnv *, jclass, jobject, jint);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: com_formdev_flatlaf_ui_FlatNativeMacLibrary
|
||||||
|
* Method: getWindowButtonsBounds
|
||||||
|
* Signature: (Ljava/awt/Window;)Ljava/awt/Rectangle;
|
||||||
|
*/
|
||||||
|
JNIEXPORT jobject JNICALL Java_com_formdev_flatlaf_ui_FlatNativeMacLibrary_getWindowButtonsBounds
|
||||||
|
(JNIEnv *, jclass, jobject);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: com_formdev_flatlaf_ui_FlatNativeMacLibrary
|
||||||
|
* Method: isWindowFullScreen
|
||||||
|
* Signature: (Ljava/awt/Window;)Z
|
||||||
|
*/
|
||||||
|
JNIEXPORT jboolean JNICALL Java_com_formdev_flatlaf_ui_FlatNativeMacLibrary_isWindowFullScreen
|
||||||
|
(JNIEnv *, jclass, jobject);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Class: com_formdev_flatlaf_ui_FlatNativeMacLibrary
|
||||||
|
* Method: toggleWindowFullScreen
|
||||||
|
* Signature: (Ljava/awt/Window;)Z
|
||||||
|
*/
|
||||||
|
JNIEXPORT jboolean JNICALL Java_com_formdev_flatlaf_ui_FlatNativeMacLibrary_toggleWindowFullScreen
|
||||||
|
(JNIEnv *, jclass, jobject);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -21,8 +21,8 @@
|
|||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
|
|
||||||
jfieldID getFieldID( JNIEnv *env, const char* className, const char* fieldName, const char* fieldSignature ) {
|
jclass findClass( JNIEnv *env, const char* className, bool globalRef ) {
|
||||||
// NSLog( @"getFieldID %s %s %s", className, fieldName, fieldSignature );
|
// NSLog( @"findClass %s", className );
|
||||||
|
|
||||||
jclass cls = env->FindClass( className );
|
jclass cls = env->FindClass( className );
|
||||||
if( cls == NULL ) {
|
if( cls == NULL ) {
|
||||||
@@ -32,7 +32,22 @@ jfieldID getFieldID( JNIEnv *env, const char* className, const char* fieldName,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
jfieldID fieldID = env->GetFieldID( cls, fieldName, fieldSignature );
|
if( globalRef )
|
||||||
|
cls = reinterpret_cast<jclass>( env->NewGlobalRef( cls ) );
|
||||||
|
|
||||||
|
return cls;
|
||||||
|
}
|
||||||
|
|
||||||
|
jfieldID getFieldID( JNIEnv *env, const char* className, const char* fieldName, const char* fieldSignature, bool staticField ) {
|
||||||
|
// NSLog( @"getFieldID %s %s %s", className, fieldName, fieldSignature );
|
||||||
|
|
||||||
|
jclass cls = findClass( env, className, false );
|
||||||
|
if( cls == NULL )
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
jfieldID fieldID = staticField
|
||||||
|
? env->GetStaticFieldID( cls, fieldName, fieldSignature )
|
||||||
|
: env->GetFieldID( cls, fieldName, fieldSignature );
|
||||||
if( fieldID == NULL ) {
|
if( fieldID == NULL ) {
|
||||||
NSLog( @"FlatLaf: failed to lookup field '%s' of type '%s' in class '%s'", fieldName, fieldSignature, className );
|
NSLog( @"FlatLaf: failed to lookup field '%s' of type '%s' in class '%s'", fieldName, fieldSignature, className );
|
||||||
env->ExceptionDescribe(); // print stack trace
|
env->ExceptionDescribe(); // print stack trace
|
||||||
@@ -42,3 +57,22 @@ jfieldID getFieldID( JNIEnv *env, const char* className, const char* fieldName,
|
|||||||
|
|
||||||
return fieldID;
|
return fieldID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
jmethodID getMethodID( JNIEnv *env, jclass cls, const char* methodName, const char* methodSignature, bool staticMethod ) {
|
||||||
|
// NSLog( @"getMethodID %s %s", methodName, methodSignature );
|
||||||
|
|
||||||
|
if( cls == NULL )
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
jmethodID methodID = staticMethod
|
||||||
|
? env->GetStaticMethodID( cls, methodName, methodSignature )
|
||||||
|
: env->GetMethodID( cls, methodName, methodSignature );
|
||||||
|
if( methodID == NULL ) {
|
||||||
|
NSLog( @"FlatLaf: failed to lookup method '%s' of type '%s'", methodName, methodSignature );
|
||||||
|
env->ExceptionDescribe(); // print stack trace
|
||||||
|
env->ExceptionClear();
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return methodID;
|
||||||
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#import <Cocoa/Cocoa.h>
|
#import <Cocoa/Cocoa.h>
|
||||||
|
#import <objc/runtime.h>
|
||||||
#import <jni.h>
|
#import <jni.h>
|
||||||
#import "JNIUtils.h"
|
#import "JNIUtils.h"
|
||||||
#import "JNFRunLoop.h"
|
#import "JNFRunLoop.h"
|
||||||
@@ -24,14 +25,37 @@
|
|||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@interface WindowData : NSObject
|
||||||
|
// used when window is full screen
|
||||||
|
@property (nonatomic) int lastWindowButtonAreaWidth;
|
||||||
|
@property (nonatomic) int lastWindowTitleBarHeight;
|
||||||
|
|
||||||
|
// full screen observers
|
||||||
|
@property (nonatomic) id willEnterFullScreenObserver;
|
||||||
|
@property (nonatomic) id willExitFullScreenObserver;
|
||||||
|
@property (nonatomic) id didExitFullScreenObserver;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation WindowData
|
||||||
|
@end
|
||||||
|
|
||||||
|
// declare internal methods
|
||||||
|
NSWindow* getNSWindow( JNIEnv* env, jclass cls, jobject window );
|
||||||
|
WindowData* getWindowData( NSWindow* nsWindow, bool allocate );
|
||||||
|
void setWindowButtonsHidden( NSWindow* nsWindow, bool hidden );
|
||||||
|
int getWindowButtonAreaWidth( NSWindow* nsWindow );
|
||||||
|
int getWindowTitleBarHeight( NSWindow* nsWindow );
|
||||||
|
bool isWindowFullScreen( NSWindow* nsWindow );
|
||||||
|
|
||||||
|
|
||||||
NSWindow* getNSWindow( JNIEnv* env, jclass cls, jobject window ) {
|
NSWindow* getNSWindow( JNIEnv* env, jclass cls, jobject window ) {
|
||||||
if( window == NULL )
|
if( window == NULL )
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
// initialize field IDs (done only once because fields are static)
|
// initialize field IDs (done only once because variables are static)
|
||||||
static jfieldID peerID = getFieldID( env, "java/awt/Component", "peer", "Ljava/awt/peer/ComponentPeer;" );
|
static jfieldID peerID = getFieldID( env, "java/awt/Component", "peer", "Ljava/awt/peer/ComponentPeer;", false );
|
||||||
static jfieldID platformWindowID = getFieldID( env, "sun/lwawt/LWWindowPeer", "platformWindow", "Lsun/lwawt/PlatformWindow;" );
|
static jfieldID platformWindowID = getFieldID( env, "sun/lwawt/LWWindowPeer", "platformWindow", "Lsun/lwawt/PlatformWindow;", false );
|
||||||
static jfieldID ptrID = getFieldID( env, "sun/lwawt/macosx/CFRetainedResource", "ptr", "J" );
|
static jfieldID ptrID = getFieldID( env, "sun/lwawt/macosx/CFRetainedResource", "ptr", "J", false );
|
||||||
if( peerID == NULL || platformWindowID == NULL || ptrID == NULL )
|
if( peerID == NULL || platformWindowID == NULL || ptrID == NULL )
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
@@ -49,6 +73,16 @@ NSWindow* getNSWindow( JNIEnv* env, jclass cls, jobject window ) {
|
|||||||
return (NSWindow *) jlong_to_ptr( env->GetLongField( platformWindow, ptrID ) );
|
return (NSWindow *) jlong_to_ptr( env->GetLongField( platformWindow, ptrID ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WindowData* getWindowData( NSWindow* nsWindow, bool allocate ) {
|
||||||
|
static char key;
|
||||||
|
WindowData* windowData = objc_getAssociatedObject( nsWindow, &key );
|
||||||
|
if( windowData == NULL && allocate ) {
|
||||||
|
windowData = [WindowData new];
|
||||||
|
objc_setAssociatedObject( nsWindow, &key, windowData, OBJC_ASSOCIATION_RETAIN_NONATOMIC );
|
||||||
|
}
|
||||||
|
return windowData;
|
||||||
|
}
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
JNIEXPORT jboolean JNICALL Java_com_formdev_flatlaf_ui_FlatNativeMacLibrary_setWindowRoundedBorder
|
JNIEXPORT jboolean JNICALL Java_com_formdev_flatlaf_ui_FlatNativeMacLibrary_setWindowRoundedBorder
|
||||||
( JNIEnv* env, jclass cls, jobject window, jfloat radius, jfloat borderWidth, jint borderColor )
|
( JNIEnv* env, jclass cls, jobject window, jfloat radius, jfloat borderWidth, jint borderColor )
|
||||||
@@ -87,3 +121,259 @@ JNIEXPORT jboolean JNICALL Java_com_formdev_flatlaf_ui_FlatNativeMacLibrary_setW
|
|||||||
JNI_COCOA_EXIT()
|
JNI_COCOA_EXIT()
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
JNIEXPORT jboolean JNICALL Java_com_formdev_flatlaf_ui_FlatNativeMacLibrary_setWindowButtonsSpacing
|
||||||
|
( JNIEnv* env, jclass cls, jobject window, jint buttonsSpacing )
|
||||||
|
{
|
||||||
|
JNI_COCOA_ENTER()
|
||||||
|
|
||||||
|
NSWindow* nsWindow = getNSWindow( env, cls, window );
|
||||||
|
if( nsWindow == NULL )
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
#define SPACING_DEFAULT com_formdev_flatlaf_ui_FlatNativeMacLibrary_BUTTONS_SPACING_DEFAULT
|
||||||
|
#define SPACING_MEDIUM com_formdev_flatlaf_ui_FlatNativeMacLibrary_BUTTONS_SPACING_MEDIUM
|
||||||
|
#define SPACING_LARGE com_formdev_flatlaf_ui_FlatNativeMacLibrary_BUTTONS_SPACING_LARGE
|
||||||
|
|
||||||
|
bool isMacOS_11_orLater = @available( macOS 11, * );
|
||||||
|
if( !isMacOS_11_orLater && buttonsSpacing == SPACING_LARGE )
|
||||||
|
buttonsSpacing = SPACING_MEDIUM;
|
||||||
|
int oldButtonsSpacing = (nsWindow.toolbar != NULL)
|
||||||
|
? ((isMacOS_11_orLater && nsWindow.toolbarStyle == NSWindowToolbarStyleUnified)
|
||||||
|
? SPACING_LARGE
|
||||||
|
: SPACING_MEDIUM)
|
||||||
|
: SPACING_DEFAULT;
|
||||||
|
|
||||||
|
if( buttonsSpacing == oldButtonsSpacing )
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
WindowData* windowData = getWindowData( nsWindow, true );
|
||||||
|
|
||||||
|
[FlatJNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
|
||||||
|
// NSLog( @"\n%@\n\n", [nsWindow.contentView.superview _subtreeDescription] );
|
||||||
|
|
||||||
|
// add/remove toolbar
|
||||||
|
NSToolbar* toolbar = NULL;
|
||||||
|
bool needsToolbar = (buttonsSpacing != SPACING_DEFAULT);
|
||||||
|
if( needsToolbar ) {
|
||||||
|
toolbar = [NSToolbar new];
|
||||||
|
toolbar.showsBaselineSeparator = NO; // necessary for older macOS versions
|
||||||
|
if( isWindowFullScreen( nsWindow ) )
|
||||||
|
toolbar.visible = NO;
|
||||||
|
}
|
||||||
|
nsWindow.toolbar = toolbar;
|
||||||
|
|
||||||
|
if( isMacOS_11_orLater ) {
|
||||||
|
nsWindow.toolbarStyle = (buttonsSpacing == SPACING_LARGE)
|
||||||
|
? NSWindowToolbarStyleUnified
|
||||||
|
: (buttonsSpacing == SPACING_MEDIUM)
|
||||||
|
? NSWindowToolbarStyleUnifiedCompact
|
||||||
|
: NSWindowToolbarStyleAutomatic;
|
||||||
|
}
|
||||||
|
|
||||||
|
windowData.lastWindowButtonAreaWidth = 0;
|
||||||
|
windowData.lastWindowTitleBarHeight = 0;
|
||||||
|
|
||||||
|
// NSLog( @"\n%@\n\n", [nsWindow.contentView.superview _subtreeDescription] );
|
||||||
|
|
||||||
|
// when window becomes full screen, it is necessary to hide the toolbar
|
||||||
|
// because it otherwise is shown non-transparent and hides Swing components
|
||||||
|
NSNotificationCenter* center = [NSNotificationCenter defaultCenter];
|
||||||
|
if( needsToolbar && windowData.willEnterFullScreenObserver == NULL ) {
|
||||||
|
// NSLog( @"add observers %@", nsWindow );
|
||||||
|
windowData.willEnterFullScreenObserver = [center addObserverForName:NSWindowWillEnterFullScreenNotification
|
||||||
|
object:nsWindow queue:nil usingBlock:^(NSNotification *note) {
|
||||||
|
// NSLog( @"enter full screen %@", nsWindow );
|
||||||
|
if( nsWindow.toolbar != NULL ) {
|
||||||
|
// remember button area width, which is used later when window exits full screen
|
||||||
|
// remembar title bar height so that "main" JToolBar keeps its height in full screen
|
||||||
|
windowData.lastWindowButtonAreaWidth = getWindowButtonAreaWidth( nsWindow );
|
||||||
|
windowData.lastWindowTitleBarHeight = getWindowTitleBarHeight( nsWindow );
|
||||||
|
// NSLog( @"%d %d", windowData.lastWindowButtonAreaWidth, windowData.lastWindowTitleBarHeight );
|
||||||
|
|
||||||
|
nsWindow.toolbar.visible = NO;
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
|
||||||
|
windowData.willExitFullScreenObserver = [center addObserverForName:NSWindowWillExitFullScreenNotification
|
||||||
|
object:nsWindow queue:nil usingBlock:^(NSNotification *note) {
|
||||||
|
// NSLog( @"will exit full screen %@", nsWindow );
|
||||||
|
if( nsWindow.toolbar != NULL )
|
||||||
|
setWindowButtonsHidden( nsWindow, true );
|
||||||
|
}];
|
||||||
|
|
||||||
|
windowData.didExitFullScreenObserver = [center addObserverForName:NSWindowDidExitFullScreenNotification
|
||||||
|
object:nsWindow queue:nil usingBlock:^(NSNotification *note) {
|
||||||
|
// NSLog( @"exit full screen %@", nsWindow );
|
||||||
|
if( nsWindow.toolbar != NULL ) {
|
||||||
|
setWindowButtonsHidden( nsWindow, false );
|
||||||
|
nsWindow.toolbar.visible = YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
windowData.lastWindowButtonAreaWidth = 0;
|
||||||
|
windowData.lastWindowTitleBarHeight = 0;
|
||||||
|
}];
|
||||||
|
} else if( !needsToolbar ) {
|
||||||
|
// NSLog( @"remove observers %@", nsWindow );
|
||||||
|
if( windowData.willEnterFullScreenObserver != NULL ) {
|
||||||
|
[center removeObserver:windowData.willEnterFullScreenObserver];
|
||||||
|
windowData.willEnterFullScreenObserver = nil;
|
||||||
|
}
|
||||||
|
if( windowData.willExitFullScreenObserver != NULL ) {
|
||||||
|
[center removeObserver:windowData.willExitFullScreenObserver];
|
||||||
|
windowData.willExitFullScreenObserver = nil;
|
||||||
|
}
|
||||||
|
if( windowData.didExitFullScreenObserver != NULL ) {
|
||||||
|
[center removeObserver:windowData.didExitFullScreenObserver];
|
||||||
|
windowData.didExitFullScreenObserver = nil;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
JNI_COCOA_EXIT()
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setWindowButtonsHidden( NSWindow* nsWindow, bool hidden ) {
|
||||||
|
// get buttons
|
||||||
|
NSView* buttons[3] = {
|
||||||
|
[nsWindow standardWindowButton:NSWindowCloseButton],
|
||||||
|
[nsWindow standardWindowButton:NSWindowMiniaturizeButton],
|
||||||
|
[nsWindow standardWindowButton:NSWindowZoomButton]
|
||||||
|
};
|
||||||
|
|
||||||
|
for( int i = 0; i < 3; i++ ) {
|
||||||
|
NSView* button = buttons[i];
|
||||||
|
if( button != NULL )
|
||||||
|
button.hidden = hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
JNIEXPORT jobject JNICALL Java_com_formdev_flatlaf_ui_FlatNativeMacLibrary_getWindowButtonsBounds
|
||||||
|
( JNIEnv* env, jclass cls, jobject window )
|
||||||
|
{
|
||||||
|
JNI_COCOA_ENTER()
|
||||||
|
|
||||||
|
NSWindow* nsWindow = getNSWindow( env, cls, window );
|
||||||
|
if( nsWindow == NULL )
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
WindowData* windowData = getWindowData( nsWindow, false );
|
||||||
|
int width = 0;
|
||||||
|
int height = 0;
|
||||||
|
|
||||||
|
// get width
|
||||||
|
if( isWindowFullScreen( nsWindow ) ) {
|
||||||
|
// use zero if window is full screen because close/minimize/zoom buttons are hidden
|
||||||
|
width = 0;
|
||||||
|
} else if( windowData != NULL && windowData.lastWindowButtonAreaWidth > 0 ) {
|
||||||
|
// use remembered value if window is in transition from full screen to non-full screen
|
||||||
|
// because NSToolbar is not yet visible
|
||||||
|
width = windowData.lastWindowButtonAreaWidth;
|
||||||
|
} else
|
||||||
|
width = getWindowButtonAreaWidth( nsWindow );
|
||||||
|
|
||||||
|
// get height
|
||||||
|
if( windowData != NULL && windowData.lastWindowTitleBarHeight > 0 ) {
|
||||||
|
// use remembered value if window is full screen because NSToolbar is hidden
|
||||||
|
height = windowData.lastWindowTitleBarHeight;
|
||||||
|
} else
|
||||||
|
height = getWindowTitleBarHeight( nsWindow );
|
||||||
|
|
||||||
|
// initialize class and method ID (done only once because variables are static)
|
||||||
|
static jclass cls = findClass( env, "java/awt/Rectangle", true );
|
||||||
|
static jmethodID methodID = getMethodID( env, cls, "<init>", "(IIII)V", false );
|
||||||
|
if( cls == NULL || methodID == NULL )
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// create and return Rectangle
|
||||||
|
return env->NewObject( cls, methodID, 0, 0, width, height );
|
||||||
|
|
||||||
|
JNI_COCOA_EXIT()
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getWindowButtonAreaWidth( NSWindow* nsWindow ) {
|
||||||
|
// get buttons
|
||||||
|
NSView* buttons[3] = {
|
||||||
|
[nsWindow standardWindowButton:NSWindowCloseButton],
|
||||||
|
[nsWindow standardWindowButton:NSWindowMiniaturizeButton],
|
||||||
|
[nsWindow standardWindowButton:NSWindowZoomButton]
|
||||||
|
};
|
||||||
|
|
||||||
|
// get most left and right coordinates
|
||||||
|
int left = -1;
|
||||||
|
int right = -1;
|
||||||
|
for( int i = 0; i < 3; i++ ) {
|
||||||
|
NSView* button = buttons[i];
|
||||||
|
if( button == NULL )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
int x = [button convertRect: [button bounds] toView:button.superview].origin.x;
|
||||||
|
int width = button.bounds.size.width;
|
||||||
|
if( left == -1 || x < left )
|
||||||
|
left = x;
|
||||||
|
if( right == -1 || x + width > right )
|
||||||
|
right = x + width;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( left == -1 || right == -1 )
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
// 'right' is the actual button area width (from left window edge)
|
||||||
|
// adding 'left' to add same empty space on right side as on left side
|
||||||
|
return right + left;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getWindowTitleBarHeight( NSWindow* nsWindow ) {
|
||||||
|
NSView* closeButton = [nsWindow standardWindowButton:NSWindowCloseButton];
|
||||||
|
if( closeButton == NULL )
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
NSView* titlebar = closeButton.superview;
|
||||||
|
return titlebar.bounds.size.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
JNIEXPORT jboolean JNICALL Java_com_formdev_flatlaf_ui_FlatNativeMacLibrary_isWindowFullScreen
|
||||||
|
( JNIEnv* env, jclass cls, jobject window )
|
||||||
|
{
|
||||||
|
JNI_COCOA_ENTER()
|
||||||
|
|
||||||
|
NSWindow* nsWindow = getNSWindow( env, cls, window );
|
||||||
|
if( nsWindow == NULL )
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
return (jboolean) isWindowFullScreen( nsWindow );
|
||||||
|
|
||||||
|
JNI_COCOA_EXIT()
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isWindowFullScreen( NSWindow* nsWindow ) {
|
||||||
|
return ((nsWindow.styleMask & NSWindowStyleMaskFullScreen) != 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
JNIEXPORT jboolean JNICALL Java_com_formdev_flatlaf_ui_FlatNativeMacLibrary_toggleWindowFullScreen
|
||||||
|
( JNIEnv* env, jclass cls, jobject window )
|
||||||
|
{
|
||||||
|
JNI_COCOA_ENTER()
|
||||||
|
|
||||||
|
NSWindow* nsWindow = getNSWindow( env, cls, window );
|
||||||
|
if( nsWindow == NULL )
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
[FlatJNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
|
||||||
|
[nsWindow toggleFullScreen:nil];
|
||||||
|
}];
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
JNI_COCOA_EXIT()
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|||||||
@@ -377,6 +377,7 @@ LRESULT FlatWndProc::WmNcCalcSize( HWND hwnd, int uMsg, WPARAM wParam, LPARAM lP
|
|||||||
// (using MONITOR_DEFAULTTONEAREST finds right monitor when restoring from minimized)
|
// (using MONITOR_DEFAULTTONEAREST finds right monitor when restoring from minimized)
|
||||||
HMONITOR hMonitor = ::MonitorFromWindow( hwnd, MONITOR_DEFAULTTONEAREST );
|
HMONITOR hMonitor = ::MonitorFromWindow( hwnd, MONITOR_DEFAULTTONEAREST );
|
||||||
MONITORINFO monitorInfo{ 0 };
|
MONITORINFO monitorInfo{ 0 };
|
||||||
|
monitorInfo.cbSize = sizeof( monitorInfo );
|
||||||
::GetMonitorInfo( hMonitor, &monitorInfo );
|
::GetMonitorInfo( hMonitor, &monitorInfo );
|
||||||
|
|
||||||
// If there's a taskbar on any side of the monitor, reduce our size
|
// If there's a taskbar on any side of the monitor, reduce our size
|
||||||
@@ -537,7 +538,6 @@ void FlatWndProc::setMenuItemState( HMENU systemMenu, int item, bool enabled ) {
|
|||||||
MENUITEMINFO mii{ 0 };
|
MENUITEMINFO mii{ 0 };
|
||||||
mii.cbSize = sizeof( mii );
|
mii.cbSize = sizeof( mii );
|
||||||
mii.fMask = MIIM_STATE;
|
mii.fMask = MIIM_STATE;
|
||||||
mii.fType = MFT_STRING;
|
|
||||||
mii.fState = enabled ? MF_ENABLED : MF_DISABLED;
|
mii.fState = enabled ? MF_ENABLED : MF_DISABLED;
|
||||||
::SetMenuItemInfo( systemMenu, item, FALSE, &mii );
|
::SetMenuItemInfo( systemMenu, item, FALSE, &mii );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,6 +41,8 @@ dependencies {
|
|||||||
implementation( libs.jide.oss )
|
implementation( libs.jide.oss )
|
||||||
implementation( libs.glazedlists )
|
implementation( libs.glazedlists )
|
||||||
implementation( libs.netbeans.api.awt )
|
implementation( libs.netbeans.api.awt )
|
||||||
|
|
||||||
|
components.all<TargetJvmVersion8Rule>()
|
||||||
}
|
}
|
||||||
|
|
||||||
applyLafs()
|
applyLafs()
|
||||||
@@ -58,3 +60,13 @@ fun applyLafs() {
|
|||||||
dependencies.implementation( parts[2] )
|
dependencies.implementation( parts[2] )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// rule that overrides 'org.gradle.jvm.version' with '8'
|
||||||
|
// (required for Radiance, which requires Java 9, but FlatLaf build uses Java 8)
|
||||||
|
abstract class TargetJvmVersion8Rule : ComponentMetadataRule {
|
||||||
|
override fun execute( context: ComponentMetadataContext ) {
|
||||||
|
context.details.allVariants {
|
||||||
|
attributes.attribute( TargetJvmVersion.TARGET_JVM_VERSION_ATTRIBUTE, 8 )
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1111,6 +1111,7 @@ Table.dropCellBackground [lazy] #3c588b HSL 219 40 39 javax.swing.pl
|
|||||||
Table.dropCellForeground [lazy] #bbbbbb HSL 0 0 73 javax.swing.plaf.ColorUIResource [UI]
|
Table.dropCellForeground [lazy] #bbbbbb HSL 0 0 73 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Table.dropLineColor [lazy] #6d8ac0 HSL 219 40 59 javax.swing.plaf.ColorUIResource [UI]
|
Table.dropLineColor [lazy] #6d8ac0 HSL 219 40 59 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Table.dropLineShortColor [lazy] #b4c3df HSL 219 40 79 javax.swing.plaf.ColorUIResource [UI]
|
Table.dropLineShortColor [lazy] #b4c3df HSL 219 40 79 javax.swing.plaf.ColorUIResource [UI]
|
||||||
|
Table.editorSelectAllOnStartEditing true
|
||||||
Table.focusCellBackground #46494b HSL 204 3 28 javax.swing.plaf.ColorUIResource [UI]
|
Table.focusCellBackground #46494b HSL 204 3 28 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Table.focusCellForeground #bbbbbb HSL 0 0 73 javax.swing.plaf.ColorUIResource [UI]
|
Table.focusCellForeground #bbbbbb HSL 0 0 73 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Table.focusCellHighlightBorder [lazy] 2,3,2,3 false com.formdev.flatlaf.ui.FlatTableCellBorder$Focused [UI] lineColor=#6d8ac0 HSL 219 40 59 javax.swing.plaf.ColorUIResource [UI] lineThickness=1.000000
|
Table.focusCellHighlightBorder [lazy] 2,3,2,3 false com.formdev.flatlaf.ui.FlatTableCellBorder$Focused [UI] lineColor=#6d8ac0 HSL 219 40 59 javax.swing.plaf.ColorUIResource [UI] lineThickness=1.000000
|
||||||
@@ -1119,6 +1120,7 @@ Table.font [active] $defaultFont [UI]
|
|||||||
Table.foreground #bbbbbb HSL 0 0 73 javax.swing.plaf.ColorUIResource [UI]
|
Table.foreground #bbbbbb HSL 0 0 73 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Table.gridColor #5a5e60 HSL 200 3 36 javax.swing.plaf.ColorUIResource [UI]
|
Table.gridColor #5a5e60 HSL 200 3 36 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Table.intercellSpacing 0,0 javax.swing.plaf.DimensionUIResource [UI]
|
Table.intercellSpacing 0,0 javax.swing.plaf.DimensionUIResource [UI]
|
||||||
|
Table.paintOutsideAlternateRows false
|
||||||
Table.rowHeight 20
|
Table.rowHeight 20
|
||||||
Table.scrollPaneBorder [lazy] 1,1,1,1 false com.formdev.flatlaf.ui.FlatScrollPaneBorder [UI]
|
Table.scrollPaneBorder [lazy] 1,1,1,1 false com.formdev.flatlaf.ui.FlatScrollPaneBorder [UI]
|
||||||
Table.selectionBackground #4b6eaf HSL 219 40 49 javax.swing.plaf.ColorUIResource [UI]
|
Table.selectionBackground #4b6eaf HSL 219 40 49 javax.swing.plaf.ColorUIResource [UI]
|
||||||
@@ -1264,7 +1266,6 @@ TitlePane.inactiveBackground #303234 HSL 210 4 20 javax.swing.plaf.Colo
|
|||||||
TitlePane.inactiveForeground #8c8c8c HSL 0 0 55 javax.swing.plaf.ColorUIResource [UI]
|
TitlePane.inactiveForeground #8c8c8c HSL 0 0 55 javax.swing.plaf.ColorUIResource [UI]
|
||||||
TitlePane.maximizeIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowMaximizeIcon [UI]
|
TitlePane.maximizeIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowMaximizeIcon [UI]
|
||||||
TitlePane.menuBarEmbedded true
|
TitlePane.menuBarEmbedded true
|
||||||
TitlePane.menuBarResizeHeight 4
|
|
||||||
TitlePane.menuBarTitleGap 40
|
TitlePane.menuBarTitleGap 40
|
||||||
TitlePane.menuBarTitleMinimumGap 12
|
TitlePane.menuBarTitleMinimumGap 12
|
||||||
TitlePane.noIconLeftGap 8
|
TitlePane.noIconLeftGap 8
|
||||||
|
|||||||
@@ -1116,6 +1116,7 @@ Table.dropCellBackground [lazy] #3f8fd9 HSL 209 67 55 javax.swing.pl
|
|||||||
Table.dropCellForeground [lazy] #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI]
|
Table.dropCellForeground [lazy] #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Table.dropLineColor [lazy] #6aa7e1 HSL 209 66 65 javax.swing.plaf.ColorUIResource [UI]
|
Table.dropLineColor [lazy] #6aa7e1 HSL 209 66 65 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Table.dropLineShortColor [lazy] #15416a HSL 209 67 25 javax.swing.plaf.ColorUIResource [UI]
|
Table.dropLineShortColor [lazy] #15416a HSL 209 67 25 javax.swing.plaf.ColorUIResource [UI]
|
||||||
|
Table.editorSelectAllOnStartEditing true
|
||||||
Table.focusCellBackground #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI]
|
Table.focusCellBackground #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Table.focusCellForeground #000000 HSL 0 0 0 javax.swing.plaf.ColorUIResource [UI]
|
Table.focusCellForeground #000000 HSL 0 0 0 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Table.focusCellHighlightBorder [lazy] 2,3,2,3 false com.formdev.flatlaf.ui.FlatTableCellBorder$Focused [UI] lineColor=#15416a HSL 209 67 25 javax.swing.plaf.ColorUIResource [UI] lineThickness=1.000000
|
Table.focusCellHighlightBorder [lazy] 2,3,2,3 false com.formdev.flatlaf.ui.FlatTableCellBorder$Focused [UI] lineColor=#15416a HSL 209 67 25 javax.swing.plaf.ColorUIResource [UI] lineThickness=1.000000
|
||||||
@@ -1124,6 +1125,7 @@ Table.font [active] $defaultFont [UI]
|
|||||||
Table.foreground #000000 HSL 0 0 0 javax.swing.plaf.ColorUIResource [UI]
|
Table.foreground #000000 HSL 0 0 0 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Table.gridColor #ebebeb HSL 0 0 92 javax.swing.plaf.ColorUIResource [UI]
|
Table.gridColor #ebebeb HSL 0 0 92 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Table.intercellSpacing 0,0 javax.swing.plaf.DimensionUIResource [UI]
|
Table.intercellSpacing 0,0 javax.swing.plaf.DimensionUIResource [UI]
|
||||||
|
Table.paintOutsideAlternateRows false
|
||||||
Table.rowHeight 20
|
Table.rowHeight 20
|
||||||
Table.scrollPaneBorder [lazy] 1,1,1,1 false com.formdev.flatlaf.ui.FlatScrollPaneBorder [UI]
|
Table.scrollPaneBorder [lazy] 1,1,1,1 false com.formdev.flatlaf.ui.FlatScrollPaneBorder [UI]
|
||||||
Table.selectionBackground #2675bf HSL 209 67 45 javax.swing.plaf.ColorUIResource [UI]
|
Table.selectionBackground #2675bf HSL 209 67 45 javax.swing.plaf.ColorUIResource [UI]
|
||||||
@@ -1269,7 +1271,6 @@ TitlePane.inactiveBackground #ffffff HSL 0 0 100 javax.swing.plaf.Colo
|
|||||||
TitlePane.inactiveForeground #8c8c8c HSL 0 0 55 javax.swing.plaf.ColorUIResource [UI]
|
TitlePane.inactiveForeground #8c8c8c HSL 0 0 55 javax.swing.plaf.ColorUIResource [UI]
|
||||||
TitlePane.maximizeIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowMaximizeIcon [UI]
|
TitlePane.maximizeIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowMaximizeIcon [UI]
|
||||||
TitlePane.menuBarEmbedded true
|
TitlePane.menuBarEmbedded true
|
||||||
TitlePane.menuBarResizeHeight 4
|
|
||||||
TitlePane.menuBarTitleGap 40
|
TitlePane.menuBarTitleGap 40
|
||||||
TitlePane.menuBarTitleMinimumGap 12
|
TitlePane.menuBarTitleMinimumGap 12
|
||||||
TitlePane.noIconLeftGap 8
|
TitlePane.noIconLeftGap 8
|
||||||
|
|||||||
@@ -322,7 +322,7 @@ OS Windows 10
|
|||||||
#---- javax.swing.JMenuBar ----
|
#---- javax.swing.JMenuBar ----
|
||||||
|
|
||||||
1 javax.swing.plaf.basic.LazyActionMap [UI]
|
1 javax.swing.plaf.basic.LazyActionMap [UI]
|
||||||
takeFocus com.formdev.flatlaf.ui.FlatMenuBarUI$TakeFocus (null)
|
takeFocus com.formdev.flatlaf.ui.FlatMenuBarUI$TakeFocusAction
|
||||||
|
|
||||||
|
|
||||||
#---- javax.swing.JMenuItem ----
|
#---- javax.swing.JMenuItem ----
|
||||||
@@ -613,7 +613,7 @@ OS Windows 10
|
|||||||
selectPreviousRowCell javax.swing.plaf.basic.BasicTableUI$Actions
|
selectPreviousRowCell javax.swing.plaf.basic.BasicTableUI$Actions
|
||||||
selectPreviousRowChangeLead javax.swing.plaf.basic.BasicTableUI$Actions
|
selectPreviousRowChangeLead javax.swing.plaf.basic.BasicTableUI$Actions
|
||||||
selectPreviousRowExtendSelection javax.swing.plaf.basic.BasicTableUI$Actions
|
selectPreviousRowExtendSelection javax.swing.plaf.basic.BasicTableUI$Actions
|
||||||
startEditing javax.swing.plaf.basic.BasicTableUI$Actions
|
startEditing com.formdev.flatlaf.ui.FlatTableUI$StartEditingAction
|
||||||
toggleAndAnchor javax.swing.plaf.basic.BasicTableUI$Actions
|
toggleAndAnchor javax.swing.plaf.basic.BasicTableUI$Actions
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1121,6 +1121,7 @@ Table.dropCellBackground [lazy] #003f99 HSL 215 100 30 javax.swing.pl
|
|||||||
Table.dropCellForeground [lazy] #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI]
|
Table.dropCellForeground [lazy] #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Table.dropLineColor [lazy] #0069ff HSL 215 100 50 javax.swing.plaf.ColorUIResource [UI]
|
Table.dropLineColor [lazy] #0069ff HSL 215 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Table.dropLineShortColor [lazy] #66a5ff HSL 215 100 70 javax.swing.plaf.ColorUIResource [UI]
|
Table.dropLineShortColor [lazy] #66a5ff HSL 215 100 70 javax.swing.plaf.ColorUIResource [UI]
|
||||||
|
Table.editorSelectAllOnStartEditing true
|
||||||
Table.focusCellBackground #282828 HSL 0 0 16 javax.swing.plaf.ColorUIResource [UI]
|
Table.focusCellBackground #282828 HSL 0 0 16 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Table.focusCellForeground #dddddd HSL 0 0 87 javax.swing.plaf.ColorUIResource [UI]
|
Table.focusCellForeground #dddddd HSL 0 0 87 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Table.focusCellHighlightBorder [lazy] 2,3,2,3 false com.formdev.flatlaf.ui.FlatTableCellBorder$Focused [UI] lineColor=#0069ff HSL 215 100 50 javax.swing.plaf.ColorUIResource [UI] lineThickness=1.000000
|
Table.focusCellHighlightBorder [lazy] 2,3,2,3 false com.formdev.flatlaf.ui.FlatTableCellBorder$Focused [UI] lineColor=#0069ff HSL 215 100 50 javax.swing.plaf.ColorUIResource [UI] lineThickness=1.000000
|
||||||
@@ -1129,6 +1130,7 @@ Table.font [active] $defaultFont [UI]
|
|||||||
Table.foreground #dddddd HSL 0 0 87 javax.swing.plaf.ColorUIResource [UI]
|
Table.foreground #dddddd HSL 0 0 87 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Table.gridColor #3c3c3c HSL 0 0 24 javax.swing.plaf.ColorUIResource [UI]
|
Table.gridColor #3c3c3c HSL 0 0 24 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Table.intercellSpacing 0,0 javax.swing.plaf.DimensionUIResource [UI]
|
Table.intercellSpacing 0,0 javax.swing.plaf.DimensionUIResource [UI]
|
||||||
|
Table.paintOutsideAlternateRows false
|
||||||
Table.rowHeight 20
|
Table.rowHeight 20
|
||||||
Table.scrollPaneBorder [lazy] 3,3,3,3 false com.formdev.flatlaf.ui.FlatScrollPaneBorder [UI]
|
Table.scrollPaneBorder [lazy] 3,3,3,3 false com.formdev.flatlaf.ui.FlatScrollPaneBorder [UI]
|
||||||
Table.selectionBackground #0054cc HSL 215 100 40 javax.swing.plaf.ColorUIResource [UI]
|
Table.selectionBackground #0054cc HSL 215 100 40 javax.swing.plaf.ColorUIResource [UI]
|
||||||
@@ -1274,7 +1276,6 @@ TitlePane.inactiveBackground #323232 HSL 0 0 20 javax.swing.plaf.Colo
|
|||||||
TitlePane.inactiveForeground #9a9a9a HSL 0 0 60 javax.swing.plaf.ColorUIResource [UI]
|
TitlePane.inactiveForeground #9a9a9a HSL 0 0 60 javax.swing.plaf.ColorUIResource [UI]
|
||||||
TitlePane.maximizeIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowMaximizeIcon [UI]
|
TitlePane.maximizeIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowMaximizeIcon [UI]
|
||||||
TitlePane.menuBarEmbedded true
|
TitlePane.menuBarEmbedded true
|
||||||
TitlePane.menuBarResizeHeight 4
|
|
||||||
TitlePane.menuBarTitleGap 40
|
TitlePane.menuBarTitleGap 40
|
||||||
TitlePane.menuBarTitleMinimumGap 12
|
TitlePane.menuBarTitleMinimumGap 12
|
||||||
TitlePane.noIconLeftGap 8
|
TitlePane.noIconLeftGap 8
|
||||||
|
|||||||
@@ -1125,6 +1125,7 @@ Table.dropCellBackground [lazy] #1a79ff HSL 215 100 55 javax.swing.pl
|
|||||||
Table.dropCellForeground [lazy] #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI]
|
Table.dropCellForeground [lazy] #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Table.dropLineColor [lazy] #4d97ff HSL 215 100 65 javax.swing.plaf.ColorUIResource [UI]
|
Table.dropLineColor [lazy] #4d97ff HSL 215 100 65 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Table.dropLineShortColor [lazy] #003580 HSL 215 100 25 javax.swing.plaf.ColorUIResource [UI]
|
Table.dropLineShortColor [lazy] #003580 HSL 215 100 25 javax.swing.plaf.ColorUIResource [UI]
|
||||||
|
Table.editorSelectAllOnStartEditing true
|
||||||
Table.focusCellBackground #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI]
|
Table.focusCellBackground #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Table.focusCellForeground #262626 HSL 0 0 15 javax.swing.plaf.ColorUIResource [UI]
|
Table.focusCellForeground #262626 HSL 0 0 15 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Table.focusCellHighlightBorder [lazy] 2,3,2,3 false com.formdev.flatlaf.ui.FlatTableCellBorder$Focused [UI] lineColor=#003580 HSL 215 100 25 javax.swing.plaf.ColorUIResource [UI] lineThickness=1.000000
|
Table.focusCellHighlightBorder [lazy] 2,3,2,3 false com.formdev.flatlaf.ui.FlatTableCellBorder$Focused [UI] lineColor=#003580 HSL 215 100 25 javax.swing.plaf.ColorUIResource [UI] lineThickness=1.000000
|
||||||
@@ -1133,6 +1134,7 @@ Table.font [active] $defaultFont [UI]
|
|||||||
Table.foreground #262626 HSL 0 0 15 javax.swing.plaf.ColorUIResource [UI]
|
Table.foreground #262626 HSL 0 0 15 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Table.gridColor #ebebeb HSL 0 0 92 javax.swing.plaf.ColorUIResource [UI]
|
Table.gridColor #ebebeb HSL 0 0 92 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Table.intercellSpacing 0,0 javax.swing.plaf.DimensionUIResource [UI]
|
Table.intercellSpacing 0,0 javax.swing.plaf.DimensionUIResource [UI]
|
||||||
|
Table.paintOutsideAlternateRows false
|
||||||
Table.rowHeight 20
|
Table.rowHeight 20
|
||||||
Table.scrollPaneBorder [lazy] 3,3,3,3 false com.formdev.flatlaf.ui.FlatScrollPaneBorder [UI]
|
Table.scrollPaneBorder [lazy] 3,3,3,3 false com.formdev.flatlaf.ui.FlatScrollPaneBorder [UI]
|
||||||
Table.selectionBackground #005fe6 HSL 215 100 45 javax.swing.plaf.ColorUIResource [UI]
|
Table.selectionBackground #005fe6 HSL 215 100 45 javax.swing.plaf.ColorUIResource [UI]
|
||||||
@@ -1278,7 +1280,6 @@ TitlePane.inactiveBackground #ececec HSL 0 0 93 javax.swing.plaf.Colo
|
|||||||
TitlePane.inactiveForeground #b6b6b6 HSL 0 0 71 javax.swing.plaf.ColorUIResource [UI]
|
TitlePane.inactiveForeground #b6b6b6 HSL 0 0 71 javax.swing.plaf.ColorUIResource [UI]
|
||||||
TitlePane.maximizeIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowMaximizeIcon [UI]
|
TitlePane.maximizeIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowMaximizeIcon [UI]
|
||||||
TitlePane.menuBarEmbedded true
|
TitlePane.menuBarEmbedded true
|
||||||
TitlePane.menuBarResizeHeight 4
|
|
||||||
TitlePane.menuBarTitleGap 40
|
TitlePane.menuBarTitleGap 40
|
||||||
TitlePane.menuBarTitleMinimumGap 12
|
TitlePane.menuBarTitleMinimumGap 12
|
||||||
TitlePane.noIconLeftGap 8
|
TitlePane.noIconLeftGap 8
|
||||||
|
|||||||
@@ -1149,6 +1149,7 @@ Table.dropCellBackground #ff0000 HSL 0 100 50 javax.swing.plaf.Colo
|
|||||||
Table.dropCellForeground #00ff00 HSL 120 100 50 javax.swing.plaf.ColorUIResource [UI]
|
Table.dropCellForeground #00ff00 HSL 120 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Table.dropLineColor #0000ff HSL 240 100 50 javax.swing.plaf.ColorUIResource [UI]
|
Table.dropLineColor #0000ff HSL 240 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Table.dropLineShortColor #ffff00 HSL 60 100 50 javax.swing.plaf.ColorUIResource [UI]
|
Table.dropLineShortColor #ffff00 HSL 60 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||||
|
Table.editorSelectAllOnStartEditing true
|
||||||
Table.focusCellBackground #fffff0 HSL 60 100 97 javax.swing.plaf.ColorUIResource [UI]
|
Table.focusCellBackground #fffff0 HSL 60 100 97 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Table.focusCellForeground #ff0000 HSL 0 100 50 javax.swing.plaf.ColorUIResource [UI]
|
Table.focusCellForeground #ff0000 HSL 0 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Table.focusCellHighlightBorder [lazy] 2,3,2,3 false com.formdev.flatlaf.ui.FlatTableCellBorder$Focused [UI] lineColor=#ff0000 HSL 0 100 50 javax.swing.plaf.ColorUIResource [UI] lineThickness=1.000000
|
Table.focusCellHighlightBorder [lazy] 2,3,2,3 false com.formdev.flatlaf.ui.FlatTableCellBorder$Focused [UI] lineColor=#ff0000 HSL 0 100 50 javax.swing.plaf.ColorUIResource [UI] lineThickness=1.000000
|
||||||
@@ -1157,6 +1158,7 @@ Table.font [active] $defaultFont [UI]
|
|||||||
Table.foreground #ff0000 HSL 0 100 50 javax.swing.plaf.ColorUIResource [UI]
|
Table.foreground #ff0000 HSL 0 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Table.gridColor #00ffff HSL 180 100 50 javax.swing.plaf.ColorUIResource [UI]
|
Table.gridColor #00ffff HSL 180 100 50 javax.swing.plaf.ColorUIResource [UI]
|
||||||
Table.intercellSpacing 0,0 javax.swing.plaf.DimensionUIResource [UI]
|
Table.intercellSpacing 0,0 javax.swing.plaf.DimensionUIResource [UI]
|
||||||
|
Table.paintOutsideAlternateRows false
|
||||||
Table.rowHeight 25
|
Table.rowHeight 25
|
||||||
Table.scrollPaneBorder [lazy] 1,9,1,9 false com.formdev.flatlaf.ui.FlatScrollPaneBorder [UI]
|
Table.scrollPaneBorder [lazy] 1,9,1,9 false com.formdev.flatlaf.ui.FlatScrollPaneBorder [UI]
|
||||||
Table.selectionBackground #00aa00 HSL 120 100 33 javax.swing.plaf.ColorUIResource [UI]
|
Table.selectionBackground #00aa00 HSL 120 100 33 javax.swing.plaf.ColorUIResource [UI]
|
||||||
@@ -1305,7 +1307,6 @@ TitlePane.inactiveBackground #008800 HSL 120 100 27 javax.swing.plaf.Colo
|
|||||||
TitlePane.inactiveForeground #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI]
|
TitlePane.inactiveForeground #ffffff HSL 0 0 100 javax.swing.plaf.ColorUIResource [UI]
|
||||||
TitlePane.maximizeIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowMaximizeIcon [UI]
|
TitlePane.maximizeIcon [lazy] 44,30 com.formdev.flatlaf.icons.FlatWindowMaximizeIcon [UI]
|
||||||
TitlePane.menuBarEmbedded true
|
TitlePane.menuBarEmbedded true
|
||||||
TitlePane.menuBarResizeHeight 4
|
|
||||||
TitlePane.menuBarTitleGap 40
|
TitlePane.menuBarTitleGap 40
|
||||||
TitlePane.menuBarTitleMinimumGap 12
|
TitlePane.menuBarTitleMinimumGap 12
|
||||||
TitlePane.noIconLeftGap 8
|
TitlePane.noIconLeftGap 8
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
org.pushingpixels.substance.api.skin.SubstanceBusinessLookAndFeel = Substance Business;ctrl F5;org.pushing-pixels:radiance-substance:3.5.1
|
org.pushingpixels.radiance.theming.api.skin.RadianceBusinessLookAndFeel = Radiance Business;ctrl F5;org.pushing-pixels:radiance-theming:7.0.1
|
||||||
org.pushingpixels.substance.api.skin.SubstanceGraphiteAquaLookAndFeel = Substance Graphite Aqua;ctrl F6
|
org.pushingpixels.radiance.theming.api.skin.RadianceGraphiteAquaLookAndFeel = Radiance Graphite Aqua;ctrl F6
|
||||||
com.alee.laf.WebLookAndFeel = WebLaf;ctrl F11;com.weblookandfeel:weblaf-ui:1.2.13
|
com.alee.laf.WebLookAndFeel = WebLaf;ctrl F11;com.weblookandfeel:weblaf-ui:1.2.14
|
||||||
com.jgoodies.looks.plastic.PlasticLookAndFeel = JGoodies Looks Plastic;ctrl F12;com.jgoodies:jgoodies-looks:2.7.0
|
com.jgoodies.looks.plastic.PlasticLookAndFeel = JGoodies Looks Plastic;ctrl F12;com.jgoodies:jgoodies-looks:2.7.0
|
||||||
com.jgoodies.looks.windows.WindowsLookAndFeel = JGoodies Looks Windows;ctrl F9
|
com.jgoodies.looks.windows.WindowsLookAndFeel = JGoodies Looks Windows;ctrl F9
|
||||||
|
mdlaf.MaterialLookAndFeel = Material-UI-Swing;shift F11;io.github.vincenzopalazzo:material-ui-swing:1.1.4
|
||||||
|
com.github.weisj.darklaf.DarkLaf = DarkLaf;shift F12;com.github.weisj:darklaf-core:3.0.2
|
||||||
|
com.github.weisj.darklaf.theme.laf.DarculaThemeDarklafLookAndFeel = DarkLaf Darcula;ctrl shift F12
|
||||||
|
com.jtattoo.plaf.smart.SmartLookAndFeel = JTattoo;ctrl shift F11;com.jtattoo:JTattoo:1.6.13
|
||||||
|
|||||||
@@ -1,221 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 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
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.formdev.flatlaf.testing;
|
|
||||||
|
|
||||||
import java.awt.*;
|
|
||||||
import java.io.File;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.function.Function;
|
|
||||||
import javax.swing.*;
|
|
||||||
import javax.swing.border.*;
|
|
||||||
import com.formdev.flatlaf.icons.FlatFileChooserHomeFolderIcon;
|
|
||||||
import net.miginfocom.swing.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Karl Tauber
|
|
||||||
*/
|
|
||||||
public class FlatChooserTest
|
|
||||||
extends FlatTestPanel
|
|
||||||
{
|
|
||||||
public static void main( String[] args ) {
|
|
||||||
// Locale.setDefault( Locale.FRENCH );
|
|
||||||
// Locale.setDefault( Locale.GERMAN );
|
|
||||||
// Locale.setDefault( Locale.ITALIAN );
|
|
||||||
// Locale.setDefault( Locale.JAPANESE );
|
|
||||||
// Locale.setDefault( Locale.SIMPLIFIED_CHINESE );
|
|
||||||
// Locale.setDefault( Locale.TRADITIONAL_CHINESE );
|
|
||||||
|
|
||||||
SwingUtilities.invokeLater( () -> {
|
|
||||||
FlatTestFrame frame = FlatTestFrame.create( args, "FlatChooserTest" );
|
|
||||||
|
|
||||||
UIManager.put( "FileChooser.shortcuts.filesFunction", (Function<File[], File[]>) files -> {
|
|
||||||
ArrayList<File> list = new ArrayList<>( Arrays.asList( files ) );
|
|
||||||
list.add( 0, new File( System.getProperty( "user.home" ) ) );
|
|
||||||
return list.toArray( new File[list.size()] );
|
|
||||||
} );
|
|
||||||
|
|
||||||
UIManager.put( "FileChooser.shortcuts.displayNameFunction", (Function<File, String>) file -> {
|
|
||||||
if( file.getAbsolutePath().equals( System.getProperty( "user.home" ) ) )
|
|
||||||
return "Home";
|
|
||||||
return null;
|
|
||||||
} );
|
|
||||||
UIManager.put( "FileChooser.shortcuts.iconFunction", (Function<File, Icon>) file -> {
|
|
||||||
if( file.getAbsolutePath().equals( System.getProperty( "user.home" ) ) )
|
|
||||||
return new FlatFileChooserHomeFolderIcon();
|
|
||||||
return null;
|
|
||||||
} );
|
|
||||||
|
|
||||||
frame.showFrame( FlatChooserTest::new );
|
|
||||||
} );
|
|
||||||
}
|
|
||||||
|
|
||||||
FlatChooserTest() {
|
|
||||||
initComponents();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void showShortcuts() {
|
|
||||||
UIManager.put( "FileChooser.noPlacesBar", !showShortcutsCheckBox.isSelected() ? true : null );
|
|
||||||
fileChooser1.updateUI();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void showAccessory() {
|
|
||||||
JPanel accessory = null;
|
|
||||||
if( showAccessoryCheckBox.isSelected() ) {
|
|
||||||
accessory = new JPanel( new BorderLayout() );
|
|
||||||
accessory.setBackground( Color.green );
|
|
||||||
accessory.add( new JLabel( " Accessory " ), BorderLayout.CENTER );
|
|
||||||
}
|
|
||||||
fileChooser1.setAccessory( accessory );
|
|
||||||
fileChooser1.revalidate();
|
|
||||||
fileChooser1.repaint();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initComponents() {
|
|
||||||
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
|
|
||||||
JLabel colorChooserLabel = new JLabel();
|
|
||||||
JPanel panel2 = new JPanel();
|
|
||||||
JColorChooser colorChooser1 = new JColorChooser();
|
|
||||||
JLabel fileChooserLabel = new JLabel();
|
|
||||||
JPanel panel1 = new JPanel();
|
|
||||||
fileChooser1 = new JFileChooser();
|
|
||||||
JPanel panel3 = new JPanel();
|
|
||||||
showShortcutsCheckBox = new JCheckBox();
|
|
||||||
showAccessoryCheckBox = new JCheckBox();
|
|
||||||
JLabel label1 = new JLabel();
|
|
||||||
JLabel label2 = new JLabel();
|
|
||||||
JLabel label3 = new JLabel();
|
|
||||||
JLabel label4 = new JLabel();
|
|
||||||
JLabel label5 = new JLabel();
|
|
||||||
JLabel label6 = new JLabel();
|
|
||||||
JLabel label7 = new JLabel();
|
|
||||||
JLabel label8 = new JLabel();
|
|
||||||
JLabel label9 = new JLabel();
|
|
||||||
JLabel label10 = new JLabel();
|
|
||||||
JLabel label11 = new JLabel();
|
|
||||||
|
|
||||||
//======== this ========
|
|
||||||
setLayout(new MigLayout(
|
|
||||||
"ltr,insets dialog,hidemode 3",
|
|
||||||
// columns
|
|
||||||
"[]" +
|
|
||||||
"[grow]",
|
|
||||||
// rows
|
|
||||||
"[top]" +
|
|
||||||
"[grow,fill]" +
|
|
||||||
"[]" +
|
|
||||||
"[]"));
|
|
||||||
|
|
||||||
//---- colorChooserLabel ----
|
|
||||||
colorChooserLabel.setText("JColorChooser:");
|
|
||||||
add(colorChooserLabel, "cell 0 0");
|
|
||||||
|
|
||||||
//======== panel2 ========
|
|
||||||
{
|
|
||||||
panel2.setBorder(new MatteBorder(4, 4, 4, 4, Color.red));
|
|
||||||
panel2.setLayout(new BorderLayout());
|
|
||||||
panel2.add(colorChooser1, BorderLayout.CENTER);
|
|
||||||
}
|
|
||||||
add(panel2, "cell 1 0");
|
|
||||||
|
|
||||||
//---- fileChooserLabel ----
|
|
||||||
fileChooserLabel.setText("JFileChooser:");
|
|
||||||
add(fileChooserLabel, "cell 0 1,aligny top,growy 0");
|
|
||||||
|
|
||||||
//======== panel1 ========
|
|
||||||
{
|
|
||||||
panel1.setBorder(new MatteBorder(4, 4, 4, 4, Color.red));
|
|
||||||
panel1.setLayout(new BorderLayout());
|
|
||||||
panel1.add(fileChooser1, BorderLayout.CENTER);
|
|
||||||
}
|
|
||||||
add(panel1, "cell 1 1,growx");
|
|
||||||
|
|
||||||
//======== panel3 ========
|
|
||||||
{
|
|
||||||
panel3.setLayout(new MigLayout(
|
|
||||||
"hidemode 3",
|
|
||||||
// columns
|
|
||||||
"[fill]" +
|
|
||||||
"[fill]",
|
|
||||||
// rows
|
|
||||||
"[]"));
|
|
||||||
|
|
||||||
//---- showShortcutsCheckBox ----
|
|
||||||
showShortcutsCheckBox.setText("Show Shortcuts");
|
|
||||||
showShortcutsCheckBox.setSelected(true);
|
|
||||||
showShortcutsCheckBox.addActionListener(e -> showShortcuts());
|
|
||||||
panel3.add(showShortcutsCheckBox, "cell 0 0");
|
|
||||||
|
|
||||||
//---- showAccessoryCheckBox ----
|
|
||||||
showAccessoryCheckBox.setText("Show Accessory");
|
|
||||||
showAccessoryCheckBox.addActionListener(e -> showAccessory());
|
|
||||||
panel3.add(showAccessoryCheckBox, "cell 1 0");
|
|
||||||
}
|
|
||||||
add(panel3, "cell 1 2");
|
|
||||||
|
|
||||||
//---- label1 ----
|
|
||||||
label1.setText("icons:");
|
|
||||||
add(label1, "cell 0 3");
|
|
||||||
|
|
||||||
//---- label2 ----
|
|
||||||
label2.setIcon(UIManager.getIcon("FileView.directoryIcon"));
|
|
||||||
add(label2, "cell 1 3");
|
|
||||||
|
|
||||||
//---- label3 ----
|
|
||||||
label3.setIcon(UIManager.getIcon("FileView.fileIcon"));
|
|
||||||
add(label3, "cell 1 3");
|
|
||||||
|
|
||||||
//---- label4 ----
|
|
||||||
label4.setIcon(UIManager.getIcon("FileView.computerIcon"));
|
|
||||||
add(label4, "cell 1 3");
|
|
||||||
|
|
||||||
//---- label5 ----
|
|
||||||
label5.setIcon(UIManager.getIcon("FileView.hardDriveIcon"));
|
|
||||||
add(label5, "cell 1 3");
|
|
||||||
|
|
||||||
//---- label6 ----
|
|
||||||
label6.setIcon(UIManager.getIcon("FileView.floppyDriveIcon"));
|
|
||||||
add(label6, "cell 1 3");
|
|
||||||
|
|
||||||
//---- label7 ----
|
|
||||||
label7.setIcon(UIManager.getIcon("FileChooser.newFolderIcon"));
|
|
||||||
add(label7, "cell 1 3");
|
|
||||||
|
|
||||||
//---- label8 ----
|
|
||||||
label8.setIcon(UIManager.getIcon("FileChooser.upFolderIcon"));
|
|
||||||
add(label8, "cell 1 3");
|
|
||||||
|
|
||||||
//---- label9 ----
|
|
||||||
label9.setIcon(UIManager.getIcon("FileChooser.homeFolderIcon"));
|
|
||||||
add(label9, "cell 1 3");
|
|
||||||
|
|
||||||
//---- label10 ----
|
|
||||||
label10.setIcon(UIManager.getIcon("FileChooser.detailsViewIcon"));
|
|
||||||
add(label10, "cell 1 3");
|
|
||||||
|
|
||||||
//---- label11 ----
|
|
||||||
label11.setIcon(UIManager.getIcon("FileChooser.listViewIcon"));
|
|
||||||
add(label11, "cell 1 3");
|
|
||||||
// JFormDesigner - End of component initialization //GEN-END:initComponents
|
|
||||||
}
|
|
||||||
|
|
||||||
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
|
|
||||||
private JFileChooser fileChooser1;
|
|
||||||
private JCheckBox showShortcutsCheckBox;
|
|
||||||
private JCheckBox showAccessoryCheckBox;
|
|
||||||
// JFormDesigner - End of variables declaration //GEN-END:variables
|
|
||||||
}
|
|
||||||
@@ -1,153 +0,0 @@
|
|||||||
JFDML JFormDesigner: "8.0.0.0.194" Java: "17.0.2" encoding: "UTF-8"
|
|
||||||
|
|
||||||
new FormModel {
|
|
||||||
contentType: "form/swing"
|
|
||||||
root: new FormRoot {
|
|
||||||
auxiliary() {
|
|
||||||
"JavaCodeGenerator.defaultVariableLocal": true
|
|
||||||
}
|
|
||||||
add( new FormContainer( "com.formdev.flatlaf.testing.FlatTestPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
|
||||||
"$layoutConstraints": "ltr,insets dialog,hidemode 3"
|
|
||||||
"$columnConstraints": "[][grow]"
|
|
||||||
"$rowConstraints": "[top][grow,fill][][]"
|
|
||||||
} ) {
|
|
||||||
name: "this"
|
|
||||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
|
||||||
name: "colorChooserLabel"
|
|
||||||
"text": "JColorChooser:"
|
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
|
||||||
"value": "cell 0 0"
|
|
||||||
} )
|
|
||||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class java.awt.BorderLayout ) ) {
|
|
||||||
name: "panel2"
|
|
||||||
"border": new javax.swing.border.MatteBorder( 4, 4, 4, 4, sfield java.awt.Color red )
|
|
||||||
add( new FormComponent( "javax.swing.JColorChooser" ) {
|
|
||||||
name: "colorChooser1"
|
|
||||||
}, new FormLayoutConstraints( class java.lang.String ) {
|
|
||||||
"value": "Center"
|
|
||||||
} )
|
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
|
||||||
"value": "cell 1 0"
|
|
||||||
} )
|
|
||||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
|
||||||
name: "fileChooserLabel"
|
|
||||||
"text": "JFileChooser:"
|
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
|
||||||
"value": "cell 0 1,aligny top,growy 0"
|
|
||||||
} )
|
|
||||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class java.awt.BorderLayout ) ) {
|
|
||||||
name: "panel1"
|
|
||||||
"border": new javax.swing.border.MatteBorder( 4, 4, 4, 4, sfield java.awt.Color red )
|
|
||||||
add( new FormComponent( "javax.swing.JFileChooser" ) {
|
|
||||||
name: "fileChooser1"
|
|
||||||
auxiliary() {
|
|
||||||
"JavaCodeGenerator.variableLocal": false
|
|
||||||
}
|
|
||||||
}, new FormLayoutConstraints( class java.lang.String ) {
|
|
||||||
"value": "Center"
|
|
||||||
} )
|
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
|
||||||
"value": "cell 1 1,growx"
|
|
||||||
} )
|
|
||||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
|
||||||
"$layoutConstraints": "hidemode 3"
|
|
||||||
"$columnConstraints": "[fill][fill]"
|
|
||||||
"$rowConstraints": "[]"
|
|
||||||
} ) {
|
|
||||||
name: "panel3"
|
|
||||||
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
|
||||||
name: "showShortcutsCheckBox"
|
|
||||||
"text": "Show Shortcuts"
|
|
||||||
"selected": true
|
|
||||||
auxiliary() {
|
|
||||||
"JavaCodeGenerator.variableLocal": false
|
|
||||||
}
|
|
||||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "showShortcuts", false ) )
|
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
|
||||||
"value": "cell 0 0"
|
|
||||||
} )
|
|
||||||
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
|
||||||
name: "showAccessoryCheckBox"
|
|
||||||
"text": "Show Accessory"
|
|
||||||
auxiliary() {
|
|
||||||
"JavaCodeGenerator.variableLocal": false
|
|
||||||
}
|
|
||||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "showAccessory", false ) )
|
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
|
||||||
"value": "cell 1 0"
|
|
||||||
} )
|
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
|
||||||
"value": "cell 1 2"
|
|
||||||
} )
|
|
||||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
|
||||||
name: "label1"
|
|
||||||
"text": "icons:"
|
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
|
||||||
"value": "cell 0 3"
|
|
||||||
} )
|
|
||||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
|
||||||
name: "label2"
|
|
||||||
"icon": new com.jformdesigner.model.SwingIcon( 2, "FileView.directoryIcon" )
|
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
|
||||||
"value": "cell 1 3"
|
|
||||||
} )
|
|
||||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
|
||||||
name: "label3"
|
|
||||||
"icon": new com.jformdesigner.model.SwingIcon( 2, "FileView.fileIcon" )
|
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
|
||||||
"value": "cell 1 3"
|
|
||||||
} )
|
|
||||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
|
||||||
name: "label4"
|
|
||||||
"icon": new com.jformdesigner.model.SwingIcon( 2, "FileView.computerIcon" )
|
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
|
||||||
"value": "cell 1 3"
|
|
||||||
} )
|
|
||||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
|
||||||
name: "label5"
|
|
||||||
"icon": new com.jformdesigner.model.SwingIcon( 2, "FileView.hardDriveIcon" )
|
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
|
||||||
"value": "cell 1 3"
|
|
||||||
} )
|
|
||||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
|
||||||
name: "label6"
|
|
||||||
"icon": new com.jformdesigner.model.SwingIcon( 2, "FileView.floppyDriveIcon" )
|
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
|
||||||
"value": "cell 1 3"
|
|
||||||
} )
|
|
||||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
|
||||||
name: "label7"
|
|
||||||
"icon": new com.jformdesigner.model.SwingIcon( 2, "FileChooser.newFolderIcon" )
|
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
|
||||||
"value": "cell 1 3"
|
|
||||||
} )
|
|
||||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
|
||||||
name: "label8"
|
|
||||||
"icon": new com.jformdesigner.model.SwingIcon( 2, "FileChooser.upFolderIcon" )
|
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
|
||||||
"value": "cell 1 3"
|
|
||||||
} )
|
|
||||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
|
||||||
name: "label9"
|
|
||||||
"icon": new com.jformdesigner.model.SwingIcon( 2, "FileChooser.homeFolderIcon" )
|
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
|
||||||
"value": "cell 1 3"
|
|
||||||
} )
|
|
||||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
|
||||||
name: "label10"
|
|
||||||
"icon": new com.jformdesigner.model.SwingIcon( 2, "FileChooser.detailsViewIcon" )
|
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
|
||||||
"value": "cell 1 3"
|
|
||||||
} )
|
|
||||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
|
||||||
name: "label11"
|
|
||||||
"icon": new com.jformdesigner.model.SwingIcon( 2, "FileChooser.listViewIcon" )
|
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
|
||||||
"value": "cell 1 3"
|
|
||||||
} )
|
|
||||||
}, new FormLayoutConstraints( null ) {
|
|
||||||
"location": new java.awt.Point( 0, 0 )
|
|
||||||
"size": new java.awt.Dimension( 790, 790 )
|
|
||||||
} )
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 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
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.formdev.flatlaf.testing;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import javax.swing.*;
|
||||||
|
import javax.swing.border.*;
|
||||||
|
import net.miginfocom.swing.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Karl Tauber
|
||||||
|
*/
|
||||||
|
public class FlatColorChooserTest
|
||||||
|
extends FlatTestPanel
|
||||||
|
{
|
||||||
|
public static void main( String[] args ) {
|
||||||
|
// Locale.setDefault( Locale.FRENCH );
|
||||||
|
// Locale.setDefault( Locale.GERMAN );
|
||||||
|
// Locale.setDefault( Locale.ITALIAN );
|
||||||
|
// Locale.setDefault( Locale.JAPANESE );
|
||||||
|
// Locale.setDefault( Locale.SIMPLIFIED_CHINESE );
|
||||||
|
// Locale.setDefault( Locale.TRADITIONAL_CHINESE );
|
||||||
|
|
||||||
|
SwingUtilities.invokeLater( () -> {
|
||||||
|
FlatTestFrame frame = FlatTestFrame.create( args, "FlatColorChooserTest" );
|
||||||
|
frame.showFrame( FlatColorChooserTest::new );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
FlatColorChooserTest() {
|
||||||
|
initComponents();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initComponents() {
|
||||||
|
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
|
||||||
|
JLabel colorChooserLabel = new JLabel();
|
||||||
|
JPanel panel2 = new JPanel();
|
||||||
|
JColorChooser colorChooser1 = new JColorChooser();
|
||||||
|
|
||||||
|
//======== this ========
|
||||||
|
setLayout(new MigLayout(
|
||||||
|
"ltr,insets dialog,hidemode 3",
|
||||||
|
// columns
|
||||||
|
"[]" +
|
||||||
|
"[grow]",
|
||||||
|
// rows
|
||||||
|
"[top]"));
|
||||||
|
|
||||||
|
//---- colorChooserLabel ----
|
||||||
|
colorChooserLabel.setText("JColorChooser:");
|
||||||
|
add(colorChooserLabel, "cell 0 0");
|
||||||
|
|
||||||
|
//======== panel2 ========
|
||||||
|
{
|
||||||
|
panel2.setBorder(new MatteBorder(4, 4, 4, 4, Color.red));
|
||||||
|
panel2.setLayout(new BorderLayout());
|
||||||
|
panel2.add(colorChooser1, BorderLayout.CENTER);
|
||||||
|
}
|
||||||
|
add(panel2, "cell 1 0");
|
||||||
|
// JFormDesigner - End of component initialization //GEN-END:initComponents
|
||||||
|
}
|
||||||
|
|
||||||
|
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
|
||||||
|
// JFormDesigner - End of variables declaration //GEN-END:variables
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
JFDML JFormDesigner: "8.2.0.0.331" Java: "21" encoding: "UTF-8"
|
||||||
|
|
||||||
|
new FormModel {
|
||||||
|
contentType: "form/swing"
|
||||||
|
root: new FormRoot {
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.defaultVariableLocal": true
|
||||||
|
}
|
||||||
|
add( new FormContainer( "com.formdev.flatlaf.testing.FlatTestPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
||||||
|
"$layoutConstraints": "ltr,insets dialog,hidemode 3"
|
||||||
|
"$columnConstraints": "[][grow]"
|
||||||
|
"$rowConstraints": "[top]"
|
||||||
|
} ) {
|
||||||
|
name: "this"
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "colorChooserLabel"
|
||||||
|
"text": "JColorChooser:"
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 0"
|
||||||
|
} )
|
||||||
|
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class java.awt.BorderLayout ) ) {
|
||||||
|
name: "panel2"
|
||||||
|
"border": new javax.swing.border.MatteBorder( 4, 4, 4, 4, sfield java.awt.Color red )
|
||||||
|
add( new FormComponent( "javax.swing.JColorChooser" ) {
|
||||||
|
name: "colorChooser1"
|
||||||
|
}, new FormLayoutConstraints( class java.lang.String ) {
|
||||||
|
"value": "Center"
|
||||||
|
} )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 0"
|
||||||
|
} )
|
||||||
|
}, new FormLayoutConstraints( null ) {
|
||||||
|
"location": new java.awt.Point( 0, 0 )
|
||||||
|
"size": new java.awt.Dimension( 790, 790 )
|
||||||
|
} )
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,556 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 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
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.formdev.flatlaf.testing;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.beans.PropertyChangeEvent;
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.ResourceBundle;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import javax.swing.*;
|
||||||
|
import javax.swing.border.*;
|
||||||
|
import javax.swing.filechooser.FileFilter;
|
||||||
|
import javax.swing.filechooser.FileNameExtensionFilter;
|
||||||
|
import javax.swing.filechooser.FileSystemView;
|
||||||
|
import com.formdev.flatlaf.FlatLaf;
|
||||||
|
import com.formdev.flatlaf.icons.FlatFileChooserHomeFolderIcon;
|
||||||
|
import com.formdev.flatlaf.ui.JavaCompatibility2;
|
||||||
|
import net.miginfocom.swing.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Karl Tauber
|
||||||
|
*/
|
||||||
|
public class FlatFileChooserTest
|
||||||
|
extends FlatTestPanel
|
||||||
|
{
|
||||||
|
public static void main( String[] args ) {
|
||||||
|
// Locale.setDefault( Locale.FRENCH );
|
||||||
|
// Locale.setDefault( Locale.GERMAN );
|
||||||
|
// Locale.setDefault( Locale.ITALIAN );
|
||||||
|
// Locale.setDefault( Locale.JAPANESE );
|
||||||
|
// Locale.setDefault( Locale.SIMPLIFIED_CHINESE );
|
||||||
|
// Locale.setDefault( Locale.TRADITIONAL_CHINESE );
|
||||||
|
|
||||||
|
SwingUtilities.invokeLater( () -> {
|
||||||
|
FlatTestFrame frame = FlatTestFrame.create( args, "FlatFileChooserTest" );
|
||||||
|
|
||||||
|
UIManager.put( "FileChooser.shortcuts.filesFunction", (Function<File[], File[]>) files -> {
|
||||||
|
ArrayList<File> list = new ArrayList<>( Arrays.asList( files ) );
|
||||||
|
list.add( 0, new File( System.getProperty( "user.home" ) ) );
|
||||||
|
return list.toArray( new File[list.size()] );
|
||||||
|
} );
|
||||||
|
|
||||||
|
UIManager.put( "FileChooser.shortcuts.displayNameFunction", (Function<File, String>) file -> {
|
||||||
|
if( file.getAbsolutePath().equals( System.getProperty( "user.home" ) ) )
|
||||||
|
return "Home";
|
||||||
|
return null;
|
||||||
|
} );
|
||||||
|
UIManager.put( "FileChooser.shortcuts.iconFunction", (Function<File, Icon>) file -> {
|
||||||
|
if( file.getAbsolutePath().equals( System.getProperty( "user.home" ) ) )
|
||||||
|
return new FlatFileChooserHomeFolderIcon();
|
||||||
|
return null;
|
||||||
|
} );
|
||||||
|
|
||||||
|
frame.showFrame( FlatFileChooserTest::new );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
FlatFileChooserTest() {
|
||||||
|
initComponents();
|
||||||
|
|
||||||
|
dialogTypeField.init( DialogType.class, false );
|
||||||
|
fileSelectionModeField.init( FileSelectionMode.class, false );
|
||||||
|
localesField.init( Locales.class, false );
|
||||||
|
|
||||||
|
showControlButtonsCheckBox.setSelected( fileChooser1.getControlButtonsAreShown() );
|
||||||
|
multiSelectionCheckBox.setSelected( fileChooser1.isMultiSelectionEnabled() );
|
||||||
|
fileHidingCheckBox.setSelected( fileChooser1.isFileHidingEnabled() );
|
||||||
|
dragCheckBox.setSelected( fileChooser1.getDragEnabled() );
|
||||||
|
filterAllFilesCheckBox.setSelected( fileChooser1.isAcceptAllFileFilterUsed() );
|
||||||
|
|
||||||
|
updateOutput();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fileChooser1PropertyChange( PropertyChangeEvent e ) {
|
||||||
|
switch( e.getPropertyName() ) {
|
||||||
|
case JFileChooser.DIRECTORY_CHANGED_PROPERTY:
|
||||||
|
case JFileChooser.SELECTED_FILE_CHANGED_PROPERTY:
|
||||||
|
case JFileChooser.SELECTED_FILES_CHANGED_PROPERTY:
|
||||||
|
updateOutput();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateOutput() {
|
||||||
|
currentDirectoryField.setText( String.valueOf( fileChooser1.getCurrentDirectory() ) );
|
||||||
|
selectedFileField.setText( String.valueOf( fileChooser1.getSelectedFile() ) );
|
||||||
|
selectedFilesField.setText( Arrays.toString( fileChooser1.getSelectedFiles() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void dialogTypeChanged() {
|
||||||
|
DialogType value = dialogTypeField.getSelectedValue();
|
||||||
|
int dialogType = (value != null) ? value.value : JFileChooser.OPEN_DIALOG;
|
||||||
|
|
||||||
|
if( dialogType == JFileChooser.CUSTOM_DIALOG )
|
||||||
|
fileChooser1.setApproveButtonText( "Custom" );
|
||||||
|
fileChooser1.setDialogType( dialogType );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fileSelectionModeChanged() {
|
||||||
|
FileSelectionMode value = fileSelectionModeField.getSelectedValue();
|
||||||
|
int mode = (value != null) ? value.value : JFileChooser.FILES_ONLY;
|
||||||
|
|
||||||
|
fileChooser1.setFileSelectionMode( mode );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showControlButtons() {
|
||||||
|
fileChooser1.setControlButtonsAreShown( showControlButtonsCheckBox.isSelected() );
|
||||||
|
fileChooser1.revalidate();
|
||||||
|
fileChooser1.repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showShortcuts() {
|
||||||
|
UIManager.put( "FileChooser.noPlacesBar", !showShortcutsCheckBox.isSelected() ? true : null );
|
||||||
|
fileChooser1.updateUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showAccessory() {
|
||||||
|
JPanel accessory = null;
|
||||||
|
if( showAccessoryCheckBox.isSelected() ) {
|
||||||
|
accessory = new JPanel( new BorderLayout() );
|
||||||
|
accessory.setBackground( Color.green );
|
||||||
|
accessory.add( new JLabel( " Accessory " ), BorderLayout.CENTER );
|
||||||
|
}
|
||||||
|
fileChooser1.setAccessory( accessory );
|
||||||
|
fileChooser1.revalidate();
|
||||||
|
fileChooser1.repaint();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void multiSelection() {
|
||||||
|
fileChooser1.setMultiSelectionEnabled( multiSelectionCheckBox.isSelected() );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fileHiding() {
|
||||||
|
fileChooser1.setFileHidingEnabled( fileHidingCheckBox.isSelected() );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void drag() {
|
||||||
|
fileChooser1.setDragEnabled( dragCheckBox.isSelected() );
|
||||||
|
}
|
||||||
|
|
||||||
|
private final FileFilter TEXT_FILTER = new FileNameExtensionFilter( "Text Files", "txt", "md" );
|
||||||
|
private final FileFilter IMAGES_FILTER = new FileNameExtensionFilter( "Images", "png", "git", "jpg", "jpeg" );
|
||||||
|
private final FileFilter LONG_DESC_FILTER = new FileNameExtensionFilter( "Some long description (.abc, .def, .ghi, .jkl)", "dummy" );
|
||||||
|
private final FileFilter EXTRA_LONG_DESC_FILTER = new FileNameExtensionFilter( "Some super extra long description (.abc, .def, .ghi, .jkl, .mno, .pqr, .stu)", "dummy" );
|
||||||
|
|
||||||
|
private void filterChanged() {
|
||||||
|
boolean all = filterAllFilesCheckBox.isSelected();
|
||||||
|
if( all != fileChooser1.isAcceptAllFileFilterUsed() )
|
||||||
|
fileChooser1.setAcceptAllFileFilterUsed( all );
|
||||||
|
|
||||||
|
addRemoveFilter( filterTextFilesCheckBox.isSelected(), TEXT_FILTER );
|
||||||
|
addRemoveFilter( filterImagesCheckBox.isSelected(), IMAGES_FILTER );
|
||||||
|
addRemoveFilter( filterLongDescCheckBox.isSelected(), LONG_DESC_FILTER );
|
||||||
|
addRemoveFilter( filterExtraLongDescCheckBox.isSelected(), EXTRA_LONG_DESC_FILTER );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addRemoveFilter( boolean add, FileFilter filter ) {
|
||||||
|
if( add )
|
||||||
|
fileChooser1.addChoosableFileFilter( filter );
|
||||||
|
else
|
||||||
|
fileChooser1.removeChoosableFileFilter( filter );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void localesChanged() {
|
||||||
|
Locales value = localesField.getSelectedValue();
|
||||||
|
Locale locale = (value != null) ? value.value : Locale.ENGLISH;
|
||||||
|
|
||||||
|
SwingUtilities.invokeLater( () -> {
|
||||||
|
Locale.setDefault( locale );
|
||||||
|
JComponent.setDefaultLocale( locale );
|
||||||
|
fileChooser1.setLocale( locale );
|
||||||
|
ResourceBundle.clearCache();
|
||||||
|
|
||||||
|
try {
|
||||||
|
UIManager.setLookAndFeel( UIManager.getLookAndFeel().getClass().getName() );
|
||||||
|
FlatLaf.updateUI();
|
||||||
|
} catch( Exception ex ) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void printShortcutFiles() {
|
||||||
|
printFiles( JavaCompatibility2.getChooserShortcutPanelFiles( fileChooser1.getFileSystemView() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void printComboBoxFiles() {
|
||||||
|
printFiles( JavaCompatibility2.getChooserComboBoxFiles( fileChooser1.getFileSystemView() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void printRoots() {
|
||||||
|
FileSystemView fsv = fileChooser1.getFileSystemView();
|
||||||
|
File[] roots = fsv.getRoots();
|
||||||
|
printFiles( roots );
|
||||||
|
|
||||||
|
for( File root : roots )
|
||||||
|
printFiles( fsv.getFiles( root, true ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void printFiles( File[] files ) {
|
||||||
|
System.out.println( "--------------------------------" );
|
||||||
|
FileSystemView fsv = fileChooser1.getFileSystemView();
|
||||||
|
for( File file : files ) {
|
||||||
|
System.out.printf( "%-30s ", file );
|
||||||
|
System.out.println(
|
||||||
|
(fsv.isComputerNode( file ) ? "computer " : "") +
|
||||||
|
(fsv.isDrive( file ) ? "drive " : "") +
|
||||||
|
(fsv.isFileSystem( file ) ? "fileSystem " : "") +
|
||||||
|
(fsv.isFileSystemRoot( file ) ? "fileSystemRoot " : "") +
|
||||||
|
(fsv.isFloppyDrive( file ) ? "floppyDrive " : "") +
|
||||||
|
(fsv.isHiddenFile( file ) ? "hiddenFile " : "") +
|
||||||
|
(fsv.isRoot( file ) ? "root " : "") +
|
||||||
|
(fsv.isTraversable( file ) ? "traversable " : "") );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initComponents() {
|
||||||
|
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
|
||||||
|
JLabel fileChooserLabel = new JLabel();
|
||||||
|
JPanel panel1 = new JPanel();
|
||||||
|
fileChooser1 = new JFileChooser();
|
||||||
|
JLabel currentDirectoryLabel = new JLabel();
|
||||||
|
currentDirectoryField = new JTextField();
|
||||||
|
JLabel selectedFileLabel = new JLabel();
|
||||||
|
selectedFileField = new JTextField();
|
||||||
|
JLabel selectedFilesLabel = new JLabel();
|
||||||
|
selectedFilesField = new JTextField();
|
||||||
|
JLabel dialogTypeLabel = new JLabel();
|
||||||
|
dialogTypeField = new FlatTestEnumSelector<>();
|
||||||
|
showControlButtonsCheckBox = new JCheckBox();
|
||||||
|
showShortcutsCheckBox = new JCheckBox();
|
||||||
|
showAccessoryCheckBox = new JCheckBox();
|
||||||
|
JLabel fileSelectionModeLabel = new JLabel();
|
||||||
|
fileSelectionModeField = new FlatTestEnumSelector<>();
|
||||||
|
multiSelectionCheckBox = new JCheckBox();
|
||||||
|
fileHidingCheckBox = new JCheckBox();
|
||||||
|
dragCheckBox = new JCheckBox();
|
||||||
|
JLabel filtersLabel = new JLabel();
|
||||||
|
filterAllFilesCheckBox = new JCheckBox();
|
||||||
|
filterTextFilesCheckBox = new JCheckBox();
|
||||||
|
filterImagesCheckBox = new JCheckBox();
|
||||||
|
filterLongDescCheckBox = new JCheckBox();
|
||||||
|
filterExtraLongDescCheckBox = new JCheckBox();
|
||||||
|
printShortcutFilesButton = new JButton();
|
||||||
|
printComboBoxFilesButton = new JButton();
|
||||||
|
printRootsButton = new JButton();
|
||||||
|
JLabel localesLabel = new JLabel();
|
||||||
|
localesField = new FlatTestEnumSelector<>();
|
||||||
|
JLabel label1 = new JLabel();
|
||||||
|
JLabel label2 = new JLabel();
|
||||||
|
JLabel label3 = new JLabel();
|
||||||
|
JLabel label4 = new JLabel();
|
||||||
|
JLabel label5 = new JLabel();
|
||||||
|
JLabel label6 = new JLabel();
|
||||||
|
JLabel label7 = new JLabel();
|
||||||
|
JLabel label8 = new JLabel();
|
||||||
|
JLabel label9 = new JLabel();
|
||||||
|
JLabel label10 = new JLabel();
|
||||||
|
JLabel label11 = new JLabel();
|
||||||
|
|
||||||
|
//======== this ========
|
||||||
|
setLayout(new MigLayout(
|
||||||
|
"ltr,insets dialog,hidemode 3",
|
||||||
|
// columns
|
||||||
|
"[]" +
|
||||||
|
"[]" +
|
||||||
|
"[grow]",
|
||||||
|
// rows
|
||||||
|
"[grow,fill]" +
|
||||||
|
"[]" +
|
||||||
|
"[]" +
|
||||||
|
"[]" +
|
||||||
|
"[]" +
|
||||||
|
"[]" +
|
||||||
|
"[]" +
|
||||||
|
"[]" +
|
||||||
|
"[]para" +
|
||||||
|
"[]"));
|
||||||
|
|
||||||
|
//---- fileChooserLabel ----
|
||||||
|
fileChooserLabel.setText("JFileChooser:");
|
||||||
|
add(fileChooserLabel, "cell 0 0,aligny top,growy 0");
|
||||||
|
|
||||||
|
//======== panel1 ========
|
||||||
|
{
|
||||||
|
panel1.setBorder(new MatteBorder(4, 4, 4, 4, Color.red));
|
||||||
|
panel1.setLayout(new BorderLayout());
|
||||||
|
|
||||||
|
//---- fileChooser1 ----
|
||||||
|
fileChooser1.addPropertyChangeListener(e -> fileChooser1PropertyChange(e));
|
||||||
|
panel1.add(fileChooser1, BorderLayout.CENTER);
|
||||||
|
}
|
||||||
|
add(panel1, "cell 1 0 2 1,growx");
|
||||||
|
|
||||||
|
//---- currentDirectoryLabel ----
|
||||||
|
currentDirectoryLabel.setText("Current Directory:");
|
||||||
|
add(currentDirectoryLabel, "cell 0 1");
|
||||||
|
|
||||||
|
//---- currentDirectoryField ----
|
||||||
|
currentDirectoryField.setEditable(false);
|
||||||
|
add(currentDirectoryField, "cell 1 1 2 1,growx");
|
||||||
|
|
||||||
|
//---- selectedFileLabel ----
|
||||||
|
selectedFileLabel.setText("Selected File:");
|
||||||
|
add(selectedFileLabel, "cell 0 2");
|
||||||
|
|
||||||
|
//---- selectedFileField ----
|
||||||
|
selectedFileField.setEditable(false);
|
||||||
|
add(selectedFileField, "cell 1 2 2 1,growx");
|
||||||
|
|
||||||
|
//---- selectedFilesLabel ----
|
||||||
|
selectedFilesLabel.setText("Selected Files:");
|
||||||
|
add(selectedFilesLabel, "cell 0 3");
|
||||||
|
|
||||||
|
//---- selectedFilesField ----
|
||||||
|
selectedFilesField.setEditable(false);
|
||||||
|
add(selectedFilesField, "cell 1 3 2 1,growx");
|
||||||
|
|
||||||
|
//---- dialogTypeLabel ----
|
||||||
|
dialogTypeLabel.setText("Dialog Type:");
|
||||||
|
add(dialogTypeLabel, "cell 0 4");
|
||||||
|
|
||||||
|
//---- dialogTypeField ----
|
||||||
|
dialogTypeField.addActionListener(e -> dialogTypeChanged());
|
||||||
|
add(dialogTypeField, "cell 1 4");
|
||||||
|
|
||||||
|
//---- showControlButtonsCheckBox ----
|
||||||
|
showControlButtonsCheckBox.setText("Show Control Buttons");
|
||||||
|
showControlButtonsCheckBox.addActionListener(e -> showControlButtons());
|
||||||
|
add(showControlButtonsCheckBox, "cell 2 4");
|
||||||
|
|
||||||
|
//---- showShortcutsCheckBox ----
|
||||||
|
showShortcutsCheckBox.setText("Show Shortcuts");
|
||||||
|
showShortcutsCheckBox.setSelected(true);
|
||||||
|
showShortcutsCheckBox.addActionListener(e -> showShortcuts());
|
||||||
|
add(showShortcutsCheckBox, "cell 2 4");
|
||||||
|
|
||||||
|
//---- showAccessoryCheckBox ----
|
||||||
|
showAccessoryCheckBox.setText("Show Accessory");
|
||||||
|
showAccessoryCheckBox.addActionListener(e -> showAccessory());
|
||||||
|
add(showAccessoryCheckBox, "cell 2 4");
|
||||||
|
|
||||||
|
//---- fileSelectionModeLabel ----
|
||||||
|
fileSelectionModeLabel.setText("File Selection Mode:");
|
||||||
|
add(fileSelectionModeLabel, "cell 0 5");
|
||||||
|
|
||||||
|
//---- fileSelectionModeField ----
|
||||||
|
fileSelectionModeField.addActionListener(e -> fileSelectionModeChanged());
|
||||||
|
add(fileSelectionModeField, "cell 1 5");
|
||||||
|
|
||||||
|
//---- multiSelectionCheckBox ----
|
||||||
|
multiSelectionCheckBox.setText("Multi Selection");
|
||||||
|
multiSelectionCheckBox.addActionListener(e -> multiSelection());
|
||||||
|
add(multiSelectionCheckBox, "cell 2 5");
|
||||||
|
|
||||||
|
//---- fileHidingCheckBox ----
|
||||||
|
fileHidingCheckBox.setText("File Hiding");
|
||||||
|
fileHidingCheckBox.addActionListener(e -> fileHiding());
|
||||||
|
add(fileHidingCheckBox, "cell 2 5");
|
||||||
|
|
||||||
|
//---- dragCheckBox ----
|
||||||
|
dragCheckBox.setText("Drag");
|
||||||
|
dragCheckBox.addActionListener(e -> drag());
|
||||||
|
add(dragCheckBox, "cell 2 5");
|
||||||
|
|
||||||
|
//---- filtersLabel ----
|
||||||
|
filtersLabel.setText("Filters:");
|
||||||
|
add(filtersLabel, "cell 0 6");
|
||||||
|
|
||||||
|
//---- filterAllFilesCheckBox ----
|
||||||
|
filterAllFilesCheckBox.setText("All Files");
|
||||||
|
filterAllFilesCheckBox.addActionListener(e -> filterChanged());
|
||||||
|
add(filterAllFilesCheckBox, "cell 1 6 2 1");
|
||||||
|
|
||||||
|
//---- filterTextFilesCheckBox ----
|
||||||
|
filterTextFilesCheckBox.setText("Text Files");
|
||||||
|
filterTextFilesCheckBox.addActionListener(e -> filterChanged());
|
||||||
|
add(filterTextFilesCheckBox, "cell 1 6 2 1");
|
||||||
|
|
||||||
|
//---- filterImagesCheckBox ----
|
||||||
|
filterImagesCheckBox.setText("Images");
|
||||||
|
filterImagesCheckBox.addActionListener(e -> filterChanged());
|
||||||
|
add(filterImagesCheckBox, "cell 1 6 2 1");
|
||||||
|
|
||||||
|
//---- filterLongDescCheckBox ----
|
||||||
|
filterLongDescCheckBox.setText("Long description");
|
||||||
|
filterLongDescCheckBox.addActionListener(e -> filterChanged());
|
||||||
|
add(filterLongDescCheckBox, "cell 1 6 2 1");
|
||||||
|
|
||||||
|
//---- filterExtraLongDescCheckBox ----
|
||||||
|
filterExtraLongDescCheckBox.setText("Extra Long description");
|
||||||
|
filterExtraLongDescCheckBox.addActionListener(e -> filterChanged());
|
||||||
|
add(filterExtraLongDescCheckBox, "cell 1 6 2 1");
|
||||||
|
|
||||||
|
//---- printShortcutFilesButton ----
|
||||||
|
printShortcutFilesButton.setText("Print Shortcut Files");
|
||||||
|
printShortcutFilesButton.addActionListener(e -> printShortcutFiles());
|
||||||
|
add(printShortcutFilesButton, "cell 1 7 2 1");
|
||||||
|
|
||||||
|
//---- printComboBoxFilesButton ----
|
||||||
|
printComboBoxFilesButton.setText("Print ComboBox Files");
|
||||||
|
printComboBoxFilesButton.addActionListener(e -> printComboBoxFiles());
|
||||||
|
add(printComboBoxFilesButton, "cell 1 7 2 1");
|
||||||
|
|
||||||
|
//---- printRootsButton ----
|
||||||
|
printRootsButton.setText("Print Roots");
|
||||||
|
printRootsButton.addActionListener(e -> printRoots());
|
||||||
|
add(printRootsButton, "cell 1 7 2 1");
|
||||||
|
|
||||||
|
//---- localesLabel ----
|
||||||
|
localesLabel.setText("Locales:");
|
||||||
|
add(localesLabel, "cell 0 8");
|
||||||
|
|
||||||
|
//---- localesField ----
|
||||||
|
localesField.addActionListener(e -> localesChanged());
|
||||||
|
add(localesField, "cell 1 8 2 1");
|
||||||
|
|
||||||
|
//---- label1 ----
|
||||||
|
label1.setText("icons:");
|
||||||
|
add(label1, "cell 0 9");
|
||||||
|
|
||||||
|
//---- label2 ----
|
||||||
|
label2.setIcon(UIManager.getIcon("FileView.directoryIcon"));
|
||||||
|
add(label2, "cell 1 9 2 1");
|
||||||
|
|
||||||
|
//---- label3 ----
|
||||||
|
label3.setIcon(UIManager.getIcon("FileView.fileIcon"));
|
||||||
|
add(label3, "cell 1 9 2 1");
|
||||||
|
|
||||||
|
//---- label4 ----
|
||||||
|
label4.setIcon(UIManager.getIcon("FileView.computerIcon"));
|
||||||
|
add(label4, "cell 1 9 2 1");
|
||||||
|
|
||||||
|
//---- label5 ----
|
||||||
|
label5.setIcon(UIManager.getIcon("FileView.hardDriveIcon"));
|
||||||
|
add(label5, "cell 1 9 2 1");
|
||||||
|
|
||||||
|
//---- label6 ----
|
||||||
|
label6.setIcon(UIManager.getIcon("FileView.floppyDriveIcon"));
|
||||||
|
add(label6, "cell 1 9 2 1");
|
||||||
|
|
||||||
|
//---- label7 ----
|
||||||
|
label7.setIcon(UIManager.getIcon("FileChooser.newFolderIcon"));
|
||||||
|
add(label7, "cell 1 9 2 1");
|
||||||
|
|
||||||
|
//---- label8 ----
|
||||||
|
label8.setIcon(UIManager.getIcon("FileChooser.upFolderIcon"));
|
||||||
|
add(label8, "cell 1 9 2 1");
|
||||||
|
|
||||||
|
//---- label9 ----
|
||||||
|
label9.setIcon(UIManager.getIcon("FileChooser.homeFolderIcon"));
|
||||||
|
add(label9, "cell 1 9 2 1");
|
||||||
|
|
||||||
|
//---- label10 ----
|
||||||
|
label10.setIcon(UIManager.getIcon("FileChooser.detailsViewIcon"));
|
||||||
|
add(label10, "cell 1 9 2 1");
|
||||||
|
|
||||||
|
//---- label11 ----
|
||||||
|
label11.setIcon(UIManager.getIcon("FileChooser.listViewIcon"));
|
||||||
|
add(label11, "cell 1 9 2 1");
|
||||||
|
// JFormDesigner - End of component initialization //GEN-END:initComponents
|
||||||
|
}
|
||||||
|
|
||||||
|
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
|
||||||
|
private JFileChooser fileChooser1;
|
||||||
|
private JTextField currentDirectoryField;
|
||||||
|
private JTextField selectedFileField;
|
||||||
|
private JTextField selectedFilesField;
|
||||||
|
private FlatTestEnumSelector<DialogType> dialogTypeField;
|
||||||
|
private JCheckBox showControlButtonsCheckBox;
|
||||||
|
private JCheckBox showShortcutsCheckBox;
|
||||||
|
private JCheckBox showAccessoryCheckBox;
|
||||||
|
private FlatTestEnumSelector<FileSelectionMode> fileSelectionModeField;
|
||||||
|
private JCheckBox multiSelectionCheckBox;
|
||||||
|
private JCheckBox fileHidingCheckBox;
|
||||||
|
private JCheckBox dragCheckBox;
|
||||||
|
private JCheckBox filterAllFilesCheckBox;
|
||||||
|
private JCheckBox filterTextFilesCheckBox;
|
||||||
|
private JCheckBox filterImagesCheckBox;
|
||||||
|
private JCheckBox filterLongDescCheckBox;
|
||||||
|
private JCheckBox filterExtraLongDescCheckBox;
|
||||||
|
private JButton printShortcutFilesButton;
|
||||||
|
private JButton printComboBoxFilesButton;
|
||||||
|
private JButton printRootsButton;
|
||||||
|
private FlatTestEnumSelector<Locales> localesField;
|
||||||
|
// JFormDesigner - End of variables declaration //GEN-END:variables
|
||||||
|
|
||||||
|
//---- enum DialogType ----------------------------------------------------
|
||||||
|
|
||||||
|
enum DialogType {
|
||||||
|
open( JFileChooser.OPEN_DIALOG ),
|
||||||
|
save( JFileChooser.SAVE_DIALOG ),
|
||||||
|
custom( JFileChooser.CUSTOM_DIALOG );
|
||||||
|
|
||||||
|
public final int value;
|
||||||
|
|
||||||
|
DialogType( int value ) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//---- enum FileSelectionMode ---------------------------------------------
|
||||||
|
|
||||||
|
enum FileSelectionMode {
|
||||||
|
files_only( JFileChooser.FILES_ONLY ),
|
||||||
|
directories_only( JFileChooser.DIRECTORIES_ONLY ),
|
||||||
|
files_and_directories( JFileChooser.FILES_AND_DIRECTORIES );
|
||||||
|
|
||||||
|
public final int value;
|
||||||
|
|
||||||
|
FileSelectionMode( int value ) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//---- enum Locales -------------------------------------------------------
|
||||||
|
|
||||||
|
// locales supported by Swing
|
||||||
|
// (see https://github.com/openjdk/jdk/tree/master/src/java.desktop/share/classes/com/sun/swing/internal/plaf/metal/resources)
|
||||||
|
enum Locales {
|
||||||
|
english( Locale.ENGLISH ),
|
||||||
|
german( Locale.GERMAN ),
|
||||||
|
spanish( new Locale( "es" ) ),
|
||||||
|
french( Locale.FRENCH ),
|
||||||
|
italian( Locale.ITALIAN ),
|
||||||
|
japanese( Locale.JAPANESE ),
|
||||||
|
korean( Locale.KOREAN ),
|
||||||
|
brazilian_portuguese( new Locale( "pt", "BR" ) ),
|
||||||
|
swedish( new Locale( "sv" ) ),
|
||||||
|
simplified_chinese( Locale.SIMPLIFIED_CHINESE ),
|
||||||
|
traditional_chinese( Locale.TRADITIONAL_CHINESE );
|
||||||
|
|
||||||
|
public final Locale value;
|
||||||
|
|
||||||
|
Locales( Locale value ) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,347 @@
|
|||||||
|
JFDML JFormDesigner: "8.2.0.0.331" Java: "21" encoding: "UTF-8"
|
||||||
|
|
||||||
|
new FormModel {
|
||||||
|
contentType: "form/swing"
|
||||||
|
root: new FormRoot {
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.defaultVariableLocal": true
|
||||||
|
}
|
||||||
|
add( new FormContainer( "com.formdev.flatlaf.testing.FlatTestPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
||||||
|
"$layoutConstraints": "ltr,insets dialog,hidemode 3"
|
||||||
|
"$columnConstraints": "[][][grow]"
|
||||||
|
"$rowConstraints": "[grow,fill][][][][][][][][]para[]"
|
||||||
|
} ) {
|
||||||
|
name: "this"
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "fileChooserLabel"
|
||||||
|
"text": "JFileChooser:"
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 0,aligny top,growy 0"
|
||||||
|
} )
|
||||||
|
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class java.awt.BorderLayout ) ) {
|
||||||
|
name: "panel1"
|
||||||
|
"border": new javax.swing.border.MatteBorder( 4, 4, 4, 4, sfield java.awt.Color red )
|
||||||
|
add( new FormComponent( "javax.swing.JFileChooser" ) {
|
||||||
|
name: "fileChooser1"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
addEvent( new FormEvent( "java.beans.PropertyChangeListener", "propertyChange", "fileChooser1PropertyChange", true ) )
|
||||||
|
}, new FormLayoutConstraints( class java.lang.String ) {
|
||||||
|
"value": "Center"
|
||||||
|
} )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 0 2 1,growx"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "currentDirectoryLabel"
|
||||||
|
"text": "Current Directory:"
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 1"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JTextField" ) {
|
||||||
|
name: "currentDirectoryField"
|
||||||
|
"editable": false
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 1 2 1,growx"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "selectedFileLabel"
|
||||||
|
"text": "Selected File:"
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 2"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JTextField" ) {
|
||||||
|
name: "selectedFileField"
|
||||||
|
"editable": false
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 2 2 1,growx"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "selectedFilesLabel"
|
||||||
|
"text": "Selected Files:"
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 3"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JTextField" ) {
|
||||||
|
name: "selectedFilesField"
|
||||||
|
"editable": false
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 3 2 1,growx"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "dialogTypeLabel"
|
||||||
|
"text": "Dialog Type:"
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 4"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "com.formdev.flatlaf.testing.FlatTestEnumSelector" ) {
|
||||||
|
name: "dialogTypeField"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
"JavaCodeGenerator.typeParameters": "DialogType"
|
||||||
|
}
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "dialogTypeChanged", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 4"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||||
|
name: "showControlButtonsCheckBox"
|
||||||
|
"text": "Show Control Buttons"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "showControlButtons", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 2 4"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||||
|
name: "showShortcutsCheckBox"
|
||||||
|
"text": "Show Shortcuts"
|
||||||
|
"selected": true
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "showShortcuts", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 2 4"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||||
|
name: "showAccessoryCheckBox"
|
||||||
|
"text": "Show Accessory"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "showAccessory", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 2 4"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "fileSelectionModeLabel"
|
||||||
|
"text": "File Selection Mode:"
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 5"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "com.formdev.flatlaf.testing.FlatTestEnumSelector" ) {
|
||||||
|
name: "fileSelectionModeField"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
"JavaCodeGenerator.typeParameters": "FileSelectionMode"
|
||||||
|
}
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "fileSelectionModeChanged", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 5"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||||
|
name: "multiSelectionCheckBox"
|
||||||
|
"text": "Multi Selection"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "multiSelection", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 2 5"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||||
|
name: "fileHidingCheckBox"
|
||||||
|
"text": "File Hiding"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "fileHiding", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 2 5"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||||
|
name: "dragCheckBox"
|
||||||
|
"text": "Drag"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "drag", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 2 5"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "filtersLabel"
|
||||||
|
"text": "Filters:"
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 6"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||||
|
name: "filterAllFilesCheckBox"
|
||||||
|
"text": "All Files"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "filterChanged", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 6 2 1"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||||
|
name: "filterTextFilesCheckBox"
|
||||||
|
"text": "Text Files"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "filterChanged", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 6 2 1"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||||
|
name: "filterImagesCheckBox"
|
||||||
|
"text": "Images"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "filterChanged", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 6 2 1"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||||
|
name: "filterLongDescCheckBox"
|
||||||
|
"text": "Long description"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "filterChanged", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 6 2 1"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||||
|
name: "filterExtraLongDescCheckBox"
|
||||||
|
"text": "Extra Long description"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "filterChanged", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 6 2 1"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JButton" ) {
|
||||||
|
name: "printShortcutFilesButton"
|
||||||
|
"text": "Print Shortcut Files"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "printShortcutFiles", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 7 2 1"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JButton" ) {
|
||||||
|
name: "printComboBoxFilesButton"
|
||||||
|
"text": "Print ComboBox Files"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "printComboBoxFiles", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 7 2 1"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JButton" ) {
|
||||||
|
name: "printRootsButton"
|
||||||
|
"text": "Print Roots"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "printRoots", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 7 2 1"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "localesLabel"
|
||||||
|
"text": "Locales:"
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 8"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "com.formdev.flatlaf.testing.FlatTestEnumSelector" ) {
|
||||||
|
name: "localesField"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
"JavaCodeGenerator.typeParameters": "Locales"
|
||||||
|
}
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "localesChanged", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 8 2 1"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "label1"
|
||||||
|
"text": "icons:"
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 9"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "label2"
|
||||||
|
"icon": new com.jformdesigner.model.SwingIcon( 2, "FileView.directoryIcon" )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 9 2 1"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "label3"
|
||||||
|
"icon": new com.jformdesigner.model.SwingIcon( 2, "FileView.fileIcon" )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 9 2 1"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "label4"
|
||||||
|
"icon": new com.jformdesigner.model.SwingIcon( 2, "FileView.computerIcon" )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 9 2 1"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "label5"
|
||||||
|
"icon": new com.jformdesigner.model.SwingIcon( 2, "FileView.hardDriveIcon" )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 9 2 1"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "label6"
|
||||||
|
"icon": new com.jformdesigner.model.SwingIcon( 2, "FileView.floppyDriveIcon" )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 9 2 1"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "label7"
|
||||||
|
"icon": new com.jformdesigner.model.SwingIcon( 2, "FileChooser.newFolderIcon" )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 9 2 1"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "label8"
|
||||||
|
"icon": new com.jformdesigner.model.SwingIcon( 2, "FileChooser.upFolderIcon" )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 9 2 1"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "label9"
|
||||||
|
"icon": new com.jformdesigner.model.SwingIcon( 2, "FileChooser.homeFolderIcon" )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 9 2 1"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "label10"
|
||||||
|
"icon": new com.jformdesigner.model.SwingIcon( 2, "FileChooser.detailsViewIcon" )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 9 2 1"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "label11"
|
||||||
|
"icon": new com.jformdesigner.model.SwingIcon( 2, "FileChooser.listViewIcon" )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 9 2 1"
|
||||||
|
} )
|
||||||
|
}, new FormLayoutConstraints( null ) {
|
||||||
|
"location": new java.awt.Point( 0, 0 )
|
||||||
|
"size": new java.awt.Dimension( 715, 660 )
|
||||||
|
} )
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,291 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2024 FormDev Software GmbH
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.formdev.flatlaf.testing;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import javax.swing.*;
|
||||||
|
import com.formdev.flatlaf.FlatClientProperties;
|
||||||
|
import com.formdev.flatlaf.ui.FlatNativeMacLibrary;
|
||||||
|
import com.formdev.flatlaf.util.SystemInfo;
|
||||||
|
import net.miginfocom.swing.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Karl Tauber
|
||||||
|
*/
|
||||||
|
public class FlatMacOSTest
|
||||||
|
extends FlatTestPanel
|
||||||
|
{
|
||||||
|
public static void main( String[] args ) {
|
||||||
|
SwingUtilities.invokeLater( () -> {
|
||||||
|
FlatTestFrame frame = FlatTestFrame.create( args, FlatMacOSTest.class.getSimpleName() );
|
||||||
|
frame.applyComponentOrientationToFrame = true;
|
||||||
|
|
||||||
|
JRootPane rootPane = frame.getRootPane();
|
||||||
|
rootPane.putClientProperty( "apple.awt.fullWindowContent", true );
|
||||||
|
rootPane.putClientProperty( "apple.awt.transparentTitleBar", true );
|
||||||
|
rootPane.putClientProperty( "apple.awt.windowTitleVisible", false );
|
||||||
|
|
||||||
|
frame.showFrame( FlatMacOSTest::new );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
FlatMacOSTest() {
|
||||||
|
initComponents();
|
||||||
|
|
||||||
|
if( SystemInfo.isMacFullWindowContentSupported ) {
|
||||||
|
fullWindowContentHint.setVisible( false );
|
||||||
|
transparentTitleBarHint.setVisible( false );
|
||||||
|
}
|
||||||
|
if( SystemInfo.isJava_17_orLater ) {
|
||||||
|
windowTitleVisibleHint.setVisible( false );
|
||||||
|
buttonsSpacingHint.setVisible( false );
|
||||||
|
}
|
||||||
|
|
||||||
|
placeholderPanel.putClientProperty( FlatClientProperties.FULL_WINDOW_CONTENT_BUTTONS_PLACEHOLDER, "mac zeroInFullScreen" );
|
||||||
|
UIManager.put( "FlatLaf.debug.panel.showPlaceholders", true );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addNotify() {
|
||||||
|
super.addNotify();
|
||||||
|
|
||||||
|
JRootPane rootPane = getRootPane();
|
||||||
|
fullWindowContentCheckBox.setSelected( FlatClientProperties.clientPropertyBoolean( rootPane, "apple.awt.fullWindowContent", false ) );
|
||||||
|
transparentTitleBarCheckBox.setSelected( FlatClientProperties.clientPropertyBoolean( rootPane, "apple.awt.transparentTitleBar", false ) );
|
||||||
|
windowTitleVisibleCheckBox.setSelected( FlatClientProperties.clientPropertyBoolean( rootPane, "apple.awt.windowTitleVisible", true ) );
|
||||||
|
|
||||||
|
rootPane.addPropertyChangeListener( FlatClientProperties.FULL_WINDOW_CONTENT_BUTTONS_BOUNDS, e -> {
|
||||||
|
Rectangle bounds = (Rectangle) e.getNewValue();
|
||||||
|
fullWindowContentButtonsBoundsField.setText( bounds2string( bounds ) );
|
||||||
|
} );
|
||||||
|
updateNativeButtonBounds();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateUI() {
|
||||||
|
super.updateUI();
|
||||||
|
|
||||||
|
if( nativeButtonsBoundsField != null )
|
||||||
|
updateNativeButtonBounds();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fullWindowContentChanged() {
|
||||||
|
getRootPane().putClientProperty( "apple.awt.fullWindowContent", fullWindowContentCheckBox.isSelected() );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void transparentTitleBarChanged() {
|
||||||
|
getRootPane().putClientProperty( "apple.awt.transparentTitleBar", transparentTitleBarCheckBox.isSelected() );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void windowTitleVisibleChanged() {
|
||||||
|
getRootPane().putClientProperty( "apple.awt.windowTitleVisible", windowTitleVisibleCheckBox.isSelected() );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void buttonsSpacingChanged() {
|
||||||
|
String buttonsSpacing = null;
|
||||||
|
if( buttonsSpacingMediumRadioButton.isSelected() )
|
||||||
|
buttonsSpacing = FlatClientProperties.MACOS_WINDOW_BUTTONS_SPACING_MEDIUM;
|
||||||
|
else if( buttonsSpacingLargeRadioButton.isSelected() )
|
||||||
|
buttonsSpacing = FlatClientProperties.MACOS_WINDOW_BUTTONS_SPACING_LARGE;
|
||||||
|
|
||||||
|
getRootPane().putClientProperty( FlatClientProperties.MACOS_WINDOW_BUTTONS_SPACING, buttonsSpacing );
|
||||||
|
|
||||||
|
updateNativeButtonBounds();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateNativeButtonBounds() {
|
||||||
|
if( !FlatNativeMacLibrary.isLoaded() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
Window window = SwingUtilities.windowForComponent( this );
|
||||||
|
Rectangle bounds = FlatNativeMacLibrary.getWindowButtonsBounds( window );
|
||||||
|
nativeButtonsBoundsField.setText( bounds2string( bounds ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
private String bounds2string( Rectangle bounds ) {
|
||||||
|
return (bounds != null)
|
||||||
|
? bounds.width + ", " + bounds.height + " @ " + bounds.x + ", " + bounds.y
|
||||||
|
: "null";
|
||||||
|
}
|
||||||
|
|
||||||
|
private void toggleFullScreen() {
|
||||||
|
if( !FlatNativeMacLibrary.isLoaded() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
Window window = SwingUtilities.windowForComponent( this );
|
||||||
|
FlatNativeMacLibrary.toggleWindowFullScreen( window );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initComponents() {
|
||||||
|
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
|
||||||
|
JPanel panel1 = new JPanel();
|
||||||
|
placeholderPanel = new JPanel();
|
||||||
|
JPanel panel2 = new JPanel();
|
||||||
|
fullWindowContentCheckBox = new JCheckBox();
|
||||||
|
fullWindowContentHint = new JLabel();
|
||||||
|
transparentTitleBarCheckBox = new JCheckBox();
|
||||||
|
transparentTitleBarHint = new JLabel();
|
||||||
|
windowTitleVisibleCheckBox = new JCheckBox();
|
||||||
|
windowTitleVisibleHint = new JLabel();
|
||||||
|
JLabel buttonsSpacingLabel = new JLabel();
|
||||||
|
buttonsSpacingDefaultRadioButton = new JRadioButton();
|
||||||
|
buttonsSpacingMediumRadioButton = new JRadioButton();
|
||||||
|
buttonsSpacingLargeRadioButton = new JRadioButton();
|
||||||
|
buttonsSpacingHint = new JLabel();
|
||||||
|
JLabel fullWindowContentButtonsBoundsLabel = new JLabel();
|
||||||
|
fullWindowContentButtonsBoundsField = new JLabel();
|
||||||
|
JLabel nativeButtonsBoundsLabel = new JLabel();
|
||||||
|
nativeButtonsBoundsField = new JLabel();
|
||||||
|
JButton toggleFullScreenButton = new JButton();
|
||||||
|
|
||||||
|
//======== this ========
|
||||||
|
setLayout(new BorderLayout());
|
||||||
|
|
||||||
|
//======== panel1 ========
|
||||||
|
{
|
||||||
|
panel1.setLayout(new BorderLayout());
|
||||||
|
|
||||||
|
//======== placeholderPanel ========
|
||||||
|
{
|
||||||
|
placeholderPanel.setBackground(Color.green);
|
||||||
|
placeholderPanel.setLayout(new FlowLayout());
|
||||||
|
}
|
||||||
|
panel1.add(placeholderPanel, BorderLayout.WEST);
|
||||||
|
}
|
||||||
|
add(panel1, BorderLayout.PAGE_START);
|
||||||
|
|
||||||
|
//======== panel2 ========
|
||||||
|
{
|
||||||
|
panel2.setLayout(new MigLayout(
|
||||||
|
"ltr,insets dialog,hidemode 3",
|
||||||
|
// columns
|
||||||
|
"[left]" +
|
||||||
|
"[left]" +
|
||||||
|
"[left]" +
|
||||||
|
"[left]para" +
|
||||||
|
"[fill]",
|
||||||
|
// rows
|
||||||
|
"[]" +
|
||||||
|
"[]" +
|
||||||
|
"[]" +
|
||||||
|
"[fill]" +
|
||||||
|
"[]" +
|
||||||
|
"[]para" +
|
||||||
|
"[]"));
|
||||||
|
|
||||||
|
//---- fullWindowContentCheckBox ----
|
||||||
|
fullWindowContentCheckBox.setText("fullWindowContent");
|
||||||
|
fullWindowContentCheckBox.addActionListener(e -> fullWindowContentChanged());
|
||||||
|
panel2.add(fullWindowContentCheckBox, "cell 0 0");
|
||||||
|
|
||||||
|
//---- fullWindowContentHint ----
|
||||||
|
fullWindowContentHint.setText("requires Java 12, 11.0.8 or 8u292");
|
||||||
|
fullWindowContentHint.setForeground(Color.red);
|
||||||
|
panel2.add(fullWindowContentHint, "cell 4 0");
|
||||||
|
|
||||||
|
//---- transparentTitleBarCheckBox ----
|
||||||
|
transparentTitleBarCheckBox.setText("transparentTitleBar");
|
||||||
|
transparentTitleBarCheckBox.addActionListener(e -> transparentTitleBarChanged());
|
||||||
|
panel2.add(transparentTitleBarCheckBox, "cell 0 1");
|
||||||
|
|
||||||
|
//---- transparentTitleBarHint ----
|
||||||
|
transparentTitleBarHint.setText("requires Java 12, 11.0.8 or 8u292");
|
||||||
|
transparentTitleBarHint.setForeground(Color.red);
|
||||||
|
panel2.add(transparentTitleBarHint, "cell 4 1");
|
||||||
|
|
||||||
|
//---- windowTitleVisibleCheckBox ----
|
||||||
|
windowTitleVisibleCheckBox.setText("windowTitleVisible");
|
||||||
|
windowTitleVisibleCheckBox.addActionListener(e -> windowTitleVisibleChanged());
|
||||||
|
panel2.add(windowTitleVisibleCheckBox, "cell 0 2");
|
||||||
|
|
||||||
|
//---- windowTitleVisibleHint ----
|
||||||
|
windowTitleVisibleHint.setText("requires Java 17");
|
||||||
|
windowTitleVisibleHint.setForeground(Color.red);
|
||||||
|
panel2.add(windowTitleVisibleHint, "cell 4 2");
|
||||||
|
|
||||||
|
//---- buttonsSpacingLabel ----
|
||||||
|
buttonsSpacingLabel.setText("Buttons spacing:");
|
||||||
|
panel2.add(buttonsSpacingLabel, "cell 0 3");
|
||||||
|
|
||||||
|
//---- buttonsSpacingDefaultRadioButton ----
|
||||||
|
buttonsSpacingDefaultRadioButton.setText("Default");
|
||||||
|
buttonsSpacingDefaultRadioButton.setSelected(true);
|
||||||
|
buttonsSpacingDefaultRadioButton.addActionListener(e -> buttonsSpacingChanged());
|
||||||
|
panel2.add(buttonsSpacingDefaultRadioButton, "cell 1 3");
|
||||||
|
|
||||||
|
//---- buttonsSpacingMediumRadioButton ----
|
||||||
|
buttonsSpacingMediumRadioButton.setText("Medium");
|
||||||
|
buttonsSpacingMediumRadioButton.addActionListener(e -> buttonsSpacingChanged());
|
||||||
|
panel2.add(buttonsSpacingMediumRadioButton, "cell 2 3");
|
||||||
|
|
||||||
|
//---- buttonsSpacingLargeRadioButton ----
|
||||||
|
buttonsSpacingLargeRadioButton.setText("Large");
|
||||||
|
buttonsSpacingLargeRadioButton.addActionListener(e -> buttonsSpacingChanged());
|
||||||
|
panel2.add(buttonsSpacingLargeRadioButton, "cell 3 3");
|
||||||
|
|
||||||
|
//---- buttonsSpacingHint ----
|
||||||
|
buttonsSpacingHint.setText("requires Java 17");
|
||||||
|
buttonsSpacingHint.setForeground(Color.red);
|
||||||
|
panel2.add(buttonsSpacingHint, "cell 4 3");
|
||||||
|
|
||||||
|
//---- fullWindowContentButtonsBoundsLabel ----
|
||||||
|
fullWindowContentButtonsBoundsLabel.setText("Buttons bounds:");
|
||||||
|
panel2.add(fullWindowContentButtonsBoundsLabel, "cell 0 4");
|
||||||
|
|
||||||
|
//---- fullWindowContentButtonsBoundsField ----
|
||||||
|
fullWindowContentButtonsBoundsField.setText("null");
|
||||||
|
panel2.add(fullWindowContentButtonsBoundsField, "cell 1 4 3 1");
|
||||||
|
|
||||||
|
//---- nativeButtonsBoundsLabel ----
|
||||||
|
nativeButtonsBoundsLabel.setText("Native buttons bounds:");
|
||||||
|
panel2.add(nativeButtonsBoundsLabel, "cell 0 5");
|
||||||
|
|
||||||
|
//---- nativeButtonsBoundsField ----
|
||||||
|
nativeButtonsBoundsField.setText("null");
|
||||||
|
panel2.add(nativeButtonsBoundsField, "cell 1 5 3 1");
|
||||||
|
|
||||||
|
//---- toggleFullScreenButton ----
|
||||||
|
toggleFullScreenButton.setText("Toggle Full Screen");
|
||||||
|
toggleFullScreenButton.addActionListener(e -> toggleFullScreen());
|
||||||
|
panel2.add(toggleFullScreenButton, "cell 0 6");
|
||||||
|
}
|
||||||
|
add(panel2, BorderLayout.CENTER);
|
||||||
|
|
||||||
|
//---- buttonsSpacingButtonGroup ----
|
||||||
|
ButtonGroup buttonsSpacingButtonGroup = new ButtonGroup();
|
||||||
|
buttonsSpacingButtonGroup.add(buttonsSpacingDefaultRadioButton);
|
||||||
|
buttonsSpacingButtonGroup.add(buttonsSpacingMediumRadioButton);
|
||||||
|
buttonsSpacingButtonGroup.add(buttonsSpacingLargeRadioButton);
|
||||||
|
// JFormDesigner - End of component initialization //GEN-END:initComponents
|
||||||
|
}
|
||||||
|
|
||||||
|
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
|
||||||
|
private JPanel placeholderPanel;
|
||||||
|
private JCheckBox fullWindowContentCheckBox;
|
||||||
|
private JLabel fullWindowContentHint;
|
||||||
|
private JCheckBox transparentTitleBarCheckBox;
|
||||||
|
private JLabel transparentTitleBarHint;
|
||||||
|
private JCheckBox windowTitleVisibleCheckBox;
|
||||||
|
private JLabel windowTitleVisibleHint;
|
||||||
|
private JRadioButton buttonsSpacingDefaultRadioButton;
|
||||||
|
private JRadioButton buttonsSpacingMediumRadioButton;
|
||||||
|
private JRadioButton buttonsSpacingLargeRadioButton;
|
||||||
|
private JLabel buttonsSpacingHint;
|
||||||
|
private JLabel fullWindowContentButtonsBoundsField;
|
||||||
|
private JLabel nativeButtonsBoundsField;
|
||||||
|
// JFormDesigner - End of variables declaration //GEN-END:variables
|
||||||
|
}
|
||||||
@@ -0,0 +1,191 @@
|
|||||||
|
JFDML JFormDesigner: "8.2.1.0.348" Java: "21.0.1" encoding: "UTF-8"
|
||||||
|
|
||||||
|
new FormModel {
|
||||||
|
contentType: "form/swing"
|
||||||
|
root: new FormRoot {
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.defaultVariableLocal": true
|
||||||
|
}
|
||||||
|
add( new FormContainer( "com.formdev.flatlaf.testing.FlatTestPanel", new FormLayoutManager( class java.awt.BorderLayout ) ) {
|
||||||
|
name: "this"
|
||||||
|
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class java.awt.BorderLayout ) ) {
|
||||||
|
name: "panel1"
|
||||||
|
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class java.awt.FlowLayout ) ) {
|
||||||
|
name: "placeholderPanel"
|
||||||
|
"background": sfield java.awt.Color green
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
}, new FormLayoutConstraints( class java.lang.String ) {
|
||||||
|
"value": "West"
|
||||||
|
} )
|
||||||
|
}, new FormLayoutConstraints( class java.lang.String ) {
|
||||||
|
"value": "First"
|
||||||
|
} )
|
||||||
|
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
||||||
|
"$layoutConstraints": "ltr,insets dialog,hidemode 3"
|
||||||
|
"$columnConstraints": "[left][left][left][left]para[fill]"
|
||||||
|
"$rowConstraints": "[][][][fill][][]para[]"
|
||||||
|
} ) {
|
||||||
|
name: "panel2"
|
||||||
|
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||||
|
name: "fullWindowContentCheckBox"
|
||||||
|
"text": "fullWindowContent"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "fullWindowContentChanged", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 0"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "fullWindowContentHint"
|
||||||
|
"text": "requires Java 12, 11.0.8 or 8u292"
|
||||||
|
"foreground": sfield java.awt.Color red
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 4 0"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||||
|
name: "transparentTitleBarCheckBox"
|
||||||
|
"text": "transparentTitleBar"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "transparentTitleBarChanged", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 1"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "transparentTitleBarHint"
|
||||||
|
"text": "requires Java 12, 11.0.8 or 8u292"
|
||||||
|
"foreground": sfield java.awt.Color red
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 4 1"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||||
|
name: "windowTitleVisibleCheckBox"
|
||||||
|
"text": "windowTitleVisible"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "windowTitleVisibleChanged", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 2"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "windowTitleVisibleHint"
|
||||||
|
"text": "requires Java 17"
|
||||||
|
"foreground": sfield java.awt.Color red
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 4 2"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "buttonsSpacingLabel"
|
||||||
|
"text": "Buttons spacing:"
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 3"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JRadioButton" ) {
|
||||||
|
name: "buttonsSpacingDefaultRadioButton"
|
||||||
|
"text": "Default"
|
||||||
|
"$buttonGroup": new FormReference( "buttonsSpacingButtonGroup" )
|
||||||
|
"selected": true
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "buttonsSpacingChanged", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 3"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JRadioButton" ) {
|
||||||
|
name: "buttonsSpacingMediumRadioButton"
|
||||||
|
"text": "Medium"
|
||||||
|
"$buttonGroup": new FormReference( "buttonsSpacingButtonGroup" )
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "buttonsSpacingChanged", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 2 3"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JRadioButton" ) {
|
||||||
|
name: "buttonsSpacingLargeRadioButton"
|
||||||
|
"text": "Large"
|
||||||
|
"$buttonGroup": new FormReference( "buttonsSpacingButtonGroup" )
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "buttonsSpacingChanged", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 3 3"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "buttonsSpacingHint"
|
||||||
|
"text": "requires Java 17"
|
||||||
|
"foreground": sfield java.awt.Color red
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 4 3"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "fullWindowContentButtonsBoundsLabel"
|
||||||
|
"text": "Buttons bounds:"
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 4"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "fullWindowContentButtonsBoundsField"
|
||||||
|
"text": "null"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 4 3 1"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "nativeButtonsBoundsLabel"
|
||||||
|
"text": "Native buttons bounds:"
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 5"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "nativeButtonsBoundsField"
|
||||||
|
"text": "null"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 1 5 3 1"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JButton" ) {
|
||||||
|
name: "toggleFullScreenButton"
|
||||||
|
"text": "Toggle Full Screen"
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "toggleFullScreen", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 6"
|
||||||
|
} )
|
||||||
|
}, new FormLayoutConstraints( class java.lang.String ) {
|
||||||
|
"value": "Center"
|
||||||
|
} )
|
||||||
|
}, new FormLayoutConstraints( null ) {
|
||||||
|
"location": new java.awt.Point( 0, 0 )
|
||||||
|
"size": new java.awt.Dimension( 725, 350 )
|
||||||
|
} )
|
||||||
|
add( new FormNonVisual( "javax.swing.ButtonGroup" ) {
|
||||||
|
name: "buttonsSpacingButtonGroup"
|
||||||
|
}, new FormLayoutConstraints( null ) {
|
||||||
|
"location": new java.awt.Point( 0, 360 )
|
||||||
|
} )
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -32,8 +32,10 @@ public class FlatTestPanel
|
|||||||
int width = getWidth();
|
int width = getWidth();
|
||||||
int height = getHeight();
|
int height = getHeight();
|
||||||
|
|
||||||
g.setColor( super.getBackground() );
|
if( isOpaque() ) {
|
||||||
g.fillRect( 0, 0, width, height );
|
g.setColor( super.getBackground() );
|
||||||
|
g.fillRect( 0, 0, width, height );
|
||||||
|
}
|
||||||
|
|
||||||
if( isPaintBackgroundPattern() ) {
|
if( isPaintBackgroundPattern() ) {
|
||||||
g.setColor( Color.magenta );
|
g.setColor( Color.magenta );
|
||||||
|
|||||||
@@ -41,6 +41,9 @@ import net.miginfocom.swing.*;
|
|||||||
public class FlatWindowDecorationsTest
|
public class FlatWindowDecorationsTest
|
||||||
extends FlatTestPanel
|
extends FlatTestPanel
|
||||||
{
|
{
|
||||||
|
// same as in FlatTitlePane
|
||||||
|
private static final String KEY_DEBUG_SHOW_RECTANGLES = "FlatLaf.debug.titlebar.showRectangles";
|
||||||
|
|
||||||
public static void main( String[] args ) {
|
public static void main( String[] args ) {
|
||||||
SwingUtilities.invokeLater( () -> {
|
SwingUtilities.invokeLater( () -> {
|
||||||
if( SystemInfo.isLinux ) {
|
if( SystemInfo.isLinux ) {
|
||||||
@@ -51,7 +54,7 @@ public class FlatWindowDecorationsTest
|
|||||||
|
|
||||||
FlatTestFrame frame = FlatTestFrame.create( args, "FlatWindowDecorationsTest" );
|
FlatTestFrame frame = FlatTestFrame.create( args, "FlatWindowDecorationsTest" );
|
||||||
frame.applyComponentOrientationToFrame = true;
|
frame.applyComponentOrientationToFrame = true;
|
||||||
UIManager.put( "FlatLaf.debug.titlebar.showRectangles", true );
|
UIManager.put( KEY_DEBUG_SHOW_RECTANGLES, true );
|
||||||
|
|
||||||
Class<?> cls = FlatWindowDecorationsTest.class;
|
Class<?> cls = FlatWindowDecorationsTest.class;
|
||||||
List<Image> images = Arrays.asList(
|
List<Image> images = Arrays.asList(
|
||||||
@@ -76,6 +79,14 @@ public class FlatWindowDecorationsTest
|
|||||||
initComponents();
|
initComponents();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void updateUI() {
|
||||||
|
super.updateUI();
|
||||||
|
|
||||||
|
if( translucentWindowBackgroundCheckBox != null )
|
||||||
|
translucentWindowBackgroundChanged();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addNotify() {
|
public void addNotify() {
|
||||||
super.addNotify();
|
super.addNotify();
|
||||||
@@ -109,6 +120,14 @@ public class FlatWindowDecorationsTest
|
|||||||
rootPane.addPropertyChangeListener( "windowDecorationStyle", e -> {
|
rootPane.addPropertyChangeListener( "windowDecorationStyle", e -> {
|
||||||
updateDecorationStyleRadioButtons( rootPane );
|
updateDecorationStyleRadioButtons( rootPane );
|
||||||
} );
|
} );
|
||||||
|
rootPane.addPropertyChangeListener( FlatClientProperties.FULL_WINDOW_CONTENT_BUTTONS_BOUNDS, e -> {
|
||||||
|
Rectangle bounds = (Rectangle) e.getNewValue();
|
||||||
|
if( bounds != null ) {
|
||||||
|
fullWindowContentButtonsBoundsField.setText( bounds.width + ", " + bounds.height
|
||||||
|
+ " @ " + bounds.x + ", " + bounds.y );
|
||||||
|
} else
|
||||||
|
fullWindowContentButtonsBoundsField.setText( "null" );
|
||||||
|
} );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -237,6 +256,27 @@ public class FlatWindowDecorationsTest
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void translucentWindowBackgroundChanged() {
|
||||||
|
boolean selected = translucentWindowBackgroundCheckBox.isSelected();
|
||||||
|
if( selected && !undecoratedCheckBox.isSelected() ) {
|
||||||
|
undecoratedCheckBox.setSelected( true );
|
||||||
|
undecoratedChanged();
|
||||||
|
}
|
||||||
|
undecoratedCheckBox.setEnabled( !selected );
|
||||||
|
|
||||||
|
Color background = selected
|
||||||
|
? new Color( 100, 0, 0, 100 )
|
||||||
|
: UIManager.getColor( "control" );
|
||||||
|
|
||||||
|
Window window = SwingUtilities.windowForComponent( this );
|
||||||
|
window.setBackground( background );
|
||||||
|
|
||||||
|
for( Component c = this; c != null; c = c.getParent() ) {
|
||||||
|
if( c instanceof JComponent )
|
||||||
|
LookAndFeel.installProperty( (JComponent) c, "opaque", !selected );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void addMenu() {
|
private void addMenu() {
|
||||||
JMenu menu = new JMenu( "Hello" );
|
JMenu menu = new JMenu( "Hello" );
|
||||||
menu.add( new JMenuItem( "world" ) );
|
menu.add( new JMenuItem( "world" ) );
|
||||||
@@ -280,12 +320,21 @@ debug*/
|
|||||||
JLabel caption = new JLabel( "Caption" );
|
JLabel caption = new JLabel( "Caption" );
|
||||||
caption.setBackground( Color.green );
|
caption.setBackground( Color.green );
|
||||||
caption.setOpaque( true );
|
caption.setOpaque( true );
|
||||||
caption.putClientProperty( FlatClientProperties.COMPONENT_TITLE_BAR_CAPTION, true );
|
|
||||||
|
|
||||||
menuBar.add( caption );
|
menuBar.add( caption );
|
||||||
menuBar.revalidate();
|
menuBar.revalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addTextField() {
|
||||||
|
JTextField textField = new JTextField( "text", 10 );
|
||||||
|
|
||||||
|
JPanel panel = new JPanel( new GridBagLayout() );
|
||||||
|
panel.add( textField, new GridBagConstraints() );
|
||||||
|
|
||||||
|
menuBar.add( panel );
|
||||||
|
menuBar.revalidate();
|
||||||
|
}
|
||||||
|
|
||||||
private void removeMenu() {
|
private void removeMenu() {
|
||||||
int menuCount = menuBar.getMenuCount();
|
int menuCount = menuBar.getMenuCount();
|
||||||
if( menuCount <= 0 )
|
if( menuCount <= 0 )
|
||||||
@@ -486,13 +535,31 @@ debug*/
|
|||||||
rootPane.putClientProperty( FlatClientProperties.TITLE_BAR_SHOW_CLOSE, showCloseCheckBox.isSelected() ? null : false );
|
rootPane.putClientProperty( FlatClientProperties.TITLE_BAR_SHOW_CLOSE, showCloseCheckBox.isSelected() ? null : false );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void fullWindowContentChanged() {
|
||||||
|
JRootPane rootPane = getWindowRootPane();
|
||||||
|
if( rootPane != null ) {
|
||||||
|
boolean selected = fullWindowContentCheckBox.isSelected();
|
||||||
|
rootPane.putClientProperty( FlatClientProperties.FULL_WINDOW_CONTENT, selected ? true : null );
|
||||||
|
|
||||||
|
showIconCheckBox.setEnabled( !selected );
|
||||||
|
showTitleCheckBox.setEnabled( !selected );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private JRootPane getWindowRootPane() {
|
private JRootPane getWindowRootPane() {
|
||||||
Window window = SwingUtilities.windowForComponent( this );
|
Window window = SwingUtilities.windowForComponent( this );
|
||||||
if( window instanceof JFrame )
|
return (window instanceof RootPaneContainer)
|
||||||
return ((JFrame)window).getRootPane();
|
? ((RootPaneContainer)window).getRootPane()
|
||||||
else if( window instanceof JDialog )
|
: null;
|
||||||
return ((JDialog)window).getRootPane();
|
}
|
||||||
return null;
|
|
||||||
|
private void showRectangles() {
|
||||||
|
JRootPane rootPane = getWindowRootPane();
|
||||||
|
if( rootPane != null ) {
|
||||||
|
UIManager.put( KEY_DEBUG_SHOW_RECTANGLES, showRectanglesCheckBox.isSelected() );
|
||||||
|
rootPane.revalidate();
|
||||||
|
rootPane.repaint();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initComponents() {
|
private void initComponents() {
|
||||||
@@ -509,6 +576,9 @@ debug*/
|
|||||||
showIconifyCheckBox = new JCheckBox();
|
showIconifyCheckBox = new JCheckBox();
|
||||||
showMaximizeCheckBox = new JCheckBox();
|
showMaximizeCheckBox = new JCheckBox();
|
||||||
showCloseCheckBox = new JCheckBox();
|
showCloseCheckBox = new JCheckBox();
|
||||||
|
fullWindowContentCheckBox = new JCheckBox();
|
||||||
|
JLabel fullWindowContentButtonsBoundsLabel = new JLabel();
|
||||||
|
fullWindowContentButtonsBoundsField = new JLabel();
|
||||||
JPanel panel6 = new JPanel();
|
JPanel panel6 = new JPanel();
|
||||||
menuBarCheckBox = new JCheckBox();
|
menuBarCheckBox = new JCheckBox();
|
||||||
menuBarEmbeddedCheckBox = new JCheckBox();
|
menuBarEmbeddedCheckBox = new JCheckBox();
|
||||||
@@ -519,6 +589,7 @@ debug*/
|
|||||||
addMenuButton = new JButton();
|
addMenuButton = new JButton();
|
||||||
addGlueButton = new JButton();
|
addGlueButton = new JButton();
|
||||||
addCaptionButton = new JButton();
|
addCaptionButton = new JButton();
|
||||||
|
addTextFieldButton = new JButton();
|
||||||
removeMenuButton = new JButton();
|
removeMenuButton = new JButton();
|
||||||
changeMenuButton = new JButton();
|
changeMenuButton = new JButton();
|
||||||
changeTitleButton = new JButton();
|
changeTitleButton = new JButton();
|
||||||
@@ -543,11 +614,13 @@ debug*/
|
|||||||
colorizeTitleBarCheckBox = new JCheckBox();
|
colorizeTitleBarCheckBox = new JCheckBox();
|
||||||
colorizeMenuBarCheckBox = new JCheckBox();
|
colorizeMenuBarCheckBox = new JCheckBox();
|
||||||
colorizeMenusCheckBox = new JCheckBox();
|
colorizeMenusCheckBox = new JCheckBox();
|
||||||
|
translucentWindowBackgroundCheckBox = new JCheckBox();
|
||||||
JButton openDialogButton = new JButton();
|
JButton openDialogButton = new JButton();
|
||||||
JButton openFrameButton = new JButton();
|
JButton openFrameButton = new JButton();
|
||||||
typeNormalRadioButton = new JRadioButton();
|
typeNormalRadioButton = new JRadioButton();
|
||||||
typeUtilityRadioButton = new JRadioButton();
|
typeUtilityRadioButton = new JRadioButton();
|
||||||
typeSmallRadioButton = new JRadioButton();
|
typeSmallRadioButton = new JRadioButton();
|
||||||
|
showRectanglesCheckBox = new JCheckBox();
|
||||||
menuBar = new JMenuBar();
|
menuBar = new JMenuBar();
|
||||||
JMenu fileMenu = new JMenu();
|
JMenu fileMenu = new JMenu();
|
||||||
JMenuItem newMenuItem = new JMenuItem();
|
JMenuItem newMenuItem = new JMenuItem();
|
||||||
@@ -586,6 +659,7 @@ debug*/
|
|||||||
// rows
|
// rows
|
||||||
"[fill]" +
|
"[fill]" +
|
||||||
"[fill]" +
|
"[fill]" +
|
||||||
|
"[]" +
|
||||||
"[]"));
|
"[]"));
|
||||||
|
|
||||||
//======== panel7 ========
|
//======== panel7 ========
|
||||||
@@ -643,6 +717,8 @@ debug*/
|
|||||||
"[]" +
|
"[]" +
|
||||||
"[]" +
|
"[]" +
|
||||||
"[]" +
|
"[]" +
|
||||||
|
"[]rel" +
|
||||||
|
"[]rel" +
|
||||||
"[]"));
|
"[]"));
|
||||||
|
|
||||||
//---- showIconCheckBox ----
|
//---- showIconCheckBox ----
|
||||||
@@ -673,6 +749,19 @@ debug*/
|
|||||||
showCloseCheckBox.setSelected(true);
|
showCloseCheckBox.setSelected(true);
|
||||||
showCloseCheckBox.addActionListener(e -> showCloseChanged());
|
showCloseCheckBox.addActionListener(e -> showCloseChanged());
|
||||||
panel4.add(showCloseCheckBox, "cell 0 4");
|
panel4.add(showCloseCheckBox, "cell 0 4");
|
||||||
|
|
||||||
|
//---- fullWindowContentCheckBox ----
|
||||||
|
fullWindowContentCheckBox.setText("full window content");
|
||||||
|
fullWindowContentCheckBox.addActionListener(e -> fullWindowContentChanged());
|
||||||
|
panel4.add(fullWindowContentCheckBox, "cell 0 5");
|
||||||
|
|
||||||
|
//---- fullWindowContentButtonsBoundsLabel ----
|
||||||
|
fullWindowContentButtonsBoundsLabel.setText("Buttons bounds:");
|
||||||
|
panel4.add(fullWindowContentButtonsBoundsLabel, "cell 0 6");
|
||||||
|
|
||||||
|
//---- fullWindowContentButtonsBoundsField ----
|
||||||
|
fullWindowContentButtonsBoundsField.setText("null");
|
||||||
|
panel4.add(fullWindowContentButtonsBoundsField, "cell 0 6");
|
||||||
}
|
}
|
||||||
add(panel4, "cell 1 0");
|
add(panel4, "cell 1 0");
|
||||||
|
|
||||||
@@ -731,6 +820,7 @@ debug*/
|
|||||||
"[]" +
|
"[]" +
|
||||||
"[]" +
|
"[]" +
|
||||||
"[]" +
|
"[]" +
|
||||||
|
"[]" +
|
||||||
"[]unrel" +
|
"[]unrel" +
|
||||||
"[]"));
|
"[]"));
|
||||||
|
|
||||||
@@ -749,20 +839,25 @@ debug*/
|
|||||||
addCaptionButton.addActionListener(e -> addCaption());
|
addCaptionButton.addActionListener(e -> addCaption());
|
||||||
panel3.add(addCaptionButton, "cell 0 2");
|
panel3.add(addCaptionButton, "cell 0 2");
|
||||||
|
|
||||||
|
//---- addTextFieldButton ----
|
||||||
|
addTextFieldButton.setText("Add text field");
|
||||||
|
addTextFieldButton.addActionListener(e -> addTextField());
|
||||||
|
panel3.add(addTextFieldButton, "cell 0 3");
|
||||||
|
|
||||||
//---- removeMenuButton ----
|
//---- removeMenuButton ----
|
||||||
removeMenuButton.setText("Remove menu");
|
removeMenuButton.setText("Remove menu");
|
||||||
removeMenuButton.addActionListener(e -> removeMenu());
|
removeMenuButton.addActionListener(e -> removeMenu());
|
||||||
panel3.add(removeMenuButton, "cell 0 3");
|
panel3.add(removeMenuButton, "cell 0 4");
|
||||||
|
|
||||||
//---- changeMenuButton ----
|
//---- changeMenuButton ----
|
||||||
changeMenuButton.setText("Change menu");
|
changeMenuButton.setText("Change menu");
|
||||||
changeMenuButton.addActionListener(e -> changeMenu());
|
changeMenuButton.addActionListener(e -> changeMenu());
|
||||||
panel3.add(changeMenuButton, "cell 0 4");
|
panel3.add(changeMenuButton, "cell 0 5");
|
||||||
|
|
||||||
//---- changeTitleButton ----
|
//---- changeTitleButton ----
|
||||||
changeTitleButton.setText("Change title");
|
changeTitleButton.setText("Change title");
|
||||||
changeTitleButton.addActionListener(e -> changeTitle());
|
changeTitleButton.addActionListener(e -> changeTitle());
|
||||||
panel3.add(changeTitleButton, "cell 0 5");
|
panel3.add(changeTitleButton, "cell 0 6");
|
||||||
}
|
}
|
||||||
add(panel3, "cell 3 0 1 2,aligny top,growy 0");
|
add(panel3, "cell 3 0 1 2,aligny top,growy 0");
|
||||||
|
|
||||||
@@ -885,6 +980,7 @@ debug*/
|
|||||||
"[]" +
|
"[]" +
|
||||||
"[]" +
|
"[]" +
|
||||||
"[]" +
|
"[]" +
|
||||||
|
"[]para" +
|
||||||
"[]"));
|
"[]"));
|
||||||
|
|
||||||
//---- unifiedBackgroundCheckBox ----
|
//---- unifiedBackgroundCheckBox ----
|
||||||
@@ -906,6 +1002,11 @@ debug*/
|
|||||||
colorizeMenusCheckBox.setText("colorize menus");
|
colorizeMenusCheckBox.setText("colorize menus");
|
||||||
colorizeMenusCheckBox.addActionListener(e -> colorizeMenus());
|
colorizeMenusCheckBox.addActionListener(e -> colorizeMenus());
|
||||||
panel5.add(colorizeMenusCheckBox, "cell 0 3");
|
panel5.add(colorizeMenusCheckBox, "cell 0 3");
|
||||||
|
|
||||||
|
//---- translucentWindowBackgroundCheckBox ----
|
||||||
|
translucentWindowBackgroundCheckBox.setText("translucent window background");
|
||||||
|
translucentWindowBackgroundCheckBox.addActionListener(e -> translucentWindowBackgroundChanged());
|
||||||
|
panel5.add(translucentWindowBackgroundCheckBox, "cell 0 4");
|
||||||
}
|
}
|
||||||
add(panel5, "cell 2 1");
|
add(panel5, "cell 2 1");
|
||||||
|
|
||||||
@@ -933,6 +1034,12 @@ debug*/
|
|||||||
typeSmallRadioButton.setText("Small");
|
typeSmallRadioButton.setText("Small");
|
||||||
add(typeSmallRadioButton, "cell 0 2 3 1");
|
add(typeSmallRadioButton, "cell 0 2 3 1");
|
||||||
|
|
||||||
|
//---- showRectanglesCheckBox ----
|
||||||
|
showRectanglesCheckBox.setText("Show debug title bar rectangles");
|
||||||
|
showRectanglesCheckBox.setSelected(true);
|
||||||
|
showRectanglesCheckBox.addActionListener(e -> showRectangles());
|
||||||
|
add(showRectanglesCheckBox, "cell 0 3");
|
||||||
|
|
||||||
//======== menuBar ========
|
//======== menuBar ========
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -1140,6 +1247,8 @@ debug*/
|
|||||||
private JCheckBox showIconifyCheckBox;
|
private JCheckBox showIconifyCheckBox;
|
||||||
private JCheckBox showMaximizeCheckBox;
|
private JCheckBox showMaximizeCheckBox;
|
||||||
private JCheckBox showCloseCheckBox;
|
private JCheckBox showCloseCheckBox;
|
||||||
|
private JCheckBox fullWindowContentCheckBox;
|
||||||
|
private JLabel fullWindowContentButtonsBoundsField;
|
||||||
private JCheckBox menuBarCheckBox;
|
private JCheckBox menuBarCheckBox;
|
||||||
private JCheckBox menuBarEmbeddedCheckBox;
|
private JCheckBox menuBarEmbeddedCheckBox;
|
||||||
private JCheckBox menuBarVisibleCheckBox;
|
private JCheckBox menuBarVisibleCheckBox;
|
||||||
@@ -1148,6 +1257,7 @@ debug*/
|
|||||||
private JButton addMenuButton;
|
private JButton addMenuButton;
|
||||||
private JButton addGlueButton;
|
private JButton addGlueButton;
|
||||||
private JButton addCaptionButton;
|
private JButton addCaptionButton;
|
||||||
|
private JButton addTextFieldButton;
|
||||||
private JButton removeMenuButton;
|
private JButton removeMenuButton;
|
||||||
private JButton changeMenuButton;
|
private JButton changeMenuButton;
|
||||||
private JButton changeTitleButton;
|
private JButton changeTitleButton;
|
||||||
@@ -1169,9 +1279,11 @@ debug*/
|
|||||||
private JCheckBox colorizeTitleBarCheckBox;
|
private JCheckBox colorizeTitleBarCheckBox;
|
||||||
private JCheckBox colorizeMenuBarCheckBox;
|
private JCheckBox colorizeMenuBarCheckBox;
|
||||||
private JCheckBox colorizeMenusCheckBox;
|
private JCheckBox colorizeMenusCheckBox;
|
||||||
|
private JCheckBox translucentWindowBackgroundCheckBox;
|
||||||
private JRadioButton typeNormalRadioButton;
|
private JRadioButton typeNormalRadioButton;
|
||||||
private JRadioButton typeUtilityRadioButton;
|
private JRadioButton typeUtilityRadioButton;
|
||||||
private JRadioButton typeSmallRadioButton;
|
private JRadioButton typeSmallRadioButton;
|
||||||
|
private JCheckBox showRectanglesCheckBox;
|
||||||
private JMenuBar menuBar;
|
private JMenuBar menuBar;
|
||||||
// JFormDesigner - End of variables declaration //GEN-END:variables
|
// JFormDesigner - End of variables declaration //GEN-END:variables
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
JFDML JFormDesigner: "8.1.0.0.283" Java: "19.0.2" encoding: "UTF-8"
|
JFDML JFormDesigner: "8.2.1.0.348" Java: "21.0.1" encoding: "UTF-8"
|
||||||
|
|
||||||
new FormModel {
|
new FormModel {
|
||||||
contentType: "form/swing"
|
contentType: "form/swing"
|
||||||
@@ -9,7 +9,7 @@ new FormModel {
|
|||||||
add( new FormContainer( "com.formdev.flatlaf.testing.FlatTestPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
add( new FormContainer( "com.formdev.flatlaf.testing.FlatTestPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
||||||
"$layoutConstraints": "ltr,insets dialog,hidemode 3"
|
"$layoutConstraints": "ltr,insets dialog,hidemode 3"
|
||||||
"$columnConstraints": "[left][fill][fill][fill]"
|
"$columnConstraints": "[left][fill][fill][fill]"
|
||||||
"$rowConstraints": "[fill][fill][]"
|
"$rowConstraints": "[fill][fill][][]"
|
||||||
} ) {
|
} ) {
|
||||||
name: "this"
|
name: "this"
|
||||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
||||||
@@ -77,7 +77,7 @@ new FormModel {
|
|||||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
||||||
"$layoutConstraints": "ltr,hidemode 3,gap 0 0"
|
"$layoutConstraints": "ltr,hidemode 3,gap 0 0"
|
||||||
"$columnConstraints": "[grow,left]"
|
"$columnConstraints": "[grow,left]"
|
||||||
"$rowConstraints": "[][][][][]"
|
"$rowConstraints": "[][][][][]rel[]rel[]"
|
||||||
} ) {
|
} ) {
|
||||||
name: "panel4"
|
name: "panel4"
|
||||||
"border": new javax.swing.border.TitledBorder( "Title Bar" )
|
"border": new javax.swing.border.TitledBorder( "Title Bar" )
|
||||||
@@ -135,6 +135,31 @@ new FormModel {
|
|||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
"value": "cell 0 4"
|
"value": "cell 0 4"
|
||||||
} )
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||||
|
name: "fullWindowContentCheckBox"
|
||||||
|
"text": "full window content"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "fullWindowContentChanged", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 5"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "fullWindowContentButtonsBoundsLabel"
|
||||||
|
"text": "Buttons bounds:"
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 6"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "fullWindowContentButtonsBoundsField"
|
||||||
|
"text": "null"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 6"
|
||||||
|
} )
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
"value": "cell 1 0"
|
"value": "cell 1 0"
|
||||||
} )
|
} )
|
||||||
@@ -204,7 +229,7 @@ new FormModel {
|
|||||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
||||||
"$layoutConstraints": "hidemode 3"
|
"$layoutConstraints": "hidemode 3"
|
||||||
"$columnConstraints": "[fill]"
|
"$columnConstraints": "[fill]"
|
||||||
"$rowConstraints": "[][][][][]unrel[]"
|
"$rowConstraints": "[][][][][][]unrel[]"
|
||||||
} ) {
|
} ) {
|
||||||
name: "panel3"
|
name: "panel3"
|
||||||
add( new FormComponent( "javax.swing.JButton" ) {
|
add( new FormComponent( "javax.swing.JButton" ) {
|
||||||
@@ -237,6 +262,16 @@ new FormModel {
|
|||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
"value": "cell 0 2"
|
"value": "cell 0 2"
|
||||||
} )
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JButton" ) {
|
||||||
|
name: "addTextFieldButton"
|
||||||
|
"text": "Add text field"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "addTextField", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 3"
|
||||||
|
} )
|
||||||
add( new FormComponent( "javax.swing.JButton" ) {
|
add( new FormComponent( "javax.swing.JButton" ) {
|
||||||
name: "removeMenuButton"
|
name: "removeMenuButton"
|
||||||
"text": "Remove menu"
|
"text": "Remove menu"
|
||||||
@@ -245,7 +280,7 @@ new FormModel {
|
|||||||
}
|
}
|
||||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "removeMenu", false ) )
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "removeMenu", false ) )
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
"value": "cell 0 3"
|
"value": "cell 0 4"
|
||||||
} )
|
} )
|
||||||
add( new FormComponent( "javax.swing.JButton" ) {
|
add( new FormComponent( "javax.swing.JButton" ) {
|
||||||
name: "changeMenuButton"
|
name: "changeMenuButton"
|
||||||
@@ -255,7 +290,7 @@ new FormModel {
|
|||||||
}
|
}
|
||||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "changeMenu", false ) )
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "changeMenu", false ) )
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
"value": "cell 0 4"
|
"value": "cell 0 5"
|
||||||
} )
|
} )
|
||||||
add( new FormComponent( "javax.swing.JButton" ) {
|
add( new FormComponent( "javax.swing.JButton" ) {
|
||||||
name: "changeTitleButton"
|
name: "changeTitleButton"
|
||||||
@@ -265,7 +300,7 @@ new FormModel {
|
|||||||
}
|
}
|
||||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "changeTitle", false ) )
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "changeTitle", false ) )
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
"value": "cell 0 5"
|
"value": "cell 0 6"
|
||||||
} )
|
} )
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
"value": "cell 3 0 1 2,aligny top,growy 0"
|
"value": "cell 3 0 1 2,aligny top,growy 0"
|
||||||
@@ -449,7 +484,7 @@ new FormModel {
|
|||||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
||||||
"$layoutConstraints": "ltr,hidemode 3,gap 0 0"
|
"$layoutConstraints": "ltr,hidemode 3,gap 0 0"
|
||||||
"$columnConstraints": "[left]"
|
"$columnConstraints": "[left]"
|
||||||
"$rowConstraints": "[][][][]"
|
"$rowConstraints": "[][][][]para[]"
|
||||||
} ) {
|
} ) {
|
||||||
name: "panel5"
|
name: "panel5"
|
||||||
"border": new javax.swing.border.TitledBorder( "Color" )
|
"border": new javax.swing.border.TitledBorder( "Color" )
|
||||||
@@ -493,6 +528,16 @@ new FormModel {
|
|||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
"value": "cell 0 3"
|
"value": "cell 0 3"
|
||||||
} )
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||||
|
name: "translucentWindowBackgroundCheckBox"
|
||||||
|
"text": "translucent window background"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "translucentWindowBackgroundChanged", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 4"
|
||||||
|
} )
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
"value": "cell 2 1"
|
"value": "cell 2 1"
|
||||||
} )
|
} )
|
||||||
@@ -542,6 +587,17 @@ new FormModel {
|
|||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
"value": "cell 0 2 3 1"
|
"value": "cell 0 2 3 1"
|
||||||
} )
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||||
|
name: "showRectanglesCheckBox"
|
||||||
|
"text": "Show debug title bar rectangles"
|
||||||
|
"selected": true
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "showRectangles", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 3"
|
||||||
|
} )
|
||||||
}, new FormLayoutConstraints( null ) {
|
}, new FormLayoutConstraints( null ) {
|
||||||
"location": new java.awt.Point( 0, 0 )
|
"location": new java.awt.Point( 0, 0 )
|
||||||
"size": new java.awt.Dimension( 960, 495 )
|
"size": new java.awt.Dimension( 960, 495 )
|
||||||
|
|||||||
@@ -119,10 +119,9 @@ public class UIDefaultsDump
|
|||||||
//
|
//
|
||||||
// dump( "com.jgoodies.looks.plastic.PlasticLookAndFeel", dir, false );
|
// dump( "com.jgoodies.looks.plastic.PlasticLookAndFeel", dir, false );
|
||||||
// dump( "com.jgoodies.looks.windows.WindowsLookAndFeel", dir, false );
|
// dump( "com.jgoodies.looks.windows.WindowsLookAndFeel", dir, false );
|
||||||
// dump( "com.alee.laf.WebLookAndFeel", dir, false );
|
|
||||||
// try {
|
// try {
|
||||||
// EventQueue.invokeAndWait( () -> {
|
// SwingUtilities.invokeAndWait( () -> {
|
||||||
// dump( "org.pushingpixels.substance.api.skin.SubstanceGraphiteAquaLookAndFeel", dir, false );
|
// dump( "org.pushingpixels.radiance.theming.api.skin.RadianceGraphiteAquaLookAndFeel", dir, false );
|
||||||
// } );
|
// } );
|
||||||
// } catch( Exception ex ) {
|
// } catch( Exception ex ) {
|
||||||
// // TODO Auto-generated catch block
|
// // TODO Auto-generated catch block
|
||||||
@@ -673,7 +672,7 @@ public class UIDefaultsDump
|
|||||||
|
|
||||||
switch( borderClassName ) {
|
switch( borderClassName ) {
|
||||||
case "com.apple.laf.AquaToolBarUI$ToolBarBorder":
|
case "com.apple.laf.AquaToolBarUI$ToolBarBorder":
|
||||||
case "org.pushingpixels.substance.internal.utils.border.SubstanceToolBarBorder":
|
case "org.pushingpixels.radiance.theming.internal.utils.border.RadianceToolBarBorder":
|
||||||
c = new JToolBar();
|
c = new JToolBar();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|||||||
@@ -68,6 +68,20 @@ public class UIDefaultsKeysDump
|
|||||||
collectKeys( FlatDarculaLaf.class.getName(), keys );
|
collectKeys( FlatDarculaLaf.class.getName(), keys );
|
||||||
collectKeys( FlatTestLaf.class.getName(), keys );
|
collectKeys( FlatTestLaf.class.getName(), keys );
|
||||||
|
|
||||||
|
// remove unused keys (defined in BasicLookAndFeel)
|
||||||
|
keys.remove( "Button.textIconGap" );
|
||||||
|
keys.remove( "Button.textShiftOffset" );
|
||||||
|
keys.remove( "CheckBox.textIconGap" );
|
||||||
|
keys.remove( "CheckBox.textShiftOffset" );
|
||||||
|
keys.remove( "RadioButton.textIconGap" );
|
||||||
|
keys.remove( "RadioButton.textShiftOffset" );
|
||||||
|
keys.remove( "TabbedPane.contentOpaque" );
|
||||||
|
keys.remove( "TabbedPane.selectedTabPadInsets" );
|
||||||
|
keys.remove( "TabbedPane.shadow" );
|
||||||
|
keys.remove( "TabbedPane.tabsOverlapBorder" );
|
||||||
|
keys.remove( "ToggleButton.textIconGap" );
|
||||||
|
keys.remove( "ToggleButton.textShiftOffset" );
|
||||||
|
|
||||||
// write key file
|
// write key file
|
||||||
try( Writer fileWriter = new BufferedWriter( new OutputStreamWriter(
|
try( Writer fileWriter = new BufferedWriter( new OutputStreamWriter(
|
||||||
new FileOutputStream( keysFile ), StandardCharsets.UTF_8 ) ) )
|
new FileOutputStream( keysFile ), StandardCharsets.UTF_8 ) ) )
|
||||||
|
|||||||
@@ -64,8 +64,6 @@ Button.selectedForeground
|
|||||||
Button.shadow
|
Button.shadow
|
||||||
Button.startBackground
|
Button.startBackground
|
||||||
Button.startBorderColor
|
Button.startBorderColor
|
||||||
Button.textIconGap
|
|
||||||
Button.textShiftOffset
|
|
||||||
Button.toolbar.disabledSelectedBackground
|
Button.toolbar.disabledSelectedBackground
|
||||||
Button.toolbar.disabledSelectedForeground
|
Button.toolbar.disabledSelectedForeground
|
||||||
Button.toolbar.hoverBackground
|
Button.toolbar.hoverBackground
|
||||||
@@ -149,8 +147,6 @@ CheckBox.icon[filled].selectedBorderColor
|
|||||||
CheckBox.icon[filled].selectedBorderWidth
|
CheckBox.icon[filled].selectedBorderWidth
|
||||||
CheckBox.margin
|
CheckBox.margin
|
||||||
CheckBox.rollover
|
CheckBox.rollover
|
||||||
CheckBox.textIconGap
|
|
||||||
CheckBox.textShiftOffset
|
|
||||||
CheckBoxMenuItem.acceleratorForeground
|
CheckBoxMenuItem.acceleratorForeground
|
||||||
CheckBoxMenuItem.acceleratorSelectionForeground
|
CheckBoxMenuItem.acceleratorSelectionForeground
|
||||||
CheckBoxMenuItem.arrowIcon
|
CheckBoxMenuItem.arrowIcon
|
||||||
@@ -655,8 +651,6 @@ RadioButton.light
|
|||||||
RadioButton.margin
|
RadioButton.margin
|
||||||
RadioButton.rollover
|
RadioButton.rollover
|
||||||
RadioButton.shadow
|
RadioButton.shadow
|
||||||
RadioButton.textIconGap
|
|
||||||
RadioButton.textShiftOffset
|
|
||||||
RadioButtonMenuItem.acceleratorForeground
|
RadioButtonMenuItem.acceleratorForeground
|
||||||
RadioButtonMenuItem.acceleratorSelectionForeground
|
RadioButtonMenuItem.acceleratorSelectionForeground
|
||||||
RadioButtonMenuItem.arrowIcon
|
RadioButtonMenuItem.arrowIcon
|
||||||
@@ -855,7 +849,6 @@ TabbedPane.closePressedBackground
|
|||||||
TabbedPane.closePressedForeground
|
TabbedPane.closePressedForeground
|
||||||
TabbedPane.closeSize
|
TabbedPane.closeSize
|
||||||
TabbedPane.contentAreaColor
|
TabbedPane.contentAreaColor
|
||||||
TabbedPane.contentOpaque
|
|
||||||
TabbedPane.contentSeparatorHeight
|
TabbedPane.contentSeparatorHeight
|
||||||
TabbedPane.darkShadow
|
TabbedPane.darkShadow
|
||||||
TabbedPane.disabledForeground
|
TabbedPane.disabledForeground
|
||||||
@@ -881,9 +874,7 @@ TabbedPane.selectedBackground
|
|||||||
TabbedPane.selectedForeground
|
TabbedPane.selectedForeground
|
||||||
TabbedPane.selectedInsets
|
TabbedPane.selectedInsets
|
||||||
TabbedPane.selectedLabelShift
|
TabbedPane.selectedLabelShift
|
||||||
TabbedPane.selectedTabPadInsets
|
|
||||||
TabbedPane.selectionFollowsFocus
|
TabbedPane.selectionFollowsFocus
|
||||||
TabbedPane.shadow
|
|
||||||
TabbedPane.showTabSeparators
|
TabbedPane.showTabSeparators
|
||||||
TabbedPane.tabAlignment
|
TabbedPane.tabAlignment
|
||||||
TabbedPane.tabArc
|
TabbedPane.tabArc
|
||||||
@@ -901,7 +892,6 @@ TabbedPane.tabSeparatorsFullHeight
|
|||||||
TabbedPane.tabType
|
TabbedPane.tabType
|
||||||
TabbedPane.tabWidthMode
|
TabbedPane.tabWidthMode
|
||||||
TabbedPane.tabsOpaque
|
TabbedPane.tabsOpaque
|
||||||
TabbedPane.tabsOverlapBorder
|
|
||||||
TabbedPane.tabsPopupPolicy
|
TabbedPane.tabsPopupPolicy
|
||||||
TabbedPane.textIconGap
|
TabbedPane.textIconGap
|
||||||
TabbedPane.underlineColor
|
TabbedPane.underlineColor
|
||||||
@@ -920,6 +910,7 @@ Table.dropCellBackground
|
|||||||
Table.dropCellForeground
|
Table.dropCellForeground
|
||||||
Table.dropLineColor
|
Table.dropLineColor
|
||||||
Table.dropLineShortColor
|
Table.dropLineShortColor
|
||||||
|
Table.editorSelectAllOnStartEditing
|
||||||
Table.focusCellBackground
|
Table.focusCellBackground
|
||||||
Table.focusCellForeground
|
Table.focusCellForeground
|
||||||
Table.focusCellHighlightBorder
|
Table.focusCellHighlightBorder
|
||||||
@@ -928,6 +919,7 @@ Table.font
|
|||||||
Table.foreground
|
Table.foreground
|
||||||
Table.gridColor
|
Table.gridColor
|
||||||
Table.intercellSpacing
|
Table.intercellSpacing
|
||||||
|
Table.paintOutsideAlternateRows
|
||||||
Table.rowHeight
|
Table.rowHeight
|
||||||
Table.scrollPaneBorder
|
Table.scrollPaneBorder
|
||||||
Table.selectionBackground
|
Table.selectionBackground
|
||||||
@@ -1047,7 +1039,6 @@ TitlePane.inactiveBackground
|
|||||||
TitlePane.inactiveForeground
|
TitlePane.inactiveForeground
|
||||||
TitlePane.maximizeIcon
|
TitlePane.maximizeIcon
|
||||||
TitlePane.menuBarEmbedded
|
TitlePane.menuBarEmbedded
|
||||||
TitlePane.menuBarResizeHeight
|
|
||||||
TitlePane.menuBarTitleGap
|
TitlePane.menuBarTitleGap
|
||||||
TitlePane.menuBarTitleMinimumGap
|
TitlePane.menuBarTitleMinimumGap
|
||||||
TitlePane.noIconLeftGap
|
TitlePane.noIconLeftGap
|
||||||
@@ -1079,7 +1070,6 @@ TitlePane.small.iconifyIcon
|
|||||||
TitlePane.small.inactiveBackground
|
TitlePane.small.inactiveBackground
|
||||||
TitlePane.small.inactiveForeground
|
TitlePane.small.inactiveForeground
|
||||||
TitlePane.small.maximizeIcon
|
TitlePane.small.maximizeIcon
|
||||||
TitlePane.small.menuBarResizeHeight
|
|
||||||
TitlePane.small.menuBarTitleGap
|
TitlePane.small.menuBarTitleGap
|
||||||
TitlePane.small.menuBarTitleMinimumGap
|
TitlePane.small.menuBarTitleMinimumGap
|
||||||
TitlePane.small.noIconLeftGap
|
TitlePane.small.noIconLeftGap
|
||||||
@@ -1130,8 +1120,6 @@ ToggleButton.tab.selectedBackground
|
|||||||
ToggleButton.tab.selectedForeground
|
ToggleButton.tab.selectedForeground
|
||||||
ToggleButton.tab.underlineColor
|
ToggleButton.tab.underlineColor
|
||||||
ToggleButton.tab.underlineHeight
|
ToggleButton.tab.underlineHeight
|
||||||
ToggleButton.textIconGap
|
|
||||||
ToggleButton.textShiftOffset
|
|
||||||
ToggleButton.toolbar.disabledSelectedBackground
|
ToggleButton.toolbar.disabledSelectedBackground
|
||||||
ToggleButton.toolbar.disabledSelectedForeground
|
ToggleButton.toolbar.disabledSelectedForeground
|
||||||
ToggleButton.toolbar.hoverBackground
|
ToggleButton.toolbar.hoverBackground
|
||||||
|
|||||||
@@ -14,8 +14,8 @@
|
|||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
#
|
#
|
||||||
|
|
||||||
flatlaf.releaseVersion = 3.3
|
flatlaf.releaseVersion = 3.4
|
||||||
flatlaf.developmentVersion = 3.4-SNAPSHOT
|
flatlaf.developmentVersion = 3.5-SNAPSHOT
|
||||||
|
|
||||||
org.gradle.parallel = true
|
org.gradle.parallel = true
|
||||||
# org.gradle.warning.mode = all
|
# org.gradle.warning.mode = all
|
||||||
|
|||||||
Reference in New Issue
Block a user