mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2026-02-11 22:47:13 -06:00
Compare commits
58 Commits
3.2.4
...
fonts/inte
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ca3b2b4b07 | ||
|
|
722dde63df | ||
|
|
c85baf4dc6 | ||
|
|
96b7770ab2 | ||
|
|
0c00117820 | ||
|
|
eed11d211b | ||
|
|
19f27a8d56 | ||
|
|
cf3fa17666 | ||
|
|
6fdc56f2d3 | ||
|
|
9f17a5b26d | ||
|
|
fa53e90847 | ||
|
|
50c630f403 | ||
|
|
5630c161ea | ||
|
|
7d16ff9e79 | ||
|
|
a9ea9daec3 | ||
|
|
45bdd40dce | ||
|
|
a2bca88eec | ||
|
|
c0dd02ee13 | ||
|
|
97495a6093 | ||
|
|
4ad45088c4 | ||
|
|
d6d1d4b1b7 | ||
|
|
6e453c170f | ||
|
|
beb2deee52 | ||
|
|
9c69043b2c | ||
|
|
4df34b3f9d | ||
|
|
ee01756188 | ||
|
|
0386aaa18b | ||
|
|
92c4230cde | ||
|
|
26165999e0 | ||
|
|
38b2641078 | ||
|
|
4e19169312 | ||
|
|
46de81c1c9 | ||
|
|
9bf4da7acf | ||
|
|
6f32236fb7 | ||
|
|
c25d857e78 | ||
|
|
8cc2925fd0 | ||
|
|
2b87d3c4db | ||
|
|
7f6f366744 | ||
|
|
b1fdbde5cd | ||
|
|
417f0f5f1c | ||
|
|
ec7673790c | ||
|
|
7d0bdf3b9e | ||
|
|
2ef5270095 | ||
|
|
61ba011c3b | ||
|
|
8d8b9f3e98 | ||
|
|
69899ec29f | ||
|
|
5063621c95 | ||
|
|
030177f739 | ||
|
|
808f5a6381 | ||
|
|
9602b191a9 | ||
|
|
34bd2d781c | ||
|
|
cf364c1264 | ||
|
|
a997820bb6 | ||
|
|
b8fabd59c0 | ||
|
|
0c604b1023 | ||
|
|
40418607e5 | ||
|
|
5436ea88d8 | ||
|
|
7bec5ec6dc |
16
.github/workflows/ci.yml
vendored
16
.github/workflows/ci.yml
vendored
@@ -19,7 +19,7 @@ jobs:
|
|||||||
# test against
|
# test against
|
||||||
# - Java 8 (minimum requirement)
|
# - Java 8 (minimum requirement)
|
||||||
# - Java LTS versions (11, 17, ...)
|
# - Java LTS versions (11, 17, ...)
|
||||||
# - lastest Java version(s)
|
# - latest Java version(s)
|
||||||
java:
|
java:
|
||||||
- 8
|
- 8
|
||||||
- 11 # LTS
|
- 11 # LTS
|
||||||
@@ -30,13 +30,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@v1
|
||||||
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 +50,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 +70,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 +106,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
|
||||||
|
|||||||
4
.github/workflows/fonts.yml
vendored
4
.github/workflows/fonts.yml
vendored
@@ -30,10 +30,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
|
||||||
|
|||||||
7
.github/workflows/natives.yml
vendored
7
.github/workflows/natives.yml
vendored
@@ -20,17 +20,18 @@ jobs:
|
|||||||
matrix:
|
matrix:
|
||||||
os:
|
os:
|
||||||
- windows
|
- windows
|
||||||
|
- macos
|
||||||
- ubuntu
|
- ubuntu
|
||||||
|
|
||||||
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@v1
|
||||||
|
|
||||||
- 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
|
||||||
@@ -42,7 +43,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: |
|
||||||
|
|||||||
88
CHANGELOG.md
88
CHANGELOG.md
@@ -1,12 +1,95 @@
|
|||||||
FlatLaf Change Log
|
FlatLaf Change Log
|
||||||
==================
|
==================
|
||||||
|
|
||||||
|
## 3.4-SNAPSHOT
|
||||||
|
|
||||||
|
#### New features and improvements
|
||||||
|
|
||||||
|
- Native libraries: System property `flatlaf.nativeLibraryPath` now supports
|
||||||
|
loading native libraries named the same as on Maven central. Improved log
|
||||||
|
messages for loading fails.
|
||||||
|
- Fonts: Updated **Inter** to
|
||||||
|
[v4.0](https://github.com/rsms/inter/releases/tag/v4.0).
|
||||||
|
|
||||||
|
#### Fixed bugs
|
||||||
|
|
||||||
|
- JIDE CommandMenuBar: Fixed `ClassCastException` when JIDE command bar displays
|
||||||
|
`JideMenu` in popup. (PR #794)
|
||||||
|
|
||||||
|
|
||||||
|
## 3.3
|
||||||
|
|
||||||
|
#### New features and improvements
|
||||||
|
|
||||||
|
- macOS (10.14+): Popups (`JPopupMenu`, `JComboBox`, `JToolTip`, etc.) now use
|
||||||
|
native macOS rounded borders. (PR #772; issue #715)
|
||||||
|
- Native libraries: Added `libflatlaf-macos-arm64.dylib` and
|
||||||
|
`libflatlaf-macos-x86_64.dylib`. See also
|
||||||
|
https://www.formdev.com/flatlaf/native-libraries/.
|
||||||
|
- ScrollPane: Support rounded border. (PR #713)
|
||||||
|
- SplitPane: Support divider hover and pressed background colors. (PR #788)
|
||||||
|
- TabbedPane: Support vertical tabs. (PR #758, issue #633)
|
||||||
|
- TabbedPane: Paint rounded tab area background for rounded cards. (issue #717)
|
||||||
|
- ToolBar: Added styling properties `separatorWidth` and `separatorColor`.
|
||||||
|
|
||||||
|
#### Fixed bugs
|
||||||
|
|
||||||
|
- Button and ToggleButton: Selected buttons did not use explicitly set
|
||||||
|
foreground color. (issue 756)
|
||||||
|
- FileChooser: Catch NPE in Java 21 when getting icon for `.exe` files that use
|
||||||
|
default Windows exe icon. (see
|
||||||
|
[JDK-8320692](https://bugs.openjdk.org/browse/JDK-8320692))
|
||||||
|
- OptionPane: Fixed styling custom panel background in `JOptionPane`. (issue
|
||||||
|
#761)
|
||||||
|
- ScrollPane: Styling ScrollPane border properties did not work if view
|
||||||
|
component is a Table.
|
||||||
|
- Table:
|
||||||
|
- Switching theme looses table grid and intercell spacing. (issues #733 and
|
||||||
|
#750)
|
||||||
|
- Fixed background of `boolean` columns when using alternating row colors.
|
||||||
|
(issue #780)
|
||||||
|
- Fixed border arc of components in complex table cell editors. (issue #786)
|
||||||
|
- TableHeader:
|
||||||
|
- No longer temporary replace header cell renderer while painting. This avoids
|
||||||
|
a `StackOverflowError` in case that custom renderer does this too. (see
|
||||||
|
[NetBeans issue #6835](https://github.com/apache/netbeans/issues/6835)) This
|
||||||
|
also improves compatibility with custom table header implementations.
|
||||||
|
- Header cell renderer background/foreground colors were not restored after
|
||||||
|
hover if renderer uses `null` for background/foreground. (PR #790)
|
||||||
|
- TabbedPane:
|
||||||
|
- Avoid unnecessary repainting whole tabbed pane content area when layouting
|
||||||
|
leading/trailing components.
|
||||||
|
- Avoid unnecessary repainting of selected tab on temporary changes.
|
||||||
|
- Fixed "endless" layouting and repainting when using nested tabbed panes (top
|
||||||
|
and bottom tab placement) and RSyntaxTextArea (with enabled line-wrapping)
|
||||||
|
as tab content. (see
|
||||||
|
[jadx issue #2030](https://github.com/skylot/jadx/issues/2030))
|
||||||
|
- Fixed broken rendering after resizing window to minimum size and then
|
||||||
|
increasing size again. (issue #767)
|
||||||
|
|
||||||
|
#### Incompatibilities
|
||||||
|
|
||||||
|
- Removed support for JetBrains custom decorations, which required
|
||||||
|
[JetBrains Runtime](https://github.com/JetBrains/JetBrainsRuntime/wiki) (JBR)
|
||||||
|
8 or 11. It did not work for JBR 17. System property
|
||||||
|
`flatlaf.useJetBrainsCustomDecorations` is now ignored. **Note**: FlatLaf
|
||||||
|
window decorations continue to work with JBR.
|
||||||
|
|
||||||
|
|
||||||
|
## 3.2.5
|
||||||
|
|
||||||
|
#### Fixed bugs
|
||||||
|
|
||||||
|
- Popup: Fixed NPE if popup invoker is `null` on Windows 10. (issue #753;
|
||||||
|
regression in 3.2.1 in fix for #626)
|
||||||
|
|
||||||
|
|
||||||
## 3.2.4
|
## 3.2.4
|
||||||
|
|
||||||
#### Fixed bugs
|
#### Fixed bugs
|
||||||
|
|
||||||
- Popup: Fixed potential NPE in (unusual) case that the popup invoker is `null`
|
- Popup: Fixed NPE if popup invoker is `null` on Linux with Wayland and Java 21.
|
||||||
(only on Linux with Wayland and Java 21; regression in 3.2.3). (issue #752)
|
(issue #752; regression in 3.2.3)
|
||||||
|
|
||||||
|
|
||||||
## 3.2.3
|
## 3.2.3
|
||||||
@@ -170,7 +253,6 @@ FlatLaf Change Log
|
|||||||
- Windows DLLs are now digitally signed with FormDev Software GmbH
|
- Windows DLLs are now digitally signed with FormDev Software GmbH
|
||||||
certificate.
|
certificate.
|
||||||
|
|
||||||
|
|
||||||
#### Fixed bugs
|
#### Fixed bugs
|
||||||
|
|
||||||
- FlatLaf window decorations:
|
- FlatLaf window decorations:
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ build script:
|
|||||||
artifactId: flatlaf
|
artifactId: flatlaf
|
||||||
version: (see button below)
|
version: (see button below)
|
||||||
|
|
||||||
Otherwise download `flatlaf-<version>.jar` here:
|
Otherwise, download `flatlaf-<version>.jar` here:
|
||||||
|
|
||||||
[](https://maven-badges.herokuapp.com/maven-central/com.formdev/flatlaf)
|
[](https://maven-badges.herokuapp.com/maven-central/com.formdev/flatlaf)
|
||||||
|
|
||||||
@@ -141,7 +141,6 @@ details and downloads.
|
|||||||
Buzz
|
Buzz
|
||||||
----
|
----
|
||||||
|
|
||||||
- [What others say about FlatLaf on Twitter](https://twitter.com/search?f=live&q=flatlaf)
|
|
||||||
- [FlatLaf 3.1 (and 3.0) announcement on Reddit](https://www.reddit.com/r/java/comments/12xgrsu/flatlaf_31_and_30_swing_look_and_feel/)
|
- [FlatLaf 3.1 (and 3.0) announcement on Reddit](https://www.reddit.com/r/java/comments/12xgrsu/flatlaf_31_and_30_swing_look_and_feel/)
|
||||||
- [FlatLaf 1.0 announcement on Reddit](https://www.reddit.com/r/java/comments/lsbcwe/flatlaf_10_swing_look_and_feel/)
|
- [FlatLaf 1.0 announcement on Reddit](https://www.reddit.com/r/java/comments/lsbcwe/flatlaf_10_swing_look_and_feel/)
|
||||||
- [FlatLaf announcement on Reddit](https://www.reddit.com/r/java/comments/dl0hu3/flatlaf_flat_look_and_feel/)
|
- [FlatLaf announcement on Reddit](https://www.reddit.com/r/java/comments/dl0hu3/flatlaf_flat_look_and_feel/)
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ public class ReorderJarEntries
|
|||||||
// 1st pass: copy .properties files
|
// 1st pass: copy .properties files
|
||||||
copyFiles( zipOutStream, jarFile, name -> name.endsWith( ".properties" ) );
|
copyFiles( zipOutStream, jarFile, name -> name.endsWith( ".properties" ) );
|
||||||
|
|
||||||
// 2st pass: copy other files
|
// 2nd pass: copy other files
|
||||||
copyFiles( zipOutStream, jarFile, name -> !name.endsWith( ".properties" ) );
|
copyFiles( zipOutStream, jarFile, name -> !name.endsWith( ".properties" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -130,6 +130,8 @@ flatlafPublish {
|
|||||||
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" ),
|
||||||
|
NativeArtifact( "${natives}/libflatlaf-macos-arm64.dylib", "macos-arm64", "dylib" ),
|
||||||
|
NativeArtifact( "${natives}/libflatlaf-macos-x86_64.dylib", "macos-x86_64", "dylib" ),
|
||||||
NativeArtifact( "${natives}/libflatlaf-linux-x86_64.so", "linux-x86_64", "so" ),
|
NativeArtifact( "${natives}/libflatlaf-linux-x86_64.so", "linux-x86_64", "so" ),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#Signature file v4.1
|
#Signature file v4.1
|
||||||
#Version 3.2.4
|
#Version 3.3
|
||||||
|
|
||||||
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"
|
||||||
@@ -23,6 +23,7 @@ fld public final static java.lang.String PLACEHOLDER_TEXT = "JTextField.placehol
|
|||||||
fld public final static java.lang.String POPUP_BORDER_CORNER_RADIUS = "Popup.borderCornerRadius"
|
fld public final static java.lang.String POPUP_BORDER_CORNER_RADIUS = "Popup.borderCornerRadius"
|
||||||
fld public final static java.lang.String POPUP_DROP_SHADOW_PAINTED = "Popup.dropShadowPainted"
|
fld public final static java.lang.String POPUP_DROP_SHADOW_PAINTED = "Popup.dropShadowPainted"
|
||||||
fld public final static java.lang.String POPUP_FORCE_HEAVY_WEIGHT = "Popup.forceHeavyWeight"
|
fld public final static java.lang.String POPUP_FORCE_HEAVY_WEIGHT = "Popup.forceHeavyWeight"
|
||||||
|
fld public final static java.lang.String POPUP_ROUNDED_BORDER_WIDTH = "Popup.roundedBorderWidth"
|
||||||
fld public final static java.lang.String PROGRESS_BAR_LARGE_HEIGHT = "JProgressBar.largeHeight"
|
fld public final static java.lang.String PROGRESS_BAR_LARGE_HEIGHT = "JProgressBar.largeHeight"
|
||||||
fld public final static java.lang.String PROGRESS_BAR_SQUARE = "JProgressBar.square"
|
fld public final static java.lang.String PROGRESS_BAR_SQUARE = "JProgressBar.square"
|
||||||
fld public final static java.lang.String SCROLL_BAR_SHOW_BUTTONS = "JScrollBar.showButtons"
|
fld public final static java.lang.String SCROLL_BAR_SHOW_BUTTONS = "JScrollBar.showButtons"
|
||||||
@@ -67,6 +68,11 @@ fld public final static java.lang.String TABBED_PANE_TAB_CLOSE_TOOLTIPTEXT = "JT
|
|||||||
fld public final static java.lang.String TABBED_PANE_TAB_HEIGHT = "JTabbedPane.tabHeight"
|
fld public final static java.lang.String TABBED_PANE_TAB_HEIGHT = "JTabbedPane.tabHeight"
|
||||||
fld public final static java.lang.String TABBED_PANE_TAB_ICON_PLACEMENT = "JTabbedPane.tabIconPlacement"
|
fld public final static java.lang.String TABBED_PANE_TAB_ICON_PLACEMENT = "JTabbedPane.tabIconPlacement"
|
||||||
fld public final static java.lang.String TABBED_PANE_TAB_INSETS = "JTabbedPane.tabInsets"
|
fld public final static java.lang.String TABBED_PANE_TAB_INSETS = "JTabbedPane.tabInsets"
|
||||||
|
fld public final static java.lang.String TABBED_PANE_TAB_ROTATION = "JTabbedPane.tabRotation"
|
||||||
|
fld public final static java.lang.String TABBED_PANE_TAB_ROTATION_AUTO = "auto"
|
||||||
|
fld public final static java.lang.String TABBED_PANE_TAB_ROTATION_LEFT = "left"
|
||||||
|
fld public final static java.lang.String TABBED_PANE_TAB_ROTATION_NONE = "none"
|
||||||
|
fld public final static java.lang.String TABBED_PANE_TAB_ROTATION_RIGHT = "right"
|
||||||
fld public final static java.lang.String TABBED_PANE_TAB_TYPE = "JTabbedPane.tabType"
|
fld public final static java.lang.String TABBED_PANE_TAB_TYPE = "JTabbedPane.tabType"
|
||||||
fld public final static java.lang.String TABBED_PANE_TAB_TYPE_CARD = "card"
|
fld public final static java.lang.String TABBED_PANE_TAB_TYPE_CARD = "card"
|
||||||
fld public final static java.lang.String TABBED_PANE_TAB_TYPE_UNDERLINED = "underlined"
|
fld public final static java.lang.String TABBED_PANE_TAB_TYPE_UNDERLINED = "underlined"
|
||||||
@@ -241,7 +247,7 @@ meth public void setExtraDefaults(java.util.Map<java.lang.String,java.lang.Strin
|
|||||||
meth public void uninitialize()
|
meth public void uninitialize()
|
||||||
meth public void unregisterUIDefaultsGetter(java.util.function.Function<java.lang.Object,java.lang.Object>)
|
meth public void unregisterUIDefaultsGetter(java.util.function.Function<java.lang.Object,java.lang.Object>)
|
||||||
supr javax.swing.plaf.basic.BasicLookAndFeel
|
supr javax.swing.plaf.basic.BasicLookAndFeel
|
||||||
hfds DESKTOPFONTHINTS,aquaLoaded,customDefaultsSources,desktopPropertyListener,desktopPropertyName,desktopPropertyName2,extraDefaults,getUIMethod,getUIMethodInitialized,globalExtraDefaults,mnemonicHandler,oldPopupFactory,postInitialization,preferredFontFamily,preferredLightFontFamily,preferredMonospacedFontFamily,preferredSemiboldFontFamily,subMenuUsabilityHelperInstalled,systemColorGetter,uiDefaultsGetters,updateUIPending
|
hfds DESKTOPFONTHINTS,aquaLoaded,customDefaultsSources,desktopPropertyListener,desktopPropertyName,desktopPropertyName2,extraDefaults,globalExtraDefaults,mnemonicHandler,oldPopupFactory,postInitialization,preferredFontFamily,preferredLightFontFamily,preferredMonospacedFontFamily,preferredSemiboldFontFamily,subMenuUsabilityHelperInstalled,systemColorGetter,uiDefaultsGetters,updateUIPending
|
||||||
hcls ActiveFont,FlatUIDefaults,ImageIconUIResource
|
hcls ActiveFont,FlatUIDefaults,ImageIconUIResource
|
||||||
|
|
||||||
CLSS public abstract interface static com.formdev.flatlaf.FlatLaf$DisabledIconProvider
|
CLSS public abstract interface static com.formdev.flatlaf.FlatLaf$DisabledIconProvider
|
||||||
@@ -282,6 +288,7 @@ fld public final static java.lang.String UI_SCALE_ALLOW_SCALE_DOWN = "flatlaf.ui
|
|||||||
fld public final static java.lang.String UI_SCALE_ENABLED = "flatlaf.uiScale.enabled"
|
fld public final static java.lang.String UI_SCALE_ENABLED = "flatlaf.uiScale.enabled"
|
||||||
fld public final static java.lang.String UPDATE_UI_ON_SYSTEM_FONT_CHANGE = "flatlaf.updateUIOnSystemFontChange"
|
fld public final static java.lang.String UPDATE_UI_ON_SYSTEM_FONT_CHANGE = "flatlaf.updateUIOnSystemFontChange"
|
||||||
fld public final static java.lang.String USE_JETBRAINS_CUSTOM_DECORATIONS = "flatlaf.useJetBrainsCustomDecorations"
|
fld public final static java.lang.String USE_JETBRAINS_CUSTOM_DECORATIONS = "flatlaf.useJetBrainsCustomDecorations"
|
||||||
|
anno 0 java.lang.Deprecated()
|
||||||
fld public final static java.lang.String USE_NATIVE_LIBRARY = "flatlaf.useNativeLibrary"
|
fld public final static java.lang.String USE_NATIVE_LIBRARY = "flatlaf.useNativeLibrary"
|
||||||
fld public final static java.lang.String USE_TEXT_Y_CORRECTION = "flatlaf.useTextYCorrection"
|
fld public final static java.lang.String USE_TEXT_Y_CORRECTION = "flatlaf.useTextYCorrection"
|
||||||
fld public final static java.lang.String USE_UBUNTU_FONT = "flatlaf.useUbuntuFont"
|
fld public final static java.lang.String USE_UBUNTU_FONT = "flatlaf.useUbuntuFont"
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ public interface FlatClientProperties
|
|||||||
//---- JButton ------------------------------------------------------------
|
//---- JButton ------------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies type of a button.
|
* Specifies type of button.
|
||||||
* <p>
|
* <p>
|
||||||
* <strong>Components</strong> {@link javax.swing.JButton} and {@link javax.swing.JToggleButton}<br>
|
* <strong>Components</strong> {@link javax.swing.JButton} and {@link javax.swing.JToggleButton}<br>
|
||||||
* <strong>Value type</strong> {@link java.lang.String}<br>
|
* <strong>Value type</strong> {@link java.lang.String}<br>
|
||||||
@@ -278,12 +278,13 @@ public interface FlatClientProperties
|
|||||||
* <p>
|
* <p>
|
||||||
* Note that this is not available on all platforms since it requires special support.
|
* Note that this is not available on all platforms since it requires special support.
|
||||||
* Supported platforms:
|
* Supported platforms:
|
||||||
* <p>
|
* <ul>
|
||||||
* <strong>Windows 11</strong> (x86 or x86_64): Only two corner radiuses are supported
|
* <li><strong>Windows 11</strong>: Only two corner radiuses are supported
|
||||||
* by the OS: {@code DWMWCP_ROUND} is 8px and {@code DWMWCP_ROUNDSMALL} is 4px.
|
* by the OS: {@code DWMWCP_ROUND} is 8px and {@code DWMWCP_ROUNDSMALL} is 4px.
|
||||||
* If this value is {@code 1 - 4}, then {@code DWMWCP_ROUNDSMALL} is used.
|
* If this value is {@code 1 - 4}, then {@code DWMWCP_ROUNDSMALL} is used.
|
||||||
* If it is {@code >= 5}, then {@code DWMWCP_ROUND} is used.
|
* If it is {@code >= 5}, then {@code DWMWCP_ROUND} is used.
|
||||||
* <p>
|
* <li><strong>macOS</strong> (10.14 and later): Any corner radius is supported.
|
||||||
|
* </ul>
|
||||||
* <strong>Component</strong> {@link javax.swing.JComponent}<br>
|
* <strong>Component</strong> {@link javax.swing.JComponent}<br>
|
||||||
* <strong>Value type</strong> {@link java.lang.Integer}<br>
|
* <strong>Value type</strong> {@link java.lang.Integer}<br>
|
||||||
*
|
*
|
||||||
@@ -291,6 +292,24 @@ public interface FlatClientProperties
|
|||||||
*/
|
*/
|
||||||
String POPUP_BORDER_CORNER_RADIUS = "Popup.borderCornerRadius";
|
String POPUP_BORDER_CORNER_RADIUS = "Popup.borderCornerRadius";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies the popup rounded border width if the component is shown in a popup
|
||||||
|
* or if the component is the owner of another component that is shown in a popup.
|
||||||
|
* <p>
|
||||||
|
* Only used if popup uses rounded border.
|
||||||
|
* <p>
|
||||||
|
* Note that this is not available on all platforms since it requires special support.
|
||||||
|
* Supported platforms:
|
||||||
|
* <ul>
|
||||||
|
* <li><strong>macOS</strong> (10.14 and later)
|
||||||
|
* </ul>
|
||||||
|
* <strong>Component</strong> {@link javax.swing.JComponent}<br>
|
||||||
|
* <strong>Value type</strong> {@link java.lang.Integer} or {@link java.lang.Float}<br>
|
||||||
|
*
|
||||||
|
* @since 3.3
|
||||||
|
*/
|
||||||
|
String POPUP_ROUNDED_BORDER_WIDTH = "Popup.roundedBorderWidth";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies whether a drop shadow is painted if the component is shown in a popup
|
* Specifies whether a drop shadow is painted if the component is shown in a popup
|
||||||
* or if the component is the owner of another component that is shown in a popup.
|
* or if the component is the owner of another component that is shown in a popup.
|
||||||
@@ -402,10 +421,10 @@ public interface FlatClientProperties
|
|||||||
String TITLE_BAR_SHOW_TITLE = "JRootPane.titleBarShowTitle";
|
String TITLE_BAR_SHOW_TITLE = "JRootPane.titleBarShowTitle";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies whether the "iconfify" button should be shown in the window title bar
|
* Specifies whether the "iconify" button should be shown in the window title bar
|
||||||
* (requires enabled window decorations). Default is {@code true}.
|
* (requires enabled window decorations). Default is {@code true}.
|
||||||
* <p>
|
* <p>
|
||||||
* Setting this shows/hides the "iconfify" button
|
* Setting this shows/hides the "iconify" button
|
||||||
* for the {@code JFrame} that contains the root pane.
|
* for the {@code JFrame} that contains the root pane.
|
||||||
* <p>
|
* <p>
|
||||||
* <strong>Component</strong> {@link javax.swing.JRootPane}<br>
|
* <strong>Component</strong> {@link javax.swing.JRootPane}<br>
|
||||||
@@ -487,7 +506,7 @@ public interface FlatClientProperties
|
|||||||
* On macOS, Java supports this out of the box.
|
* On macOS, Java supports this out of the box.
|
||||||
* <p>
|
* <p>
|
||||||
* Note that this client property must be set before the window becomes displayable.
|
* Note that this client property must be set before the window becomes displayable.
|
||||||
* Otherwise an {@link IllegalComponentStateException} is thrown.
|
* Otherwise, an {@link IllegalComponentStateException} is thrown.
|
||||||
* <p>
|
* <p>
|
||||||
* <strong>Component</strong> {@link javax.swing.JRootPane}<br>
|
* <strong>Component</strong> {@link javax.swing.JRootPane}<br>
|
||||||
* <strong>Value type</strong> {@link java.lang.String}<br>
|
* <strong>Value type</strong> {@link java.lang.String}<br>
|
||||||
@@ -932,6 +951,59 @@ public interface FlatClientProperties
|
|||||||
*/
|
*/
|
||||||
String TABBED_PANE_TAB_ICON_PLACEMENT = "JTabbedPane.tabIconPlacement";
|
String TABBED_PANE_TAB_ICON_PLACEMENT = "JTabbedPane.tabIconPlacement";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies the rotation of the tabs (title, icon, etc.).
|
||||||
|
* <p>
|
||||||
|
* <strong>Component</strong> {@link javax.swing.JTabbedPane}<br>
|
||||||
|
* <strong>Value type</strong> {@link java.lang.Integer} or {@link java.lang.String}<br>
|
||||||
|
* <strong>Allowed Values</strong>
|
||||||
|
* {@link SwingConstants#LEFT},
|
||||||
|
* {@link SwingConstants#RIGHT},
|
||||||
|
* {@link #TABBED_PANE_TAB_ROTATION_NONE}, (default)
|
||||||
|
* {@link #TABBED_PANE_TAB_ROTATION_AUTO},
|
||||||
|
* {@link #TABBED_PANE_TAB_ROTATION_LEFT} or
|
||||||
|
* {@link #TABBED_PANE_TAB_ROTATION_RIGHT}
|
||||||
|
*
|
||||||
|
* @since 3.3
|
||||||
|
*/
|
||||||
|
String TABBED_PANE_TAB_ROTATION = "JTabbedPane.tabRotation";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tabs are not rotated.
|
||||||
|
*
|
||||||
|
* @see #TABBED_PANE_TAB_ROTATION
|
||||||
|
* @since 3.3
|
||||||
|
*/
|
||||||
|
String TABBED_PANE_TAB_ROTATION_NONE = "none";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tabs are rotated depending on tab placement.
|
||||||
|
* <p>
|
||||||
|
* For top and bottom tab placement, the tabs are not rotated.<br>
|
||||||
|
* For left tab placement, the tabs are rotated counter-clockwise.<br>
|
||||||
|
* For right tab placement, the tabs are rotated clockwise.
|
||||||
|
*
|
||||||
|
* @see #TABBED_PANE_TAB_ROTATION
|
||||||
|
* @since 3.3
|
||||||
|
*/
|
||||||
|
String TABBED_PANE_TAB_ROTATION_AUTO = "auto";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tabs are rotated counter-clockwise.
|
||||||
|
*
|
||||||
|
* @see #TABBED_PANE_TAB_ROTATION
|
||||||
|
* @since 3.3
|
||||||
|
*/
|
||||||
|
String TABBED_PANE_TAB_ROTATION_LEFT = "left";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tabs are rotated clockwise.
|
||||||
|
*
|
||||||
|
* @see #TABBED_PANE_TAB_ROTATION
|
||||||
|
* @since 3.3
|
||||||
|
*/
|
||||||
|
String TABBED_PANE_TAB_ROTATION_RIGHT = "right";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies a component that will be placed at the leading edge of the tabs area.
|
* Specifies a component that will be placed at the leading edge of the tabs area.
|
||||||
* <p>
|
* <p>
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ class FlatInputMaps
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// join ltr and rtl bindings to fix up/down/etc keys in right-to-left component orientation
|
// join ltr and rtl bindings to fix up/down/etc. keys in right-to-left component orientation
|
||||||
Object[] bindings = (Object[]) defaults.get( "PopupMenu.selectedWindowInputMapBindings" );
|
Object[] bindings = (Object[]) defaults.get( "PopupMenu.selectedWindowInputMapBindings" );
|
||||||
Object[] rtlBindings = (Object[]) defaults.get( "PopupMenu.selectedWindowInputMapBindings.RightToLeft" );
|
Object[] rtlBindings = (Object[]) defaults.get( "PopupMenu.selectedWindowInputMapBindings.RightToLeft" );
|
||||||
if( bindings != null && rtlBindings != null ) {
|
if( bindings != null && rtlBindings != null ) {
|
||||||
|
|||||||
@@ -30,9 +30,6 @@ import java.awt.image.ImageProducer;
|
|||||||
import java.beans.PropertyChangeEvent;
|
import java.beans.PropertyChangeEvent;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.lang.invoke.MethodHandle;
|
|
||||||
import java.lang.invoke.MethodHandles;
|
|
||||||
import java.lang.invoke.MethodType;
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -78,6 +75,7 @@ import com.formdev.flatlaf.ui.FlatNativeWindowBorder;
|
|||||||
import com.formdev.flatlaf.ui.FlatPopupFactory;
|
import com.formdev.flatlaf.ui.FlatPopupFactory;
|
||||||
import com.formdev.flatlaf.ui.FlatRootPaneUI;
|
import com.formdev.flatlaf.ui.FlatRootPaneUI;
|
||||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||||
|
import com.formdev.flatlaf.ui.JavaCompatibility2;
|
||||||
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
|
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
|
||||||
import com.formdev.flatlaf.util.FontUtils;
|
import com.formdev.flatlaf.util.FontUtils;
|
||||||
import com.formdev.flatlaf.util.GrayFilter;
|
import com.formdev.flatlaf.util.GrayFilter;
|
||||||
@@ -183,17 +181,11 @@ public abstract class FlatLaf
|
|||||||
* This depends on the operating system and on the used Java runtime.
|
* This depends on the operating system and on the used Java runtime.
|
||||||
* <p>
|
* <p>
|
||||||
* This method returns {@code true} on Windows 10/11 (see exception below)
|
* This method returns {@code true} on Windows 10/11 (see exception below)
|
||||||
* and on Linux, {@code false} otherwise.
|
* and on Linux, otherwise returns {@code false}.
|
||||||
|
* <p>
|
||||||
|
* Returns also {@code false} on Windows 10/11 if
|
||||||
|
* FlatLaf native window border support is available (requires Windows 10/11).
|
||||||
* <p>
|
* <p>
|
||||||
* Returns also {@code false} on Windows 10/11 if:
|
|
||||||
* <ul>
|
|
||||||
* <li>FlatLaf native window border support is available (requires Windows 10/11)</li>
|
|
||||||
* <li>running in
|
|
||||||
* <a href="https://confluence.jetbrains.com/display/JBR/JetBrains+Runtime">JetBrains Runtime 11 (or later)</a>
|
|
||||||
* (<a href="https://github.com/JetBrains/JetBrainsRuntime">source code on github</a>)
|
|
||||||
* and JBR supports custom window decorations
|
|
||||||
* </li>
|
|
||||||
* </ul>
|
|
||||||
* In these cases, custom decorations are enabled by the root pane.
|
* In these cases, custom decorations are enabled by the root pane.
|
||||||
* Usage of {@link JFrame#setDefaultLookAndFeelDecorated(boolean)} or
|
* Usage of {@link JFrame#setDefaultLookAndFeelDecorated(boolean)} or
|
||||||
* {@link JDialog#setDefaultLookAndFeelDecorated(boolean)} is not necessary.
|
* {@link JDialog#setDefaultLookAndFeelDecorated(boolean)} is not necessary.
|
||||||
@@ -1295,8 +1287,8 @@ public abstract class FlatLaf
|
|||||||
* @since 2.5
|
* @since 2.5
|
||||||
*/
|
*/
|
||||||
public static Map<String, Class<?>> getStyleableInfos( JComponent c ) {
|
public static Map<String, Class<?>> getStyleableInfos( JComponent c ) {
|
||||||
StyleableUI ui = getStyleableUI( c );
|
ComponentUI ui = JavaCompatibility2.getUI( c );
|
||||||
return (ui != null) ? ui.getStyleableInfos( c ) : null;
|
return (ui instanceof StyleableUI) ? ((StyleableUI)ui).getStyleableInfos( c ) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1308,41 +1300,10 @@ public abstract class FlatLaf
|
|||||||
*/
|
*/
|
||||||
@SuppressWarnings( "unchecked" )
|
@SuppressWarnings( "unchecked" )
|
||||||
public static <T> T getStyleableValue( JComponent c, String key ) {
|
public static <T> T getStyleableValue( JComponent c, String key ) {
|
||||||
StyleableUI ui = getStyleableUI( c );
|
ComponentUI ui = JavaCompatibility2.getUI( c );
|
||||||
return (ui != null) ? (T) ui.getStyleableValue( c, key ) : null;
|
return (ui instanceof StyleableUI) ? (T) ((StyleableUI)ui).getStyleableValue( c, key ) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static StyleableUI getStyleableUI( JComponent c ) {
|
|
||||||
if( !getUIMethodInitialized ) {
|
|
||||||
getUIMethodInitialized = true;
|
|
||||||
|
|
||||||
if( SystemInfo.isJava_9_orLater ) {
|
|
||||||
try {
|
|
||||||
// JComponent.getUI() is available since Java 9
|
|
||||||
getUIMethod = MethodHandles.lookup().findVirtual( JComponent.class, "getUI",
|
|
||||||
MethodType.methodType( ComponentUI.class ) );
|
|
||||||
} catch( Exception ex ) {
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
Object ui;
|
|
||||||
if( getUIMethod != null )
|
|
||||||
ui = getUIMethod.invoke( c );
|
|
||||||
else
|
|
||||||
ui = c.getClass().getMethod( "getUI" ).invoke( c );
|
|
||||||
return (ui instanceof StyleableUI) ? (StyleableUI) ui : null;
|
|
||||||
} catch( Throwable ex ) {
|
|
||||||
// ignore
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean getUIMethodInitialized;
|
|
||||||
private static MethodHandle getUIMethod;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the preferred font family to be used for (nearly) all fonts; or {@code null}.
|
* Returns the preferred font family to be used for (nearly) all fonts; or {@code null}.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -103,7 +103,10 @@ public interface FlatSystemProperties
|
|||||||
* <p>
|
* <p>
|
||||||
* <strong>Allowed Values</strong> {@code false} and {@code true}<br>
|
* <strong>Allowed Values</strong> {@code false} and {@code true}<br>
|
||||||
* <strong>Default</strong> {@code false} (since v2; was {@code true} in v1)
|
* <strong>Default</strong> {@code false} (since v2; was {@code true} in v1)
|
||||||
|
*
|
||||||
|
* @deprecated No longer used since FlatLaf 3.3. Retained for API compatibility.
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
String USE_JETBRAINS_CUSTOM_DECORATIONS = "flatlaf.useJetBrainsCustomDecorations";
|
String USE_JETBRAINS_CUSTOM_DECORATIONS = "flatlaf.useJetBrainsCustomDecorations";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -169,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 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
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -203,7 +203,7 @@ class LinuxFontPolicy
|
|||||||
* Gets the default font for KDE from KDE configuration files.
|
* Gets the default font for KDE from KDE configuration files.
|
||||||
*
|
*
|
||||||
* The Swing fonts are not updated when the user changes system font size
|
* The Swing fonts are not updated when the user changes system font size
|
||||||
* (System Settings > Fonts > Force Font DPI). A application restart is necessary.
|
* (System Settings > Fonts > Force Font DPI). An application restart is necessary.
|
||||||
* This is the same behavior as in native KDE applications.
|
* This is the same behavior as in native KDE applications.
|
||||||
*
|
*
|
||||||
* The "display scale factor" (kdeglobals: [KScreen] > ScaleFactor) is not used
|
* The "display scale factor" (kdeglobals: [KScreen] > ScaleFactor) is not used
|
||||||
|
|||||||
@@ -172,7 +172,7 @@ debug*/
|
|||||||
targetTopY = popupLocation.y;
|
targetTopY = popupLocation.y;
|
||||||
targetBottomY = popupLocation.y + popupSize.height;
|
targetBottomY = popupLocation.y + popupSize.height;
|
||||||
|
|
||||||
// install own event queue to supress mouse events when mouse is moved within safe triangle
|
// install own event queue to suppress mouse events when mouse is moved within safe triangle
|
||||||
if( subMenuEventQueue == null )
|
if( subMenuEventQueue == null )
|
||||||
subMenuEventQueue = new SubMenuEventQueue();
|
subMenuEventQueue = new SubMenuEventQueue();
|
||||||
|
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ public class FlatTabbedPaneCloseIcon
|
|||||||
closeSize.width, closeSize.height, closeArc, closeArc );
|
closeSize.width, closeSize.height, closeArc, closeArc );
|
||||||
}
|
}
|
||||||
|
|
||||||
// set cross color
|
// set color of cross
|
||||||
Color fg = FlatButtonUI.buttonStateColor( c, closeForeground, null, null, closeHoverForeground, closePressedForeground );
|
Color fg = FlatButtonUI.buttonStateColor( c, closeForeground, null, null, closeHoverForeground, closePressedForeground );
|
||||||
g.setColor( FlatUIUtils.deriveColor( fg, c.getForeground() ) );
|
g.setColor( FlatUIUtils.deriveColor( fg, c.getForeground() ) );
|
||||||
|
|
||||||
|
|||||||
@@ -57,11 +57,11 @@ public class FlatTreeOpenIcon
|
|||||||
double arc = 1.5;
|
double arc = 1.5;
|
||||||
double arc2 = 0.5;
|
double arc2 = 0.5;
|
||||||
path = FlatUIUtils.createPath( false,
|
path = FlatUIUtils.createPath( false,
|
||||||
// bottom-left of opend part
|
// bottom-left of opened part
|
||||||
2,13.5,
|
2,13.5,
|
||||||
// top-left of opend part
|
// top-left of opened part
|
||||||
FlatUIUtils.ROUNDED, 4.5,7.5, arc,
|
FlatUIUtils.ROUNDED, 4.5,7.5, arc,
|
||||||
// top-right of opend part
|
// top-right of opened part
|
||||||
FlatUIUtils.ROUNDED, 15.5,7.5, arc2,
|
FlatUIUtils.ROUNDED, 15.5,7.5, arc2,
|
||||||
|
|
||||||
// bottom-right
|
// bottom-right
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ public abstract class FlatWindowAbstractIcon
|
|||||||
protected void paintBackground( Component c, Graphics2D g ) {
|
protected void paintBackground( Component c, Graphics2D g ) {
|
||||||
Color background = FlatButtonUI.buttonStateColor( c, null, null, null, hoverBackground, pressedBackground );
|
Color background = FlatButtonUI.buttonStateColor( c, null, null, null, hoverBackground, pressedBackground );
|
||||||
if( background != null ) {
|
if( background != null ) {
|
||||||
// disable antialiasing for background rectangle painting to avoid blury edges when scaled (e.g. at 125% or 175%)
|
// disable antialiasing for background rectangle painting to avoid blurry edges when scaled (e.g. at 125% or 175%)
|
||||||
Object oldHint = g.getRenderingHint( RenderingHints.KEY_ANTIALIASING );
|
Object oldHint = g.getRenderingHint( RenderingHints.KEY_ANTIALIASING );
|
||||||
g.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF );
|
g.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF );
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ import javax.swing.JComboBox;
|
|||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
import javax.swing.JScrollPane;
|
import javax.swing.JScrollPane;
|
||||||
import javax.swing.JSpinner;
|
import javax.swing.JSpinner;
|
||||||
import javax.swing.JViewport;
|
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import javax.swing.plaf.basic.BasicBorders;
|
import javax.swing.plaf.basic.BasicBorders;
|
||||||
import com.formdev.flatlaf.FlatClientProperties;
|
import com.formdev.flatlaf.FlatClientProperties;
|
||||||
@@ -195,8 +194,7 @@ public class FlatBorder
|
|||||||
protected boolean isEnabled( Component c ) {
|
protected boolean isEnabled( Component c ) {
|
||||||
if( c instanceof JScrollPane ) {
|
if( c instanceof JScrollPane ) {
|
||||||
// check whether view component is disabled
|
// check whether view component is disabled
|
||||||
JViewport viewport = ((JScrollPane)c).getViewport();
|
Component view = FlatScrollPaneUI.getView( (JScrollPane) c );
|
||||||
Component view = (viewport != null) ? viewport.getView() : null;
|
|
||||||
if( view != null && !isEnabled( view ) )
|
if( view != null && !isEnabled( view ) )
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -721,14 +721,15 @@ public class FlatButtonUI
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected Color getForeground( JComponent c ) {
|
protected Color getForeground( JComponent c ) {
|
||||||
|
Color fg = c.getForeground();
|
||||||
boolean toolBarButton = isToolBarButton( c ) || isBorderlessButton( c );
|
boolean toolBarButton = isToolBarButton( c ) || isBorderlessButton( c );
|
||||||
|
|
||||||
// selected state
|
// selected state
|
||||||
if( ((AbstractButton)c).isSelected() ) {
|
if( ((AbstractButton)c).isSelected() ) {
|
||||||
return buttonStateColor( c,
|
return buttonStateColor( c,
|
||||||
toolBarButton
|
toolBarButton
|
||||||
? (toolbarSelectedForeground != null ? toolbarSelectedForeground : c.getForeground())
|
? (toolbarSelectedForeground != null ? toolbarSelectedForeground : fg)
|
||||||
: selectedForeground,
|
: (isCustomForeground( fg ) ? fg : selectedForeground),
|
||||||
toolBarButton
|
toolBarButton
|
||||||
? (toolbarDisabledSelectedForeground != null ? toolbarDisabledSelectedForeground : disabledText)
|
? (toolbarDisabledSelectedForeground != null ? toolbarDisabledSelectedForeground : disabledText)
|
||||||
: (disabledSelectedForeground != null ? disabledSelectedForeground : disabledText),
|
: (disabledSelectedForeground != null ? disabledSelectedForeground : disabledText),
|
||||||
@@ -740,7 +741,7 @@ public class FlatButtonUI
|
|||||||
// toolbar button
|
// toolbar button
|
||||||
if( toolBarButton ) {
|
if( toolBarButton ) {
|
||||||
return buttonStateColor( c,
|
return buttonStateColor( c,
|
||||||
c.getForeground(),
|
fg,
|
||||||
disabledText,
|
disabledText,
|
||||||
null,
|
null,
|
||||||
toolbarHoverForeground,
|
toolbarHoverForeground,
|
||||||
@@ -751,7 +752,7 @@ public class FlatButtonUI
|
|||||||
return buttonStateColor( c,
|
return buttonStateColor( c,
|
||||||
getForegroundBase( c, def ),
|
getForegroundBase( c, def ),
|
||||||
disabledText,
|
disabledText,
|
||||||
isCustomForeground( c.getForeground() ) ? null : (def ? defaultFocusedForeground : focusedForeground),
|
isCustomForeground( fg ) ? null : (def ? defaultFocusedForeground : focusedForeground),
|
||||||
def ? defaultHoverForeground : hoverForeground,
|
def ? defaultHoverForeground : hoverForeground,
|
||||||
def ? defaultPressedForeground : pressedForeground );
|
def ? defaultPressedForeground : pressedForeground );
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -926,7 +926,7 @@ public class FlatComboBoxUI
|
|||||||
protected void configurePopup() {
|
protected void configurePopup() {
|
||||||
super.configurePopup();
|
super.configurePopup();
|
||||||
|
|
||||||
// make opaque to avoid that background shines thru border (e.g. at 150% scaling)
|
// make opaque to avoid that background shines through border (e.g. at 150% scaling)
|
||||||
setOpaque( true );
|
setOpaque( true );
|
||||||
|
|
||||||
// set popup border
|
// set popup border
|
||||||
@@ -944,7 +944,7 @@ public class FlatComboBoxUI
|
|||||||
if( popupBackground != null )
|
if( popupBackground != null )
|
||||||
list.setBackground( popupBackground );
|
list.setBackground( popupBackground );
|
||||||
|
|
||||||
// set popup background because it may shine thru when scaled (e.g. at 150%)
|
// set popup background because it may shine through when scaled (e.g. at 150%)
|
||||||
// use non-UIResource to avoid that it is overwritten when making
|
// use non-UIResource to avoid that it is overwritten when making
|
||||||
// popup visible (see JPopupMenu.setInvoker()) in theme editor preview
|
// popup visible (see JPopupMenu.setInvoker()) in theme editor preview
|
||||||
setBackground( FlatUIUtils.nonUIResource( list.getBackground() ) );
|
setBackground( FlatUIUtils.nonUIResource( list.getBackground() ) );
|
||||||
@@ -1090,7 +1090,7 @@ public class FlatComboBoxUI
|
|||||||
}
|
}
|
||||||
|
|
||||||
// using synchronized to avoid problems with code that modifies combo box
|
// using synchronized to avoid problems with code that modifies combo box
|
||||||
// (model, selection, etc) not on AWT thread (which should be not done)
|
// (model, selection, etc.) not on AWT thread (which should be not done)
|
||||||
synchronized void install( Component c, int focusWidth ) {
|
synchronized void install( Component c, int focusWidth ) {
|
||||||
if( !(c instanceof JComponent) )
|
if( !(c instanceof JComponent) )
|
||||||
return;
|
return;
|
||||||
@@ -1242,7 +1242,7 @@ public class FlatComboBoxUI
|
|||||||
* Key selection manager that delegates to the default manager.
|
* Key selection manager that delegates to the default manager.
|
||||||
* Shows the popup if Space key is pressed and "typed characters" buffer is empty.
|
* Shows the popup if Space key is pressed and "typed characters" buffer is empty.
|
||||||
* If items contain spaces (e.g. "a b") it is still possible to select them
|
* If items contain spaces (e.g. "a b") it is still possible to select them
|
||||||
* by pressing keys a, Space and b.
|
* by pressing keys 'a', 'Space' and 'b'.
|
||||||
*/
|
*/
|
||||||
private class FlatKeySelectionManager
|
private class FlatKeySelectionManager
|
||||||
implements JComboBox.KeySelectionManager, UIResource
|
implements JComboBox.KeySelectionManager, UIResource
|
||||||
|
|||||||
@@ -370,7 +370,11 @@ public class FlatFileChooserUI
|
|||||||
|
|
||||||
// get system icon
|
// get system icon
|
||||||
if( f != null ) {
|
if( f != null ) {
|
||||||
|
try {
|
||||||
icon = getFileChooser().getFileSystemView().getSystemIcon( f );
|
icon = getFileChooser().getFileSystemView().getSystemIcon( f );
|
||||||
|
} catch( NullPointerException ex ) {
|
||||||
|
// Java 21 may throw a NPE for exe files that use default Windows exe icon
|
||||||
|
}
|
||||||
|
|
||||||
if( icon != null ) {
|
if( icon != null ) {
|
||||||
if( icon instanceof ImageIcon )
|
if( icon instanceof ImageIcon )
|
||||||
@@ -540,6 +544,7 @@ public class FlatFileChooserUI
|
|||||||
if( doNotUseSystemIcons() )
|
if( doNotUseSystemIcons() )
|
||||||
return new FlatFileViewDirectoryIcon();
|
return new FlatFileViewDirectoryIcon();
|
||||||
|
|
||||||
|
try {
|
||||||
// Java 17+ supports getting larger system icons
|
// Java 17+ supports getting larger system icons
|
||||||
try {
|
try {
|
||||||
if( SystemInfo.isJava_17_orLater ) {
|
if( SystemInfo.isJava_17_orLater ) {
|
||||||
@@ -565,6 +570,10 @@ public class FlatFileChooserUI
|
|||||||
|
|
||||||
// get system icon in default size 16x16
|
// get system icon in default size 16x16
|
||||||
return fsv.getSystemIcon( file );
|
return fsv.getSystemIcon( file );
|
||||||
|
} catch( NullPointerException ex ) {
|
||||||
|
// Java 21 may throw a NPE for exe files that use default Windows exe icon
|
||||||
|
return new FlatFileViewDirectoryIcon();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void directoryChanged( File file ) {
|
protected void directoryChanged( File file ) {
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import java.awt.Component;
|
|||||||
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 javax.swing.JComponent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Line border for various components.
|
* Line border for various components.
|
||||||
@@ -66,6 +67,9 @@ public class FlatLineBorder
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
|
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
|
||||||
|
if( c instanceof JComponent && ((JComponent)c).getClientProperty( FlatPopupFactory.KEY_POPUP_USES_NATIVE_BORDER ) != null )
|
||||||
|
return;
|
||||||
|
|
||||||
Graphics2D g2 = (Graphics2D) g.create();
|
Graphics2D g2 = (Graphics2D) g.create();
|
||||||
try {
|
try {
|
||||||
FlatUIUtils.setRenderingHints( g2 );
|
FlatUIUtils.setRenderingHints( g2 );
|
||||||
|
|||||||
@@ -411,7 +411,7 @@ public class FlatListUI
|
|||||||
int leftIndex = locationToIndex( list, new Point( r.x - 1, r.y ) );
|
int leftIndex = locationToIndex( list, new Point( r.x - 1, r.y ) );
|
||||||
int rightIndex = locationToIndex( list, new Point( r.x + r.width, r.y ) );
|
int rightIndex = locationToIndex( list, new Point( r.x + r.width, r.y ) );
|
||||||
|
|
||||||
// special handling for the case that last column contains less cells than the other columns
|
// special handling for the case that last column contains fewer cells than the other columns
|
||||||
boolean ltr = list.getComponentOrientation().isLeftToRight();
|
boolean ltr = list.getComponentOrientation().isLeftToRight();
|
||||||
if( !ltr && leftIndex >= 0 && leftIndex != row && leftIndex == locationToIndex( list, new Point( r.x - 1, r.y - 1 ) ) )
|
if( !ltr && leftIndex >= 0 && leftIndex != row && leftIndex == locationToIndex( list, new Point( r.x - 1, r.y - 1 ) ) )
|
||||||
leftIndex = -1;
|
leftIndex = -1;
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,9 +78,15 @@ class FlatNativeLibrary
|
|||||||
//
|
//
|
||||||
// To avoid this, flatlaf.dll is not linked to jawt.dll,
|
// To avoid this, flatlaf.dll is not linked to jawt.dll,
|
||||||
// which avoids loading jawt.dll when flatlaf.dll is loaded.
|
// which avoids loading jawt.dll when flatlaf.dll is loaded.
|
||||||
// Instead flatlaf.dll dynamically loads jawt.dll when first used,
|
// Instead, flatlaf.dll dynamically loads jawt.dll when first used,
|
||||||
// which is guaranteed after AWT initialization.
|
// which is guaranteed after AWT initialization.
|
||||||
|
|
||||||
|
} else if( SystemInfo.isMacOS_10_14_Mojave_orLater && (SystemInfo.isAARCH64 || SystemInfo.isX86_64) ) {
|
||||||
|
// macOS: requires macOS 10.14 or later (arm64 or x86_64)
|
||||||
|
|
||||||
|
classifier = SystemInfo.isAARCH64 ? "macos-arm64" : "macos-x86_64";
|
||||||
|
ext = "dylib";
|
||||||
|
|
||||||
} else if( SystemInfo.isLinux && SystemInfo.isX86_64 ) {
|
} else if( SystemInfo.isLinux && SystemInfo.isX86_64 ) {
|
||||||
// Linux: requires x86_64
|
// Linux: requires x86_64
|
||||||
|
|
||||||
@@ -111,13 +117,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 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,6 +170,33 @@ 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 parent = jarFile.getParentFile();
|
||||||
|
|
||||||
|
// 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 native library exists
|
||||||
|
// in "../bin" directory
|
||||||
|
if( parent.getName().equalsIgnoreCase( "lib" ) ) {
|
||||||
|
libraryFile = new File( parent.getParentFile(), "bin/" + 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();
|
||||||
@@ -162,31 +214,19 @@ 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( '.' ) );
|
||||||
|
return jarBasename
|
||||||
|
+ (jarBasename.contains( "flatlaf" ) ? "" : "-flatlaf")
|
||||||
|
+ '-' + classifier + '.' + ext;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void loadJAWT() {
|
private static void loadJAWT() {
|
||||||
|
|||||||
@@ -35,6 +35,12 @@ import com.formdev.flatlaf.util.SystemInfo;
|
|||||||
*/
|
*/
|
||||||
class FlatNativeLinuxLibrary
|
class FlatNativeLinuxLibrary
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Checks whether native library is loaded/available.
|
||||||
|
* <p>
|
||||||
|
* <b>Note</b>: It is required to invoke this method before invoking any other
|
||||||
|
* method of this class. Otherwise, the native library may not be loaded.
|
||||||
|
*/
|
||||||
static boolean isLoaded() {
|
static boolean isLoaded() {
|
||||||
return SystemInfo.isLinux && FlatNativeLibrary.isLoaded();
|
return SystemInfo.isLinux && FlatNativeLibrary.isLoaded();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2023 FormDev Software GmbH
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.formdev.flatlaf.ui;
|
||||||
|
|
||||||
|
import java.awt.Window;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Native methods for macOS.
|
||||||
|
* <p>
|
||||||
|
* <b>Note</b>: This is private API. Do not use!
|
||||||
|
*
|
||||||
|
* <h2>Methods that use windows as parameter</h2>
|
||||||
|
*
|
||||||
|
* For all methods that accept a {@link java.awt.Window} as parameter,
|
||||||
|
* the underlying macOS window must be already created,
|
||||||
|
* otherwise the method fails. You can use following to ensure this:
|
||||||
|
* <pre>{@code
|
||||||
|
* if( !window.isDisplayable() )
|
||||||
|
* window.addNotify();
|
||||||
|
* }</pre>
|
||||||
|
* or invoke the method after packing the window. E.g.
|
||||||
|
* <pre>{@code
|
||||||
|
* window.pack();
|
||||||
|
* }</pre>
|
||||||
|
*
|
||||||
|
* @author Karl Tauber
|
||||||
|
* @since 3.3
|
||||||
|
*/
|
||||||
|
public class FlatNativeMacLibrary
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Checks whether native library is loaded/available.
|
||||||
|
* <p>
|
||||||
|
* <b>Note</b>: It is required to invoke this method before invoking any other
|
||||||
|
* method of this class. Otherwise, the native library may not be loaded.
|
||||||
|
*/
|
||||||
|
public static boolean isLoaded() {
|
||||||
|
return FlatNativeLibrary.isLoaded();
|
||||||
|
}
|
||||||
|
|
||||||
|
public native static boolean setWindowRoundedBorder( Window window, float radius, float borderWidth, int borderColor );
|
||||||
|
}
|
||||||
@@ -17,20 +17,26 @@
|
|||||||
package com.formdev.flatlaf.ui;
|
package com.formdev.flatlaf.ui;
|
||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
|
import java.awt.Component;
|
||||||
import java.awt.Container;
|
import java.awt.Container;
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
import java.awt.Rectangle;
|
import java.awt.Rectangle;
|
||||||
|
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.List;
|
||||||
import javax.swing.JDialog;
|
import javax.swing.JDialog;
|
||||||
import javax.swing.JFrame;
|
import javax.swing.JFrame;
|
||||||
import javax.swing.JRootPane;
|
import javax.swing.JRootPane;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import javax.swing.event.ChangeListener;
|
import javax.swing.event.ChangeListener;
|
||||||
|
import javax.swing.plaf.BorderUIResource;
|
||||||
import com.formdev.flatlaf.FlatClientProperties;
|
import com.formdev.flatlaf.FlatClientProperties;
|
||||||
import com.formdev.flatlaf.FlatLaf;
|
import com.formdev.flatlaf.FlatLaf;
|
||||||
import com.formdev.flatlaf.FlatSystemProperties;
|
import com.formdev.flatlaf.FlatSystemProperties;
|
||||||
import com.formdev.flatlaf.ui.JBRCustomDecorations.JBRWindowTopBorder;
|
import com.formdev.flatlaf.util.HiDPIUtils;
|
||||||
import com.formdev.flatlaf.util.SystemInfo;
|
import com.formdev.flatlaf.util.SystemInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -54,27 +60,15 @@ public class FlatNativeWindowBorder
|
|||||||
!SystemInfo.isWinPE &&
|
!SystemInfo.isWinPE &&
|
||||||
FlatSystemProperties.getBoolean( FlatSystemProperties.USE_WINDOW_DECORATIONS, true );
|
FlatSystemProperties.getBoolean( FlatSystemProperties.USE_WINDOW_DECORATIONS, true );
|
||||||
|
|
||||||
// check this field before using class JBRCustomDecorations to avoid unnecessary loading of that class
|
|
||||||
private static final boolean canUseJBRCustomDecorations =
|
|
||||||
canUseWindowDecorations &&
|
|
||||||
SystemInfo.isJetBrainsJVM_11_orLater &&
|
|
||||||
FlatSystemProperties.getBoolean( FlatSystemProperties.USE_JETBRAINS_CUSTOM_DECORATIONS, false );
|
|
||||||
|
|
||||||
private static Boolean supported;
|
private static Boolean supported;
|
||||||
private static Provider nativeProvider;
|
private static Provider nativeProvider;
|
||||||
|
|
||||||
public static boolean isSupported() {
|
public static boolean isSupported() {
|
||||||
if( canUseJBRCustomDecorations )
|
|
||||||
return JBRCustomDecorations.isSupported();
|
|
||||||
|
|
||||||
initialize();
|
initialize();
|
||||||
return supported;
|
return supported;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Object install( JRootPane rootPane ) {
|
static Object install( JRootPane rootPane ) {
|
||||||
if( canUseJBRCustomDecorations )
|
|
||||||
return JBRCustomDecorations.install( rootPane );
|
|
||||||
|
|
||||||
if( !isSupported() )
|
if( !isSupported() )
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
@@ -163,11 +157,6 @@ public class FlatNativeWindowBorder
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void uninstall( JRootPane rootPane, Object data ) {
|
static void uninstall( JRootPane rootPane, Object data ) {
|
||||||
if( canUseJBRCustomDecorations ) {
|
|
||||||
JBRCustomDecorations.uninstall( rootPane, data );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !isSupported() )
|
if( !isSupported() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -215,9 +204,6 @@ public class FlatNativeWindowBorder
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static boolean hasCustomDecoration( Window window ) {
|
public static boolean hasCustomDecoration( Window window ) {
|
||||||
if( canUseJBRCustomDecorations )
|
|
||||||
return JBRCustomDecorations.hasCustomDecoration( window );
|
|
||||||
|
|
||||||
if( !isSupported() )
|
if( !isSupported() )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -225,11 +211,6 @@ public class FlatNativeWindowBorder
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void setHasCustomDecoration( Window window, boolean hasCustomDecoration ) {
|
public static void setHasCustomDecoration( Window window, boolean hasCustomDecoration ) {
|
||||||
if( canUseJBRCustomDecorations ) {
|
|
||||||
JBRCustomDecorations.setHasCustomDecoration( window, hasCustomDecoration );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !isSupported() )
|
if( !isSupported() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -240,11 +221,6 @@ public class FlatNativeWindowBorder
|
|||||||
List<Rectangle> hitTestSpots, Rectangle appIconBounds, Rectangle minimizeButtonBounds,
|
List<Rectangle> hitTestSpots, Rectangle appIconBounds, Rectangle minimizeButtonBounds,
|
||||||
Rectangle maximizeButtonBounds, Rectangle closeButtonBounds )
|
Rectangle maximizeButtonBounds, Rectangle closeButtonBounds )
|
||||||
{
|
{
|
||||||
if( canUseJBRCustomDecorations ) {
|
|
||||||
JBRCustomDecorations.setTitleBarHeightAndHitTestSpots( window, titleBarHeight, hitTestSpots );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !isSupported() )
|
if( !isSupported() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -253,7 +229,7 @@ public class FlatNativeWindowBorder
|
|||||||
}
|
}
|
||||||
|
|
||||||
static boolean showWindow( Window window, int cmd ) {
|
static boolean showWindow( Window window, int cmd ) {
|
||||||
if( canUseJBRCustomDecorations || !isSupported() )
|
if( !isSupported() )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return nativeProvider.showWindow( window, cmd );
|
return nativeProvider.showWindow( window, cmd );
|
||||||
@@ -320,20 +296,36 @@ public class FlatNativeWindowBorder
|
|||||||
* No longer needed since Windows 11.
|
* No longer needed since Windows 11.
|
||||||
*/
|
*/
|
||||||
static class WindowTopBorder
|
static class WindowTopBorder
|
||||||
extends JBRCustomDecorations.JBRWindowTopBorder
|
extends BorderUIResource.EmptyBorderUIResource
|
||||||
{
|
{
|
||||||
private static WindowTopBorder instance;
|
private static WindowTopBorder instance;
|
||||||
|
|
||||||
static JBRWindowTopBorder getInstance() {
|
private final Color activeLightColor = new Color( 0x707070 );
|
||||||
if( canUseJBRCustomDecorations )
|
private final Color activeDarkColor = new Color( 0x2D2E2F );
|
||||||
return JBRWindowTopBorder.getInstance();
|
private final Color inactiveLightColor = new Color( 0xaaaaaa );
|
||||||
|
private final Color inactiveDarkColor = new Color( 0x494A4B );
|
||||||
|
|
||||||
|
private boolean colorizationAffectsBorders;
|
||||||
|
private Color activeColor;
|
||||||
|
|
||||||
|
static WindowTopBorder getInstance() {
|
||||||
if( instance == null )
|
if( instance == null )
|
||||||
instance = new WindowTopBorder();
|
instance = new WindowTopBorder();
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
WindowTopBorder() {
|
||||||
|
super( 1, 0, 0, 0 );
|
||||||
|
|
||||||
|
update();
|
||||||
|
installListeners();
|
||||||
|
}
|
||||||
|
|
||||||
|
void update() {
|
||||||
|
colorizationAffectsBorders = isColorizationColorAffectsBorders();
|
||||||
|
activeColor = calculateActiveBorderColor();
|
||||||
|
}
|
||||||
|
|
||||||
void installListeners() {
|
void installListeners() {
|
||||||
nativeProvider.addChangeListener( e -> {
|
nativeProvider.addChangeListener( e -> {
|
||||||
update();
|
update();
|
||||||
@@ -346,19 +338,69 @@ public class FlatNativeWindowBorder
|
|||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
boolean isColorizationColorAffectsBorders() {
|
boolean isColorizationColorAffectsBorders() {
|
||||||
return nativeProvider.isColorizationColorAffectsBorders();
|
return nativeProvider.isColorizationColorAffectsBorders();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
Color getColorizationColor() {
|
Color getColorizationColor() {
|
||||||
return nativeProvider.getColorizationColor();
|
return nativeProvider.getColorizationColor();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
int getColorizationColorBalance() {
|
int getColorizationColorBalance() {
|
||||||
return nativeProvider.getColorizationColorBalance();
|
return nativeProvider.getColorizationColorBalance();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Color calculateActiveBorderColor() {
|
||||||
|
if( !colorizationAffectsBorders )
|
||||||
|
return null;
|
||||||
|
|
||||||
|
Color colorizationColor = getColorizationColor();
|
||||||
|
if( colorizationColor != null ) {
|
||||||
|
int colorizationColorBalance = getColorizationColorBalance();
|
||||||
|
if( colorizationColorBalance < 0 || colorizationColorBalance > 100 )
|
||||||
|
colorizationColorBalance = 100;
|
||||||
|
|
||||||
|
if( colorizationColorBalance == 0 )
|
||||||
|
return new Color( 0xD9D9D9 );
|
||||||
|
if( colorizationColorBalance == 100 )
|
||||||
|
return colorizationColor;
|
||||||
|
|
||||||
|
float alpha = colorizationColorBalance / 100.0f;
|
||||||
|
float remainder = 1 - alpha;
|
||||||
|
int r = Math.round( colorizationColor.getRed() * alpha + 0xD9 * remainder );
|
||||||
|
int g = Math.round( colorizationColor.getGreen() * alpha + 0xD9 * remainder );
|
||||||
|
int b = Math.round( colorizationColor.getBlue() * alpha + 0xD9 * remainder );
|
||||||
|
|
||||||
|
// avoid potential IllegalArgumentException in Color constructor
|
||||||
|
r = Math.min( Math.max( r, 0 ), 255 );
|
||||||
|
g = Math.min( Math.max( g, 0 ), 255 );
|
||||||
|
b = Math.min( Math.max( b, 0 ), 255 );
|
||||||
|
|
||||||
|
return new Color( r, g, b );
|
||||||
|
}
|
||||||
|
|
||||||
|
Color activeBorderColor = (Color) Toolkit.getDefaultToolkit().getDesktopProperty( "win.frame.activeBorderColor" );
|
||||||
|
return (activeBorderColor != null) ? activeBorderColor : UIManager.getColor( "MenuBar.borderColor" );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
|
||||||
|
Window window = SwingUtilities.windowForComponent( c );
|
||||||
|
boolean active = window != null && window.isActive();
|
||||||
|
boolean dark = FlatLaf.isLafDark();
|
||||||
|
|
||||||
|
g.setColor( active
|
||||||
|
? (activeColor != null ? activeColor : (dark ? activeDarkColor : activeLightColor))
|
||||||
|
: (dark ? inactiveDarkColor : inactiveLightColor) );
|
||||||
|
HiDPIUtils.paintAtScale1x( (Graphics2D) g, x, y, width, height, this::paintImpl );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void paintImpl( Graphics2D g, int x, int y, int width, int height, double scaleFactor ) {
|
||||||
|
g.fillRect( x, y, width, 1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
void repaintBorder( Component c ) {
|
||||||
|
c.repaint( 0, 0, c.getWidth(), 1 );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf.ui;
|
package com.formdev.flatlaf.ui;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
import java.awt.Window;
|
import java.awt.Window;
|
||||||
import com.formdev.flatlaf.util.SystemInfo;
|
import com.formdev.flatlaf.util.SystemInfo;
|
||||||
|
|
||||||
@@ -31,6 +32,12 @@ public class FlatNativeWindowsLibrary
|
|||||||
{
|
{
|
||||||
private static long osBuildNumber = Long.MIN_VALUE;
|
private static long osBuildNumber = Long.MIN_VALUE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether native library is loaded/available.
|
||||||
|
* <p>
|
||||||
|
* <b>Note</b>: It is required to invoke this method before invoking any other
|
||||||
|
* method of this class. Otherwise, the native library may not be loaded.
|
||||||
|
*/
|
||||||
public static boolean isLoaded() {
|
public static boolean isLoaded() {
|
||||||
return SystemInfo.isWindows && FlatNativeLibrary.isLoaded();
|
return SystemInfo.isWindows && FlatNativeLibrary.isLoaded();
|
||||||
}
|
}
|
||||||
@@ -93,15 +100,60 @@ public class FlatNativeWindowsLibrary
|
|||||||
public native static boolean setWindowCornerPreference( long hwnd, int cornerPreference );
|
public native static boolean setWindowCornerPreference( long hwnd, int cornerPreference );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the color of the window border.
|
* DWMWINDOWATTRIBUTE
|
||||||
* The red/green/blue values must be in range {@code 0 - 255}.
|
* see https://learn.microsoft.com/en-us/windows/win32/api/dwmapi/ne-dwmapi-dwmwindowattribute
|
||||||
* If red is {@code -1}, then the system default border color is used (useful to reset the border color).
|
*
|
||||||
* If red is {@code -2}, then no border is painted.
|
* @since 3.3
|
||||||
* <p>
|
*/
|
||||||
* Invokes Win32 API method {@code DwmSetWindowAttribute(DWMWA_BORDER_COLOR)}.
|
public static final int
|
||||||
|
DWMWA_USE_IMMERSIVE_DARK_MODE = 20,
|
||||||
|
DWMWA_BORDER_COLOR = 34,
|
||||||
|
DWMWA_CAPTION_COLOR = 35,
|
||||||
|
DWMWA_TEXT_COLOR = 36;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invokes Win32 API method {@code DwmSetWindowAttribute()} with a {@code BOOL} attribute value.
|
||||||
|
* See https://learn.microsoft.com/en-us/windows/win32/api/dwmapi/nf-dwmapi-dwmsetwindowattribute
|
||||||
|
*
|
||||||
|
* @since 3.3
|
||||||
|
*/
|
||||||
|
public native static boolean dwmSetWindowAttributeBOOL( long hwnd, int attribute, boolean value );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invokes Win32 API method {@code DwmSetWindowAttribute()} with a {@code DWORD} attribute value.
|
||||||
|
* See https://learn.microsoft.com/en-us/windows/win32/api/dwmapi/nf-dwmapi-dwmsetwindowattribute
|
||||||
|
*
|
||||||
|
* @since 3.3
|
||||||
|
*/
|
||||||
|
public native static boolean dwmSetWindowAttributeDWORD( long hwnd, int attribute, int value );
|
||||||
|
|
||||||
|
/** @since 3.3 */
|
||||||
|
public static final int
|
||||||
|
// use this constant to reset any window part colors to the system default behavior
|
||||||
|
DWMWA_COLOR_DEFAULT = 0xFFFFFFFF,
|
||||||
|
// use this constant to specify that a window part should not be rendered
|
||||||
|
DWMWA_COLOR_NONE = 0xFFFFFFFE;
|
||||||
|
|
||||||
|
/** @since 3.3 */
|
||||||
|
public static final Color COLOR_NONE = new Color( 0, true );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invokes Win32 API method {@code DwmSetWindowAttribute()} with a {@code COLORREF} attribute value.
|
||||||
* See https://learn.microsoft.com/en-us/windows/win32/api/dwmapi/nf-dwmapi-dwmsetwindowattribute
|
* See https://learn.microsoft.com/en-us/windows/win32/api/dwmapi/nf-dwmapi-dwmsetwindowattribute
|
||||||
* <p>
|
* <p>
|
||||||
* Supported since Windows 11 Build 22000.
|
* Supported since Windows 11 Build 22000.
|
||||||
|
*
|
||||||
|
* @since 3.3
|
||||||
*/
|
*/
|
||||||
public native static boolean setWindowBorderColor( long hwnd, int red, int green, int blue );
|
public static boolean dwmSetWindowAttributeCOLORREF( long hwnd, int attribute, Color color ) {
|
||||||
|
// convert color to Windows RGB value
|
||||||
|
int rgb = (color == COLOR_NONE)
|
||||||
|
? DWMWA_COLOR_NONE
|
||||||
|
: (color != null
|
||||||
|
? (color.getRed() | (color.getGreen() << 8) | (color.getBlue() << 16))
|
||||||
|
: DWMWA_COLOR_DEFAULT);
|
||||||
|
|
||||||
|
// DwmSetWindowAttribute() expects COLORREF as attribute value, which is defined as DWORD
|
||||||
|
return dwmSetWindowAttributeDWORD( hwnd, attribute, rgb );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,9 +30,7 @@ import javax.swing.JPanel;
|
|||||||
import javax.swing.JRootPane;
|
import javax.swing.JRootPane;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import javax.swing.border.Border;
|
|
||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
import javax.swing.plaf.UIResource;
|
|
||||||
import javax.swing.plaf.basic.BasicHTML;
|
import javax.swing.plaf.basic.BasicHTML;
|
||||||
import javax.swing.plaf.basic.BasicOptionPaneUI;
|
import javax.swing.plaf.basic.BasicOptionPaneUI;
|
||||||
import com.formdev.flatlaf.FlatClientProperties;
|
import com.formdev.flatlaf.FlatClientProperties;
|
||||||
@@ -115,13 +113,6 @@ public class FlatOptionPaneUI
|
|||||||
sameSizeButtons = FlatUIUtils.getUIBoolean( "OptionPane.sameSizeButtons", true );
|
sameSizeButtons = FlatUIUtils.getUIBoolean( "OptionPane.sameSizeButtons", true );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void installComponents() {
|
|
||||||
super.installComponents();
|
|
||||||
|
|
||||||
updateChildPanels( optionPane );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected PropertyChangeListener createPropertyChangeListener() {
|
protected PropertyChangeListener createPropertyChangeListener() {
|
||||||
PropertyChangeListener superListener = super.createPropertyChangeListener();
|
PropertyChangeListener superListener = super.createPropertyChangeListener();
|
||||||
@@ -155,6 +146,13 @@ public class FlatOptionPaneUI
|
|||||||
protected Container createMessageArea() {
|
protected Container createMessageArea() {
|
||||||
Container messageArea = super.createMessageArea();
|
Container messageArea = super.createMessageArea();
|
||||||
|
|
||||||
|
// use non-UIResource OptionPane.messageAreaBorder to avoid that it is replaced when switching LaF
|
||||||
|
// and make panel non-opaque for OptionPane.background
|
||||||
|
updateAreaPanel( messageArea );
|
||||||
|
|
||||||
|
// make known sub-panels non-opaque for OptionPane.background
|
||||||
|
updateKnownChildPanels( messageArea );
|
||||||
|
|
||||||
// set icon-message gap
|
// set icon-message gap
|
||||||
if( iconMessageGap > 0 ) {
|
if( iconMessageGap > 0 ) {
|
||||||
Component iconMessageSeparator = SwingUtils.getComponentByName( messageArea, "OptionPane.separator" );
|
Component iconMessageSeparator = SwingUtils.getComponentByName( messageArea, "OptionPane.separator" );
|
||||||
@@ -169,6 +167,10 @@ public class FlatOptionPaneUI
|
|||||||
protected Container createButtonArea() {
|
protected Container createButtonArea() {
|
||||||
Container buttonArea = super.createButtonArea();
|
Container buttonArea = super.createButtonArea();
|
||||||
|
|
||||||
|
// use non-UIResource OptionPane.buttonAreaBorder to avoid that it is replaced when switching LaF
|
||||||
|
// and make panel non-opaque for OptionPane.background
|
||||||
|
updateAreaPanel( buttonArea );
|
||||||
|
|
||||||
// scale button padding and subtract focusWidth
|
// scale button padding and subtract focusWidth
|
||||||
if( buttonArea.getLayout() instanceof ButtonAreaLayout ) {
|
if( buttonArea.getLayout() instanceof ButtonAreaLayout ) {
|
||||||
ButtonAreaLayout layout = (ButtonAreaLayout) buttonArea.getLayout();
|
ButtonAreaLayout layout = (ButtonAreaLayout) buttonArea.getLayout();
|
||||||
@@ -218,22 +220,33 @@ public class FlatOptionPaneUI
|
|||||||
super.addMessageComponents( container, cons, msg, maxll, internallyCreated );
|
super.addMessageComponents( container, cons, msg, maxll, internallyCreated );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateChildPanels( Container c ) {
|
private void updateAreaPanel( Container area ) {
|
||||||
for( Component child : c.getComponents() ) {
|
if( !(area instanceof JPanel) )
|
||||||
if( child.getClass() == JPanel.class ) {
|
return;
|
||||||
JPanel panel = (JPanel)child;
|
|
||||||
|
|
||||||
// make sub-panel non-opaque for OptionPane.background
|
// use non-UIResource border to avoid that it is replaced when switching LaF
|
||||||
|
// and make panel non-opaque for OptionPane.background
|
||||||
|
JPanel panel = (JPanel) area;
|
||||||
|
panel.setBorder( FlatUIUtils.nonUIResource( panel.getBorder() ) );
|
||||||
panel.setOpaque( false );
|
panel.setOpaque( false );
|
||||||
|
}
|
||||||
|
|
||||||
// use non-UIResource borders to avoid that they are replaced when switching LaF
|
private void updateKnownChildPanels( Container c ) {
|
||||||
Border border = panel.getBorder();
|
for( Component child : c.getComponents() ) {
|
||||||
if( border instanceof UIResource )
|
if( child instanceof JPanel && child.getName() != null ) {
|
||||||
panel.setBorder( FlatUIUtils.nonUIResource( border ) );
|
switch( child.getName() ) {
|
||||||
|
case "OptionPane.realBody":
|
||||||
|
case "OptionPane.body":
|
||||||
|
case "OptionPane.separator":
|
||||||
|
case "OptionPane.break":
|
||||||
|
// make known sub-panels non-opaque for OptionPane.background
|
||||||
|
((JPanel)child).setOpaque( false );
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( child instanceof Container )
|
if( child instanceof Container )
|
||||||
updateChildPanels( (Container) child );
|
updateKnownChildPanels( (Container) child );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -71,6 +71,8 @@ import com.formdev.flatlaf.util.UIScale;
|
|||||||
public class FlatPopupFactory
|
public class FlatPopupFactory
|
||||||
extends PopupFactory
|
extends PopupFactory
|
||||||
{
|
{
|
||||||
|
static final String KEY_POPUP_USES_NATIVE_BORDER = "FlatLaf.internal.FlatPopupFactory.popupUsesNativeBorder";
|
||||||
|
|
||||||
private MethodHandle java8getPopupMethod;
|
private MethodHandle java8getPopupMethod;
|
||||||
private MethodHandle java9getPopupMethod;
|
private MethodHandle java9getPopupMethod;
|
||||||
|
|
||||||
@@ -92,17 +94,20 @@ public class FlatPopupFactory
|
|||||||
return new NonFlashingPopup( getPopupForScreenOfOwner( owner, contents, x, y, forceHeavyWeight ), contents );
|
return new NonFlashingPopup( getPopupForScreenOfOwner( owner, contents, x, y, forceHeavyWeight ), contents );
|
||||||
|
|
||||||
// macOS and Linux adds drop shadow to heavy weight popups
|
// macOS and Linux adds drop shadow to heavy weight popups
|
||||||
if( SystemInfo.isMacOS || SystemInfo.isLinux )
|
if( SystemInfo.isMacOS || SystemInfo.isLinux ) {
|
||||||
return new NonFlashingPopup( getPopupForScreenOfOwner( owner, contents, x, y, true ), contents );
|
NonFlashingPopup popup = new NonFlashingPopup( getPopupForScreenOfOwner( owner, contents, x, y, true ), contents );
|
||||||
|
if( popup.popupWindow != null && SystemInfo.isMacOS && FlatNativeMacLibrary.isLoaded() )
|
||||||
|
setupRoundedBorder( popup.popupWindow, owner, contents );
|
||||||
|
return popup;
|
||||||
|
}
|
||||||
|
|
||||||
// Windows 11 with FlatLaf native library can use rounded corners and shows drop shadow for heavy weight popups
|
// Windows 11 with FlatLaf native library can use rounded corners and shows drop shadow for heavy weight popups
|
||||||
int borderCornerRadius;
|
|
||||||
if( isWindows11BorderSupported() &&
|
if( isWindows11BorderSupported() &&
|
||||||
(borderCornerRadius = getBorderCornerRadius( owner, contents )) > 0 )
|
getBorderCornerRadius( owner, contents ) > 0 )
|
||||||
{
|
{
|
||||||
NonFlashingPopup popup = new NonFlashingPopup( getPopupForScreenOfOwner( owner, contents, x, y, true ), contents );
|
NonFlashingPopup popup = new NonFlashingPopup( getPopupForScreenOfOwner( owner, contents, x, y, true ), contents );
|
||||||
if( popup.popupWindow != null )
|
if( popup.popupWindow != null )
|
||||||
setupWindows11Border( popup.popupWindow, contents, borderCornerRadius );
|
setupRoundedBorder( popup.popupWindow, owner, contents );
|
||||||
return popup;
|
return popup;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,67 +167,6 @@ public class FlatPopupFactory
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Shows the given popup and, if necessary, fixes the location of a heavy weight popup window.
|
|
||||||
* <p>
|
|
||||||
* On a dual screen setup, where screens use different scale factors, it may happen
|
|
||||||
* that the window location changes when showing a heavy weight popup window.
|
|
||||||
* E.g. when opening a dialog on the secondary screen and making combobox popup visible.
|
|
||||||
* <p>
|
|
||||||
* This is a workaround for https://bugs.openjdk.java.net/browse/JDK-8224608
|
|
||||||
*/
|
|
||||||
private static void showPopupAndFixLocation( Popup popup, Window popupWindow ) {
|
|
||||||
if( popupWindow != null ) {
|
|
||||||
// remember location of heavy weight popup window
|
|
||||||
int x = popupWindow.getX();
|
|
||||||
int y = popupWindow.getY();
|
|
||||||
|
|
||||||
popup.show();
|
|
||||||
|
|
||||||
// restore popup window location if it has changed
|
|
||||||
// (probably scaled when screens use different scale factors)
|
|
||||||
if( popupWindow.getX() != x || popupWindow.getY() != y )
|
|
||||||
popupWindow.setLocation( x, y );
|
|
||||||
} else
|
|
||||||
popup.show();
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isOptionEnabled( Component owner, Component contents, String clientKey, String uiKey ) {
|
|
||||||
Object value = getOption( owner, contents, clientKey, uiKey );
|
|
||||||
return (value instanceof Boolean) ? (Boolean) value : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private int getBorderCornerRadius( Component owner, Component contents ) {
|
|
||||||
String uiKey =
|
|
||||||
(contents instanceof BasicComboPopup) ? "ComboBox.borderCornerRadius" :
|
|
||||||
(contents instanceof JPopupMenu) ? "PopupMenu.borderCornerRadius" :
|
|
||||||
(contents instanceof JToolTip) ? "ToolTip.borderCornerRadius" :
|
|
||||||
"Popup.borderCornerRadius";
|
|
||||||
|
|
||||||
Object value = getOption( owner, contents, FlatClientProperties.POPUP_BORDER_CORNER_RADIUS, uiKey );
|
|
||||||
return (value instanceof Integer) ? (Integer) value : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get option from:
|
|
||||||
* <ol>
|
|
||||||
* <li>client property {@code clientKey} of {@code owner}
|
|
||||||
* <li>client property {@code clientKey} of {@code contents}
|
|
||||||
* <li>UI property {@code uiKey}
|
|
||||||
* </ol>
|
|
||||||
*/
|
|
||||||
private Object getOption( Component owner, Component contents, String clientKey, String uiKey ) {
|
|
||||||
for( Component c : new Component[] { owner, contents } ) {
|
|
||||||
if( c instanceof JComponent ) {
|
|
||||||
Object value = ((JComponent)c).getClientProperty( clientKey );
|
|
||||||
if( value != null )
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return UIManager.get( uiKey );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* There is no API in Java 8 to force creation of heavy weight popups,
|
* There is no API in Java 8 to force creation of heavy weight popups,
|
||||||
* but it is possible with reflection. Java 9 provides a new method.
|
* but it is possible with reflection. Java 9 provides a new method.
|
||||||
@@ -258,6 +202,33 @@ public class FlatPopupFactory
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static boolean isOptionEnabled( Component owner, Component contents, String clientKey, String uiKey ) {
|
||||||
|
Object value = getOption( owner, contents, clientKey, uiKey );
|
||||||
|
return (value instanceof Boolean) ? (Boolean) value : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get option from:
|
||||||
|
* <ol>
|
||||||
|
* <li>client property {@code clientKey} of {@code owner}
|
||||||
|
* <li>client property {@code clientKey} of {@code contents}
|
||||||
|
* <li>UI property {@code uiKey}
|
||||||
|
* </ol>
|
||||||
|
*/
|
||||||
|
private static Object getOption( Component owner, Component contents, String clientKey, String uiKey ) {
|
||||||
|
for( Component c : new Component[] { owner, contents } ) {
|
||||||
|
if( c instanceof JComponent ) {
|
||||||
|
Object value = ((JComponent)c).getClientProperty( clientKey );
|
||||||
|
if( value != null )
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return UIManager.get( uiKey );
|
||||||
|
}
|
||||||
|
|
||||||
|
//---- tooltips -----------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Usually ToolTipManager places a tooltip at (mouseLocation.x, mouseLocation.y + 20).
|
* Usually ToolTipManager places a tooltip at (mouseLocation.x, mouseLocation.y + 20).
|
||||||
* In case that the tooltip would be partly outside of the screen,
|
* In case that the tooltip would be partly outside of the screen,
|
||||||
@@ -342,16 +313,40 @@ public class FlatPopupFactory
|
|||||||
((JComponent)owner).getToolTipLocation( me ) != null;
|
((JComponent)owner).getToolTipLocation( me ) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---- native rounded border ----------------------------------------------
|
||||||
|
|
||||||
private static boolean isWindows11BorderSupported() {
|
private static boolean isWindows11BorderSupported() {
|
||||||
return SystemInfo.isWindows_11_orLater && FlatNativeWindowsLibrary.isLoaded();
|
return SystemInfo.isWindows_11_orLater && FlatNativeWindowsLibrary.isLoaded();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void setupWindows11Border( Window popupWindow, Component contents, int borderCornerRadius ) {
|
private static void setupRoundedBorder( Window popupWindow, Component owner, Component contents ) {
|
||||||
// make sure that the Windows 11 window is created
|
// make sure that the native window is created
|
||||||
if( !popupWindow.isDisplayable() )
|
if( !popupWindow.isDisplayable() )
|
||||||
popupWindow.addNotify();
|
popupWindow.addNotify();
|
||||||
|
|
||||||
// get window handle
|
int borderCornerRadius = getBorderCornerRadius( owner, contents );
|
||||||
|
float borderWidth = getRoundedBorderWidth( owner, contents );
|
||||||
|
|
||||||
|
// get Swing border color
|
||||||
|
Color borderColor = null; // use system default color
|
||||||
|
if( contents instanceof JComponent ) {
|
||||||
|
Border border = ((JComponent)contents).getBorder();
|
||||||
|
border = FlatUIUtils.unwrapNonUIResourceBorder( border );
|
||||||
|
|
||||||
|
// get color from border of contents (e.g. JPopupMenu or JToolTip)
|
||||||
|
if( border instanceof FlatLineBorder )
|
||||||
|
borderColor = ((FlatLineBorder)border).getLineColor();
|
||||||
|
else if( border instanceof LineBorder )
|
||||||
|
borderColor = ((LineBorder)border).getLineColor();
|
||||||
|
else if( border instanceof EmptyBorder )
|
||||||
|
borderColor = FlatNativeWindowsLibrary.COLOR_NONE; // do not paint border
|
||||||
|
|
||||||
|
// avoid that FlatLineBorder paints the Swing border
|
||||||
|
((JComponent)contents).putClientProperty( KEY_POPUP_USES_NATIVE_BORDER, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( SystemInfo.isWindows ) {
|
||||||
|
// get native window handle
|
||||||
long hwnd = FlatNativeWindowsLibrary.getHWND( popupWindow );
|
long hwnd = FlatNativeWindowsLibrary.getHWND( popupWindow );
|
||||||
|
|
||||||
// set corner preference
|
// set corner preference
|
||||||
@@ -361,30 +356,16 @@ public class FlatPopupFactory
|
|||||||
FlatNativeWindowsLibrary.setWindowCornerPreference( hwnd, cornerPreference );
|
FlatNativeWindowsLibrary.setWindowCornerPreference( hwnd, cornerPreference );
|
||||||
|
|
||||||
// set border color
|
// set border color
|
||||||
int red = -1; // use system default color
|
FlatNativeWindowsLibrary.dwmSetWindowAttributeCOLORREF( hwnd, FlatNativeWindowsLibrary.DWMWA_BORDER_COLOR, borderColor );
|
||||||
int green = 0;
|
} else if( SystemInfo.isMacOS ) {
|
||||||
int blue = 0;
|
if( borderColor == null || borderColor == FlatNativeWindowsLibrary.COLOR_NONE )
|
||||||
if( contents instanceof JComponent ) {
|
borderWidth = 0;
|
||||||
Border border = ((JComponent)contents).getBorder();
|
|
||||||
border = FlatUIUtils.unwrapNonUIResourceBorder( border );
|
|
||||||
|
|
||||||
// get color from border of contents (e.g. JPopupMenu or JToolTip)
|
// set corner radius, border width and color
|
||||||
Color borderColor = null;
|
FlatNativeMacLibrary.setWindowRoundedBorder( popupWindow, borderCornerRadius,
|
||||||
if( border instanceof FlatLineBorder )
|
borderWidth, (borderColor != null) ? borderColor.getRGB() : 0 );
|
||||||
borderColor = ((FlatLineBorder)border).getLineColor();
|
|
||||||
else if( border instanceof LineBorder )
|
|
||||||
borderColor = ((LineBorder)border).getLineColor();
|
|
||||||
else if( border instanceof EmptyBorder )
|
|
||||||
red = -2; // do not paint border
|
|
||||||
|
|
||||||
if( borderColor != null ) {
|
|
||||||
red = borderColor.getRed();
|
|
||||||
green = borderColor.getGreen();
|
|
||||||
blue = borderColor.getBlue();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
FlatNativeWindowsLibrary.setWindowBorderColor( hwnd, red, green, blue );
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void resetWindows11Border( Window popupWindow ) {
|
private static void resetWindows11Border( Window popupWindow ) {
|
||||||
// get window handle
|
// get window handle
|
||||||
@@ -396,7 +377,34 @@ public class FlatPopupFactory
|
|||||||
FlatNativeWindowsLibrary.setWindowCornerPreference( hwnd, FlatNativeWindowsLibrary.DWMWCP_DONOTROUND );
|
FlatNativeWindowsLibrary.setWindowCornerPreference( hwnd, FlatNativeWindowsLibrary.DWMWCP_DONOTROUND );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static int getBorderCornerRadius( Component owner, Component contents ) {
|
||||||
|
String uiKey =
|
||||||
|
(contents instanceof BasicComboPopup) ? "ComboBox.borderCornerRadius" :
|
||||||
|
(contents instanceof JPopupMenu) ? "PopupMenu.borderCornerRadius" :
|
||||||
|
(contents instanceof JToolTip) ? "ToolTip.borderCornerRadius" :
|
||||||
|
"Popup.borderCornerRadius";
|
||||||
|
|
||||||
|
Object value = getOption( owner, contents, FlatClientProperties.POPUP_BORDER_CORNER_RADIUS, uiKey );
|
||||||
|
return (value instanceof Integer) ? (Integer) value : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static float getRoundedBorderWidth( Component owner, Component contents ) {
|
||||||
|
String uiKey =
|
||||||
|
(contents instanceof BasicComboPopup) ? "ComboBox.roundedBorderWidth" :
|
||||||
|
(contents instanceof JPopupMenu) ? "PopupMenu.roundedBorderWidth" :
|
||||||
|
(contents instanceof JToolTip) ? "ToolTip.roundedBorderWidth" :
|
||||||
|
"Popup.roundedBorderWidth";
|
||||||
|
|
||||||
|
Object value = getOption( owner, contents, FlatClientProperties.POPUP_ROUNDED_BORDER_WIDTH, uiKey );
|
||||||
|
return (value instanceof Number) ? ((Number)value).floatValue() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---- fixes --------------------------------------------------------------
|
||||||
|
|
||||||
private static boolean overlapsHeavyWeightComponent( Component owner, Component contents, int x, int y ) {
|
private static boolean overlapsHeavyWeightComponent( Component owner, Component contents, int x, int y ) {
|
||||||
|
if( owner == null )
|
||||||
|
return false;
|
||||||
|
|
||||||
Window window = SwingUtilities.getWindowAncestor( owner );
|
Window window = SwingUtilities.getWindowAncestor( owner );
|
||||||
if( window == null )
|
if( window == null )
|
||||||
return false;
|
return false;
|
||||||
@@ -427,7 +435,7 @@ public class FlatPopupFactory
|
|||||||
* On Linux with Wayland, since Java 21, Swing adds a window focus listener to popup owner/invoker window,
|
* On Linux with Wayland, since Java 21, Swing adds a window focus listener to popup owner/invoker window,
|
||||||
* which hides the popup as soon as the owner/invoker window looses focus.
|
* which hides the popup as soon as the owner/invoker window looses focus.
|
||||||
* This works fine for light-weight popups.
|
* This works fine for light-weight popups.
|
||||||
* It also works for heavy-weight popups if the do not request focus.
|
* It also works for heavy-weight popups if they do not request focus.
|
||||||
* Because FlatLaf always uses heavy-weight popups, all popups that request focus
|
* Because FlatLaf always uses heavy-weight popups, all popups that request focus
|
||||||
* are broken since Java 21.
|
* are broken since Java 21.
|
||||||
*
|
*
|
||||||
@@ -455,6 +463,31 @@ public class FlatPopupFactory
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows the given popup and, if necessary, fixes the location of a heavy weight popup window.
|
||||||
|
* <p>
|
||||||
|
* On a dual screen setup, where screens use different scale factors, it may happen
|
||||||
|
* that the window location changes when showing a heavy weight popup window.
|
||||||
|
* E.g. when opening a dialog on the secondary screen and making combobox popup visible.
|
||||||
|
* <p>
|
||||||
|
* This is a workaround for https://bugs.openjdk.java.net/browse/JDK-8224608
|
||||||
|
*/
|
||||||
|
private static void showPopupAndFixLocation( Popup popup, Window popupWindow ) {
|
||||||
|
if( popupWindow != null ) {
|
||||||
|
// remember location of heavy weight popup window
|
||||||
|
int x = popupWindow.getX();
|
||||||
|
int y = popupWindow.getY();
|
||||||
|
|
||||||
|
popup.show();
|
||||||
|
|
||||||
|
// restore popup window location if it has changed
|
||||||
|
// (probably scaled when screens use different scale factors)
|
||||||
|
if( popupWindow.getX() != x || popupWindow.getY() != y )
|
||||||
|
popupWindow.setLocation( x, y );
|
||||||
|
} else
|
||||||
|
popup.show();
|
||||||
|
}
|
||||||
|
|
||||||
//---- class NonFlashingPopup ---------------------------------------------
|
//---- class NonFlashingPopup ---------------------------------------------
|
||||||
|
|
||||||
private static class NonFlashingPopup
|
private static class NonFlashingPopup
|
||||||
@@ -508,6 +541,9 @@ public class FlatPopupFactory
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void hide() {
|
public void hide() {
|
||||||
|
if( contents instanceof JComponent )
|
||||||
|
((JComponent)contents).putClientProperty( KEY_POPUP_USES_NATIVE_BORDER, null );
|
||||||
|
|
||||||
if( delegate != null ) {
|
if( delegate != null ) {
|
||||||
delegate.hide();
|
delegate.hide();
|
||||||
delegate = null;
|
delegate = null;
|
||||||
|
|||||||
@@ -263,7 +263,7 @@ public class FlatRadioButtonUI
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void paint( Graphics g, JComponent c ) {
|
public void paint( Graphics g, JComponent c ) {
|
||||||
// fill background even if not opaque if
|
// fill background even if not opaque and if:
|
||||||
// - contentAreaFilled is true and
|
// - contentAreaFilled is true and
|
||||||
// - if background color is different to default background color
|
// - if background color is different to default background color
|
||||||
// (this paints selection if using the component as cell renderer)
|
// (this paints selection if using the component as cell renderer)
|
||||||
|
|||||||
@@ -50,7 +50,6 @@ 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;
|
||||||
@@ -156,10 +155,6 @@ 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" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
// enable dark window appearance on macOS when running in JetBrains Runtime
|
|
||||||
if( SystemInfo.isJetBrainsJVM && SystemInfo.isMacOS_10_14_Mojave_orLater )
|
|
||||||
c.putClientProperty( "jetbrains.awt.windowDarkAppearance", FlatLaf.isLafDark() );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -499,7 +494,7 @@ public class FlatRootPaneUI
|
|||||||
@Override
|
@Override
|
||||||
public void invalidateLayout( Container parent ) {
|
public void invalidateLayout( Container parent ) {
|
||||||
if( titlePane != null )
|
if( titlePane != null )
|
||||||
titlePane.menuBarChanged();
|
titlePane.menuBarInvalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -245,7 +245,7 @@ public class FlatScrollBarUI
|
|||||||
// because scroll bars do not receive mouse exited event.
|
// because scroll bars do not receive mouse exited event.
|
||||||
// The scroll pane, including its scroll bars, is not part
|
// The scroll pane, including its scroll bars, is not part
|
||||||
// of the component hierarchy and does not receive mouse events
|
// of the component hierarchy and does not receive mouse events
|
||||||
// directly. Instead LWComponentPeer receives mouse events
|
// directly. Instead, LWComponentPeer receives mouse events
|
||||||
// and delegates them to peers, but entered/exited events
|
// and delegates them to peers, but entered/exited events
|
||||||
// are sent only for the whole scroll pane.
|
// are sent only for the whole scroll pane.
|
||||||
// Exited event is only sent when mouse leaves scroll pane.
|
// Exited event is only sent when mouse leaves scroll pane.
|
||||||
|
|||||||
@@ -0,0 +1,118 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2023 FormDev Software GmbH
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* 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.awt.Component;
|
||||||
|
import java.awt.Insets;
|
||||||
|
import javax.swing.JList;
|
||||||
|
import javax.swing.JScrollPane;
|
||||||
|
import javax.swing.JTable;
|
||||||
|
import javax.swing.JTree;
|
||||||
|
import javax.swing.UIManager;
|
||||||
|
import javax.swing.text.JTextComponent;
|
||||||
|
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
||||||
|
import com.formdev.flatlaf.util.UIScale;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Border for {@link javax.swing.JScrollPane}.
|
||||||
|
*
|
||||||
|
* @uiDefault ScrollPane.arc int
|
||||||
|
* @uiDefault ScrollPane.List.arc int
|
||||||
|
* @uiDefault ScrollPane.Table.arc int
|
||||||
|
* @uiDefault ScrollPane.TextComponent.arc int
|
||||||
|
* @uiDefault ScrollPane.Tree.arc int
|
||||||
|
|
||||||
|
* @author Karl Tauber
|
||||||
|
* @since 3.3
|
||||||
|
*/
|
||||||
|
public class FlatScrollPaneBorder
|
||||||
|
extends FlatBorder
|
||||||
|
{
|
||||||
|
@Styleable protected int arc = UIManager.getInt( "ScrollPane.arc" );
|
||||||
|
|
||||||
|
private boolean isArcStyled;
|
||||||
|
private final int listArc = FlatUIUtils.getUIInt( "ScrollPane.List.arc", -1 );
|
||||||
|
private final int tableArc = FlatUIUtils.getUIInt( "ScrollPane.Table.arc", -1 );
|
||||||
|
private final int textComponentArc = FlatUIUtils.getUIInt( "ScrollPane.TextComponent.arc", -1 );
|
||||||
|
private final int treeArc = FlatUIUtils.getUIInt( "ScrollPane.Tree.arc", -1 );
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object applyStyleProperty( String key, Object value ) {
|
||||||
|
Object oldValue = super.applyStyleProperty( key, value );
|
||||||
|
|
||||||
|
if( "arc".equals( key ) )
|
||||||
|
isArcStyled = true;
|
||||||
|
|
||||||
|
return oldValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Insets getBorderInsets( Component c, Insets insets ) {
|
||||||
|
insets = super.getBorderInsets( c, insets );
|
||||||
|
|
||||||
|
// if view is rounded, increase left and right insets to avoid that the viewport
|
||||||
|
// is painted over the rounded border on the corners
|
||||||
|
int padding = getLeftRightPadding( c );
|
||||||
|
if( padding > 0 ) {
|
||||||
|
insets.left += padding;
|
||||||
|
insets.right += padding;
|
||||||
|
}
|
||||||
|
|
||||||
|
return insets;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getArc( Component c ) {
|
||||||
|
if( isCellEditor( c ) )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if( isArcStyled )
|
||||||
|
return arc;
|
||||||
|
|
||||||
|
if( c instanceof JScrollPane ) {
|
||||||
|
Component view = FlatScrollPaneUI.getView( (JScrollPane) c );
|
||||||
|
if( listArc >= 0 && view instanceof JList )
|
||||||
|
return listArc;
|
||||||
|
if( tableArc >= 0 && view instanceof JTable )
|
||||||
|
return tableArc;
|
||||||
|
if( textComponentArc >= 0&& view instanceof JTextComponent )
|
||||||
|
return textComponentArc;
|
||||||
|
if( treeArc >= 0 && view instanceof JTree )
|
||||||
|
return treeArc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return arc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the scaled left/right padding used when arc is larger than zero.
|
||||||
|
* <p>
|
||||||
|
* This is the distance from the inside of the left border to the left side of the view component.
|
||||||
|
* On the right side, this is the distance between the right side of the view component and
|
||||||
|
* the vertical scrollbar. Or the inside of the right border if the scrollbar is hidden.
|
||||||
|
*/
|
||||||
|
public int getLeftRightPadding( Component c ) {
|
||||||
|
// Subtract lineWidth from radius because radius is given for the outside
|
||||||
|
// of the painted line, but insets from super already include lineWidth.
|
||||||
|
// Reduce padding by 10% to make padding slightly smaller because it is not recognizable
|
||||||
|
// when the view is minimally painted over the beginning of the border curve.
|
||||||
|
int arc = getArc( c );
|
||||||
|
return (arc > 0)
|
||||||
|
? Math.max( Math.round( UIScale.scale( ((arc / 2f) - getLineWidth( c )) * 0.9f ) ), 0 )
|
||||||
|
: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,9 +17,12 @@
|
|||||||
package com.formdev.flatlaf.ui;
|
package com.formdev.flatlaf.ui;
|
||||||
|
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
|
import java.awt.Container;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
import java.awt.Insets;
|
import java.awt.Insets;
|
||||||
import java.awt.KeyboardFocusManager;
|
import java.awt.KeyboardFocusManager;
|
||||||
|
import java.awt.LayoutManager;
|
||||||
import java.awt.Rectangle;
|
import java.awt.Rectangle;
|
||||||
import java.awt.event.ContainerEvent;
|
import java.awt.event.ContainerEvent;
|
||||||
import java.awt.event.ContainerListener;
|
import java.awt.event.ContainerListener;
|
||||||
@@ -41,16 +44,19 @@ import javax.swing.JTree;
|
|||||||
import javax.swing.JViewport;
|
import javax.swing.JViewport;
|
||||||
import javax.swing.LookAndFeel;
|
import javax.swing.LookAndFeel;
|
||||||
import javax.swing.ScrollPaneConstants;
|
import javax.swing.ScrollPaneConstants;
|
||||||
|
import javax.swing.ScrollPaneLayout;
|
||||||
import javax.swing.Scrollable;
|
import javax.swing.Scrollable;
|
||||||
import javax.swing.SwingConstants;
|
import javax.swing.SwingConstants;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
|
import javax.swing.border.Border;
|
||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
import javax.swing.plaf.basic.BasicScrollPaneUI;
|
import javax.swing.plaf.basic.BasicScrollPaneUI;
|
||||||
import com.formdev.flatlaf.FlatClientProperties;
|
import com.formdev.flatlaf.FlatClientProperties;
|
||||||
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
||||||
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
|
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
|
||||||
import com.formdev.flatlaf.util.LoggingFacade;
|
import com.formdev.flatlaf.util.LoggingFacade;
|
||||||
|
import com.formdev.flatlaf.util.UIScale;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JScrollPane}.
|
* Provides the Flat LaF UI delegate for {@link javax.swing.JScrollPane}.
|
||||||
@@ -97,7 +103,13 @@ public class FlatScrollPaneUI
|
|||||||
super.installUI( c );
|
super.installUI( c );
|
||||||
|
|
||||||
int focusWidth = UIManager.getInt( "Component.focusWidth" );
|
int focusWidth = UIManager.getInt( "Component.focusWidth" );
|
||||||
LookAndFeel.installProperty( c, "opaque", focusWidth == 0 );
|
int arc = UIManager.getInt( "ScrollPane.arc" );
|
||||||
|
LookAndFeel.installProperty( c, "opaque", focusWidth == 0 && arc == 0 );
|
||||||
|
|
||||||
|
// install layout manager
|
||||||
|
LayoutManager layout = c.getLayout();
|
||||||
|
if( layout != null && layout.getClass() == ScrollPaneLayout.UIResource.class )
|
||||||
|
c.setLayout( createScrollPaneLayout() );
|
||||||
|
|
||||||
installStyle();
|
installStyle();
|
||||||
|
|
||||||
@@ -108,6 +120,10 @@ public class FlatScrollPaneUI
|
|||||||
public void uninstallUI( JComponent c ) {
|
public void uninstallUI( JComponent c ) {
|
||||||
MigLayoutVisualPadding.uninstall( scrollpane );
|
MigLayoutVisualPadding.uninstall( scrollpane );
|
||||||
|
|
||||||
|
// uninstall layout manager
|
||||||
|
if( c.getLayout() instanceof FlatScrollPaneLayout )
|
||||||
|
c.setLayout( new ScrollPaneLayout.UIResource() );
|
||||||
|
|
||||||
super.uninstallUI( c );
|
super.uninstallUI( c );
|
||||||
|
|
||||||
oldStyleValues = null;
|
oldStyleValues = null;
|
||||||
@@ -130,6 +146,13 @@ public class FlatScrollPaneUI
|
|||||||
handler = null;
|
handler = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 3.3
|
||||||
|
*/
|
||||||
|
protected FlatScrollPaneLayout createScrollPaneLayout() {
|
||||||
|
return new FlatScrollPaneLayout();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected MouseWheelListener createMouseWheelListener() {
|
protected MouseWheelListener createMouseWheelListener() {
|
||||||
MouseWheelListener superListener = super.createMouseWheelListener();
|
MouseWheelListener superListener = super.createMouseWheelListener();
|
||||||
@@ -290,8 +313,7 @@ public class FlatScrollPaneUI
|
|||||||
Object corner = e.getNewValue();
|
Object corner = e.getNewValue();
|
||||||
if( corner instanceof JButton &&
|
if( corner instanceof JButton &&
|
||||||
((JButton)corner).getBorder() instanceof FlatButtonBorder &&
|
((JButton)corner).getBorder() instanceof FlatButtonBorder &&
|
||||||
scrollpane.getViewport() != null &&
|
getView( scrollpane ) instanceof JTable )
|
||||||
scrollpane.getViewport().getView() instanceof JTable )
|
|
||||||
{
|
{
|
||||||
((JButton)corner).setBorder( BorderFactory.createEmptyBorder() );
|
((JButton)corner).setBorder( BorderFactory.createEmptyBorder() );
|
||||||
((JButton)corner).setFocusable( false );
|
((JButton)corner).setFocusable( false );
|
||||||
@@ -308,6 +330,18 @@ public class FlatScrollPaneUI
|
|||||||
scrollpane.revalidate();
|
scrollpane.revalidate();
|
||||||
scrollpane.repaint();
|
scrollpane.repaint();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case "border":
|
||||||
|
Object newBorder = e.getNewValue();
|
||||||
|
if( newBorder != null && newBorder == UIManager.getBorder( "Table.scrollPaneBorder" ) ) {
|
||||||
|
// JTable.configureEnclosingScrollPaneUI() replaces the scrollpane border
|
||||||
|
// with another one --> re-apply style on new border
|
||||||
|
borderShared = null;
|
||||||
|
installStyle();
|
||||||
|
scrollpane.revalidate();
|
||||||
|
scrollpane.repaint();
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -334,9 +368,10 @@ public class FlatScrollPaneUI
|
|||||||
|
|
||||||
/** @since 2 */
|
/** @since 2 */
|
||||||
protected Object applyStyleProperty( String key, Object value ) {
|
protected Object applyStyleProperty( String key, Object value ) {
|
||||||
if( key.equals( "focusWidth" ) ) {
|
if( key.equals( "focusWidth" ) || key.equals( "arc" ) ) {
|
||||||
int focusWidth = (value instanceof Integer) ? (int) value : UIManager.getInt( "Component.focusWidth" );
|
int focusWidth = (value instanceof Integer) ? (int) value : UIManager.getInt( "Component.focusWidth" );
|
||||||
LookAndFeel.installProperty( scrollpane, "opaque", focusWidth == 0 );
|
int arc = (value instanceof Integer) ? (int) value : UIManager.getInt( "ScrollPane.arc" );
|
||||||
|
LookAndFeel.installProperty( scrollpane, "opaque", focusWidth == 0 && arc == 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( borderShared == null )
|
if( borderShared == null )
|
||||||
@@ -402,13 +437,46 @@ public class FlatScrollPaneUI
|
|||||||
c.getHeight() - insets.top - insets.bottom );
|
c.getHeight() - insets.top - insets.bottom );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if view is rounded, paint rounded background with view background color
|
||||||
|
// to ensure that free areas at left and right have same color as view
|
||||||
|
Component view;
|
||||||
|
float arc = getBorderArc( scrollpane );
|
||||||
|
if( arc > 0 && (view = getView( scrollpane )) != null ) {
|
||||||
|
float focusWidth = FlatUIUtils.getBorderFocusWidth( c );
|
||||||
|
|
||||||
|
g.setColor( view.getBackground() );
|
||||||
|
|
||||||
|
Object[] oldRenderingHints = FlatUIUtils.setRenderingHints( g );
|
||||||
|
FlatUIUtils.paintComponentBackground( (Graphics2D) g, 0, 0, c.getWidth(), c.getHeight(), focusWidth, arc );
|
||||||
|
FlatUIUtils.resetRenderingHints( g, oldRenderingHints );
|
||||||
|
}
|
||||||
|
|
||||||
paint( g, c );
|
paint( g, c );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void paint( Graphics g, JComponent c ) {
|
||||||
|
Border viewportBorder = scrollpane.getViewportBorder();
|
||||||
|
if( viewportBorder != null ) {
|
||||||
|
Rectangle r = scrollpane.getViewportBorderBounds();
|
||||||
|
int padding = getBorderLeftRightPadding( scrollpane );
|
||||||
|
JScrollBar vsb = scrollpane.getVerticalScrollBar();
|
||||||
|
if( padding > 0 &&
|
||||||
|
vsb != null && vsb.isVisible() &&
|
||||||
|
scrollpane.getLayout() instanceof FlatScrollPaneLayout &&
|
||||||
|
((FlatScrollPaneLayout)scrollpane.getLayout()).canIncreaseViewportWidth( scrollpane ) )
|
||||||
|
{
|
||||||
|
boolean ltr = scrollpane.getComponentOrientation().isLeftToRight();
|
||||||
|
int extraWidth = Math.min( padding, vsb.getWidth() );
|
||||||
|
viewportBorder.paintBorder( scrollpane, g, r.x - (ltr ? 0 : extraWidth), r.y, r.width + extraWidth, r.height );
|
||||||
|
} else
|
||||||
|
viewportBorder.paintBorder( scrollpane, g, r.x, r.y, r.width, r.height );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** @since 1.3 */
|
/** @since 1.3 */
|
||||||
public static boolean isPermanentFocusOwner( JScrollPane scrollPane ) {
|
public static boolean isPermanentFocusOwner( JScrollPane scrollPane ) {
|
||||||
JViewport viewport = scrollPane.getViewport();
|
Component view = getView( scrollPane );
|
||||||
Component view = (viewport != null) ? viewport.getView() : null;
|
|
||||||
if( view == null )
|
if( view == null )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@@ -428,6 +496,25 @@ public class FlatScrollPaneUI
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Component getView( JScrollPane scrollPane ) {
|
||||||
|
JViewport viewport = scrollPane.getViewport();
|
||||||
|
return (viewport != null) ? viewport.getView() : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static float getBorderArc( JScrollPane scrollPane ) {
|
||||||
|
Border border = scrollPane.getBorder();
|
||||||
|
return (border instanceof FlatScrollPaneBorder)
|
||||||
|
? UIScale.scale( (float) ((FlatScrollPaneBorder)border).getArc( scrollPane ) )
|
||||||
|
: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int getBorderLeftRightPadding( JScrollPane scrollPane ) {
|
||||||
|
Border border = scrollPane.getBorder();
|
||||||
|
return (border instanceof FlatScrollPaneBorder)
|
||||||
|
? ((FlatScrollPaneBorder)border).getLeftRightPadding( scrollPane )
|
||||||
|
: 0;
|
||||||
|
}
|
||||||
|
|
||||||
//---- class Handler ------------------------------------------------------
|
//---- class Handler ------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -450,13 +537,71 @@ public class FlatScrollPaneUI
|
|||||||
@Override
|
@Override
|
||||||
public void focusGained( FocusEvent e ) {
|
public void focusGained( FocusEvent e ) {
|
||||||
// necessary to update focus border
|
// necessary to update focus border
|
||||||
|
if( scrollpane.getBorder() instanceof FlatBorder )
|
||||||
scrollpane.repaint();
|
scrollpane.repaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void focusLost( FocusEvent e ) {
|
public void focusLost( FocusEvent e ) {
|
||||||
// necessary to update focus border
|
// necessary to update focus border
|
||||||
|
if( scrollpane.getBorder() instanceof FlatBorder )
|
||||||
scrollpane.repaint();
|
scrollpane.repaint();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---- class FlatScrollPaneLayout -----------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 3.3
|
||||||
|
*/
|
||||||
|
protected static class FlatScrollPaneLayout
|
||||||
|
extends ScrollPaneLayout.UIResource
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void layoutContainer( Container parent ) {
|
||||||
|
super.layoutContainer( parent );
|
||||||
|
|
||||||
|
JScrollPane scrollPane = (JScrollPane) parent;
|
||||||
|
int padding = getBorderLeftRightPadding( scrollPane );
|
||||||
|
if( padding > 0 && vsb != null && vsb.isVisible() ) {
|
||||||
|
// move vertical scrollbar to trailing edge
|
||||||
|
Insets insets = scrollPane.getInsets();
|
||||||
|
Rectangle r = vsb.getBounds();
|
||||||
|
int y = Math.max( r.y, insets.top + padding );
|
||||||
|
int y2 = Math.min( r.y + r.height, scrollPane.getHeight() - insets.bottom - padding );
|
||||||
|
boolean ltr = scrollPane.getComponentOrientation().isLeftToRight();
|
||||||
|
|
||||||
|
vsb.setBounds( r.x + (ltr ? padding : -padding), y, r.width, y2 - y );
|
||||||
|
|
||||||
|
// increase width of viewport, column header and horizontal scrollbar
|
||||||
|
if( canIncreaseViewportWidth( scrollPane ) ) {
|
||||||
|
int extraWidth = Math.min( padding, vsb.getWidth() );
|
||||||
|
resizeViewport( viewport, extraWidth, ltr );
|
||||||
|
resizeViewport( colHead, extraWidth, ltr );
|
||||||
|
resizeViewport( hsb, extraWidth, ltr );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean canIncreaseViewportWidth( JScrollPane scrollPane ) {
|
||||||
|
return scrollPane.getComponentOrientation().isLeftToRight()
|
||||||
|
? !isCornerVisible( upperRight ) && !isCornerVisible( lowerRight )
|
||||||
|
: !isCornerVisible( upperLeft ) && !isCornerVisible( lowerLeft );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isCornerVisible( Component corner ) {
|
||||||
|
return corner != null &&
|
||||||
|
corner.getWidth() > 0 &&
|
||||||
|
corner.getHeight() > 0 &&
|
||||||
|
corner.isVisible();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void resizeViewport( Component c, int extraWidth, boolean ltr ) {
|
||||||
|
if( c == null )
|
||||||
|
return;
|
||||||
|
|
||||||
|
Rectangle vr = c.getBounds();
|
||||||
|
c.setBounds( vr.x - (ltr ? 0 : extraWidth), vr.y, vr.width + extraWidth, vr.height );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,9 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf.ui;
|
package com.formdev.flatlaf.ui;
|
||||||
|
|
||||||
|
import java.awt.Canvas;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
|
import java.awt.Component;
|
||||||
import java.awt.Container;
|
import java.awt.Container;
|
||||||
import java.awt.Cursor;
|
import java.awt.Cursor;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
@@ -67,6 +69,8 @@ import com.formdev.flatlaf.util.UIScale;
|
|||||||
* <!-- FlatSplitPaneUI -->
|
* <!-- FlatSplitPaneUI -->
|
||||||
*
|
*
|
||||||
* @uiDefault Component.arrowType String chevron (default) or triangle
|
* @uiDefault Component.arrowType String chevron (default) or triangle
|
||||||
|
* @uiDefault SplitPaneDivider.hoverColor Color optional
|
||||||
|
* @uiDefault SplitPaneDivider.pressedColor Color optional
|
||||||
* @uiDefault SplitPaneDivider.oneTouchArrowColor Color
|
* @uiDefault SplitPaneDivider.oneTouchArrowColor Color
|
||||||
* @uiDefault SplitPaneDivider.oneTouchHoverArrowColor Color
|
* @uiDefault SplitPaneDivider.oneTouchHoverArrowColor Color
|
||||||
* @uiDefault SplitPaneDivider.oneTouchPressedArrowColor Color
|
* @uiDefault SplitPaneDivider.oneTouchPressedArrowColor Color
|
||||||
@@ -83,6 +87,7 @@ public class FlatSplitPaneUI
|
|||||||
implements StyleableUI
|
implements StyleableUI
|
||||||
{
|
{
|
||||||
@Styleable protected String arrowType;
|
@Styleable protected String arrowType;
|
||||||
|
/** @since 3.3 */ @Styleable protected Color draggingColor;
|
||||||
@Styleable protected Color oneTouchArrowColor;
|
@Styleable protected Color oneTouchArrowColor;
|
||||||
@Styleable protected Color oneTouchHoverArrowColor;
|
@Styleable protected Color oneTouchHoverArrowColor;
|
||||||
@Styleable protected Color oneTouchPressedArrowColor;
|
@Styleable protected Color oneTouchPressedArrowColor;
|
||||||
@@ -104,6 +109,8 @@ public class FlatSplitPaneUI
|
|||||||
protected void installDefaults() {
|
protected void installDefaults() {
|
||||||
arrowType = UIManager.getString( "Component.arrowType" );
|
arrowType = UIManager.getString( "Component.arrowType" );
|
||||||
|
|
||||||
|
draggingColor = UIManager.getColor( "SplitPaneDivider.draggingColor" );
|
||||||
|
|
||||||
// get one-touch colors before invoking super.installDefaults() because they are
|
// get one-touch colors before invoking super.installDefaults() because they are
|
||||||
// used in there on LaF switching
|
// used in there on LaF switching
|
||||||
oneTouchArrowColor = UIManager.getColor( "SplitPaneDivider.oneTouchArrowColor" );
|
oneTouchArrowColor = UIManager.getColor( "SplitPaneDivider.oneTouchArrowColor" );
|
||||||
@@ -117,6 +124,8 @@ public class FlatSplitPaneUI
|
|||||||
protected void uninstallDefaults() {
|
protected void uninstallDefaults() {
|
||||||
super.uninstallDefaults();
|
super.uninstallDefaults();
|
||||||
|
|
||||||
|
draggingColor = null;
|
||||||
|
|
||||||
oneTouchArrowColor = null;
|
oneTouchArrowColor = null;
|
||||||
oneTouchHoverArrowColor = null;
|
oneTouchHoverArrowColor = null;
|
||||||
oneTouchPressedArrowColor = null;
|
oneTouchPressedArrowColor = null;
|
||||||
@@ -183,12 +192,49 @@ public class FlatSplitPaneUI
|
|||||||
return FlatStylingSupport.getAnnotatedStyleableValue( this, key );
|
return FlatStylingSupport.getAnnotatedStyleableValue( this, key );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Component createDefaultNonContinuousLayoutDivider() {
|
||||||
|
// only used for non-continuous layout if left or right component is heavy weight
|
||||||
|
return new Canvas() {
|
||||||
|
@Override
|
||||||
|
public void paint( Graphics g ) {
|
||||||
|
if( !isContinuousLayout() && getLastDragLocation() != -1 )
|
||||||
|
paintDragDivider( g, 0 );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void finishedPaintingChildren( JSplitPane sp, Graphics g ) {
|
||||||
|
if( sp == splitPane && getLastDragLocation() != -1 && !isContinuousLayout() && !draggingHW )
|
||||||
|
paintDragDivider( g, getLastDragLocation() );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void paintDragDivider( Graphics g, int dividerLocation ) {
|
||||||
|
// divider bounds
|
||||||
|
boolean horizontal = (getOrientation() == JSplitPane.HORIZONTAL_SPLIT);
|
||||||
|
int x = horizontal ? dividerLocation : 0;
|
||||||
|
int y = !horizontal ? dividerLocation : 0;
|
||||||
|
int width = horizontal ? dividerSize : splitPane.getWidth();
|
||||||
|
int height = !horizontal ? dividerSize : splitPane.getHeight();
|
||||||
|
|
||||||
|
// paint background
|
||||||
|
g.setColor( FlatUIUtils.deriveColor( draggingColor, splitPane.getBackground() ) );
|
||||||
|
g.fillRect( x, y, width, height );
|
||||||
|
|
||||||
|
// paint divider style (e.g. grip)
|
||||||
|
if( divider instanceof FlatSplitPaneDivider )
|
||||||
|
((FlatSplitPaneDivider)divider).paintStyle( g, x, y, width, height );
|
||||||
|
}
|
||||||
|
|
||||||
//---- class FlatSplitPaneDivider -----------------------------------------
|
//---- class FlatSplitPaneDivider -----------------------------------------
|
||||||
|
|
||||||
protected class FlatSplitPaneDivider
|
protected class FlatSplitPaneDivider
|
||||||
extends BasicSplitPaneDivider
|
extends BasicSplitPaneDivider
|
||||||
{
|
{
|
||||||
@Styleable protected String style = UIManager.getString( "SplitPaneDivider.style" );
|
@Styleable protected String style = UIManager.getString( "SplitPaneDivider.style" );
|
||||||
|
/** @since 3.3 */ @Styleable protected Color hoverColor = UIManager.getColor( "SplitPaneDivider.hoverColor" );
|
||||||
|
/** @since 3.3 */ @Styleable protected Color pressedColor = UIManager.getColor( "SplitPaneDivider.pressedColor" );
|
||||||
@Styleable protected Color gripColor = UIManager.getColor( "SplitPaneDivider.gripColor" );
|
@Styleable protected Color gripColor = UIManager.getColor( "SplitPaneDivider.gripColor" );
|
||||||
@Styleable protected int gripDotCount = FlatUIUtils.getUIInt( "SplitPaneDivider.gripDotCount", 3 );
|
@Styleable protected int gripDotCount = FlatUIUtils.getUIInt( "SplitPaneDivider.gripDotCount", 3 );
|
||||||
@Styleable protected int gripDotSize = FlatUIUtils.getUIInt( "SplitPaneDivider.gripDotSize", 3 );
|
@Styleable protected int gripDotSize = FlatUIUtils.getUIInt( "SplitPaneDivider.gripDotSize", 3 );
|
||||||
@@ -251,15 +297,31 @@ public class FlatSplitPaneUI
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void paint( Graphics g ) {
|
public void paint( Graphics g ) {
|
||||||
|
// paint hover or pressed background
|
||||||
|
Color hoverOrPressedColor = (isContinuousLayout() && dragger != null)
|
||||||
|
? pressedColor
|
||||||
|
: (isMouseOver() && dragger == null
|
||||||
|
? hoverColor
|
||||||
|
: null);
|
||||||
|
if( hoverOrPressedColor != null ) {
|
||||||
|
g.setColor( FlatUIUtils.deriveColor( hoverOrPressedColor, splitPane.getBackground() ) );
|
||||||
|
g.fillRect( 0, 0, getWidth(), getHeight() );
|
||||||
|
}
|
||||||
|
|
||||||
super.paint( g );
|
super.paint( g );
|
||||||
|
|
||||||
|
paintStyle( g, 0, 0, getWidth(), getHeight() );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since 3.3 */
|
||||||
|
protected void paintStyle( Graphics g, int x, int y, int width, int height ) {
|
||||||
if( "plain".equals( style ) )
|
if( "plain".equals( style ) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Object[] oldRenderingHints = FlatUIUtils.setRenderingHints( g );
|
Object[] oldRenderingHints = FlatUIUtils.setRenderingHints( g );
|
||||||
|
|
||||||
g.setColor( gripColor );
|
g.setColor( gripColor );
|
||||||
paintGrip( g, 0, 0, getWidth(), getHeight() );
|
paintGrip( g, x, y, width, height );
|
||||||
|
|
||||||
FlatUIUtils.resetRenderingHints( g, oldRenderingHints );
|
FlatUIUtils.resetRenderingHints( g, oldRenderingHints );
|
||||||
}
|
}
|
||||||
@@ -286,6 +348,29 @@ public class FlatSplitPaneUI
|
|||||||
: location == (splitPane.getWidth() - getWidth() - insets.right);
|
: location == (splitPane.getWidth() - getWidth() - insets.right);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setMouseOver( boolean mouseOver ) {
|
||||||
|
super.setMouseOver( mouseOver );
|
||||||
|
repaintIfNecessary();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void prepareForDragging() {
|
||||||
|
super.prepareForDragging();
|
||||||
|
repaintIfNecessary();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void finishDraggingTo( int location ) {
|
||||||
|
super.finishDraggingTo( location );
|
||||||
|
repaintIfNecessary();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void repaintIfNecessary() {
|
||||||
|
if( hoverColor != null || pressedColor != null )
|
||||||
|
repaint();
|
||||||
|
}
|
||||||
|
|
||||||
//---- class FlatOneTouchButton ---------------------------------------
|
//---- class FlatOneTouchButton ---------------------------------------
|
||||||
|
|
||||||
protected class FlatOneTouchButton
|
protected class FlatOneTouchButton
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -18,6 +18,7 @@ package com.formdev.flatlaf.ui;
|
|||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
|
import java.awt.Container;
|
||||||
import java.awt.Cursor;
|
import java.awt.Cursor;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
@@ -28,16 +29,15 @@ import java.awt.event.MouseEvent;
|
|||||||
import java.awt.geom.Rectangle2D;
|
import java.awt.geom.Rectangle2D;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import javax.swing.CellRendererPane;
|
||||||
import javax.swing.Icon;
|
import javax.swing.Icon;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
import javax.swing.JTable;
|
import javax.swing.JTable;
|
||||||
import javax.swing.SwingConstants;
|
import javax.swing.SwingConstants;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import javax.swing.border.Border;
|
|
||||||
import javax.swing.event.MouseInputListener;
|
import javax.swing.event.MouseInputListener;
|
||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
import javax.swing.plaf.UIResource;
|
|
||||||
import javax.swing.plaf.basic.BasicTableHeaderUI;
|
import javax.swing.plaf.basic.BasicTableHeaderUI;
|
||||||
import javax.swing.table.JTableHeader;
|
import javax.swing.table.JTableHeader;
|
||||||
import javax.swing.table.TableCellRenderer;
|
import javax.swing.table.TableCellRenderer;
|
||||||
@@ -114,6 +114,11 @@ public class FlatTableHeaderUI
|
|||||||
public void installUI( JComponent c ) {
|
public void installUI( JComponent c ) {
|
||||||
super.installUI( c );
|
super.installUI( c );
|
||||||
|
|
||||||
|
// replace cell renderer pane
|
||||||
|
header.remove( rendererPane );
|
||||||
|
rendererPane = new FlatTableHeaderCellRendererPane();
|
||||||
|
header.add( rendererPane );
|
||||||
|
|
||||||
installStyle();
|
installStyle();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -265,16 +270,8 @@ public class FlatTableHeaderUI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// temporary use own default renderer
|
|
||||||
FlatTableCellHeaderRenderer tempRenderer = new FlatTableCellHeaderRenderer( header.getDefaultRenderer() );
|
|
||||||
header.setDefaultRenderer( tempRenderer );
|
|
||||||
|
|
||||||
// paint header
|
// paint header
|
||||||
super.paint( g, c );
|
super.paint( g, c );
|
||||||
|
|
||||||
// restore default renderer
|
|
||||||
tempRenderer.reset();
|
|
||||||
header.setDefaultRenderer( tempRenderer.delegate );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isSystemDefaultRenderer( Object headerRenderer ) {
|
private boolean isSystemDefaultRenderer( Object headerRenderer ) {
|
||||||
@@ -332,119 +329,129 @@ public class FlatTableHeaderUI
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//---- class FlatTableCellHeaderRenderer ----------------------------------
|
//---- class FlatTableHeaderCellRendererPane ------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A delegating header renderer that is only used to paint hover and pressed
|
* Cell renderer pane that is used to paint hover and pressed background/foreground
|
||||||
* background/foreground and to paint sort arrows at top, bottom or left position.
|
* and to paint sort arrows at top, bottom or left position.
|
||||||
*/
|
*/
|
||||||
private class FlatTableCellHeaderRenderer
|
private class FlatTableHeaderCellRendererPane
|
||||||
implements TableCellRenderer, Border, UIResource
|
extends CellRendererPane
|
||||||
{
|
{
|
||||||
private final TableCellRenderer delegate;
|
private final Icon ascendingSortIcon;
|
||||||
|
private final Icon descendingSortIcon;
|
||||||
|
|
||||||
private JLabel l;
|
public FlatTableHeaderCellRendererPane() {
|
||||||
private Color oldBackground;
|
ascendingSortIcon = UIManager.getIcon( "Table.ascendingSortIcon" );
|
||||||
private Color oldForeground;
|
descendingSortIcon = UIManager.getIcon( "Table.descendingSortIcon" );
|
||||||
private Boolean oldOpaque;
|
|
||||||
private int oldHorizontalTextPosition = -1;
|
|
||||||
private Border origBorder;
|
|
||||||
private Icon sortIcon;
|
|
||||||
|
|
||||||
FlatTableCellHeaderRenderer( TableCellRenderer delegate ) {
|
|
||||||
this.delegate = delegate;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Component getTableCellRendererComponent( JTable table, Object value, boolean isSelected,
|
public void paintComponent( Graphics g, Component c, Container p, int x, int y, int w, int h, boolean shouldValidate ) {
|
||||||
boolean hasFocus, int row, int column )
|
if( !(c instanceof JLabel) ) {
|
||||||
{
|
super.paintComponent( g, c, p, x, y, w, h, shouldValidate );
|
||||||
Component c = delegate.getTableCellRendererComponent( table, value, isSelected, hasFocus, row, column );
|
return;
|
||||||
if( !(c instanceof JLabel) )
|
}
|
||||||
return c;
|
|
||||||
|
|
||||||
l = (JLabel) c;
|
JLabel l = (JLabel) c;
|
||||||
|
Color oldBackground = null;
|
||||||
|
Color oldForeground = null;
|
||||||
|
boolean oldOpaque = false;
|
||||||
|
Icon oldIcon = null;
|
||||||
|
int oldHorizontalTextPosition = -1;
|
||||||
|
|
||||||
// hover and pressed background/foreground
|
// hover and pressed background/foreground
|
||||||
TableColumn draggedColumn = header.getDraggedColumn();
|
TableColumn draggedColumn = header.getDraggedColumn();
|
||||||
Color background = null;
|
Color background = null;
|
||||||
Color foreground = null;
|
Color foreground = null;
|
||||||
if( draggedColumn != null && header.getTable().convertColumnIndexToView( draggedColumn.getModelIndex() ) == column ) {
|
if( draggedColumn != null &&
|
||||||
|
header.getTable().convertColumnIndexToView( draggedColumn.getModelIndex() )
|
||||||
|
== getColumn( x - header.getDraggedDistance(), w ) )
|
||||||
|
{
|
||||||
background = pressedBackground;
|
background = pressedBackground;
|
||||||
foreground = pressedForeground;
|
foreground = pressedForeground;
|
||||||
} else if( getRolloverColumn() == column ) {
|
} else if( getRolloverColumn() >= 0 && getRolloverColumn() == getColumn( x, w ) ) {
|
||||||
background = hoverBackground;
|
background = hoverBackground;
|
||||||
foreground = hoverForeground;
|
foreground = hoverForeground;
|
||||||
}
|
}
|
||||||
if( background != null ) {
|
if( background != null ) {
|
||||||
if( oldBackground == null )
|
|
||||||
oldBackground = l.getBackground();
|
oldBackground = l.getBackground();
|
||||||
if( oldOpaque == null )
|
|
||||||
oldOpaque = l.isOpaque();
|
oldOpaque = l.isOpaque();
|
||||||
l.setBackground( FlatUIUtils.deriveColor( background, header.getBackground() ) );
|
l.setBackground( FlatUIUtils.deriveColor( background, header.getBackground() ) );
|
||||||
l.setOpaque( true );
|
l.setOpaque( true );
|
||||||
}
|
}
|
||||||
if( foreground != null ) {
|
if( foreground != null ) {
|
||||||
if( oldForeground == null )
|
|
||||||
oldForeground = l.getForeground();
|
oldForeground = l.getForeground();
|
||||||
l.setForeground( FlatUIUtils.deriveColor( foreground, header.getForeground() ) );
|
l.setForeground( FlatUIUtils.deriveColor( foreground, header.getForeground() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
// sort icon
|
// sort icon position
|
||||||
|
Icon icon = l.getIcon();
|
||||||
|
boolean isSortIcon = (icon != null && (icon == ascendingSortIcon || icon == descendingSortIcon));
|
||||||
|
if( isSortIcon ) {
|
||||||
if( sortIconPosition == SwingConstants.LEFT ) {
|
if( sortIconPosition == SwingConstants.LEFT ) {
|
||||||
// left
|
// left
|
||||||
if( oldHorizontalTextPosition < 0 )
|
|
||||||
oldHorizontalTextPosition = l.getHorizontalTextPosition();
|
oldHorizontalTextPosition = l.getHorizontalTextPosition();
|
||||||
l.setHorizontalTextPosition( SwingConstants.RIGHT );
|
l.setHorizontalTextPosition( SwingConstants.RIGHT );
|
||||||
} else if( sortIconPosition == SwingConstants.TOP || sortIconPosition == SwingConstants.BOTTOM ) {
|
} else if( sortIconPosition == SwingConstants.TOP || sortIconPosition == SwingConstants.BOTTOM ) {
|
||||||
// top or bottom
|
// top or bottom
|
||||||
sortIcon = l.getIcon();
|
oldIcon = icon;
|
||||||
origBorder = l.getBorder();
|
|
||||||
l.setIcon( null );
|
l.setIcon( null );
|
||||||
l.setBorder( this );
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return l;
|
// paint renderer component
|
||||||
|
super.paintComponent( g, c, p, x, y, w, h, shouldValidate );
|
||||||
|
|
||||||
|
// paint top or bottom sort icon
|
||||||
|
if( isSortIcon && (sortIconPosition == SwingConstants.TOP || sortIconPosition == SwingConstants.BOTTOM) ) {
|
||||||
|
int xi = x + ((w - icon.getIconWidth()) / 2);
|
||||||
|
int yi = (sortIconPosition == SwingConstants.TOP)
|
||||||
|
? y + UIScale.scale( 1 )
|
||||||
|
: y + height - icon.getIconHeight()
|
||||||
|
- 1 // for gap
|
||||||
|
- (int) (1 * UIScale.getUserScaleFactor()); // for bottom border
|
||||||
|
icon.paintIcon( c, g, xi, yi );
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset() {
|
// restore modified renderer component properties
|
||||||
if( l == null )
|
if( background != null ) {
|
||||||
return;
|
|
||||||
|
|
||||||
if( oldBackground != null )
|
|
||||||
l.setBackground( oldBackground );
|
l.setBackground( oldBackground );
|
||||||
if( oldForeground != null )
|
|
||||||
l.setForeground( oldForeground );
|
|
||||||
if( oldOpaque != null )
|
|
||||||
l.setOpaque( oldOpaque );
|
l.setOpaque( oldOpaque );
|
||||||
|
}
|
||||||
|
if( foreground != null )
|
||||||
|
l.setForeground( oldForeground );
|
||||||
|
if( oldIcon != null )
|
||||||
|
l.setIcon( oldIcon );
|
||||||
if( oldHorizontalTextPosition >= 0 )
|
if( oldHorizontalTextPosition >= 0 )
|
||||||
l.setHorizontalTextPosition( oldHorizontalTextPosition );
|
l.setHorizontalTextPosition( oldHorizontalTextPosition );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
|
* Get column index for given coordinates.
|
||||||
if( origBorder != null )
|
*/
|
||||||
origBorder.paintBorder( c, g, x, y, width, height );
|
private int getColumn( int x, int width ) {
|
||||||
|
TableColumnModel columnModel = header.getColumnModel();
|
||||||
|
int columnCount = columnModel.getColumnCount();
|
||||||
|
boolean ltr = header.getComponentOrientation().isLeftToRight();
|
||||||
|
int cx = ltr ? 0 : getWidthInRightToLef();
|
||||||
|
|
||||||
if( sortIcon != null ) {
|
for( int i = 0; i < columnCount; i++ ) {
|
||||||
int xi = x + ((width - sortIcon.getIconWidth()) / 2);
|
int cw = columnModel.getColumn( i ).getWidth();
|
||||||
int yi = (sortIconPosition == SwingConstants.TOP)
|
if( x == cx - (ltr ? 0 : cw) && width == cw )
|
||||||
? y + UIScale.scale( 1 )
|
return i;
|
||||||
: y + height - sortIcon.getIconHeight()
|
|
||||||
- 1 // for gap
|
cx += ltr ? cw : -cw;
|
||||||
- (int) (1 * UIScale.getUserScaleFactor()); // for bottom border
|
|
||||||
sortIcon.paintIcon( c, g, xi, yi );
|
|
||||||
}
|
}
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
// similar to JTableHeader.getWidthInRightToLeft()
|
||||||
public Insets getBorderInsets( Component c ) {
|
private int getWidthInRightToLef() {
|
||||||
return (origBorder != null) ? origBorder.getBorderInsets( c ) : new Insets( 0, 0, 0, 0 );
|
JTable table = header.getTable();
|
||||||
}
|
return (table != null && table.getAutoResizeMode() != JTable.AUTO_RESIZE_OFF)
|
||||||
|
? table.getWidth()
|
||||||
@Override
|
: header.getWidth();
|
||||||
public boolean isBorderOpaque() {
|
|
||||||
return (origBorder != null) ? origBorder.isBorderOpaque() : false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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.Component;
|
||||||
import java.awt.Container;
|
import java.awt.Container;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.EventQueue;
|
import java.awt.EventQueue;
|
||||||
@@ -26,18 +27,25 @@ import java.awt.Insets;
|
|||||||
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.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
import javax.swing.JScrollPane;
|
import javax.swing.JScrollPane;
|
||||||
|
import javax.swing.JTable;
|
||||||
import javax.swing.JViewport;
|
import javax.swing.JViewport;
|
||||||
import javax.swing.LookAndFeel;
|
import javax.swing.LookAndFeel;
|
||||||
|
import javax.swing.SwingConstants;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
|
import javax.swing.plaf.UIResource;
|
||||||
import javax.swing.plaf.basic.BasicTableUI;
|
import javax.swing.plaf.basic.BasicTableUI;
|
||||||
|
import javax.swing.table.DefaultTableCellRenderer;
|
||||||
import javax.swing.table.JTableHeader;
|
import javax.swing.table.JTableHeader;
|
||||||
|
import javax.swing.table.TableCellRenderer;
|
||||||
import com.formdev.flatlaf.FlatClientProperties;
|
import com.formdev.flatlaf.FlatClientProperties;
|
||||||
|
import com.formdev.flatlaf.icons.FlatCheckBoxIcon;
|
||||||
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
||||||
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
|
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
|
||||||
import com.formdev.flatlaf.util.Graphics2DProxy;
|
import com.formdev.flatlaf.util.Graphics2DProxy;
|
||||||
@@ -116,6 +124,7 @@ public class FlatTableUI
|
|||||||
private boolean oldShowHorizontalLines;
|
private boolean oldShowHorizontalLines;
|
||||||
private boolean oldShowVerticalLines;
|
private boolean oldShowVerticalLines;
|
||||||
private Dimension oldIntercellSpacing;
|
private Dimension oldIntercellSpacing;
|
||||||
|
private TableCellRenderer oldBooleanRenderer;
|
||||||
|
|
||||||
private PropertyChangeListener propertyChangeListener;
|
private PropertyChangeListener propertyChangeListener;
|
||||||
private Map<String, Object> oldStyleValues;
|
private Map<String, Object> oldStyleValues;
|
||||||
@@ -151,19 +160,35 @@ public class FlatTableUI
|
|||||||
if( rowHeight > 0 )
|
if( rowHeight > 0 )
|
||||||
LookAndFeel.installProperty( table, "rowHeight", UIScale.scale( rowHeight ) );
|
LookAndFeel.installProperty( table, "rowHeight", UIScale.scale( rowHeight ) );
|
||||||
|
|
||||||
if( !showHorizontalLines ) {
|
FlatTablePropertyWatcher watcher = FlatTablePropertyWatcher.get( table );
|
||||||
|
if( watcher != null )
|
||||||
|
watcher.enabled = false;
|
||||||
|
|
||||||
|
if( !showHorizontalLines && (watcher == null || !watcher.showHorizontalLinesChanged) ) {
|
||||||
oldShowHorizontalLines = table.getShowHorizontalLines();
|
oldShowHorizontalLines = table.getShowHorizontalLines();
|
||||||
table.setShowHorizontalLines( false );
|
table.setShowHorizontalLines( false );
|
||||||
}
|
}
|
||||||
if( !showVerticalLines ) {
|
if( !showVerticalLines && (watcher == null || !watcher.showVerticalLinesChanged) ) {
|
||||||
oldShowVerticalLines = table.getShowVerticalLines();
|
oldShowVerticalLines = table.getShowVerticalLines();
|
||||||
table.setShowVerticalLines( false );
|
table.setShowVerticalLines( false );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( intercellSpacing != null ) {
|
if( intercellSpacing != null && (watcher == null || !watcher.intercellSpacingChanged) ) {
|
||||||
oldIntercellSpacing = table.getIntercellSpacing();
|
oldIntercellSpacing = table.getIntercellSpacing();
|
||||||
table.setIntercellSpacing( intercellSpacing );
|
table.setIntercellSpacing( intercellSpacing );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( watcher != null )
|
||||||
|
watcher.enabled = true;
|
||||||
|
else
|
||||||
|
table.addPropertyChangeListener( new FlatTablePropertyWatcher() );
|
||||||
|
|
||||||
|
// install boolean renderer
|
||||||
|
oldBooleanRenderer = table.getDefaultRenderer( Boolean.class );
|
||||||
|
if( oldBooleanRenderer instanceof UIResource )
|
||||||
|
table.setDefaultRenderer( Boolean.class, new FlatBooleanRenderer() );
|
||||||
|
else
|
||||||
|
oldBooleanRenderer = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -177,15 +202,36 @@ public class FlatTableUI
|
|||||||
|
|
||||||
oldStyleValues = null;
|
oldStyleValues = null;
|
||||||
|
|
||||||
|
FlatTablePropertyWatcher watcher = FlatTablePropertyWatcher.get( table );
|
||||||
|
if( watcher != null )
|
||||||
|
watcher.enabled = false;
|
||||||
|
|
||||||
// restore old show horizontal/vertical lines (if not modified)
|
// restore old show horizontal/vertical lines (if not modified)
|
||||||
if( !showHorizontalLines && oldShowHorizontalLines && !table.getShowHorizontalLines() )
|
if( !showHorizontalLines && oldShowHorizontalLines && !table.getShowHorizontalLines() &&
|
||||||
|
(watcher == null || !watcher.showHorizontalLinesChanged) )
|
||||||
table.setShowHorizontalLines( true );
|
table.setShowHorizontalLines( true );
|
||||||
if( !showVerticalLines && oldShowVerticalLines && !table.getShowVerticalLines() )
|
if( !showVerticalLines && oldShowVerticalLines && !table.getShowVerticalLines() &&
|
||||||
|
(watcher == null || !watcher.showVerticalLinesChanged) )
|
||||||
table.setShowVerticalLines( true );
|
table.setShowVerticalLines( true );
|
||||||
|
|
||||||
// restore old intercell spacing (if not modified)
|
// restore old intercell spacing (if not modified)
|
||||||
if( intercellSpacing != null && table.getIntercellSpacing().equals( intercellSpacing ) )
|
if( intercellSpacing != null && table.getIntercellSpacing().equals( intercellSpacing ) &&
|
||||||
|
(watcher == null || !watcher.intercellSpacingChanged) )
|
||||||
table.setIntercellSpacing( oldIntercellSpacing );
|
table.setIntercellSpacing( oldIntercellSpacing );
|
||||||
|
|
||||||
|
if( watcher != null )
|
||||||
|
watcher.enabled = true;
|
||||||
|
|
||||||
|
// uninstall boolean renderer
|
||||||
|
if( table.getDefaultRenderer( Boolean.class ) instanceof FlatBooleanRenderer ) {
|
||||||
|
if( oldBooleanRenderer instanceof Component ) {
|
||||||
|
// because the old renderer component was not attached to any component hierarchy,
|
||||||
|
// its UI was not yet updated, and it is necessary to do it here
|
||||||
|
SwingUtilities.updateComponentTreeUI( (Component) oldBooleanRenderer );
|
||||||
|
}
|
||||||
|
table.setDefaultRenderer( Boolean.class, oldBooleanRenderer );
|
||||||
|
}
|
||||||
|
oldBooleanRenderer = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -467,4 +513,70 @@ public class FlatTableUI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---- class FlatTablePropertyWatcher -------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listener that watches for change of some table properties from application code.
|
||||||
|
* This information is used in {@link FlatTableUI#installDefaults()} and
|
||||||
|
* {@link FlatTableUI#uninstallDefaults()} to decide whether FlatLaf modifies those properties.
|
||||||
|
* If they are modified in application code, FlatLaf no longer changes them.
|
||||||
|
*
|
||||||
|
* The listener is added once for each table, but never removed.
|
||||||
|
* So switching Laf/theme reuses existing listener.
|
||||||
|
*/
|
||||||
|
private static class FlatTablePropertyWatcher
|
||||||
|
implements PropertyChangeListener
|
||||||
|
{
|
||||||
|
boolean enabled = true;
|
||||||
|
boolean showHorizontalLinesChanged;
|
||||||
|
boolean showVerticalLinesChanged;
|
||||||
|
boolean intercellSpacingChanged;
|
||||||
|
|
||||||
|
static FlatTablePropertyWatcher get( JTable table ) {
|
||||||
|
for( PropertyChangeListener l : table.getPropertyChangeListeners() ) {
|
||||||
|
if( l instanceof FlatTablePropertyWatcher )
|
||||||
|
return (FlatTablePropertyWatcher) l;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---- interface PropertyChangeListener ----
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void propertyChange( PropertyChangeEvent e ) {
|
||||||
|
if( !enabled )
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch( e.getPropertyName() ) {
|
||||||
|
case "showHorizontalLines": showHorizontalLinesChanged = true; break;
|
||||||
|
case "showVerticalLines": showVerticalLinesChanged = true; break;
|
||||||
|
case "rowMargin": intercellSpacingChanged = true; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//---- class FlatBooleanRenderer ------------------------------------------
|
||||||
|
|
||||||
|
private static class FlatBooleanRenderer
|
||||||
|
extends DefaultTableCellRenderer
|
||||||
|
implements UIResource
|
||||||
|
{
|
||||||
|
private boolean selected;
|
||||||
|
|
||||||
|
FlatBooleanRenderer() {
|
||||||
|
setHorizontalAlignment( SwingConstants.CENTER );
|
||||||
|
setIcon( new FlatCheckBoxIcon() {
|
||||||
|
@Override
|
||||||
|
protected boolean isSelected( Component c ) {
|
||||||
|
return selected;
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void setValue( Object value ) {
|
||||||
|
selected = (value != null && (Boolean) value);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -608,6 +608,10 @@ public class FlatTitlePane
|
|||||||
doLayout();
|
doLayout();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void menuBarInvalidate() {
|
||||||
|
menuBarPlaceholder.invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void paint( Graphics g ) {
|
public void paint( Graphics g ) {
|
||||||
super.paint( g );
|
super.paint( g );
|
||||||
@@ -835,10 +839,6 @@ public class FlatTitlePane
|
|||||||
window.dispatchEvent( new WindowEvent( window, WindowEvent.WINDOW_CLOSING ) );
|
window.dispatchEvent( new WindowEvent( window, WindowEvent.WINDOW_CLOSING ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean hasJBRCustomDecoration() {
|
|
||||||
return window != null && JBRCustomDecorations.hasCustomDecoration( window );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether windows uses native window border and has custom decorations enabled.
|
* Returns whether windows uses native window border and has custom decorations enabled.
|
||||||
*/
|
*/
|
||||||
@@ -896,9 +896,6 @@ public class FlatTitlePane
|
|||||||
iconBounds.width += iconInsets.right;
|
iconBounds.width += iconInsets.right;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( hasJBRCustomDecoration() )
|
|
||||||
hitTestSpots.add( iconBounds );
|
|
||||||
else
|
|
||||||
appIconBounds = iconBounds;
|
appIconBounds = iconBounds;
|
||||||
} else if( showIconBesideTitle && titleLabel.getIcon() != null && titleLabel.getUI() instanceof FlatTitleLabelUI ) {
|
} else if( showIconBesideTitle && titleLabel.getIcon() != null && titleLabel.getUI() instanceof FlatTitleLabelUI ) {
|
||||||
FlatTitleLabelUI ui = (FlatTitleLabelUI) titleLabel.getUI();
|
FlatTitleLabelUI ui = (FlatTitleLabelUI) titleLabel.getUI();
|
||||||
@@ -927,9 +924,6 @@ public class FlatTitlePane
|
|||||||
iconR.width += 2;
|
iconR.width += 2;
|
||||||
iconR.height += 2;
|
iconR.height += 2;
|
||||||
|
|
||||||
if( hasJBRCustomDecoration() )
|
|
||||||
hitTestSpots.add( iconR );
|
|
||||||
else
|
|
||||||
appIconBounds = iconR;
|
appIconBounds = iconR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1270,7 +1264,7 @@ debug*/
|
|||||||
public void mouseClicked( MouseEvent e ) {
|
public void mouseClicked( MouseEvent e ) {
|
||||||
// on Linux, when using native library, the mouse clicked event
|
// on Linux, when using native library, the mouse clicked event
|
||||||
// is usually not sent and maximize/restore is done in mouse pressed event
|
// is usually not sent and maximize/restore is done in mouse pressed event
|
||||||
// this check is here for the case that a mouse clicked event comes thru for some reason
|
// this check is here for the case that a mouse clicked event comes through for some reason
|
||||||
if( linuxNativeMove && SystemInfo.isLinux && FlatNativeLinuxLibrary.isWMUtilsSupported( window ) ) {
|
if( linuxNativeMove && SystemInfo.isLinux && FlatNativeLinuxLibrary.isWMUtilsSupported( window ) ) {
|
||||||
// see comment in mousePressed()
|
// see comment in mousePressed()
|
||||||
if( lastSingleClickWhen != 0 && (e.getWhen() - lastSingleClickWhen) <= getMultiClickInterval() ) {
|
if( lastSingleClickWhen != 0 && (e.getWhen() - lastSingleClickWhen) <= getMultiClickInterval() ) {
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ package com.formdev.flatlaf.ui;
|
|||||||
|
|
||||||
import static com.formdev.flatlaf.util.UIScale.scale;
|
import static com.formdev.flatlaf.util.UIScale.scale;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
|
import java.awt.Container;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
@@ -173,6 +174,12 @@ public class FlatToolBarSeparatorUI
|
|||||||
if( size != null )
|
if( size != null )
|
||||||
return scale( size );
|
return scale( size );
|
||||||
|
|
||||||
|
// get separator width
|
||||||
|
int separatorWidth = this.separatorWidth;
|
||||||
|
FlatToolBarUI toolBarUI = getToolBarUI( c );
|
||||||
|
if( toolBarUI != null && toolBarUI.separatorWidth != null )
|
||||||
|
separatorWidth = toolBarUI.separatorWidth;
|
||||||
|
|
||||||
// make sure that gap on left and right side of line have same size
|
// make sure that gap on left and right side of line have same size
|
||||||
int sepWidth = (scale( (separatorWidth - LINE_WIDTH) / 2 ) * 2) + scale( LINE_WIDTH );
|
int sepWidth = (scale( (separatorWidth - LINE_WIDTH) / 2 ) * 2) + scale( LINE_WIDTH );
|
||||||
|
|
||||||
@@ -196,6 +203,12 @@ public class FlatToolBarSeparatorUI
|
|||||||
float lineWidth = scale( 1f );
|
float lineWidth = scale( 1f );
|
||||||
float offset = scale( 2f );
|
float offset = scale( 2f );
|
||||||
|
|
||||||
|
// get separator color
|
||||||
|
Color separatorColor = this.separatorColor;
|
||||||
|
FlatToolBarUI toolBarUI = getToolBarUI( c );
|
||||||
|
if( toolBarUI != null && toolBarUI.separatorColor != null )
|
||||||
|
separatorColor = toolBarUI.separatorColor;
|
||||||
|
|
||||||
Object[] oldRenderingHints = FlatUIUtils.setRenderingHints( g );
|
Object[] oldRenderingHints = FlatUIUtils.setRenderingHints( g );
|
||||||
g.setColor( separatorColor );
|
g.setColor( separatorColor );
|
||||||
|
|
||||||
@@ -210,4 +223,11 @@ public class FlatToolBarSeparatorUI
|
|||||||
private boolean isVertical( JComponent c ) {
|
private boolean isVertical( JComponent c ) {
|
||||||
return ((JToolBar.Separator)c).getOrientation() == SwingConstants.VERTICAL;
|
return ((JToolBar.Separator)c).getOrientation() == SwingConstants.VERTICAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private FlatToolBarUI getToolBarUI( JComponent c ) {
|
||||||
|
Container parent = c.getParent();
|
||||||
|
return (parent instanceof JToolBar && ((JToolBar)parent).getUI() instanceof FlatToolBarUI)
|
||||||
|
? (FlatToolBarUI) ((JToolBar)parent).getUI()
|
||||||
|
: null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -93,6 +93,10 @@ public class FlatToolBarUI
|
|||||||
@Styleable protected Insets borderMargins;
|
@Styleable protected Insets borderMargins;
|
||||||
@Styleable protected Color gripColor;
|
@Styleable protected Color gripColor;
|
||||||
|
|
||||||
|
// for FlatToolBarSeparatorUI
|
||||||
|
/** @since 3.3 */ @Styleable protected Integer separatorWidth;
|
||||||
|
/** @since 3.3 */ @Styleable protected Color separatorColor;
|
||||||
|
|
||||||
private FocusTraversalPolicy focusTraversalPolicy;
|
private FocusTraversalPolicy focusTraversalPolicy;
|
||||||
private Boolean oldFloatable;
|
private Boolean oldFloatable;
|
||||||
private Map<String, Object> oldStyleValues;
|
private Map<String, Object> oldStyleValues;
|
||||||
|
|||||||
@@ -299,16 +299,11 @@ public class FlatUIUtils
|
|||||||
if( c == null )
|
if( c == null )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// check whether used in cell editor (check 3 levels up)
|
// check whether used as table cell editor
|
||||||
Component c2 = c;
|
Container parent = c.getParent();
|
||||||
for( int i = 0; i <= 2 && c2 != null; i++ ) {
|
if( parent instanceof JTable && ((JTable)parent).getEditorComponent() == c )
|
||||||
Container parent = c2.getParent();
|
|
||||||
if( parent instanceof JTable && ((JTable)parent).getEditorComponent() == c2 )
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
c2 = parent;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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()
|
||||||
@@ -734,7 +729,7 @@ public class FlatUIUtils
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a (rounded) rectangle used to paint components (border, background, etc).
|
* Creates a (rounded) rectangle used to paint components (border, background, etc.).
|
||||||
* The given arc diameter is limited to min(width,height).
|
* The given arc diameter is limited to min(width,height).
|
||||||
*/
|
*/
|
||||||
public static Shape createComponentRectangle( float x, float y, float w, float h, float arc ) {
|
public static Shape createComponentRectangle( float x, float y, float w, float h, float arc ) {
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ package com.formdev.flatlaf.ui;
|
|||||||
|
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
import javax.swing.JViewport;
|
import javax.swing.JViewport;
|
||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
@@ -48,14 +47,9 @@ public class FlatViewportUI
|
|||||||
|
|
||||||
Component view = ((JViewport)c).getView();
|
Component view = ((JViewport)c).getView();
|
||||||
if( view instanceof JComponent ) {
|
if( view instanceof JComponent ) {
|
||||||
try {
|
ComponentUI ui = JavaCompatibility2.getUI( (JComponent) view );
|
||||||
Method m = view.getClass().getMethod( "getUI" );
|
|
||||||
Object ui = m.invoke( view );
|
|
||||||
if( ui instanceof ViewportPainter )
|
if( ui instanceof ViewportPainter )
|
||||||
((ViewportPainter)ui).paintViewport( g, (JComponent) view, (JViewport) c );
|
((ViewportPainter)ui).paintViewport( g, (JComponent) view, (JViewport) c );
|
||||||
} catch( Exception ex ) {
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,306 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2020 FormDev Software GmbH
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* https://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.formdev.flatlaf.ui;
|
|
||||||
|
|
||||||
import java.awt.Color;
|
|
||||||
import java.awt.Component;
|
|
||||||
import java.awt.Container;
|
|
||||||
import java.awt.EventQueue;
|
|
||||||
import java.awt.Graphics;
|
|
||||||
import java.awt.Graphics2D;
|
|
||||||
import java.awt.Rectangle;
|
|
||||||
import java.awt.Toolkit;
|
|
||||||
import java.awt.Window;
|
|
||||||
import java.awt.event.HierarchyEvent;
|
|
||||||
import java.awt.event.HierarchyListener;
|
|
||||||
import java.beans.PropertyChangeListener;
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import javax.swing.JRootPane;
|
|
||||||
import javax.swing.SwingUtilities;
|
|
||||||
import javax.swing.UIManager;
|
|
||||||
import javax.swing.plaf.BorderUIResource;
|
|
||||||
import com.formdev.flatlaf.FlatLaf;
|
|
||||||
import com.formdev.flatlaf.util.LoggingFacade;
|
|
||||||
import com.formdev.flatlaf.util.HiDPIUtils;
|
|
||||||
import com.formdev.flatlaf.util.SystemInfo;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Support for custom window decorations provided by JetBrains Runtime (based on OpenJDK).
|
|
||||||
* Requires that the application runs on Windows 10 in a JetBrains Runtime 11 or later.
|
|
||||||
* <ul>
|
|
||||||
* <li><a href="https://confluence.jetbrains.com/display/JBR/JetBrains+Runtime">https://confluence.jetbrains.com/display/JBR/JetBrains+Runtime</a></li>
|
|
||||||
* <li><a href="https://github.com/JetBrains/JetBrainsRuntime">https://github.com/JetBrains/JetBrainsRuntime</a></li>
|
|
||||||
* </ul>
|
|
||||||
*
|
|
||||||
* @author Karl Tauber
|
|
||||||
*/
|
|
||||||
public class JBRCustomDecorations
|
|
||||||
{
|
|
||||||
private static Boolean supported;
|
|
||||||
private static Method Window_hasCustomDecoration;
|
|
||||||
private static Method Window_setHasCustomDecoration;
|
|
||||||
private static Method WWindowPeer_setCustomDecorationTitleBarHeight;
|
|
||||||
private static Method WWindowPeer_setCustomDecorationHitTestSpots;
|
|
||||||
private static Method AWTAccessor_getComponentAccessor;
|
|
||||||
private static Method AWTAccessor_ComponentAccessor_getPeer;
|
|
||||||
|
|
||||||
public static boolean isSupported() {
|
|
||||||
initialize();
|
|
||||||
return supported;
|
|
||||||
}
|
|
||||||
|
|
||||||
static Object install( JRootPane rootPane ) {
|
|
||||||
if( !isSupported() )
|
|
||||||
return null;
|
|
||||||
|
|
||||||
// check whether root pane already has a parent, which is the case when switching LaF
|
|
||||||
Container parent = rootPane.getParent();
|
|
||||||
if( parent != null ) {
|
|
||||||
if( parent instanceof Window )
|
|
||||||
FlatNativeWindowBorder.install( (Window) parent );
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use hierarchy listener to wait until the root pane is added to a window.
|
|
||||||
// Enabling JBR decorations must be done very early, probably before
|
|
||||||
// window becomes displayable (window.isDisplayable()). Tried also using
|
|
||||||
// "ancestor" property change event on root pane, but this is invoked too late.
|
|
||||||
HierarchyListener addListener = new HierarchyListener() {
|
|
||||||
@Override
|
|
||||||
public void hierarchyChanged( HierarchyEvent e ) {
|
|
||||||
if( e.getChanged() != rootPane || (e.getChangeFlags() & HierarchyEvent.PARENT_CHANGED) == 0 )
|
|
||||||
return;
|
|
||||||
|
|
||||||
Container parent = e.getChangedParent();
|
|
||||||
if( parent instanceof Window )
|
|
||||||
FlatNativeWindowBorder.install( (Window) parent );
|
|
||||||
|
|
||||||
// remove listener since it is actually not possible to uninstall JBR decorations
|
|
||||||
// use invokeLater to remove listener to avoid that listener
|
|
||||||
// is removed while listener queue is processed
|
|
||||||
EventQueue.invokeLater( () -> {
|
|
||||||
rootPane.removeHierarchyListener( this );
|
|
||||||
} );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
rootPane.addHierarchyListener( addListener );
|
|
||||||
return addListener;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void uninstall( JRootPane rootPane, Object data ) {
|
|
||||||
// remove listener (if not yet done)
|
|
||||||
if( data instanceof HierarchyListener )
|
|
||||||
rootPane.removeHierarchyListener( (HierarchyListener) data );
|
|
||||||
|
|
||||||
// since it is actually not possible to uninstall JBR decorations,
|
|
||||||
// simply reduce titleBarHeight so that it is still possible to resize window
|
|
||||||
// and remove hitTestSpots
|
|
||||||
Container parent = rootPane.getParent();
|
|
||||||
if( parent instanceof Window )
|
|
||||||
setHasCustomDecoration( (Window) parent, false );
|
|
||||||
}
|
|
||||||
|
|
||||||
static boolean hasCustomDecoration( Window window ) {
|
|
||||||
if( !isSupported() )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
try {
|
|
||||||
return (Boolean) Window_hasCustomDecoration.invoke( window );
|
|
||||||
} catch( Exception ex ) {
|
|
||||||
LoggingFacade.INSTANCE.logSevere( null, ex );
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void setHasCustomDecoration( Window window, boolean hasCustomDecoration ) {
|
|
||||||
if( !isSupported() )
|
|
||||||
return;
|
|
||||||
|
|
||||||
try {
|
|
||||||
if( hasCustomDecoration )
|
|
||||||
Window_setHasCustomDecoration.invoke( window );
|
|
||||||
else
|
|
||||||
setTitleBarHeightAndHitTestSpots( window, 4, Collections.emptyList() );
|
|
||||||
} catch( Exception ex ) {
|
|
||||||
LoggingFacade.INSTANCE.logSevere( null, ex );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void setTitleBarHeightAndHitTestSpots( Window window, int titleBarHeight, List<Rectangle> hitTestSpots ) {
|
|
||||||
if( !isSupported() )
|
|
||||||
return;
|
|
||||||
|
|
||||||
try {
|
|
||||||
Object compAccessor = AWTAccessor_getComponentAccessor.invoke( null );
|
|
||||||
Object peer = AWTAccessor_ComponentAccessor_getPeer.invoke( compAccessor, window );
|
|
||||||
WWindowPeer_setCustomDecorationTitleBarHeight.invoke( peer, titleBarHeight );
|
|
||||||
WWindowPeer_setCustomDecorationHitTestSpots.invoke( peer, hitTestSpots );
|
|
||||||
} catch( Exception ex ) {
|
|
||||||
LoggingFacade.INSTANCE.logSevere( null, ex );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void initialize() {
|
|
||||||
if( supported != null )
|
|
||||||
return;
|
|
||||||
supported = false;
|
|
||||||
|
|
||||||
// requires JetBrains Runtime 11 and Windows 10
|
|
||||||
if( !SystemInfo.isJetBrainsJVM_11_orLater || !SystemInfo.isWindows_10_orLater )
|
|
||||||
return;
|
|
||||||
|
|
||||||
try {
|
|
||||||
Class<?> awtAcessorClass = Class.forName( "sun.awt.AWTAccessor" );
|
|
||||||
Class<?> compAccessorClass = Class.forName( "sun.awt.AWTAccessor$ComponentAccessor" );
|
|
||||||
AWTAccessor_getComponentAccessor = awtAcessorClass.getDeclaredMethod( "getComponentAccessor" );
|
|
||||||
AWTAccessor_ComponentAccessor_getPeer = compAccessorClass.getDeclaredMethod( "getPeer", Component.class );
|
|
||||||
|
|
||||||
Class<?> peerClass = Class.forName( "sun.awt.windows.WWindowPeer" );
|
|
||||||
WWindowPeer_setCustomDecorationTitleBarHeight = peerClass.getDeclaredMethod( "setCustomDecorationTitleBarHeight", int.class );
|
|
||||||
WWindowPeer_setCustomDecorationHitTestSpots = peerClass.getDeclaredMethod( "setCustomDecorationHitTestSpots", List.class );
|
|
||||||
WWindowPeer_setCustomDecorationTitleBarHeight.setAccessible( true );
|
|
||||||
WWindowPeer_setCustomDecorationHitTestSpots.setAccessible( true );
|
|
||||||
|
|
||||||
Window_hasCustomDecoration = Window.class.getDeclaredMethod( "hasCustomDecoration" );
|
|
||||||
Window_setHasCustomDecoration = Window.class.getDeclaredMethod( "setHasCustomDecoration" );
|
|
||||||
Window_hasCustomDecoration.setAccessible( true );
|
|
||||||
Window_setHasCustomDecoration.setAccessible( true );
|
|
||||||
|
|
||||||
supported = true;
|
|
||||||
} catch( Exception ex ) {
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//---- class JBRWindowTopBorder -------------------------------------------
|
|
||||||
|
|
||||||
static class JBRWindowTopBorder
|
|
||||||
extends BorderUIResource.EmptyBorderUIResource
|
|
||||||
{
|
|
||||||
private static JBRWindowTopBorder instance;
|
|
||||||
|
|
||||||
private final Color activeLightColor = new Color( 0x707070 );
|
|
||||||
private final Color activeDarkColor = new Color( 0x2D2E2F );
|
|
||||||
private final Color inactiveLightColor = new Color( 0xaaaaaa );
|
|
||||||
private final Color inactiveDarkColor = new Color( 0x494A4B );
|
|
||||||
|
|
||||||
private boolean colorizationAffectsBorders;
|
|
||||||
private Color activeColor;
|
|
||||||
|
|
||||||
static JBRWindowTopBorder getInstance() {
|
|
||||||
if( instance == null )
|
|
||||||
instance = new JBRWindowTopBorder();
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
JBRWindowTopBorder() {
|
|
||||||
super( 1, 0, 0, 0 );
|
|
||||||
|
|
||||||
update();
|
|
||||||
installListeners();
|
|
||||||
}
|
|
||||||
|
|
||||||
void update() {
|
|
||||||
colorizationAffectsBorders = isColorizationColorAffectsBorders();
|
|
||||||
activeColor = calculateActiveBorderColor();
|
|
||||||
}
|
|
||||||
|
|
||||||
void installListeners() {
|
|
||||||
Toolkit toolkit = Toolkit.getDefaultToolkit();
|
|
||||||
toolkit.addPropertyChangeListener( "win.dwm.colorizationColor.affects.borders", e -> {
|
|
||||||
colorizationAffectsBorders = isColorizationColorAffectsBorders();
|
|
||||||
activeColor = calculateActiveBorderColor();
|
|
||||||
} );
|
|
||||||
|
|
||||||
PropertyChangeListener l = e -> {
|
|
||||||
activeColor = calculateActiveBorderColor();
|
|
||||||
};
|
|
||||||
toolkit.addPropertyChangeListener( "win.dwm.colorizationColor", l );
|
|
||||||
toolkit.addPropertyChangeListener( "win.dwm.colorizationColorBalance", l );
|
|
||||||
toolkit.addPropertyChangeListener( "win.frame.activeBorderColor", l );
|
|
||||||
}
|
|
||||||
|
|
||||||
boolean isColorizationColorAffectsBorders() {
|
|
||||||
Object value = Toolkit.getDefaultToolkit().getDesktopProperty( "win.dwm.colorizationColor.affects.borders" );
|
|
||||||
return (value instanceof Boolean) ? (Boolean) value : true;
|
|
||||||
}
|
|
||||||
|
|
||||||
Color getColorizationColor() {
|
|
||||||
return (Color) Toolkit.getDefaultToolkit().getDesktopProperty( "win.dwm.colorizationColor" );
|
|
||||||
}
|
|
||||||
|
|
||||||
int getColorizationColorBalance() {
|
|
||||||
Object value = Toolkit.getDefaultToolkit().getDesktopProperty( "win.dwm.colorizationColorBalance" );
|
|
||||||
return (value instanceof Integer) ? (Integer) value : -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Color calculateActiveBorderColor() {
|
|
||||||
if( !colorizationAffectsBorders )
|
|
||||||
return null;
|
|
||||||
|
|
||||||
Color colorizationColor = getColorizationColor();
|
|
||||||
if( colorizationColor != null ) {
|
|
||||||
int colorizationColorBalance = getColorizationColorBalance();
|
|
||||||
if( colorizationColorBalance < 0 || colorizationColorBalance > 100 )
|
|
||||||
colorizationColorBalance = 100;
|
|
||||||
|
|
||||||
if( colorizationColorBalance == 0 )
|
|
||||||
return new Color( 0xD9D9D9 );
|
|
||||||
if( colorizationColorBalance == 100 )
|
|
||||||
return colorizationColor;
|
|
||||||
|
|
||||||
float alpha = colorizationColorBalance / 100.0f;
|
|
||||||
float remainder = 1 - alpha;
|
|
||||||
int r = Math.round( colorizationColor.getRed() * alpha + 0xD9 * remainder );
|
|
||||||
int g = Math.round( colorizationColor.getGreen() * alpha + 0xD9 * remainder );
|
|
||||||
int b = Math.round( colorizationColor.getBlue() * alpha + 0xD9 * remainder );
|
|
||||||
|
|
||||||
// avoid potential IllegalArgumentException in Color constructor
|
|
||||||
r = Math.min( Math.max( r, 0 ), 255 );
|
|
||||||
g = Math.min( Math.max( g, 0 ), 255 );
|
|
||||||
b = Math.min( Math.max( b, 0 ), 255 );
|
|
||||||
|
|
||||||
return new Color( r, g, b );
|
|
||||||
}
|
|
||||||
|
|
||||||
Color activeBorderColor = (Color) Toolkit.getDefaultToolkit().getDesktopProperty( "win.frame.activeBorderColor" );
|
|
||||||
return (activeBorderColor != null) ? activeBorderColor : UIManager.getColor( "MenuBar.borderColor" );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
|
|
||||||
Window window = SwingUtilities.windowForComponent( c );
|
|
||||||
boolean active = window != null && window.isActive();
|
|
||||||
boolean dark = FlatLaf.isLafDark();
|
|
||||||
|
|
||||||
g.setColor( active
|
|
||||||
? (activeColor != null ? activeColor : (dark ? activeDarkColor : activeLightColor))
|
|
||||||
: (dark ? inactiveDarkColor : inactiveLightColor) );
|
|
||||||
HiDPIUtils.paintAtScale1x( (Graphics2D) g, x, y, width, height, this::paintImpl );
|
|
||||||
}
|
|
||||||
|
|
||||||
private void paintImpl( Graphics2D g, int x, int y, int width, int height, double scaleFactor ) {
|
|
||||||
g.fillRect( x, y, width, 1 );
|
|
||||||
}
|
|
||||||
|
|
||||||
void repaintBorder( Component c ) {
|
|
||||||
c.repaint( 0, 0, c.getWidth(), 1 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,91 @@
|
|||||||
|
/*
|
||||||
|
* 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.lang.invoke.MethodHandle;
|
||||||
|
import java.lang.invoke.MethodHandles;
|
||||||
|
import java.lang.invoke.MethodType;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import javax.swing.JComponent;
|
||||||
|
import javax.swing.JList;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JTable;
|
||||||
|
import javax.swing.JTree;
|
||||||
|
import javax.swing.plaf.ComponentUI;
|
||||||
|
import javax.swing.text.JTextComponent;
|
||||||
|
import com.formdev.flatlaf.util.LoggingFacade;
|
||||||
|
import com.formdev.flatlaf.util.SystemInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides Java version compatibility methods.
|
||||||
|
* <p>
|
||||||
|
* WARNING: This is private API and may change.
|
||||||
|
*
|
||||||
|
* @author Karl Tauber
|
||||||
|
* @since 3.3
|
||||||
|
*/
|
||||||
|
public class JavaCompatibility2
|
||||||
|
{
|
||||||
|
private static boolean getUIMethodInitialized;
|
||||||
|
private static MethodHandle getUIMethod;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Java 8: getUI() method on various components (e.g. JButton, JList, etc)
|
||||||
|
* <br>
|
||||||
|
* Java 9: javax.swing.JComponent.getUI()
|
||||||
|
*/
|
||||||
|
public static ComponentUI getUI( JComponent c ) {
|
||||||
|
try {
|
||||||
|
// Java 9+
|
||||||
|
if( SystemInfo.isJava_9_orLater ) {
|
||||||
|
if( !getUIMethodInitialized ) {
|
||||||
|
getUIMethodInitialized = true;
|
||||||
|
|
||||||
|
try {
|
||||||
|
MethodType mt = MethodType.methodType( ComponentUI.class, new Class[0] );
|
||||||
|
getUIMethod = MethodHandles.publicLookup().findVirtual( JComponent.class, "getUI", mt );
|
||||||
|
} catch( Exception ex ) {
|
||||||
|
// ignore
|
||||||
|
LoggingFacade.INSTANCE.logSevere( null, ex );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( getUIMethod != null )
|
||||||
|
return (ComponentUI) getUIMethod.invoke( c );
|
||||||
|
}
|
||||||
|
|
||||||
|
// components often used (e.g. as view in scroll panes)
|
||||||
|
if( c instanceof JPanel )
|
||||||
|
return ((JPanel)c).getUI();
|
||||||
|
if( c instanceof JList )
|
||||||
|
return ((JList<?>)c).getUI();
|
||||||
|
if( c instanceof JTable )
|
||||||
|
return ((JTable)c).getUI();
|
||||||
|
if( c instanceof JTree )
|
||||||
|
return ((JTree)c).getUI();
|
||||||
|
if( c instanceof JTextComponent )
|
||||||
|
return ((JTextComponent)c).getUI();
|
||||||
|
|
||||||
|
// Java 8 and fallback
|
||||||
|
Method m = c.getClass().getMethod( "getUI" );
|
||||||
|
return (ComponentUI) m.invoke( c );
|
||||||
|
} catch( Throwable ex ) {
|
||||||
|
// ignore
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -80,7 +80,7 @@ public class FontUtils
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads a font family previously registered via {@link #registerFontFamilyLoader(String, Runnable)}.
|
* Loads a font family previously registered via {@link #registerFontFamilyLoader(String, Runnable)}.
|
||||||
* If the family is already loaded or no londer is registered for that family, nothing happens.
|
* If the family is already loaded or no loader is registered for that family, nothing happens.
|
||||||
*/
|
*/
|
||||||
public static void loadFontFamily( String family ) {
|
public static void loadFontFamily( String family ) {
|
||||||
if( !hasLoaders() )
|
if( !hasLoaders() )
|
||||||
@@ -109,7 +109,7 @@ public class FontUtils
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns all font familiy names available in the graphics environment.
|
* Returns all font family names available in the graphics environment.
|
||||||
* This invokes {@link GraphicsEnvironment#getAvailableFontFamilyNames()} and
|
* This invokes {@link GraphicsEnvironment#getAvailableFontFamilyNames()} and
|
||||||
* appends families registered for lazy loading via {@link #registerFontFamilyLoader(String, Runnable)}
|
* appends families registered for lazy loading via {@link #registerFontFamilyLoader(String, Runnable)}
|
||||||
* to the result.
|
* to the result.
|
||||||
|
|||||||
@@ -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":
|
||||||
|
|||||||
@@ -116,7 +116,11 @@ public class NativeLibrary
|
|||||||
try {
|
try {
|
||||||
// for development environment
|
// for development environment
|
||||||
if( "file".equals( libraryUrl.getProtocol() ) ) {
|
if( "file".equals( libraryUrl.getProtocol() ) ) {
|
||||||
File libraryFile = new File( libraryUrl.getPath() );
|
String binPath = libraryUrl.getPath();
|
||||||
|
String srcPath = binPath.replace( "flatlaf-core/bin/main/", "flatlaf-core/src/main/resources/" );
|
||||||
|
File libraryFile = new File( srcPath ); // use from 'src' folder if available
|
||||||
|
if( !libraryFile.isFile() )
|
||||||
|
libraryFile = new File( binPath ); // use from 'bin' or 'output' folder if available
|
||||||
if( libraryFile.isFile() ) {
|
if( libraryFile.isFile() ) {
|
||||||
// load library without copying
|
// load library without copying
|
||||||
System.load( libraryFile.getCanonicalPath() );
|
System.load( libraryFile.getCanonicalPath() );
|
||||||
|
|||||||
@@ -204,7 +204,7 @@ public class UIScale
|
|||||||
if( SystemInfo.isWindows ) {
|
if( SystemInfo.isWindows ) {
|
||||||
// Special handling for Windows to be compatible with OS scaling,
|
// Special handling for Windows to be compatible with OS scaling,
|
||||||
// which distinguish between "screen scaling" and "text scaling".
|
// which distinguish between "screen scaling" and "text scaling".
|
||||||
// - Windows "screen scaling" scales everything (text, icon, gaps, etc)
|
// - Windows "screen scaling" scales everything (text, icon, gaps, etc.)
|
||||||
// and may have different scaling factors for each screen.
|
// and may have different scaling factors for each screen.
|
||||||
// - Windows "text scaling" increases only the font size, but on all screens.
|
// - Windows "text scaling" increases only the font size, but on all screens.
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -246,6 +246,7 @@ PasswordField.revealIconColor = @foreground
|
|||||||
|
|
||||||
#---- Popup ----
|
#---- Popup ----
|
||||||
|
|
||||||
|
[mac]Popup.roundedBorderWidth = 1
|
||||||
Popup.dropShadowColor = #000
|
Popup.dropShadowColor = #000
|
||||||
Popup.dropShadowOpacity = 0.25
|
Popup.dropShadowOpacity = 0.25
|
||||||
|
|
||||||
|
|||||||
@@ -289,6 +289,7 @@ ComboBox.popupInsets = 0,0,0,0
|
|||||||
ComboBox.selectionInsets = 0,0,0,0
|
ComboBox.selectionInsets = 0,0,0,0
|
||||||
ComboBox.selectionArc = 0
|
ComboBox.selectionArc = 0
|
||||||
ComboBox.borderCornerRadius = $Popup.borderCornerRadius
|
ComboBox.borderCornerRadius = $Popup.borderCornerRadius
|
||||||
|
[mac]ComboBox.roundedBorderWidth = $Popup.roundedBorderWidth
|
||||||
|
|
||||||
|
|
||||||
#---- Component ----
|
#---- Component ----
|
||||||
@@ -505,6 +506,7 @@ PasswordField.revealIcon = com.formdev.flatlaf.icons.FlatRevealIcon
|
|||||||
#---- Popup ----
|
#---- Popup ----
|
||||||
|
|
||||||
Popup.borderCornerRadius = 4
|
Popup.borderCornerRadius = 4
|
||||||
|
[mac]Popup.roundedBorderWidth = 0
|
||||||
Popup.dropShadowPainted = true
|
Popup.dropShadowPainted = true
|
||||||
Popup.dropShadowInsets = -4,-4,4,4
|
Popup.dropShadowInsets = -4,-4,4,4
|
||||||
|
|
||||||
@@ -514,6 +516,7 @@ Popup.dropShadowInsets = -4,-4,4,4
|
|||||||
PopupMenu.border = com.formdev.flatlaf.ui.FlatPopupMenuBorder
|
PopupMenu.border = com.formdev.flatlaf.ui.FlatPopupMenuBorder
|
||||||
PopupMenu.borderInsets = 4,1,4,1
|
PopupMenu.borderInsets = 4,1,4,1
|
||||||
PopupMenu.borderCornerRadius = $Popup.borderCornerRadius
|
PopupMenu.borderCornerRadius = $Popup.borderCornerRadius
|
||||||
|
[mac]PopupMenu.roundedBorderWidth = $Popup.roundedBorderWidth
|
||||||
PopupMenu.background = @menuBackground
|
PopupMenu.background = @menuBackground
|
||||||
PopupMenu.scrollArrowColor = @buttonArrowColor
|
PopupMenu.scrollArrowColor = @buttonArrowColor
|
||||||
|
|
||||||
@@ -597,10 +600,15 @@ ScrollBar.allowsAbsolutePositioning = true
|
|||||||
|
|
||||||
#---- ScrollPane ----
|
#---- ScrollPane ----
|
||||||
|
|
||||||
ScrollPane.border = com.formdev.flatlaf.ui.FlatBorder
|
ScrollPane.border = com.formdev.flatlaf.ui.FlatScrollPaneBorder
|
||||||
ScrollPane.background = $ScrollBar.track
|
ScrollPane.background = $ScrollBar.track
|
||||||
ScrollPane.fillUpperCorner = true
|
ScrollPane.fillUpperCorner = true
|
||||||
ScrollPane.smoothScrolling = true
|
ScrollPane.smoothScrolling = true
|
||||||
|
ScrollPane.arc = 0
|
||||||
|
#ScrollPane.List.arc = -1
|
||||||
|
#ScrollPane.Table.arc = -1
|
||||||
|
#ScrollPane.TextComponent.arc = -1
|
||||||
|
#ScrollPane.Tree.arc = -1
|
||||||
|
|
||||||
|
|
||||||
#---- SearchField ----
|
#---- SearchField ----
|
||||||
@@ -697,6 +705,8 @@ TabbedPane.tabAreaAlignment = leading
|
|||||||
TabbedPane.tabAlignment = center
|
TabbedPane.tabAlignment = center
|
||||||
# allowed values: preferred, equal or compact
|
# allowed values: preferred, equal or compact
|
||||||
TabbedPane.tabWidthMode = preferred
|
TabbedPane.tabWidthMode = preferred
|
||||||
|
# allowed values: none, auto, left or right
|
||||||
|
TabbedPane.tabRotation = none
|
||||||
|
|
||||||
# allowed values: underlined or card
|
# allowed values: underlined or card
|
||||||
TabbedPane.tabType = underlined
|
TabbedPane.tabType = underlined
|
||||||
@@ -731,7 +741,7 @@ Table.showVerticalLines = false
|
|||||||
Table.showTrailingVerticalLine = false
|
Table.showTrailingVerticalLine = false
|
||||||
Table.consistentHomeEndKeyBehavior = true
|
Table.consistentHomeEndKeyBehavior = true
|
||||||
Table.intercellSpacing = 0,0
|
Table.intercellSpacing = 0,0
|
||||||
Table.scrollPaneBorder = com.formdev.flatlaf.ui.FlatBorder
|
Table.scrollPaneBorder = com.formdev.flatlaf.ui.FlatScrollPaneBorder
|
||||||
Table.ascendingSortIcon = com.formdev.flatlaf.icons.FlatAscendingSortIcon
|
Table.ascendingSortIcon = com.formdev.flatlaf.icons.FlatAscendingSortIcon
|
||||||
Table.descendingSortIcon = com.formdev.flatlaf.icons.FlatDescendingSortIcon
|
Table.descendingSortIcon = com.formdev.flatlaf.icons.FlatDescendingSortIcon
|
||||||
Table.sortIconColor = @icon
|
Table.sortIconColor = @icon
|
||||||
@@ -902,6 +912,7 @@ ToolTipManager.enableToolTipMode = activeApplication
|
|||||||
#---- ToolTip ----
|
#---- ToolTip ----
|
||||||
|
|
||||||
ToolTip.borderCornerRadius = $Popup.borderCornerRadius
|
ToolTip.borderCornerRadius = $Popup.borderCornerRadius
|
||||||
|
[mac]ToolTip.roundedBorderWidth = $Popup.roundedBorderWidth
|
||||||
|
|
||||||
|
|
||||||
#---- Tree ----
|
#---- Tree ----
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -295,3 +295,8 @@ ToggleButton.disabledBackground = $Button.disabledBackground
|
|||||||
ToggleButton.selectedBackground = lighten($ToggleButton.background,20%,derived)
|
ToggleButton.selectedBackground = lighten($ToggleButton.background,20%,derived)
|
||||||
|
|
||||||
ToggleButton.toolbar.selectedBackground = #fff3
|
ToggleButton.toolbar.selectedBackground = #fff3
|
||||||
|
|
||||||
|
|
||||||
|
#---- ToolBar ----
|
||||||
|
|
||||||
|
ToolBar.hoverButtonGroupArc = 14
|
||||||
|
|||||||
@@ -291,3 +291,8 @@ TextPane.selectionForeground = @textSelectionForeground
|
|||||||
#---- ToggleButton ----
|
#---- ToggleButton ----
|
||||||
|
|
||||||
ToggleButton.disabledBackground = $Button.disabledBackground
|
ToggleButton.disabledBackground = $Button.disabledBackground
|
||||||
|
|
||||||
|
|
||||||
|
#---- ToolBar ----
|
||||||
|
|
||||||
|
ToolBar.hoverButtonGroupArc = 14
|
||||||
|
|||||||
@@ -601,7 +601,7 @@ public class TestFlatStyleableInfo
|
|||||||
);
|
);
|
||||||
|
|
||||||
// border
|
// border
|
||||||
flatBorder( expected );
|
flatScrollPaneBorder( expected );
|
||||||
|
|
||||||
assertMapEquals( expected, ui.getStyleableInfos( c ) );
|
assertMapEquals( expected, ui.getStyleableInfos( c ) );
|
||||||
}
|
}
|
||||||
@@ -689,6 +689,9 @@ public class TestFlatStyleableInfo
|
|||||||
|
|
||||||
Map<String, Class<?>> expected = expectedMap(
|
Map<String, Class<?>> expected = expectedMap(
|
||||||
"arrowType", String.class,
|
"arrowType", String.class,
|
||||||
|
"draggingColor", Color.class,
|
||||||
|
"hoverColor", Color.class,
|
||||||
|
"pressedColor", Color.class,
|
||||||
"oneTouchArrowColor", Color.class,
|
"oneTouchArrowColor", Color.class,
|
||||||
"oneTouchHoverArrowColor", Color.class,
|
"oneTouchHoverArrowColor", Color.class,
|
||||||
"oneTouchPressedArrowColor", Color.class,
|
"oneTouchPressedArrowColor", Color.class,
|
||||||
@@ -752,6 +755,7 @@ public class TestFlatStyleableInfo
|
|||||||
"tabAreaAlignment", String.class,
|
"tabAreaAlignment", String.class,
|
||||||
"tabAlignment", String.class,
|
"tabAlignment", String.class,
|
||||||
"tabWidthMode", String.class,
|
"tabWidthMode", String.class,
|
||||||
|
"tabRotation", String.class,
|
||||||
|
|
||||||
"arrowType", String.class,
|
"arrowType", String.class,
|
||||||
"buttonInsets", Insets.class,
|
"buttonInsets", Insets.class,
|
||||||
@@ -925,7 +929,10 @@ public class TestFlatStyleableInfo
|
|||||||
"hoverButtonGroupBackground", Color.class,
|
"hoverButtonGroupBackground", Color.class,
|
||||||
|
|
||||||
"borderMargins", Insets.class,
|
"borderMargins", Insets.class,
|
||||||
"gripColor", Color.class
|
"gripColor", Color.class,
|
||||||
|
|
||||||
|
"separatorWidth", Integer.class,
|
||||||
|
"separatorColor", Color.class
|
||||||
);
|
);
|
||||||
|
|
||||||
assertMapEquals( expected, ui.getStyleableInfos( c ) );
|
assertMapEquals( expected, ui.getStyleableInfos( c ) );
|
||||||
@@ -1005,17 +1012,23 @@ public class TestFlatStyleableInfo
|
|||||||
|
|
||||||
expectedMap( expected,
|
expectedMap( expected,
|
||||||
"arc", int.class,
|
"arc", int.class,
|
||||||
|
|
||||||
"roundRect", Boolean.class
|
"roundRect", Boolean.class
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void flatScrollPaneBorder( Map<String, Class<?>> expected ) {
|
||||||
|
flatBorder( expected );
|
||||||
|
|
||||||
|
expectedMap( expected,
|
||||||
|
"arc", int.class
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
private void flatTextBorder( Map<String, Class<?>> expected ) {
|
private void flatTextBorder( Map<String, Class<?>> expected ) {
|
||||||
flatBorder( expected );
|
flatBorder( expected );
|
||||||
|
|
||||||
expectedMap( expected,
|
expectedMap( expected,
|
||||||
"arc", int.class,
|
"arc", int.class,
|
||||||
|
|
||||||
"roundRect", Boolean.class
|
"roundRect", Boolean.class
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -625,7 +625,7 @@ public class TestFlatStyleableValue
|
|||||||
FlatScrollPaneUI ui = (FlatScrollPaneUI) c.getUI();
|
FlatScrollPaneUI ui = (FlatScrollPaneUI) c.getUI();
|
||||||
|
|
||||||
// border
|
// border
|
||||||
flatBorder( c, ui );
|
flatScrollPaneBorder( c, ui );
|
||||||
|
|
||||||
testBoolean( c, ui, "showButtons", true );
|
testBoolean( c, ui, "showButtons", true );
|
||||||
}
|
}
|
||||||
@@ -699,6 +699,9 @@ public class TestFlatStyleableValue
|
|||||||
FlatSplitPaneUI ui = (FlatSplitPaneUI) c.getUI();
|
FlatSplitPaneUI ui = (FlatSplitPaneUI) c.getUI();
|
||||||
|
|
||||||
testString( c, ui, "arrowType", "chevron" );
|
testString( c, ui, "arrowType", "chevron" );
|
||||||
|
testColor( c, ui, "draggingColor", 0x123456 );
|
||||||
|
testColor( c, ui, "hoverColor", 0x123456 );
|
||||||
|
testColor( c, ui, "pressedColor", 0x123456 );
|
||||||
testColor( c, ui, "oneTouchArrowColor", 0x123456 );
|
testColor( c, ui, "oneTouchArrowColor", 0x123456 );
|
||||||
testColor( c, ui, "oneTouchHoverArrowColor", 0x123456 );
|
testColor( c, ui, "oneTouchHoverArrowColor", 0x123456 );
|
||||||
testColor( c, ui, "oneTouchPressedArrowColor", 0x123456 );
|
testColor( c, ui, "oneTouchPressedArrowColor", 0x123456 );
|
||||||
@@ -758,6 +761,7 @@ public class TestFlatStyleableValue
|
|||||||
testString( c, ui, "tabAreaAlignment", "leading" );
|
testString( c, ui, "tabAreaAlignment", "leading" );
|
||||||
testString( c, ui, "tabAlignment", "center" );
|
testString( c, ui, "tabAlignment", "center" );
|
||||||
testString( c, ui, "tabWidthMode", "preferred" );
|
testString( c, ui, "tabWidthMode", "preferred" );
|
||||||
|
testString( c, ui, "tabRotation", "none" );
|
||||||
|
|
||||||
testString( c, ui, "arrowType", "chevron" );
|
testString( c, ui, "arrowType", "chevron" );
|
||||||
testInsets( c, ui, "buttonInsets", 1,2,3,4 );
|
testInsets( c, ui, "buttonInsets", 1,2,3,4 );
|
||||||
@@ -902,6 +906,9 @@ public class TestFlatStyleableValue
|
|||||||
|
|
||||||
testInsets( c, ui, "borderMargins", 1,2,3,4 );
|
testInsets( c, ui, "borderMargins", 1,2,3,4 );
|
||||||
testColor( c, ui, "gripColor", 0x123456 );
|
testColor( c, ui, "gripColor", 0x123456 );
|
||||||
|
|
||||||
|
testInteger( c, ui, "separatorWidth", 123 );
|
||||||
|
testColor( c, ui, "separatorColor", 0x123456 );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -965,15 +972,19 @@ public class TestFlatStyleableValue
|
|||||||
flatBorder( c, ui );
|
flatBorder( c, ui );
|
||||||
|
|
||||||
testInteger( c, ui, "arc", 123 );
|
testInteger( c, ui, "arc", 123 );
|
||||||
|
|
||||||
testBoolean( c, ui, "roundRect", true );
|
testBoolean( c, ui, "roundRect", true );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void flatScrollPaneBorder( JComponent c, StyleableUI ui ) {
|
||||||
|
flatBorder( c, ui );
|
||||||
|
|
||||||
|
testInteger( c, ui, "arc", 123 );
|
||||||
|
}
|
||||||
|
|
||||||
private void flatTextBorder( JComponent c, StyleableUI ui ) {
|
private void flatTextBorder( JComponent c, StyleableUI ui ) {
|
||||||
flatBorder( c, ui );
|
flatBorder( c, ui );
|
||||||
|
|
||||||
testInteger( c, ui, "arc", 123 );
|
testInteger( c, ui, "arc", 123 );
|
||||||
|
|
||||||
testBoolean( c, ui, "roundRect", true );
|
testBoolean( c, ui, "roundRect", true );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1034,6 +1045,17 @@ public class TestFlatStyleableValue
|
|||||||
// FlatRoundBorder extends FlatBorder
|
// FlatRoundBorder extends FlatBorder
|
||||||
flatBorder( border );
|
flatBorder( border );
|
||||||
|
|
||||||
|
testValue( border, "arc", 6 );
|
||||||
|
testValue( border, "roundRect", true );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void flatScrollPaneBorder() {
|
||||||
|
FlatScrollPaneBorder border = new FlatScrollPaneBorder();
|
||||||
|
|
||||||
|
// FlatScrollPaneBorder extends FlatBorder
|
||||||
|
flatBorder( border );
|
||||||
|
|
||||||
testValue( border, "arc", 6 );
|
testValue( border, "arc", 6 );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1045,6 +1067,7 @@ public class TestFlatStyleableValue
|
|||||||
flatBorder( border );
|
flatBorder( border );
|
||||||
|
|
||||||
testValue( border, "arc", 6 );
|
testValue( border, "arc", 6 );
|
||||||
|
testValue( border, "roundRect", true );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -760,7 +760,7 @@ public class TestFlatStyling
|
|||||||
FlatScrollPaneUI ui = (FlatScrollPaneUI) c.getUI();
|
FlatScrollPaneUI ui = (FlatScrollPaneUI) c.getUI();
|
||||||
|
|
||||||
// border
|
// border
|
||||||
flatBorder( style -> ui.applyStyle( style ) );
|
flatScrollPaneBorder( style -> ui.applyStyle( style ) );
|
||||||
|
|
||||||
ui.applyStyle( "showButtons: true" );
|
ui.applyStyle( "showButtons: true" );
|
||||||
|
|
||||||
@@ -870,6 +870,9 @@ public class TestFlatStyling
|
|||||||
FlatSplitPaneUI ui = (FlatSplitPaneUI) c.getUI();
|
FlatSplitPaneUI ui = (FlatSplitPaneUI) c.getUI();
|
||||||
|
|
||||||
ui.applyStyle( "arrowType: chevron" );
|
ui.applyStyle( "arrowType: chevron" );
|
||||||
|
ui.applyStyle( "draggingColor: #fff" );
|
||||||
|
ui.applyStyle( "hoverColor: #fff" );
|
||||||
|
ui.applyStyle( "pressedColor: #fff" );
|
||||||
ui.applyStyle( "oneTouchArrowColor: #fff" );
|
ui.applyStyle( "oneTouchArrowColor: #fff" );
|
||||||
ui.applyStyle( "oneTouchHoverArrowColor: #fff" );
|
ui.applyStyle( "oneTouchHoverArrowColor: #fff" );
|
||||||
ui.applyStyle( "oneTouchPressedArrowColor: #fff" );
|
ui.applyStyle( "oneTouchPressedArrowColor: #fff" );
|
||||||
@@ -937,6 +940,7 @@ public class TestFlatStyling
|
|||||||
ui.applyStyle( "tabAreaAlignment: leading" );
|
ui.applyStyle( "tabAreaAlignment: leading" );
|
||||||
ui.applyStyle( "tabAlignment: center" );
|
ui.applyStyle( "tabAlignment: center" );
|
||||||
ui.applyStyle( "tabWidthMode: preferred" );
|
ui.applyStyle( "tabWidthMode: preferred" );
|
||||||
|
ui.applyStyle( "tabRotation: none" );
|
||||||
|
|
||||||
ui.applyStyle( "arrowType: chevron" );
|
ui.applyStyle( "arrowType: chevron" );
|
||||||
ui.applyStyle( "buttonInsets: 1,2,3,4" );
|
ui.applyStyle( "buttonInsets: 1,2,3,4" );
|
||||||
@@ -1146,6 +1150,9 @@ public class TestFlatStyling
|
|||||||
ui.applyStyle( "borderMargins: 1,2,3,4" );
|
ui.applyStyle( "borderMargins: 1,2,3,4" );
|
||||||
ui.applyStyle( "gripColor: #fff" );
|
ui.applyStyle( "gripColor: #fff" );
|
||||||
|
|
||||||
|
ui.applyStyle( "separatorWidth: 6" );
|
||||||
|
ui.applyStyle( "separatorColor: #fff" );
|
||||||
|
|
||||||
// JComponent properties
|
// JComponent properties
|
||||||
ui.applyStyle( "background: #fff" );
|
ui.applyStyle( "background: #fff" );
|
||||||
ui.applyStyle( "foreground: #fff" );
|
ui.applyStyle( "foreground: #fff" );
|
||||||
@@ -1234,15 +1241,19 @@ public class TestFlatStyling
|
|||||||
flatBorder( applyStyle );
|
flatBorder( applyStyle );
|
||||||
|
|
||||||
applyStyle.accept( "arc: 6" );
|
applyStyle.accept( "arc: 6" );
|
||||||
|
|
||||||
applyStyle.accept( "roundRect: true" );
|
applyStyle.accept( "roundRect: true" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void flatScrollPaneBorder( Consumer<String> applyStyle ) {
|
||||||
|
flatBorder( applyStyle );
|
||||||
|
|
||||||
|
applyStyle.accept( "arc: 6" );
|
||||||
|
}
|
||||||
|
|
||||||
private void flatTextBorder( Consumer<String> applyStyle ) {
|
private void flatTextBorder( Consumer<String> applyStyle ) {
|
||||||
flatBorder( applyStyle );
|
flatBorder( applyStyle );
|
||||||
|
|
||||||
applyStyle.accept( "arc: 6" );
|
applyStyle.accept( "arc: 6" );
|
||||||
|
|
||||||
applyStyle.accept( "roundRect: true" );
|
applyStyle.accept( "roundRect: true" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ import javax.swing.plaf.metal.MetalLookAndFeel;
|
|||||||
import javax.swing.plaf.nimbus.NimbusLookAndFeel;
|
import javax.swing.plaf.nimbus.NimbusLookAndFeel;
|
||||||
import com.formdev.flatlaf.*;
|
import com.formdev.flatlaf.*;
|
||||||
import com.formdev.flatlaf.extras.FlatAnimatedLafChange;
|
import com.formdev.flatlaf.extras.FlatAnimatedLafChange;
|
||||||
|
import com.formdev.flatlaf.themes.FlatMacDarkLaf;
|
||||||
|
import com.formdev.flatlaf.themes.FlatMacLightLaf;
|
||||||
import com.formdev.flatlaf.util.LoggingFacade;
|
import com.formdev.flatlaf.util.LoggingFacade;
|
||||||
import com.formdev.flatlaf.util.SystemInfo;
|
import com.formdev.flatlaf.util.SystemInfo;
|
||||||
import com.formdev.flatlaf.util.UIScale;
|
import com.formdev.flatlaf.util.UIScale;
|
||||||
@@ -66,6 +68,8 @@ class ControlBar
|
|||||||
lafModel.addElement( new LookAndFeelInfo( "FlatLaf Dark (F2)", FlatDarkLaf.class.getName() ) );
|
lafModel.addElement( new LookAndFeelInfo( "FlatLaf Dark (F2)", FlatDarkLaf.class.getName() ) );
|
||||||
lafModel.addElement( new LookAndFeelInfo( "FlatLaf IntelliJ (F3)", FlatIntelliJLaf.class.getName() ) );
|
lafModel.addElement( new LookAndFeelInfo( "FlatLaf IntelliJ (F3)", FlatIntelliJLaf.class.getName() ) );
|
||||||
lafModel.addElement( new LookAndFeelInfo( "FlatLaf Darcula (F4)", FlatDarculaLaf.class.getName() ) );
|
lafModel.addElement( new LookAndFeelInfo( "FlatLaf Darcula (F4)", FlatDarculaLaf.class.getName() ) );
|
||||||
|
lafModel.addElement( new LookAndFeelInfo( "FlatLaf macOS Light (F5)", FlatMacLightLaf.class.getName() ) );
|
||||||
|
lafModel.addElement( new LookAndFeelInfo( "FlatLaf macOS Dark (F6)", FlatMacDarkLaf.class.getName() ) );
|
||||||
|
|
||||||
UIManager.LookAndFeelInfo[] lookAndFeels = UIManager.getInstalledLookAndFeels();
|
UIManager.LookAndFeelInfo[] lookAndFeels = UIManager.getInstalledLookAndFeels();
|
||||||
for( UIManager.LookAndFeelInfo lookAndFeel : lookAndFeels ) {
|
for( UIManager.LookAndFeelInfo lookAndFeel : lookAndFeels ) {
|
||||||
@@ -127,6 +131,8 @@ class ControlBar
|
|||||||
registerSwitchToLookAndFeel( KeyEvent.VK_F2, FlatDarkLaf.class.getName() );
|
registerSwitchToLookAndFeel( KeyEvent.VK_F2, FlatDarkLaf.class.getName() );
|
||||||
registerSwitchToLookAndFeel( KeyEvent.VK_F3, FlatIntelliJLaf.class.getName() );
|
registerSwitchToLookAndFeel( KeyEvent.VK_F3, FlatIntelliJLaf.class.getName() );
|
||||||
registerSwitchToLookAndFeel( KeyEvent.VK_F4, FlatDarculaLaf.class.getName() );
|
registerSwitchToLookAndFeel( KeyEvent.VK_F4, FlatDarculaLaf.class.getName() );
|
||||||
|
registerSwitchToLookAndFeel( KeyEvent.VK_F5, FlatMacLightLaf.class.getName() );
|
||||||
|
registerSwitchToLookAndFeel( KeyEvent.VK_F6, FlatMacDarkLaf.class.getName() );
|
||||||
|
|
||||||
if( SystemInfo.isWindows )
|
if( SystemInfo.isWindows )
|
||||||
registerSwitchToLookAndFeel( KeyEvent.VK_F9, "com.sun.java.swing.plaf.windows.WindowsLookAndFeel" );
|
registerSwitchToLookAndFeel( KeyEvent.VK_F9, "com.sun.java.swing.plaf.windows.WindowsLookAndFeel" );
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ package com.formdev.flatlaf.demo;
|
|||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.EventQueue;
|
|
||||||
import java.awt.datatransfer.DataFlavor;
|
import java.awt.datatransfer.DataFlavor;
|
||||||
import java.awt.datatransfer.StringSelection;
|
import java.awt.datatransfer.StringSelection;
|
||||||
import java.awt.datatransfer.Transferable;
|
import java.awt.datatransfer.Transferable;
|
||||||
@@ -116,15 +115,16 @@ class DataComponentsPanel
|
|||||||
table1.setGridColor( redGridColorCheckBox.isSelected() ? Color.red : UIManager.getColor( "Table.gridColor" ) );
|
table1.setGridColor( redGridColorCheckBox.isSelected() ? Color.red : UIManager.getColor( "Table.gridColor" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private void showHorizontalLinesPropertyChange() {
|
||||||
public void updateUI() {
|
showHorizontalLinesCheckBox.setSelected( table1.getShowHorizontalLines() );
|
||||||
super.updateUI();
|
}
|
||||||
|
|
||||||
EventQueue.invokeLater( () -> {
|
private void showVerticalLinesPropertyChange() {
|
||||||
showHorizontalLinesChanged();
|
showVerticalLinesCheckBox.setSelected( table1.getShowVerticalLines() );
|
||||||
showVerticalLinesChanged();
|
}
|
||||||
intercellSpacingChanged();
|
|
||||||
} );
|
private void intercellSpacingPropertyChange() {
|
||||||
|
intercellSpacingCheckBox.setSelected( table1.getRowMargin() != 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings( { "unchecked", "rawtypes" } )
|
@SuppressWarnings( { "unchecked", "rawtypes" } )
|
||||||
@@ -333,10 +333,10 @@ class DataComponentsPanel
|
|||||||
"Not editable", "Text", "Combo", "Combo Editable", "Integer", "Boolean"
|
"Not editable", "Text", "Combo", "Combo Editable", "Integer", "Boolean"
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
Class<?>[] columnTypes = new Class<?>[] {
|
Class<?>[] columnTypes = {
|
||||||
Object.class, Object.class, String.class, String.class, Integer.class, Boolean.class
|
Object.class, Object.class, String.class, String.class, Integer.class, Boolean.class
|
||||||
};
|
};
|
||||||
boolean[] columnEditable = new boolean[] {
|
boolean[] columnEditable = {
|
||||||
false, true, true, true, true, true
|
false, true, true, true, true, true
|
||||||
};
|
};
|
||||||
@Override
|
@Override
|
||||||
@@ -383,6 +383,9 @@ class DataComponentsPanel
|
|||||||
}
|
}
|
||||||
table1.setAutoCreateRowSorter(true);
|
table1.setAutoCreateRowSorter(true);
|
||||||
table1.setComponentPopupMenu(popupMenu2);
|
table1.setComponentPopupMenu(popupMenu2);
|
||||||
|
table1.addPropertyChangeListener("showHorizontalLines", e -> showHorizontalLinesPropertyChange());
|
||||||
|
table1.addPropertyChangeListener("showVerticalLines", e -> showVerticalLinesPropertyChange());
|
||||||
|
table1.addPropertyChangeListener("rowMargin", e -> intercellSpacingPropertyChange());
|
||||||
scrollPane5.setViewportView(table1);
|
scrollPane5.setViewportView(table1);
|
||||||
}
|
}
|
||||||
add(scrollPane5, "cell 1 3 3 1,width 300");
|
add(scrollPane5, "cell 1 3 3 1,width 300");
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
JFDML JFormDesigner: "8.0.0.0.194" Java: "17.0.2" encoding: "UTF-8"
|
JFDML JFormDesigner: "8.2.0.0.331" Java: "21" encoding: "UTF-8"
|
||||||
|
|
||||||
new FormModel {
|
new FormModel {
|
||||||
contentType: "form/swing"
|
contentType: "form/swing"
|
||||||
@@ -333,6 +333,9 @@ new FormModel {
|
|||||||
auxiliary() {
|
auxiliary() {
|
||||||
"JavaCodeGenerator.variableLocal": false
|
"JavaCodeGenerator.variableLocal": false
|
||||||
}
|
}
|
||||||
|
addEvent( new FormEvent( "java.beans.PropertyChangeListener", "propertyChange", "showHorizontalLinesPropertyChange", false, "showHorizontalLines" ) )
|
||||||
|
addEvent( new FormEvent( "java.beans.PropertyChangeListener", "propertyChange", "showVerticalLinesPropertyChange", false, "showVerticalLines" ) )
|
||||||
|
addEvent( new FormEvent( "java.beans.PropertyChangeListener", "propertyChange", "intercellSpacingPropertyChange", false, "rowMargin" ) )
|
||||||
} )
|
} )
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
"value": "cell 1 3 3 1,width 300"
|
"value": "cell 1 3 3 1,width 300"
|
||||||
|
|||||||
@@ -46,7 +46,6 @@ import com.formdev.flatlaf.icons.FlatAbstractIcon;
|
|||||||
import com.formdev.flatlaf.themes.FlatMacDarkLaf;
|
import com.formdev.flatlaf.themes.FlatMacDarkLaf;
|
||||||
import com.formdev.flatlaf.themes.FlatMacLightLaf;
|
import com.formdev.flatlaf.themes.FlatMacLightLaf;
|
||||||
import com.formdev.flatlaf.extras.FlatSVGUtils;
|
import com.formdev.flatlaf.extras.FlatSVGUtils;
|
||||||
import com.formdev.flatlaf.ui.JBRCustomDecorations;
|
|
||||||
import com.formdev.flatlaf.util.ColorFunctions;
|
import com.formdev.flatlaf.util.ColorFunctions;
|
||||||
import com.formdev.flatlaf.util.FontUtils;
|
import com.formdev.flatlaf.util.FontUtils;
|
||||||
import com.formdev.flatlaf.util.LoggingFacade;
|
import com.formdev.flatlaf.util.LoggingFacade;
|
||||||
@@ -931,12 +930,6 @@ class DemoFrame
|
|||||||
menuBarEmbeddedCheckBoxMenuItem.setSelected( UIManager.getBoolean( "TitlePane.menuBarEmbedded" ) );
|
menuBarEmbeddedCheckBoxMenuItem.setSelected( UIManager.getBoolean( "TitlePane.menuBarEmbedded" ) );
|
||||||
unifiedTitleBarMenuItem.setSelected( UIManager.getBoolean( "TitlePane.unifiedBackground" ) );
|
unifiedTitleBarMenuItem.setSelected( UIManager.getBoolean( "TitlePane.unifiedBackground" ) );
|
||||||
showTitleBarIconMenuItem.setSelected( UIManager.getBoolean( "TitlePane.showIcon" ) );
|
showTitleBarIconMenuItem.setSelected( UIManager.getBoolean( "TitlePane.showIcon" ) );
|
||||||
|
|
||||||
if( JBRCustomDecorations.isSupported() ) {
|
|
||||||
// If the JetBrains Runtime is used, it forces the use of it's own custom
|
|
||||||
// window decoration, which can not disabled.
|
|
||||||
windowDecorationsCheckBoxMenuItem.setEnabled( false );
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
unsupported( windowDecorationsCheckBoxMenuItem );
|
unsupported( windowDecorationsCheckBoxMenuItem );
|
||||||
unsupported( menuBarEmbeddedCheckBoxMenuItem );
|
unsupported( menuBarEmbeddedCheckBoxMenuItem );
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ public class ScrollablePanel
|
|||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public Dimension getPreferredScrollableViewportSize() {
|
public Dimension getPreferredScrollableViewportSize() {
|
||||||
return UIScale.scale( new Dimension( 400, 400 ) );
|
return new Dimension( getPreferredSize().width, UIScale.scale( 400 ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -49,7 +49,7 @@ public class ScrollablePanel
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean getScrollableTracksViewportWidth() {
|
public boolean getScrollableTracksViewportWidth() {
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -204,7 +204,7 @@ class TabsPanel
|
|||||||
private void closeButtonStyleChanged() {
|
private void closeButtonStyleChanged() {
|
||||||
// WARNING:
|
// WARNING:
|
||||||
// Do not use this trick to style individual tabbed panes in own code.
|
// Do not use this trick to style individual tabbed panes in own code.
|
||||||
// Instead use one styling for all tabbed panes in your application.
|
// Instead, use one styling for all tabbed panes in your application.
|
||||||
if( circleCloseButton.isSelected() ) {
|
if( circleCloseButton.isSelected() ) {
|
||||||
UIManager.put( "TabbedPane.closeArc", 999 );
|
UIManager.put( "TabbedPane.closeArc", 999 );
|
||||||
UIManager.put( "TabbedPane.closeCrossFilledSize", 5.5f );
|
UIManager.put( "TabbedPane.closeCrossFilledSize", 5.5f );
|
||||||
@@ -313,6 +313,14 @@ class TabsPanel
|
|||||||
putTabbedPanesClientProperty( TABBED_PANE_SHOW_TAB_SEPARATORS, showTabSeparators );
|
putTabbedPanesClientProperty( TABBED_PANE_SHOW_TAB_SEPARATORS, showTabSeparators );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void tabRotationChanged() {
|
||||||
|
String tabRotation = rotationAutoButton.isSelected() ? TABBED_PANE_TAB_ROTATION_AUTO
|
||||||
|
: rotationLeftButton.isSelected() ? TABBED_PANE_TAB_ROTATION_LEFT
|
||||||
|
: rotationRightButton.isSelected() ? TABBED_PANE_TAB_ROTATION_RIGHT
|
||||||
|
: null;
|
||||||
|
putTabbedPanesClientProperty( TABBED_PANE_TAB_ROTATION, tabRotation );
|
||||||
|
}
|
||||||
|
|
||||||
private void putTabbedPanesClientProperty( String key, Object value ) {
|
private void putTabbedPanesClientProperty( String key, Object value ) {
|
||||||
updateTabbedPanesRecur( this, tabbedPane -> tabbedPane.putClientProperty( key, value ) );
|
updateTabbedPanesRecur( this, tabbedPane -> tabbedPane.putClientProperty( key, value ) );
|
||||||
}
|
}
|
||||||
@@ -331,6 +339,8 @@ class TabsPanel
|
|||||||
|
|
||||||
private void initComponents() {
|
private void initComponents() {
|
||||||
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
|
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
|
||||||
|
JScrollPane tabsScrollPane = new JScrollPane();
|
||||||
|
ScrollablePanel panel6 = new ScrollablePanel();
|
||||||
JPanel panel1 = new JPanel();
|
JPanel panel1 = new JPanel();
|
||||||
JLabel tabPlacementLabel = new JLabel();
|
JLabel tabPlacementLabel = new JLabel();
|
||||||
tabPlacementToolBar = new JToolBar();
|
tabPlacementToolBar = new JToolBar();
|
||||||
@@ -397,31 +407,50 @@ class TabsPanel
|
|||||||
scrollAsNeededSingleButton = new JToggleButton();
|
scrollAsNeededSingleButton = new JToggleButton();
|
||||||
scrollAsNeededButton = new JToggleButton();
|
scrollAsNeededButton = new JToggleButton();
|
||||||
scrollNeverButton = new JToggleButton();
|
scrollNeverButton = new JToggleButton();
|
||||||
scrollButtonsPlacementLabel = new JLabel();
|
|
||||||
scrollButtonsPlacementToolBar = new JToolBar();
|
|
||||||
scrollBothButton = new JToggleButton();
|
|
||||||
scrollTrailingButton = new JToggleButton();
|
|
||||||
showTabSeparatorsCheckBox = new JCheckBox();
|
|
||||||
tabsPopupPolicyLabel = new JLabel();
|
tabsPopupPolicyLabel = new JLabel();
|
||||||
tabsPopupPolicyToolBar = new JToolBar();
|
tabsPopupPolicyToolBar = new JToolBar();
|
||||||
popupAsNeededButton = new JToggleButton();
|
popupAsNeededButton = new JToggleButton();
|
||||||
popupNeverButton = new JToggleButton();
|
popupNeverButton = new JToggleButton();
|
||||||
|
showTabSeparatorsCheckBox = new JCheckBox();
|
||||||
|
scrollButtonsPlacementLabel = new JLabel();
|
||||||
|
scrollButtonsPlacementToolBar = new JToolBar();
|
||||||
|
scrollBothButton = new JToggleButton();
|
||||||
|
scrollTrailingButton = new JToggleButton();
|
||||||
tabTypeLabel = new JLabel();
|
tabTypeLabel = new JLabel();
|
||||||
tabTypeToolBar = new JToolBar();
|
tabTypeToolBar = new JToolBar();
|
||||||
underlinedTabTypeButton = new JToggleButton();
|
underlinedTabTypeButton = new JToggleButton();
|
||||||
cardTabTypeButton = new JToggleButton();
|
cardTabTypeButton = new JToggleButton();
|
||||||
|
tabRotationLabel = new JLabel();
|
||||||
|
tabRotationToolBar = new JToolBar();
|
||||||
|
rotationNoneButton = new JToggleButton();
|
||||||
|
rotationAutoButton = new JToggleButton();
|
||||||
|
rotationLeftButton = new JToggleButton();
|
||||||
|
rotationRightButton = new JToggleButton();
|
||||||
|
|
||||||
//======== this ========
|
//======== this ========
|
||||||
setLayout(new MigLayout(
|
setLayout(new MigLayout(
|
||||||
|
"insets 0,hidemode 3",
|
||||||
|
// columns
|
||||||
|
"[grow,fill]",
|
||||||
|
// rows
|
||||||
|
"[grow,fill]0" +
|
||||||
|
"[]0" +
|
||||||
|
"[]"));
|
||||||
|
|
||||||
|
//======== tabsScrollPane ========
|
||||||
|
{
|
||||||
|
tabsScrollPane.setBorder(BorderFactory.createEmptyBorder());
|
||||||
|
|
||||||
|
//======== panel6 ========
|
||||||
|
{
|
||||||
|
panel6.setLayout(new MigLayout(
|
||||||
"insets dialog,hidemode 3",
|
"insets dialog,hidemode 3",
|
||||||
// columns
|
// columns
|
||||||
"[grow,fill]para" +
|
"[grow,fill]para" +
|
||||||
"[fill]para" +
|
"[fill]para" +
|
||||||
"[fill]",
|
"[fill]",
|
||||||
// rows
|
// rows
|
||||||
"[grow,fill]para" +
|
"[grow,fill]"));
|
||||||
"[]" +
|
|
||||||
"[]"));
|
|
||||||
|
|
||||||
//======== panel1 ========
|
//======== panel1 ========
|
||||||
{
|
{
|
||||||
@@ -589,7 +618,7 @@ class TabsPanel
|
|||||||
panel1.add(tabAreaComponentsToolBar, "cell 0 7,alignx right,growx 0");
|
panel1.add(tabAreaComponentsToolBar, "cell 0 7,alignx right,growx 0");
|
||||||
panel1.add(customComponentsTabbedPane, "cell 0 8");
|
panel1.add(customComponentsTabbedPane, "cell 0 8");
|
||||||
}
|
}
|
||||||
add(panel1, "cell 0 0");
|
panel6.add(panel1, "cell 0 0");
|
||||||
|
|
||||||
//======== panel2 ========
|
//======== panel2 ========
|
||||||
{
|
{
|
||||||
@@ -641,7 +670,7 @@ class TabsPanel
|
|||||||
panel2.add(alignTrailingTabbedPane, "cell 0 10");
|
panel2.add(alignTrailingTabbedPane, "cell 0 10");
|
||||||
panel2.add(alignFillTabbedPane, "cell 0 11");
|
panel2.add(alignFillTabbedPane, "cell 0 11");
|
||||||
}
|
}
|
||||||
add(panel2, "cell 1 0,growy");
|
panel6.add(panel2, "cell 1 0,growy");
|
||||||
|
|
||||||
//======== panel3 ========
|
//======== panel3 ========
|
||||||
{
|
{
|
||||||
@@ -698,6 +727,7 @@ class TabsPanel
|
|||||||
"[]" +
|
"[]" +
|
||||||
"[]" +
|
"[]" +
|
||||||
"[]" +
|
"[]" +
|
||||||
|
"[]" +
|
||||||
"[]"));
|
"[]"));
|
||||||
|
|
||||||
//---- tabAlignmentNoteLabel ----
|
//---- tabAlignmentNoteLabel ----
|
||||||
@@ -717,24 +747,29 @@ class TabsPanel
|
|||||||
{
|
{
|
||||||
tabAlignVerticalTabbedPane.setTabPlacement(SwingConstants.LEFT);
|
tabAlignVerticalTabbedPane.setTabPlacement(SwingConstants.LEFT);
|
||||||
}
|
}
|
||||||
panel5.add(tabAlignVerticalTabbedPane, "cell 1 1 1 3,growy");
|
panel5.add(tabAlignVerticalTabbedPane, "cell 1 1 1 4,growy");
|
||||||
panel5.add(tabAlignCenterTabbedPane, "cell 0 2");
|
panel5.add(tabAlignCenterTabbedPane, "cell 0 2");
|
||||||
panel5.add(tabAlignTrailingTabbedPane, "cell 0 3");
|
panel5.add(tabAlignTrailingTabbedPane, "cell 0 3");
|
||||||
}
|
}
|
||||||
panel3.add(panel5, "cell 0 9");
|
panel3.add(panel5, "cell 0 9");
|
||||||
}
|
}
|
||||||
add(panel3, "cell 2 0");
|
panel6.add(panel3, "cell 2 0");
|
||||||
add(separator2, "cell 0 1 3 1");
|
}
|
||||||
|
tabsScrollPane.setViewportView(panel6);
|
||||||
|
}
|
||||||
|
add(tabsScrollPane, "cell 0 0");
|
||||||
|
add(separator2, "cell 0 1");
|
||||||
|
|
||||||
//======== panel4 ========
|
//======== panel4 ========
|
||||||
{
|
{
|
||||||
panel4.setLayout(new MigLayout(
|
panel4.setLayout(new MigLayout(
|
||||||
"insets 0,hidemode 3",
|
"insets panel,hidemode 3",
|
||||||
// columns
|
// columns
|
||||||
"[]" +
|
"[]" +
|
||||||
"[fill]para" +
|
"[fill]para" +
|
||||||
"[fill]" +
|
"[fill]" +
|
||||||
"[fill]para" +
|
"[fill]para" +
|
||||||
|
"[fill]" +
|
||||||
"[fill]",
|
"[fill]",
|
||||||
// rows
|
// rows
|
||||||
"[]" +
|
"[]" +
|
||||||
@@ -770,38 +805,9 @@ class TabsPanel
|
|||||||
}
|
}
|
||||||
panel4.add(scrollButtonsPolicyToolBar, "cell 1 0");
|
panel4.add(scrollButtonsPolicyToolBar, "cell 1 0");
|
||||||
|
|
||||||
//---- scrollButtonsPlacementLabel ----
|
|
||||||
scrollButtonsPlacementLabel.setText("Scroll buttons placement:");
|
|
||||||
panel4.add(scrollButtonsPlacementLabel, "cell 2 0");
|
|
||||||
|
|
||||||
//======== scrollButtonsPlacementToolBar ========
|
|
||||||
{
|
|
||||||
scrollButtonsPlacementToolBar.setFloatable(false);
|
|
||||||
scrollButtonsPlacementToolBar.setBorder(BorderFactory.createEmptyBorder());
|
|
||||||
|
|
||||||
//---- scrollBothButton ----
|
|
||||||
scrollBothButton.setText("both");
|
|
||||||
scrollBothButton.setSelected(true);
|
|
||||||
scrollBothButton.putClientProperty("FlatLaf.styleClass", "small");
|
|
||||||
scrollBothButton.addActionListener(e -> scrollButtonsPlacementChanged());
|
|
||||||
scrollButtonsPlacementToolBar.add(scrollBothButton);
|
|
||||||
|
|
||||||
//---- scrollTrailingButton ----
|
|
||||||
scrollTrailingButton.setText("trailing");
|
|
||||||
scrollTrailingButton.putClientProperty("FlatLaf.styleClass", "small");
|
|
||||||
scrollTrailingButton.addActionListener(e -> scrollButtonsPlacementChanged());
|
|
||||||
scrollButtonsPlacementToolBar.add(scrollTrailingButton);
|
|
||||||
}
|
|
||||||
panel4.add(scrollButtonsPlacementToolBar, "cell 3 0");
|
|
||||||
|
|
||||||
//---- showTabSeparatorsCheckBox ----
|
|
||||||
showTabSeparatorsCheckBox.setText("Show tab separators");
|
|
||||||
showTabSeparatorsCheckBox.addActionListener(e -> showTabSeparatorsChanged());
|
|
||||||
panel4.add(showTabSeparatorsCheckBox, "cell 4 0");
|
|
||||||
|
|
||||||
//---- tabsPopupPolicyLabel ----
|
//---- tabsPopupPolicyLabel ----
|
||||||
tabsPopupPolicyLabel.setText("Tabs popup policy:");
|
tabsPopupPolicyLabel.setText("Tabs popup policy:");
|
||||||
panel4.add(tabsPopupPolicyLabel, "cell 0 1");
|
panel4.add(tabsPopupPolicyLabel, "cell 2 0");
|
||||||
|
|
||||||
//======== tabsPopupPolicyToolBar ========
|
//======== tabsPopupPolicyToolBar ========
|
||||||
{
|
{
|
||||||
@@ -821,7 +827,36 @@ class TabsPanel
|
|||||||
popupNeverButton.addActionListener(e -> tabsPopupPolicyChanged());
|
popupNeverButton.addActionListener(e -> tabsPopupPolicyChanged());
|
||||||
tabsPopupPolicyToolBar.add(popupNeverButton);
|
tabsPopupPolicyToolBar.add(popupNeverButton);
|
||||||
}
|
}
|
||||||
panel4.add(tabsPopupPolicyToolBar, "cell 1 1");
|
panel4.add(tabsPopupPolicyToolBar, "cell 3 0");
|
||||||
|
|
||||||
|
//---- showTabSeparatorsCheckBox ----
|
||||||
|
showTabSeparatorsCheckBox.setText("Show tab separators");
|
||||||
|
showTabSeparatorsCheckBox.addActionListener(e -> showTabSeparatorsChanged());
|
||||||
|
panel4.add(showTabSeparatorsCheckBox, "cell 4 0 2 1,alignx left,growx 0");
|
||||||
|
|
||||||
|
//---- scrollButtonsPlacementLabel ----
|
||||||
|
scrollButtonsPlacementLabel.setText("Scroll buttons placement:");
|
||||||
|
panel4.add(scrollButtonsPlacementLabel, "cell 0 1");
|
||||||
|
|
||||||
|
//======== scrollButtonsPlacementToolBar ========
|
||||||
|
{
|
||||||
|
scrollButtonsPlacementToolBar.setFloatable(false);
|
||||||
|
scrollButtonsPlacementToolBar.setBorder(BorderFactory.createEmptyBorder());
|
||||||
|
|
||||||
|
//---- scrollBothButton ----
|
||||||
|
scrollBothButton.setText("both");
|
||||||
|
scrollBothButton.setSelected(true);
|
||||||
|
scrollBothButton.putClientProperty("FlatLaf.styleClass", "small");
|
||||||
|
scrollBothButton.addActionListener(e -> scrollButtonsPlacementChanged());
|
||||||
|
scrollButtonsPlacementToolBar.add(scrollBothButton);
|
||||||
|
|
||||||
|
//---- scrollTrailingButton ----
|
||||||
|
scrollTrailingButton.setText("trailing");
|
||||||
|
scrollTrailingButton.putClientProperty("FlatLaf.styleClass", "small");
|
||||||
|
scrollTrailingButton.addActionListener(e -> scrollButtonsPlacementChanged());
|
||||||
|
scrollButtonsPlacementToolBar.add(scrollTrailingButton);
|
||||||
|
}
|
||||||
|
panel4.add(scrollButtonsPlacementToolBar, "cell 1 1");
|
||||||
|
|
||||||
//---- tabTypeLabel ----
|
//---- tabTypeLabel ----
|
||||||
tabTypeLabel.setText("Tab type:");
|
tabTypeLabel.setText("Tab type:");
|
||||||
@@ -845,8 +880,44 @@ class TabsPanel
|
|||||||
tabTypeToolBar.add(cardTabTypeButton);
|
tabTypeToolBar.add(cardTabTypeButton);
|
||||||
}
|
}
|
||||||
panel4.add(tabTypeToolBar, "cell 3 1");
|
panel4.add(tabTypeToolBar, "cell 3 1");
|
||||||
|
|
||||||
|
//---- tabRotationLabel ----
|
||||||
|
tabRotationLabel.setText("Tab rotation:");
|
||||||
|
panel4.add(tabRotationLabel, "cell 4 1");
|
||||||
|
|
||||||
|
//======== tabRotationToolBar ========
|
||||||
|
{
|
||||||
|
tabRotationToolBar.setFloatable(false);
|
||||||
|
tabRotationToolBar.setBorder(BorderFactory.createEmptyBorder());
|
||||||
|
|
||||||
|
//---- rotationNoneButton ----
|
||||||
|
rotationNoneButton.setText("none");
|
||||||
|
rotationNoneButton.setSelected(true);
|
||||||
|
rotationNoneButton.putClientProperty("FlatLaf.styleClass", "small");
|
||||||
|
rotationNoneButton.addActionListener(e -> tabRotationChanged());
|
||||||
|
tabRotationToolBar.add(rotationNoneButton);
|
||||||
|
|
||||||
|
//---- rotationAutoButton ----
|
||||||
|
rotationAutoButton.setText("auto");
|
||||||
|
rotationAutoButton.putClientProperty("FlatLaf.styleClass", "small");
|
||||||
|
rotationAutoButton.addActionListener(e -> tabRotationChanged());
|
||||||
|
tabRotationToolBar.add(rotationAutoButton);
|
||||||
|
|
||||||
|
//---- rotationLeftButton ----
|
||||||
|
rotationLeftButton.setText("left");
|
||||||
|
rotationLeftButton.putClientProperty("FlatLaf.styleClass", "small");
|
||||||
|
rotationLeftButton.addActionListener(e -> tabRotationChanged());
|
||||||
|
tabRotationToolBar.add(rotationLeftButton);
|
||||||
|
|
||||||
|
//---- rotationRightButton ----
|
||||||
|
rotationRightButton.setText("right");
|
||||||
|
rotationRightButton.putClientProperty("FlatLaf.styleClass", "small");
|
||||||
|
rotationRightButton.addActionListener(e -> tabRotationChanged());
|
||||||
|
tabRotationToolBar.add(rotationRightButton);
|
||||||
}
|
}
|
||||||
add(panel4, "cell 0 2 3 1");
|
panel4.add(tabRotationToolBar, "cell 5 1");
|
||||||
|
}
|
||||||
|
add(panel4, "cell 0 2");
|
||||||
|
|
||||||
//---- tabPlacementButtonGroup ----
|
//---- tabPlacementButtonGroup ----
|
||||||
ButtonGroup tabPlacementButtonGroup = new ButtonGroup();
|
ButtonGroup tabPlacementButtonGroup = new ButtonGroup();
|
||||||
@@ -872,20 +943,27 @@ class TabsPanel
|
|||||||
scrollButtonsPolicyButtonGroup.add(scrollAsNeededButton);
|
scrollButtonsPolicyButtonGroup.add(scrollAsNeededButton);
|
||||||
scrollButtonsPolicyButtonGroup.add(scrollNeverButton);
|
scrollButtonsPolicyButtonGroup.add(scrollNeverButton);
|
||||||
|
|
||||||
//---- scrollButtonsPlacementButtonGroup ----
|
|
||||||
ButtonGroup scrollButtonsPlacementButtonGroup = new ButtonGroup();
|
|
||||||
scrollButtonsPlacementButtonGroup.add(scrollBothButton);
|
|
||||||
scrollButtonsPlacementButtonGroup.add(scrollTrailingButton);
|
|
||||||
|
|
||||||
//---- tabsPopupPolicyButtonGroup ----
|
//---- tabsPopupPolicyButtonGroup ----
|
||||||
ButtonGroup tabsPopupPolicyButtonGroup = new ButtonGroup();
|
ButtonGroup tabsPopupPolicyButtonGroup = new ButtonGroup();
|
||||||
tabsPopupPolicyButtonGroup.add(popupAsNeededButton);
|
tabsPopupPolicyButtonGroup.add(popupAsNeededButton);
|
||||||
tabsPopupPolicyButtonGroup.add(popupNeverButton);
|
tabsPopupPolicyButtonGroup.add(popupNeverButton);
|
||||||
|
|
||||||
|
//---- scrollButtonsPlacementButtonGroup ----
|
||||||
|
ButtonGroup scrollButtonsPlacementButtonGroup = new ButtonGroup();
|
||||||
|
scrollButtonsPlacementButtonGroup.add(scrollBothButton);
|
||||||
|
scrollButtonsPlacementButtonGroup.add(scrollTrailingButton);
|
||||||
|
|
||||||
//---- tabTypeButtonGroup ----
|
//---- tabTypeButtonGroup ----
|
||||||
ButtonGroup tabTypeButtonGroup = new ButtonGroup();
|
ButtonGroup tabTypeButtonGroup = new ButtonGroup();
|
||||||
tabTypeButtonGroup.add(underlinedTabTypeButton);
|
tabTypeButtonGroup.add(underlinedTabTypeButton);
|
||||||
tabTypeButtonGroup.add(cardTabTypeButton);
|
tabTypeButtonGroup.add(cardTabTypeButton);
|
||||||
|
|
||||||
|
//---- tabRotationButtonGroup ----
|
||||||
|
ButtonGroup tabRotationButtonGroup = new ButtonGroup();
|
||||||
|
tabRotationButtonGroup.add(rotationNoneButton);
|
||||||
|
tabRotationButtonGroup.add(rotationAutoButton);
|
||||||
|
tabRotationButtonGroup.add(rotationLeftButton);
|
||||||
|
tabRotationButtonGroup.add(rotationRightButton);
|
||||||
// JFormDesigner - End of component initialization //GEN-END:initComponents
|
// JFormDesigner - End of component initialization //GEN-END:initComponents
|
||||||
|
|
||||||
if( FlatLafDemo.screenshotsMode ) {
|
if( FlatLafDemo.screenshotsMode ) {
|
||||||
@@ -961,18 +1039,24 @@ class TabsPanel
|
|||||||
private JToggleButton scrollAsNeededSingleButton;
|
private JToggleButton scrollAsNeededSingleButton;
|
||||||
private JToggleButton scrollAsNeededButton;
|
private JToggleButton scrollAsNeededButton;
|
||||||
private JToggleButton scrollNeverButton;
|
private JToggleButton scrollNeverButton;
|
||||||
private JLabel scrollButtonsPlacementLabel;
|
|
||||||
private JToolBar scrollButtonsPlacementToolBar;
|
|
||||||
private JToggleButton scrollBothButton;
|
|
||||||
private JToggleButton scrollTrailingButton;
|
|
||||||
private JCheckBox showTabSeparatorsCheckBox;
|
|
||||||
private JLabel tabsPopupPolicyLabel;
|
private JLabel tabsPopupPolicyLabel;
|
||||||
private JToolBar tabsPopupPolicyToolBar;
|
private JToolBar tabsPopupPolicyToolBar;
|
||||||
private JToggleButton popupAsNeededButton;
|
private JToggleButton popupAsNeededButton;
|
||||||
private JToggleButton popupNeverButton;
|
private JToggleButton popupNeverButton;
|
||||||
|
private JCheckBox showTabSeparatorsCheckBox;
|
||||||
|
private JLabel scrollButtonsPlacementLabel;
|
||||||
|
private JToolBar scrollButtonsPlacementToolBar;
|
||||||
|
private JToggleButton scrollBothButton;
|
||||||
|
private JToggleButton scrollTrailingButton;
|
||||||
private JLabel tabTypeLabel;
|
private JLabel tabTypeLabel;
|
||||||
private JToolBar tabTypeToolBar;
|
private JToolBar tabTypeToolBar;
|
||||||
private JToggleButton underlinedTabTypeButton;
|
private JToggleButton underlinedTabTypeButton;
|
||||||
private JToggleButton cardTabTypeButton;
|
private JToggleButton cardTabTypeButton;
|
||||||
|
private JLabel tabRotationLabel;
|
||||||
|
private JToolBar tabRotationToolBar;
|
||||||
|
private JToggleButton rotationNoneButton;
|
||||||
|
private JToggleButton rotationAutoButton;
|
||||||
|
private JToggleButton rotationLeftButton;
|
||||||
|
private JToggleButton rotationRightButton;
|
||||||
// JFormDesigner - End of variables declaration //GEN-END:variables
|
// JFormDesigner - End of variables declaration //GEN-END:variables
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,29 @@
|
|||||||
JFDML JFormDesigner: "7.0.5.0.404" Java: "17" encoding: "UTF-8"
|
JFDML JFormDesigner: "8.2.0.0.331" Java: "21" encoding: "UTF-8"
|
||||||
|
|
||||||
new FormModel {
|
new FormModel {
|
||||||
contentType: "form/swing"
|
contentType: "form/swing"
|
||||||
root: new FormRoot {
|
root: new FormRoot {
|
||||||
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 0,hidemode 3"
|
||||||
"$columnConstraints": "[grow,fill]para[fill]para[fill]"
|
"$columnConstraints": "[grow,fill]"
|
||||||
"$rowConstraints": "[grow,fill]para[][]"
|
"$rowConstraints": "[grow,fill]0[]0[]"
|
||||||
} ) {
|
} ) {
|
||||||
name: "this"
|
name: "this"
|
||||||
|
add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) {
|
||||||
|
name: "tabsScrollPane"
|
||||||
|
"border": new javax.swing.border.EmptyBorder( 0, 0, 0, 0 )
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": true
|
||||||
|
}
|
||||||
|
add( new FormContainer( "com.formdev.flatlaf.demo.ScrollablePanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
|
||||||
|
"$columnConstraints": "[grow,fill]para[fill]para[fill]"
|
||||||
|
"$rowConstraints": "[grow,fill]"
|
||||||
|
"$layoutConstraints": "insets dialog,hidemode 3"
|
||||||
|
} ) {
|
||||||
|
name: "panel6"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": true
|
||||||
|
}
|
||||||
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 0,hidemode 3"
|
"$layoutConstraints": "insets 0,hidemode 3"
|
||||||
"$columnConstraints": "[grow,fill]"
|
"$columnConstraints": "[grow,fill]"
|
||||||
@@ -396,7 +411,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 ) {
|
||||||
"$columnConstraints": "[grow,fill]para[fill]"
|
"$columnConstraints": "[grow,fill]para[fill]"
|
||||||
"$rowConstraints": "[][][][]"
|
"$rowConstraints": "[][][][][]"
|
||||||
"$layoutConstraints": "insets 0,hidemode 3"
|
"$layoutConstraints": "insets 0,hidemode 3"
|
||||||
} ) {
|
} ) {
|
||||||
name: "panel5"
|
name: "panel5"
|
||||||
@@ -431,7 +446,7 @@ new FormModel {
|
|||||||
name: "tabAlignVerticalTabbedPane"
|
name: "tabAlignVerticalTabbedPane"
|
||||||
"tabPlacement": 2
|
"tabPlacement": 2
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
"value": "cell 1 1 1 3,growy"
|
"value": "cell 1 1 1 4,growy"
|
||||||
} )
|
} )
|
||||||
add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) {
|
add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) {
|
||||||
name: "tabAlignCenterTabbedPane"
|
name: "tabAlignCenterTabbedPane"
|
||||||
@@ -449,14 +464,18 @@ new FormModel {
|
|||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
"value": "cell 2 0"
|
"value": "cell 2 0"
|
||||||
} )
|
} )
|
||||||
|
} )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 0"
|
||||||
|
} )
|
||||||
add( new FormComponent( "javax.swing.JSeparator" ) {
|
add( new FormComponent( "javax.swing.JSeparator" ) {
|
||||||
name: "separator2"
|
name: "separator2"
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
"value": "cell 0 1 3 1"
|
"value": "cell 0 1"
|
||||||
} )
|
} )
|
||||||
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 0,hidemode 3"
|
"$layoutConstraints": "insets panel,hidemode 3"
|
||||||
"$columnConstraints": "[][fill]para[fill][fill]para[fill]"
|
"$columnConstraints": "[][fill]para[fill][fill]para[fill][fill]"
|
||||||
"$rowConstraints": "[][center]"
|
"$rowConstraints": "[][center]"
|
||||||
} ) {
|
} ) {
|
||||||
name: "panel4"
|
name: "panel4"
|
||||||
@@ -498,49 +517,11 @@ new FormModel {
|
|||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
"value": "cell 1 0"
|
"value": "cell 1 0"
|
||||||
} )
|
} )
|
||||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
|
||||||
name: "scrollButtonsPlacementLabel"
|
|
||||||
"text": "Scroll buttons placement:"
|
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
|
||||||
"value": "cell 2 0"
|
|
||||||
} )
|
|
||||||
add( new FormContainer( "javax.swing.JToolBar", new FormLayoutManager( class javax.swing.JToolBar ) ) {
|
|
||||||
name: "scrollButtonsPlacementToolBar"
|
|
||||||
"floatable": false
|
|
||||||
"border": #EmptyBorder0
|
|
||||||
add( new FormComponent( "javax.swing.JToggleButton" ) {
|
|
||||||
name: "scrollBothButton"
|
|
||||||
"text": "both"
|
|
||||||
"selected": true
|
|
||||||
"$buttonGroup": new FormReference( "scrollButtonsPlacementButtonGroup" )
|
|
||||||
"$client.FlatLaf.styleClass": "small"
|
|
||||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "scrollButtonsPlacementChanged", false ) )
|
|
||||||
} )
|
|
||||||
add( new FormComponent( "javax.swing.JToggleButton" ) {
|
|
||||||
name: "scrollTrailingButton"
|
|
||||||
"text": "trailing"
|
|
||||||
"$buttonGroup": new FormReference( "scrollButtonsPlacementButtonGroup" )
|
|
||||||
"$client.FlatLaf.styleClass": "small"
|
|
||||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "scrollButtonsPlacementChanged", false ) )
|
|
||||||
} )
|
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
|
||||||
"value": "cell 3 0"
|
|
||||||
} )
|
|
||||||
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
|
||||||
name: "showTabSeparatorsCheckBox"
|
|
||||||
"text": "Show tab separators"
|
|
||||||
auxiliary() {
|
|
||||||
"JavaCodeGenerator.variableLocal": false
|
|
||||||
}
|
|
||||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "showTabSeparatorsChanged", false ) )
|
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
|
||||||
"value": "cell 4 0"
|
|
||||||
} )
|
|
||||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
name: "tabsPopupPolicyLabel"
|
name: "tabsPopupPolicyLabel"
|
||||||
"text": "Tabs popup policy:"
|
"text": "Tabs popup policy:"
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
"value": "cell 0 1"
|
"value": "cell 2 0"
|
||||||
} )
|
} )
|
||||||
add( new FormContainer( "javax.swing.JToolBar", new FormLayoutManager( class javax.swing.JToolBar ) ) {
|
add( new FormContainer( "javax.swing.JToolBar", new FormLayoutManager( class javax.swing.JToolBar ) ) {
|
||||||
name: "tabsPopupPolicyToolBar"
|
name: "tabsPopupPolicyToolBar"
|
||||||
@@ -561,6 +542,44 @@ new FormModel {
|
|||||||
"$client.FlatLaf.styleClass": "small"
|
"$client.FlatLaf.styleClass": "small"
|
||||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabsPopupPolicyChanged", false ) )
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabsPopupPolicyChanged", false ) )
|
||||||
} )
|
} )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 3 0"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JCheckBox" ) {
|
||||||
|
name: "showTabSeparatorsCheckBox"
|
||||||
|
"text": "Show tab separators"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "showTabSeparatorsChanged", false ) )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 4 0 2 1,alignx left,growx 0"
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "scrollButtonsPlacementLabel"
|
||||||
|
"text": "Scroll buttons placement:"
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 1"
|
||||||
|
} )
|
||||||
|
add( new FormContainer( "javax.swing.JToolBar", new FormLayoutManager( class javax.swing.JToolBar ) ) {
|
||||||
|
name: "scrollButtonsPlacementToolBar"
|
||||||
|
"floatable": false
|
||||||
|
"border": #EmptyBorder0
|
||||||
|
add( new FormComponent( "javax.swing.JToggleButton" ) {
|
||||||
|
name: "scrollBothButton"
|
||||||
|
"text": "both"
|
||||||
|
"selected": true
|
||||||
|
"$buttonGroup": new FormReference( "scrollButtonsPlacementButtonGroup" )
|
||||||
|
"$client.FlatLaf.styleClass": "small"
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "scrollButtonsPlacementChanged", false ) )
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JToggleButton" ) {
|
||||||
|
name: "scrollTrailingButton"
|
||||||
|
"text": "trailing"
|
||||||
|
"$buttonGroup": new FormReference( "scrollButtonsPlacementButtonGroup" )
|
||||||
|
"$client.FlatLaf.styleClass": "small"
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "scrollButtonsPlacementChanged", false ) )
|
||||||
|
} )
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
"value": "cell 1 1"
|
"value": "cell 1 1"
|
||||||
} )
|
} )
|
||||||
@@ -591,47 +610,94 @@ new FormModel {
|
|||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
"value": "cell 3 1"
|
"value": "cell 3 1"
|
||||||
} )
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
|
name: "tabRotationLabel"
|
||||||
|
"text": "Tab rotation:"
|
||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
"value": "cell 0 2 3 1"
|
"value": "cell 4 1"
|
||||||
|
} )
|
||||||
|
add( new FormContainer( "javax.swing.JToolBar", new FormLayoutManager( class javax.swing.JToolBar ) ) {
|
||||||
|
name: "tabRotationToolBar"
|
||||||
|
"floatable": false
|
||||||
|
"border": #EmptyBorder0
|
||||||
|
add( new FormComponent( "javax.swing.JToggleButton" ) {
|
||||||
|
name: "rotationNoneButton"
|
||||||
|
"text": "none"
|
||||||
|
"selected": true
|
||||||
|
"$client.FlatLaf.styleClass": "small"
|
||||||
|
"$buttonGroup": new FormReference( "tabRotationButtonGroup" )
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabRotationChanged", false ) )
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JToggleButton" ) {
|
||||||
|
name: "rotationAutoButton"
|
||||||
|
"text": "auto"
|
||||||
|
"$client.FlatLaf.styleClass": "small"
|
||||||
|
"$buttonGroup": new FormReference( "tabRotationButtonGroup" )
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabRotationChanged", false ) )
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JToggleButton" ) {
|
||||||
|
name: "rotationLeftButton"
|
||||||
|
"text": "left"
|
||||||
|
"$client.FlatLaf.styleClass": "small"
|
||||||
|
"$buttonGroup": new FormReference( "tabRotationButtonGroup" )
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabRotationChanged", false ) )
|
||||||
|
} )
|
||||||
|
add( new FormComponent( "javax.swing.JToggleButton" ) {
|
||||||
|
name: "rotationRightButton"
|
||||||
|
"text": "right"
|
||||||
|
"$client.FlatLaf.styleClass": "small"
|
||||||
|
"$buttonGroup": new FormReference( "tabRotationButtonGroup" )
|
||||||
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabRotationChanged", false ) )
|
||||||
|
} )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 5 1"
|
||||||
|
} )
|
||||||
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
|
"value": "cell 0 2"
|
||||||
} )
|
} )
|
||||||
}, 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( 1145, 895 )
|
"size": new java.awt.Dimension( 1145, 1045 )
|
||||||
} )
|
} )
|
||||||
add( new FormNonVisual( "javax.swing.ButtonGroup" ) {
|
add( new FormNonVisual( "javax.swing.ButtonGroup" ) {
|
||||||
name: "tabPlacementButtonGroup"
|
name: "tabPlacementButtonGroup"
|
||||||
}, new FormLayoutConstraints( null ) {
|
}, new FormLayoutConstraints( null ) {
|
||||||
"location": new java.awt.Point( 5, 915 )
|
"location": new java.awt.Point( 5, 1080 )
|
||||||
} )
|
} )
|
||||||
add( new FormNonVisual( "javax.swing.ButtonGroup" ) {
|
add( new FormNonVisual( "javax.swing.ButtonGroup" ) {
|
||||||
name: "closableTabsButtonGroup"
|
name: "closableTabsButtonGroup"
|
||||||
}, new FormLayoutConstraints( null ) {
|
}, new FormLayoutConstraints( null ) {
|
||||||
"location": new java.awt.Point( 5, 970 )
|
"location": new java.awt.Point( 5, 1135 )
|
||||||
} )
|
} )
|
||||||
add( new FormNonVisual( "javax.swing.ButtonGroup" ) {
|
add( new FormNonVisual( "javax.swing.ButtonGroup" ) {
|
||||||
name: "tabLayoutButtonGroup"
|
name: "tabLayoutButtonGroup"
|
||||||
}, new FormLayoutConstraints( null ) {
|
}, new FormLayoutConstraints( null ) {
|
||||||
"location": new java.awt.Point( 5, 1020 )
|
"location": new java.awt.Point( 5, 1185 )
|
||||||
} )
|
} )
|
||||||
add( new FormNonVisual( "javax.swing.ButtonGroup" ) {
|
add( new FormNonVisual( "javax.swing.ButtonGroup" ) {
|
||||||
name: "tabsPopupPolicyButtonGroup"
|
name: "tabsPopupPolicyButtonGroup"
|
||||||
}, new FormLayoutConstraints( null ) {
|
}, new FormLayoutConstraints( null ) {
|
||||||
"location": new java.awt.Point( 200, 915 )
|
"location": new java.awt.Point( 200, 1080 )
|
||||||
} )
|
} )
|
||||||
add( new FormNonVisual( "javax.swing.ButtonGroup" ) {
|
add( new FormNonVisual( "javax.swing.ButtonGroup" ) {
|
||||||
name: "scrollButtonsPolicyButtonGroup"
|
name: "scrollButtonsPolicyButtonGroup"
|
||||||
}, new FormLayoutConstraints( null ) {
|
}, new FormLayoutConstraints( null ) {
|
||||||
"location": new java.awt.Point( 200, 965 )
|
"location": new java.awt.Point( 200, 1130 )
|
||||||
} )
|
} )
|
||||||
add( new FormNonVisual( "javax.swing.ButtonGroup" ) {
|
add( new FormNonVisual( "javax.swing.ButtonGroup" ) {
|
||||||
name: "scrollButtonsPlacementButtonGroup"
|
name: "scrollButtonsPlacementButtonGroup"
|
||||||
}, new FormLayoutConstraints( null ) {
|
}, new FormLayoutConstraints( null ) {
|
||||||
"location": new java.awt.Point( 200, 1020 )
|
"location": new java.awt.Point( 200, 1185 )
|
||||||
} )
|
} )
|
||||||
add( new FormNonVisual( "javax.swing.ButtonGroup" ) {
|
add( new FormNonVisual( "javax.swing.ButtonGroup" ) {
|
||||||
name: "tabTypeButtonGroup"
|
name: "tabTypeButtonGroup"
|
||||||
}, new FormLayoutConstraints( null ) {
|
}, new FormLayoutConstraints( null ) {
|
||||||
"location": new java.awt.Point( 0, 1072 )
|
"location": new java.awt.Point( 0, 1235 )
|
||||||
|
} )
|
||||||
|
add( new FormNonVisual( "javax.swing.ButtonGroup" ) {
|
||||||
|
name: "tabRotationButtonGroup"
|
||||||
|
}, new FormLayoutConstraints( null ) {
|
||||||
|
"location": new java.awt.Point( 200, 1235 )
|
||||||
} )
|
} )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ build script:
|
|||||||
artifactId: flatlaf-extras
|
artifactId: flatlaf-extras
|
||||||
version: (see button below)
|
version: (see button below)
|
||||||
|
|
||||||
Otherwise download `flatlaf-extras-<version>.jar` here:
|
Otherwise, download `flatlaf-extras-<version>.jar` here:
|
||||||
|
|
||||||
[](https://maven-badges.herokuapp.com/maven-central/com.formdev/flatlaf-extras)
|
[](https://maven-badges.herokuapp.com/maven-central/com.formdev/flatlaf-extras)
|
||||||
|
|
||||||
|
|||||||
@@ -133,8 +133,8 @@ public class FlatAnimatedLafChange
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts an animation that shows the snapshot (created by {@link #showSnapshot()}
|
* Starts an animation that shows the snapshot (created by {@link #showSnapshot()})
|
||||||
* with an decreasing alpha. At the end, the snapshot is removed and the new UI is shown.
|
* with a decreasing alpha. At the end, the snapshot is removed and the new UI is shown.
|
||||||
* Invoke after updating UI.
|
* Invoke after updating UI.
|
||||||
*/
|
*/
|
||||||
public static void hideSnapshotWithAnimation() {
|
public static void hideSnapshotWithAnimation() {
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ public class FlatDesktop
|
|||||||
(proxy, method, args) -> {
|
(proxy, method, args) -> {
|
||||||
// Use invokeLater to release the listener firing for the case
|
// Use invokeLater to release the listener firing for the case
|
||||||
// that the action listener shows a modal dialog.
|
// that the action listener shows a modal dialog.
|
||||||
// This (hopefully) prevents application hunging.
|
// This (hopefully) prevents application hanging.
|
||||||
EventQueue.invokeLater( () -> {
|
EventQueue.invokeLater( () -> {
|
||||||
handler.run();
|
handler.run();
|
||||||
} );
|
} );
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ public class FlatSVGIcon
|
|||||||
* in the tag {@code <svg>} are used as icon size.
|
* in the tag {@code <svg>} are used as icon size.
|
||||||
* <p>
|
* <p>
|
||||||
* If using Java modules, the package containing the icon must be opened in {@code module-info.java}.
|
* If using Java modules, the package containing the icon must be opened in {@code module-info.java}.
|
||||||
* Otherwise use {@link #FlatSVGIcon(URL)}.
|
* Otherwise, use {@link #FlatSVGIcon(URL)}.
|
||||||
* <p>
|
* <p>
|
||||||
* This is cheap operation because the icon is only loaded when used.
|
* This is cheap operation because the icon is only loaded when used.
|
||||||
*
|
*
|
||||||
@@ -106,7 +106,7 @@ public class FlatSVGIcon
|
|||||||
* in the tag {@code <svg>} are used as icon size.
|
* in the tag {@code <svg>} are used as icon size.
|
||||||
* <p>
|
* <p>
|
||||||
* If using Java modules, the package containing the icon must be opened in {@code module-info.java}.
|
* If using Java modules, the package containing the icon must be opened in {@code module-info.java}.
|
||||||
* Otherwise use {@link #FlatSVGIcon(URL)}.
|
* Otherwise, use {@link #FlatSVGIcon(URL)}.
|
||||||
* <p>
|
* <p>
|
||||||
* This is cheap operation because the icon is only loaded when used.
|
* This is cheap operation because the icon is only loaded when used.
|
||||||
*
|
*
|
||||||
@@ -124,7 +124,7 @@ public class FlatSVGIcon
|
|||||||
* The icon is scaled if the given size is different to the size specified in the SVG file.
|
* The icon is scaled if the given size is different to the size specified in the SVG file.
|
||||||
* <p>
|
* <p>
|
||||||
* If using Java modules, the package containing the icon must be opened in {@code module-info.java}.
|
* If using Java modules, the package containing the icon must be opened in {@code module-info.java}.
|
||||||
* Otherwise use {@link #FlatSVGIcon(URL)}.
|
* Otherwise, use {@link #FlatSVGIcon(URL)}.
|
||||||
* <p>
|
* <p>
|
||||||
* This is cheap operation because the icon is only loaded when used.
|
* This is cheap operation because the icon is only loaded when used.
|
||||||
*
|
*
|
||||||
@@ -144,7 +144,7 @@ public class FlatSVGIcon
|
|||||||
* The icon is scaled if the given size is different to the size specified in the SVG file.
|
* The icon is scaled if the given size is different to the size specified in the SVG file.
|
||||||
* <p>
|
* <p>
|
||||||
* If using Java modules, the package containing the icon must be opened in {@code module-info.java}.
|
* If using Java modules, the package containing the icon must be opened in {@code module-info.java}.
|
||||||
* Otherwise use {@link #FlatSVGIcon(URL)}.
|
* Otherwise, use {@link #FlatSVGIcon(URL)}.
|
||||||
* <p>
|
* <p>
|
||||||
* This is cheap operation because the icon is only loaded when used.
|
* This is cheap operation because the icon is only loaded when used.
|
||||||
*
|
*
|
||||||
@@ -166,7 +166,7 @@ public class FlatSVGIcon
|
|||||||
* by the given scale factor.
|
* by the given scale factor.
|
||||||
* <p>
|
* <p>
|
||||||
* If using Java modules, the package containing the icon must be opened in {@code module-info.java}.
|
* If using Java modules, the package containing the icon must be opened in {@code module-info.java}.
|
||||||
* Otherwise use {@link #FlatSVGIcon(URL)}.
|
* Otherwise, use {@link #FlatSVGIcon(URL)}.
|
||||||
* <p>
|
* <p>
|
||||||
* This is cheap operation because the icon is only loaded when used.
|
* This is cheap operation because the icon is only loaded when used.
|
||||||
*
|
*
|
||||||
@@ -187,7 +187,7 @@ public class FlatSVGIcon
|
|||||||
* by the given scale factor.
|
* by the given scale factor.
|
||||||
* <p>
|
* <p>
|
||||||
* If using Java modules, the package containing the icon must be opened in {@code module-info.java}.
|
* If using Java modules, the package containing the icon must be opened in {@code module-info.java}.
|
||||||
* Otherwise use {@link #FlatSVGIcon(URL)}.
|
* Otherwise, use {@link #FlatSVGIcon(URL)}.
|
||||||
* <p>
|
* <p>
|
||||||
* This is cheap operation because the icon is only loaded when used.
|
* This is cheap operation because the icon is only loaded when used.
|
||||||
*
|
*
|
||||||
@@ -259,7 +259,7 @@ public class FlatSVGIcon
|
|||||||
* <p>
|
* <p>
|
||||||
* The input stream is loaded, parsed and closed immediately.
|
* The input stream is loaded, parsed and closed immediately.
|
||||||
*
|
*
|
||||||
* @param in the input stream for reading a SVG resource
|
* @param in the input stream for reading an SVG resource
|
||||||
* @throws IOException if an I/O exception occurs
|
* @throws IOException if an I/O exception occurs
|
||||||
* @since 2
|
* @since 2
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -46,10 +46,10 @@ public class FlatSVGUtils
|
|||||||
* then a single multi-resolution image is returned that creates images on demand
|
* then a single multi-resolution image is returned that creates images on demand
|
||||||
* for requested sizes from SVG.
|
* for requested sizes from SVG.
|
||||||
* This has the advantage that only images for used sizes are created.
|
* This has the advantage that only images for used sizes are created.
|
||||||
* Also if unusual sizes are requested (e.g. 18x18), then they are created from SVG.
|
* Also, if unusual sizes are requested (e.g. 18x18), then they are created from SVG.
|
||||||
* <p>
|
* <p>
|
||||||
* If using Java modules, the package containing the SVG must be opened in {@code module-info.java}.
|
* If using Java modules, the package containing the SVG must be opened in {@code module-info.java}.
|
||||||
* Otherwise use {@link #createWindowIconImages(URL)}.
|
* Otherwise, use {@link #createWindowIconImages(URL)}.
|
||||||
*
|
*
|
||||||
* @param svgName the name of the SVG resource (a '/'-separated path)
|
* @param svgName the name of the SVG resource (a '/'-separated path)
|
||||||
* @return list of icon images with different sizes (16x16, 20x20, 24x24, 28x28, 32x32, 48x48 and 64x64)
|
* @return list of icon images with different sizes (16x16, 20x20, 24x24, 28x28, 32x32, 48x48 and 64x64)
|
||||||
@@ -69,7 +69,7 @@ public class FlatSVGUtils
|
|||||||
* then a single multi-resolution image is returned that creates images on demand
|
* then a single multi-resolution image is returned that creates images on demand
|
||||||
* for requested sizes from SVG.
|
* for requested sizes from SVG.
|
||||||
* This has the advantage that only images for used sizes are created.
|
* This has the advantage that only images for used sizes are created.
|
||||||
* Also if unusual sizes are requested (e.g. 18x18), then they are created from SVG.
|
* Also, if unusual sizes are requested (e.g. 18x18), then they are created from SVG.
|
||||||
* <p>
|
* <p>
|
||||||
* This method is useful if using Java modules and the package containing the SVG
|
* This method is useful if using Java modules and the package containing the SVG
|
||||||
* is not opened in {@code module-info.java}.
|
* is not opened in {@code module-info.java}.
|
||||||
@@ -92,7 +92,7 @@ public class FlatSVGUtils
|
|||||||
// any size is created on demand when
|
// any size is created on demand when
|
||||||
// MultiResolutionImage.getResolutionVariant(double destImageWidth, double destImageHeight)
|
// MultiResolutionImage.getResolutionVariant(double destImageWidth, double destImageHeight)
|
||||||
// is invoked.
|
// is invoked.
|
||||||
// This sizes are only used by MultiResolutionImage.getResolutionVariants().
|
// These sizes are only used by MultiResolutionImage.getResolutionVariants().
|
||||||
new Dimension( 16, 16 ), // 100%
|
new Dimension( 16, 16 ), // 100%
|
||||||
new Dimension( 20, 20 ), // 125%
|
new Dimension( 20, 20 ), // 125%
|
||||||
new Dimension( 24, 24 ), // 150%
|
new Dimension( 24, 24 ), // 150%
|
||||||
@@ -120,7 +120,7 @@ public class FlatSVGUtils
|
|||||||
* Creates a buffered image and renders the given SVG into it.
|
* Creates a buffered image and renders the given SVG into it.
|
||||||
* <p>
|
* <p>
|
||||||
* If using Java modules, the package containing the SVG must be opened in {@code module-info.java}.
|
* If using Java modules, the package containing the SVG must be opened in {@code module-info.java}.
|
||||||
* Otherwise use {@link #svg2image(URL, int, int)}.
|
* Otherwise, use {@link #svg2image(URL, int, int)}.
|
||||||
*
|
*
|
||||||
* @param svgName the name of the SVG resource (a '/'-separated path)
|
* @param svgName the name of the SVG resource (a '/'-separated path)
|
||||||
* @param width the width of the image
|
* @param width the width of the image
|
||||||
@@ -154,7 +154,7 @@ public class FlatSVGUtils
|
|||||||
* Creates a buffered image and renders the given SVG into it.
|
* Creates a buffered image and renders the given SVG into it.
|
||||||
* <p>
|
* <p>
|
||||||
* If using Java modules, the package containing the SVG must be opened in {@code module-info.java}.
|
* If using Java modules, the package containing the SVG must be opened in {@code module-info.java}.
|
||||||
* Otherwise use {@link #svg2image(URL, float)}.
|
* Otherwise, use {@link #svg2image(URL, float)}.
|
||||||
*
|
*
|
||||||
* @param svgName the name of the SVG resource (a '/'-separated path)
|
* @param svgName the name of the SVG resource (a '/'-separated path)
|
||||||
* @param scaleFactor the amount by which the SVG size is scaled
|
* @param scaleFactor the amount by which the SVG size is scaled
|
||||||
|
|||||||
@@ -557,7 +557,7 @@ public class FlatUIDefaultsInspector
|
|||||||
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
|
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
|
||||||
panel = new JPanel();
|
panel = new JPanel();
|
||||||
filterPanel = new JPanel();
|
filterPanel = new JPanel();
|
||||||
flterLabel = new JLabel();
|
filterLabel = new JLabel();
|
||||||
filterField = new FlatTextField();
|
filterField = new FlatTextField();
|
||||||
valueTypeLabel = new JLabel();
|
valueTypeLabel = new JLabel();
|
||||||
valueTypeField = new JComboBox<>();
|
valueTypeField = new JComboBox<>();
|
||||||
@@ -580,11 +580,11 @@ public class FlatUIDefaultsInspector
|
|||||||
((GridBagLayout)filterPanel.getLayout()).columnWeights = new double[] {0.0, 1.0, 0.0, 0.0, 1.0E-4};
|
((GridBagLayout)filterPanel.getLayout()).columnWeights = new double[] {0.0, 1.0, 0.0, 0.0, 1.0E-4};
|
||||||
((GridBagLayout)filterPanel.getLayout()).rowWeights = new double[] {0.0, 1.0E-4};
|
((GridBagLayout)filterPanel.getLayout()).rowWeights = new double[] {0.0, 1.0E-4};
|
||||||
|
|
||||||
//---- flterLabel ----
|
//---- filterLabel ----
|
||||||
flterLabel.setText("Filter:");
|
filterLabel.setText("Filter:");
|
||||||
flterLabel.setLabelFor(filterField);
|
filterLabel.setLabelFor(filterField);
|
||||||
flterLabel.setDisplayedMnemonic('F');
|
filterLabel.setDisplayedMnemonic('F');
|
||||||
filterPanel.add(flterLabel, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0,
|
filterPanel.add(filterLabel, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0,
|
||||||
GridBagConstraints.CENTER, GridBagConstraints.BOTH,
|
GridBagConstraints.CENTER, GridBagConstraints.BOTH,
|
||||||
new Insets(0, 0, 0, 10), 0, 0));
|
new Insets(0, 0, 0, 10), 0, 0));
|
||||||
|
|
||||||
@@ -668,7 +668,7 @@ public class FlatUIDefaultsInspector
|
|||||||
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
|
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
|
||||||
private JPanel panel;
|
private JPanel panel;
|
||||||
private JPanel filterPanel;
|
private JPanel filterPanel;
|
||||||
private JLabel flterLabel;
|
private JLabel filterLabel;
|
||||||
private FlatTextField filterField;
|
private FlatTextField filterField;
|
||||||
private JLabel valueTypeLabel;
|
private JLabel valueTypeLabel;
|
||||||
private JComboBox<String> valueTypeField;
|
private JComboBox<String> valueTypeField;
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ new FormModel {
|
|||||||
} ) {
|
} ) {
|
||||||
name: "filterPanel"
|
name: "filterPanel"
|
||||||
add( new FormComponent( "javax.swing.JLabel" ) {
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
name: "flterLabel"
|
name: "filterLabel"
|
||||||
"text": "Filter:"
|
"text": "Filter:"
|
||||||
"labelFor": new FormReference( "filterField" )
|
"labelFor": new FormReference( "filterField" )
|
||||||
"displayedMnemonic": 70
|
"displayedMnemonic": 70
|
||||||
|
|||||||
@@ -33,14 +33,14 @@ public class FlatButton
|
|||||||
public enum ButtonType { none, square, roundRect, tab, help, toolBarButton, borderless }
|
public enum ButtonType { none, square, roundRect, tab, help, toolBarButton, borderless }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns type of a button.
|
* Returns type of button.
|
||||||
*/
|
*/
|
||||||
public ButtonType getButtonType() {
|
public ButtonType getButtonType() {
|
||||||
return getClientPropertyEnumString( BUTTON_TYPE, ButtonType.class, null, ButtonType.none );
|
return getClientPropertyEnumString( BUTTON_TYPE, ButtonType.class, null, ButtonType.none );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies type of a button.
|
* Specifies type of button.
|
||||||
*/
|
*/
|
||||||
public void setButtonType( ButtonType buttonType ) {
|
public void setButtonType( ButtonType buttonType ) {
|
||||||
if( buttonType == ButtonType.none )
|
if( buttonType == ButtonType.none )
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ public class FlatFormattedTextField
|
|||||||
* The component should be not opaque because the text field border is painted
|
* The component should be not opaque because the text field border is painted
|
||||||
* slightly inside the usually visible border in some cases.
|
* slightly inside the usually visible border in some cases.
|
||||||
* E.g. when focused (in some themes) or when an outline color is specified
|
* E.g. when focused (in some themes) or when an outline color is specified
|
||||||
* (see {@link #setOutline(Object)}.
|
* (see {@link #setOutline(Object)}).
|
||||||
*
|
*
|
||||||
* @since 2
|
* @since 2
|
||||||
*/
|
*/
|
||||||
@@ -135,7 +135,7 @@ public class FlatFormattedTextField
|
|||||||
* The component should be not opaque because the text field border is painted
|
* The component should be not opaque because the text field border is painted
|
||||||
* slightly inside the usually visible border in some cases.
|
* slightly inside the usually visible border in some cases.
|
||||||
* E.g. when focused (in some themes) or when an outline color is specified
|
* E.g. when focused (in some themes) or when an outline color is specified
|
||||||
* (see {@link #setOutline(Object)}.
|
* (see {@link #setOutline(Object)}).
|
||||||
*
|
*
|
||||||
* @since 2
|
* @since 2
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ public class FlatPasswordField
|
|||||||
* The component should be not opaque because the text field border is painted
|
* The component should be not opaque because the text field border is painted
|
||||||
* slightly inside the usually visible border in some cases.
|
* slightly inside the usually visible border in some cases.
|
||||||
* E.g. when focused (in some themes) or when an outline color is specified
|
* E.g. when focused (in some themes) or when an outline color is specified
|
||||||
* (see {@link #setOutline(Object)}.
|
* (see {@link #setOutline(Object)}).
|
||||||
*
|
*
|
||||||
* @since 2
|
* @since 2
|
||||||
*/
|
*/
|
||||||
@@ -135,7 +135,7 @@ public class FlatPasswordField
|
|||||||
* The component should be not opaque because the text field border is painted
|
* The component should be not opaque because the text field border is painted
|
||||||
* slightly inside the usually visible border in some cases.
|
* slightly inside the usually visible border in some cases.
|
||||||
* E.g. when focused (in some themes) or when an outline color is specified
|
* E.g. when focused (in some themes) or when an outline color is specified
|
||||||
* (see {@link #setOutline(Object)}.
|
* (see {@link #setOutline(Object)}).
|
||||||
*
|
*
|
||||||
* @since 2
|
* @since 2
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -502,6 +502,29 @@ public class FlatTabbedPane
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// NOTE: enum names must be equal to allowed strings
|
||||||
|
/** @since 3.3 */ public enum TabRotation { none, auto, left, right }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns how the tabs should be rotated.
|
||||||
|
*
|
||||||
|
* @since 3.3
|
||||||
|
*/
|
||||||
|
public TabRotation getTabRotation() {
|
||||||
|
return getClientPropertyEnumString( TABBED_PANE_TAB_ROTATION, TabRotation.class,
|
||||||
|
"TabbedPane.tabRotation", TabRotation.none );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies how the tabs should be rotated.
|
||||||
|
*
|
||||||
|
* @since 3.3
|
||||||
|
*/
|
||||||
|
public void setTabRotation( TabRotation tabRotation ) {
|
||||||
|
putClientPropertyEnumString( TABBED_PANE_TAB_ROTATION, tabRotation );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the tab icon placement (relative to tab title).
|
* Returns the tab icon placement (relative to tab title).
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ public class FlatTextField
|
|||||||
* The component should be not opaque because the text field border is painted
|
* The component should be not opaque because the text field border is painted
|
||||||
* slightly inside the usually visible border in some cases.
|
* slightly inside the usually visible border in some cases.
|
||||||
* E.g. when focused (in some themes) or when an outline color is specified
|
* E.g. when focused (in some themes) or when an outline color is specified
|
||||||
* (see {@link #setOutline(Object)}.
|
* (see {@link #setOutline(Object)}).
|
||||||
*
|
*
|
||||||
* @since 2
|
* @since 2
|
||||||
*/
|
*/
|
||||||
@@ -134,7 +134,7 @@ public class FlatTextField
|
|||||||
* The component should be not opaque because the text field border is painted
|
* The component should be not opaque because the text field border is painted
|
||||||
* slightly inside the usually visible border in some cases.
|
* slightly inside the usually visible border in some cases.
|
||||||
* E.g. when focused (in some themes) or when an outline color is specified
|
* E.g. when focused (in some themes) or when an outline color is specified
|
||||||
* (see {@link #setOutline(Object)}.
|
* (see {@link #setOutline(Object)}).
|
||||||
*
|
*
|
||||||
* @since 2
|
* @since 2
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -31,14 +31,14 @@ public class FlatToggleButton
|
|||||||
implements FlatComponentExtension, FlatStyleableComponent
|
implements FlatComponentExtension, FlatStyleableComponent
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Returns type of a button.
|
* Returns type of button.
|
||||||
*/
|
*/
|
||||||
public ButtonType getButtonType() {
|
public ButtonType getButtonType() {
|
||||||
return getClientPropertyEnumString( BUTTON_TYPE, ButtonType.class, null, ButtonType.none );
|
return getClientPropertyEnumString( BUTTON_TYPE, ButtonType.class, null, ButtonType.none );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies type of a button.
|
* Specifies type of button.
|
||||||
*/
|
*/
|
||||||
public void setButtonType( ButtonType buttonType ) {
|
public void setButtonType( ButtonType buttonType ) {
|
||||||
if( buttonType == ButtonType.none )
|
if( buttonType == ButtonType.none )
|
||||||
|
|||||||
@@ -30,8 +30,8 @@ import com.formdev.flatlaf.FlatLaf;
|
|||||||
* <p>
|
* <p>
|
||||||
* The initial state is {@link State#INDETERMINATE}.
|
* The initial state is {@link State#INDETERMINATE}.
|
||||||
* <p>
|
* <p>
|
||||||
* By default the third state is allowed and clicking on the checkbox cycles thru all
|
* By default, the third state is allowed and clicking on the checkbox cycles through all
|
||||||
* three states. If you want that the user can cycle only thru two states, disallow
|
* three states. If you want that the user can cycle only through two states, disallow
|
||||||
* intermediate state using {@link #setAllowIndeterminate(boolean)}. Then you can still
|
* intermediate state using {@link #setAllowIndeterminate(boolean)}. Then you can still
|
||||||
* set the indeterminate state via API if necessary, but the user can not.
|
* set the indeterminate state via API if necessary, but the user can not.
|
||||||
* <p>
|
* <p>
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ package com.formdev.flatlaf.extras.resources;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The only purpose of this file is to add a .class file to this package to make it non-empty.
|
* The only purpose of this file is to add a .class file to this package to make it non-empty.
|
||||||
* Otherwise the compiler outputs a warning because this package is opend in module-info.java.
|
* Otherwise, the compiler outputs a warning because this package is opened in module-info.java.
|
||||||
* Also when using --patch-module (e.g. from an IDE), an error would occur for empty packages.
|
* Also, when using --patch-module (e.g. from an IDE), an error would occur for empty packages.
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -175,6 +175,9 @@ Spinner.buttonPressedArrowColor = Spinner.buttonArrowColor
|
|||||||
|
|
||||||
#---- SplitPaneDivider ----
|
#---- SplitPaneDivider ----
|
||||||
|
|
||||||
|
SplitPaneDivider.draggingColor = SplitPane.background
|
||||||
|
SplitPaneDivider.hoverColor = SplitPane.background
|
||||||
|
SplitPaneDivider.pressedColor = SplitPane.background
|
||||||
SplitPaneDivider.oneTouchHoverArrowColor = SplitPaneDivider.oneTouchArrowColor
|
SplitPaneDivider.oneTouchHoverArrowColor = SplitPaneDivider.oneTouchArrowColor
|
||||||
SplitPaneDivider.oneTouchPressedArrowColor = SplitPaneDivider.oneTouchArrowColor
|
SplitPaneDivider.oneTouchPressedArrowColor = SplitPaneDivider.oneTouchArrowColor
|
||||||
|
|
||||||
|
|||||||
@@ -100,6 +100,6 @@ build script:
|
|||||||
artifactId: flatlaf-fonts-inter
|
artifactId: flatlaf-fonts-inter
|
||||||
version: (see button below)
|
version: (see button below)
|
||||||
|
|
||||||
Otherwise download `flatlaf-fonts-inter-<version>.jar` here:
|
Otherwise, download `flatlaf-fonts-inter-<version>.jar` here:
|
||||||
|
|
||||||
[](https://maven-badges.herokuapp.com/maven-central/com.formdev/flatlaf-fonts-inter)
|
[](https://maven-badges.herokuapp.com/maven-central/com.formdev/flatlaf-fonts-inter)
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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:
|
||||||
|
|||||||
@@ -81,6 +81,6 @@ build script:
|
|||||||
artifactId: flatlaf-fonts-jetbrains-mono
|
artifactId: flatlaf-fonts-jetbrains-mono
|
||||||
version: (see button below)
|
version: (see button below)
|
||||||
|
|
||||||
Otherwise download `flatlaf-fonts-jetbrains-mono-<version>.jar` here:
|
Otherwise, download `flatlaf-fonts-jetbrains-mono-<version>.jar` here:
|
||||||
|
|
||||||
[](https://maven-badges.herokuapp.com/maven-central/com.formdev/flatlaf-fonts-jetbrains-mono)
|
[](https://maven-badges.herokuapp.com/maven-central/com.formdev/flatlaf-fonts-jetbrains-mono)
|
||||||
|
|||||||
@@ -81,6 +81,6 @@ build script:
|
|||||||
artifactId: flatlaf-fonts-roboto-mono
|
artifactId: flatlaf-fonts-roboto-mono
|
||||||
version: (see button below)
|
version: (see button below)
|
||||||
|
|
||||||
Otherwise download `flatlaf-fonts-roboto-mono-<version>.jar` here:
|
Otherwise, download `flatlaf-fonts-roboto-mono-<version>.jar` here:
|
||||||
|
|
||||||
[](https://maven-badges.herokuapp.com/maven-central/com.formdev/flatlaf-fonts-roboto-mono)
|
[](https://maven-badges.herokuapp.com/maven-central/com.formdev/flatlaf-fonts-roboto-mono)
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user