mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2026-02-12 06:57:13 -06:00
Compare commits
94 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f842530537 | ||
|
|
63077bbb19 | ||
|
|
4dad337377 | ||
|
|
10a965d765 | ||
|
|
3e9c9c9066 | ||
|
|
8b5a738e65 | ||
|
|
2c041dce3a | ||
|
|
ef151c68f4 | ||
|
|
52feaac92a | ||
|
|
cddbb3d7d4 | ||
|
|
42764550e6 | ||
|
|
6ee737b314 | ||
|
|
f460ef7685 | ||
|
|
9977bcb468 | ||
|
|
7437d984c7 | ||
|
|
5cd0b2403c | ||
|
|
a372da22f3 | ||
|
|
8b10d3ba5a | ||
|
|
a8b15c6a12 | ||
|
|
23bac7e5fd | ||
|
|
b82ee2ef61 | ||
|
|
b7761f4b71 | ||
|
|
f9a4f9771c | ||
|
|
d2acb2c98a | ||
|
|
d60bd5df14 | ||
|
|
73b6ca3762 | ||
|
|
6c18431a30 | ||
|
|
a49d20249f | ||
|
|
ad384acd57 | ||
|
|
69851b7f3a | ||
|
|
92b53bf0df | ||
|
|
93e0496fd2 | ||
|
|
5151951f46 | ||
|
|
58dbccec2d | ||
|
|
90de14d013 | ||
|
|
5f961618bf | ||
|
|
37c375e2fa | ||
|
|
1758c175ed | ||
|
|
96f2a02cfa | ||
|
|
96d4bda6c8 | ||
|
|
02cf6050a1 | ||
|
|
38cf32a2e9 | ||
|
|
2ae7589d14 | ||
|
|
bcb2e1f0a1 | ||
|
|
14932d3f07 | ||
|
|
c3b9dc397d | ||
|
|
58b653f55d | ||
|
|
1dcdc42dde | ||
|
|
58a0a16985 | ||
|
|
a117243f14 | ||
|
|
22411060be | ||
|
|
045263ae58 | ||
|
|
024b6daaf6 | ||
|
|
bd5512c121 | ||
|
|
9afce83a02 | ||
|
|
07a8bd9486 | ||
|
|
bcdc0a8fce | ||
|
|
b295809432 | ||
|
|
52763ab932 | ||
|
|
99666265c9 | ||
|
|
af3e280d74 | ||
|
|
b57e4c0565 | ||
|
|
aca9931560 | ||
|
|
d09e166e4a | ||
|
|
68a7a60ff2 | ||
|
|
f21261914b | ||
|
|
7b11339fdc | ||
|
|
081fd43d98 | ||
|
|
ef2eedfc7c | ||
|
|
0dba9265be | ||
|
|
301aae9b8e | ||
|
|
c63f4e9662 | ||
|
|
47508dc6ac | ||
|
|
3a8879608a | ||
|
|
b221889549 | ||
|
|
c00d99b85f | ||
|
|
0bf87b753d | ||
|
|
53f2730064 | ||
|
|
d487c3b005 | ||
|
|
fef6ae7ff7 | ||
|
|
f6b42754de | ||
|
|
2ae9bb381d | ||
|
|
53bde84710 | ||
|
|
d006ac27ff | ||
|
|
c478d28b71 | ||
|
|
99f7b9ad84 | ||
|
|
ab58101ce3 | ||
|
|
d8f3682dc0 | ||
|
|
1fec7ba553 | ||
|
|
418f55f34e | ||
|
|
05d795b2ae | ||
|
|
a365b750d9 | ||
|
|
0aecfb565f | ||
|
|
0cf4edd9e5 |
14
.github/workflows/ci.yml
vendored
14
.github/workflows/ci.yml
vendored
@@ -28,13 +28,13 @@ jobs:
|
|||||||
- 17 # LTS
|
- 17 # LTS
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
- 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@v2
|
uses: actions/setup-java@v3
|
||||||
with:
|
with:
|
||||||
java-version: ${{ matrix.java }}
|
java-version: ${{ matrix.java }}
|
||||||
distribution: adopt # Java 8 and 11 are pre-installed on ubuntu-latest
|
distribution: adopt # Java 8 and 11 are pre-installed on ubuntu-latest
|
||||||
@@ -44,7 +44,7 @@ jobs:
|
|||||||
run: ./gradlew build
|
run: ./gradlew build
|
||||||
|
|
||||||
- name: Upload artifacts
|
- name: Upload artifacts
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v3
|
||||||
if: matrix.java == '11'
|
if: matrix.java == '11'
|
||||||
with:
|
with:
|
||||||
name: FlatLaf-build-artifacts
|
name: FlatLaf-build-artifacts
|
||||||
@@ -63,10 +63,10 @@ jobs:
|
|||||||
github.repository == 'JFormDesigner/FlatLaf'
|
github.repository == 'JFormDesigner/FlatLaf'
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Setup Java 11
|
- name: Setup Java 11
|
||||||
uses: actions/setup-java@v2
|
uses: actions/setup-java@v3
|
||||||
with:
|
with:
|
||||||
java-version: 11
|
java-version: 11
|
||||||
distribution: adopt # pre-installed on ubuntu-latest
|
distribution: adopt # pre-installed on ubuntu-latest
|
||||||
@@ -99,10 +99,10 @@ jobs:
|
|||||||
github.repository == 'JFormDesigner/FlatLaf'
|
github.repository == 'JFormDesigner/FlatLaf'
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Setup Java 11
|
- name: Setup Java 11
|
||||||
uses: actions/setup-java@v2
|
uses: actions/setup-java@v3
|
||||||
with:
|
with:
|
||||||
java-version: 11
|
java-version: 11
|
||||||
distribution: adopt # pre-installed on ubuntu-latest
|
distribution: adopt # pre-installed on ubuntu-latest
|
||||||
|
|||||||
9
.github/workflows/natives.yml
vendored
9
.github/workflows/natives.yml
vendored
@@ -25,12 +25,12 @@ jobs:
|
|||||||
runs-on: windows-latest
|
runs-on: windows-latest
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3
|
||||||
|
|
||||||
- uses: gradle/wrapper-validation-action@v1
|
- uses: gradle/wrapper-validation-action@v1
|
||||||
|
|
||||||
- name: Setup Java 11
|
- name: Setup Java 11
|
||||||
uses: actions/setup-java@v2
|
uses: actions/setup-java@v3
|
||||||
with:
|
with:
|
||||||
java-version: 11
|
java-version: 11
|
||||||
distribution: adopt
|
distribution: adopt
|
||||||
@@ -39,11 +39,12 @@ jobs:
|
|||||||
- name: Build with Gradle
|
- name: Build with Gradle
|
||||||
# --no-daemon is necessary on Windows otherwise caching Gradle would fail with:
|
# --no-daemon is necessary on Windows otherwise caching Gradle would fail with:
|
||||||
# tar.exe: Couldn't open ~/.gradle/caches/modules-2/modules-2.lock: Permission denied
|
# tar.exe: Couldn't open ~/.gradle/caches/modules-2/modules-2.lock: Permission denied
|
||||||
run: ./gradlew :flatlaf-natives-windows:build --no-daemon
|
run: ./gradlew :flatlaf-natives-windows:build-natives --no-daemon
|
||||||
|
|
||||||
- name: Upload artifacts
|
- name: Upload artifacts
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: FlatLaf-natives-windows-build-artifacts
|
name: FlatLaf-natives-windows-build-artifacts
|
||||||
path: |
|
path: |
|
||||||
|
flatlaf-core/src/main/resources/com/formdev/flatlaf/natives
|
||||||
flatlaf-natives/flatlaf-natives-windows/build
|
flatlaf-natives/flatlaf-natives-windows/build
|
||||||
|
|||||||
129
CHANGELOG.md
129
CHANGELOG.md
@@ -1,6 +1,133 @@
|
|||||||
FlatLaf Change Log
|
FlatLaf Change Log
|
||||||
==================
|
==================
|
||||||
|
|
||||||
|
## 2.4
|
||||||
|
|
||||||
|
#### New features and improvements
|
||||||
|
|
||||||
|
- Native window decorations (Windows 10/11 only):
|
||||||
|
- There is now a small area at top of the embedded menu bar to resize the
|
||||||
|
window.
|
||||||
|
- Improved window title bar layout for small window widths:
|
||||||
|
- Width of iconify/maximize/close buttons is reduced (if necessary) to give
|
||||||
|
more space to embedded menu bar and title.
|
||||||
|
- Window title now has a minimum width to always allow moving window
|
||||||
|
(click-and-drag on window title). Instead, embedded menu bar is made
|
||||||
|
smaller.
|
||||||
|
- Option to show window icon beside window title, if menu bar is embedded or
|
||||||
|
title is centered. Set UI value `TitlePane.showIconBesideTitle` to `true`.
|
||||||
|
- No longer reduce height of window title bar if it has an embedded menu bar
|
||||||
|
and is maximized.
|
||||||
|
|
||||||
|
#### Fixed bugs
|
||||||
|
|
||||||
|
- ComboBox: Fixed vertical alignment of text in popup list with text in combo
|
||||||
|
box in IntelliJ/Darcula themes.
|
||||||
|
- Menus: Fixed application freeze under very special conditions (invoking
|
||||||
|
`FlatLaf.initialize()` twice in NetBeans GUI builder) and using menu that has
|
||||||
|
submenus. See
|
||||||
|
[NetBeans issue #4231](https://github.com/apache/netbeans/issues/4231#issuecomment-1179611682)
|
||||||
|
for details.
|
||||||
|
- MenuItem: Fixed sometimes wrapped HTML text on HiDPI screens on Windows.
|
||||||
|
- TableHeader: Fixed exception when changing table structure (e.g. removing
|
||||||
|
column) from a table header popup menu action. (issue #532)
|
||||||
|
- `HiDPIUtils.paintAtScale1x()` now supports rotated graphics. (issue #557)
|
||||||
|
- Typography: No longer use `Consolas` or `Courier New` as monospaced font on
|
||||||
|
Windows because they have bad vertically placement.
|
||||||
|
- Native window decorations (Windows 10/11 only):
|
||||||
|
- Do not center window title if embedded menu bar is empty or has no menus at
|
||||||
|
left side, but some components at right side. (issue #558)
|
||||||
|
- Do not use window decorations if system property `sun.java2d.opengl` is
|
||||||
|
`true` on Windows 10. (issue #540)
|
||||||
|
- Fixed missing top window border in dark themes if window drop shadows are
|
||||||
|
disabled in system settings. (issue #554; Windows 10 only)
|
||||||
|
- Right-to-left component orientation of title bar was lost when switching
|
||||||
|
theme.
|
||||||
|
|
||||||
|
|
||||||
|
## 2.3
|
||||||
|
|
||||||
|
#### New features and improvements
|
||||||
|
|
||||||
|
- FileChooser: Added (optional) shortcuts panel. On Windows it contains "Recent
|
||||||
|
Items", "Desktop", "Documents", "This PC" and "Network". On macOS and Linux it
|
||||||
|
is empty/hidden. (issue #100)
|
||||||
|
- Button and ToggleButton: Added missing foreground colors for hover, pressed,
|
||||||
|
focused and selected states. (issue #535)
|
||||||
|
- Table: Optionally paint alternating rows below table if table is smaller than
|
||||||
|
scroll pane. Set UI value `Table.paintOutsideAlternateRows` to `true`.
|
||||||
|
Requires that `Table.alternateRowColor` is set to a color. (issue #504)
|
||||||
|
- ToggleButton: Made the underline placement of tab-style toggle buttons
|
||||||
|
configurable. (PR #530; issue #529)
|
||||||
|
- Added spanish translation. (PR #525)
|
||||||
|
|
||||||
|
#### Fixed bugs
|
||||||
|
|
||||||
|
- IntelliJ Themes: Fixed `TitledBorder` text color in "Monokai Pro" theme.
|
||||||
|
(issue #524)
|
||||||
|
|
||||||
|
|
||||||
|
## 2.2
|
||||||
|
|
||||||
|
#### New features and improvements
|
||||||
|
|
||||||
|
- SplitPane: Allow limiting one-touch expanding to a single side (set client
|
||||||
|
property `JSplitPane.expandableSide` to `"left"` or `"right"`). (issue #355)
|
||||||
|
- TabbedPane: Selected tab underline color now changes depending on whether the
|
||||||
|
focus is within the tab content. (issue #398)
|
||||||
|
- IntelliJ Themes:
|
||||||
|
- Added "Monokai Pro" and "Xcode-Dark" themes.
|
||||||
|
- TabbedPane now use different background color for selected tabs in all "Arc"
|
||||||
|
themes, in "Hiberbee Dark" and in all "Material UI Lite" themes.
|
||||||
|
|
||||||
|
#### Fixed bugs
|
||||||
|
|
||||||
|
- Native window decorations (Windows 10/11 only): Fixed wrong window title
|
||||||
|
character encoding used in Windows taskbar. (issue #502)
|
||||||
|
- Button: Fixed icon layout and preferred width of default buttons that use bold
|
||||||
|
font. (issue #506)
|
||||||
|
- FileChooser: Enabled full row selection for details view to fix alternate row
|
||||||
|
coloring. (issue #512)
|
||||||
|
- SplitPane: Fixed `StackOverflowError` caused by layout loop that may occur
|
||||||
|
under special circumstances. (issue #513)
|
||||||
|
- Table: Slightly changed grid colors to make grid better recognizable. (issue
|
||||||
|
#514)
|
||||||
|
- ToolBar: Fixed endless loop in focus navigation that may occur under special
|
||||||
|
circumstances. (issue #505)
|
||||||
|
- IntelliJ Themes: `Component.accentColor` UI property now has useful theme
|
||||||
|
specific values. (issue #507)
|
||||||
|
|
||||||
|
|
||||||
|
## 2.1
|
||||||
|
|
||||||
|
#### New features and improvements
|
||||||
|
|
||||||
|
- Menus: Improved usability of submenus. (PR #490; issue #247)
|
||||||
|
- Menus: Scroll large menus using mouse wheel or up/down arrows. (issue #225)
|
||||||
|
- Linux: Support using custom window decorations. Enable with
|
||||||
|
`JFrame.setDefaultLookAndFeelDecorated(true)` and
|
||||||
|
`JDialog.setDefaultLookAndFeelDecorated(true)` before creating a window.
|
||||||
|
(issue #482)
|
||||||
|
- ScrollBar: Added UI value `ScrollBar.minimumButtonSize` to specify minimum
|
||||||
|
scroll arrow button size (if shown). (issue #493)
|
||||||
|
|
||||||
|
#### Fixed bugs
|
||||||
|
|
||||||
|
- PasswordField: Fixed reveal button appearance in IntelliJ themes. (issue #494)
|
||||||
|
- ScrollBar: Center and scale arrows in scroll up/down buttons (if shown).
|
||||||
|
(issue #493)
|
||||||
|
- TextArea, TextPane and EditorPane: No longer select all text when component is
|
||||||
|
focused for the first time. (issue #498; regression in FlatLaf 2.0)
|
||||||
|
- TabbedPane: Disable all items in "Show Hidden Tabs" popup menu if tabbed pane
|
||||||
|
is disabled.
|
||||||
|
|
||||||
|
#### Incompatibilities
|
||||||
|
|
||||||
|
- Method `FlatUIUtils.paintArrow()` (and class `FlatArrowButton`) now paints
|
||||||
|
arrows one pixel smaller than before. To fix this, increase parameter
|
||||||
|
`arrowSize` by one.
|
||||||
|
|
||||||
|
|
||||||
## 2.0.2
|
## 2.0.2
|
||||||
|
|
||||||
- Native window decorations (Windows 10/11 only): Fixed rendering artifacts on
|
- Native window decorations (Windows 10/11 only): Fixed rendering artifacts on
|
||||||
@@ -80,7 +207,7 @@ FlatLaf Change Log
|
|||||||
- Possibility to hide window title bar icon (for single window set client
|
- Possibility to hide window title bar icon (for single window set client
|
||||||
property `JRootPane.titleBarShowIcon` to `false`; for all windows set UI
|
property `JRootPane.titleBarShowIcon` to `false`; for all windows set UI
|
||||||
value `TitlePane.showIcon` to `false`).
|
value `TitlePane.showIcon` to `false`).
|
||||||
- OptionPane: Hide window title bar icon by default. Can be be made visibly by
|
- OptionPane: Hide window title bar icon by default. Can be made visibly by
|
||||||
setting UI default `OptionPane.showIcon` to `true`. (issue #416)
|
setting UI default `OptionPane.showIcon` to `true`. (issue #416)
|
||||||
- No longer show the Java "duke/cup" icon if no window icon image is set.
|
- No longer show the Java "duke/cup" icon if no window icon image is set.
|
||||||
(issue #416)
|
(issue #416)
|
||||||
|
|||||||
@@ -14,8 +14,8 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
val releaseVersion = "2.0.2"
|
val releaseVersion = "2.4"
|
||||||
val developmentVersion = "2.1-SNAPSHOT"
|
val developmentVersion = "2.5-SNAPSHOT"
|
||||||
|
|
||||||
version = if( java.lang.Boolean.getBoolean( "release" ) ) releaseVersion else developmentVersion
|
version = if( java.lang.Boolean.getBoolean( "release" ) ) releaseVersion else developmentVersion
|
||||||
|
|
||||||
|
|||||||
@@ -61,8 +61,6 @@ if( JavaVersion.current() >= JavaVersion.VERSION_1_9 ) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
jar {
|
jar {
|
||||||
manifest.attributes( "Multi-Release" to "true" )
|
|
||||||
|
|
||||||
from( sourceSets["module-info"].output ) {
|
from( sourceSets["module-info"].output ) {
|
||||||
include( "module-info.class" )
|
include( "module-info.class" )
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,11 +43,6 @@ tasks {
|
|||||||
options.headerOutputDirectory.set( buildDir.resolve( "generated/jni-headers" ) )
|
options.headerOutputDirectory.set( buildDir.resolve( "generated/jni-headers" ) )
|
||||||
}
|
}
|
||||||
|
|
||||||
processResources {
|
|
||||||
// build native libraries
|
|
||||||
dependsOn( ":flatlaf-natives-windows:assemble" )
|
|
||||||
}
|
|
||||||
|
|
||||||
jar {
|
jar {
|
||||||
archiveBaseName.set( "flatlaf" )
|
archiveBaseName.set( "flatlaf" )
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#Signature file v4.1
|
#Signature file v4.1
|
||||||
#Version 2.0
|
#Version 2.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"
|
||||||
@@ -30,6 +30,9 @@ fld public final static java.lang.String SELECT_ALL_ON_FOCUS_POLICY = "JTextFiel
|
|||||||
fld public final static java.lang.String SELECT_ALL_ON_FOCUS_POLICY_ALWAYS = "always"
|
fld public final static java.lang.String SELECT_ALL_ON_FOCUS_POLICY_ALWAYS = "always"
|
||||||
fld public final static java.lang.String SELECT_ALL_ON_FOCUS_POLICY_NEVER = "never"
|
fld public final static java.lang.String SELECT_ALL_ON_FOCUS_POLICY_NEVER = "never"
|
||||||
fld public final static java.lang.String SELECT_ALL_ON_FOCUS_POLICY_ONCE = "once"
|
fld public final static java.lang.String SELECT_ALL_ON_FOCUS_POLICY_ONCE = "once"
|
||||||
|
fld public final static java.lang.String SPLIT_PANE_EXPANDABLE_SIDE = "JSplitPane.expandableSide"
|
||||||
|
fld public final static java.lang.String SPLIT_PANE_EXPANDABLE_SIDE_LEFT = "left"
|
||||||
|
fld public final static java.lang.String SPLIT_PANE_EXPANDABLE_SIDE_RIGHT = "right"
|
||||||
fld public final static java.lang.String SQUARE_SIZE = "JButton.squareSize"
|
fld public final static java.lang.String SQUARE_SIZE = "JButton.squareSize"
|
||||||
fld public final static java.lang.String STYLE = "FlatLaf.style"
|
fld public final static java.lang.String STYLE = "FlatLaf.style"
|
||||||
fld public final static java.lang.String STYLE_CLASS = "FlatLaf.styleClass"
|
fld public final static java.lang.String STYLE_CLASS = "FlatLaf.styleClass"
|
||||||
@@ -72,6 +75,7 @@ fld public final static java.lang.String TABBED_PANE_TRAILING_COMPONENT = "JTabb
|
|||||||
fld public final static java.lang.String TAB_BUTTON_SELECTED_BACKGROUND = "JToggleButton.tab.selectedBackground"
|
fld public final static java.lang.String TAB_BUTTON_SELECTED_BACKGROUND = "JToggleButton.tab.selectedBackground"
|
||||||
fld public final static java.lang.String TAB_BUTTON_UNDERLINE_COLOR = "JToggleButton.tab.underlineColor"
|
fld public final static java.lang.String TAB_BUTTON_UNDERLINE_COLOR = "JToggleButton.tab.underlineColor"
|
||||||
fld public final static java.lang.String TAB_BUTTON_UNDERLINE_HEIGHT = "JToggleButton.tab.underlineHeight"
|
fld public final static java.lang.String TAB_BUTTON_UNDERLINE_HEIGHT = "JToggleButton.tab.underlineHeight"
|
||||||
|
fld public final static java.lang.String TAB_BUTTON_UNDERLINE_PLACEMENT = "JToggleButton.tab.underlinePlacement"
|
||||||
fld public final static java.lang.String TEXT_FIELD_CLEAR_CALLBACK = "JTextField.clearCallback"
|
fld public final static java.lang.String TEXT_FIELD_CLEAR_CALLBACK = "JTextField.clearCallback"
|
||||||
fld public final static java.lang.String TEXT_FIELD_LEADING_COMPONENT = "JTextField.leadingComponent"
|
fld public final static java.lang.String TEXT_FIELD_LEADING_COMPONENT = "JTextField.leadingComponent"
|
||||||
fld public final static java.lang.String TEXT_FIELD_LEADING_ICON = "JTextField.leadingIcon"
|
fld public final static java.lang.String TEXT_FIELD_LEADING_ICON = "JTextField.leadingIcon"
|
||||||
@@ -216,7 +220,7 @@ meth public void setExtraDefaults(java.util.Map<java.lang.String,java.lang.Strin
|
|||||||
meth public void uninitialize()
|
meth public void uninitialize()
|
||||||
meth public void unregisterUIDefaultsGetter(java.util.function.Function<java.lang.Object,java.lang.Object>)
|
meth public void unregisterUIDefaultsGetter(java.util.function.Function<java.lang.Object,java.lang.Object>)
|
||||||
supr javax.swing.plaf.basic.BasicLookAndFeel
|
supr javax.swing.plaf.basic.BasicLookAndFeel
|
||||||
hfds DESKTOPFONTHINTS,aquaLoaded,customDefaultsSources,desktopPropertyListener,desktopPropertyName,desktopPropertyName2,extraDefaults,globalExtraDefaults,mnemonicHandler,oldPopupFactory,postInitialization,uiDefaultsGetters,updateUIPending
|
hfds DESKTOPFONTHINTS,aquaLoaded,customDefaultsSources,desktopPropertyListener,desktopPropertyName,desktopPropertyName2,extraDefaults,globalExtraDefaults,mnemonicHandler,oldPopupFactory,postInitialization,subMenuUsabilityHelper,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
|
||||||
@@ -662,6 +666,7 @@ CLSS public com.formdev.flatlaf.util.SystemInfo
|
|||||||
cons public init()
|
cons public init()
|
||||||
fld public final static boolean isAARCH64
|
fld public final static boolean isAARCH64
|
||||||
fld public final static boolean isJava_11_orLater
|
fld public final static boolean isJava_11_orLater
|
||||||
|
fld public final static boolean isJava_12_orLater
|
||||||
fld public final static boolean isJava_15_orLater
|
fld public final static boolean isJava_15_orLater
|
||||||
fld public final static boolean isJava_17_orLater
|
fld public final static boolean isJava_17_orLater
|
||||||
fld public final static boolean isJava_18_orLater
|
fld public final static boolean isJava_18_orLater
|
||||||
@@ -670,6 +675,7 @@ fld public final static boolean isJetBrainsJVM
|
|||||||
fld public final static boolean isJetBrainsJVM_11_orLater
|
fld public final static boolean isJetBrainsJVM_11_orLater
|
||||||
fld public final static boolean isKDE
|
fld public final static boolean isKDE
|
||||||
fld public final static boolean isLinux
|
fld public final static boolean isLinux
|
||||||
|
fld public final static boolean isMacFullWindowContentSupported
|
||||||
fld public final static boolean isMacOS
|
fld public final static boolean isMacOS
|
||||||
fld public final static boolean isMacOS_10_11_ElCapitan_orLater
|
fld public final static boolean isMacOS_10_11_ElCapitan_orLater
|
||||||
fld public final static boolean isMacOS_10_14_Mojave_orLater
|
fld public final static boolean isMacOS_10_14_Mojave_orLater
|
||||||
|
|||||||
@@ -391,6 +391,40 @@ public interface FlatClientProperties
|
|||||||
*/
|
*/
|
||||||
String SCROLL_PANE_SMOOTH_SCROLLING = "JScrollPane.smoothScrolling";
|
String SCROLL_PANE_SMOOTH_SCROLLING = "JScrollPane.smoothScrolling";
|
||||||
|
|
||||||
|
//---- JSplitPane ---------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies what side of the spilt pane is allowed to expand
|
||||||
|
* via one-touch expanding arrow buttons.
|
||||||
|
* Requires that one-touch expanding is enabled with
|
||||||
|
* {@link javax.swing.JSplitPane#setOneTouchExpandable(boolean)}.
|
||||||
|
* <p>
|
||||||
|
* <strong>Component</strong> {@link javax.swing.JSplitPane}<br>
|
||||||
|
* <strong>Value type</strong> {@link java.lang.String}<br>
|
||||||
|
* <strong>Allowed Values</strong>
|
||||||
|
* {@link #SPLIT_PANE_EXPANDABLE_SIDE_LEFT} or
|
||||||
|
* {@link #SPLIT_PANE_EXPANDABLE_SIDE_RIGHT}
|
||||||
|
*
|
||||||
|
* @since 2.2
|
||||||
|
*/
|
||||||
|
String SPLIT_PANE_EXPANDABLE_SIDE = "JSplitPane.expandableSide";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allow expanding only left/top side of the split pane.
|
||||||
|
*
|
||||||
|
* @see #SPLIT_PANE_EXPANDABLE_SIDE
|
||||||
|
* @since 2.2
|
||||||
|
*/
|
||||||
|
String SPLIT_PANE_EXPANDABLE_SIDE_LEFT = "left";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allow expanding only right/bottom side of the split pane.
|
||||||
|
*
|
||||||
|
* @see #SPLIT_PANE_EXPANDABLE_SIDE
|
||||||
|
* @since 2.2
|
||||||
|
*/
|
||||||
|
String SPLIT_PANE_EXPANDABLE_SIDE_RIGHT = "right";
|
||||||
|
|
||||||
//---- JTabbedPane --------------------------------------------------------
|
//---- JTabbedPane --------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -958,7 +992,22 @@ public interface FlatClientProperties
|
|||||||
//---- JToggleButton ------------------------------------------------------
|
//---- JToggleButton ------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Height of underline if toggle button type is {@link #BUTTON_TYPE_TAB}.
|
* Placement of underline if toggle button type is {@link #BUTTON_TYPE_TAB}
|
||||||
|
* <p>
|
||||||
|
* <strong>Component</strong> {@link javax.swing.JToggleButton}<br>
|
||||||
|
* <strong>Value type</strong> {@link java.lang.Integer}<br>
|
||||||
|
* <strong>SupportedValues:</strong>
|
||||||
|
* {@link SwingConstants#BOTTOM} (default)
|
||||||
|
* {@link SwingConstants#TOP},
|
||||||
|
* {@link SwingConstants#LEFT} or
|
||||||
|
* {@link SwingConstants#RIGHT}
|
||||||
|
*
|
||||||
|
* @since 2.3
|
||||||
|
*/
|
||||||
|
String TAB_BUTTON_UNDERLINE_PLACEMENT = "JToggleButton.tab.underlinePlacement";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thickness of underline if toggle button type is {@link #BUTTON_TYPE_TAB}.
|
||||||
* <p>
|
* <p>
|
||||||
* <strong>Component</strong> {@link javax.swing.JToggleButton}<br>
|
* <strong>Component</strong> {@link javax.swing.JToggleButton}<br>
|
||||||
* <strong>Value type</strong> {@link java.lang.Integer}
|
* <strong>Value type</strong> {@link java.lang.Integer}
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ import javax.swing.UIDefaults;
|
|||||||
* Allows loading of additional .properties files from addon JARs.
|
* Allows loading of additional .properties files from addon JARs.
|
||||||
* {@link java.util.ServiceLoader} is used to load extensions of this class from addon JARs.
|
* {@link java.util.ServiceLoader} is used to load extensions of this class from addon JARs.
|
||||||
* <p>
|
* <p>
|
||||||
* If you extend this class in a addon JAR, you also have to add a text file named
|
* If you extend this class in an addon JAR, you also have to add a text file named
|
||||||
* {@code META-INF/services/com.formdev.flatlaf.FlatDefaultsAddon}
|
* {@code META-INF/services/com.formdev.flatlaf.FlatDefaultsAddon}
|
||||||
* to the addon JAR. The file must contain a single line with the class name.
|
* to the addon JAR. The file must contain a single line with the class name.
|
||||||
* <p>
|
* <p>
|
||||||
@@ -61,7 +61,7 @@ public abstract class FlatDefaultsAddon
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the priority used to sort addon loading.
|
* Returns the priority used to sort addon loading.
|
||||||
* The order is only important if you want overwrite UI defaults of other addons.
|
* The order is only important if you want to overwrite UI defaults of other addons.
|
||||||
* Lower numbers mean higher priority.
|
* Lower numbers mean higher priority.
|
||||||
* Returns 10000 by default.
|
* Returns 10000 by default.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ package com.formdev.flatlaf;
|
|||||||
/**
|
/**
|
||||||
* Default color palette for action icons and object icons.
|
* Default color palette for action icons and object icons.
|
||||||
* <p>
|
* <p>
|
||||||
* The idea is to use only this well defined set of colors in SVG icons and
|
* The idea is to use only this well-defined set of colors in SVG icons, and
|
||||||
* then they are replaced at runtime to dark variants or to other theme colors.
|
* then they are replaced at runtime to dark variants or to other theme colors.
|
||||||
* Then a single SVG icon (light variant) can be used for dark themes too.
|
* Then a single SVG icon (light variant) can be used for dark themes too.
|
||||||
* IntelliJ Platform uses this mechanism to allow themes to change IntelliJ Platform icons.
|
* IntelliJ Platform uses this mechanism to allow themes to change IntelliJ Platform icons.
|
||||||
@@ -35,7 +35,7 @@ package com.formdev.flatlaf;
|
|||||||
* <p>
|
* <p>
|
||||||
* You may use these colors also in your application (outside of SVG icons), but do
|
* You may use these colors also in your application (outside of SVG icons), but do
|
||||||
* not use the RGB values defined in this enum.<br>
|
* not use the RGB values defined in this enum.<br>
|
||||||
* Instead use {@code UIManager.getColor( FlatIconColors.ACTIONS_GREY.key )}.
|
* Instead, use {@code UIManager.getColor( FlatIconColors.ACTIONS_GREY.key )}.
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -596,7 +596,7 @@ class FlatInputMaps
|
|||||||
//---- class LazyInputMapEx -----------------------------------------------
|
//---- class LazyInputMapEx -----------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lazily creates a input map.
|
* Lazily creates an input map.
|
||||||
* Similar to {@link UIDefaults.LazyInputMap}, but can use multiple bindings arrays.
|
* Similar to {@link UIDefaults.LazyInputMap}, but can use multiple bindings arrays.
|
||||||
*/
|
*/
|
||||||
private static class LazyInputMapEx
|
private static class LazyInputMapEx
|
||||||
|
|||||||
@@ -103,6 +103,7 @@ public abstract class FlatLaf
|
|||||||
|
|
||||||
private PopupFactory oldPopupFactory;
|
private PopupFactory oldPopupFactory;
|
||||||
private MnemonicHandler mnemonicHandler;
|
private MnemonicHandler mnemonicHandler;
|
||||||
|
private boolean subMenuUsabilityHelperInstalled;
|
||||||
|
|
||||||
private Consumer<UIDefaults> postInitialization;
|
private Consumer<UIDefaults> postInitialization;
|
||||||
private List<Function<Object, Object>> uiDefaultsGetters;
|
private List<Function<Object, Object>> uiDefaultsGetters;
|
||||||
@@ -166,18 +167,19 @@ public abstract class FlatLaf
|
|||||||
* Returns whether FlatLaf supports custom window decorations.
|
* Returns whether FlatLaf supports custom window decorations.
|
||||||
* 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 (see exception below), {@code false} otherwise.
|
* This method returns {@code true} on Windows 10/11 (see exception below)
|
||||||
|
* and on Linux, {@code false} otherwise.
|
||||||
* <p>
|
* <p>
|
||||||
* Returns also {@code false} on Windows 10 if:
|
* Returns also {@code false} on Windows 10/11 if:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>FlatLaf native window border support is available (requires Windows 10)</li>
|
* <li>FlatLaf native window border support is available (requires Windows 10/11)</li>
|
||||||
* <li>running in
|
* <li>running in
|
||||||
* <a href="https://confluence.jetbrains.com/display/JBR/JetBrains+Runtime">JetBrains Runtime 11 (or later)</a>
|
* <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>)
|
* (<a href="https://github.com/JetBrains/JetBrainsRuntime">source code on github</a>)
|
||||||
* and JBR supports custom window decorations
|
* and JBR supports custom window decorations
|
||||||
* </li>
|
* </li>
|
||||||
* </ul>
|
* </ul>
|
||||||
* In this 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.
|
||||||
*/
|
*/
|
||||||
@@ -190,7 +192,7 @@ public abstract class FlatLaf
|
|||||||
FlatNativeWindowBorder.isSupported() )
|
FlatNativeWindowBorder.isSupported() )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return SystemInfo.isWindows_10_orLater;
|
return SystemInfo.isWindows_10_orLater || SystemInfo.isLinux;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -230,6 +232,15 @@ public abstract class FlatLaf
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initialize() {
|
public void initialize() {
|
||||||
|
// do not initialize if this is not the current look and feel
|
||||||
|
// This is only necessary for special Laf usage. E.g. in GUI builders,
|
||||||
|
// which may use multiple Lafs and may invoke this method directly.
|
||||||
|
// This avoids that listeners and factories are installed multiple times.
|
||||||
|
// In case of the NetBeans GUI builder, which does not invoke uninitialize(),
|
||||||
|
// this also avoids that listeners stay registered in the system.
|
||||||
|
if( UIManager.getLookAndFeel() != this )
|
||||||
|
return;
|
||||||
|
|
||||||
if( SystemInfo.isMacOS )
|
if( SystemInfo.isMacOS )
|
||||||
initializeAqua();
|
initializeAqua();
|
||||||
|
|
||||||
@@ -243,6 +254,9 @@ public abstract class FlatLaf
|
|||||||
mnemonicHandler = new MnemonicHandler();
|
mnemonicHandler = new MnemonicHandler();
|
||||||
mnemonicHandler.install();
|
mnemonicHandler.install();
|
||||||
|
|
||||||
|
// install submenu usability helper
|
||||||
|
subMenuUsabilityHelperInstalled = SubMenuUsabilityHelper.install();
|
||||||
|
|
||||||
// listen to desktop property changes to update UI if system font or scaling changes
|
// listen to desktop property changes to update UI if system font or scaling changes
|
||||||
if( SystemInfo.isWindows ) {
|
if( SystemInfo.isWindows ) {
|
||||||
// Windows 10 allows increasing font size independent of scaling:
|
// Windows 10 allows increasing font size independent of scaling:
|
||||||
@@ -298,6 +312,10 @@ public abstract class FlatLaf
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void uninitialize() {
|
public void uninitialize() {
|
||||||
|
// do not uninitialize if this is not the current look and feel
|
||||||
|
if( UIManager.getLookAndFeel() != this )
|
||||||
|
return;
|
||||||
|
|
||||||
// remove desktop property listener
|
// remove desktop property listener
|
||||||
if( desktopPropertyListener != null ) {
|
if( desktopPropertyListener != null ) {
|
||||||
Toolkit toolkit = Toolkit.getDefaultToolkit();
|
Toolkit toolkit = Toolkit.getDefaultToolkit();
|
||||||
@@ -322,6 +340,12 @@ public abstract class FlatLaf
|
|||||||
mnemonicHandler = null;
|
mnemonicHandler = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// uninstall submenu usability helper
|
||||||
|
if( subMenuUsabilityHelperInstalled ) {
|
||||||
|
SubMenuUsabilityHelper.uninstall();
|
||||||
|
subMenuUsabilityHelperInstalled = false;
|
||||||
|
}
|
||||||
|
|
||||||
// restore default link color
|
// restore default link color
|
||||||
new HTMLEditorKit().getStyleSheet().addRule( "a, address { color: blue; }" );
|
new HTMLEditorKit().getStyleSheet().addRule( "a, address { color: blue; }" );
|
||||||
postInitialization = null;
|
postInitialization = null;
|
||||||
@@ -605,7 +629,7 @@ public abstract class FlatLaf
|
|||||||
uiFont = ((ActiveFont)defaultFont).derive( baseFont, fontSize -> {
|
uiFont = ((ActiveFont)defaultFont).derive( baseFont, fontSize -> {
|
||||||
return Math.round( fontSize * UIScale.computeFontScaleFactor( baseFont ) );
|
return Math.round( fontSize * UIScale.computeFontScaleFactor( baseFont ) );
|
||||||
} );
|
} );
|
||||||
};
|
}
|
||||||
|
|
||||||
// increase font size if system property "flatlaf.uiScale" is set
|
// increase font size if system property "flatlaf.uiScale" is set
|
||||||
uiFont = UIScale.applyCustomScaleFactor( uiFont );
|
uiFont = UIScale.applyCustomScaleFactor( uiFont );
|
||||||
@@ -760,7 +784,7 @@ public abstract class FlatLaf
|
|||||||
* Invoke this method before setting the look and feel.
|
* Invoke this method before setting the look and feel.
|
||||||
* <p>
|
* <p>
|
||||||
* If using Java modules, the package must be opened in {@code module-info.java}.
|
* If using Java modules, the package must be opened in {@code module-info.java}.
|
||||||
* Otherwise use {@link #registerCustomDefaultsSource(URL)}.
|
* Otherwise, use {@link #registerCustomDefaultsSource(URL)}.
|
||||||
*
|
*
|
||||||
* @param packageName a package name (e.g. "com.myapp.resources")
|
* @param packageName a package name (e.g. "com.myapp.resources")
|
||||||
*/
|
*/
|
||||||
@@ -862,7 +886,7 @@ public abstract class FlatLaf
|
|||||||
* E.g. using {@link UIManager#setLookAndFeel(LookAndFeel)} or {@link #setup(LookAndFeel)}.
|
* E.g. using {@link UIManager#setLookAndFeel(LookAndFeel)} or {@link #setup(LookAndFeel)}.
|
||||||
* <p>
|
* <p>
|
||||||
* The global extra defaults are useful for smaller additional defaults that may change.
|
* The global extra defaults are useful for smaller additional defaults that may change.
|
||||||
* E.g. accent color. Otherwise FlatLaf properties files should be used.
|
* E.g. accent color. Otherwise, FlatLaf properties files should be used.
|
||||||
* See {@link #registerCustomDefaultsSource(String)}.
|
* See {@link #registerCustomDefaultsSource(String)}.
|
||||||
* <p>
|
* <p>
|
||||||
* The keys and values are strings in same format as in FlatLaf properties files.
|
* The keys and values are strings in same format as in FlatLaf properties files.
|
||||||
@@ -894,7 +918,7 @@ public abstract class FlatLaf
|
|||||||
* E.g. using {@link UIManager#setLookAndFeel(LookAndFeel)} or {@link #setup(LookAndFeel)}.
|
* E.g. using {@link UIManager#setLookAndFeel(LookAndFeel)} or {@link #setup(LookAndFeel)}.
|
||||||
* <p>
|
* <p>
|
||||||
* The extra defaults are useful for smaller additional defaults that may change.
|
* The extra defaults are useful for smaller additional defaults that may change.
|
||||||
* E.g. accent color. Otherwise FlatLaf properties files should be used.
|
* E.g. accent color. Otherwise, FlatLaf properties files should be used.
|
||||||
* See {@link #registerCustomDefaultsSource(String)}.
|
* See {@link #registerCustomDefaultsSource(String)}.
|
||||||
* <p>
|
* <p>
|
||||||
* The keys and values are strings in same format as in FlatLaf properties files.
|
* The keys and values are strings in same format as in FlatLaf properties files.
|
||||||
@@ -951,7 +975,7 @@ public abstract class FlatLaf
|
|||||||
// re-set current LaF
|
// re-set current LaF
|
||||||
UIManager.setLookAndFeel( lookAndFeel );
|
UIManager.setLookAndFeel( lookAndFeel );
|
||||||
|
|
||||||
// must fire property change events ourself because old and new LaF are the same
|
// must fire property change events ourselves because old and new LaF are the same
|
||||||
PropertyChangeEvent e = new PropertyChangeEvent( UIManager.class, "lookAndFeel", lookAndFeel, lookAndFeel );
|
PropertyChangeEvent e = new PropertyChangeEvent( UIManager.class, "lookAndFeel", lookAndFeel, lookAndFeel );
|
||||||
for( PropertyChangeListener l : UIManager.getPropertyChangeListeners() )
|
for( PropertyChangeListener l : UIManager.getPropertyChangeListeners() )
|
||||||
l.propertyChange( e );
|
l.propertyChange( e );
|
||||||
@@ -995,7 +1019,7 @@ public abstract class FlatLaf
|
|||||||
/**
|
/**
|
||||||
* Returns whether native window decorations are supported on current platform.
|
* Returns whether native window decorations are supported on current platform.
|
||||||
* <p>
|
* <p>
|
||||||
* This requires Windows 10, but may be disabled if running in special environments
|
* This requires Windows 10/11, but may be disabled if running in special environments
|
||||||
* (JetBrains Projector, Webswing or WinPE) or if loading native library fails.
|
* (JetBrains Projector, Webswing or WinPE) or if loading native library fails.
|
||||||
* If system property {@link FlatSystemProperties#USE_WINDOW_DECORATIONS} is set to
|
* If system property {@link FlatSystemProperties#USE_WINDOW_DECORATIONS} is set to
|
||||||
* {@code false}, then this method also returns {@code false}.
|
* {@code false}, then this method also returns {@code false}.
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ public interface FlatSystemProperties
|
|||||||
* To replace the Java 9+ system scale factor, use system property "sun.java2d.uiScale",
|
* To replace the Java 9+ system scale factor, use system property "sun.java2d.uiScale",
|
||||||
* which has the same syntax as this one.
|
* which has the same syntax as this one.
|
||||||
* <p>
|
* <p>
|
||||||
* Since FlatLaf 1.1.2: Scale factors less then 100% are allowed.
|
* Since FlatLaf 1.1.2: Scale factors less than 100% are allowed.
|
||||||
* <p>
|
* <p>
|
||||||
* <strong>Allowed Values</strong> e.g. {@code 1.5}, {@code 1.5x}, {@code 150%} or {@code 144dpi} (96dpi is 100%)<br>
|
* <strong>Allowed Values</strong> e.g. {@code 1.5}, {@code 1.5x}, {@code 150%} or {@code 144dpi} (96dpi is 100%)<br>
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ import com.formdev.flatlaf.json.ParseException;
|
|||||||
import com.formdev.flatlaf.util.ColorFunctions;
|
import com.formdev.flatlaf.util.ColorFunctions;
|
||||||
import com.formdev.flatlaf.util.LoggingFacade;
|
import com.formdev.flatlaf.util.LoggingFacade;
|
||||||
import com.formdev.flatlaf.util.StringUtils;
|
import com.formdev.flatlaf.util.StringUtils;
|
||||||
|
import com.formdev.flatlaf.util.SystemInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class supports loading IntelliJ .theme.json files and using them as a Laf.
|
* This class supports loading IntelliJ .theme.json files and using them as a Laf.
|
||||||
@@ -162,8 +163,11 @@ public class IntelliJTheme
|
|||||||
applyCheckBoxColors( defaults );
|
applyCheckBoxColors( defaults );
|
||||||
|
|
||||||
// copy values
|
// copy values
|
||||||
for( Map.Entry<String, String> e : uiKeyCopying.entrySet() )
|
for( Map.Entry<String, String> e : uiKeyCopying.entrySet() ) {
|
||||||
defaults.put( e.getKey(), defaults.get( e.getValue() ) );
|
Object value = defaults.get( e.getValue() );
|
||||||
|
if( value != null )
|
||||||
|
defaults.put( e.getKey(), value );
|
||||||
|
}
|
||||||
|
|
||||||
// IDEA does not paint button background if disabled, but FlatLaf does
|
// IDEA does not paint button background if disabled, but FlatLaf does
|
||||||
Object panelBackground = defaults.get( "Panel.background" );
|
Object panelBackground = defaults.get( "Panel.background" );
|
||||||
@@ -175,7 +179,7 @@ public class IntelliJTheme
|
|||||||
defaults.put( "Button.hoverBorderColor", defaults.get( "Button.focusedBorderColor" ) );
|
defaults.put( "Button.hoverBorderColor", defaults.get( "Button.focusedBorderColor" ) );
|
||||||
defaults.put( "HelpButton.hoverBorderColor", defaults.get( "Button.focusedBorderColor" ) );
|
defaults.put( "HelpButton.hoverBorderColor", defaults.get( "Button.focusedBorderColor" ) );
|
||||||
|
|
||||||
// IDEA uses a SVG icon for the help button, but paints the background with Button.startBackground and Button.endBackground
|
// IDEA uses an SVG icon for the help button, but paints the background with Button.startBackground and Button.endBackground
|
||||||
Object helpButtonBackground = defaults.get( "Button.startBackground" );
|
Object helpButtonBackground = defaults.get( "Button.startBackground" );
|
||||||
Object helpButtonBorderColor = defaults.get( "Button.startBorderColor" );
|
Object helpButtonBorderColor = defaults.get( "Button.startBorderColor" );
|
||||||
if( helpButtonBackground == null )
|
if( helpButtonBackground == null )
|
||||||
@@ -242,7 +246,19 @@ public class IntelliJTheme
|
|||||||
defaults.put( "Tree.rowHeight", 22 );
|
defaults.put( "Tree.rowHeight", 22 );
|
||||||
|
|
||||||
// apply theme specific UI defaults at the end to allow overwriting
|
// apply theme specific UI defaults at the end to allow overwriting
|
||||||
defaults.putAll( themeSpecificDefaults );
|
for( Map.Entry<Object, Object> e : themeSpecificDefaults.entrySet() ) {
|
||||||
|
Object key = e.getKey();
|
||||||
|
Object value = e.getValue();
|
||||||
|
|
||||||
|
// append styles to existing styles
|
||||||
|
if( key instanceof String && ((String)key).startsWith( "[style]" ) ) {
|
||||||
|
Object oldValue = defaults.get( key );
|
||||||
|
if( oldValue != null )
|
||||||
|
value = oldValue + "; " + value;
|
||||||
|
}
|
||||||
|
|
||||||
|
defaults.put( key, value );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<Object, Object> removeThemeSpecificDefaults( UIDefaults defaults ) {
|
private Map<Object, Object> removeThemeSpecificDefaults( UIDefaults defaults ) {
|
||||||
@@ -299,8 +315,19 @@ public class IntelliJTheme
|
|||||||
@SuppressWarnings( "unchecked" )
|
@SuppressWarnings( "unchecked" )
|
||||||
private void apply( String key, Object value, UIDefaults defaults, ArrayList<Object> defaultsKeysCache, Set<String> uiKeys ) {
|
private void apply( String key, Object value, UIDefaults defaults, ArrayList<Object> defaultsKeysCache, Set<String> uiKeys ) {
|
||||||
if( value instanceof Map ) {
|
if( value instanceof Map ) {
|
||||||
for( Map.Entry<String, Object> e : ((Map<String, Object>)value).entrySet() )
|
Map<String, Object> map = (Map<String, Object>)value;
|
||||||
apply( key + '.' + e.getKey(), e.getValue(), defaults, defaultsKeysCache, uiKeys );
|
if( map.containsKey( "os.default" ) || map.containsKey( "os.windows" ) || map.containsKey( "os.mac" ) || map.containsKey( "os.linux" ) ) {
|
||||||
|
String osKey = SystemInfo.isWindows ? "os.windows"
|
||||||
|
: SystemInfo.isMacOS ? "os.mac"
|
||||||
|
: SystemInfo.isLinux ? "os.linux" : null;
|
||||||
|
if( osKey != null && map.containsKey( osKey ) )
|
||||||
|
apply( key, map.get( osKey ), defaults, defaultsKeysCache, uiKeys );
|
||||||
|
else if( map.containsKey( "os.default" ) )
|
||||||
|
apply( key, map.get( "os.default" ), defaults, defaultsKeysCache, uiKeys );
|
||||||
|
} else {
|
||||||
|
for( Map.Entry<String, Object> e : map.entrySet() )
|
||||||
|
apply( key + '.' + e.getKey(), e.getValue(), defaults, defaultsKeysCache, uiKeys );
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if( "".equals( value ) )
|
if( "".equals( value ) )
|
||||||
return; // ignore empty value
|
return; // ignore empty value
|
||||||
@@ -534,12 +561,12 @@ public class IntelliJTheme
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Rename UI default keys (key --> value). */
|
/** Rename UI default keys (key --> value). */
|
||||||
private static Map<String, String> uiKeyMapping = new HashMap<>();
|
private static final Map<String, String> uiKeyMapping = new HashMap<>();
|
||||||
/** Copy UI default keys (value --> key). */
|
/** Copy UI default keys (value --> key). */
|
||||||
private static Map<String, String> uiKeyCopying = new HashMap<>();
|
private static final Map<String, String> uiKeyCopying = new HashMap<>();
|
||||||
private static Map<String, String> uiKeyInverseMapping = new HashMap<>();
|
private static final Map<String, String> uiKeyInverseMapping = new HashMap<>();
|
||||||
private static Map<String, String> checkboxKeyMapping = new HashMap<>();
|
private static final Map<String, String> checkboxKeyMapping = new HashMap<>();
|
||||||
private static Map<String, String> checkboxDuplicateColors = new HashMap<>();
|
private static final Map<String, String> checkboxDuplicateColors = new HashMap<>();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
// ComboBox
|
// ComboBox
|
||||||
@@ -600,6 +627,11 @@ public class IntelliJTheme
|
|||||||
uiKeyCopying.put( "Spinner.buttonSeparatorColor", "Component.borderColor" );
|
uiKeyCopying.put( "Spinner.buttonSeparatorColor", "Component.borderColor" );
|
||||||
uiKeyCopying.put( "Spinner.buttonDisabledSeparatorColor", "Component.disabledBorderColor" );
|
uiKeyCopying.put( "Spinner.buttonDisabledSeparatorColor", "Component.disabledBorderColor" );
|
||||||
|
|
||||||
|
// TabbedPane
|
||||||
|
uiKeyCopying.put( "TabbedPane.selectedBackground", "DefaultTabs.underlinedTabBackground" );
|
||||||
|
uiKeyCopying.put( "TabbedPane.selectedForeground", "DefaultTabs.underlinedTabForeground" );
|
||||||
|
uiKeyCopying.put( "TabbedPane.inactiveUnderlineColor", "DefaultTabs.inactiveUnderlineColor" );
|
||||||
|
|
||||||
// TitlePane
|
// TitlePane
|
||||||
uiKeyCopying.put( "TitlePane.inactiveBackground", "TitlePane.background" );
|
uiKeyCopying.put( "TitlePane.inactiveBackground", "TitlePane.background" );
|
||||||
uiKeyMapping.put( "TitlePane.infoForeground", "TitlePane.foreground" );
|
uiKeyMapping.put( "TitlePane.infoForeground", "TitlePane.foreground" );
|
||||||
|
|||||||
@@ -170,7 +170,7 @@ class LinuxFontPolicy
|
|||||||
|
|
||||||
Object value = Toolkit.getDefaultToolkit().getDesktopProperty( "gnome.Xft/DPI" );
|
Object value = Toolkit.getDefaultToolkit().getDesktopProperty( "gnome.Xft/DPI" );
|
||||||
if( value instanceof Integer ) {
|
if( value instanceof Integer ) {
|
||||||
int dpi = ((Integer)value).intValue() / 1024;
|
int dpi = (Integer) value / 1024;
|
||||||
if( dpi == -1 )
|
if( dpi == -1 )
|
||||||
dpi = 96;
|
dpi = 96;
|
||||||
if( dpi < 50 )
|
if( dpi < 50 )
|
||||||
@@ -197,7 +197,7 @@ class LinuxFontPolicy
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the default font for KDE for 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). A application restart is necessary.
|
||||||
@@ -278,7 +278,7 @@ class LinuxFontPolicy
|
|||||||
// read config file
|
// read config file
|
||||||
ArrayList<String> lines = new ArrayList<>( 200 );
|
ArrayList<String> lines = new ArrayList<>( 200 );
|
||||||
try( BufferedReader reader = new BufferedReader( new FileReader( file ) ) ) {
|
try( BufferedReader reader = new BufferedReader( new FileReader( file ) ) ) {
|
||||||
String line = null;
|
String line;
|
||||||
while( (line = reader.readLine()) != null )
|
while( (line = reader.readLine()) != null )
|
||||||
lines.add( line );
|
lines.add( line );
|
||||||
} catch( IOException ex ) {
|
} catch( IOException ex ) {
|
||||||
|
|||||||
@@ -0,0 +1,336 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2022 FormDev Software GmbH
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.formdev.flatlaf;
|
||||||
|
|
||||||
|
import java.awt.AWTEvent;
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Component;
|
||||||
|
import java.awt.Container;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.EventQueue;
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.MouseInfo;
|
||||||
|
import java.awt.Point;
|
||||||
|
import java.awt.PointerInfo;
|
||||||
|
import java.awt.Polygon;
|
||||||
|
import java.awt.Rectangle;
|
||||||
|
import java.awt.Toolkit;
|
||||||
|
import java.awt.Window;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
import javax.swing.JComponent;
|
||||||
|
import javax.swing.JLayeredPane;
|
||||||
|
import javax.swing.JMenu;
|
||||||
|
import javax.swing.JPopupMenu;
|
||||||
|
import javax.swing.MenuElement;
|
||||||
|
import javax.swing.MenuSelectionManager;
|
||||||
|
import javax.swing.RootPaneContainer;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
|
import javax.swing.Timer;
|
||||||
|
import javax.swing.UIManager;
|
||||||
|
import javax.swing.event.ChangeEvent;
|
||||||
|
import javax.swing.event.ChangeListener;
|
||||||
|
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Improves usability of submenus by using a
|
||||||
|
* <a href="https://height.app/blog/guide-to-build-context-menus#safe-triangle">safe triangle</a>
|
||||||
|
* to avoid that the submenu closes while the user moves the mouse to it.
|
||||||
|
*
|
||||||
|
* @author Karl Tauber
|
||||||
|
*/
|
||||||
|
class SubMenuUsabilityHelper
|
||||||
|
implements ChangeListener
|
||||||
|
{
|
||||||
|
private static final String KEY_USE_SAFE_TRIANGLE = "Menu.useSafeTriangle";
|
||||||
|
private static final String KEY_SHOW_SAFE_TRIANGLE = "FlatLaf.debug.menu.showSafeTriangle";
|
||||||
|
|
||||||
|
// Using a static field to ensure that there is only one instance in the system.
|
||||||
|
// Multiple instances would freeze the application.
|
||||||
|
// https://github.com/apache/netbeans/issues/4231#issuecomment-1179616607
|
||||||
|
private static SubMenuUsabilityHelper instance;
|
||||||
|
|
||||||
|
private SubMenuEventQueue subMenuEventQueue;
|
||||||
|
private SafeTrianglePainter safeTrianglePainter;
|
||||||
|
private boolean changePending;
|
||||||
|
|
||||||
|
// mouse location in screen coordinates
|
||||||
|
private int mouseX;
|
||||||
|
private int mouseY;
|
||||||
|
|
||||||
|
// target popup bounds in screen coordinates
|
||||||
|
private int targetX;
|
||||||
|
private int targetTopY;
|
||||||
|
private int targetBottomY;
|
||||||
|
|
||||||
|
private Rectangle invokerBounds;
|
||||||
|
|
||||||
|
static synchronized boolean install() {
|
||||||
|
if( instance != null )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
instance = new SubMenuUsabilityHelper();
|
||||||
|
MenuSelectionManager.defaultManager().addChangeListener( instance );
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static synchronized void uninstall() {
|
||||||
|
if( instance == null )
|
||||||
|
return;
|
||||||
|
|
||||||
|
MenuSelectionManager.defaultManager().removeChangeListener( instance );
|
||||||
|
instance.uninstallEventQueue();
|
||||||
|
instance = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stateChanged( ChangeEvent e ) {
|
||||||
|
if( !FlatUIUtils.getUIBoolean( KEY_USE_SAFE_TRIANGLE, true ))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// handle menu selection change later, but only once in case of temporary changes
|
||||||
|
// e.g. moving mouse from one menu item to another one, fires two events:
|
||||||
|
// 1. old menu item is removed from menu selection
|
||||||
|
// 2. new menu item is added to menu selection
|
||||||
|
synchronized( this ) {
|
||||||
|
if( changePending )
|
||||||
|
return;
|
||||||
|
changePending = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
EventQueue.invokeLater( () -> {
|
||||||
|
synchronized( this ) {
|
||||||
|
changePending = false;
|
||||||
|
}
|
||||||
|
menuSelectionChanged();
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void menuSelectionChanged() {
|
||||||
|
MenuElement[] path = MenuSelectionManager.defaultManager().getSelectedPath();
|
||||||
|
|
||||||
|
/*debug
|
||||||
|
System.out.println( "--- " + path.length );
|
||||||
|
for( int i = 0; i < path.length; i++ )
|
||||||
|
System.out.println( " " + i + ": " + path[i].getClass().getName() );
|
||||||
|
debug*/
|
||||||
|
|
||||||
|
// find submenu in menu selection
|
||||||
|
int subMenuIndex = findSubMenu( path );
|
||||||
|
|
||||||
|
// uninstall if there is no submenu in selection
|
||||||
|
if( subMenuIndex < 0 || subMenuIndex != path.length - 1 ) {
|
||||||
|
uninstallEventQueue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get current mouse location
|
||||||
|
PointerInfo pointerInfo = MouseInfo.getPointerInfo();
|
||||||
|
Point mouseLocation = (pointerInfo != null) ? pointerInfo.getLocation() : new Point();
|
||||||
|
mouseX = mouseLocation.x;
|
||||||
|
mouseY = mouseLocation.y;
|
||||||
|
|
||||||
|
// check whether popup is showing, which is e.g. not the case if it is empty
|
||||||
|
JPopupMenu popup = (JPopupMenu) path[subMenuIndex];
|
||||||
|
if( !popup.isShowing() ) {
|
||||||
|
uninstallEventQueue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// get invoker screen bounds
|
||||||
|
Component invoker = popup.getInvoker();
|
||||||
|
invokerBounds = (invoker != null)
|
||||||
|
? new Rectangle( invoker.getLocationOnScreen(), invoker.getSize() )
|
||||||
|
: null;
|
||||||
|
|
||||||
|
// check whether mouse location is within invoker
|
||||||
|
if( invokerBounds != null && !invokerBounds.contains( mouseX, mouseY ) ) {
|
||||||
|
uninstallEventQueue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// compute top/bottom target locations
|
||||||
|
Point popupLocation = popup.getLocationOnScreen();
|
||||||
|
Dimension popupSize = popup.getSize();
|
||||||
|
targetX = (mouseX < popupLocation.x + (popupSize.width / 2))
|
||||||
|
? popupLocation.x
|
||||||
|
: popupLocation.x + popupSize.width;
|
||||||
|
targetTopY = popupLocation.y;
|
||||||
|
targetBottomY = popupLocation.y + popupSize.height;
|
||||||
|
|
||||||
|
// install own event queue to supress mouse events when mouse is moved within safe triangle
|
||||||
|
if( subMenuEventQueue == null )
|
||||||
|
subMenuEventQueue = new SubMenuEventQueue();
|
||||||
|
|
||||||
|
// create safe triangle painter
|
||||||
|
if( safeTrianglePainter == null && UIManager.getBoolean( KEY_SHOW_SAFE_TRIANGLE ) )
|
||||||
|
safeTrianglePainter = new SafeTrianglePainter( popup );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void uninstallEventQueue() {
|
||||||
|
if( subMenuEventQueue != null ) {
|
||||||
|
subMenuEventQueue.uninstall();
|
||||||
|
subMenuEventQueue = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( safeTrianglePainter != null ) {
|
||||||
|
safeTrianglePainter.uninstall();
|
||||||
|
safeTrianglePainter = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private int findSubMenu( MenuElement[] path ) {
|
||||||
|
for( int i = path.length - 1; i >= 1; i-- ) {
|
||||||
|
if( path[i] instanceof JPopupMenu &&
|
||||||
|
path[i - 1] instanceof JMenu &&
|
||||||
|
!((JMenu)path[i - 1]).isTopLevelMenu() )
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Polygon createSafeTriangle() {
|
||||||
|
return new Polygon(
|
||||||
|
new int[] { mouseX, targetX, targetX },
|
||||||
|
new int[] { mouseY, targetTopY, targetBottomY },
|
||||||
|
3 );
|
||||||
|
}
|
||||||
|
|
||||||
|
//---- class SubMenuEventQueue --------------------------------------------
|
||||||
|
|
||||||
|
private class SubMenuEventQueue
|
||||||
|
extends EventQueue
|
||||||
|
{
|
||||||
|
private Timer mouseUpdateTimer;
|
||||||
|
private Timer timeoutTimer;
|
||||||
|
|
||||||
|
private int newMouseX;
|
||||||
|
private int newMouseY;
|
||||||
|
private AWTEvent lastMouseEvent;
|
||||||
|
|
||||||
|
SubMenuEventQueue() {
|
||||||
|
// timer used to slightly delay update of mouse location used for safe triangle
|
||||||
|
mouseUpdateTimer = new Timer( 50, e -> {
|
||||||
|
mouseX = newMouseX;
|
||||||
|
mouseY = newMouseY;
|
||||||
|
|
||||||
|
if( safeTrianglePainter != null )
|
||||||
|
safeTrianglePainter.repaint();
|
||||||
|
} );
|
||||||
|
mouseUpdateTimer.setRepeats( false );
|
||||||
|
|
||||||
|
// timer used to timeout safe triangle when mouse stops moving
|
||||||
|
timeoutTimer = new Timer( 200, e -> {
|
||||||
|
if( invokerBounds != null && !invokerBounds.contains( newMouseX, newMouseY ) ) {
|
||||||
|
// post last mouse event, which selects menu item at mouse location
|
||||||
|
if( lastMouseEvent != null ) {
|
||||||
|
postEvent( lastMouseEvent );
|
||||||
|
lastMouseEvent = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
uninstallEventQueue();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
timeoutTimer.setRepeats( false );
|
||||||
|
|
||||||
|
Toolkit.getDefaultToolkit().getSystemEventQueue().push( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
void uninstall() {
|
||||||
|
mouseUpdateTimer.stop();
|
||||||
|
mouseUpdateTimer = null;
|
||||||
|
|
||||||
|
timeoutTimer.stop();
|
||||||
|
timeoutTimer = null;
|
||||||
|
|
||||||
|
lastMouseEvent = null;
|
||||||
|
|
||||||
|
super.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void dispatchEvent( AWTEvent e ) {
|
||||||
|
int id = e.getID();
|
||||||
|
|
||||||
|
if( e instanceof MouseEvent &&
|
||||||
|
(id == MouseEvent.MOUSE_MOVED || id == MouseEvent.MOUSE_DRAGGED) )
|
||||||
|
{
|
||||||
|
newMouseX = ((MouseEvent)e).getXOnScreen();
|
||||||
|
newMouseY = ((MouseEvent)e).getYOnScreen();
|
||||||
|
|
||||||
|
if( safeTrianglePainter != null )
|
||||||
|
safeTrianglePainter.repaint();
|
||||||
|
|
||||||
|
mouseUpdateTimer.stop();
|
||||||
|
timeoutTimer.stop();
|
||||||
|
|
||||||
|
// check whether mouse moved within safe triangle
|
||||||
|
if( createSafeTriangle().contains( newMouseX, newMouseY ) ) {
|
||||||
|
// update mouse location delayed (this changes the safe triangle)
|
||||||
|
mouseUpdateTimer.start();
|
||||||
|
|
||||||
|
timeoutTimer.start();
|
||||||
|
|
||||||
|
// remember last mouse event, which will be posted if the mouse stops moving
|
||||||
|
lastMouseEvent = e;
|
||||||
|
|
||||||
|
// ignore mouse event
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// update mouse location immediately (this changes the safe triangle)
|
||||||
|
mouseX = newMouseX;
|
||||||
|
mouseY = newMouseY;
|
||||||
|
}
|
||||||
|
|
||||||
|
super.dispatchEvent( e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//---- class SafeTrianglePainter ------------------------------------------
|
||||||
|
|
||||||
|
private class SafeTrianglePainter
|
||||||
|
extends JComponent
|
||||||
|
{
|
||||||
|
SafeTrianglePainter( JPopupMenu popup ) {
|
||||||
|
Window window = SwingUtilities.windowForComponent( popup.getInvoker() );
|
||||||
|
if( window instanceof RootPaneContainer ) {
|
||||||
|
JLayeredPane layeredPane = ((RootPaneContainer)window).getLayeredPane();
|
||||||
|
setSize( layeredPane.getSize() );
|
||||||
|
layeredPane.add( this, new Integer( JLayeredPane.POPUP_LAYER + 1 ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void uninstall() {
|
||||||
|
Container parent = getParent();
|
||||||
|
if( parent != null ) {
|
||||||
|
parent.remove( this );
|
||||||
|
parent.repaint();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void paintComponent( Graphics g ) {
|
||||||
|
Point locationOnScreen = getLocationOnScreen();
|
||||||
|
g.translate( -locationOnScreen.x, -locationOnScreen.y );
|
||||||
|
|
||||||
|
g.setColor( Color.red );
|
||||||
|
((Graphics2D)g).draw( createSafeTriangle() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -350,7 +350,7 @@ class UIDefaultsLoader
|
|||||||
enum ValueType { UNKNOWN, STRING, BOOLEAN, CHARACTER, INTEGER, INTEGERORFLOAT, FLOAT, BORDER, ICON, INSETS, DIMENSION, COLOR, FONT,
|
enum ValueType { UNKNOWN, STRING, BOOLEAN, CHARACTER, INTEGER, INTEGERORFLOAT, FLOAT, BORDER, ICON, INSETS, DIMENSION, COLOR, FONT,
|
||||||
SCALEDINTEGER, SCALEDFLOAT, SCALEDINSETS, SCALEDDIMENSION, INSTANCE, CLASS, GRAYFILTER, NULL, LAZY }
|
SCALEDINTEGER, SCALEDFLOAT, SCALEDINSETS, SCALEDDIMENSION, INSTANCE, CLASS, GRAYFILTER, NULL, LAZY }
|
||||||
|
|
||||||
private static ValueType[] tempResultValueType = new ValueType[1];
|
private static final ValueType[] tempResultValueType = new ValueType[1];
|
||||||
private static Map<Class<?>, ValueType> javaValueTypes;
|
private static Map<Class<?>, ValueType> javaValueTypes;
|
||||||
private static Map<String, ValueType> knownValueTypes;
|
private static Map<String, ValueType> knownValueTypes;
|
||||||
|
|
||||||
@@ -466,6 +466,10 @@ class UIDefaultsLoader
|
|||||||
if( knownValueTypes == null ) {
|
if( knownValueTypes == null ) {
|
||||||
// create lazy
|
// create lazy
|
||||||
knownValueTypes = new HashMap<>();
|
knownValueTypes = new HashMap<>();
|
||||||
|
// system colors
|
||||||
|
knownValueTypes.put( "activeCaptionBorder", ValueType.COLOR );
|
||||||
|
knownValueTypes.put( "inactiveCaptionBorder", ValueType.COLOR );
|
||||||
|
knownValueTypes.put( "windowBorder", ValueType.COLOR );
|
||||||
// SplitPane
|
// SplitPane
|
||||||
knownValueTypes.put( "SplitPane.dividerSize", ValueType.INTEGER );
|
knownValueTypes.put( "SplitPane.dividerSize", ValueType.INTEGER );
|
||||||
knownValueTypes.put( "SplitPaneDivider.gripDotSize", ValueType.INTEGER );
|
knownValueTypes.put( "SplitPaneDivider.gripDotSize", ValueType.INTEGER );
|
||||||
@@ -780,6 +784,7 @@ class UIDefaultsLoader
|
|||||||
case "tint": return parseColorMix( "#fff", params, resolver, reportError );
|
case "tint": return parseColorMix( "#fff", params, resolver, reportError );
|
||||||
case "shade": return parseColorMix( "#000", params, resolver, reportError );
|
case "shade": return parseColorMix( "#000", params, resolver, reportError );
|
||||||
case "contrast": return parseColorContrast( params, resolver, reportError );
|
case "contrast": return parseColorContrast( params, resolver, reportError );
|
||||||
|
case "over": return parseColorOver( params, resolver, reportError );
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
parseColorDepth--;
|
parseColorDepth--;
|
||||||
@@ -792,7 +797,7 @@ class UIDefaultsLoader
|
|||||||
* Syntax: if(condition,trueValue,falseValue)
|
* Syntax: if(condition,trueValue,falseValue)
|
||||||
* <p>
|
* <p>
|
||||||
* This "if" function is only used if the "if" is passed as parameter to another
|
* This "if" function is only used if the "if" is passed as parameter to another
|
||||||
* color function. Otherwise the general "if" function is used.
|
* color function. Otherwise, the general "if" function is used.
|
||||||
*/
|
*/
|
||||||
private static Object parseColorIf( String value, List<String> params, Function<String, String> resolver, boolean reportError ) {
|
private static Object parseColorIf( String value, List<String> params, Function<String, String> resolver, boolean reportError ) {
|
||||||
if( params.size() != 3 )
|
if( params.size() != 3 )
|
||||||
@@ -847,7 +852,7 @@ class UIDefaultsLoader
|
|||||||
int lightness = parsePercentage( params.get( 2 ) );
|
int lightness = parsePercentage( params.get( 2 ) );
|
||||||
int alpha = hasAlpha ? parsePercentage( params.get( 3 ) ) : 100;
|
int alpha = hasAlpha ? parsePercentage( params.get( 3 ) ) : 100;
|
||||||
|
|
||||||
float[] hsl = new float[] { hue, saturation, lightness };
|
float[] hsl = { hue, saturation, lightness };
|
||||||
return new ColorUIResource( HSLColor.toRGB( hsl, alpha / 100f ) );
|
return new ColorUIResource( HSLColor.toRGB( hsl, alpha / 100f ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1041,6 +1046,33 @@ class UIDefaultsLoader
|
|||||||
return parseColorOrFunction( resolver.apply( darkOrLightColor ), resolver, reportError );
|
return parseColorOrFunction( resolver.apply( darkOrLightColor ), resolver, reportError );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Syntax: over(foreground,background)
|
||||||
|
* - foreground: a foreground color (e.g. #f00) or a color function;
|
||||||
|
* the alpha of this color is used as weight to mix the two colors
|
||||||
|
* - background: a background color (e.g. #f00) or a color function
|
||||||
|
*/
|
||||||
|
private static Object parseColorOver( List<String> params, Function<String, String> resolver, boolean reportError ) {
|
||||||
|
String foregroundStr = params.get( 0 );
|
||||||
|
String backgroundStr = params.get( 1 );
|
||||||
|
|
||||||
|
// parse foreground color
|
||||||
|
ColorUIResource foreground = (ColorUIResource) parseColorOrFunction( resolver.apply( foregroundStr ), resolver, reportError );
|
||||||
|
if( foreground == null || foreground.getAlpha() == 255 )
|
||||||
|
return foreground;
|
||||||
|
|
||||||
|
Color foreground2 = new Color( foreground.getRGB() );
|
||||||
|
|
||||||
|
// parse background color
|
||||||
|
ColorUIResource background = (ColorUIResource) parseColorOrFunction( resolver.apply( backgroundStr ), resolver, reportError );
|
||||||
|
if( background == null )
|
||||||
|
return foreground2;
|
||||||
|
|
||||||
|
// create new color
|
||||||
|
float weight = foreground.getAlpha() / 255f;
|
||||||
|
return new ColorUIResource( ColorFunctions.mix( foreground2, background, weight ) );
|
||||||
|
}
|
||||||
|
|
||||||
private static Object parseFunctionBaseColor( String colorStr, ColorFunction function,
|
private static Object parseFunctionBaseColor( String colorStr, ColorFunction function,
|
||||||
boolean derived, Function<String, String> resolver, boolean reportError )
|
boolean derived, Function<String, String> resolver, boolean reportError )
|
||||||
{
|
{
|
||||||
@@ -1209,7 +1241,7 @@ class UIDefaultsLoader
|
|||||||
}
|
}
|
||||||
|
|
||||||
Integer integer = parseInteger( value, true );
|
Integer integer = parseInteger( value, true );
|
||||||
if( integer.intValue() < min || integer.intValue() > max )
|
if( integer < min || integer > max )
|
||||||
throw new NumberFormatException( "integer '" + value + "' out of range (" + min + '-' + max + ')' );
|
throw new NumberFormatException( "integer '" + value + "' out of range (" + min + '-' + max + ')' );
|
||||||
return integer;
|
return integer;
|
||||||
}
|
}
|
||||||
@@ -1250,28 +1282,28 @@ class UIDefaultsLoader
|
|||||||
|
|
||||||
private static ActiveValue parseScaledInteger( String value ) {
|
private static ActiveValue parseScaledInteger( String value ) {
|
||||||
int val = parseInteger( value, true );
|
int val = parseInteger( value, true );
|
||||||
return (ActiveValue) t -> {
|
return t -> {
|
||||||
return UIScale.scale( val );
|
return UIScale.scale( val );
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ActiveValue parseScaledFloat( String value ) {
|
private static ActiveValue parseScaledFloat( String value ) {
|
||||||
float val = parseFloat( value, true );
|
float val = parseFloat( value, true );
|
||||||
return (ActiveValue) t -> {
|
return t -> {
|
||||||
return UIScale.scale( val );
|
return UIScale.scale( val );
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ActiveValue parseScaledInsets( String value ) {
|
private static ActiveValue parseScaledInsets( String value ) {
|
||||||
Insets insets = parseInsets( value );
|
Insets insets = parseInsets( value );
|
||||||
return (ActiveValue) t -> {
|
return t -> {
|
||||||
return UIScale.scale( insets );
|
return UIScale.scale( insets );
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ActiveValue parseScaledDimension( String value ) {
|
private static ActiveValue parseScaledDimension( String value ) {
|
||||||
Dimension dimension = parseDimension( value );
|
Dimension dimension = parseDimension( value );
|
||||||
return (ActiveValue) t -> {
|
return t -> {
|
||||||
return UIScale.scale( dimension );
|
return UIScale.scale( dimension );
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,13 +23,13 @@ import java.awt.Graphics2D;
|
|||||||
import com.formdev.flatlaf.util.AnimatedIcon;
|
import com.formdev.flatlaf.util.AnimatedIcon;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for animated icons that scales width and height, creates and initializes
|
* Base class for animated icons that scale width and height, creates and initializes
|
||||||
* a scaled graphics context for icon painting.
|
* a scaled graphics context for icon painting.
|
||||||
* <p>
|
* <p>
|
||||||
* Subclasses do not need to scale icon painting.
|
* Subclasses do not need to scale icon painting.
|
||||||
* <p>
|
* <p>
|
||||||
* This class does not store any state information (needed for animation) in its instance.
|
* This class does not store any state information (needed for animation) in its instance.
|
||||||
* Instead a client property is set on the painted component.
|
* Instead, a client property is set on the painted component.
|
||||||
* This makes it possible to use a share icon instance for multiple components.
|
* This makes it possible to use a share icon instance for multiple components.
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ public class FlatAscendingSortIcon
|
|||||||
boolean chevron = this.chevron;
|
boolean chevron = this.chevron;
|
||||||
Color sortIconColor = this.sortIconColor;
|
Color sortIconColor = this.sortIconColor;
|
||||||
|
|
||||||
// Because this icons are always shared for all table headers,
|
// Because this icon is always shared for all table headers,
|
||||||
// get icon specific style from FlatTableHeaderUI.
|
// get icon specific style from FlatTableHeaderUI.
|
||||||
JTableHeader tableHeader = (JTableHeader) SwingUtilities.getAncestorOfClass( JTableHeader.class, c );
|
JTableHeader tableHeader = (JTableHeader) SwingUtilities.getAncestorOfClass( JTableHeader.class, c );
|
||||||
if( tableHeader != null ) {
|
if( tableHeader != null ) {
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ public class FlatTreeCollapsedIcon
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Because this icons are always shared for all trees,
|
* Because this icon is always shared for all trees,
|
||||||
* get icon specific style from FlatTreeUI.
|
* get icon specific style from FlatTreeUI.
|
||||||
*/
|
*/
|
||||||
static <T> T getStyleFromTreeUI( Component c, Function<FlatTreeUI, T> f ) {
|
static <T> T getStyleFromTreeUI( Component c, Function<FlatTreeUI, T> f ) {
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ package com.formdev.flatlaf.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
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ public class FlatArrowButton
|
|||||||
extends BasicArrowButton
|
extends BasicArrowButton
|
||||||
implements UIResource
|
implements UIResource
|
||||||
{
|
{
|
||||||
public static final int DEFAULT_ARROW_WIDTH = 8;
|
public static final int DEFAULT_ARROW_WIDTH = 9;
|
||||||
|
|
||||||
protected boolean chevron;
|
protected boolean chevron;
|
||||||
protected Color foreground;
|
protected Color foreground;
|
||||||
@@ -211,6 +211,6 @@ public class FlatArrowButton
|
|||||||
if( vert && parent instanceof JComponent && FlatUIUtils.hasRoundBorder( (JComponent) parent ) )
|
if( vert && parent instanceof JComponent && FlatUIUtils.hasRoundBorder( (JComponent) parent ) )
|
||||||
x -= scale( parent.getComponentOrientation().isLeftToRight() ? 1 : -1 );
|
x -= scale( parent.getComponentOrientation().isLeftToRight() ? 1 : -1 );
|
||||||
|
|
||||||
FlatUIUtils.paintArrow( g, x, 0, getWidth(), getHeight(), getDirection(), chevron, arrowWidth, xOffset, yOffset );
|
FlatUIUtils.paintArrow( g, x, 0, getWidth(), getHeight(), getDirection(), chevron, getArrowWidth(), getXOffset(), getYOffset() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -159,7 +159,7 @@ public class FlatButtonBorder
|
|||||||
public Insets getBorderInsets( Component c, Insets insets ) {
|
public Insets getBorderInsets( Component c, Insets insets ) {
|
||||||
if( FlatButtonUI.isToolBarButton( c ) ) {
|
if( FlatButtonUI.isToolBarButton( c ) ) {
|
||||||
// In toolbars, use button margin only if explicitly set.
|
// In toolbars, use button margin only if explicitly set.
|
||||||
// Otherwise use toolbar margin specified in UI defaults.
|
// Otherwise, use toolbar margin specified in UI defaults.
|
||||||
Insets margin = (c instanceof AbstractButton)
|
Insets margin = (c instanceof AbstractButton)
|
||||||
? ((AbstractButton)c).getMargin()
|
? ((AbstractButton)c).getMargin()
|
||||||
: null;
|
: null;
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ import javax.swing.JTextField;
|
|||||||
import javax.swing.JToggleButton;
|
import javax.swing.JToggleButton;
|
||||||
import javax.swing.JToolBar;
|
import javax.swing.JToolBar;
|
||||||
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.ButtonUI;
|
import javax.swing.plaf.ButtonUI;
|
||||||
@@ -77,20 +78,27 @@ import com.formdev.flatlaf.util.UIScale;
|
|||||||
* @uiDefault Button.startBackground Color optional; if set, a gradient paint is used and Button.background is ignored
|
* @uiDefault Button.startBackground Color optional; if set, a gradient paint is used and Button.background is ignored
|
||||||
* @uiDefault Button.endBackground Color optional; if set, a gradient paint is used
|
* @uiDefault Button.endBackground Color optional; if set, a gradient paint is used
|
||||||
* @uiDefault Button.focusedBackground Color optional
|
* @uiDefault Button.focusedBackground Color optional
|
||||||
|
* @uiDefault Button.focusedForeground Color optional
|
||||||
* @uiDefault Button.hoverBackground Color optional
|
* @uiDefault Button.hoverBackground Color optional
|
||||||
|
* @uiDefault Button.hoverForeground Color optional
|
||||||
* @uiDefault Button.pressedBackground Color optional
|
* @uiDefault Button.pressedBackground Color optional
|
||||||
|
* @uiDefault Button.pressedForeground Color optional
|
||||||
* @uiDefault Button.selectedBackground Color
|
* @uiDefault Button.selectedBackground Color
|
||||||
* @uiDefault Button.selectedForeground Color
|
* @uiDefault Button.selectedForeground Color
|
||||||
* @uiDefault Button.disabledBackground Color optional
|
* @uiDefault Button.disabledBackground Color optional
|
||||||
* @uiDefault Button.disabledText Color
|
* @uiDefault Button.disabledText Color
|
||||||
* @uiDefault Button.disabledSelectedBackground Color
|
* @uiDefault Button.disabledSelectedBackground Color
|
||||||
|
* @uiDefault Button.disabledSelectedForeground Color optional
|
||||||
* @uiDefault Button.default.background Color
|
* @uiDefault Button.default.background Color
|
||||||
* @uiDefault Button.default.startBackground Color optional; if set, a gradient paint is used and Button.default.background is ignored
|
* @uiDefault Button.default.startBackground Color optional; if set, a gradient paint is used and Button.default.background is ignored
|
||||||
* @uiDefault Button.default.endBackground Color optional; if set, a gradient paint is used
|
* @uiDefault Button.default.endBackground Color optional; if set, a gradient paint is used
|
||||||
* @uiDefault Button.default.foreground Color
|
* @uiDefault Button.default.foreground Color
|
||||||
* @uiDefault Button.default.focusedBackground Color optional
|
* @uiDefault Button.default.focusedBackground Color optional
|
||||||
|
* @uiDefault Button.default.focusedForeground Color optional
|
||||||
* @uiDefault Button.default.hoverBackground Color optional
|
* @uiDefault Button.default.hoverBackground Color optional
|
||||||
|
* @uiDefault Button.default.hoverForeground Color optional
|
||||||
* @uiDefault Button.default.pressedBackground Color optional
|
* @uiDefault Button.default.pressedBackground Color optional
|
||||||
|
* @uiDefault Button.default.pressedForeground Color optional
|
||||||
* @uiDefault Button.default.boldText boolean
|
* @uiDefault Button.default.boldText boolean
|
||||||
* @uiDefault Button.paintShadow boolean default is false
|
* @uiDefault Button.paintShadow boolean default is false
|
||||||
* @uiDefault Button.shadowWidth int default is 2
|
* @uiDefault Button.shadowWidth int default is 2
|
||||||
@@ -98,8 +106,13 @@ import com.formdev.flatlaf.util.UIScale;
|
|||||||
* @uiDefault Button.default.shadowColor Color optional
|
* @uiDefault Button.default.shadowColor Color optional
|
||||||
* @uiDefault Button.toolbar.spacingInsets Insets
|
* @uiDefault Button.toolbar.spacingInsets Insets
|
||||||
* @uiDefault Button.toolbar.hoverBackground Color
|
* @uiDefault Button.toolbar.hoverBackground Color
|
||||||
|
* @uiDefault Button.toolbar.hoverForeground Color optional
|
||||||
* @uiDefault Button.toolbar.pressedBackground Color
|
* @uiDefault Button.toolbar.pressedBackground Color
|
||||||
|
* @uiDefault Button.toolbar.pressedForeground Color optional
|
||||||
* @uiDefault Button.toolbar.selectedBackground Color
|
* @uiDefault Button.toolbar.selectedBackground Color
|
||||||
|
* @uiDefault Button.toolbar.selectedForeground Color optional
|
||||||
|
* @uiDefault Button.toolbar.disabledSelectedBackground Color optional
|
||||||
|
* @uiDefault Button.toolbar.disabledSelectedForeground Color optional
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
@@ -116,20 +129,27 @@ public class FlatButtonUI
|
|||||||
protected Color startBackground;
|
protected Color startBackground;
|
||||||
protected Color endBackground;
|
protected Color endBackground;
|
||||||
@Styleable protected Color focusedBackground;
|
@Styleable protected Color focusedBackground;
|
||||||
|
/** @since 2.3 */ @Styleable protected Color focusedForeground;
|
||||||
@Styleable protected Color hoverBackground;
|
@Styleable protected Color hoverBackground;
|
||||||
|
/** @since 2.3 */ @Styleable protected Color hoverForeground;
|
||||||
@Styleable protected Color pressedBackground;
|
@Styleable protected Color pressedBackground;
|
||||||
|
/** @since 2.3 */ @Styleable protected Color pressedForeground;
|
||||||
@Styleable protected Color selectedBackground;
|
@Styleable protected Color selectedBackground;
|
||||||
@Styleable protected Color selectedForeground;
|
@Styleable protected Color selectedForeground;
|
||||||
@Styleable protected Color disabledBackground;
|
@Styleable protected Color disabledBackground;
|
||||||
@Styleable protected Color disabledText;
|
@Styleable protected Color disabledText;
|
||||||
@Styleable protected Color disabledSelectedBackground;
|
@Styleable protected Color disabledSelectedBackground;
|
||||||
|
/** @since 2.3 */ @Styleable protected Color disabledSelectedForeground;
|
||||||
|
|
||||||
@Styleable(dot=true) protected Color defaultBackground;
|
@Styleable(dot=true) protected Color defaultBackground;
|
||||||
protected Color defaultEndBackground;
|
protected Color defaultEndBackground;
|
||||||
@Styleable(dot=true) protected Color defaultForeground;
|
@Styleable(dot=true) protected Color defaultForeground;
|
||||||
@Styleable(dot=true) protected Color defaultFocusedBackground;
|
@Styleable(dot=true) protected Color defaultFocusedBackground;
|
||||||
|
/** @since 2.3 */ @Styleable(dot=true) protected Color defaultFocusedForeground;
|
||||||
@Styleable(dot=true) protected Color defaultHoverBackground;
|
@Styleable(dot=true) protected Color defaultHoverBackground;
|
||||||
|
/** @since 2.3 */ @Styleable(dot=true) protected Color defaultHoverForeground;
|
||||||
@Styleable(dot=true) protected Color defaultPressedBackground;
|
@Styleable(dot=true) protected Color defaultPressedBackground;
|
||||||
|
/** @since 2.3 */ @Styleable(dot=true) protected Color defaultPressedForeground;
|
||||||
@Styleable(dot=true) protected boolean defaultBoldText;
|
@Styleable(dot=true) protected boolean defaultBoldText;
|
||||||
|
|
||||||
@Styleable protected boolean paintShadow;
|
@Styleable protected boolean paintShadow;
|
||||||
@@ -138,8 +158,13 @@ public class FlatButtonUI
|
|||||||
@Styleable(dot=true) protected Color defaultShadowColor;
|
@Styleable(dot=true) protected Color defaultShadowColor;
|
||||||
|
|
||||||
@Styleable(dot=true) protected Color toolbarHoverBackground;
|
@Styleable(dot=true) protected Color toolbarHoverBackground;
|
||||||
|
/** @since 2.3 */ @Styleable(dot=true) protected Color toolbarHoverForeground;
|
||||||
@Styleable(dot=true) protected Color toolbarPressedBackground;
|
@Styleable(dot=true) protected Color toolbarPressedBackground;
|
||||||
|
/** @since 2.3 */ @Styleable(dot=true) protected Color toolbarPressedForeground;
|
||||||
@Styleable(dot=true) protected Color toolbarSelectedBackground;
|
@Styleable(dot=true) protected Color toolbarSelectedBackground;
|
||||||
|
/** @since 2.3 */ @Styleable(dot=true) protected Color toolbarSelectedForeground;
|
||||||
|
/** @since 2.3 */ @Styleable(dot=true) protected Color toolbarDisabledSelectedBackground;
|
||||||
|
/** @since 2.3 */ @Styleable(dot=true) protected Color toolbarDisabledSelectedForeground;
|
||||||
|
|
||||||
// only used via styling (not in UI defaults, but has likewise client properties)
|
// only used via styling (not in UI defaults, but has likewise client properties)
|
||||||
/** @since 2 */ @Styleable protected String buttonType;
|
/** @since 2 */ @Styleable protected String buttonType;
|
||||||
@@ -189,20 +214,27 @@ public class FlatButtonUI
|
|||||||
startBackground = UIManager.getColor( prefix + "startBackground" );
|
startBackground = UIManager.getColor( prefix + "startBackground" );
|
||||||
endBackground = UIManager.getColor( prefix + "endBackground" );
|
endBackground = UIManager.getColor( prefix + "endBackground" );
|
||||||
focusedBackground = UIManager.getColor( prefix + "focusedBackground" );
|
focusedBackground = UIManager.getColor( prefix + "focusedBackground" );
|
||||||
|
focusedForeground = UIManager.getColor( prefix + "focusedForeground" );
|
||||||
hoverBackground = UIManager.getColor( prefix + "hoverBackground" );
|
hoverBackground = UIManager.getColor( prefix + "hoverBackground" );
|
||||||
|
hoverForeground = UIManager.getColor( prefix + "hoverForeground" );
|
||||||
pressedBackground = UIManager.getColor( prefix + "pressedBackground" );
|
pressedBackground = UIManager.getColor( prefix + "pressedBackground" );
|
||||||
|
pressedForeground = UIManager.getColor( prefix + "pressedForeground" );
|
||||||
selectedBackground = UIManager.getColor( prefix + "selectedBackground" );
|
selectedBackground = UIManager.getColor( prefix + "selectedBackground" );
|
||||||
selectedForeground = UIManager.getColor( prefix + "selectedForeground" );
|
selectedForeground = UIManager.getColor( prefix + "selectedForeground" );
|
||||||
disabledBackground = UIManager.getColor( prefix + "disabledBackground" );
|
disabledBackground = UIManager.getColor( prefix + "disabledBackground" );
|
||||||
disabledText = UIManager.getColor( prefix + "disabledText" );
|
disabledText = UIManager.getColor( prefix + "disabledText" );
|
||||||
disabledSelectedBackground = UIManager.getColor( prefix + "disabledSelectedBackground" );
|
disabledSelectedBackground = UIManager.getColor( prefix + "disabledSelectedBackground" );
|
||||||
|
disabledSelectedForeground = UIManager.getColor( prefix + "disabledSelectedForeground" );
|
||||||
|
|
||||||
defaultBackground = FlatUIUtils.getUIColor( "Button.default.startBackground", "Button.default.background" );
|
defaultBackground = FlatUIUtils.getUIColor( "Button.default.startBackground", "Button.default.background" );
|
||||||
defaultEndBackground = UIManager.getColor( "Button.default.endBackground" );
|
defaultEndBackground = UIManager.getColor( "Button.default.endBackground" );
|
||||||
defaultForeground = UIManager.getColor( "Button.default.foreground" );
|
defaultForeground = UIManager.getColor( "Button.default.foreground" );
|
||||||
defaultFocusedBackground = UIManager.getColor( "Button.default.focusedBackground" );
|
defaultFocusedBackground = UIManager.getColor( "Button.default.focusedBackground" );
|
||||||
|
defaultFocusedForeground = UIManager.getColor( "Button.default.focusedForeground" );
|
||||||
defaultHoverBackground = UIManager.getColor( "Button.default.hoverBackground" );
|
defaultHoverBackground = UIManager.getColor( "Button.default.hoverBackground" );
|
||||||
|
defaultHoverForeground = UIManager.getColor( "Button.default.hoverForeground" );
|
||||||
defaultPressedBackground = UIManager.getColor( "Button.default.pressedBackground" );
|
defaultPressedBackground = UIManager.getColor( "Button.default.pressedBackground" );
|
||||||
|
defaultPressedForeground = UIManager.getColor( "Button.default.pressedForeground" );
|
||||||
defaultBoldText = UIManager.getBoolean( "Button.default.boldText" );
|
defaultBoldText = UIManager.getBoolean( "Button.default.boldText" );
|
||||||
|
|
||||||
paintShadow = UIManager.getBoolean( "Button.paintShadow" );
|
paintShadow = UIManager.getBoolean( "Button.paintShadow" );
|
||||||
@@ -211,8 +243,13 @@ public class FlatButtonUI
|
|||||||
defaultShadowColor = UIManager.getColor( "Button.default.shadowColor" );
|
defaultShadowColor = UIManager.getColor( "Button.default.shadowColor" );
|
||||||
|
|
||||||
toolbarHoverBackground = UIManager.getColor( prefix + "toolbar.hoverBackground" );
|
toolbarHoverBackground = UIManager.getColor( prefix + "toolbar.hoverBackground" );
|
||||||
|
toolbarHoverForeground = UIManager.getColor( prefix + "toolbar.hoverForeground" );
|
||||||
toolbarPressedBackground = UIManager.getColor( prefix + "toolbar.pressedBackground" );
|
toolbarPressedBackground = UIManager.getColor( prefix + "toolbar.pressedBackground" );
|
||||||
|
toolbarPressedForeground = UIManager.getColor( prefix + "toolbar.pressedForeground" );
|
||||||
toolbarSelectedBackground = UIManager.getColor( prefix + "toolbar.selectedBackground" );
|
toolbarSelectedBackground = UIManager.getColor( prefix + "toolbar.selectedBackground" );
|
||||||
|
toolbarSelectedForeground = UIManager.getColor( prefix + "toolbar.selectedForeground" );
|
||||||
|
toolbarDisabledSelectedBackground = UIManager.getColor( prefix + "toolbar.disabledSelectedBackground" );
|
||||||
|
toolbarDisabledSelectedForeground = UIManager.getColor( prefix + "toolbar.disabledSelectedForeground" );
|
||||||
|
|
||||||
helpButtonIcon = UIManager.getIcon( "HelpButton.icon" );
|
helpButtonIcon = UIManager.getIcon( "HelpButton.icon" );
|
||||||
defaultMargin = UIManager.getInsets( prefix + "margin" );
|
defaultMargin = UIManager.getInsets( prefix + "margin" );
|
||||||
@@ -343,7 +380,7 @@ public class FlatButtonUI
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the button has an icon but no text,
|
* Returns true if the button has an icon but no text,
|
||||||
* or it it does not have an icon and the text is either "..." or one character.
|
* or it does not have an icon and the text is either "..." or one character.
|
||||||
*/
|
*/
|
||||||
static boolean isIconOnlyOrSingleCharacterButton( Component c ) {
|
static boolean isIconOnlyOrSingleCharacterButton( Component c ) {
|
||||||
if( !(c instanceof JButton) && !(c instanceof JToggleButton) )
|
if( !(c instanceof JButton) && !(c instanceof JToggleButton) )
|
||||||
@@ -494,6 +531,23 @@ public class FlatButtonUI
|
|||||||
super.paint( FlatLabelUI.createGraphicsHTMLTextYCorrection( g, c ), c );
|
super.paint( FlatLabelUI.createGraphicsHTMLTextYCorrection( g, c ), c );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void paintIcon( Graphics g, JComponent c, Rectangle iconRect ) {
|
||||||
|
// correct icon location when using bold font for default button
|
||||||
|
int xOffset = defaultBoldPlainWidthDiff( c ) / 2;
|
||||||
|
if( xOffset > 0 ) {
|
||||||
|
boolean ltr = c.getComponentOrientation().isLeftToRight();
|
||||||
|
switch( ((AbstractButton)c).getHorizontalTextPosition() ) {
|
||||||
|
case SwingConstants.RIGHT: iconRect.x -= xOffset; break;
|
||||||
|
case SwingConstants.LEFT: iconRect.x += xOffset; break;
|
||||||
|
case SwingConstants.TRAILING: iconRect.x -= ltr ? xOffset : -xOffset; break;
|
||||||
|
case SwingConstants.LEADING: iconRect.x += ltr ? xOffset : -xOffset; break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
super.paintIcon( g, c, iconRect );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void paintText( Graphics g, AbstractButton b, Rectangle textRect, String text ) {
|
protected void paintText( Graphics g, AbstractButton b, Rectangle textRect, String text ) {
|
||||||
if( isHelpButton( b ) )
|
if( isHelpButton( b ) )
|
||||||
@@ -514,6 +568,8 @@ public class FlatButtonUI
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void paintText( Graphics g, AbstractButton b, Rectangle textRect, String text, Color foreground ) {
|
public static void paintText( Graphics g, AbstractButton b, Rectangle textRect, String text, Color foreground ) {
|
||||||
|
if(foreground == null)
|
||||||
|
foreground=Color.red;
|
||||||
FontMetrics fm = b.getFontMetrics( b.getFont() );
|
FontMetrics fm = b.getFontMetrics( b.getFont() );
|
||||||
int mnemonicIndex = FlatLaf.isShowMnemonics() ? b.getDisplayedMnemonicIndex() : -1;
|
int mnemonicIndex = FlatLaf.isShowMnemonics() ? b.getDisplayedMnemonicIndex() : -1;
|
||||||
|
|
||||||
@@ -527,11 +583,14 @@ public class FlatButtonUI
|
|||||||
|
|
||||||
// selected state
|
// selected state
|
||||||
if( ((AbstractButton)c).isSelected() ) {
|
if( ((AbstractButton)c).isSelected() ) {
|
||||||
// in toolbar use same background colors for disabled and enabled because
|
// in toolbar, if toolbarDisabledSelectedBackground is null,
|
||||||
|
// use same background colors for disabled and enabled because
|
||||||
// we assume that toolbar icon is shown disabled
|
// we assume that toolbar icon is shown disabled
|
||||||
return buttonStateColor( c,
|
return buttonStateColor( c,
|
||||||
toolBarButton ? toolbarSelectedBackground : selectedBackground,
|
toolBarButton ? toolbarSelectedBackground : selectedBackground,
|
||||||
toolBarButton ? toolbarSelectedBackground : disabledSelectedBackground,
|
toolBarButton
|
||||||
|
? (toolbarDisabledSelectedBackground != null ? toolbarDisabledSelectedBackground : toolbarSelectedBackground)
|
||||||
|
: disabledSelectedBackground,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
toolBarButton ? toolbarPressedBackground : pressedBackground );
|
toolBarButton ? toolbarPressedBackground : pressedBackground );
|
||||||
@@ -596,18 +655,48 @@ public class FlatButtonUI
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected Color getForeground( JComponent c ) {
|
protected Color getForeground( JComponent c ) {
|
||||||
if( !c.isEnabled() )
|
boolean toolBarButton = isToolBarButton( c ) || isBorderlessButton( c );
|
||||||
return disabledText;
|
|
||||||
|
|
||||||
if( ((AbstractButton)c).isSelected() && !(isToolBarButton( c ) || isBorderlessButton( c )) )
|
// selected state
|
||||||
return selectedForeground;
|
if( ((AbstractButton)c).isSelected() ) {
|
||||||
|
return buttonStateColor( c,
|
||||||
|
toolBarButton
|
||||||
|
? (toolbarSelectedForeground != null ? toolbarSelectedForeground : c.getForeground())
|
||||||
|
: selectedForeground,
|
||||||
|
toolBarButton
|
||||||
|
? (toolbarDisabledSelectedForeground != null ? toolbarDisabledSelectedForeground : disabledText)
|
||||||
|
: (disabledSelectedForeground != null ? disabledSelectedForeground : disabledText),
|
||||||
|
null,
|
||||||
|
null,
|
||||||
|
toolBarButton ? toolbarPressedForeground : pressedForeground );
|
||||||
|
}
|
||||||
|
|
||||||
|
// toolbar button
|
||||||
|
if( toolBarButton ) {
|
||||||
|
return buttonStateColor( c,
|
||||||
|
c.getForeground(),
|
||||||
|
disabledText,
|
||||||
|
null,
|
||||||
|
toolbarHoverForeground,
|
||||||
|
toolbarPressedForeground );
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean def = isDefaultButton( c );
|
||||||
|
return buttonStateColor( c,
|
||||||
|
getForegroundBase( c, def ),
|
||||||
|
disabledText,
|
||||||
|
isCustomForeground( c.getForeground() ) ? null : (def ? defaultFocusedForeground : focusedForeground),
|
||||||
|
def ? defaultHoverForeground : hoverForeground,
|
||||||
|
def ? defaultPressedForeground : pressedForeground );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since 2.3 */
|
||||||
|
protected Color getForegroundBase( JComponent c, boolean def ) {
|
||||||
// use component foreground if explicitly set
|
// use component foreground if explicitly set
|
||||||
Color fg = c.getForeground();
|
Color fg = c.getForeground();
|
||||||
if( isCustomForeground( fg ) )
|
if( isCustomForeground( fg ) )
|
||||||
return fg;
|
return fg;
|
||||||
|
|
||||||
boolean def = isDefaultButton( c );
|
|
||||||
return def ? defaultForeground : fg;
|
return def ? defaultForeground : fg;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -624,6 +713,9 @@ public class FlatButtonUI
|
|||||||
if( prefSize == null )
|
if( prefSize == null )
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
// increase width when using bold font for default button
|
||||||
|
prefSize.width += defaultBoldPlainWidthDiff( c );
|
||||||
|
|
||||||
// make square or apply minimum width/height
|
// make square or apply minimum width/height
|
||||||
boolean isIconOnlyOrSingleCharacter = isIconOnlyOrSingleCharacterButton( c );
|
boolean isIconOnlyOrSingleCharacter = isIconOnlyOrSingleCharacterButton( c );
|
||||||
if( clientPropertyBoolean( c, SQUARE_SIZE, squareSize ) ) {
|
if( clientPropertyBoolean( c, SQUARE_SIZE, squareSize ) ) {
|
||||||
@@ -644,6 +736,23 @@ public class FlatButtonUI
|
|||||||
return prefSize;
|
return prefSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int defaultBoldPlainWidthDiff( JComponent c ) {
|
||||||
|
if( defaultBoldText && isDefaultButton( c ) && c.getFont() instanceof UIResource ) {
|
||||||
|
String text = ((AbstractButton)c).getText();
|
||||||
|
if( text == null || text.isEmpty() )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
Font font = c.getFont();
|
||||||
|
Font boldFont = font.deriveFont( Font.BOLD );
|
||||||
|
int boldWidth = c.getFontMetrics( boldFont ).stringWidth( text );
|
||||||
|
int plainWidth = c.getFontMetrics( font ).stringWidth( text );
|
||||||
|
if( boldWidth > plainWidth )
|
||||||
|
return boldWidth - plainWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
private boolean hasDefaultMargins( JComponent c ) {
|
private boolean hasDefaultMargins( JComponent c ) {
|
||||||
Insets margin = ((AbstractButton)c).getMargin();
|
Insets margin = ((AbstractButton)c).getMargin();
|
||||||
return margin instanceof UIResource && Objects.equals( margin, defaultMargin );
|
return margin instanceof UIResource && Objects.equals( margin, defaultMargin );
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ public class FlatCaret
|
|||||||
|
|
||||||
// if text component is focused, then caret and selection are visible,
|
// if text component is focused, then caret and selection are visible,
|
||||||
// but when switching theme, the component does not yet have
|
// but when switching theme, the component does not yet have
|
||||||
// an highlighter and the selection is not painted
|
// a highlighter and the selection is not painted
|
||||||
// --> make selection temporary invisible later, then the caret
|
// --> make selection temporary invisible later, then the caret
|
||||||
// adds selection highlights to the text component highlighter
|
// adds selection highlights to the text component highlighter
|
||||||
if( isSelectionVisible() ) {
|
if( isSelectionVisible() ) {
|
||||||
@@ -236,7 +236,7 @@ public class FlatCaret
|
|||||||
if( selectAllOnFocusPolicy == null )
|
if( selectAllOnFocusPolicy == null )
|
||||||
selectAllOnFocusPolicy = this.selectAllOnFocusPolicy;
|
selectAllOnFocusPolicy = this.selectAllOnFocusPolicy;
|
||||||
|
|
||||||
if( SELECT_ALL_ON_FOCUS_POLICY_NEVER.equals( selectAllOnFocusPolicy ) )
|
if( selectAllOnFocusPolicy == null || SELECT_ALL_ON_FOCUS_POLICY_NEVER.equals( selectAllOnFocusPolicy ) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if( !SELECT_ALL_ON_FOCUS_POLICY_ALWAYS.equals( selectAllOnFocusPolicy ) ) {
|
if( !SELECT_ALL_ON_FOCUS_POLICY_ALWAYS.equals( selectAllOnFocusPolicy ) ) {
|
||||||
|
|||||||
@@ -86,6 +86,11 @@ import com.formdev.flatlaf.util.SystemInfo;
|
|||||||
* @uiDefault ComboBox.padding Insets
|
* @uiDefault ComboBox.padding Insets
|
||||||
* @uiDefault ComboBox.squareButton boolean default is true
|
* @uiDefault ComboBox.squareButton boolean default is true
|
||||||
*
|
*
|
||||||
|
* <!-- BasicComboPopup -->
|
||||||
|
*
|
||||||
|
* @uiDefault ComboBox.selectionBackground Color
|
||||||
|
* @uiDefault ComboBox.selectionForeground Color
|
||||||
|
*
|
||||||
* <!-- FlatComboBoxUI -->
|
* <!-- FlatComboBoxUI -->
|
||||||
*
|
*
|
||||||
* @uiDefault ComboBox.minimumWidth int
|
* @uiDefault ComboBox.minimumWidth int
|
||||||
@@ -603,7 +608,7 @@ public class FlatComboBoxUI
|
|||||||
|
|
||||||
boolean shouldValidate = (c instanceof JPanel);
|
boolean shouldValidate = (c instanceof JPanel);
|
||||||
|
|
||||||
paddingBorder.install( c );
|
paddingBorder.install( c, 0 );
|
||||||
currentValuePane.paintComponent( g, c, comboBox, bounds.x, bounds.y, bounds.width, bounds.height, shouldValidate );
|
currentValuePane.paintComponent( g, c, comboBox, bounds.x, bounds.y, bounds.width, bounds.height, shouldValidate );
|
||||||
paddingBorder.uninstall();
|
paddingBorder.uninstall();
|
||||||
|
|
||||||
@@ -677,7 +682,7 @@ public class FlatComboBoxUI
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Dimension getSizeForComponent( Component comp ) {
|
protected Dimension getSizeForComponent( Component comp ) {
|
||||||
paddingBorder.install( comp );
|
paddingBorder.install( comp, 0 );
|
||||||
Dimension size = super.getSizeForComponent( comp );
|
Dimension size = super.getSizeForComponent( comp );
|
||||||
paddingBorder.uninstall();
|
paddingBorder.uninstall();
|
||||||
return size;
|
return size;
|
||||||
@@ -700,7 +705,7 @@ public class FlatComboBoxUI
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
Component editorComponent = comboBox.getEditor().getEditorComponent();
|
Component editorComponent = comboBox.getEditor().getEditorComponent();
|
||||||
return (editorComponent != null) ? FlatUIUtils.isPermanentFocusOwner( editorComponent ) : false;
|
return editorComponent != null && FlatUIUtils.isPermanentFocusOwner( editorComponent );
|
||||||
} else
|
} else
|
||||||
return FlatUIUtils.isPermanentFocusOwner( comboBox );
|
return FlatUIUtils.isPermanentFocusOwner( comboBox );
|
||||||
}
|
}
|
||||||
@@ -895,7 +900,7 @@ public class FlatComboBoxUI
|
|||||||
Component c = renderer.getListCellRendererComponent( list, value, index, isSelected, cellHasFocus );
|
Component c = renderer.getListCellRendererComponent( list, value, index, isSelected, cellHasFocus );
|
||||||
c.applyComponentOrientation( comboBox.getComponentOrientation() );
|
c.applyComponentOrientation( comboBox.getComponentOrientation() );
|
||||||
|
|
||||||
paddingBorder.install( c );
|
paddingBorder.install( c, Math.round( FlatUIUtils.getBorderFocusWidth( comboBox ) ) );
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
@@ -918,6 +923,7 @@ public class FlatComboBoxUI
|
|||||||
private Insets padding;
|
private Insets padding;
|
||||||
private JComponent rendererComponent;
|
private JComponent rendererComponent;
|
||||||
private Border rendererBorder;
|
private Border rendererBorder;
|
||||||
|
private int focusWidth;
|
||||||
|
|
||||||
CellPaddingBorder( Insets padding ) {
|
CellPaddingBorder( Insets padding ) {
|
||||||
this.padding = padding;
|
this.padding = padding;
|
||||||
@@ -925,10 +931,12 @@ 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 ) {
|
synchronized void install( Component c, int focusWidth ) {
|
||||||
if( !(c instanceof JComponent) )
|
if( !(c instanceof JComponent) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
this.focusWidth = focusWidth;
|
||||||
|
|
||||||
JComponent jc = (JComponent) c;
|
JComponent jc = (JComponent) c;
|
||||||
Border oldBorder = jc.getBorder();
|
Border oldBorder = jc.getBorder();
|
||||||
if( oldBorder == this )
|
if( oldBorder == this )
|
||||||
@@ -982,6 +990,12 @@ public class FlatComboBoxUI
|
|||||||
insets.bottom = padding.bottom;
|
insets.bottom = padding.bottom;
|
||||||
insets.right = padding.right;
|
insets.right = padding.right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if used in popup list, add focus width for exact vertical alignment
|
||||||
|
// of text in popup list with text in combobox
|
||||||
|
insets.left += focusWidth;
|
||||||
|
insets.right += focusWidth;
|
||||||
|
|
||||||
return insets;
|
return insets;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ public class FlatEmptyBorder
|
|||||||
protected static Insets scaleInsets( Component c, Insets insets,
|
protected static Insets scaleInsets( Component c, Insets insets,
|
||||||
int top, int left, int bottom, int right )
|
int top, int left, int bottom, int right )
|
||||||
{
|
{
|
||||||
boolean leftToRight = left == right || c.getComponentOrientation().isLeftToRight();
|
boolean leftToRight = left == right || c == null || c.getComponentOrientation().isLeftToRight();
|
||||||
insets.left = scale( leftToRight ? left : right );
|
insets.left = scale( leftToRight ? left : right );
|
||||||
insets.top = scale( top );
|
insets.top = scale( top );
|
||||||
insets.right = scale( leftToRight ? right : left );
|
insets.right = scale( leftToRight ? right : left );
|
||||||
|
|||||||
@@ -19,11 +19,21 @@ package com.formdev.flatlaf.ui;
|
|||||||
import java.awt.BorderLayout;
|
import java.awt.BorderLayout;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.Image;
|
||||||
import java.awt.Insets;
|
import java.awt.Insets;
|
||||||
|
import java.awt.LayoutManager;
|
||||||
|
import java.awt.RenderingHints;
|
||||||
|
import java.beans.PropertyChangeEvent;
|
||||||
|
import java.beans.PropertyChangeListener;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.function.Function;
|
||||||
import javax.swing.AbstractButton;
|
import javax.swing.AbstractButton;
|
||||||
import javax.swing.Box;
|
import javax.swing.Box;
|
||||||
import javax.swing.BoxLayout;
|
import javax.swing.BoxLayout;
|
||||||
|
import javax.swing.ButtonGroup;
|
||||||
import javax.swing.Icon;
|
import javax.swing.Icon;
|
||||||
import javax.swing.ImageIcon;
|
import javax.swing.ImageIcon;
|
||||||
import javax.swing.JButton;
|
import javax.swing.JButton;
|
||||||
@@ -34,12 +44,16 @@ import javax.swing.JPanel;
|
|||||||
import javax.swing.JScrollPane;
|
import javax.swing.JScrollPane;
|
||||||
import javax.swing.JTable;
|
import javax.swing.JTable;
|
||||||
import javax.swing.JToggleButton;
|
import javax.swing.JToggleButton;
|
||||||
|
import javax.swing.JToolBar;
|
||||||
|
import javax.swing.SwingConstants;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
|
import javax.swing.filechooser.FileSystemView;
|
||||||
import javax.swing.filechooser.FileView;
|
import javax.swing.filechooser.FileView;
|
||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
import javax.swing.plaf.metal.MetalFileChooserUI;
|
import javax.swing.plaf.metal.MetalFileChooserUI;
|
||||||
import javax.swing.table.TableCellRenderer;
|
import javax.swing.table.TableCellRenderer;
|
||||||
import com.formdev.flatlaf.FlatClientProperties;
|
import com.formdev.flatlaf.FlatClientProperties;
|
||||||
|
import com.formdev.flatlaf.util.LoggingFacade;
|
||||||
import com.formdev.flatlaf.util.ScaledImageIcon;
|
import com.formdev.flatlaf.util.ScaledImageIcon;
|
||||||
import com.formdev.flatlaf.util.SystemInfo;
|
import com.formdev.flatlaf.util.SystemInfo;
|
||||||
import com.formdev.flatlaf.util.UIScale;
|
import com.formdev.flatlaf.util.UIScale;
|
||||||
@@ -133,12 +147,21 @@ import com.formdev.flatlaf.util.UIScale;
|
|||||||
* @uiDefault FileChooser.listViewActionLabelText String
|
* @uiDefault FileChooser.listViewActionLabelText String
|
||||||
* @uiDefault FileChooser.detailsViewActionLabelText String
|
* @uiDefault FileChooser.detailsViewActionLabelText String
|
||||||
*
|
*
|
||||||
|
* <!-- FlatFileChooserUI -->
|
||||||
|
*
|
||||||
|
* @uiDefault FileChooser.shortcuts.buttonSize Dimension optional; default is 84,64
|
||||||
|
* @uiDefault FileChooser.shortcuts.iconSize Dimension optional; default is 32,32
|
||||||
|
* @uiDefault FileChooser.shortcuts.filesFunction Function<File[], File[]>
|
||||||
|
* @uiDefault FileChooser.shortcuts.displayNameFunction Function<File, String>
|
||||||
|
* @uiDefault FileChooser.shortcuts.iconFunction Function<File, Icon>
|
||||||
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
public class FlatFileChooserUI
|
public class FlatFileChooserUI
|
||||||
extends MetalFileChooserUI
|
extends MetalFileChooserUI
|
||||||
{
|
{
|
||||||
private final FlatFileView fileView = new FlatFileView();
|
private final FlatFileView fileView = new FlatFileView();
|
||||||
|
private FlatShortcutsPanel shortcutsPanel;
|
||||||
|
|
||||||
public static ComponentUI createUI( JComponent c ) {
|
public static ComponentUI createUI( JComponent c ) {
|
||||||
return new FlatFileChooserUI( (JFileChooser) c );
|
return new FlatFileChooserUI( (JFileChooser) c );
|
||||||
@@ -153,6 +176,25 @@ public class FlatFileChooserUI
|
|||||||
super.installComponents( fc );
|
super.installComponents( fc );
|
||||||
|
|
||||||
patchUI( fc );
|
patchUI( fc );
|
||||||
|
|
||||||
|
if( !UIManager.getBoolean( "FileChooser.noPlacesBar" ) ) { // same as in Windows L&F
|
||||||
|
FlatShortcutsPanel panel = createShortcutsPanel( fc );
|
||||||
|
if( panel.getComponentCount() > 0 ) {
|
||||||
|
shortcutsPanel = panel;
|
||||||
|
fc.add( shortcutsPanel, BorderLayout.LINE_START );
|
||||||
|
fc.addPropertyChangeListener( shortcutsPanel );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void uninstallComponents( JFileChooser fc ) {
|
||||||
|
super.uninstallComponents( fc );
|
||||||
|
|
||||||
|
if( shortcutsPanel != null ) {
|
||||||
|
fc.removePropertyChangeListener( shortcutsPanel );
|
||||||
|
shortcutsPanel = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void patchUI( JFileChooser fc ) {
|
private void patchUI( JFileChooser fc ) {
|
||||||
@@ -192,6 +234,25 @@ public class FlatFileChooserUI
|
|||||||
} catch( ArrayIndexOutOfBoundsException ex ) {
|
} catch( ArrayIndexOutOfBoundsException ex ) {
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// put north, center and south components into a new panel so that
|
||||||
|
// the shortcuts panel (at west) gets full height
|
||||||
|
LayoutManager layout = fc.getLayout();
|
||||||
|
if( layout instanceof BorderLayout ) {
|
||||||
|
BorderLayout borderLayout = (BorderLayout) layout;
|
||||||
|
borderLayout.setHgap( 8 );
|
||||||
|
|
||||||
|
Component north = borderLayout.getLayoutComponent( BorderLayout.NORTH );
|
||||||
|
Component center = borderLayout.getLayoutComponent( BorderLayout.CENTER );
|
||||||
|
Component south = borderLayout.getLayoutComponent( BorderLayout.SOUTH );
|
||||||
|
if( north != null && center != null && south != null ) {
|
||||||
|
JPanel p = new JPanel( new BorderLayout( 0, 11 ) );
|
||||||
|
p.add( north, BorderLayout.NORTH );
|
||||||
|
p.add( center, BorderLayout.CENTER );
|
||||||
|
p.add( south, BorderLayout.SOUTH );
|
||||||
|
fc.add( p, BorderLayout.CENTER );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -250,9 +311,19 @@ public class FlatFileChooserUI
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 2.3 */
|
||||||
|
protected FlatShortcutsPanel createShortcutsPanel( JFileChooser fc ) {
|
||||||
|
return new FlatShortcutsPanel( fc );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Dimension getPreferredSize( JComponent c ) {
|
public Dimension getPreferredSize( JComponent c ) {
|
||||||
return UIScale.scale( super.getPreferredSize( c ) );
|
Dimension prefSize = super.getPreferredSize( c );
|
||||||
|
Dimension minSize = getMinimumSize( c );
|
||||||
|
int shortcutsPanelWidth = (shortcutsPanel != null) ? shortcutsPanel.getPreferredSize().width : 0;
|
||||||
|
return new Dimension(
|
||||||
|
Math.max( prefSize.width, minSize.width + shortcutsPanelWidth ),
|
||||||
|
Math.max( prefSize.height, minSize.height ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -316,4 +387,234 @@ public class FlatFileChooserUI
|
|||||||
return icon;
|
return icon;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---- class FlatShortcutsPanel -------------------------------------------
|
||||||
|
|
||||||
|
/** @since 2.3 */
|
||||||
|
public static class FlatShortcutsPanel
|
||||||
|
extends JToolBar
|
||||||
|
implements PropertyChangeListener
|
||||||
|
{
|
||||||
|
private final JFileChooser fc;
|
||||||
|
|
||||||
|
private final Dimension buttonSize;
|
||||||
|
private final Dimension iconSize;
|
||||||
|
private final Function<File[], File[]> filesFunction;
|
||||||
|
private final Function<File, String> displayNameFunction;
|
||||||
|
private final Function<File, Icon> iconFunction;
|
||||||
|
|
||||||
|
protected final File[] files;
|
||||||
|
protected final JToggleButton[] buttons;
|
||||||
|
protected final ButtonGroup buttonGroup;
|
||||||
|
|
||||||
|
@SuppressWarnings( "unchecked" )
|
||||||
|
public FlatShortcutsPanel( JFileChooser fc ) {
|
||||||
|
super( JToolBar.VERTICAL );
|
||||||
|
this.fc = fc;
|
||||||
|
setFloatable( false );
|
||||||
|
|
||||||
|
buttonSize = UIScale.scale( getUIDimension( "FileChooser.shortcuts.buttonSize", 84, 64 ) );
|
||||||
|
iconSize = getUIDimension( "FileChooser.shortcuts.iconSize", 32, 32 );
|
||||||
|
|
||||||
|
filesFunction = (Function<File[], File[]>) UIManager.get( "FileChooser.shortcuts.filesFunction" );
|
||||||
|
displayNameFunction = (Function<File, String>) UIManager.get( "FileChooser.shortcuts.displayNameFunction" );
|
||||||
|
iconFunction = (Function<File, Icon>) UIManager.get( "FileChooser.shortcuts.iconFunction" );
|
||||||
|
|
||||||
|
FileSystemView fsv = fc.getFileSystemView();
|
||||||
|
File[] files = getChooserShortcutPanelFiles( fsv );
|
||||||
|
if( filesFunction != null )
|
||||||
|
files = filesFunction.apply( files );
|
||||||
|
this.files = files;
|
||||||
|
|
||||||
|
// create toolbar buttons
|
||||||
|
buttons = new JToggleButton[files.length];
|
||||||
|
buttonGroup = new ButtonGroup();
|
||||||
|
for( int i = 0; i < files.length; i++ ) {
|
||||||
|
// wrap drive path
|
||||||
|
if( fsv.isFileSystemRoot( files[i] ) )
|
||||||
|
files[i] = fsv.createFileObject( files[i].getAbsolutePath() );
|
||||||
|
|
||||||
|
File file = files[i];
|
||||||
|
String name = getDisplayName( fsv, file );
|
||||||
|
Icon icon = getIcon( fsv, file );
|
||||||
|
|
||||||
|
// remove path from name
|
||||||
|
int lastSepIndex = name.lastIndexOf( File.separatorChar );
|
||||||
|
if( lastSepIndex >= 0 && lastSepIndex < name.length() - 1 )
|
||||||
|
name = name.substring( lastSepIndex + 1 );
|
||||||
|
|
||||||
|
// scale icon (if necessary)
|
||||||
|
if( icon instanceof ImageIcon )
|
||||||
|
icon = new ScaledImageIcon( (ImageIcon) icon, iconSize.width, iconSize.height );
|
||||||
|
else if( icon != null )
|
||||||
|
icon = new ShortcutIcon( icon, iconSize.width, iconSize.height );
|
||||||
|
|
||||||
|
// create button
|
||||||
|
JToggleButton button = createButton( name, icon );
|
||||||
|
button.addActionListener( e -> {
|
||||||
|
fc.setCurrentDirectory( file );
|
||||||
|
} );
|
||||||
|
|
||||||
|
add( button );
|
||||||
|
buttonGroup.add( button );
|
||||||
|
buttons[i] = button;
|
||||||
|
}
|
||||||
|
|
||||||
|
directoryChanged( fc.getCurrentDirectory() );
|
||||||
|
}
|
||||||
|
|
||||||
|
private Dimension getUIDimension( String key, int defaultWidth, int defaultHeight ) {
|
||||||
|
Dimension size = UIManager.getDimension( key );
|
||||||
|
if( size == null )
|
||||||
|
size = new Dimension( defaultWidth, defaultHeight );
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected JToggleButton createButton( String name, Icon icon ) {
|
||||||
|
JToggleButton button = new JToggleButton( name, icon );
|
||||||
|
button.setVerticalTextPosition( SwingConstants.BOTTOM );
|
||||||
|
button.setHorizontalTextPosition( SwingConstants.CENTER );
|
||||||
|
button.setAlignmentX( Component.CENTER_ALIGNMENT );
|
||||||
|
button.setIconTextGap( 0 );
|
||||||
|
button.setPreferredSize( buttonSize );
|
||||||
|
button.setMaximumSize( buttonSize );
|
||||||
|
return button;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected File[] getChooserShortcutPanelFiles( FileSystemView fsv ) {
|
||||||
|
try {
|
||||||
|
if( SystemInfo.isJava_12_orLater ) {
|
||||||
|
Method m = fsv.getClass().getMethod( "getChooserShortcutPanelFiles" );
|
||||||
|
File[] files = (File[]) m.invoke( fsv );
|
||||||
|
|
||||||
|
// on macOS and Linux, files consists only of the user home directory
|
||||||
|
if( files.length == 1 && files[0].equals( new File( System.getProperty( "user.home" ) ) ) )
|
||||||
|
files = new File[0];
|
||||||
|
|
||||||
|
return files;
|
||||||
|
} else if( SystemInfo.isWindows ) {
|
||||||
|
Class<?> cls = Class.forName( "sun.awt.shell.ShellFolder" );
|
||||||
|
Method m = cls.getMethod( "get", String.class );
|
||||||
|
return (File[]) m.invoke( null, "fileChooserShortcutPanelFolders" );
|
||||||
|
}
|
||||||
|
} catch( IllegalAccessException ex ) {
|
||||||
|
// do not log because access may be denied via VM option '--illegal-access=deny'
|
||||||
|
} catch( Exception ex ) {
|
||||||
|
LoggingFacade.INSTANCE.logSevere( null, ex );
|
||||||
|
}
|
||||||
|
|
||||||
|
// fallback
|
||||||
|
return new File[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getDisplayName( FileSystemView fsv, File file ) {
|
||||||
|
if( displayNameFunction != null ) {
|
||||||
|
String name = displayNameFunction.apply( file );
|
||||||
|
if( name != null )
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fsv.getSystemDisplayName( file );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Icon getIcon( FileSystemView fsv, File file ) {
|
||||||
|
if( iconFunction != null ) {
|
||||||
|
Icon icon = iconFunction.apply( file );
|
||||||
|
if( icon != null )
|
||||||
|
return icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Java 17+ supports getting larger system icons
|
||||||
|
try {
|
||||||
|
if( SystemInfo.isJava_17_orLater ) {
|
||||||
|
Method m = fsv.getClass().getMethod( "getSystemIcon", File.class, int.class, int.class );
|
||||||
|
return (Icon) m.invoke( fsv, file, iconSize.width, iconSize.height );
|
||||||
|
} else if( iconSize.width > 16 || iconSize.height > 16 ) {
|
||||||
|
Class<?> cls = Class.forName( "sun.awt.shell.ShellFolder" );
|
||||||
|
if( cls.isInstance( file ) ) {
|
||||||
|
Method m = file.getClass().getMethod( "getIcon", boolean.class );
|
||||||
|
m.setAccessible( true );
|
||||||
|
Image image = (Image) m.invoke( file, true );
|
||||||
|
if( image != null )
|
||||||
|
return new ImageIcon( image );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch( IllegalAccessException ex ) {
|
||||||
|
// do not log because access may be denied via VM option '--illegal-access=deny'
|
||||||
|
} catch( Exception ex ) {
|
||||||
|
LoggingFacade.INSTANCE.logSevere( null, ex );
|
||||||
|
}
|
||||||
|
|
||||||
|
// get system icon in default size 16x16
|
||||||
|
return fsv.getSystemIcon( file );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void directoryChanged( File file ) {
|
||||||
|
if( file != null ) {
|
||||||
|
String absolutePath = file.getAbsolutePath();
|
||||||
|
for( int i = 0; i < files.length; i++ ) {
|
||||||
|
// also compare path because otherwise selecting "Documents"
|
||||||
|
// in "Look in" combobox would not select "Documents" shortcut item
|
||||||
|
if( files[i].equals( file ) || files[i].getAbsolutePath().equals( absolutePath ) ) {
|
||||||
|
buttons[i].setSelected( true );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buttonGroup.clearSelection();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void propertyChange( PropertyChangeEvent e ) {
|
||||||
|
switch( e.getPropertyName() ) {
|
||||||
|
case JFileChooser.DIRECTORY_CHANGED_PROPERTY:
|
||||||
|
directoryChanged( fc.getCurrentDirectory() );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//---- class ShortcutIcon -------------------------------------------------
|
||||||
|
|
||||||
|
private static class ShortcutIcon
|
||||||
|
implements Icon
|
||||||
|
{
|
||||||
|
private final Icon icon;
|
||||||
|
private final int iconWidth;
|
||||||
|
private final int iconHeight;
|
||||||
|
|
||||||
|
ShortcutIcon( Icon icon, int iconWidth, int iconHeight ) {
|
||||||
|
this.icon = icon;
|
||||||
|
this.iconWidth = iconWidth;
|
||||||
|
this.iconHeight = iconHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void paintIcon( Component c, Graphics g, int x, int y ) {
|
||||||
|
Graphics2D g2 = (Graphics2D) g.create();
|
||||||
|
try {
|
||||||
|
// set rendering hint for the case that the icon is a bitmap (not used for vector icons)
|
||||||
|
g2.setRenderingHint( RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC );
|
||||||
|
|
||||||
|
double scale = (double) getIconWidth() / (double) icon.getIconWidth();
|
||||||
|
g2.translate( x, y );
|
||||||
|
g2.scale( scale, scale );
|
||||||
|
|
||||||
|
icon.paintIcon( c, g2, 0, 0 );
|
||||||
|
} finally {
|
||||||
|
g2.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getIconWidth() {
|
||||||
|
return UIScale.scale( iconWidth );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getIconHeight() {
|
||||||
|
return UIScale.scale( iconHeight );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ public class FlatListCellBorder
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Because this borders are always shared for all lists,
|
* Because this border is always shared for all lists,
|
||||||
* get border specific style from FlatListUI.
|
* get border specific style from FlatListUI.
|
||||||
*/
|
*/
|
||||||
static <T> T getStyleFromListUI( Component c, Function<FlatListUI, T> f ) {
|
static <T> T getStyleFromListUI( Component c, Function<FlatListUI, T> f ) {
|
||||||
|
|||||||
@@ -212,7 +212,7 @@ public class FlatListUI
|
|||||||
/**
|
/**
|
||||||
* Toggle selection colors from focused to inactive and vice versa.
|
* Toggle selection colors from focused to inactive and vice versa.
|
||||||
*
|
*
|
||||||
* This is not a optimal solution but much easier than rewriting the whole paint methods.
|
* This is not an optimal solution but much easier than rewriting the whole paint methods.
|
||||||
*
|
*
|
||||||
* Using a LaF specific renderer was avoided because often a custom renderer is
|
* Using a LaF specific renderer was avoided because often a custom renderer is
|
||||||
* already used in applications. Then either the inactive colors are not used,
|
* already used in applications. Then either the inactive colors are not used,
|
||||||
|
|||||||
@@ -18,8 +18,10 @@ 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.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.awt.Insets;
|
import java.awt.Insets;
|
||||||
|
import java.awt.LayoutManager;
|
||||||
import java.awt.Window;
|
import java.awt.Window;
|
||||||
import java.awt.event.ActionEvent;
|
import java.awt.event.ActionEvent;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
@@ -27,6 +29,7 @@ import java.util.Map;
|
|||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import javax.swing.AbstractAction;
|
import javax.swing.AbstractAction;
|
||||||
import javax.swing.ActionMap;
|
import javax.swing.ActionMap;
|
||||||
|
import javax.swing.BoxLayout;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
import javax.swing.JMenu;
|
import javax.swing.JMenu;
|
||||||
import javax.swing.JMenuBar;
|
import javax.swing.JMenuBar;
|
||||||
@@ -40,11 +43,13 @@ import javax.swing.plaf.ActionMapUIResource;
|
|||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
import javax.swing.plaf.UIResource;
|
import javax.swing.plaf.UIResource;
|
||||||
import javax.swing.plaf.basic.BasicMenuBarUI;
|
import javax.swing.plaf.basic.BasicMenuBarUI;
|
||||||
|
import javax.swing.plaf.basic.DefaultMenuLayout;
|
||||||
import com.formdev.flatlaf.FlatLaf;
|
import com.formdev.flatlaf.FlatLaf;
|
||||||
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
||||||
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
|
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
|
||||||
import com.formdev.flatlaf.util.LoggingFacade;
|
import com.formdev.flatlaf.util.LoggingFacade;
|
||||||
import com.formdev.flatlaf.util.SystemInfo;
|
import com.formdev.flatlaf.util.SystemInfo;
|
||||||
|
import com.formdev.flatlaf.util.UIScale;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JMenuBar}.
|
* Provides the Flat LaF UI delegate for {@link javax.swing.JMenuBar}.
|
||||||
@@ -100,6 +105,10 @@ public class FlatMenuBarUI
|
|||||||
super.installDefaults();
|
super.installDefaults();
|
||||||
|
|
||||||
LookAndFeel.installProperty( menuBar, "opaque", false );
|
LookAndFeel.installProperty( menuBar, "opaque", false );
|
||||||
|
|
||||||
|
LayoutManager layout = menuBar.getLayout();
|
||||||
|
if( layout == null || layout instanceof UIResource )
|
||||||
|
menuBar.setLayout( new FlatMenuBarLayout( menuBar ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -210,7 +219,7 @@ public class FlatMenuBarUI
|
|||||||
// check whether:
|
// check whether:
|
||||||
// - TitlePane.unifiedBackground is true and
|
// - TitlePane.unifiedBackground is true and
|
||||||
// - menu bar is the "main" menu bar and
|
// - menu bar is the "main" menu bar and
|
||||||
// - window has custom decorations enabled
|
// - window root pane has custom decoration style
|
||||||
|
|
||||||
JRootPane rootPane;
|
JRootPane rootPane;
|
||||||
// (not storing value of "TitlePane.unifiedBackground" in class to allow changing at runtime)
|
// (not storing value of "TitlePane.unifiedBackground" in class to allow changing at runtime)
|
||||||
@@ -218,7 +227,131 @@ public class FlatMenuBarUI
|
|||||||
(rootPane = SwingUtilities.getRootPane( c )) != null &&
|
(rootPane = SwingUtilities.getRootPane( c )) != null &&
|
||||||
rootPane.getParent() instanceof Window &&
|
rootPane.getParent() instanceof Window &&
|
||||||
rootPane.getJMenuBar() == c &&
|
rootPane.getJMenuBar() == c &&
|
||||||
FlatNativeWindowBorder.hasCustomDecoration( (Window) rootPane.getParent() );
|
rootPane.getWindowDecorationStyle() != JRootPane.NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---- class FlatMenuBarLayout --------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 2.4
|
||||||
|
*/
|
||||||
|
protected static class FlatMenuBarLayout
|
||||||
|
extends DefaultMenuLayout
|
||||||
|
{
|
||||||
|
public FlatMenuBarLayout( Container target ) {
|
||||||
|
super( target, BoxLayout.LINE_AXIS );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void layoutContainer( Container target ) {
|
||||||
|
super.layoutContainer( target );
|
||||||
|
|
||||||
|
|
||||||
|
// The only purpose of the code below is to make sure that a horizontal glue,
|
||||||
|
// which can be used to move window and displays the window title in embedded menu bar,
|
||||||
|
// is always visible within the menu bar bounds and has a minimum width.
|
||||||
|
// If this is not the case, the horizontal glue is made larger and
|
||||||
|
// components that are on the left side of the glue are made smaller.
|
||||||
|
|
||||||
|
|
||||||
|
// get root pane and check whether this menu bar is the root pane menu bar
|
||||||
|
JRootPane rootPane = SwingUtilities.getRootPane( target );
|
||||||
|
if( rootPane == null || rootPane.getJMenuBar() != target )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// get title pane and check whether menu bar is embedded
|
||||||
|
FlatTitlePane titlePane = FlatRootPaneUI.getTitlePane( rootPane );
|
||||||
|
if( titlePane == null || !titlePane.isMenuBarEmbedded() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// check whether there is a horizontal glue (used for window title in embedded menu bar)
|
||||||
|
// and check minimum width of horizontal glue
|
||||||
|
Component horizontalGlue = titlePane.findHorizontalGlue( (JMenuBar) target );
|
||||||
|
int minTitleWidth = UIScale.scale( titlePane.titleMinimumWidth );
|
||||||
|
if( horizontalGlue != null && horizontalGlue.getWidth() < minTitleWidth ) {
|
||||||
|
// get index of glue component
|
||||||
|
int glueIndex = -1;
|
||||||
|
Component[] components = target.getComponents();
|
||||||
|
for( int i = components.length - 1; i >= 0; i-- ) {
|
||||||
|
if( components[i] == horizontalGlue ) {
|
||||||
|
glueIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( glueIndex < 0 )
|
||||||
|
return; // should never happen
|
||||||
|
|
||||||
|
if( target.getComponentOrientation().isLeftToRight() ) {
|
||||||
|
// left-to-right
|
||||||
|
|
||||||
|
// make horizontal glue wider (minimum title width)
|
||||||
|
int offset = minTitleWidth - horizontalGlue.getWidth();
|
||||||
|
horizontalGlue.setSize( minTitleWidth, horizontalGlue.getHeight() );
|
||||||
|
|
||||||
|
// check whether glue is fully visible
|
||||||
|
int minGlueX = target.getWidth() - target.getInsets().right - minTitleWidth;
|
||||||
|
if( minGlueX < horizontalGlue.getX() ) {
|
||||||
|
// move glue to the left to make it fully visible
|
||||||
|
offset -= (horizontalGlue.getX() - minGlueX);
|
||||||
|
horizontalGlue.setLocation( minGlueX, horizontalGlue.getY() );
|
||||||
|
|
||||||
|
// shrink and move components that are on the left side of the glue
|
||||||
|
for( int i = glueIndex - 1; i >= 0; i-- ) {
|
||||||
|
Component c = components[i];
|
||||||
|
if( c.getX() > minGlueX ) {
|
||||||
|
// move component and set width to zero
|
||||||
|
c.setBounds( minGlueX, c.getY(), 0, c.getHeight() );
|
||||||
|
} else {
|
||||||
|
// reduce size of component
|
||||||
|
c.setSize( minGlueX - c.getX(), c.getHeight() );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// move components that are on the right side of the glue
|
||||||
|
for( int i = glueIndex + 1; i < components.length; i++ ) {
|
||||||
|
Component c = components[i];
|
||||||
|
c.setLocation( c.getX() + offset, c.getY() );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// right-to-left
|
||||||
|
|
||||||
|
// make horizontal glue wider (minimum title width)
|
||||||
|
int offset = minTitleWidth - horizontalGlue.getWidth();
|
||||||
|
horizontalGlue.setBounds( horizontalGlue.getX() - offset, horizontalGlue.getY(),
|
||||||
|
minTitleWidth, horizontalGlue.getHeight() );
|
||||||
|
|
||||||
|
// check whether glue is fully visible
|
||||||
|
int minGlueX = target.getInsets().left;
|
||||||
|
if( minGlueX > horizontalGlue.getX() ) {
|
||||||
|
// move glue to the right to make it fully visible
|
||||||
|
offset -= (horizontalGlue.getX() - minGlueX);
|
||||||
|
horizontalGlue.setLocation( minGlueX, horizontalGlue.getY() );
|
||||||
|
|
||||||
|
// shrink and move components that are on the right side of the glue
|
||||||
|
int x = horizontalGlue.getX() + horizontalGlue.getWidth();
|
||||||
|
for( int i = glueIndex - 1; i >= 0; i-- ) {
|
||||||
|
Component c = components[i];
|
||||||
|
if( c.getX() + c.getWidth() < x ) {
|
||||||
|
// move component and set width to zero
|
||||||
|
c.setBounds( x, c.getY(), 0, c.getHeight() );
|
||||||
|
} else {
|
||||||
|
// move component and reduce size
|
||||||
|
c.setBounds( x, c.getY(), c.getWidth() - (x - c.getX()), c.getHeight() );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// move components that are on the left side of the glue
|
||||||
|
for( int i = glueIndex + 1; i < components.length; i++ ) {
|
||||||
|
Component c = components[i];
|
||||||
|
c.setLocation( c.getX() - offset, c.getY() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//---- class TakeFocus ----------------------------------------------------
|
//---- class TakeFocus ----------------------------------------------------
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ import javax.swing.plaf.MenuBarUI;
|
|||||||
public class FlatMenuItemBorder
|
public class FlatMenuItemBorder
|
||||||
extends FlatMarginBorder
|
extends FlatMarginBorder
|
||||||
{
|
{
|
||||||
// only used if parent menubar is not a instance of FlatMenuBarUI
|
// only used if parent menubar is not an instance of FlatMenuBarUI
|
||||||
private final Insets menuBarItemMargins = UIManager.getInsets( "MenuBar.itemMargins" );
|
private final Insets menuBarItemMargins = UIManager.getInsets( "MenuBar.itemMargins" );
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -446,6 +446,19 @@ debug*/
|
|||||||
protected static void paintHTMLText( Graphics g, JMenuItem menuItem,
|
protected static void paintHTMLText( Graphics g, JMenuItem menuItem,
|
||||||
Rectangle textRect, View htmlView, Color selectionForeground )
|
Rectangle textRect, View htmlView, Color selectionForeground )
|
||||||
{
|
{
|
||||||
|
// On Windows, using Segoe UI font, Java 15 or older and scaling greater than 1,
|
||||||
|
// the width of the HTML view may be initially too small (because component
|
||||||
|
// is not connected to a GraphicsConfiguration when getPreferredSize() is invoked).
|
||||||
|
// Since Java 16, this seems to be fixed somehow by doing popup menu layout twice.
|
||||||
|
//
|
||||||
|
// If using a too small width for htmlView.paint(), the view would rearrange
|
||||||
|
// its children and wrap them to two lines. To avoid this, use view preferred X span
|
||||||
|
// for painting. Core Lafs actually do the same in class MenuItemLayoutHelper.
|
||||||
|
//
|
||||||
|
// Example HTML text that causes the problem: "<html>some <b>HTML</b> <i>text</i></html>"
|
||||||
|
textRect = new Rectangle( textRect );
|
||||||
|
textRect.width = (int) htmlView.getPreferredSpan( View.X_AXIS );
|
||||||
|
|
||||||
if( isArmedOrSelected( menuItem ) && selectionForeground != null )
|
if( isArmedOrSelected( menuItem ) && selectionForeground != null )
|
||||||
g = new GraphicsProxyWithTextColor( (Graphics2D) g, selectionForeground );
|
g = new GraphicsProxyWithTextColor( (Graphics2D) g, selectionForeground );
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,99 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2022 FormDev Software GmbH
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.formdev.flatlaf.ui;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import com.formdev.flatlaf.FlatSystemProperties;
|
||||||
|
import com.formdev.flatlaf.util.LoggingFacade;
|
||||||
|
import com.formdev.flatlaf.util.NativeLibrary;
|
||||||
|
import com.formdev.flatlaf.util.SystemInfo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper class to load FlatLaf native library (.dll, .so or .dylib),
|
||||||
|
* if available for current operating system and CPU architecture.
|
||||||
|
*
|
||||||
|
* @author Karl Tauber
|
||||||
|
* @since 2.3
|
||||||
|
*/
|
||||||
|
class FlatNativeLibrary
|
||||||
|
{
|
||||||
|
private static NativeLibrary nativeLibrary;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads native library (if available) and returns whether loaded successfully.
|
||||||
|
* Returns {@code false} if no native library is available.
|
||||||
|
*/
|
||||||
|
static synchronized boolean isLoaded() {
|
||||||
|
initialize();
|
||||||
|
return (nativeLibrary != null) ? nativeLibrary.isLoaded() : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void initialize() {
|
||||||
|
if( nativeLibrary != null )
|
||||||
|
return;
|
||||||
|
|
||||||
|
String libraryName;
|
||||||
|
if( SystemInfo.isWindows_10_orLater && (SystemInfo.isX86 || SystemInfo.isX86_64) ) {
|
||||||
|
// Windows: requires Windows 10 (x86 or x86_64)
|
||||||
|
|
||||||
|
libraryName = "flatlaf-windows-x86";
|
||||||
|
if( SystemInfo.isX86_64 )
|
||||||
|
libraryName += "_64";
|
||||||
|
|
||||||
|
// load jawt native library
|
||||||
|
loadJAWT();
|
||||||
|
} else
|
||||||
|
return; // no native library available for current OS or CPU architecture
|
||||||
|
|
||||||
|
// load native library
|
||||||
|
nativeLibrary = createNativeLibrary( libraryName );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static NativeLibrary createNativeLibrary( String libraryName ) {
|
||||||
|
String libraryPath = System.getProperty( FlatSystemProperties.NATIVE_LIBRARY_PATH );
|
||||||
|
if( libraryPath != null ) {
|
||||||
|
File libraryFile = new File( libraryPath, System.mapLibraryName( libraryName ) );
|
||||||
|
if( libraryFile.exists() )
|
||||||
|
return new NativeLibrary( libraryFile, true );
|
||||||
|
else
|
||||||
|
LoggingFacade.INSTANCE.logSevere( "Did not find external library " + libraryFile + ", using extracted library instead", null );
|
||||||
|
}
|
||||||
|
|
||||||
|
return new NativeLibrary( "com/formdev/flatlaf/natives/" + libraryName, null, true );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void loadJAWT() {
|
||||||
|
if( SystemInfo.isJava_9_orLater )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// In Java 8, load jawt.dll (part of JRE) explicitly because it
|
||||||
|
// is not found when running application with <jdk>/bin/java.exe.
|
||||||
|
// When using <jdk>/jre/bin/java.exe, it is found.
|
||||||
|
// jawt.dll is located in <jdk>/jre/bin/.
|
||||||
|
// Java 9 and later do not have this problem.
|
||||||
|
try {
|
||||||
|
System.loadLibrary( "jawt" );
|
||||||
|
} catch( UnsatisfiedLinkError ex ) {
|
||||||
|
// log error only if native library jawt.dll not already loaded
|
||||||
|
String message = ex.getMessage();
|
||||||
|
if( message == null || !message.contains( "already loaded in another classloader" ) )
|
||||||
|
LoggingFacade.INSTANCE.logSevere( null, ex );
|
||||||
|
} catch( Exception ex ) {
|
||||||
|
LoggingFacade.INSTANCE.logSevere( null, ex );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -42,11 +42,13 @@ import com.formdev.flatlaf.util.SystemInfo;
|
|||||||
public class FlatNativeWindowBorder
|
public class FlatNativeWindowBorder
|
||||||
{
|
{
|
||||||
// can use window decorations if:
|
// can use window decorations if:
|
||||||
// - on Windows 10
|
// - on Windows 10 or later
|
||||||
|
// - not if system property "sun.java2d.opengl" is true on Windows 10
|
||||||
// - not when running in JetBrains Projector, Webswing or WinPE
|
// - not when running in JetBrains Projector, Webswing or WinPE
|
||||||
// - not disabled via system property
|
// - not disabled via system property
|
||||||
private static final boolean canUseWindowDecorations =
|
private static final boolean canUseWindowDecorations =
|
||||||
SystemInfo.isWindows_10_orLater &&
|
SystemInfo.isWindows_10_orLater &&
|
||||||
|
(SystemInfo.isWindows_11_orLater || !FlatSystemProperties.getBoolean( "sun.java2d.opengl", false )) &&
|
||||||
!SystemInfo.isProjector &&
|
!SystemInfo.isProjector &&
|
||||||
!SystemInfo.isWebswing &&
|
!SystemInfo.isWebswing &&
|
||||||
!SystemInfo.isWinPE &&
|
!SystemInfo.isWinPE &&
|
||||||
|
|||||||
@@ -143,7 +143,7 @@ public class FlatPopupFactory
|
|||||||
* <p>
|
* <p>
|
||||||
* On a dual screen setup, where screens use different scale factors, it may happen
|
* 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.
|
* that the window location changes when showing a heavy weight popup window.
|
||||||
* E.g. when opening an dialog on the secondary screen and making combobox popup visible.
|
* E.g. when opening a dialog on the secondary screen and making combobox popup visible.
|
||||||
* <p>
|
* <p>
|
||||||
* This is a workaround for https://bugs.openjdk.java.net/browse/JDK-8224608
|
* This is a workaround for https://bugs.openjdk.java.net/browse/JDK-8224608
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -16,18 +16,58 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf.ui;
|
package com.formdev.flatlaf.ui;
|
||||||
|
|
||||||
|
import java.awt.BorderLayout;
|
||||||
|
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.Graphics;
|
||||||
|
import java.awt.GraphicsConfiguration;
|
||||||
|
import java.awt.GraphicsDevice;
|
||||||
|
import java.awt.GraphicsEnvironment;
|
||||||
|
import java.awt.Insets;
|
||||||
import java.awt.LayoutManager;
|
import java.awt.LayoutManager;
|
||||||
|
import java.awt.Point;
|
||||||
|
import java.awt.Rectangle;
|
||||||
|
import java.awt.Toolkit;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.awt.event.MouseListener;
|
||||||
|
import java.awt.event.MouseWheelEvent;
|
||||||
|
import java.awt.event.MouseWheelListener;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import javax.swing.BoxLayout;
|
import javax.swing.BoxLayout;
|
||||||
|
import javax.swing.JButton;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
|
import javax.swing.JMenuItem;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JPopupMenu;
|
||||||
|
import javax.swing.JScrollPane;
|
||||||
|
import javax.swing.JViewport;
|
||||||
|
import javax.swing.MenuElement;
|
||||||
|
import javax.swing.MenuSelectionManager;
|
||||||
|
import javax.swing.Popup;
|
||||||
|
import javax.swing.PopupFactory;
|
||||||
|
import javax.swing.SwingConstants;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
|
import javax.swing.Timer;
|
||||||
|
import javax.swing.UIManager;
|
||||||
|
import javax.swing.event.MenuKeyEvent;
|
||||||
|
import javax.swing.event.MenuKeyListener;
|
||||||
|
import javax.swing.event.PopupMenuEvent;
|
||||||
|
import javax.swing.event.PopupMenuListener;
|
||||||
|
import javax.swing.plaf.ButtonUI;
|
||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
import javax.swing.plaf.UIResource;
|
import javax.swing.plaf.UIResource;
|
||||||
|
import javax.swing.plaf.basic.BasicComboPopup;
|
||||||
|
import javax.swing.plaf.basic.BasicMenuItemUI;
|
||||||
import javax.swing.plaf.basic.BasicPopupMenuUI;
|
import javax.swing.plaf.basic.BasicPopupMenuUI;
|
||||||
import javax.swing.plaf.basic.DefaultMenuLayout;
|
import javax.swing.plaf.basic.DefaultMenuLayout;
|
||||||
|
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;
|
||||||
|
|
||||||
@@ -41,12 +81,22 @@ import com.formdev.flatlaf.util.LoggingFacade;
|
|||||||
* @uiDefault PopupMenu.foreground Color
|
* @uiDefault PopupMenu.foreground Color
|
||||||
* @uiDefault PopupMenu.border Border
|
* @uiDefault PopupMenu.border Border
|
||||||
*
|
*
|
||||||
|
* <!-- FlatPopupMenuUI -->
|
||||||
|
*
|
||||||
|
* @uiDefault Component.arrowType String chevron (default) or triangle
|
||||||
|
* @uiDefault PopupMenu.scrollArrowColor Color
|
||||||
|
* @uiDefault PopupMenu.hoverScrollArrowBackground Color optional
|
||||||
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
public class FlatPopupMenuUI
|
public class FlatPopupMenuUI
|
||||||
extends BasicPopupMenuUI
|
extends BasicPopupMenuUI
|
||||||
implements StyleableUI
|
implements StyleableUI
|
||||||
{
|
{
|
||||||
|
/** @since 2.1 */ @Styleable protected String arrowType;
|
||||||
|
/** @since 2.1 */ @Styleable protected Color scrollArrowColor;
|
||||||
|
/** @since 2.1 */ @Styleable protected Color hoverScrollArrowBackground;
|
||||||
|
|
||||||
private PropertyChangeListener propertyChangeListener;
|
private PropertyChangeListener propertyChangeListener;
|
||||||
private Map<String, Object> oldStyleValues;
|
private Map<String, Object> oldStyleValues;
|
||||||
private AtomicBoolean borderShared;
|
private AtomicBoolean borderShared;
|
||||||
@@ -74,9 +124,21 @@ public class FlatPopupMenuUI
|
|||||||
public void installDefaults() {
|
public void installDefaults() {
|
||||||
super.installDefaults();
|
super.installDefaults();
|
||||||
|
|
||||||
|
arrowType = UIManager.getString( "Component.arrowType" );
|
||||||
|
scrollArrowColor = UIManager.getColor( "PopupMenu.scrollArrowColor" );
|
||||||
|
hoverScrollArrowBackground = UIManager.getColor( "PopupMenu.hoverScrollArrowBackground" );
|
||||||
|
|
||||||
LayoutManager layout = popupMenu.getLayout();
|
LayoutManager layout = popupMenu.getLayout();
|
||||||
if( layout == null || layout instanceof UIResource )
|
if( layout == null || layout instanceof UIResource )
|
||||||
popupMenu.setLayout( new FlatMenuLayout( popupMenu, BoxLayout.Y_AXIS ) );
|
popupMenu.setLayout( new FlatPopupMenuLayout( popupMenu, BoxLayout.Y_AXIS ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void uninstallDefaults() {
|
||||||
|
super.uninstallDefaults();
|
||||||
|
|
||||||
|
scrollArrowColor = null;
|
||||||
|
hoverScrollArrowBackground = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -122,12 +184,61 @@ public class FlatPopupMenuUI
|
|||||||
return FlatStylingSupport.getAnnotatedStyleableInfos( this, popupMenu.getBorder() );
|
return FlatStylingSupport.getAnnotatedStyleableInfos( this, popupMenu.getBorder() );
|
||||||
}
|
}
|
||||||
|
|
||||||
//---- class FlatMenuLayout -----------------------------------------------
|
@Override
|
||||||
|
public Popup getPopup( JPopupMenu popup, int x, int y ) {
|
||||||
|
// do not add scroller to combobox popups or to popups that already have a scroll pane
|
||||||
|
if( popup instanceof BasicComboPopup ||
|
||||||
|
(popup.getComponentCount() > 0 && popup.getComponent( 0 ) instanceof JScrollPane) )
|
||||||
|
return super.getPopup( popup, x, y );
|
||||||
|
|
||||||
protected static class FlatMenuLayout
|
// do not add scroller if popup fits into screen
|
||||||
|
Dimension prefSize = popup.getPreferredSize();
|
||||||
|
int screenHeight = getScreenHeightAt( x, y );
|
||||||
|
if( prefSize.height <= screenHeight )
|
||||||
|
return super.getPopup( popup, x, y );
|
||||||
|
|
||||||
|
// create scroller
|
||||||
|
FlatPopupScroller scroller = new FlatPopupScroller( popup );
|
||||||
|
scroller.setPreferredSize( new Dimension( prefSize.width, screenHeight ) );
|
||||||
|
|
||||||
|
// create popup
|
||||||
|
PopupFactory popupFactory = PopupFactory.getSharedInstance();
|
||||||
|
return popupFactory.getPopup( popup.getInvoker(), scroller, x, y );
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getScreenHeightAt( int x, int y ) {
|
||||||
|
// find GraphicsConfiguration at popup location (similar to JPopupMenu.getCurrentGraphicsConfiguration())
|
||||||
|
GraphicsConfiguration gc = null;
|
||||||
|
for( GraphicsDevice device : GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices() ) {
|
||||||
|
if( device.getType() == GraphicsDevice.TYPE_RASTER_SCREEN ) {
|
||||||
|
GraphicsConfiguration dgc = device.getDefaultConfiguration();
|
||||||
|
if( dgc.getBounds().contains( x, y ) ) {
|
||||||
|
gc = dgc;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( gc == null && popupMenu.getInvoker() != null )
|
||||||
|
gc = popupMenu.getInvoker().getGraphicsConfiguration();
|
||||||
|
|
||||||
|
// compute screen height
|
||||||
|
// (always subtract screen insets because there is no API to detect whether
|
||||||
|
// the popup can overlap the taskbar; see JPopupMenu.canPopupOverlapTaskBar())
|
||||||
|
Toolkit toolkit = Toolkit.getDefaultToolkit();
|
||||||
|
Rectangle screenBounds = (gc != null) ? gc.getBounds() : new Rectangle( toolkit.getScreenSize() );
|
||||||
|
Insets screenInsets = Toolkit.getDefaultToolkit().getScreenInsets( gc );
|
||||||
|
return screenBounds.height - screenInsets.top - screenInsets.bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---- class FlatPopupMenuLayout ------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 2.4
|
||||||
|
*/
|
||||||
|
protected static class FlatPopupMenuLayout
|
||||||
extends DefaultMenuLayout
|
extends DefaultMenuLayout
|
||||||
{
|
{
|
||||||
public FlatMenuLayout( Container target, int axis ) {
|
public FlatPopupMenuLayout( Container target, int axis ) {
|
||||||
super( target, axis );
|
super( target, axis );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,4 +249,206 @@ public class FlatPopupMenuUI
|
|||||||
return super.preferredLayoutSize( target );
|
return super.preferredLayoutSize( target );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---- class FlatPopupScroller --------------------------------------------
|
||||||
|
|
||||||
|
private class FlatPopupScroller
|
||||||
|
extends JPanel
|
||||||
|
implements MouseWheelListener, PopupMenuListener, MenuKeyListener
|
||||||
|
{
|
||||||
|
private final JPopupMenu popup;
|
||||||
|
|
||||||
|
private final JScrollPane scrollPane;
|
||||||
|
private final JButton scrollUpButton;
|
||||||
|
private final JButton scrollDownButton;
|
||||||
|
private int unitIncrement;
|
||||||
|
|
||||||
|
FlatPopupScroller( JPopupMenu popup ) {
|
||||||
|
super( new BorderLayout() );
|
||||||
|
this.popup = popup;
|
||||||
|
|
||||||
|
// this panel is required to avoid that JPopupMenu.setLocation() will be invoked
|
||||||
|
// while scrolling, because this would call JPopupMenu.showPopup()
|
||||||
|
JPanel view = new JPanel( new BorderLayout() );
|
||||||
|
view.add( popup, BorderLayout.CENTER );
|
||||||
|
|
||||||
|
scrollPane = new JScrollPane( view, JScrollPane.VERTICAL_SCROLLBAR_NEVER, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER );
|
||||||
|
scrollPane.setBorder( null );
|
||||||
|
|
||||||
|
scrollUpButton = new ArrowButton( SwingConstants.NORTH );
|
||||||
|
scrollDownButton = new ArrowButton( SwingConstants.SOUTH );
|
||||||
|
|
||||||
|
add( scrollPane, BorderLayout.CENTER );
|
||||||
|
add( scrollUpButton, BorderLayout.NORTH );
|
||||||
|
add( scrollDownButton, BorderLayout.SOUTH );
|
||||||
|
|
||||||
|
setBackground( popup.getBackground() );
|
||||||
|
setBorder( popup.getBorder() );
|
||||||
|
popup.setBorder( null );
|
||||||
|
|
||||||
|
popup.addPopupMenuListener( this );
|
||||||
|
popup.addMouseWheelListener( this );
|
||||||
|
popup.addMenuKeyListener( this );
|
||||||
|
|
||||||
|
updateArrowButtons();
|
||||||
|
}
|
||||||
|
|
||||||
|
void scroll( int unitsToScroll ) {
|
||||||
|
if( unitIncrement == 0 )
|
||||||
|
unitIncrement = new JMenuItem( "X" ).getPreferredSize().height;
|
||||||
|
|
||||||
|
JViewport viewport = scrollPane.getViewport();
|
||||||
|
Point viewPosition = viewport.getViewPosition();
|
||||||
|
int newY = viewPosition.y + (unitIncrement * unitsToScroll);
|
||||||
|
if( newY < 0 )
|
||||||
|
newY = 0;
|
||||||
|
else
|
||||||
|
newY = Math.min( newY, viewport.getViewSize().height - viewport.getExtentSize().height );
|
||||||
|
viewport.setViewPosition( new Point( viewPosition.x, newY ) );
|
||||||
|
|
||||||
|
updateArrowButtons();
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateArrowButtons() {
|
||||||
|
JViewport viewport = scrollPane.getViewport();
|
||||||
|
Point viewPosition = viewport.getViewPosition();
|
||||||
|
|
||||||
|
scrollUpButton.setVisible( viewPosition.y > 0 );
|
||||||
|
scrollDownButton.setVisible( viewPosition.y < viewport.getViewSize().height - viewport.getExtentSize().height );
|
||||||
|
}
|
||||||
|
|
||||||
|
//---- interface PopupMenuListener ----
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void popupMenuWillBecomeInvisible( PopupMenuEvent e ) {
|
||||||
|
// restore popup border
|
||||||
|
popup.setBorder( getBorder() );
|
||||||
|
|
||||||
|
popup.removePopupMenuListener( this );
|
||||||
|
popup.removeMouseWheelListener( this );
|
||||||
|
popup.removeMenuKeyListener( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void popupMenuWillBecomeVisible( PopupMenuEvent e ) {}
|
||||||
|
@Override public void popupMenuCanceled( PopupMenuEvent e ) {}
|
||||||
|
|
||||||
|
//---- interface MouseWheelListener ----
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scroll when user rotates mouse wheel.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void mouseWheelMoved( MouseWheelEvent e ) {
|
||||||
|
// convert mouse location before scrolling
|
||||||
|
Point mouseLocation = SwingUtilities.convertPoint( (Component) e.getSource(), e.getPoint(), this );
|
||||||
|
|
||||||
|
// scroll
|
||||||
|
scroll( e.getUnitsToScroll() );
|
||||||
|
|
||||||
|
// select menu item at mouse location
|
||||||
|
Component c = SwingUtilities.getDeepestComponentAt( this, mouseLocation.x, mouseLocation.y );
|
||||||
|
if( c instanceof JMenuItem ) {
|
||||||
|
ButtonUI ui = ((JMenuItem)c).getUI();
|
||||||
|
if( ui instanceof BasicMenuItemUI )
|
||||||
|
MenuSelectionManager.defaultManager().setSelectedPath( ((BasicMenuItemUI)ui).getPath() );
|
||||||
|
}
|
||||||
|
|
||||||
|
// this avoids that the popup is closed when running on Java 8
|
||||||
|
// https://bugs.openjdk.java.net/browse/JDK-8075063
|
||||||
|
e.consume();
|
||||||
|
}
|
||||||
|
|
||||||
|
//---- interface MenuKeyListener ----
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scroll when user presses Up or Down keys.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void menuKeyPressed( MenuKeyEvent e ) {
|
||||||
|
// use invokeLater() because menu selection is not yet updated because
|
||||||
|
// this listener is invoked before another listener that updates the menu selection
|
||||||
|
EventQueue.invokeLater( () -> {
|
||||||
|
if( !isDisplayable() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
MenuElement[] path = MenuSelectionManager.defaultManager().getSelectedPath();
|
||||||
|
if( path.length == 0 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// scroll selected menu item to visible area
|
||||||
|
Component c = path[path.length - 1].getComponent();
|
||||||
|
JViewport viewport = scrollPane.getViewport();
|
||||||
|
Point pt = SwingUtilities.convertPoint( c, 0, 0, viewport );
|
||||||
|
viewport.scrollRectToVisible( new Rectangle( pt, c.getSize() ) );
|
||||||
|
|
||||||
|
// update arrow buttons
|
||||||
|
boolean upVisible = scrollUpButton.isVisible();
|
||||||
|
updateArrowButtons();
|
||||||
|
if( !upVisible && scrollUpButton.isVisible() ) {
|
||||||
|
// if "up" button becomes visible, make sure that bottom menu item stays visible
|
||||||
|
Point viewPosition = viewport.getViewPosition();
|
||||||
|
int newY = viewPosition.y + scrollUpButton.getPreferredSize().height;
|
||||||
|
viewport.setViewPosition( new Point( viewPosition.x, newY ) );
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override public void menuKeyTyped( MenuKeyEvent e ) {}
|
||||||
|
@Override public void menuKeyReleased( MenuKeyEvent e ) {}
|
||||||
|
|
||||||
|
//---- class ArrowButton ----------------------------------------------
|
||||||
|
|
||||||
|
private class ArrowButton
|
||||||
|
extends FlatArrowButton
|
||||||
|
implements MouseListener, ActionListener
|
||||||
|
{
|
||||||
|
private Timer timer;
|
||||||
|
|
||||||
|
ArrowButton( int direction ) {
|
||||||
|
super( direction, arrowType, scrollArrowColor, null, null, hoverScrollArrowBackground, null, null );
|
||||||
|
|
||||||
|
addMouseListener( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void paint( Graphics g ) {
|
||||||
|
// always fill background to paint over border on HiDPI screens
|
||||||
|
g.setColor( popup.getBackground() );
|
||||||
|
g.fillRect( 0, 0, getWidth(), getHeight() );
|
||||||
|
|
||||||
|
super.paint( g );
|
||||||
|
}
|
||||||
|
|
||||||
|
//---- interface MouseListener ----
|
||||||
|
|
||||||
|
@Override public void mouseClicked( MouseEvent e ) {}
|
||||||
|
@Override public void mousePressed( MouseEvent e ) {}
|
||||||
|
@Override public void mouseReleased( MouseEvent e ) {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseEntered( MouseEvent e ) {
|
||||||
|
if( timer == null )
|
||||||
|
timer = new Timer( 50, this );
|
||||||
|
timer.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseExited( MouseEvent e ) {
|
||||||
|
if( timer != null )
|
||||||
|
timer.stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
//---- interface ActionListener ----
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed( ActionEvent e ) {
|
||||||
|
if( timer != null && !isDisplayable() ) {
|
||||||
|
timer.stop();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
scroll( direction == SwingConstants.NORTH ? -1 : 1 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -199,7 +199,7 @@ public class FlatRadioButtonUI
|
|||||||
return infos;
|
return infos;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Insets tempInsets = new Insets( 0, 0, 0, 0 );
|
private static final Insets tempInsets = new Insets( 0, 0, 0, 0 );
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Dimension getPreferredSize( JComponent c ) {
|
public Dimension getPreferredSize( JComponent c ) {
|
||||||
@@ -212,7 +212,7 @@ public class FlatRadioButtonUI
|
|||||||
if( focusWidth > 0 ) {
|
if( focusWidth > 0 ) {
|
||||||
// Increase preferred width and height if insets were explicitly reduced (e.g. with
|
// Increase preferred width and height if insets were explicitly reduced (e.g. with
|
||||||
// an EmptyBorder) and icon has a focus width, which is not included in icon size.
|
// an EmptyBorder) and icon has a focus width, which is not included in icon size.
|
||||||
// Otherwise the component may be too small and outer focus border may be cut off.
|
// Otherwise, the component may be too small and outer focus border may be cut off.
|
||||||
Insets insets = c.getInsets( tempInsets );
|
Insets insets = c.getInsets( tempInsets );
|
||||||
size.width += Math.max( focusWidth - insets.left, 0 ) + Math.max( focusWidth - insets.right, 0 );
|
size.width += Math.max( focusWidth - insets.left, 0 ) + Math.max( focusWidth - insets.right, 0 );
|
||||||
size.height += Math.max( focusWidth - insets.top, 0 ) + Math.max( focusWidth - insets.bottom, 0 );
|
size.height += Math.max( focusWidth - insets.top, 0 ) + Math.max( focusWidth - insets.bottom, 0 );
|
||||||
|
|||||||
@@ -179,8 +179,8 @@ public class FlatRootPaneUI
|
|||||||
super.installListeners( root );
|
super.installListeners( root );
|
||||||
|
|
||||||
if( SystemInfo.isJava_9_orLater ) {
|
if( SystemInfo.isJava_9_orLater ) {
|
||||||
// On HiDPI screens, where scaling is used, there may be white lines at the
|
// On HiDPI screens, where scaling is used, there may be white lines on the
|
||||||
// bottom and at the right side of the window when it is initially shown.
|
// bottom and on the right side of the window when it is initially shown.
|
||||||
// This is very disturbing in dark themes, but hard to notice in light themes.
|
// This is very disturbing in dark themes, but hard to notice in light themes.
|
||||||
// Seems to be a rounding issue when Swing adds dirty region of window
|
// Seems to be a rounding issue when Swing adds dirty region of window
|
||||||
// using RepaintManager.nativeAddDirtyRegion().
|
// using RepaintManager.nativeAddDirtyRegion().
|
||||||
@@ -364,6 +364,12 @@ public class FlatRootPaneUI
|
|||||||
((FlatRootPaneUI)ui).titlePane.isMenuBarEmbedded();
|
((FlatRootPaneUI)ui).titlePane.isMenuBarEmbedded();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 2.4 */
|
||||||
|
protected static FlatTitlePane getTitlePane( JRootPane rootPane ) {
|
||||||
|
RootPaneUI ui = rootPane.getUI();
|
||||||
|
return ui instanceof FlatRootPaneUI ? ((FlatRootPaneUI)ui).titlePane : null;
|
||||||
|
}
|
||||||
|
|
||||||
//---- class FlatRootLayout -----------------------------------------------
|
//---- class FlatRootLayout -----------------------------------------------
|
||||||
|
|
||||||
protected class FlatRootLayout
|
protected class FlatRootLayout
|
||||||
@@ -510,7 +516,7 @@ public class FlatRootPaneUI
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
Container parent = c.getParent();
|
Container parent = c.getParent();
|
||||||
boolean active = parent instanceof Window ? ((Window)parent).isActive() : false;
|
boolean active = parent instanceof Window && ((Window)parent).isActive();
|
||||||
|
|
||||||
g.setColor( FlatUIUtils.deriveColor( active ? activeBorderColor : inactiveBorderColor, baseBorderColor ) );
|
g.setColor( FlatUIUtils.deriveColor( active ? activeBorderColor : inactiveBorderColor, baseBorderColor ) );
|
||||||
HiDPIUtils.paintAtScale1x( (Graphics2D) g, x, y, width, height, this::paintImpl );
|
HiDPIUtils.paintAtScale1x( (Graphics2D) g, x, y, width, height, this::paintImpl );
|
||||||
@@ -522,9 +528,7 @@ public class FlatRootPaneUI
|
|||||||
|
|
||||||
protected boolean isWindowMaximized( Component c ) {
|
protected boolean isWindowMaximized( Component c ) {
|
||||||
Container parent = c.getParent();
|
Container parent = c.getParent();
|
||||||
return parent instanceof Frame
|
return parent instanceof Frame && (((Frame)parent).getExtendedState() & Frame.MAXIMIZED_BOTH) != 0;
|
||||||
? (((Frame)parent).getExtendedState() & Frame.MAXIMIZED_BOTH) != 0
|
|
||||||
: false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ import com.formdev.flatlaf.util.UIScale;
|
|||||||
*
|
*
|
||||||
* <!-- FlatScrollBarUI -->
|
* <!-- FlatScrollBarUI -->
|
||||||
*
|
*
|
||||||
|
* @uiDefault ScrollBar.minimumButtonSize Dimension
|
||||||
* @uiDefault ScrollBar.trackInsets Insets
|
* @uiDefault ScrollBar.trackInsets Insets
|
||||||
* @uiDefault ScrollBar.thumbInsets Insets
|
* @uiDefault ScrollBar.thumbInsets Insets
|
||||||
* @uiDefault ScrollBar.trackArc int
|
* @uiDefault ScrollBar.trackArc int
|
||||||
@@ -83,6 +84,7 @@ public class FlatScrollBarUI
|
|||||||
// overrides BasicScrollBarUI.supportsAbsolutePositioning (which is private)
|
// overrides BasicScrollBarUI.supportsAbsolutePositioning (which is private)
|
||||||
@Styleable protected boolean allowsAbsolutePositioning;
|
@Styleable protected boolean allowsAbsolutePositioning;
|
||||||
|
|
||||||
|
/** @since 2.1 */ @Styleable protected Dimension minimumButtonSize;
|
||||||
@Styleable protected Insets trackInsets;
|
@Styleable protected Insets trackInsets;
|
||||||
@Styleable protected Insets thumbInsets;
|
@Styleable protected Insets thumbInsets;
|
||||||
@Styleable protected int trackArc;
|
@Styleable protected int trackArc;
|
||||||
@@ -142,6 +144,7 @@ public class FlatScrollBarUI
|
|||||||
|
|
||||||
allowsAbsolutePositioning = super.getSupportsAbsolutePositioning();
|
allowsAbsolutePositioning = super.getSupportsAbsolutePositioning();
|
||||||
|
|
||||||
|
minimumButtonSize = UIManager.getDimension( "ScrollBar.minimumButtonSize" );
|
||||||
trackInsets = UIManager.getInsets( "ScrollBar.trackInsets" );
|
trackInsets = UIManager.getInsets( "ScrollBar.trackInsets" );
|
||||||
thumbInsets = UIManager.getInsets( "ScrollBar.thumbInsets" );
|
thumbInsets = UIManager.getInsets( "ScrollBar.thumbInsets" );
|
||||||
trackArc = UIManager.getInt( "ScrollBar.trackArc" );
|
trackArc = UIManager.getInt( "ScrollBar.trackArc" );
|
||||||
@@ -171,6 +174,7 @@ public class FlatScrollBarUI
|
|||||||
protected void uninstallDefaults() {
|
protected void uninstallDefaults() {
|
||||||
super.uninstallDefaults();
|
super.uninstallDefaults();
|
||||||
|
|
||||||
|
minimumButtonSize = null;
|
||||||
trackInsets = null;
|
trackInsets = null;
|
||||||
thumbInsets = null;
|
thumbInsets = null;
|
||||||
hoverTrackColor = null;
|
hoverTrackColor = null;
|
||||||
@@ -451,7 +455,6 @@ public class FlatScrollBarUI
|
|||||||
super( direction, type, foreground, disabledForeground,
|
super( direction, type, foreground, disabledForeground,
|
||||||
hoverForeground, hoverBackground, pressedForeground, pressedBackground );
|
hoverForeground, hoverBackground, pressedForeground, pressedBackground );
|
||||||
|
|
||||||
setArrowWidth( FlatArrowButton.DEFAULT_ARROW_WIDTH - 2 );
|
|
||||||
setFocusable( false );
|
setFocusable( false );
|
||||||
setRequestFocusEnabled( false );
|
setRequestFocusEnabled( false );
|
||||||
}
|
}
|
||||||
@@ -461,6 +464,18 @@ public class FlatScrollBarUI
|
|||||||
null, hoverButtonBackground, null, pressedButtonBackground );
|
null, hoverButtonBackground, null, pressedButtonBackground );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getArrowWidth() {
|
||||||
|
// scale arrow size depending on scroll bar width
|
||||||
|
// (6 is default arrow width; 10 is base scroll bar width)
|
||||||
|
int arrowWidth = Math.round( 6 * (scrollBarWidth / 10f) );
|
||||||
|
|
||||||
|
// compute arrow size that leaves equal space on both sides (arrow is centered)
|
||||||
|
arrowWidth = scrollBarWidth - (((scrollBarWidth - arrowWidth) / 2) * 2);
|
||||||
|
|
||||||
|
return arrowWidth;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Color deriveBackground( Color background ) {
|
protected Color deriveBackground( Color background ) {
|
||||||
return FlatUIUtils.deriveColor( background, scrollbar.getBackground() );
|
return FlatUIUtils.deriveColor( background, scrollbar.getBackground() );
|
||||||
@@ -469,8 +484,9 @@ public class FlatScrollBarUI
|
|||||||
@Override
|
@Override
|
||||||
public Dimension getPreferredSize() {
|
public Dimension getPreferredSize() {
|
||||||
if( isShowButtons() ) {
|
if( isShowButtons() ) {
|
||||||
int w = UIScale.scale( scrollBarWidth );
|
int w = UIScale.scale( Math.max( scrollBarWidth, (minimumButtonSize != null) ? minimumButtonSize.width : 0 ) );
|
||||||
return new Dimension( w, w );
|
int h = UIScale.scale( Math.max( scrollBarWidth, (minimumButtonSize != null) ? minimumButtonSize.height : 0 ) );
|
||||||
|
return new Dimension( w, h );
|
||||||
} else
|
} else
|
||||||
return new Dimension();
|
return new Dimension();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -234,7 +234,7 @@ public class FlatSliderUI
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
// use default font (instead of slider font) because the slider font size
|
// use default font (instead of slider font) because the slider font size
|
||||||
// may be different to label font size, but we want align the track/thumb with labels
|
// may be different to label font size, but we want to align the track/thumb with labels
|
||||||
Font font = UIManager.getFont( "defaultFont" );
|
Font font = UIManager.getFont( "defaultFont" );
|
||||||
if( font == null )
|
if( font == null )
|
||||||
font = slider.getFont();
|
font = slider.getFont();
|
||||||
|
|||||||
@@ -293,9 +293,7 @@ public class FlatSpinnerUI
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
JTextField textField = getEditorTextField( spinner.getEditor() );
|
JTextField textField = getEditorTextField( spinner.getEditor() );
|
||||||
return (textField != null)
|
return textField != null && FlatUIUtils.isPermanentFocusOwner( textField );
|
||||||
? FlatUIUtils.isPermanentFocusOwner( textField )
|
|
||||||
: false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Color getBackground( boolean enabled ) {
|
protected Color getBackground( boolean enabled ) {
|
||||||
@@ -447,7 +445,7 @@ public class FlatSpinnerUI
|
|||||||
Insets padding = scale( FlatSpinnerUI.this.padding );
|
Insets padding = scale( FlatSpinnerUI.this.padding );
|
||||||
Dimension editorSize = (editor != null) ? editor.getPreferredSize() : new Dimension( 0, 0 );
|
Dimension editorSize = (editor != null) ? editor.getPreferredSize() : new Dimension( 0, 0 );
|
||||||
|
|
||||||
// the arrows width is the same as the inner height so that the arrows area is square
|
// the arrow buttons width is the same as the inner height so that the arrow buttons area is square
|
||||||
int minimumWidth = FlatUIUtils.minimumWidth( spinner, FlatSpinnerUI.this.minimumWidth );
|
int minimumWidth = FlatUIUtils.minimumWidth( spinner, FlatSpinnerUI.this.minimumWidth );
|
||||||
int innerHeight = editorSize.height + padding.top + padding.bottom;
|
int innerHeight = editorSize.height + padding.top + padding.bottom;
|
||||||
float focusWidth = FlatUIUtils.getBorderFocusWidth( spinner );
|
float focusWidth = FlatUIUtils.getBorderFocusWidth( spinner );
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ import javax.swing.UIManager;
|
|||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
import javax.swing.plaf.basic.BasicSplitPaneDivider;
|
import javax.swing.plaf.basic.BasicSplitPaneDivider;
|
||||||
import javax.swing.plaf.basic.BasicSplitPaneUI;
|
import javax.swing.plaf.basic.BasicSplitPaneUI;
|
||||||
|
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.ui.FlatStylingSupport.UnknownStyleException;
|
import com.formdev.flatlaf.ui.FlatStylingSupport.UnknownStyleException;
|
||||||
@@ -52,6 +53,13 @@ import com.formdev.flatlaf.util.UIScale;
|
|||||||
* @uiDefault SplitPaneDivider.border Border
|
* @uiDefault SplitPaneDivider.border Border
|
||||||
* @uiDefault SplitPaneDivider.draggingColor Color only used if continuousLayout is false
|
* @uiDefault SplitPaneDivider.draggingColor Color only used if continuousLayout is false
|
||||||
*
|
*
|
||||||
|
* <!-- BasicSplitPaneDivider -->
|
||||||
|
*
|
||||||
|
* @uiDefault SplitPane.oneTouchButtonSize int
|
||||||
|
* @uiDefault SplitPane.oneTouchButtonOffset int
|
||||||
|
* @uiDefault SplitPane.centerOneTouchButtons boolean
|
||||||
|
* @uiDefault SplitPane.supportsOneTouchButtons boolean optional; default is true
|
||||||
|
*
|
||||||
* <!-- JSplitPane -->
|
* <!-- JSplitPane -->
|
||||||
*
|
*
|
||||||
* @uiDefault SplitPane.continuousLayout boolean
|
* @uiDefault SplitPane.continuousLayout boolean
|
||||||
@@ -235,7 +243,7 @@ public class FlatSplitPaneUI
|
|||||||
switch( e.getPropertyName() ) {
|
switch( e.getPropertyName() ) {
|
||||||
case JSplitPane.DIVIDER_LOCATION_PROPERTY:
|
case JSplitPane.DIVIDER_LOCATION_PROPERTY:
|
||||||
// necessary to show/hide one-touch buttons on expand/collapse
|
// necessary to show/hide one-touch buttons on expand/collapse
|
||||||
revalidate();
|
doLayout();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -345,7 +353,7 @@ public class FlatSplitPaneUI
|
|||||||
if( leftButton == null || rightButton == null || !splitPane.isOneTouchExpandable() )
|
if( leftButton == null || rightButton == null || !splitPane.isOneTouchExpandable() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// increase side of buttons, which makes them easier to hit by the user
|
// increase size of buttons, which makes them easier to hit by the user
|
||||||
// and avoids cut arrows at small divider sizes
|
// and avoids cut arrows at small divider sizes
|
||||||
int extraSize = UIScale.scale( 4 );
|
int extraSize = UIScale.scale( 4 );
|
||||||
if( orientation == JSplitPane.VERTICAL_SPLIT ) {
|
if( orientation == JSplitPane.VERTICAL_SPLIT ) {
|
||||||
@@ -360,10 +368,19 @@ public class FlatSplitPaneUI
|
|||||||
|
|
||||||
// hide buttons if not applicable
|
// hide buttons if not applicable
|
||||||
boolean leftCollapsed = isLeftCollapsed();
|
boolean leftCollapsed = isLeftCollapsed();
|
||||||
if( leftCollapsed )
|
boolean rightCollapsed = isRightCollapsed();
|
||||||
|
if( leftCollapsed || rightCollapsed ) {
|
||||||
|
leftButton.setVisible( !leftCollapsed );
|
||||||
|
rightButton.setVisible( !rightCollapsed );
|
||||||
|
} else {
|
||||||
|
Object expandableSide = splitPane.getClientProperty( FlatClientProperties.SPLIT_PANE_EXPANDABLE_SIDE );
|
||||||
|
leftButton.setVisible( expandableSide == null || !FlatClientProperties.SPLIT_PANE_EXPANDABLE_SIDE_LEFT.equals( expandableSide ) );
|
||||||
|
rightButton.setVisible( expandableSide == null || !FlatClientProperties.SPLIT_PANE_EXPANDABLE_SIDE_RIGHT.equals( expandableSide ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// move right button if left button is hidden
|
||||||
|
if( !leftButton.isVisible() )
|
||||||
rightButton.setLocation( leftButton.getLocation() );
|
rightButton.setLocation( leftButton.getLocation() );
|
||||||
leftButton.setVisible( !leftCollapsed );
|
|
||||||
rightButton.setVisible( !isRightCollapsed() );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -359,7 +359,7 @@ public class FlatStylingSupport
|
|||||||
* @param key the name of the field
|
* @param key the name of the field
|
||||||
* @param value the new value
|
* @param value the new value
|
||||||
* @return the old value of the field
|
* @return the old value of the field
|
||||||
* @throws UnknownStyleException if object does not have a annotated field with given name
|
* @throws UnknownStyleException if object does not have an annotated field with given name
|
||||||
* @throws IllegalArgumentException if value type does not fit to expected type
|
* @throws IllegalArgumentException if value type does not fit to expected type
|
||||||
*/
|
*/
|
||||||
public static Object applyToAnnotatedObject( Object obj, String key, Object value )
|
public static Object applyToAnnotatedObject( Object obj, String key, Object value )
|
||||||
@@ -517,7 +517,7 @@ public class FlatStylingSupport
|
|||||||
* @param key the name of the field
|
* @param key the name of the field
|
||||||
* @param value the new value
|
* @param value the new value
|
||||||
* @return the old value of the field
|
* @return the old value of the field
|
||||||
* @throws UnknownStyleException if object does not have a annotated field with given name
|
* @throws UnknownStyleException if object does not have an annotated field with given name
|
||||||
* @throws IllegalArgumentException if value type does not fit to expected type
|
* @throws IllegalArgumentException if value type does not fit to expected type
|
||||||
*/
|
*/
|
||||||
public static Object applyToAnnotatedObjectOrComponent( Object obj, Object comp, String key, Object value )
|
public static Object applyToAnnotatedObjectOrComponent( Object obj, Object comp, String key, Object value )
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ import java.util.Map;
|
|||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.BiConsumer;
|
import java.util.function.BiConsumer;
|
||||||
import java.util.function.IntConsumer;
|
import java.util.function.IntConsumer;
|
||||||
|
import java.util.function.Predicate;
|
||||||
import javax.accessibility.Accessible;
|
import javax.accessibility.Accessible;
|
||||||
import javax.accessibility.AccessibleContext;
|
import javax.accessibility.AccessibleContext;
|
||||||
import javax.swing.Action;
|
import javax.swing.Action;
|
||||||
@@ -82,10 +83,12 @@ import javax.swing.event.ChangeListener;
|
|||||||
import javax.swing.event.PopupMenuEvent;
|
import javax.swing.event.PopupMenuEvent;
|
||||||
import javax.swing.event.PopupMenuListener;
|
import javax.swing.event.PopupMenuListener;
|
||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
|
import javax.swing.plaf.TabbedPaneUI;
|
||||||
import javax.swing.plaf.UIResource;
|
import javax.swing.plaf.UIResource;
|
||||||
import javax.swing.plaf.basic.BasicTabbedPaneUI;
|
import javax.swing.plaf.basic.BasicTabbedPaneUI;
|
||||||
import javax.swing.text.JTextComponent;
|
import javax.swing.text.JTextComponent;
|
||||||
import javax.swing.text.View;
|
import javax.swing.text.View;
|
||||||
|
import com.formdev.flatlaf.FlatClientProperties;
|
||||||
import com.formdev.flatlaf.FlatLaf;
|
import com.formdev.flatlaf.FlatLaf;
|
||||||
import com.formdev.flatlaf.icons.FlatTabbedPaneCloseIcon;
|
import com.formdev.flatlaf.icons.FlatTabbedPaneCloseIcon;
|
||||||
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
||||||
@@ -127,6 +130,7 @@ import com.formdev.flatlaf.util.UIScale;
|
|||||||
* @uiDefault TabbedPane.selectedBackground Color optional
|
* @uiDefault TabbedPane.selectedBackground Color optional
|
||||||
* @uiDefault TabbedPane.selectedForeground Color
|
* @uiDefault TabbedPane.selectedForeground Color
|
||||||
* @uiDefault TabbedPane.underlineColor Color
|
* @uiDefault TabbedPane.underlineColor Color
|
||||||
|
* @uiDefault TabbedPane.inactiveUnderlineColor Color
|
||||||
* @uiDefault TabbedPane.disabledUnderlineColor Color
|
* @uiDefault TabbedPane.disabledUnderlineColor Color
|
||||||
* @uiDefault TabbedPane.hoverColor Color
|
* @uiDefault TabbedPane.hoverColor Color
|
||||||
* @uiDefault TabbedPane.focusColor Color
|
* @uiDefault TabbedPane.focusColor Color
|
||||||
@@ -198,6 +202,7 @@ public class FlatTabbedPaneUI
|
|||||||
@Styleable protected Color selectedBackground;
|
@Styleable protected Color selectedBackground;
|
||||||
@Styleable protected Color selectedForeground;
|
@Styleable protected Color selectedForeground;
|
||||||
@Styleable protected Color underlineColor;
|
@Styleable protected Color underlineColor;
|
||||||
|
/** @since 2.2 */ @Styleable protected Color inactiveUnderlineColor;
|
||||||
@Styleable protected Color disabledUnderlineColor;
|
@Styleable protected Color disabledUnderlineColor;
|
||||||
@Styleable protected Color hoverColor;
|
@Styleable protected Color hoverColor;
|
||||||
@Styleable protected Color focusColor;
|
@Styleable protected Color focusColor;
|
||||||
@@ -288,6 +293,7 @@ public class FlatTabbedPaneUI
|
|||||||
|
|
||||||
super.installUI( c );
|
super.installUI( c );
|
||||||
|
|
||||||
|
FlatSelectedTabRepainter.install();
|
||||||
installStyle();
|
installStyle();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -318,6 +324,7 @@ public class FlatTabbedPaneUI
|
|||||||
selectedBackground = UIManager.getColor( "TabbedPane.selectedBackground" );
|
selectedBackground = UIManager.getColor( "TabbedPane.selectedBackground" );
|
||||||
selectedForeground = UIManager.getColor( "TabbedPane.selectedForeground" );
|
selectedForeground = UIManager.getColor( "TabbedPane.selectedForeground" );
|
||||||
underlineColor = UIManager.getColor( "TabbedPane.underlineColor" );
|
underlineColor = UIManager.getColor( "TabbedPane.underlineColor" );
|
||||||
|
inactiveUnderlineColor = FlatUIUtils.getUIColor( "TabbedPane.inactiveUnderlineColor", underlineColor );
|
||||||
disabledUnderlineColor = UIManager.getColor( "TabbedPane.disabledUnderlineColor" );
|
disabledUnderlineColor = UIManager.getColor( "TabbedPane.disabledUnderlineColor" );
|
||||||
hoverColor = UIManager.getColor( "TabbedPane.hoverColor" );
|
hoverColor = UIManager.getColor( "TabbedPane.hoverColor" );
|
||||||
focusColor = UIManager.getColor( "TabbedPane.focusColor" );
|
focusColor = UIManager.getColor( "TabbedPane.focusColor" );
|
||||||
@@ -385,6 +392,7 @@ public class FlatTabbedPaneUI
|
|||||||
selectedBackground = null;
|
selectedBackground = null;
|
||||||
selectedForeground = null;
|
selectedForeground = null;
|
||||||
underlineColor = null;
|
underlineColor = null;
|
||||||
|
inactiveUnderlineColor = null;
|
||||||
disabledUnderlineColor = null;
|
disabledUnderlineColor = null;
|
||||||
hoverColor = null;
|
hoverColor = null;
|
||||||
focusColor = null;
|
focusColor = null;
|
||||||
@@ -650,7 +658,7 @@ public class FlatTabbedPaneUI
|
|||||||
case "tabIconPlacement": value = parseTabIconPlacement( (String) value ); break;
|
case "tabIconPlacement": value = parseTabIconPlacement( (String) value ); break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Object oldValue = null;
|
Object oldValue;
|
||||||
switch( key ) {
|
switch( key ) {
|
||||||
// BasicTabbedPaneUI
|
// BasicTabbedPaneUI
|
||||||
case "tabInsets": oldValue = tabInsets; tabInsets = (Insets) value; return oldValue;
|
case "tabInsets": oldValue = tabInsets; tabInsets = (Insets) value; return oldValue;
|
||||||
@@ -733,7 +741,6 @@ public class FlatTabbedPaneUI
|
|||||||
|
|
||||||
// increase size of repaint region to include part of content border
|
// increase size of repaint region to include part of content border
|
||||||
if( contentSeparatorHeight > 0 &&
|
if( contentSeparatorHeight > 0 &&
|
||||||
getTabType() == TAB_TYPE_CARD &&
|
|
||||||
clientPropertyBoolean( tabPane, TABBED_PANE_SHOW_CONTENT_SEPARATOR, true ) )
|
clientPropertyBoolean( tabPane, TABBED_PANE_SHOW_CONTENT_SEPARATOR, true ) )
|
||||||
{
|
{
|
||||||
int sh = scale( contentSeparatorHeight );
|
int sh = scale( contentSeparatorHeight );
|
||||||
@@ -1205,7 +1212,9 @@ public class FlatTabbedPaneUI
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void paintTabSelection( Graphics g, int tabPlacement, int x, int y, int w, int h ) {
|
protected void paintTabSelection( Graphics g, int tabPlacement, int x, int y, int w, int h ) {
|
||||||
g.setColor( tabPane.isEnabled() ? underlineColor : disabledUnderlineColor );
|
g.setColor( tabPane.isEnabled()
|
||||||
|
? (isTabbedPaneOrChildFocused() ? underlineColor : inactiveUnderlineColor)
|
||||||
|
: disabledUnderlineColor );
|
||||||
|
|
||||||
// paint underline selection
|
// paint underline selection
|
||||||
boolean atBottom = (getTabType() != TAB_TYPE_CARD);
|
boolean atBottom = (getTabType() != TAB_TYPE_CARD);
|
||||||
@@ -1236,6 +1245,23 @@ public class FlatTabbedPaneUI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 2.2 */
|
||||||
|
@SuppressWarnings( "unchecked" )
|
||||||
|
protected boolean isTabbedPaneOrChildFocused() {
|
||||||
|
KeyboardFocusManager keyboardFocusManager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
|
||||||
|
|
||||||
|
Object value = tabPane.getClientProperty( FlatClientProperties.COMPONENT_FOCUS_OWNER );
|
||||||
|
if( value instanceof Predicate ) {
|
||||||
|
return ((Predicate<JComponent>)value).test( tabPane ) &&
|
||||||
|
FlatUIUtils.isInActiveWindow( tabPane, keyboardFocusManager.getActiveWindow() );
|
||||||
|
}
|
||||||
|
|
||||||
|
Component focusOwner = keyboardFocusManager.getPermanentFocusOwner();
|
||||||
|
return focusOwner != null &&
|
||||||
|
SwingUtilities.isDescendingFrom( focusOwner, tabPane ) &&
|
||||||
|
FlatUIUtils.isInActiveWindow( focusOwner, keyboardFocusManager.getActiveWindow() );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Actually does nearly the same as super.paintContentBorder() but
|
* Actually does nearly the same as super.paintContentBorder() but
|
||||||
* - not using UIManager.getColor("TabbedPane.contentAreaColor") to be GUI builder friendly
|
* - not using UIManager.getColor("TabbedPane.contentAreaColor") to be GUI builder friendly
|
||||||
@@ -1841,7 +1867,7 @@ public class FlatTabbedPaneUI
|
|||||||
super( direction, arrowType,
|
super( direction, arrowType,
|
||||||
FlatTabbedPaneUI.this.foreground, FlatTabbedPaneUI.this.disabledForeground,
|
FlatTabbedPaneUI.this.foreground, FlatTabbedPaneUI.this.disabledForeground,
|
||||||
null, buttonHoverBackground, null, buttonPressedBackground );
|
null, buttonHoverBackground, null, buttonPressedBackground );
|
||||||
setArrowWidth( 10 );
|
setArrowWidth( 11 );
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void updateStyle() {
|
protected void updateStyle() {
|
||||||
@@ -1983,7 +2009,7 @@ public class FlatTabbedPaneUI
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected JMenuItem createTabMenuItem( int tabIndex ) {
|
protected JMenuItem createTabMenuItem( int tabIndex ) {
|
||||||
// search for tab name in this places
|
// search for tab name in these places
|
||||||
// 1. tab title
|
// 1. tab title
|
||||||
// 2. text of label or text component in custom tab component (including children)
|
// 2. text of label or text component in custom tab component (including children)
|
||||||
// 3. accessible name of tab
|
// 3. accessible name of tab
|
||||||
@@ -2016,7 +2042,7 @@ public class FlatTabbedPaneUI
|
|||||||
menuItem.setOpaque( true );
|
menuItem.setOpaque( true );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !tabPane.isEnabledAt( tabIndex ) )
|
if( !tabPane.isEnabled() || !tabPane.isEnabledAt( tabIndex ) )
|
||||||
menuItem.setEnabled( false );
|
menuItem.setEnabled( false );
|
||||||
|
|
||||||
menuItem.addActionListener( e -> selectTab( tabIndex ) );
|
menuItem.addActionListener( e -> selectTab( tabIndex ) );
|
||||||
@@ -2412,7 +2438,7 @@ public class FlatTabbedPaneUI
|
|||||||
if( tabPane == null || tabViewport == null )
|
if( tabPane == null || tabViewport == null )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if( !scrolled || tabViewport == null )
|
if( !scrolled )
|
||||||
return;
|
return;
|
||||||
scrolled = false;
|
scrolled = false;
|
||||||
|
|
||||||
@@ -2525,9 +2551,7 @@ public class FlatTabbedPaneUI
|
|||||||
setRolloverTab( tabIndex );
|
setRolloverTab( tabIndex );
|
||||||
|
|
||||||
// check whether mouse hit tab close area
|
// check whether mouse hit tab close area
|
||||||
boolean hitClose = isTabClosable( tabIndex )
|
boolean hitClose = isTabClosable( tabIndex ) && getTabCloseHitArea( tabIndex ).contains( x, y );
|
||||||
? getTabCloseHitArea( tabIndex ).contains( x, y )
|
|
||||||
: false;
|
|
||||||
if( e.getID() == MouseEvent.MOUSE_PRESSED )
|
if( e.getID() == MouseEvent.MOUSE_PRESSED )
|
||||||
pressedTabIndex = hitClose ? tabIndex : -1;
|
pressedTabIndex = hitClose ? tabIndex : -1;
|
||||||
setRolloverTabClose( hitClose );
|
setRolloverTabClose( hitClose );
|
||||||
@@ -2550,8 +2574,7 @@ public class FlatTabbedPaneUI
|
|||||||
if( tabIndex == lastTipTabIndex )
|
if( tabIndex == lastTipTabIndex )
|
||||||
return; // closeTip already set
|
return; // closeTip already set
|
||||||
|
|
||||||
if( tabIndex != lastTipTabIndex )
|
restoreTabToolTip();
|
||||||
restoreTabToolTip();
|
|
||||||
|
|
||||||
lastTipTabIndex = tabIndex;
|
lastTipTabIndex = tabIndex;
|
||||||
lastTip = tabPane.getToolTipTextAt( lastTipTabIndex );
|
lastTip = tabPane.getToolTipTextAt( lastTipTabIndex );
|
||||||
@@ -3344,4 +3367,77 @@ public class FlatTabbedPaneUI
|
|||||||
delegate.actionPerformed( e );
|
delegate.actionPerformed( e );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---- class FlatSelectedTabRepainter -------------------------------------
|
||||||
|
|
||||||
|
private static class FlatSelectedTabRepainter
|
||||||
|
implements PropertyChangeListener//, Runnable
|
||||||
|
{
|
||||||
|
private static FlatSelectedTabRepainter instance;
|
||||||
|
|
||||||
|
private KeyboardFocusManager keyboardFocusManager;
|
||||||
|
|
||||||
|
static void install() {
|
||||||
|
synchronized( FlatSelectedTabRepainter.class ) {
|
||||||
|
if( instance != null )
|
||||||
|
return;
|
||||||
|
|
||||||
|
instance = new FlatSelectedTabRepainter();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FlatSelectedTabRepainter() {
|
||||||
|
keyboardFocusManager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
|
||||||
|
keyboardFocusManager.addPropertyChangeListener( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void uninstall() {
|
||||||
|
synchronized( FlatSelectedTabRepainter.class ) {
|
||||||
|
if( instance == null )
|
||||||
|
return;
|
||||||
|
|
||||||
|
keyboardFocusManager.removePropertyChangeListener( this );
|
||||||
|
keyboardFocusManager = null;
|
||||||
|
instance = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void propertyChange( PropertyChangeEvent e ) {
|
||||||
|
// uninstall if no longer using FlatLaf
|
||||||
|
if( !(UIManager.getLookAndFeel() instanceof FlatLaf) ) {
|
||||||
|
uninstall();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch( e.getPropertyName() ) {
|
||||||
|
case "permanentFocusOwner":
|
||||||
|
Object oldValue = e.getOldValue();
|
||||||
|
Object newValue = e.getNewValue();
|
||||||
|
if( oldValue instanceof Component )
|
||||||
|
repaintSelectedTabs( (Component) oldValue );
|
||||||
|
if( newValue instanceof Component )
|
||||||
|
repaintSelectedTabs( (Component) newValue );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "activeWindow":
|
||||||
|
repaintSelectedTabs( keyboardFocusManager.getPermanentFocusOwner() );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void repaintSelectedTabs( Component c ) {
|
||||||
|
if( c instanceof JTabbedPane )
|
||||||
|
repaintSelectedTab( (JTabbedPane) c );
|
||||||
|
|
||||||
|
while( (c = SwingUtilities.getAncestorOfClass( JTabbedPane.class, c )) != null )
|
||||||
|
repaintSelectedTab( (JTabbedPane) c );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void repaintSelectedTab( JTabbedPane tabbedPane ) {
|
||||||
|
TabbedPaneUI ui = tabbedPane.getUI();
|
||||||
|
if( ui instanceof FlatTabbedPaneUI )
|
||||||
|
((FlatTabbedPaneUI) ui).repaintTab( tabbedPane.getSelectedIndex() );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ public class FlatTableCellBorder
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Because this borders are always shared for all tables,
|
* Because this border is always shared for all tables,
|
||||||
* get border specific style from FlatTableUI.
|
* get border specific style from FlatTableUI.
|
||||||
*/
|
*/
|
||||||
static <T> T getStyleFromTableUI( Component c, Function<FlatTableUI, T> f ) {
|
static <T> T getStyleFromTableUI( Component c, Function<FlatTableUI, T> f ) {
|
||||||
|
|||||||
@@ -39,7 +39,9 @@ import javax.swing.event.MouseInputListener;
|
|||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
import javax.swing.plaf.UIResource;
|
import javax.swing.plaf.UIResource;
|
||||||
import javax.swing.plaf.basic.BasicTableHeaderUI;
|
import javax.swing.plaf.basic.BasicTableHeaderUI;
|
||||||
|
import javax.swing.table.JTableHeader;
|
||||||
import javax.swing.table.TableCellRenderer;
|
import javax.swing.table.TableCellRenderer;
|
||||||
|
import javax.swing.table.TableColumn;
|
||||||
import javax.swing.table.TableColumnModel;
|
import javax.swing.table.TableColumnModel;
|
||||||
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;
|
||||||
@@ -195,6 +197,8 @@ public class FlatTableHeaderUI
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void paint( Graphics g, JComponent c ) {
|
public void paint( Graphics g, JComponent c ) {
|
||||||
|
fixDraggedAndResizingColumns( header );
|
||||||
|
|
||||||
TableColumnModel columnModel = header.getColumnModel();
|
TableColumnModel columnModel = header.getColumnModel();
|
||||||
if( columnModel.getColumnCount() <= 0 )
|
if( columnModel.getColumnCount() <= 0 )
|
||||||
return;
|
return;
|
||||||
@@ -269,6 +273,32 @@ public class FlatTableHeaderUI
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void fixDraggedAndResizingColumns( JTableHeader header ) {
|
||||||
|
if( header == null )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Dragged column may be outdated in the case that the table structure
|
||||||
|
// was changed from a table header popup menu action. In this case
|
||||||
|
// the paint methods in BasicTableHeaderUI and BasicTableUI would throw exceptions.
|
||||||
|
TableColumn draggedColumn = header.getDraggedColumn();
|
||||||
|
if( draggedColumn != null && !isValidColumn( header.getColumnModel(), draggedColumn ) )
|
||||||
|
header.setDraggedColumn( null );
|
||||||
|
|
||||||
|
// also clear outdated resizing column (although this seems not cause exceptions)
|
||||||
|
TableColumn resizingColumn = header.getResizingColumn();
|
||||||
|
if( resizingColumn != null && !isValidColumn( header.getColumnModel(), resizingColumn ) )
|
||||||
|
header.setResizingColumn( null );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isValidColumn( TableColumnModel cm, TableColumn column ) {
|
||||||
|
int count = cm.getColumnCount();
|
||||||
|
for( int i = 0; i < count; i++ ) {
|
||||||
|
if( cm.getColumn( i ) == column )
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
//---- class FlatTableCellHeaderRenderer ----------------------------------
|
//---- class FlatTableCellHeaderRenderer ----------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ import com.formdev.flatlaf.util.UIScale;
|
|||||||
* @uiDefault Table.intercellSpacing Dimension
|
* @uiDefault Table.intercellSpacing Dimension
|
||||||
* @uiDefault Table.selectionInactiveBackground Color
|
* @uiDefault Table.selectionInactiveBackground Color
|
||||||
* @uiDefault Table.selectionInactiveForeground Color
|
* @uiDefault Table.selectionInactiveForeground Color
|
||||||
|
* @uiDefault Table.paintOutsideAlternateRows boolean
|
||||||
*
|
*
|
||||||
* <!-- FlatTableCellBorder -->
|
* <!-- FlatTableCellBorder -->
|
||||||
*
|
*
|
||||||
@@ -95,7 +96,7 @@ import com.formdev.flatlaf.util.UIScale;
|
|||||||
*/
|
*/
|
||||||
public class FlatTableUI
|
public class FlatTableUI
|
||||||
extends BasicTableUI
|
extends BasicTableUI
|
||||||
implements StyleableUI
|
implements StyleableUI, FlatViewportUI.ViewportPainter
|
||||||
{
|
{
|
||||||
protected boolean showHorizontalLines;
|
protected boolean showHorizontalLines;
|
||||||
protected boolean showVerticalLines;
|
protected boolean showVerticalLines;
|
||||||
@@ -288,7 +289,7 @@ public class FlatTableUI
|
|||||||
/**
|
/**
|
||||||
* Toggle selection colors from focused to inactive and vice versa.
|
* Toggle selection colors from focused to inactive and vice versa.
|
||||||
*
|
*
|
||||||
* This is not a optimal solution but much easier than rewriting the whole paint methods.
|
* This is not an optimal solution but much easier than rewriting the whole paint methods.
|
||||||
*
|
*
|
||||||
* Using a LaF specific renderer was avoided because often a custom renderer is
|
* Using a LaF specific renderer was avoided because often a custom renderer is
|
||||||
* already used in applications. Then either the inactive colors are not used,
|
* already used in applications. Then either the inactive colors are not used,
|
||||||
@@ -313,6 +314,8 @@ public class FlatTableUI
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void paint( Graphics g, JComponent c ) {
|
public void paint( Graphics g, JComponent c ) {
|
||||||
|
FlatTableHeaderUI.fixDraggedAndResizingColumns( table.getTableHeader() );
|
||||||
|
|
||||||
boolean horizontalLines = table.getShowHorizontalLines();
|
boolean horizontalLines = table.getShowHorizontalLines();
|
||||||
boolean verticalLines = table.getShowVerticalLines();
|
boolean verticalLines = table.getShowVerticalLines();
|
||||||
if( horizontalLines || verticalLines ) {
|
if( horizontalLines || verticalLines ) {
|
||||||
@@ -421,4 +424,38 @@ public class FlatTableUI
|
|||||||
? (viewport != rowHeader)
|
? (viewport != rowHeader)
|
||||||
: (viewport == rowHeader || rowHeader == null);
|
: (viewport == rowHeader || rowHeader == null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 2.3 */
|
||||||
|
@Override
|
||||||
|
public void paintViewport( Graphics g, JComponent c, JViewport viewport ) {
|
||||||
|
int viewportWidth = viewport.getWidth();
|
||||||
|
int viewportHeight = viewport.getHeight();
|
||||||
|
|
||||||
|
// fill viewport background in same color as table background
|
||||||
|
if( viewport.isOpaque() ) {
|
||||||
|
g.setColor( table.getBackground() );
|
||||||
|
g.fillRect( 0, 0, viewportWidth, viewportHeight );
|
||||||
|
}
|
||||||
|
|
||||||
|
// paint alternating empty rows
|
||||||
|
boolean paintOutside = UIManager.getBoolean( "Table.paintOutsideAlternateRows" );
|
||||||
|
Color alternateColor;
|
||||||
|
if( paintOutside && (alternateColor = UIManager.getColor( "Table.alternateRowColor" )) != null ) {
|
||||||
|
g.setColor( alternateColor );
|
||||||
|
|
||||||
|
int rowCount = table.getRowCount();
|
||||||
|
|
||||||
|
// paint alternating empty rows below the table
|
||||||
|
int tableHeight = table.getHeight();
|
||||||
|
if( tableHeight < viewportHeight ) {
|
||||||
|
int tableWidth = table.getWidth();
|
||||||
|
int rowHeight = table.getRowHeight();
|
||||||
|
|
||||||
|
for( int y = tableHeight, row = rowCount; y < viewportHeight; y += rowHeight, row++ ) {
|
||||||
|
if( row % 2 != 0 )
|
||||||
|
g.fillRect( 0, y, tableWidth, rowHeight );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -369,7 +369,7 @@ public class FlatTextFieldUI
|
|||||||
if( !(oldBackground instanceof UIResource) )
|
if( !(oldBackground instanceof UIResource) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// do not update background if it currently has a unknown color (assigned from outside)
|
// do not update background if it currently has an unknown color (assigned from outside)
|
||||||
if( oldBackground != background &&
|
if( oldBackground != background &&
|
||||||
oldBackground != disabledBackground &&
|
oldBackground != disabledBackground &&
|
||||||
oldBackground != inactiveBackground &&
|
oldBackground != inactiveBackground &&
|
||||||
@@ -610,7 +610,7 @@ debug*/
|
|||||||
* Returns the rectangle used to paint leading and trailing icons.
|
* Returns the rectangle used to paint leading and trailing icons.
|
||||||
* It invokes {@code super.getVisibleEditorRect()} and reduces left and/or
|
* It invokes {@code super.getVisibleEditorRect()} and reduces left and/or
|
||||||
* right margin if the text field has leading or trailing icons or components.
|
* right margin if the text field has leading or trailing icons or components.
|
||||||
* Also the preferred widths of leading and trailing components are removed.
|
* Also, the preferred widths of leading and trailing components are removed.
|
||||||
*
|
*
|
||||||
* @since 2
|
* @since 2
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import java.awt.Container;
|
|||||||
import java.awt.Dialog;
|
import java.awt.Dialog;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.EventQueue;
|
import java.awt.EventQueue;
|
||||||
|
import java.awt.FontMetrics;
|
||||||
import java.awt.Frame;
|
import java.awt.Frame;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.awt.GraphicsConfiguration;
|
import java.awt.GraphicsConfiguration;
|
||||||
@@ -50,13 +51,13 @@ import javax.accessibility.AccessibleContext;
|
|||||||
import javax.swing.BorderFactory;
|
import javax.swing.BorderFactory;
|
||||||
import javax.swing.Box;
|
import javax.swing.Box;
|
||||||
import javax.swing.BoxLayout;
|
import javax.swing.BoxLayout;
|
||||||
|
import javax.swing.Icon;
|
||||||
import javax.swing.JButton;
|
import javax.swing.JButton;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
import javax.swing.JMenuBar;
|
import javax.swing.JMenuBar;
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
import javax.swing.JRootPane;
|
import javax.swing.JRootPane;
|
||||||
import javax.swing.SwingConstants;
|
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import javax.swing.border.AbstractBorder;
|
import javax.swing.border.AbstractBorder;
|
||||||
@@ -83,10 +84,14 @@ import com.formdev.flatlaf.util.UIScale;
|
|||||||
* @uiDefault TitlePane.iconMargins Insets
|
* @uiDefault TitlePane.iconMargins Insets
|
||||||
* @uiDefault TitlePane.titleMargins Insets
|
* @uiDefault TitlePane.titleMargins Insets
|
||||||
* @uiDefault TitlePane.menuBarEmbedded boolean
|
* @uiDefault TitlePane.menuBarEmbedded boolean
|
||||||
|
* @uiDefault TitlePane.titleMinimumWidth int
|
||||||
|
* @uiDefault TitlePane.buttonMinimumWidth int
|
||||||
* @uiDefault TitlePane.buttonMaximizedHeight int
|
* @uiDefault TitlePane.buttonMaximizedHeight int
|
||||||
* @uiDefault TitlePane.centerTitle boolean
|
* @uiDefault TitlePane.centerTitle boolean
|
||||||
* @uiDefault TitlePane.centerTitleIfMenuBarEmbedded boolean
|
* @uiDefault TitlePane.centerTitleIfMenuBarEmbedded boolean
|
||||||
|
* @uiDefault TitlePane.showIconBesideTitle boolean
|
||||||
* @uiDefault TitlePane.menuBarTitleGap int
|
* @uiDefault TitlePane.menuBarTitleGap int
|
||||||
|
* @uiDefault TitlePane.menuBarResizeHeight int
|
||||||
* @uiDefault TitlePane.closeIcon Icon
|
* @uiDefault TitlePane.closeIcon Icon
|
||||||
* @uiDefault TitlePane.iconifyIcon Icon
|
* @uiDefault TitlePane.iconifyIcon Icon
|
||||||
* @uiDefault TitlePane.maximizeIcon Icon
|
* @uiDefault TitlePane.maximizeIcon Icon
|
||||||
@@ -107,10 +112,15 @@ public class FlatTitlePane
|
|||||||
/** @since 2 */ protected final boolean showIcon = FlatUIUtils.getUIBoolean( "TitlePane.showIcon", true );
|
/** @since 2 */ protected final boolean showIcon = FlatUIUtils.getUIBoolean( "TitlePane.showIcon", true );
|
||||||
/** @since 2 */ protected final int noIconLeftGap = FlatUIUtils.getUIInt( "TitlePane.noIconLeftGap", 8 );
|
/** @since 2 */ protected final int noIconLeftGap = FlatUIUtils.getUIInt( "TitlePane.noIconLeftGap", 8 );
|
||||||
protected final Dimension iconSize = UIManager.getDimension( "TitlePane.iconSize" );
|
protected final Dimension iconSize = UIManager.getDimension( "TitlePane.iconSize" );
|
||||||
|
/** @since 2.4 */ protected final int titleMinimumWidth = FlatUIUtils.getUIInt( "TitlePane.titleMinimumWidth", 60 );
|
||||||
|
/** @since 2.4 */ protected final int buttonMinimumWidth = FlatUIUtils.getUIInt( "TitlePane.buttonMinimumWidth", 30 );
|
||||||
protected final int buttonMaximizedHeight = UIManager.getInt( "TitlePane.buttonMaximizedHeight" );
|
protected final int buttonMaximizedHeight = UIManager.getInt( "TitlePane.buttonMaximizedHeight" );
|
||||||
protected final boolean centerTitle = UIManager.getBoolean( "TitlePane.centerTitle" );
|
protected final boolean centerTitle = UIManager.getBoolean( "TitlePane.centerTitle" );
|
||||||
protected final boolean centerTitleIfMenuBarEmbedded = FlatUIUtils.getUIBoolean( "TitlePane.centerTitleIfMenuBarEmbedded", true );
|
protected final boolean centerTitleIfMenuBarEmbedded = FlatUIUtils.getUIBoolean( "TitlePane.centerTitleIfMenuBarEmbedded", true );
|
||||||
protected final int menuBarTitleGap = FlatUIUtils.getUIInt( "TitlePane.menuBarTitleGap", 20 );
|
/** @since 2.4 */ protected final boolean showIconBesideTitle = UIManager.getBoolean( "TitlePane.showIconBesideTitle" );
|
||||||
|
protected final int menuBarTitleGap = FlatUIUtils.getUIInt( "TitlePane.menuBarTitleGap", 40 );
|
||||||
|
/** @since 2.4 */ protected final int menuBarTitleMinimumGap = FlatUIUtils.getUIInt( "TitlePane.menuBarTitleMinimumGap", 12 );
|
||||||
|
/** @since 2.4 */ protected final int menuBarResizeHeight = FlatUIUtils.getUIInt( "TitlePane.menuBarResizeHeight", 4 );
|
||||||
|
|
||||||
protected final JRootPane rootPane;
|
protected final JRootPane rootPane;
|
||||||
|
|
||||||
@@ -142,6 +152,8 @@ public class FlatTitlePane
|
|||||||
|
|
||||||
// necessary for closing window with double-click on icon
|
// necessary for closing window with double-click on icon
|
||||||
iconLabel.addMouseListener( handler );
|
iconLabel.addMouseListener( handler );
|
||||||
|
|
||||||
|
applyComponentOrientation( rootPane.getComponentOrientation() );
|
||||||
}
|
}
|
||||||
|
|
||||||
protected FlatTitlePaneBorder createTitlePaneBorder() {
|
protected FlatTitlePaneBorder createTitlePaneBorder() {
|
||||||
@@ -163,7 +175,6 @@ public class FlatTitlePane
|
|||||||
};
|
};
|
||||||
iconLabel.setBorder( new FlatEmptyBorder( UIManager.getInsets( "TitlePane.iconMargins" ) ) );
|
iconLabel.setBorder( new FlatEmptyBorder( UIManager.getInsets( "TitlePane.iconMargins" ) ) );
|
||||||
titleLabel.setBorder( new FlatEmptyBorder( UIManager.getInsets( "TitlePane.titleMargins" ) ) );
|
titleLabel.setBorder( new FlatEmptyBorder( UIManager.getInsets( "TitlePane.titleMargins" ) ) );
|
||||||
titleLabel.setHorizontalAlignment( SwingConstants.CENTER );
|
|
||||||
|
|
||||||
leftPanel.setLayout( new BoxLayout( leftPanel, BoxLayout.LINE_AXIS ) );
|
leftPanel.setLayout( new BoxLayout( leftPanel, BoxLayout.LINE_AXIS ) );
|
||||||
leftPanel.setOpaque( false );
|
leftPanel.setOpaque( false );
|
||||||
@@ -183,18 +194,52 @@ public class FlatTitlePane
|
|||||||
setLayout( new BorderLayout() {
|
setLayout( new BorderLayout() {
|
||||||
@Override
|
@Override
|
||||||
public void layoutContainer( Container target ) {
|
public void layoutContainer( Container target ) {
|
||||||
super.layoutContainer( target );
|
// compute available bounds
|
||||||
|
|
||||||
// make left panel (with embedded menu bar) smaller if horizontal space is rare
|
|
||||||
// to avoid that embedded menu bar overlaps button bar
|
|
||||||
Insets insets = target.getInsets();
|
Insets insets = target.getInsets();
|
||||||
int width = target.getWidth() - insets.left - insets.right;
|
int x = insets.left;
|
||||||
if( leftPanel.getWidth() + buttonPanel.getWidth() > width ) {
|
int y = insets.top;
|
||||||
int oldWidth = leftPanel.getWidth();
|
int w = target.getWidth() - insets.left - insets.right;
|
||||||
int newWidth = Math.max( width - buttonPanel.getWidth(), 0 );
|
int h = target.getHeight() - insets.top - insets.bottom;
|
||||||
leftPanel.setSize( newWidth, leftPanel.getHeight() );
|
|
||||||
if( !getComponentOrientation().isLeftToRight() )
|
// compute widths
|
||||||
leftPanel.setLocation( leftPanel.getX() + (oldWidth - newWidth), leftPanel.getY() );
|
int leftWidth = leftPanel.getPreferredSize().width;
|
||||||
|
int buttonsWidth = buttonPanel.getPreferredSize().width;
|
||||||
|
int titleWidth = w - leftWidth - buttonsWidth;
|
||||||
|
int minTitleWidth = UIScale.scale( titleMinimumWidth );
|
||||||
|
|
||||||
|
// increase minimum width if icon is show besides the title
|
||||||
|
Icon icon = titleLabel.getIcon();
|
||||||
|
if( icon != null ) {
|
||||||
|
Insets iconInsets = iconLabel.getInsets();
|
||||||
|
int iconTextGap = titleLabel.getComponentOrientation().isLeftToRight() ? iconInsets.right : iconInsets.left;
|
||||||
|
minTitleWidth += icon.getIconWidth() + iconTextGap;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if title is too small, reduce width of buttons
|
||||||
|
if( titleWidth < minTitleWidth ) {
|
||||||
|
buttonsWidth = Math.max( buttonsWidth - (minTitleWidth - titleWidth), buttonPanel.getMinimumSize().width );
|
||||||
|
titleWidth = w - leftWidth - buttonsWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if title is still too small, reduce width of left panel (icon and embedded menu bar)
|
||||||
|
if( titleWidth < minTitleWidth ) {
|
||||||
|
int minLeftWidth = iconLabel.isVisible()
|
||||||
|
? iconLabel.getWidth() - iconLabel.getInsets().right
|
||||||
|
: UIScale.scale( noIconLeftGap );
|
||||||
|
leftWidth = Math.max( leftWidth - (minTitleWidth - titleWidth), minLeftWidth );
|
||||||
|
titleWidth = w - leftWidth - buttonsWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( target.getComponentOrientation().isLeftToRight() ) {
|
||||||
|
// left-to-right
|
||||||
|
leftPanel.setBounds( x, y, leftWidth, h );
|
||||||
|
titleLabel.setBounds( x + leftWidth, y, titleWidth, h );
|
||||||
|
buttonPanel.setBounds( x + leftWidth + titleWidth, y, buttonsWidth, h );
|
||||||
|
} else {
|
||||||
|
// right-to-left
|
||||||
|
buttonPanel.setBounds( x, y, buttonsWidth, h );
|
||||||
|
titleLabel.setBounds( x + buttonsWidth, y, titleWidth, h );
|
||||||
|
leftPanel.setBounds( x + buttonsWidth + titleWidth, y, leftWidth, h );
|
||||||
}
|
}
|
||||||
|
|
||||||
// If menu bar is embedded and contains a horizontal glue component,
|
// If menu bar is embedded and contains a horizontal glue component,
|
||||||
@@ -233,10 +278,7 @@ public class FlatTitlePane
|
|||||||
@Override
|
@Override
|
||||||
public Dimension getPreferredSize() {
|
public Dimension getPreferredSize() {
|
||||||
Dimension size = super.getPreferredSize();
|
Dimension size = super.getPreferredSize();
|
||||||
if( buttonMaximizedHeight > 0 &&
|
if( buttonMaximizedHeight > 0 && isWindowMaximized() && !hasVisibleEmbeddedMenuBar( rootPane.getJMenuBar() ) ) {
|
||||||
window instanceof Frame &&
|
|
||||||
(((Frame)window).getExtendedState() & Frame.MAXIMIZED_BOTH) != 0 )
|
|
||||||
{
|
|
||||||
// make title pane height smaller when frame is maximized
|
// make title pane height smaller when frame is maximized
|
||||||
size = new Dimension( size.width, Math.min( size.height, UIScale.scale( buttonMaximizedHeight ) ) );
|
size = new Dimension( size.width, Math.min( size.height, UIScale.scale( buttonMaximizedHeight ) ) );
|
||||||
}
|
}
|
||||||
@@ -248,7 +290,7 @@ public class FlatTitlePane
|
|||||||
if( rootPane.getWindowDecorationStyle() == JRootPane.FRAME ) {
|
if( rootPane.getWindowDecorationStyle() == JRootPane.FRAME ) {
|
||||||
// JRootPane.FRAME works only for frames (and not for dialogs)
|
// JRootPane.FRAME works only for frames (and not for dialogs)
|
||||||
// but at this time the owner window type is unknown (not yet added)
|
// but at this time the owner window type is unknown (not yet added)
|
||||||
// so we add the iconify/maximize/restore buttons and they are shown
|
// so we add the iconify/maximize/restore buttons, and they are shown
|
||||||
// later in frameStateChanged(), which is invoked from addNotify()
|
// later in frameStateChanged(), which is invoked from addNotify()
|
||||||
|
|
||||||
buttonPanel.add( iconifyButton );
|
buttonPanel.add( iconifyButton );
|
||||||
@@ -259,7 +301,13 @@ public class FlatTitlePane
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected JButton createButton( String iconKey, String accessibleName, ActionListener action ) {
|
protected JButton createButton( String iconKey, String accessibleName, ActionListener action ) {
|
||||||
JButton button = new JButton( UIManager.getIcon( iconKey ) );
|
JButton button = new JButton( UIManager.getIcon( iconKey ) ) {
|
||||||
|
@Override
|
||||||
|
public Dimension getMinimumSize() {
|
||||||
|
// allow the button to shrink if space is rare
|
||||||
|
return new Dimension( UIScale.scale( buttonMinimumWidth ), super.getMinimumSize().height );
|
||||||
|
}
|
||||||
|
};
|
||||||
button.setFocusable( false );
|
button.setFocusable( false );
|
||||||
button.setContentAreaFilled( false );
|
button.setContentAreaFilled( false );
|
||||||
button.setBorder( BorderFactory.createEmptyBorder() );
|
button.setBorder( BorderFactory.createEmptyBorder() );
|
||||||
@@ -356,11 +404,12 @@ public class FlatTitlePane
|
|||||||
boolean hasIcon = (images != null && !images.isEmpty());
|
boolean hasIcon = (images != null && !images.isEmpty());
|
||||||
|
|
||||||
// set icon
|
// set icon
|
||||||
iconLabel.setIcon( hasIcon ? new FlatTitlePaneIcon( images, iconSize ) : null );
|
iconLabel.setIcon( hasIcon && !showIconBesideTitle ? new FlatTitlePaneIcon( images, iconSize ) : null );
|
||||||
|
titleLabel.setIcon( hasIcon && showIconBesideTitle ? new FlatTitlePaneIcon( images, iconSize ) : null );
|
||||||
|
|
||||||
// show/hide icon
|
// show/hide icon
|
||||||
iconLabel.setVisible( hasIcon );
|
iconLabel.setVisible( hasIcon && !showIconBesideTitle );
|
||||||
leftPanel.setBorder( hasIcon ? null : FlatUIUtils.nonUIResource( new FlatEmptyBorder( 0, noIconLeftGap, 0, 0 ) ) );
|
leftPanel.setBorder( hasIcon && !showIconBesideTitle ? null : FlatUIUtils.nonUIResource( new FlatEmptyBorder( 0, noIconLeftGap, 0, 0 ) ) );
|
||||||
|
|
||||||
updateNativeTitleBarHeightAndHitTestSpotsLater();
|
updateNativeTitleBarHeightAndHitTestSpotsLater();
|
||||||
}
|
}
|
||||||
@@ -420,7 +469,7 @@ public class FlatTitlePane
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether this title pane currently has an visible and embedded menubar.
|
* Returns whether this title pane currently has a visible and embedded menubar.
|
||||||
*/
|
*/
|
||||||
protected boolean hasVisibleEmbeddedMenuBar( JMenuBar menuBar ) {
|
protected boolean hasVisibleEmbeddedMenuBar( JMenuBar menuBar ) {
|
||||||
return menuBar != null && menuBar.isVisible() && isMenuBarEmbedded();
|
return menuBar != null && menuBar.isVisible() && isMenuBarEmbedded();
|
||||||
@@ -567,6 +616,11 @@ debug*/
|
|||||||
frame.setExtendedState( frame.getExtendedState() | Frame.ICONIFIED );
|
frame.setExtendedState( frame.getExtendedState() | Frame.ICONIFIED );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 2.4 */
|
||||||
|
protected boolean isWindowMaximized() {
|
||||||
|
return window instanceof Frame && (((Frame)window).getExtendedState() & Frame.MAXIMIZED_BOTH) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Maximizes the window.
|
* Maximizes the window.
|
||||||
*/
|
*/
|
||||||
@@ -615,7 +669,7 @@ debug*/
|
|||||||
int maximizedWidth = screenBounds.width;
|
int maximizedWidth = screenBounds.width;
|
||||||
int maximizedHeight = screenBounds.height;
|
int maximizedHeight = screenBounds.height;
|
||||||
|
|
||||||
if( !isMaximizedBoundsFixed() ) {
|
if( SystemInfo.isWindows && !isMaximizedBoundsFixed() ) {
|
||||||
// on Java 8 to 14, maximized x,y are 0,0 based on all screens in a multi-screen environment
|
// on Java 8 to 14, maximized x,y are 0,0 based on all screens in a multi-screen environment
|
||||||
maximizedX = 0;
|
maximizedX = 0;
|
||||||
maximizedY = 0;
|
maximizedY = 0;
|
||||||
@@ -729,7 +783,7 @@ debug*/
|
|||||||
List<Rectangle> hitTestSpots = new ArrayList<>();
|
List<Rectangle> hitTestSpots = new ArrayList<>();
|
||||||
Rectangle appIconBounds = null;
|
Rectangle appIconBounds = null;
|
||||||
|
|
||||||
if( iconLabel.isVisible() ) {
|
if( !showIconBesideTitle && iconLabel.isVisible() ) {
|
||||||
// compute real icon size (without insets; 1px larger for easier hitting)
|
// compute real icon size (without insets; 1px larger for easier hitting)
|
||||||
Point location = SwingUtilities.convertPoint( iconLabel, 0, 0, window );
|
Point location = SwingUtilities.convertPoint( iconLabel, 0, 0, window );
|
||||||
Insets iconInsets = iconLabel.getInsets();
|
Insets iconInsets = iconLabel.getInsets();
|
||||||
@@ -741,9 +795,7 @@ debug*/
|
|||||||
|
|
||||||
// if frame is maximized, increase icon bounds to upper-left corner
|
// if frame is maximized, increase icon bounds to upper-left corner
|
||||||
// of window to allow closing window via double-click in upper-left corner
|
// of window to allow closing window via double-click in upper-left corner
|
||||||
if( window instanceof Frame &&
|
if( isWindowMaximized() ) {
|
||||||
(((Frame)window).getExtendedState() & Frame.MAXIMIZED_BOTH) != 0 )
|
|
||||||
{
|
|
||||||
iconBounds.height += iconBounds.y;
|
iconBounds.height += iconBounds.y;
|
||||||
iconBounds.y = 0;
|
iconBounds.y = 0;
|
||||||
|
|
||||||
@@ -758,6 +810,38 @@ debug*/
|
|||||||
hitTestSpots.add( iconBounds );
|
hitTestSpots.add( iconBounds );
|
||||||
else
|
else
|
||||||
appIconBounds = iconBounds;
|
appIconBounds = iconBounds;
|
||||||
|
} else if( showIconBesideTitle && titleLabel.getIcon() != null && titleLabel.getUI() instanceof FlatTitleLabelUI ) {
|
||||||
|
FlatTitleLabelUI ui = (FlatTitleLabelUI) titleLabel.getUI();
|
||||||
|
|
||||||
|
// compute real icon bounds
|
||||||
|
Insets insets = titleLabel.getInsets();
|
||||||
|
Rectangle viewR = new Rectangle( insets.left, insets.top,
|
||||||
|
titleLabel.getWidth() - insets.left - insets.right,
|
||||||
|
titleLabel.getHeight() - insets.top - insets.bottom );
|
||||||
|
Rectangle iconR = new Rectangle();
|
||||||
|
Rectangle textR = new Rectangle();
|
||||||
|
ui.layoutCL( titleLabel, titleLabel.getFontMetrics( titleLabel.getFont() ),
|
||||||
|
titleLabel.getText(), titleLabel.getIcon(),
|
||||||
|
viewR, iconR, textR );
|
||||||
|
|
||||||
|
// Windows shows the window system menu only in the upper-left corner
|
||||||
|
if( iconR.x == 0 ) {
|
||||||
|
// convert icon location to window coordinates
|
||||||
|
Point location = SwingUtilities.convertPoint( titleLabel, 0, 0, window );
|
||||||
|
iconR.x += location.x;
|
||||||
|
iconR.y += location.y;
|
||||||
|
|
||||||
|
// make icon bounds 1px larger for easier hitting
|
||||||
|
iconR.x -= 1;
|
||||||
|
iconR.y -= 1;
|
||||||
|
iconR.width += 2;
|
||||||
|
iconR.height += 2;
|
||||||
|
|
||||||
|
if( hasJBRCustomDecoration() )
|
||||||
|
hitTestSpots.add( iconR );
|
||||||
|
else
|
||||||
|
appIconBounds = iconR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle r = getNativeHitTestSpot( buttonPanel );
|
Rectangle r = getNativeHitTestSpot( buttonPanel );
|
||||||
@@ -768,11 +852,20 @@ debug*/
|
|||||||
if( hasVisibleEmbeddedMenuBar( menuBar ) ) {
|
if( hasVisibleEmbeddedMenuBar( menuBar ) ) {
|
||||||
r = getNativeHitTestSpot( menuBar );
|
r = getNativeHitTestSpot( menuBar );
|
||||||
if( r != null ) {
|
if( r != null ) {
|
||||||
|
// if frame is resizable and not maximized, make menu bar hit test spot smaller at top
|
||||||
|
// to have a small area above the menu bar to resize the window
|
||||||
|
if( window instanceof Frame && ((Frame)window).isResizable() && !isWindowMaximized() ) {
|
||||||
|
// limit to 8, because Windows does not use a larger height
|
||||||
|
int resizeHeight = UIScale.scale( Math.min( menuBarResizeHeight, 8 ) );
|
||||||
|
r.y += resizeHeight;
|
||||||
|
r.height -= resizeHeight;
|
||||||
|
}
|
||||||
|
|
||||||
Component horizontalGlue = findHorizontalGlue( menuBar );
|
Component horizontalGlue = findHorizontalGlue( menuBar );
|
||||||
if( horizontalGlue != null ) {
|
if( horizontalGlue != null ) {
|
||||||
// If menu bar is embedded and contains a horizontal glue component,
|
// If menu bar is embedded and contains a horizontal glue component,
|
||||||
// then split the hit test spot into two spots so that
|
// then split the hit test spot into two spots so that
|
||||||
// the glue component area can used to move the window.
|
// the glue component area can be used to move the window.
|
||||||
|
|
||||||
Point glueLocation = SwingUtilities.convertPoint( horizontalGlue, 0, 0, window );
|
Point glueLocation = SwingUtilities.convertPoint( horizontalGlue, 0, 0, window );
|
||||||
int x2 = glueLocation.x + horizontalGlue.getWidth();
|
int x2 = glueLocation.x + horizontalGlue.getWidth();
|
||||||
@@ -854,7 +947,7 @@ debug*/
|
|||||||
} else if( borderColor != null && (rootPane.getJMenuBar() == null || !rootPane.getJMenuBar().isVisible()) )
|
} else if( borderColor != null && (rootPane.getJMenuBar() == null || !rootPane.getJMenuBar().isVisible()) )
|
||||||
insets.bottom += UIScale.scale( 1 );
|
insets.bottom += UIScale.scale( 1 );
|
||||||
|
|
||||||
if( !SystemInfo.isWindows_11_orLater && hasNativeCustomDecoration() && !isWindowMaximized( c ) )
|
if( !SystemInfo.isWindows_11_orLater && hasNativeCustomDecoration() && !isWindowMaximized() )
|
||||||
insets = FlatUIUtils.addInsets( insets, WindowTopBorder.getInstance().getBorderInsets() );
|
insets = FlatUIUtils.addInsets( insets, WindowTopBorder.getInstance().getBorderInsets() );
|
||||||
|
|
||||||
return insets;
|
return insets;
|
||||||
@@ -873,7 +966,7 @@ debug*/
|
|||||||
FlatUIUtils.paintFilledRectangle( g, borderColor, x, y + height - lineHeight, width, lineHeight );
|
FlatUIUtils.paintFilledRectangle( g, borderColor, x, y + height - lineHeight, width, lineHeight );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !SystemInfo.isWindows_11_orLater && hasNativeCustomDecoration() && !isWindowMaximized( c ) )
|
if( !SystemInfo.isWindows_11_orLater && hasNativeCustomDecoration() && !isWindowMaximized() )
|
||||||
WindowTopBorder.getInstance().paintBorder( c, g, x, y, width, height );
|
WindowTopBorder.getInstance().paintBorder( c, g, x, y, width, height );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -881,12 +974,6 @@ debug*/
|
|||||||
JMenuBar menuBar = rootPane.getJMenuBar();
|
JMenuBar menuBar = rootPane.getJMenuBar();
|
||||||
return hasVisibleEmbeddedMenuBar( menuBar ) ? menuBar.getBorder() : null;
|
return hasVisibleEmbeddedMenuBar( menuBar ) ? menuBar.getBorder() : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean isWindowMaximized( Component c ) {
|
|
||||||
return window instanceof Frame
|
|
||||||
? (((Frame)window).getExtendedState() & Frame.MAXIMIZED_BOTH) != 0
|
|
||||||
: false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//---- class FlatTitleLabelUI ---------------------------------------------
|
//---- class FlatTitleLabelUI ---------------------------------------------
|
||||||
@@ -900,32 +987,101 @@ debug*/
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void paintEnabledText( JLabel l, Graphics g, String s, int textX, int textY ) {
|
protected String layoutCL( JLabel label, FontMetrics fontMetrics, String text, Icon icon,
|
||||||
boolean hasEmbeddedMenuBar = hasVisibleEmbeddedMenuBar( rootPane.getJMenuBar() );
|
Rectangle viewR, Rectangle iconR, Rectangle textR )
|
||||||
int labelWidth = l.getWidth();
|
{
|
||||||
int textWidth = labelWidth - (textX * 2);
|
JMenuBar menuBar = rootPane.getJMenuBar();
|
||||||
int gap = UIScale.scale( menuBarTitleGap );
|
boolean hasEmbeddedMenuBar = hasVisibleEmbeddedMenuBar( menuBar );
|
||||||
|
boolean hasEmbeddedLeadingMenus = hasEmbeddedMenuBar && hasLeadingMenus( menuBar );
|
||||||
|
boolean leftToRight = getComponentOrientation().isLeftToRight();
|
||||||
|
|
||||||
// The passed in textX coordinate is always to horizontally center the text within the label bounds.
|
if( hasEmbeddedMenuBar ) {
|
||||||
// Modify textX so that the text is painted either centered within the window bounds or leading aligned.
|
int minGap = UIScale.scale( menuBarTitleMinimumGap );
|
||||||
boolean center = hasEmbeddedMenuBar ? centerTitleIfMenuBarEmbedded : centerTitle;
|
|
||||||
if( center ) {
|
// apply minimum leading gap (between embedded menu bar and title)
|
||||||
// If window is wide enough, center title within window bounds.
|
if( hasEmbeddedLeadingMenus ) {
|
||||||
// Otherwise leave it centered within free space (label bounds).
|
if( leftToRight )
|
||||||
int centeredTextX = ((l.getParent().getWidth() - textWidth) / 2) - l.getX();
|
viewR.x += minGap;
|
||||||
if( centeredTextX >= gap && centeredTextX + textWidth <= labelWidth - gap )
|
viewR.width -= minGap;
|
||||||
textX = centeredTextX;
|
}
|
||||||
} else {
|
|
||||||
// leading aligned
|
// apply minimum trailing gap (between title and right aligned components of embedded menu bar)
|
||||||
boolean leftToRight = getComponentOrientation().isLeftToRight();
|
Component horizontalGlue = findHorizontalGlue( menuBar );
|
||||||
Insets insets = l.getInsets();
|
if( horizontalGlue != null && menuBar.getComponent( menuBar.getComponentCount() - 1 ) != horizontalGlue ) {
|
||||||
int leadingInset = hasEmbeddedMenuBar ? gap : (leftToRight ? insets.left : insets.right);
|
if( !leftToRight )
|
||||||
int leadingTextX = leftToRight ? leadingInset : labelWidth - leadingInset - textWidth;
|
viewR.x += minGap;
|
||||||
if( leftToRight ? leadingTextX < textX : leadingTextX > textX )
|
viewR.width -= minGap;
|
||||||
textX = leadingTextX;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
super.paintEnabledText( l, g, s, textX, textY );
|
// compute icon width and gap (if icon is show besides the title)
|
||||||
|
int iconTextGap = 0;
|
||||||
|
int iconWidthAndGap = 0;
|
||||||
|
if( icon != null ) {
|
||||||
|
Insets iconInsets = iconLabel.getInsets();
|
||||||
|
iconTextGap = leftToRight ? iconInsets.right : iconInsets.left;
|
||||||
|
iconWidthAndGap = icon.getIconWidth() + iconTextGap;
|
||||||
|
}
|
||||||
|
|
||||||
|
// layout title and icon (if show besides the title)
|
||||||
|
String clippedText = SwingUtilities.layoutCompoundLabel( label, fontMetrics, text, icon,
|
||||||
|
label.getVerticalAlignment(), label.getHorizontalAlignment(),
|
||||||
|
label.getVerticalTextPosition(), label.getHorizontalTextPosition(),
|
||||||
|
viewR, iconR, textR,
|
||||||
|
iconTextGap );
|
||||||
|
|
||||||
|
// compute text X location
|
||||||
|
if( !clippedText.equals( text ) ) {
|
||||||
|
// if text is clipped, align to left (or right)
|
||||||
|
textR.x = leftToRight
|
||||||
|
? viewR.x + iconWidthAndGap
|
||||||
|
: viewR.x + viewR.width - iconWidthAndGap - textR.width;
|
||||||
|
} else {
|
||||||
|
int leadingGap = hasEmbeddedLeadingMenus ? UIScale.scale( menuBarTitleGap - menuBarTitleMinimumGap ) : 0;
|
||||||
|
|
||||||
|
boolean center = hasEmbeddedLeadingMenus ? centerTitleIfMenuBarEmbedded : centerTitle;
|
||||||
|
if( center ) {
|
||||||
|
// If window is wide enough, center title within window bounds.
|
||||||
|
// Otherwise, center within free space (label bounds).
|
||||||
|
Container parent = label.getParent();
|
||||||
|
int centeredTextX = (parent != null) ? ((parent.getWidth() - textR.width - iconWidthAndGap) / 2) + iconWidthAndGap - label.getX() : -1;
|
||||||
|
textR.x = (centeredTextX >= viewR.x + leadingGap && centeredTextX + textR.width <= viewR.x + viewR.width - leadingGap)
|
||||||
|
? centeredTextX
|
||||||
|
: viewR.x + ((viewR.width - textR.width - iconWidthAndGap) / 2) + iconWidthAndGap;
|
||||||
|
} else {
|
||||||
|
// leading aligned with leading gap, which is reduced if space is rare
|
||||||
|
textR.x = leftToRight
|
||||||
|
? Math.min( viewR.x + leadingGap + iconWidthAndGap, viewR.x + viewR.width - textR.width )
|
||||||
|
: Math.max( viewR.x + viewR.width - leadingGap - iconWidthAndGap - textR.width, viewR.x );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// compute icon X location (relative to text X location)
|
||||||
|
if( icon != null ) {
|
||||||
|
iconR.x = leftToRight
|
||||||
|
? textR.x - iconWidthAndGap
|
||||||
|
: textR.x + textR.width + iconTextGap;
|
||||||
|
}
|
||||||
|
|
||||||
|
return clippedText;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean hasLeadingMenus( JMenuBar menuBar ) {
|
||||||
|
// check whether menu bar is empty
|
||||||
|
if( menuBar.getComponentCount() == 0 || menuBar.getWidth() == 0 )
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// check whether menu bar has a leading glue component
|
||||||
|
// (no menus/components at left side)
|
||||||
|
Component horizontalGlue = findHorizontalGlue( menuBar );
|
||||||
|
if( horizontalGlue != null ) {
|
||||||
|
boolean leftToRight = getComponentOrientation().isLeftToRight();
|
||||||
|
if( (leftToRight && horizontalGlue.getX() == 0) ||
|
||||||
|
(!leftToRight && horizontalGlue.getX() + horizontalGlue.getWidth() == menuBar.getWidth()) )
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1018,6 +1174,9 @@ debug*/
|
|||||||
if( window == null )
|
if( window == null )
|
||||||
return; // should newer occur
|
return; // should newer occur
|
||||||
|
|
||||||
|
if( !SwingUtilities.isLeftMouseButton( e ) )
|
||||||
|
return;
|
||||||
|
|
||||||
dragOffset = SwingUtilities.convertPoint( FlatTitlePane.this, e.getPoint(), window );
|
dragOffset = SwingUtilities.convertPoint( FlatTitlePane.this, e.getPoint(), window );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1032,6 +1191,9 @@ debug*/
|
|||||||
if( window == null )
|
if( window == null )
|
||||||
return; // should newer occur
|
return; // should newer occur
|
||||||
|
|
||||||
|
if( !SwingUtilities.isLeftMouseButton( e ) )
|
||||||
|
return;
|
||||||
|
|
||||||
if( hasNativeCustomDecoration() )
|
if( hasNativeCustomDecoration() )
|
||||||
return; // do nothing if having native window border
|
return; // do nothing if having native window border
|
||||||
|
|
||||||
|
|||||||
@@ -21,12 +21,8 @@ import java.awt.Color;
|
|||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.beans.PropertyChangeEvent;
|
import java.beans.PropertyChangeEvent;
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import javax.swing.AbstractButton;
|
import javax.swing.*;
|
||||||
import javax.swing.JComponent;
|
|
||||||
import javax.swing.JToggleButton;
|
|
||||||
import javax.swing.UIManager;
|
|
||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
||||||
import com.formdev.flatlaf.ui.FlatStylingSupport.UnknownStyleException;
|
import com.formdev.flatlaf.ui.FlatStylingSupport.UnknownStyleException;
|
||||||
@@ -52,15 +48,29 @@ import com.formdev.flatlaf.util.UIScale;
|
|||||||
* @uiDefault ToggleButton.iconTextGap int
|
* @uiDefault ToggleButton.iconTextGap int
|
||||||
* @uiDefault ToggleButton.startBackground Color optional; if set, a gradient paint is used and ToggleButton.background is ignored
|
* @uiDefault ToggleButton.startBackground Color optional; if set, a gradient paint is used and ToggleButton.background is ignored
|
||||||
* @uiDefault ToggleButton.endBackground Color optional; if set, a gradient paint is used
|
* @uiDefault ToggleButton.endBackground Color optional; if set, a gradient paint is used
|
||||||
* @uiDefault ToggleButton.pressedBackground Color
|
* @uiDefault ToggleButton.focusedBackground Color optional
|
||||||
|
* @uiDefault ToggleButton.focusedForeground Color optional
|
||||||
|
* @uiDefault ToggleButton.hoverBackground Color optional
|
||||||
|
* @uiDefault ToggleButton.hoverForeground Color optional
|
||||||
|
* @uiDefault ToggleButton.pressedBackground Color optional
|
||||||
|
* @uiDefault ToggleButton.pressedForeground Color optional
|
||||||
* @uiDefault ToggleButton.selectedBackground Color
|
* @uiDefault ToggleButton.selectedBackground Color
|
||||||
* @uiDefault ToggleButton.selectedForeground Color
|
* @uiDefault ToggleButton.selectedForeground Color
|
||||||
* @uiDefault ToggleButton.disabledBackground Color optional
|
* @uiDefault ToggleButton.disabledBackground Color optional
|
||||||
* @uiDefault ToggleButton.disabledText Color
|
* @uiDefault ToggleButton.disabledText Color
|
||||||
* @uiDefault ToggleButton.disabledSelectedBackground Color
|
* @uiDefault ToggleButton.disabledSelectedBackground Color
|
||||||
|
* @uiDefault ToggleButton.disabledSelectedForeground Color optional
|
||||||
|
* @uiDefault Button.paintShadow boolean default is false
|
||||||
|
* @uiDefault Button.shadowWidth int default is 2
|
||||||
|
* @uiDefault Button.shadowColor Color optional
|
||||||
* @uiDefault ToggleButton.toolbar.hoverBackground Color
|
* @uiDefault ToggleButton.toolbar.hoverBackground Color
|
||||||
|
* @uiDefault ToggleButton.toolbar.hoverForeground Color optional
|
||||||
* @uiDefault ToggleButton.toolbar.pressedBackground Color
|
* @uiDefault ToggleButton.toolbar.pressedBackground Color
|
||||||
|
* @uiDefault ToggleButton.toolbar.pressedForeground Color optional
|
||||||
* @uiDefault ToggleButton.toolbar.selectedBackground Color
|
* @uiDefault ToggleButton.toolbar.selectedBackground Color
|
||||||
|
* @uiDefault ToggleButton.toolbar.selectedForeground Color optional
|
||||||
|
* @uiDefault ToggleButton.toolbar.disabledSelectedBackground Color optional
|
||||||
|
* @uiDefault ToggleButton.toolbar.disabledSelectedForeground Color optional
|
||||||
*
|
*
|
||||||
* <!-- FlatToggleButtonUI -->
|
* <!-- FlatToggleButtonUI -->
|
||||||
*
|
*
|
||||||
@@ -68,8 +78,11 @@ import com.formdev.flatlaf.util.UIScale;
|
|||||||
* @uiDefault ToggleButton.tab.underlineColor Color
|
* @uiDefault ToggleButton.tab.underlineColor Color
|
||||||
* @uiDefault ToggleButton.tab.disabledUnderlineColor Color
|
* @uiDefault ToggleButton.tab.disabledUnderlineColor Color
|
||||||
* @uiDefault ToggleButton.tab.selectedBackground Color optional
|
* @uiDefault ToggleButton.tab.selectedBackground Color optional
|
||||||
|
* @uiDefault ToggleButton.tab.selectedForeground Color optional
|
||||||
* @uiDefault ToggleButton.tab.hoverBackground Color
|
* @uiDefault ToggleButton.tab.hoverBackground Color
|
||||||
|
* @uiDefault ToggleButton.tab.hoverForeground Color optional
|
||||||
* @uiDefault ToggleButton.tab.focusBackground Color
|
* @uiDefault ToggleButton.tab.focusBackground Color
|
||||||
|
* @uiDefault ToggleButton.tab.focusForeground Color optional
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
@@ -81,8 +94,11 @@ public class FlatToggleButtonUI
|
|||||||
@Styleable(dot=true) protected Color tabUnderlineColor;
|
@Styleable(dot=true) protected Color tabUnderlineColor;
|
||||||
@Styleable(dot=true) protected Color tabDisabledUnderlineColor;
|
@Styleable(dot=true) protected Color tabDisabledUnderlineColor;
|
||||||
@Styleable(dot=true) protected Color tabSelectedBackground;
|
@Styleable(dot=true) protected Color tabSelectedBackground;
|
||||||
|
/** @since 2.3 */ @Styleable(dot=true) protected Color tabSelectedForeground;
|
||||||
@Styleable(dot=true) protected Color tabHoverBackground;
|
@Styleable(dot=true) protected Color tabHoverBackground;
|
||||||
|
/** @since 2.3 */ @Styleable(dot=true) protected Color tabHoverForeground;
|
||||||
@Styleable(dot=true) protected Color tabFocusBackground;
|
@Styleable(dot=true) protected Color tabFocusBackground;
|
||||||
|
/** @since 2.3 */ @Styleable(dot=true) protected Color tabFocusForeground;
|
||||||
|
|
||||||
private boolean defaults_initialized = false;
|
private boolean defaults_initialized = false;
|
||||||
|
|
||||||
@@ -115,8 +131,11 @@ public class FlatToggleButtonUI
|
|||||||
tabUnderlineColor = UIManager.getColor( "ToggleButton.tab.underlineColor" );
|
tabUnderlineColor = UIManager.getColor( "ToggleButton.tab.underlineColor" );
|
||||||
tabDisabledUnderlineColor = UIManager.getColor( "ToggleButton.tab.disabledUnderlineColor" );
|
tabDisabledUnderlineColor = UIManager.getColor( "ToggleButton.tab.disabledUnderlineColor" );
|
||||||
tabSelectedBackground = UIManager.getColor( "ToggleButton.tab.selectedBackground" );
|
tabSelectedBackground = UIManager.getColor( "ToggleButton.tab.selectedBackground" );
|
||||||
|
tabSelectedForeground = UIManager.getColor( "ToggleButton.tab.selectedForeground" );
|
||||||
tabHoverBackground = UIManager.getColor( "ToggleButton.tab.hoverBackground" );
|
tabHoverBackground = UIManager.getColor( "ToggleButton.tab.hoverBackground" );
|
||||||
|
tabHoverForeground = UIManager.getColor( "ToggleButton.tab.hoverForeground" );
|
||||||
tabFocusBackground = UIManager.getColor( "ToggleButton.tab.focusBackground" );
|
tabFocusBackground = UIManager.getColor( "ToggleButton.tab.focusBackground" );
|
||||||
|
tabFocusForeground = UIManager.getColor( "ToggleButton.tab.focusForeground" );
|
||||||
|
|
||||||
defaults_initialized = true;
|
defaults_initialized = true;
|
||||||
}
|
}
|
||||||
@@ -143,6 +162,7 @@ public class FlatToggleButtonUI
|
|||||||
b.repaint();
|
b.repaint();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TAB_BUTTON_UNDERLINE_PLACEMENT:
|
||||||
case TAB_BUTTON_UNDERLINE_HEIGHT:
|
case TAB_BUTTON_UNDERLINE_HEIGHT:
|
||||||
case TAB_BUTTON_UNDERLINE_COLOR:
|
case TAB_BUTTON_UNDERLINE_COLOR:
|
||||||
case TAB_BUTTON_SELECTED_BACKGROUND:
|
case TAB_BUTTON_SELECTED_BACKGROUND:
|
||||||
@@ -164,11 +184,7 @@ public class FlatToggleButtonUI
|
|||||||
@Override
|
@Override
|
||||||
public Map<String, Class<?>> getStyleableInfos( JComponent c ) {
|
public Map<String, Class<?>> getStyleableInfos( JComponent c ) {
|
||||||
Map<String, Class<?>> infos = super.getStyleableInfos( c );
|
Map<String, Class<?>> infos = super.getStyleableInfos( c );
|
||||||
Iterator<String> it = infos.keySet().iterator();
|
infos.keySet().removeIf( s -> s.startsWith( "help." ) );
|
||||||
while( it.hasNext() ) {
|
|
||||||
if( it.next().startsWith( "help." ) )
|
|
||||||
it.remove();
|
|
||||||
}
|
|
||||||
return infos;
|
return infos;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -201,13 +217,42 @@ public class FlatToggleButtonUI
|
|||||||
|
|
||||||
// paint underline if selected
|
// paint underline if selected
|
||||||
if( selected ) {
|
if( selected ) {
|
||||||
int underlineHeight = UIScale.scale( clientPropertyInt( c, TAB_BUTTON_UNDERLINE_HEIGHT, tabUnderlineHeight ) );
|
int underlineThickness = UIScale.scale( clientPropertyInt( c, TAB_BUTTON_UNDERLINE_HEIGHT, tabUnderlineHeight ) );
|
||||||
g.setColor( c.isEnabled()
|
g.setColor( c.isEnabled()
|
||||||
? clientPropertyColor( c, TAB_BUTTON_UNDERLINE_COLOR, tabUnderlineColor )
|
? clientPropertyColor( c, TAB_BUTTON_UNDERLINE_COLOR, tabUnderlineColor )
|
||||||
: tabDisabledUnderlineColor );
|
: tabDisabledUnderlineColor );
|
||||||
g.fillRect( 0, height - underlineHeight, width, underlineHeight );
|
int placement = clientPropertyInt( c, TAB_BUTTON_UNDERLINE_PLACEMENT, SwingConstants.BOTTOM );
|
||||||
|
switch (placement) {
|
||||||
|
case SwingConstants.TOP:
|
||||||
|
g.fillRect( 0, 0, width, underlineThickness );
|
||||||
|
break;
|
||||||
|
case SwingConstants.LEFT:
|
||||||
|
g.fillRect( 0, 0, underlineThickness, height );
|
||||||
|
break;
|
||||||
|
case SwingConstants.RIGHT:
|
||||||
|
g.fillRect( width - underlineThickness, 0, underlineThickness, height );
|
||||||
|
break;
|
||||||
|
case SwingConstants.BOTTOM:
|
||||||
|
default:
|
||||||
|
g.fillRect( 0, height - underlineThickness, width, underlineThickness );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
super.paintBackground( g, c );
|
super.paintBackground( g, c );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Color getForeground( JComponent c ) {
|
||||||
|
if( isTabButton( c ) ) {
|
||||||
|
if( !c.isEnabled() )
|
||||||
|
return disabledText;
|
||||||
|
|
||||||
|
if( tabSelectedForeground != null && ((AbstractButton)c).isSelected() )
|
||||||
|
return tabSelectedForeground;
|
||||||
|
|
||||||
|
return buttonStateColor( c, c.getForeground(), disabledText,
|
||||||
|
tabFocusForeground, tabHoverForeground, null );
|
||||||
|
} else
|
||||||
|
return super.getForeground( c );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -256,11 +256,15 @@ public class FlatToolBarUI
|
|||||||
default: return;
|
default: return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for( int i = focusedCompIndex + add; i != focusedCompIndex; i += add ) {
|
int i = focusedCompIndex;
|
||||||
|
for(;;) {
|
||||||
|
i += add;
|
||||||
if( i < 0 )
|
if( i < 0 )
|
||||||
i = count - 1;
|
i = count - 1;
|
||||||
else if( i >= count )
|
else if( i >= count )
|
||||||
i = 0;
|
i = 0;
|
||||||
|
if( i == focusedCompIndex )
|
||||||
|
break;
|
||||||
|
|
||||||
Component c = toolBar.getComponentAtIndex( i );
|
Component c = toolBar.getComponentAtIndex( i );
|
||||||
if( canBeFocusOwner( c ) ) {
|
if( canBeFocusOwner( c ) ) {
|
||||||
@@ -282,7 +286,7 @@ public class FlatToolBarUI
|
|||||||
return comboBox.getUI().isFocusTraversable( comboBox );
|
return comboBox.getUI().isFocusTraversable( comboBox );
|
||||||
}
|
}
|
||||||
|
|
||||||
// check whether component has a empty input map to skip components that
|
// check whether component has an empty input map to skip components that
|
||||||
// are focusable, but do nothing when focused (e.g. JLabel)
|
// are focusable, but do nothing when focused (e.g. JLabel)
|
||||||
// see LayoutFocusTraversalPolicy.accept()
|
// see LayoutFocusTraversalPolicy.accept()
|
||||||
if( c instanceof JComponent ) {
|
if( c instanceof JComponent ) {
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ public class FlatUIUtils
|
|||||||
public static final boolean MAC_USE_QUARTZ = Boolean.getBoolean( "apple.awt.graphics.UseQuartz" );
|
public static final boolean MAC_USE_QUARTZ = Boolean.getBoolean( "apple.awt.graphics.UseQuartz" );
|
||||||
|
|
||||||
private static boolean useSharedUIs = true;
|
private static boolean useSharedUIs = true;
|
||||||
private static WeakHashMap<LookAndFeel, IdentityHashMap<Object, ComponentUI>> sharedUIinstances = new WeakHashMap<>();
|
private static final WeakHashMap<LookAndFeel, IdentityHashMap<Object, ComponentUI>> sharedUIinstances = new WeakHashMap<>();
|
||||||
|
|
||||||
public static Rectangle addInsets( Rectangle r, Insets insets ) {
|
public static Rectangle addInsets( Rectangle r, Insets insets ) {
|
||||||
return new Rectangle(
|
return new Rectangle(
|
||||||
@@ -245,7 +245,7 @@ public class FlatUIUtils
|
|||||||
isInActiveWindow( c, keyboardFocusManager.getActiveWindow() );
|
isInActiveWindow( c, keyboardFocusManager.getActiveWindow() );
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isInActiveWindow( Component c, Window activeWindow ) {
|
static boolean isInActiveWindow( Component c, Window activeWindow ) {
|
||||||
Window window = SwingUtilities.windowForComponent( c );
|
Window window = SwingUtilities.windowForComponent( c );
|
||||||
return window == activeWindow ||
|
return window == activeWindow ||
|
||||||
(window != null && window.getType() == Window.Type.POPUP && window.getOwner() == activeWindow);
|
(window != null && window.getType() == Window.Type.POPUP && window.getOwner() == activeWindow);
|
||||||
@@ -777,8 +777,8 @@ public class FlatUIUtils
|
|||||||
* {@link SwingConstants#WEST} or {@link SwingConstants#EAST})
|
* {@link SwingConstants#WEST} or {@link SwingConstants#EAST})
|
||||||
* @param chevron {@code true} for chevron arrow, {@code false} for triangle arrow
|
* @param chevron {@code true} for chevron arrow, {@code false} for triangle arrow
|
||||||
* @param arrowSize the width of the painted arrow (for vertical direction) (will be scaled)
|
* @param arrowSize the width of the painted arrow (for vertical direction) (will be scaled)
|
||||||
* @param xOffset a offset added to the x coordinate of the arrow to paint it out-of-center. Usually zero. (will be scaled)
|
* @param xOffset an offset added to the x coordinate of the arrow to paint it out-of-center. Usually zero. (will be scaled)
|
||||||
* @param yOffset a offset added to the y coordinate of the arrow to paint it out-of-center. Usually zero. (will be scaled)
|
* @param yOffset an offset added to the y coordinate of the arrow to paint it out-of-center. Usually zero. (will be scaled)
|
||||||
*
|
*
|
||||||
* @since 1.1
|
* @since 1.1
|
||||||
*/
|
*/
|
||||||
@@ -786,13 +786,15 @@ public class FlatUIUtils
|
|||||||
int direction, boolean chevron, int arrowSize, float xOffset, float yOffset )
|
int direction, boolean chevron, int arrowSize, float xOffset, float yOffset )
|
||||||
{
|
{
|
||||||
// compute arrow width/height
|
// compute arrow width/height
|
||||||
int aw = UIScale.scale( arrowSize + (chevron ? 0 : 1) );
|
// - make chevron arrows one pixel smaller because coordinates are based on center of pixels (0.5/0.5)
|
||||||
int ah = UIScale.scale( (arrowSize / 2) + (chevron ? 0 : 1) );
|
// - make triangle arrows one pixel taller (and round height up) to make them look stronger
|
||||||
|
float aw = UIScale.scale( arrowSize + (chevron ? -1 : 0) );
|
||||||
|
float ah = chevron ? (aw / 2) : UIScale.scale( (arrowSize / 2) + 1 );
|
||||||
|
|
||||||
// rotate arrow width/height for horizontal directions
|
// rotate arrow width/height for horizontal directions
|
||||||
boolean vert = (direction == SwingConstants.NORTH || direction == SwingConstants.SOUTH);
|
boolean vert = (direction == SwingConstants.NORTH || direction == SwingConstants.SOUTH);
|
||||||
if( !vert ) {
|
if( !vert ) {
|
||||||
int temp = aw;
|
float temp = aw;
|
||||||
aw = ah;
|
aw = ah;
|
||||||
ah = temp;
|
ah = temp;
|
||||||
}
|
}
|
||||||
@@ -804,19 +806,19 @@ public class FlatUIUtils
|
|||||||
// compute arrow location
|
// compute arrow location
|
||||||
float ox = ((width - (aw + extra)) / 2f) + UIScale.scale( xOffset );
|
float ox = ((width - (aw + extra)) / 2f) + UIScale.scale( xOffset );
|
||||||
float oy = ((height - (ah + extra)) / 2f) + UIScale.scale( yOffset );
|
float oy = ((height - (ah + extra)) / 2f) + UIScale.scale( yOffset );
|
||||||
int ax = x + ((direction == SwingConstants.WEST) ? -Math.round( -ox ) : Math.round( ox ));
|
float ax = x + ((direction == SwingConstants.WEST) ? -Math.round( -(ox + aw) ) - aw : Math.round( ox ));
|
||||||
int ay = y + ((direction == SwingConstants.NORTH) ? -Math.round( -oy ) : Math.round( oy ));
|
float ay = y + ((direction == SwingConstants.NORTH) ? -Math.round( -(oy + ah) ) - ah : Math.round( oy ));
|
||||||
|
|
||||||
// paint arrow
|
// paint arrow
|
||||||
g.translate( ax, ay );
|
g.translate( ax, ay );
|
||||||
/*debug
|
/*debug
|
||||||
debugPaintArrow( g, Color.red, vert, aw + extra, ah + extra );
|
debugPaintArrow( g, Color.red, vert, Math.round( aw + extra ), Math.round( ah + extra ) );
|
||||||
debug*/
|
debug*/
|
||||||
Shape arrowShape = createArrowShape( direction, chevron, aw, ah );
|
Shape arrowShape = createArrowShape( direction, chevron, aw, ah );
|
||||||
if( chevron ) {
|
if( chevron ) {
|
||||||
Stroke oldStroke = g.getStroke();
|
Stroke oldStroke = g.getStroke();
|
||||||
g.setStroke( new BasicStroke( UIScale.scale( 1f ) ) );
|
g.setStroke( new BasicStroke( UIScale.scale( 1f ) ) );
|
||||||
g.draw( arrowShape );
|
drawShapePure( g, arrowShape );
|
||||||
g.setStroke( oldStroke );
|
g.setStroke( oldStroke );
|
||||||
} else {
|
} else {
|
||||||
// triangle
|
// triangle
|
||||||
@@ -828,7 +830,7 @@ debug*/
|
|||||||
/**
|
/**
|
||||||
* Creates a chevron or triangle arrow shape for the given direction and size.
|
* Creates a chevron or triangle arrow shape for the given direction and size.
|
||||||
* <p>
|
* <p>
|
||||||
* The chevron shape is a open path that can be painted with {@link Graphics2D#draw(Shape)}.
|
* The chevron shape is an open path that can be painted with {@link Graphics2D#draw(Shape)}.
|
||||||
* The triangle shape is a close path that can be painted with {@link Graphics2D#fill(Shape)}.
|
* The triangle shape is a close path that can be painted with {@link Graphics2D#fill(Shape)}.
|
||||||
*
|
*
|
||||||
* @param direction the arrow direction ({@link SwingConstants#NORTH}, {@link SwingConstants#SOUTH}
|
* @param direction the arrow direction ({@link SwingConstants#NORTH}, {@link SwingConstants#SOUTH}
|
||||||
@@ -880,7 +882,7 @@ debug*/
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a open or closed path for the given points.
|
* Creates an open or closed path for the given points.
|
||||||
*/
|
*/
|
||||||
public static Path2D createPath( boolean close, double... points ) {
|
public static Path2D createPath( boolean close, double... points ) {
|
||||||
Path2D path = new Path2D.Float();
|
Path2D path = new Path2D.Float();
|
||||||
@@ -892,6 +894,23 @@ debug*/
|
|||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draws the given shape with disabled stroke normalization.
|
||||||
|
* The x/y coordinates of the shape are translated by a half pixel.
|
||||||
|
*
|
||||||
|
* @since 2.1
|
||||||
|
*/
|
||||||
|
public static void drawShapePure( Graphics2D g, Shape shape ) {
|
||||||
|
Object oldStrokeControl = g.getRenderingHint( RenderingHints.KEY_STROKE_CONTROL );
|
||||||
|
g.setRenderingHint( RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE );
|
||||||
|
|
||||||
|
g.translate( 0.5, 0.5 );
|
||||||
|
g.draw( shape );
|
||||||
|
g.translate( -0.5, -0.5 );
|
||||||
|
|
||||||
|
g.setRenderingHint( RenderingHints.KEY_STROKE_CONTROL, oldStrokeControl );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draws the given string at the specified location.
|
* Draws the given string at the specified location.
|
||||||
* The provided component is used to query text properties and anti-aliasing hints.
|
* The provided component is used to query text properties and anti-aliasing hints.
|
||||||
|
|||||||
@@ -18,8 +18,8 @@ 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.JTable;
|
|
||||||
import javax.swing.JViewport;
|
import javax.swing.JViewport;
|
||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
import javax.swing.plaf.basic.BasicViewportUI;
|
import javax.swing.plaf.basic.BasicViewportUI;
|
||||||
@@ -43,15 +43,28 @@ public class FlatViewportUI
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update( Graphics g, JComponent c ) {
|
public void paint( Graphics g, JComponent c ) {
|
||||||
Component view = ((JViewport)c).getView();
|
super.paint( g, c );
|
||||||
if( c.isOpaque() && view instanceof JTable ) {
|
|
||||||
// paint viewport background in same color as table background
|
|
||||||
g.setColor( view.getBackground() );
|
|
||||||
g.fillRect( 0, 0, c.getWidth(), c.getHeight() );
|
|
||||||
|
|
||||||
paint( g, c );
|
Component view = ((JViewport)c).getView();
|
||||||
} else
|
if( view instanceof JComponent ) {
|
||||||
super.update( g, c );
|
try {
|
||||||
|
Method m = view.getClass().getMethod( "getUI" );
|
||||||
|
Object ui = m.invoke( view );
|
||||||
|
if( ui instanceof ViewportPainter )
|
||||||
|
((ViewportPainter)ui).paintViewport( g, (JComponent) view, (JViewport) c );
|
||||||
|
} catch( Exception ex ) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//---- interface ViewportPainter ------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @since 2.3
|
||||||
|
*/
|
||||||
|
public interface ViewportPainter {
|
||||||
|
void paintViewport( Graphics g, JComponent c, JViewport viewport );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import java.awt.Dialog;
|
|||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.Frame;
|
import java.awt.Frame;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
|
import java.awt.GraphicsConfiguration;
|
||||||
import java.awt.Insets;
|
import java.awt.Insets;
|
||||||
import java.awt.Rectangle;
|
import java.awt.Rectangle;
|
||||||
import java.awt.Toolkit;
|
import java.awt.Toolkit;
|
||||||
@@ -42,7 +43,9 @@ import javax.swing.JComponent;
|
|||||||
import javax.swing.JInternalFrame;
|
import javax.swing.JInternalFrame;
|
||||||
import javax.swing.JLayeredPane;
|
import javax.swing.JLayeredPane;
|
||||||
import javax.swing.JRootPane;
|
import javax.swing.JRootPane;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
|
import com.formdev.flatlaf.util.SystemInfo;
|
||||||
import com.formdev.flatlaf.util.UIScale;
|
import com.formdev.flatlaf.util.UIScale;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -231,8 +234,15 @@ public abstract class FlatWindowResizer
|
|||||||
{
|
{
|
||||||
protected Window window;
|
protected Window window;
|
||||||
|
|
||||||
|
private final boolean limitResizeToScreenBounds;
|
||||||
|
|
||||||
public WindowResizer( JRootPane rootPane ) {
|
public WindowResizer( JRootPane rootPane ) {
|
||||||
super( rootPane );
|
super( rootPane );
|
||||||
|
|
||||||
|
// On Linux, limit window resizing to screen bounds because otherwise
|
||||||
|
// there would be a strange effect when the mouse is moved over a sidebar
|
||||||
|
// while resizing and the opposite window side is also resized.
|
||||||
|
limitResizeToScreenBounds = SystemInfo.isLinux;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -289,11 +299,19 @@ public abstract class FlatWindowResizer
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean limitToParentBounds() {
|
protected boolean limitToParentBounds() {
|
||||||
return false;
|
return limitResizeToScreenBounds && window != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Rectangle getParentBounds() {
|
protected Rectangle getParentBounds() {
|
||||||
|
if( limitResizeToScreenBounds && window != null ) {
|
||||||
|
GraphicsConfiguration gc = window.getGraphicsConfiguration();
|
||||||
|
Rectangle bounds = gc.getBounds();
|
||||||
|
Insets insets = window.getToolkit().getScreenInsets( gc );
|
||||||
|
return new Rectangle( bounds.x + insets.left, bounds.y + insets.top,
|
||||||
|
bounds.width - insets.left - insets.right,
|
||||||
|
bounds.height - insets.top - insets.bottom );
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -385,7 +403,7 @@ public abstract class FlatWindowResizer
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Rectangle getParentBounds() {
|
protected Rectangle getParentBounds() {
|
||||||
return getFrame().getParent().getBounds();
|
return new Rectangle( getFrame().getParent().getSize() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -504,7 +522,7 @@ debug*/
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mousePressed( MouseEvent e ) {
|
public void mousePressed( MouseEvent e ) {
|
||||||
if( !isWindowResizable() )
|
if( !SwingUtilities.isLeftMouseButton( e ) || !isWindowResizable() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int xOnScreen = e.getXOnScreen();
|
int xOnScreen = e.getXOnScreen();
|
||||||
@@ -533,7 +551,7 @@ debug*/
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mouseReleased( MouseEvent e ) {
|
public void mouseReleased( MouseEvent e ) {
|
||||||
if( !isWindowResizable() )
|
if( !SwingUtilities.isLeftMouseButton( e ) || !isWindowResizable() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
dragLeftOffset = dragRightOffset = dragTopOffset = dragBottomOffset = 0;
|
dragLeftOffset = dragRightOffset = dragTopOffset = dragBottomOffset = 0;
|
||||||
@@ -559,7 +577,7 @@ debug*/
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mouseDragged( MouseEvent e ) {
|
public void mouseDragged( MouseEvent e ) {
|
||||||
if( !isWindowResizable() )
|
if( !SwingUtilities.isLeftMouseButton( e ) || !isWindowResizable() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int xOnScreen = e.getXOnScreen();
|
int xOnScreen = e.getXOnScreen();
|
||||||
@@ -579,8 +597,8 @@ debug*/
|
|||||||
// top
|
// top
|
||||||
if( resizeDir == N_RESIZE_CURSOR || resizeDir == NW_RESIZE_CURSOR || resizeDir == NE_RESIZE_CURSOR ) {
|
if( resizeDir == N_RESIZE_CURSOR || resizeDir == NW_RESIZE_CURSOR || resizeDir == NE_RESIZE_CURSOR ) {
|
||||||
newBounds.y = yOnScreen - dragTopOffset;
|
newBounds.y = yOnScreen - dragTopOffset;
|
||||||
if( limitToParentBounds() && newBounds.y < 0 )
|
if( limitToParentBounds() )
|
||||||
newBounds.y = 0;
|
newBounds.y = Math.max( newBounds.y, getParentBounds().y );
|
||||||
newBounds.height += (oldBounds.y - newBounds.y);
|
newBounds.height += (oldBounds.y - newBounds.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -597,8 +615,8 @@ debug*/
|
|||||||
// left
|
// left
|
||||||
if( resizeDir == W_RESIZE_CURSOR || resizeDir == NW_RESIZE_CURSOR || resizeDir == SW_RESIZE_CURSOR ) {
|
if( resizeDir == W_RESIZE_CURSOR || resizeDir == NW_RESIZE_CURSOR || resizeDir == SW_RESIZE_CURSOR ) {
|
||||||
newBounds.x = xOnScreen - dragLeftOffset;
|
newBounds.x = xOnScreen - dragLeftOffset;
|
||||||
if( limitToParentBounds() && newBounds.x < 0 )
|
if( limitToParentBounds() )
|
||||||
newBounds.x = 0;
|
newBounds.x = Math.max( newBounds.x, getParentBounds().x );
|
||||||
newBounds.width += (oldBounds.x - newBounds.x);
|
newBounds.width += (oldBounds.x - newBounds.x);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ import java.awt.Window;
|
|||||||
import java.awt.geom.AffineTransform;
|
import java.awt.geom.AffineTransform;
|
||||||
import java.beans.PropertyChangeEvent;
|
import java.beans.PropertyChangeEvent;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
import java.io.File;
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.IdentityHashMap;
|
import java.util.IdentityHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -38,9 +37,7 @@ import javax.swing.Timer;
|
|||||||
import javax.swing.event.ChangeEvent;
|
import javax.swing.event.ChangeEvent;
|
||||||
import javax.swing.event.ChangeListener;
|
import javax.swing.event.ChangeListener;
|
||||||
import javax.swing.event.EventListenerList;
|
import javax.swing.event.EventListenerList;
|
||||||
import com.formdev.flatlaf.FlatSystemProperties;
|
|
||||||
import com.formdev.flatlaf.util.LoggingFacade;
|
import com.formdev.flatlaf.util.LoggingFacade;
|
||||||
import com.formdev.flatlaf.util.NativeLibrary;
|
|
||||||
import com.formdev.flatlaf.util.SystemInfo;
|
import com.formdev.flatlaf.util.SystemInfo;
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -84,7 +81,6 @@ class FlatWindowsNativeWindowBorder
|
|||||||
private Color colorizationColor;
|
private Color colorizationColor;
|
||||||
private int colorizationColorBalance;
|
private int colorizationColorBalance;
|
||||||
|
|
||||||
private static NativeLibrary nativeLibrary;
|
|
||||||
private static FlatWindowsNativeWindowBorder instance;
|
private static FlatWindowsNativeWindowBorder instance;
|
||||||
|
|
||||||
static FlatNativeWindowBorder.Provider getInstance() {
|
static FlatNativeWindowBorder.Provider getInstance() {
|
||||||
@@ -96,31 +92,8 @@ class FlatWindowsNativeWindowBorder
|
|||||||
if( !SystemInfo.isX86 && !SystemInfo.isX86_64 )
|
if( !SystemInfo.isX86 && !SystemInfo.isX86_64 )
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
// load native library
|
|
||||||
if( nativeLibrary == null ) {
|
|
||||||
if( !SystemInfo.isJava_9_orLater ) {
|
|
||||||
// In Java 8, load jawt.dll (part of JRE) explicitly because it
|
|
||||||
// is not found when running application with <jdk>/bin/java.exe.
|
|
||||||
// When using <jdk>/jre/bin/java.exe, it is found.
|
|
||||||
// jawt.dll is located in <jdk>/jre/bin/.
|
|
||||||
// Java 9 and later does not have this problem.
|
|
||||||
try {
|
|
||||||
System.loadLibrary( "jawt" );
|
|
||||||
} catch( UnsatisfiedLinkError ex ) {
|
|
||||||
// log error only if native library jawt.dll not already loaded
|
|
||||||
String message = ex.getMessage();
|
|
||||||
if( message == null || !message.contains( "already loaded in another classloader" ) )
|
|
||||||
LoggingFacade.INSTANCE.logSevere( null, ex );
|
|
||||||
} catch( Exception ex ) {
|
|
||||||
LoggingFacade.INSTANCE.logSevere( null, ex );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nativeLibrary = createNativeLibrary();
|
|
||||||
}
|
|
||||||
|
|
||||||
// check whether native library was successfully loaded
|
// check whether native library was successfully loaded
|
||||||
if( !nativeLibrary.isLoaded() )
|
if( !FlatNativeLibrary.isLoaded() )
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
// create new instance
|
// create new instance
|
||||||
@@ -129,23 +102,6 @@ class FlatWindowsNativeWindowBorder
|
|||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static NativeLibrary createNativeLibrary() {
|
|
||||||
String libraryName = "flatlaf-windows-x86";
|
|
||||||
if( SystemInfo.isX86_64 )
|
|
||||||
libraryName += "_64";
|
|
||||||
|
|
||||||
String libraryPath = System.getProperty( FlatSystemProperties.NATIVE_LIBRARY_PATH );
|
|
||||||
if( libraryPath != null ) {
|
|
||||||
File libraryFile = new File( libraryPath, libraryName + ".dll" );
|
|
||||||
if( libraryFile.exists() )
|
|
||||||
return new NativeLibrary( libraryFile, true );
|
|
||||||
else
|
|
||||||
LoggingFacade.INSTANCE.logSevere( "Did not find external library " + libraryFile + ", using extracted library instead", null );
|
|
||||||
}
|
|
||||||
|
|
||||||
return new NativeLibrary( "com/formdev/flatlaf/natives/" + libraryName, null, true );
|
|
||||||
}
|
|
||||||
|
|
||||||
private FlatWindowsNativeWindowBorder() {
|
private FlatWindowsNativeWindowBorder() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,7 +111,7 @@ class FlatWindowsNativeWindowBorder
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tell the window whether the application wants use custom decorations.
|
* Tell the window whether the application wants to use custom decorations.
|
||||||
* If {@code true}, the Windows 10 title bar is hidden (including minimize,
|
* If {@code true}, the Windows 10 title bar is hidden (including minimize,
|
||||||
* maximize and close buttons), but not the resize borders (including drop shadow).
|
* maximize and close buttons), but not the resize borders (including drop shadow).
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -195,11 +195,13 @@ public class JBRCustomDecorations
|
|||||||
{
|
{
|
||||||
private static JBRWindowTopBorder instance;
|
private static JBRWindowTopBorder instance;
|
||||||
|
|
||||||
private final Color defaultActiveBorder = new Color( 0x707070 );
|
private final Color activeLightColor = new Color( 0x707070 );
|
||||||
|
private final Color activeDarkColor = new Color( 0x2D2E2F );
|
||||||
private final Color inactiveLightColor = new Color( 0xaaaaaa );
|
private final Color inactiveLightColor = new Color( 0xaaaaaa );
|
||||||
|
private final Color inactiveDarkColor = new Color( 0x494A4B );
|
||||||
|
|
||||||
private boolean colorizationAffectsBorders;
|
private boolean colorizationAffectsBorders;
|
||||||
private Color activeColor = defaultActiveBorder;
|
private Color activeColor;
|
||||||
|
|
||||||
static JBRWindowTopBorder getInstance() {
|
static JBRWindowTopBorder getInstance() {
|
||||||
if( instance == null )
|
if( instance == null )
|
||||||
@@ -250,7 +252,7 @@ public class JBRCustomDecorations
|
|||||||
|
|
||||||
private Color calculateActiveBorderColor() {
|
private Color calculateActiveBorderColor() {
|
||||||
if( !colorizationAffectsBorders )
|
if( !colorizationAffectsBorders )
|
||||||
return defaultActiveBorder;
|
return null;
|
||||||
|
|
||||||
Color colorizationColor = getColorizationColor();
|
Color colorizationColor = getColorizationColor();
|
||||||
if( colorizationColor != null ) {
|
if( colorizationColor != null ) {
|
||||||
@@ -284,16 +286,12 @@ public class JBRCustomDecorations
|
|||||||
@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 ) {
|
||||||
Window window = SwingUtilities.windowForComponent( c );
|
Window window = SwingUtilities.windowForComponent( c );
|
||||||
boolean active = (window != null) ? window.isActive() : false;
|
boolean active = window != null && window.isActive();
|
||||||
|
boolean dark = FlatLaf.isLafDark();
|
||||||
|
|
||||||
// paint top border
|
g.setColor( active
|
||||||
// - in light themes
|
? (activeColor != null ? activeColor : (dark ? activeDarkColor : activeLightColor))
|
||||||
// - in dark themes only for active windows if colorization affects borders
|
: (dark ? inactiveDarkColor : inactiveLightColor) );
|
||||||
boolean paintTopBorder = !FlatLaf.isLafDark() || (active && colorizationAffectsBorders);
|
|
||||||
if( !paintTopBorder )
|
|
||||||
return;
|
|
||||||
|
|
||||||
g.setColor( active ? activeColor : inactiveLightColor );
|
|
||||||
HiDPIUtils.paintAtScale1x( (Graphics2D) g, x, y, width, height, this::paintImpl );
|
HiDPIUtils.paintAtScale1x( (Graphics2D) g, x, y, width, height, this::paintImpl );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -143,8 +143,8 @@ public class MigLayoutVisualPadding
|
|||||||
//---- class FlatMigInsets ------------------------------------------------
|
//---- class FlatMigInsets ------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Marker class to identify our visual paddings and leaf paddings,
|
* Marker class to identify our visual paddings and leave paddings
|
||||||
* which were set from outside, untouched.
|
* set from outside untouched.
|
||||||
*/
|
*/
|
||||||
private static class FlatMigInsets
|
private static class FlatMigInsets
|
||||||
extends Insets
|
extends Insets
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ import com.formdev.flatlaf.util.Animator.Interpolator;
|
|||||||
* </pre>
|
* </pre>
|
||||||
*
|
*
|
||||||
* Animation works only if the component passed to {@link #paintIcon(Component, Graphics, int, int)}
|
* Animation works only if the component passed to {@link #paintIcon(Component, Graphics, int, int)}
|
||||||
* is a instance of {@link JComponent}.
|
* is an instance of {@link JComponent}.
|
||||||
* A client property is set on the component to store the animation state.
|
* A client property is set on the component to store the animation state.
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
@@ -68,7 +68,7 @@ public interface AnimatedIcon
|
|||||||
extends Icon
|
extends Icon
|
||||||
{
|
{
|
||||||
@Override
|
@Override
|
||||||
public default void paintIcon( Component c, Graphics g, int x, int y ) {
|
default void paintIcon( Component c, Graphics g, int x, int y ) {
|
||||||
AnimationSupport.paintIcon( this, c, g, x, y );
|
AnimationSupport.paintIcon( this, c, g, x, y );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ public class DerivedColor
|
|||||||
Color result = ColorFunctions.applyFunctions( baseColor, functions );
|
Color result = ColorFunctions.applyFunctions( baseColor, functions );
|
||||||
|
|
||||||
// if the result is equal to the default color, then the original base color
|
// if the result is equal to the default color, then the original base color
|
||||||
// was passed and we can cache this to avoid color calculations
|
// was passed, and we can cache this to avoid color calculations
|
||||||
if( !hasBaseOfDefaultColor && result.getRGB() == this.getRGB() ) {
|
if( !hasBaseOfDefaultColor && result.getRGB() == this.getRGB() ) {
|
||||||
hasBaseOfDefaultColor = true;
|
hasBaseOfDefaultColor = true;
|
||||||
baseOfDefaultColorRGB = baseColor.getRGB();
|
baseOfDefaultColorRGB = baseColor.getRGB();
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ public class HSLColor
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a HSLColor object using an an array containing the
|
* Create a HSLColor object using an array containing the
|
||||||
* individual HSL values and with a default alpha value of 1.
|
* individual HSL values and with a default alpha value of 1.
|
||||||
*
|
*
|
||||||
* @param hsl array containing HSL values
|
* @param hsl array containing HSL values
|
||||||
@@ -87,7 +87,7 @@ public class HSLColor
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a HSLColor object using an an array containing the
|
* Create a HSLColor object using an array containing the
|
||||||
* individual HSL values.
|
* individual HSL values.
|
||||||
*
|
*
|
||||||
* @param hsl array containing HSL values
|
* @param hsl array containing HSL values
|
||||||
@@ -291,7 +291,7 @@ public class HSLColor
|
|||||||
|
|
||||||
// Calculate the Saturation
|
// Calculate the Saturation
|
||||||
|
|
||||||
float s = 0;
|
float s;
|
||||||
|
|
||||||
if (max == min)
|
if (max == min)
|
||||||
s = 0;
|
s = 0;
|
||||||
@@ -386,7 +386,7 @@ public class HSLColor
|
|||||||
s /= 100f;
|
s /= 100f;
|
||||||
l /= 100f;
|
l /= 100f;
|
||||||
|
|
||||||
float q = 0;
|
float q;
|
||||||
|
|
||||||
if (l < 0.5)
|
if (l < 0.5)
|
||||||
q = l * (1 + s);
|
q = l * (1 + s);
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ import com.formdev.flatlaf.FlatSystemProperties;
|
|||||||
public class HiDPIUtils
|
public class HiDPIUtils
|
||||||
{
|
{
|
||||||
public interface Painter {
|
public interface Painter {
|
||||||
public void paint( Graphics2D g, int x, int y, int width, int height, double scaleFactor );
|
void paint( Graphics2D g, int x, int y, int width, int height, double scaleFactor );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void paintAtScale1x( Graphics2D g, JComponent c, Painter painter ) {
|
public static void paintAtScale1x( Graphics2D g, JComponent c, Painter painter ) {
|
||||||
@@ -48,30 +48,55 @@ public class HiDPIUtils
|
|||||||
*/
|
*/
|
||||||
public static void paintAtScale1x( Graphics2D g, int x, int y, int width, int height, Painter painter ) {
|
public static void paintAtScale1x( Graphics2D g, int x, int y, int width, int height, Painter painter ) {
|
||||||
// save original transform
|
// save original transform
|
||||||
AffineTransform transform = g.getTransform();
|
AffineTransform t = g.getTransform();
|
||||||
|
|
||||||
|
// get scale X/Y and shear X/Y
|
||||||
|
double scaleX = t.getScaleX();
|
||||||
|
double scaleY = t.getScaleY();
|
||||||
|
double shearX = t.getShearX();
|
||||||
|
double shearY = t.getShearY();
|
||||||
|
|
||||||
|
// check whether rotated
|
||||||
|
// (also check for negative scale X/Y because shear X/Y are zero for 180 degrees rotation)
|
||||||
|
boolean rotated = (shearX != 0 || shearY != 0 || scaleX <= 0 || scaleY <= 0);
|
||||||
|
if( rotated ) {
|
||||||
|
// resulting scale X/Y values are always positive
|
||||||
|
scaleX = Math.hypot( scaleX, shearX );
|
||||||
|
scaleY = Math.hypot( scaleY, shearY );
|
||||||
|
} else {
|
||||||
|
// make scale X/Y positive
|
||||||
|
scaleX = Math.abs( scaleX );
|
||||||
|
scaleY = Math.abs( scaleY );
|
||||||
|
}
|
||||||
|
|
||||||
// check whether scaled
|
// check whether scaled
|
||||||
if( transform.getScaleX() == 1 && transform.getScaleY() == 1 ) {
|
if( scaleX == 1 && scaleY == 1 ) {
|
||||||
painter.paint( g, x, y, width, height, 1 );
|
painter.paint( g, x, y, width, height, 1 );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// scale rectangle
|
// scale rectangle
|
||||||
Rectangle2D.Double scaledRect = scale( transform, x, y, width, height );
|
Rectangle2D.Double scaledRect = scale( scaleX, scaleY, t, x, y, width, height );
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// unscale to factor 1.0 and move origin (to whole numbers)
|
// unscale to factor 1.0, keep rotation and move origin (to whole numbers)
|
||||||
g.setTransform( new AffineTransform( 1, 0, 0, 1,
|
AffineTransform t1x;
|
||||||
Math.floor( scaledRect.x ), Math.floor( scaledRect.y ) ) );
|
if( rotated ) {
|
||||||
|
t1x = new AffineTransform( t.getScaleX(), t.getShearY(), t.getShearX(), t.getScaleY(),
|
||||||
|
Math.floor( scaledRect.x ), Math.floor( scaledRect.y ) );
|
||||||
|
t1x.scale( 1. / scaleX, 1. / scaleY );
|
||||||
|
} else
|
||||||
|
t1x = new AffineTransform( 1, 0, 0, 1, Math.floor( scaledRect.x ), Math.floor( scaledRect.y ) );
|
||||||
|
g.setTransform( t1x );
|
||||||
|
|
||||||
int swidth = (int) scaledRect.width;
|
int swidth = (int) scaledRect.width;
|
||||||
int sheight = (int) scaledRect.height;
|
int sheight = (int) scaledRect.height;
|
||||||
|
|
||||||
// paint
|
// paint
|
||||||
painter.paint( g, 0, 0, swidth, sheight, transform.getScaleX() );
|
painter.paint( g, 0, 0, swidth, sheight, scaleX );
|
||||||
} finally {
|
} finally {
|
||||||
// restore original transform
|
// restore original transform
|
||||||
g.setTransform( transform );
|
g.setTransform( t );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,20 +105,16 @@ public class HiDPIUtils
|
|||||||
* sun.java2d.pipe.PixelToParallelogramConverter.fillRectangle(),
|
* sun.java2d.pipe.PixelToParallelogramConverter.fillRectangle(),
|
||||||
* which is used by Graphics.fillRect().
|
* which is used by Graphics.fillRect().
|
||||||
*/
|
*/
|
||||||
private static Rectangle2D.Double scale( AffineTransform transform, int x, int y, int width, int height ) {
|
private static Rectangle2D.Double scale( double scaleX, double scaleY, AffineTransform t, int x, int y, int width, int height ) {
|
||||||
double dx1 = transform.getScaleX();
|
double px = (x * scaleX) + t.getTranslateX();
|
||||||
double dy2 = transform.getScaleY();
|
double py = (y * scaleY) + t.getTranslateY();
|
||||||
double px = x * dx1 + transform.getTranslateX();
|
|
||||||
double py = y * dy2 + transform.getTranslateY();
|
|
||||||
dx1 *= width;
|
|
||||||
dy2 *= height;
|
|
||||||
|
|
||||||
double newx = normalize( px );
|
double newX = normalize( px );
|
||||||
double newy = normalize( py );
|
double newY = normalize( py );
|
||||||
dx1 = normalize( px + dx1 ) - newx;
|
double newWidth = normalize( px + (width * scaleX) ) - newX;
|
||||||
dy2 = normalize( py + dy2 ) - newy;
|
double newHeight = normalize( py + (height * scaleY) ) - newY;
|
||||||
|
|
||||||
return new Rectangle2D.Double( newx, newy, dx1, dy2 );
|
return new Rectangle2D.Double( newX, newY, newWidth, newHeight );
|
||||||
}
|
}
|
||||||
|
|
||||||
private static double normalize( double value ) {
|
private static double normalize( double value ) {
|
||||||
@@ -114,7 +135,7 @@ public class HiDPIUtils
|
|||||||
* painted too far down on some operating systems.
|
* painted too far down on some operating systems.
|
||||||
* The higher the system scale factor is, the more.
|
* The higher the system scale factor is, the more.
|
||||||
* <p>
|
* <p>
|
||||||
* This methods computes a correction value for the Y position.
|
* This method computes a correction value for the Y position.
|
||||||
*/
|
*/
|
||||||
public static float computeTextYCorrection( Graphics2D g ) {
|
public static float computeTextYCorrection( Graphics2D g ) {
|
||||||
if( !useTextYCorrection() || !SystemInfo.isWindows )
|
if( !useTextYCorrection() || !SystemInfo.isWindows )
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ public class JavaCompatibility
|
|||||||
getClippedStringMethod = cls.getMethod( SystemInfo.isJava_9_orLater
|
getClippedStringMethod = cls.getMethod( SystemInfo.isJava_9_orLater
|
||||||
? "getClippedString"
|
? "getClippedString"
|
||||||
: "clipStringIfNecessary",
|
: "clipStringIfNecessary",
|
||||||
new Class[] { JComponent.class, FontMetrics.class, String.class, int.class } );
|
JComponent.class, FontMetrics.class, String.class, int.class );
|
||||||
} catch( Exception ex ) {
|
} catch( Exception ex ) {
|
||||||
LoggingFacade.INSTANCE.logSevere( null, ex );
|
LoggingFacade.INSTANCE.logSevere( null, ex );
|
||||||
throw new RuntimeException( ex );
|
throw new RuntimeException( ex );
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ public class MultiResolutionImageSupport
|
|||||||
* <p>
|
* <p>
|
||||||
* The given dimensions array is only used for {@link #getResolutionVariants(Image)}.
|
* The given dimensions array is only used for {@link #getResolutionVariants(Image)}.
|
||||||
* The producer function may be invoked with any dimension (that is not contained in
|
* The producer function may be invoked with any dimension (that is not contained in
|
||||||
* dimensions array) and is expected to produce a image for the passed in dimension.
|
* dimensions array) and is expected to produce an image for the passed in dimension.
|
||||||
*
|
*
|
||||||
* @param baseImageIndex index of the base image in the dimensions array
|
* @param baseImageIndex index of the base image in the dimensions array
|
||||||
* @param dimensions dimensions of resolution variants (sorted by size; smallest first)
|
* @param dimensions dimensions of resolution variants (sorted by size; smallest first)
|
||||||
@@ -92,7 +92,7 @@ public class MultiResolutionImageSupport
|
|||||||
* for "disabled" state.
|
* for "disabled" state.
|
||||||
*
|
*
|
||||||
* @param image a multi-resolution image that is mapped using the given mapper function
|
* @param image a multi-resolution image that is mapped using the given mapper function
|
||||||
* @param mapper mapper function that maps a single resolution variant to a new image (e.g. applying an filter)
|
* @param mapper mapper function that maps a single resolution variant to a new image (e.g. applying a filter)
|
||||||
* @return a multi-resolution image on Java 9 or later; a mapped image on Java 8
|
* @return a multi-resolution image on Java 9 or later; a mapped image on Java 8
|
||||||
*/
|
*/
|
||||||
public static Image map( Image image, Function<Image, Image> mapper ) {
|
public static Image map( Image image, Function<Image, Image> mapper ) {
|
||||||
@@ -104,7 +104,7 @@ public class MultiResolutionImageSupport
|
|||||||
* <p>
|
* <p>
|
||||||
* If the given image is a multi-resolution image then invokes
|
* If the given image is a multi-resolution image then invokes
|
||||||
* {@code java.awt.image.MultiResolutionImage.getResolutionVariant(destImageWidth, destImageHeight)}.
|
* {@code java.awt.image.MultiResolutionImage.getResolutionVariant(destImageWidth, destImageHeight)}.
|
||||||
* Otherwise returns the given image.
|
* Otherwise, returns the given image.
|
||||||
*/
|
*/
|
||||||
public static Image getResolutionVariant( Image image, int destImageWidth, int destImageHeight ) {
|
public static Image getResolutionVariant( Image image, int destImageWidth, int destImageHeight ) {
|
||||||
return image;
|
return image;
|
||||||
@@ -115,7 +115,7 @@ public class MultiResolutionImageSupport
|
|||||||
* <p>
|
* <p>
|
||||||
* If the given image is a multi-resolution image then invokes
|
* If the given image is a multi-resolution image then invokes
|
||||||
* {@code java.awt.image.MultiResolutionImage.getResolutionVariants()}.
|
* {@code java.awt.image.MultiResolutionImage.getResolutionVariants()}.
|
||||||
* Otherwise returns a list containing only the given image.
|
* Otherwise, returns a list containing only the given image.
|
||||||
*/
|
*/
|
||||||
public static List<Image> getResolutionVariants( Image image ) {
|
public static List<Image> getResolutionVariants( Image image ) {
|
||||||
return Collections.singletonList( image );
|
return Collections.singletonList( image );
|
||||||
|
|||||||
@@ -143,16 +143,19 @@ public class NativeLibrary
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add prefix and suffix to library name.
|
||||||
|
* <ul>
|
||||||
|
* <li>Windows: libraryName + ".dll"
|
||||||
|
* <li>macOS: "lib" + libraryName + ".dylib"
|
||||||
|
* <li>Linux: "lib" + libraryName + ".so"
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
private static String decorateLibraryName( String libraryName ) {
|
private static String decorateLibraryName( String libraryName ) {
|
||||||
if( SystemInfo.isWindows )
|
|
||||||
return libraryName.concat( ".dll" );
|
|
||||||
|
|
||||||
String suffix = SystemInfo.isMacOS ? ".dylib" : ".so";
|
|
||||||
|
|
||||||
int sep = libraryName.lastIndexOf( '/' );
|
int sep = libraryName.lastIndexOf( '/' );
|
||||||
return (sep >= 0)
|
return (sep >= 0)
|
||||||
? libraryName.substring( 0, sep + 1 ) + "lib" + libraryName.substring( sep + 1 ) + suffix
|
? libraryName.substring( 0, sep + 1 ) + System.mapLibraryName( libraryName.substring( sep + 1 ) )
|
||||||
: "lib" + libraryName + suffix;
|
: System.mapLibraryName( libraryName );
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void log( String msg, Throwable thrown ) {
|
private static void log( String msg, Throwable thrown ) {
|
||||||
@@ -195,7 +198,7 @@ public class NativeLibrary
|
|||||||
// for loaded native libraries, they will be deleted on next application startup.
|
// for loaded native libraries, they will be deleted on next application startup.
|
||||||
// The default temporary directory may contain hundreds or thousands of files.
|
// The default temporary directory may contain hundreds or thousands of files.
|
||||||
// To make searching for "marked for deletion" files as fast as possible,
|
// To make searching for "marked for deletion" files as fast as possible,
|
||||||
// use a sub directory that contains only our temporary native libraries.
|
// use a subdirectory that contains only our temporary native libraries.
|
||||||
tmpdir += "\\flatlaf.temp";
|
tmpdir += "\\flatlaf.temp";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ public class SystemInfo
|
|||||||
public static final long javaVersion;
|
public static final long javaVersion;
|
||||||
public static final boolean isJava_9_orLater;
|
public static final boolean isJava_9_orLater;
|
||||||
public static final boolean isJava_11_orLater;
|
public static final boolean isJava_11_orLater;
|
||||||
|
/** @since 2.3 */ public static final boolean isJava_12_orLater;
|
||||||
public static final boolean isJava_15_orLater;
|
public static final boolean isJava_15_orLater;
|
||||||
/** @since 2 */ public static final boolean isJava_17_orLater;
|
/** @since 2 */ public static final boolean isJava_17_orLater;
|
||||||
/** @since 2 */ public static final boolean isJava_18_orLater;
|
/** @since 2 */ public static final boolean isJava_18_orLater;
|
||||||
@@ -66,6 +67,9 @@ public class SystemInfo
|
|||||||
/** @since 1.1.2 */ public static final boolean isWebswing;
|
/** @since 1.1.2 */ public static final boolean isWebswing;
|
||||||
/** @since 1.1.1 */ public static final boolean isWinPE;
|
/** @since 1.1.1 */ public static final boolean isWinPE;
|
||||||
|
|
||||||
|
// features
|
||||||
|
/** @since 2.3 */ public static final boolean isMacFullWindowContentSupported;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
// platforms
|
// platforms
|
||||||
String osName = System.getProperty( "os.name" ).toLowerCase( Locale.ENGLISH );
|
String osName = System.getProperty( "os.name" ).toLowerCase( Locale.ENGLISH );
|
||||||
@@ -92,6 +96,7 @@ public class SystemInfo
|
|||||||
javaVersion = scanVersion( System.getProperty( "java.version" ) );
|
javaVersion = scanVersion( System.getProperty( "java.version" ) );
|
||||||
isJava_9_orLater = (javaVersion >= toVersion( 9, 0, 0, 0 ));
|
isJava_9_orLater = (javaVersion >= toVersion( 9, 0, 0, 0 ));
|
||||||
isJava_11_orLater = (javaVersion >= toVersion( 11, 0, 0, 0 ));
|
isJava_11_orLater = (javaVersion >= toVersion( 11, 0, 0, 0 ));
|
||||||
|
isJava_12_orLater = (javaVersion >= toVersion( 12, 0, 0, 0 ));
|
||||||
isJava_15_orLater = (javaVersion >= toVersion( 15, 0, 0, 0 ));
|
isJava_15_orLater = (javaVersion >= toVersion( 15, 0, 0, 0 ));
|
||||||
isJava_17_orLater = (javaVersion >= toVersion( 17, 0, 0, 0 ));
|
isJava_17_orLater = (javaVersion >= toVersion( 17, 0, 0, 0 ));
|
||||||
isJava_18_orLater = (javaVersion >= toVersion( 18, 0, 0, 0 ));
|
isJava_18_orLater = (javaVersion >= toVersion( 18, 0, 0, 0 ));
|
||||||
@@ -108,6 +113,12 @@ public class SystemInfo
|
|||||||
isProjector = Boolean.getBoolean( "org.jetbrains.projector.server.enable" );
|
isProjector = Boolean.getBoolean( "org.jetbrains.projector.server.enable" );
|
||||||
isWebswing = (System.getProperty( "webswing.rootDir" ) != null);
|
isWebswing = (System.getProperty( "webswing.rootDir" ) != null);
|
||||||
isWinPE = isWindows && "X:\\Windows\\System32".equalsIgnoreCase( System.getProperty( "user.dir" ) );
|
isWinPE = isWindows && "X:\\Windows\\System32".equalsIgnoreCase( System.getProperty( "user.dir" ) );
|
||||||
|
|
||||||
|
// features
|
||||||
|
// available since Java 12; backported to Java 11.0.8 and 8u292
|
||||||
|
isMacFullWindowContentSupported =
|
||||||
|
javaVersion >= toVersion( 11, 0, 8, 0 ) ||
|
||||||
|
(javaVersion >= toVersion( 1, 8, 0, 292 ) && !isJava_9_orLater);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static long scanVersion( String version ) {
|
public static long scanVersion( String version ) {
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ public class UIScale
|
|||||||
// Java 9 and later supports per-monitor scaling
|
// Java 9 and later supports per-monitor scaling
|
||||||
jreHiDPI = true;
|
jreHiDPI = true;
|
||||||
} else if( SystemInfo.isJetBrainsJVM ) {
|
} else if( SystemInfo.isJetBrainsJVM ) {
|
||||||
// IntelliJ IDEA ships its own JetBrains Java 8 JRE that may supports per-monitor scaling
|
// IntelliJ IDEA ships its own JetBrains Java 8 JRE that may support per-monitor scaling
|
||||||
// see com.intellij.ui.JreHiDpiUtil.isJreHiDPIEnabled()
|
// see com.intellij.ui.JreHiDpiUtil.isJreHiDPIEnabled()
|
||||||
try {
|
try {
|
||||||
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
|
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
|
||||||
@@ -411,7 +411,7 @@ public class UIScale
|
|||||||
* Scales the given dimension with the user scale factor.
|
* Scales the given dimension with the user scale factor.
|
||||||
* <p>
|
* <p>
|
||||||
* If user scale factor is 1, then the given dimension is simply returned.
|
* If user scale factor is 1, then the given dimension is simply returned.
|
||||||
* Otherwise a new instance of {@link Dimension} or {@link DimensionUIResource}
|
* Otherwise, a new instance of {@link Dimension} or {@link DimensionUIResource}
|
||||||
* is returned, depending on whether the passed dimension implements {@link UIResource}.
|
* is returned, depending on whether the passed dimension implements {@link UIResource}.
|
||||||
*/
|
*/
|
||||||
public static Dimension scale( Dimension dimension ) {
|
public static Dimension scale( Dimension dimension ) {
|
||||||
@@ -427,7 +427,7 @@ public class UIScale
|
|||||||
* Scales the given insets with the user scale factor.
|
* Scales the given insets with the user scale factor.
|
||||||
* <p>
|
* <p>
|
||||||
* If user scale factor is 1, then the given insets is simply returned.
|
* If user scale factor is 1, then the given insets is simply returned.
|
||||||
* Otherwise a new instance of {@link Insets} or {@link InsetsUIResource}
|
* Otherwise, a new instance of {@link Insets} or {@link InsetsUIResource}
|
||||||
* is returned, depending on whether the passed dimension implements {@link UIResource}.
|
* is returned, depending on whether the passed dimension implements {@link UIResource}.
|
||||||
*/
|
*/
|
||||||
public static Insets scale( Insets insets ) {
|
public static Insets scale( Insets insets ) {
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
#
|
#
|
||||||
# NOTE: Avoid copying the whole content of this file to own properties files.
|
# NOTE: Avoid copying the whole content of this file to own properties files.
|
||||||
# This will make upgrading to newer FlatLaf versions complex and error-prone.
|
# This will make upgrading to newer FlatLaf versions complex and error-prone.
|
||||||
# Instead copy and modify only those properties that you need to alter.
|
# Instead, copy and modify only those properties that you need to alter.
|
||||||
#
|
#
|
||||||
|
|
||||||
# Colors and style mostly based on Darcula theme from IntelliJ IDEA Community Edition,
|
# Colors and style mostly based on Darcula theme from IntelliJ IDEA Community Edition,
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
#
|
#
|
||||||
# NOTE: Avoid copying the whole content of this file to own properties files.
|
# NOTE: Avoid copying the whole content of this file to own properties files.
|
||||||
# This will make upgrading to newer FlatLaf versions complex and error-prone.
|
# This will make upgrading to newer FlatLaf versions complex and error-prone.
|
||||||
# Instead copy and modify only those properties that you need to alter.
|
# Instead, copy and modify only those properties that you need to alter.
|
||||||
#
|
#
|
||||||
|
|
||||||
# Colors and style mostly based on Darcula theme from IntelliJ IDEA Community Edition,
|
# Colors and style mostly based on Darcula theme from IntelliJ IDEA Community Edition,
|
||||||
@@ -240,6 +240,7 @@ MenuBar.borderColor = $Separator.foreground
|
|||||||
#---- PasswordField ----
|
#---- PasswordField ----
|
||||||
|
|
||||||
PasswordField.capsLockIconColor = #ffffff64
|
PasswordField.capsLockIconColor = #ffffff64
|
||||||
|
PasswordField.revealIconColor = @foreground
|
||||||
|
|
||||||
|
|
||||||
#---- Popup ----
|
#---- Popup ----
|
||||||
@@ -251,6 +252,7 @@ Popup.dropShadowOpacity = 0.25
|
|||||||
#---- PopupMenu ----
|
#---- PopupMenu ----
|
||||||
|
|
||||||
PopupMenu.borderColor = tint(@background,17%)
|
PopupMenu.borderColor = tint(@background,17%)
|
||||||
|
PopupMenu.hoverScrollArrowBackground = lighten(@background,5%)
|
||||||
|
|
||||||
|
|
||||||
#---- ProgressBar ----
|
#---- ProgressBar ----
|
||||||
@@ -304,6 +306,7 @@ SplitPaneDivider.draggingColor = $Component.borderColor
|
|||||||
#---- TabbedPane ----
|
#---- TabbedPane ----
|
||||||
|
|
||||||
TabbedPane.underlineColor = @accentUnderlineColor
|
TabbedPane.underlineColor = @accentUnderlineColor
|
||||||
|
TabbedPane.inactiveUnderlineColor = mix(@accentUnderlineColor,$TabbedPane.background,60%)
|
||||||
TabbedPane.disabledUnderlineColor = lighten(@background,23%)
|
TabbedPane.disabledUnderlineColor = lighten(@background,23%)
|
||||||
TabbedPane.hoverColor = darken($TabbedPane.background,5%,derived noAutoInverse)
|
TabbedPane.hoverColor = darken($TabbedPane.background,5%,derived noAutoInverse)
|
||||||
TabbedPane.focusColor = mix(@selectionBackground,$TabbedPane.background,25%)
|
TabbedPane.focusColor = mix(@selectionBackground,$TabbedPane.background,25%)
|
||||||
@@ -322,7 +325,7 @@ TabbedPane.closePressedForeground = $TabbedPane.closeHoverForeground
|
|||||||
|
|
||||||
#---- Table ----
|
#---- Table ----
|
||||||
|
|
||||||
Table.gridColor = lighten($Table.background,5%)
|
Table.gridColor = lighten($Table.background,8%)
|
||||||
|
|
||||||
|
|
||||||
#---- TableHeader ----
|
#---- TableHeader ----
|
||||||
@@ -367,6 +370,6 @@ Tree.hash = lighten($Tree.background,5%)
|
|||||||
focusable: false; \
|
focusable: false; \
|
||||||
toolbar.margin: 1,1,1,1; \
|
toolbar.margin: 1,1,1,1; \
|
||||||
toolbar.spacingInsets: 1,1,1,1; \
|
toolbar.spacingInsets: 1,1,1,1; \
|
||||||
toolbar.hoverBackground: fade(Actions.GreyInline,30%,lazy); \
|
toolbar.hoverBackground: lighten($TextField.background,5%); \
|
||||||
toolbar.pressedBackground: fade(Actions.GreyInline,40%,lazy); \
|
toolbar.pressedBackground: lighten($TextField.background,10%); \
|
||||||
toolbar.selectedBackground: fade(Actions.GreyInline,50%,lazy)
|
toolbar.selectedBackground: lighten($TextField.background,15%)
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
#
|
#
|
||||||
# NOTE: Avoid copying the whole content of this file to own properties files.
|
# NOTE: Avoid copying the whole content of this file to own properties files.
|
||||||
# This will make upgrading to newer FlatLaf versions complex and error-prone.
|
# This will make upgrading to newer FlatLaf versions complex and error-prone.
|
||||||
# Instead copy and modify only those properties that you need to alter.
|
# Instead, copy and modify only those properties that you need to alter.
|
||||||
#
|
#
|
||||||
|
|
||||||
# Colors and style mostly based on IntelliJ theme from IntelliJ IDEA Community Edition,
|
# Colors and style mostly based on IntelliJ theme from IntelliJ IDEA Community Edition,
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
#
|
#
|
||||||
# NOTE: Avoid copying the whole content of this file to own properties files.
|
# NOTE: Avoid copying the whole content of this file to own properties files.
|
||||||
# This will make upgrading to newer FlatLaf versions complex and error-prone.
|
# This will make upgrading to newer FlatLaf versions complex and error-prone.
|
||||||
# Instead copy and modify only those properties that you need to alter.
|
# Instead, copy and modify only those properties that you need to alter.
|
||||||
#
|
#
|
||||||
|
|
||||||
#---- typography / fonts ----
|
#---- typography / fonts ----
|
||||||
@@ -64,7 +64,7 @@ light.font = +0
|
|||||||
semibold.font = +0
|
semibold.font = +0
|
||||||
|
|
||||||
# monospaced
|
# monospaced
|
||||||
[win]monospaced.font = Consolas, "Courier New", Monospaced
|
[win]monospaced.font = Monospaced
|
||||||
[mac]monospaced.font = Menlo, Monospaced
|
[mac]monospaced.font = Menlo, Monospaced
|
||||||
[linux]monospaced.font = "Liberation Mono", "Ubuntu Mono", Monospaced
|
[linux]monospaced.font = "Liberation Mono", "Ubuntu Mono", Monospaced
|
||||||
monospaced.font = Monospaced
|
monospaced.font = Monospaced
|
||||||
@@ -332,6 +332,7 @@ FileView.fileIcon = com.formdev.flatlaf.icons.FlatFileViewFileIcon
|
|||||||
FileView.computerIcon = com.formdev.flatlaf.icons.FlatFileViewComputerIcon
|
FileView.computerIcon = com.formdev.flatlaf.icons.FlatFileViewComputerIcon
|
||||||
FileView.hardDriveIcon = com.formdev.flatlaf.icons.FlatFileViewHardDriveIcon
|
FileView.hardDriveIcon = com.formdev.flatlaf.icons.FlatFileViewHardDriveIcon
|
||||||
FileView.floppyDriveIcon = com.formdev.flatlaf.icons.FlatFileViewFloppyDriveIcon
|
FileView.floppyDriveIcon = com.formdev.flatlaf.icons.FlatFileViewFloppyDriveIcon
|
||||||
|
FileView.fullRowSelection = true
|
||||||
|
|
||||||
|
|
||||||
#---- FormattedTextField ----
|
#---- FormattedTextField ----
|
||||||
@@ -487,7 +488,6 @@ PasswordField.showCapsLock = true
|
|||||||
PasswordField.showRevealButton = false
|
PasswordField.showRevealButton = false
|
||||||
PasswordField.capsLockIcon = com.formdev.flatlaf.icons.FlatCapsLockIcon
|
PasswordField.capsLockIcon = com.formdev.flatlaf.icons.FlatCapsLockIcon
|
||||||
PasswordField.revealIcon = com.formdev.flatlaf.icons.FlatRevealIcon
|
PasswordField.revealIcon = com.formdev.flatlaf.icons.FlatRevealIcon
|
||||||
PasswordField.revealIconColor = lazy(Actions.Grey)
|
|
||||||
|
|
||||||
|
|
||||||
#---- Popup ----
|
#---- Popup ----
|
||||||
@@ -501,6 +501,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.background = @menuBackground
|
PopupMenu.background = @menuBackground
|
||||||
|
PopupMenu.scrollArrowColor = @buttonArrowColor
|
||||||
|
|
||||||
|
|
||||||
#---- PopupMenuSeparator ----
|
#---- PopupMenuSeparator ----
|
||||||
@@ -555,6 +556,7 @@ RootPane.honorDialogMinimumSizeOnResize = true
|
|||||||
#---- ScrollBar ----
|
#---- ScrollBar ----
|
||||||
|
|
||||||
ScrollBar.width = 10
|
ScrollBar.width = 10
|
||||||
|
ScrollBar.minimumButtonSize = 12,12
|
||||||
ScrollBar.minimumThumbSize = 10,10
|
ScrollBar.minimumThumbSize = 10,10
|
||||||
ScrollBar.maximumThumbSize = 100000,100000
|
ScrollBar.maximumThumbSize = 100000,100000
|
||||||
ScrollBar.trackInsets = 0,0,0,0
|
ScrollBar.trackInsets = 0,0,0,0
|
||||||
@@ -787,11 +789,16 @@ TitlePane.noIconLeftGap = 8
|
|||||||
TitlePane.iconSize = 16,16
|
TitlePane.iconSize = 16,16
|
||||||
TitlePane.iconMargins = 3,8,3,8
|
TitlePane.iconMargins = 3,8,3,8
|
||||||
TitlePane.titleMargins = 3,0,3,0
|
TitlePane.titleMargins = 3,0,3,0
|
||||||
|
TitlePane.titleMinimumWidth = 60
|
||||||
TitlePane.buttonSize = 44,30
|
TitlePane.buttonSize = 44,30
|
||||||
|
TitlePane.buttonMinimumWidth = 30
|
||||||
TitlePane.buttonMaximizedHeight = 22
|
TitlePane.buttonMaximizedHeight = 22
|
||||||
TitlePane.centerTitle = false
|
TitlePane.centerTitle = false
|
||||||
TitlePane.centerTitleIfMenuBarEmbedded = true
|
TitlePane.centerTitleIfMenuBarEmbedded = true
|
||||||
TitlePane.menuBarTitleGap = 20
|
TitlePane.showIconBesideTitle = false
|
||||||
|
TitlePane.menuBarTitleGap = 40
|
||||||
|
TitlePane.menuBarTitleMinimumGap = 12
|
||||||
|
TitlePane.menuBarResizeHeight = 4
|
||||||
TitlePane.closeIcon = com.formdev.flatlaf.icons.FlatWindowCloseIcon
|
TitlePane.closeIcon = com.formdev.flatlaf.icons.FlatWindowCloseIcon
|
||||||
TitlePane.iconifyIcon = com.formdev.flatlaf.icons.FlatWindowIconifyIcon
|
TitlePane.iconifyIcon = com.formdev.flatlaf.icons.FlatWindowIconifyIcon
|
||||||
TitlePane.maximizeIcon = com.formdev.flatlaf.icons.FlatWindowMaximizeIcon
|
TitlePane.maximizeIcon = com.formdev.flatlaf.icons.FlatWindowMaximizeIcon
|
||||||
@@ -827,6 +834,7 @@ ToggleButton.tab.underlineHeight = 2
|
|||||||
ToggleButton.tab.underlineColor = $TabbedPane.underlineColor
|
ToggleButton.tab.underlineColor = $TabbedPane.underlineColor
|
||||||
ToggleButton.tab.disabledUnderlineColor = $TabbedPane.disabledUnderlineColor
|
ToggleButton.tab.disabledUnderlineColor = $TabbedPane.disabledUnderlineColor
|
||||||
ToggleButton.tab.selectedBackground = $?TabbedPane.selectedBackground
|
ToggleButton.tab.selectedBackground = $?TabbedPane.selectedBackground
|
||||||
|
ToggleButton.tab.selectedForeground = $?TabbedPane.selectedForeground
|
||||||
ToggleButton.tab.hoverBackground = $TabbedPane.hoverColor
|
ToggleButton.tab.hoverBackground = $TabbedPane.hoverColor
|
||||||
ToggleButton.tab.focusBackground = $TabbedPane.focusColor
|
ToggleButton.tab.focusBackground = $TabbedPane.focusColor
|
||||||
|
|
||||||
|
|||||||
@@ -23,7 +23,7 @@
|
|||||||
#
|
#
|
||||||
# NOTE: Avoid copying the whole content of this file to own properties files.
|
# NOTE: Avoid copying the whole content of this file to own properties files.
|
||||||
# This will make upgrading to newer FlatLaf versions complex and error-prone.
|
# This will make upgrading to newer FlatLaf versions complex and error-prone.
|
||||||
# Instead copy and modify only those properties that you need to alter.
|
# Instead, copy and modify only those properties that you need to alter.
|
||||||
#
|
#
|
||||||
|
|
||||||
# Colors and style mostly based on IntelliJ theme from IntelliJ IDEA Community Edition,
|
# Colors and style mostly based on IntelliJ theme from IntelliJ IDEA Community Edition,
|
||||||
@@ -247,6 +247,7 @@ MenuBar.borderColor = $Separator.foreground
|
|||||||
#---- PasswordField ----
|
#---- PasswordField ----
|
||||||
|
|
||||||
PasswordField.capsLockIconColor = #00000064
|
PasswordField.capsLockIconColor = #00000064
|
||||||
|
PasswordField.revealIconColor = tint(@foreground,40%)
|
||||||
|
|
||||||
|
|
||||||
#---- Popup ----
|
#---- Popup ----
|
||||||
@@ -258,6 +259,7 @@ Popup.dropShadowOpacity = 0.15
|
|||||||
#---- PopupMenu ----
|
#---- PopupMenu ----
|
||||||
|
|
||||||
PopupMenu.borderColor = shade(@background,28%)
|
PopupMenu.borderColor = shade(@background,28%)
|
||||||
|
PopupMenu.hoverScrollArrowBackground = darken(@background,5%)
|
||||||
|
|
||||||
|
|
||||||
#---- ProgressBar ----
|
#---- ProgressBar ----
|
||||||
@@ -311,6 +313,7 @@ SplitPaneDivider.draggingColor = $Component.borderColor
|
|||||||
#---- TabbedPane ----
|
#---- TabbedPane ----
|
||||||
|
|
||||||
TabbedPane.underlineColor = @accentUnderlineColor
|
TabbedPane.underlineColor = @accentUnderlineColor
|
||||||
|
TabbedPane.inactiveUnderlineColor = mix(@accentUnderlineColor,$TabbedPane.background,50%)
|
||||||
TabbedPane.disabledUnderlineColor = darken(@background,28%)
|
TabbedPane.disabledUnderlineColor = darken(@background,28%)
|
||||||
TabbedPane.hoverColor = darken($TabbedPane.background,7%,derived)
|
TabbedPane.hoverColor = darken($TabbedPane.background,7%,derived)
|
||||||
TabbedPane.focusColor = mix(@selectionBackground,$TabbedPane.background,10%)
|
TabbedPane.focusColor = mix(@selectionBackground,$TabbedPane.background,10%)
|
||||||
@@ -329,7 +332,7 @@ TabbedPane.closePressedForeground = $TabbedPane.closeHoverForeground
|
|||||||
|
|
||||||
#---- Table ----
|
#---- Table ----
|
||||||
|
|
||||||
Table.gridColor = darken($Table.background,5%)
|
Table.gridColor = darken($Table.background,8%)
|
||||||
|
|
||||||
|
|
||||||
#---- TableHeader ----
|
#---- TableHeader ----
|
||||||
@@ -374,6 +377,6 @@ Tree.hash = darken($Tree.background,10%)
|
|||||||
focusable: false; \
|
focusable: false; \
|
||||||
toolbar.margin: 1,1,1,1; \
|
toolbar.margin: 1,1,1,1; \
|
||||||
toolbar.spacingInsets: 1,1,1,1; \
|
toolbar.spacingInsets: 1,1,1,1; \
|
||||||
toolbar.hoverBackground: fade(Actions.GreyInline,10%,lazy); \
|
toolbar.hoverBackground: darken($TextField.background,4%); \
|
||||||
toolbar.pressedBackground: fade(Actions.GreyInline,20%,lazy); \
|
toolbar.pressedBackground: darken($TextField.background,8%); \
|
||||||
toolbar.selectedBackground: fade(Actions.GreyInline,30%,lazy)
|
toolbar.selectedBackground: darken($TextField.background,12%)
|
||||||
|
|||||||
@@ -67,6 +67,11 @@ Button.default.hoverBorderColor = null
|
|||||||
[dark]CheckBoxMenuItem.icon.checkmarkColor=#fff9
|
[dark]CheckBoxMenuItem.icon.checkmarkColor=#fff9
|
||||||
|
|
||||||
|
|
||||||
|
#---- Component ----
|
||||||
|
|
||||||
|
Component.accentColor = lazy(ProgressBar.foreground)
|
||||||
|
|
||||||
|
|
||||||
#---- HelpButton ----
|
#---- HelpButton ----
|
||||||
|
|
||||||
HelpButton.hoverBorderColor = null
|
HelpButton.hoverBorderColor = null
|
||||||
@@ -77,6 +82,13 @@ HelpButton.hoverBorderColor = null
|
|||||||
Slider.focusedColor = fade($Component.focusColor,40%,derived)
|
Slider.focusedColor = fade($Component.focusColor,40%,derived)
|
||||||
|
|
||||||
|
|
||||||
|
#---- TabbedPane ----
|
||||||
|
|
||||||
|
# colors from JBUI.CurrentTheme.DefaultTabs.inactiveUnderlineColor()
|
||||||
|
[light]TabbedPane.inactiveUnderlineColor = #9ca7b8
|
||||||
|
[dark]TabbedPane.inactiveUnderlineColor = #747a80
|
||||||
|
|
||||||
|
|
||||||
#---- ToggleButton ----
|
#---- ToggleButton ----
|
||||||
|
|
||||||
ToggleButton.startBackground = $ToggleButton.background
|
ToggleButton.startBackground = $ToggleButton.background
|
||||||
@@ -91,36 +103,37 @@ ToggleButton.endBackground = $ToggleButton.background
|
|||||||
@ijMenuCheckBackgroundL20 = lighten(@selectionBackground,20%,derived noAutoInverse)
|
@ijMenuCheckBackgroundL20 = lighten(@selectionBackground,20%,derived noAutoInverse)
|
||||||
@ijMenuCheckBackgroundD10 = darken(@selectionBackground,10%,derived noAutoInverse)
|
@ijMenuCheckBackgroundD10 = darken(@selectionBackground,10%,derived noAutoInverse)
|
||||||
|
|
||||||
[Arc_Theme]CheckBoxMenuItem.foreground = lazy(MenuItem.foreground)
|
[Arc_Theme]CheckBoxMenuItem.foreground = lazy(MenuItem.foreground)
|
||||||
[Arc_Theme]PopupMenu.foreground = lazy(MenuItem.foreground)
|
[Arc_Theme]PopupMenu.foreground = lazy(MenuItem.foreground)
|
||||||
[Arc_Theme]RadioButtonMenuItem.foreground = lazy(MenuItem.foreground)
|
[Arc_Theme]RadioButtonMenuItem.foreground = lazy(MenuItem.foreground)
|
||||||
[Arc_Theme]ProgressBar.selectionBackground = #000
|
[Arc_Theme]ProgressBar.selectionBackground = #000
|
||||||
[Arc_Theme]ProgressBar.selectionForeground = #fff
|
[Arc_Theme]ProgressBar.selectionForeground = #fff
|
||||||
[Arc_Theme]List.selectionInactiveForeground = #fff
|
[Arc_Theme]List.selectionInactiveForeground = #fff
|
||||||
[Arc_Theme]Table.selectionInactiveForeground = #fff
|
[Arc_Theme]Table.selectionInactiveForeground = #fff
|
||||||
[Arc_Theme]Tree.selectionInactiveForeground = #fff
|
[Arc_Theme]Tree.selectionInactiveForeground = #fff
|
||||||
|
|
||||||
[Arc_Theme_-_Orange]CheckBoxMenuItem.foreground = lazy(MenuItem.foreground)
|
[Arc_Theme_-_Orange]CheckBoxMenuItem.foreground = lazy(MenuItem.foreground)
|
||||||
[Arc_Theme_-_Orange]PopupMenu.foreground = lazy(MenuItem.foreground)
|
[Arc_Theme_-_Orange]PopupMenu.foreground = lazy(MenuItem.foreground)
|
||||||
[Arc_Theme_-_Orange]RadioButtonMenuItem.foreground = lazy(MenuItem.foreground)
|
[Arc_Theme_-_Orange]RadioButtonMenuItem.foreground = lazy(MenuItem.foreground)
|
||||||
[Arc_Theme_-_Orange]ProgressBar.selectionBackground = #000
|
[Arc_Theme_-_Orange]ProgressBar.selectionBackground = #000
|
||||||
[Arc_Theme_-_Orange]ProgressBar.selectionForeground = #fff
|
[Arc_Theme_-_Orange]ProgressBar.selectionForeground = #fff
|
||||||
[Arc_Theme_-_Orange]List.selectionInactiveForeground = #fff
|
[Arc_Theme_-_Orange]List.selectionInactiveForeground = #fff
|
||||||
[Arc_Theme_-_Orange]Table.selectionInactiveForeground = #fff
|
[Arc_Theme_-_Orange]Table.selectionInactiveForeground = #fff
|
||||||
[Arc_Theme_-_Orange]Tree.selectionInactiveForeground = #fff
|
[Arc_Theme_-_Orange]Tree.selectionInactiveForeground = #fff
|
||||||
|
|
||||||
[Arc_Theme_Dark]CheckBoxMenuItem.foreground = lazy(MenuItem.foreground)
|
[Arc_Theme_Dark]CheckBoxMenuItem.foreground = lazy(MenuItem.foreground)
|
||||||
[Arc_Theme_Dark]PopupMenu.foreground = lazy(MenuItem.foreground)
|
[Arc_Theme_Dark]PopupMenu.foreground = lazy(MenuItem.foreground)
|
||||||
[Arc_Theme_Dark]RadioButtonMenuItem.foreground = lazy(MenuItem.foreground)
|
[Arc_Theme_Dark]RadioButtonMenuItem.foreground = lazy(MenuItem.foreground)
|
||||||
[Arc_Theme_Dark]ProgressBar.selectionBackground = #ddd
|
[Arc_Theme_Dark]ProgressBar.selectionBackground = #ddd
|
||||||
[Arc_Theme_Dark]ProgressBar.selectionForeground = #ddd
|
[Arc_Theme_Dark]ProgressBar.selectionForeground = #ddd
|
||||||
|
|
||||||
[Arc_Theme_Dark_-_Orange]CheckBoxMenuItem.foreground = lazy(MenuItem.foreground)
|
[Arc_Theme_Dark_-_Orange]CheckBoxMenuItem.foreground = lazy(MenuItem.foreground)
|
||||||
[Arc_Theme_Dark_-_Orange]PopupMenu.foreground = lazy(MenuItem.foreground)
|
[Arc_Theme_Dark_-_Orange]PopupMenu.foreground = lazy(MenuItem.foreground)
|
||||||
[Arc_Theme_Dark_-_Orange]RadioButtonMenuItem.foreground = lazy(MenuItem.foreground)
|
[Arc_Theme_Dark_-_Orange]RadioButtonMenuItem.foreground = lazy(MenuItem.foreground)
|
||||||
[Arc_Theme_Dark_-_Orange]ProgressBar.selectionBackground = #ddd
|
[Arc_Theme_Dark_-_Orange]ProgressBar.selectionBackground = #ddd
|
||||||
[Arc_Theme_Dark_-_Orange]ProgressBar.selectionForeground = #fff
|
[Arc_Theme_Dark_-_Orange]ProgressBar.selectionForeground = #fff
|
||||||
|
|
||||||
|
[Cobalt_2]Component.accentColor = lazy(Component.focusColor)
|
||||||
[Cobalt_2]CheckBox.icon.background = #002946
|
[Cobalt_2]CheckBox.icon.background = #002946
|
||||||
[Cobalt_2]CheckBox.icon.checkmarkColor = #002946
|
[Cobalt_2]CheckBox.icon.checkmarkColor = #002946
|
||||||
[Cobalt_2]MenuItem.checkBackground = @ijMenuCheckBackgroundL10
|
[Cobalt_2]MenuItem.checkBackground = @ijMenuCheckBackgroundL10
|
||||||
@@ -129,37 +142,50 @@ ToggleButton.endBackground = $ToggleButton.background
|
|||||||
[Cyan_light]MenuItem.checkBackground = @ijMenuCheckBackgroundL20
|
[Cyan_light]MenuItem.checkBackground = @ijMenuCheckBackgroundL20
|
||||||
[Cyan_light]MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundL20
|
[Cyan_light]MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundL20
|
||||||
|
|
||||||
|
[Dark_Flat_Theme]Component.accentColor = lazy(List.selectionBackground)
|
||||||
[Dark_Flat_Theme]TableHeader.background = #3B3B3B
|
[Dark_Flat_Theme]TableHeader.background = #3B3B3B
|
||||||
|
|
||||||
[Dark_purple]Slider.focusedColor = fade($Component.focusColor,70%,derived)
|
[Dark_purple]Slider.focusedColor = fade($Component.focusColor,70%,derived)
|
||||||
|
|
||||||
|
[Dracula---Zihan_Ma]Component.accentColor = lazy(Component.focusColor)
|
||||||
[Dracula---Zihan_Ma]ProgressBar.selectionBackground = #fff
|
[Dracula---Zihan_Ma]ProgressBar.selectionBackground = #fff
|
||||||
[Dracula---Zihan_Ma]ProgressBar.selectionForeground = #fff
|
[Dracula---Zihan_Ma]ProgressBar.selectionForeground = #fff
|
||||||
|
|
||||||
[Gradianto_Dark_Fuchsia]MenuItem.checkBackground = @ijMenuCheckBackgroundL10
|
[Gradianto_Dark_Fuchsia]MenuItem.checkBackground = @ijMenuCheckBackgroundL10
|
||||||
[Gradianto_Dark_Fuchsia]MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundL10
|
[Gradianto_Dark_Fuchsia]MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundL10
|
||||||
|
|
||||||
|
[Gruvbox_Dark_Hard]Component.accentColor = lazy(TabbedPane.underlineColor)
|
||||||
[Gruvbox_Dark_Hard]ToggleButton.selectedBackground = $ToggleButton.selectedBackground
|
[Gruvbox_Dark_Hard]ToggleButton.selectedBackground = $ToggleButton.selectedBackground
|
||||||
[Gruvbox_Dark_Hard]ToggleButton.toolbar.selectedBackground = $ToggleButton.toolbar.selectedBackground
|
[Gruvbox_Dark_Hard]ToggleButton.toolbar.selectedBackground = $ToggleButton.toolbar.selectedBackground
|
||||||
|
|
||||||
|
[Gruvbox_Dark_Medium]Component.accentColor = lazy(TabbedPane.underlineColor)
|
||||||
[Gruvbox_Dark_Medium]ToggleButton.selectedBackground = $ToggleButton.selectedBackground
|
[Gruvbox_Dark_Medium]ToggleButton.selectedBackground = $ToggleButton.selectedBackground
|
||||||
[Gruvbox_Dark_Medium]ToggleButton.toolbar.selectedBackground = $ToggleButton.toolbar.selectedBackground
|
[Gruvbox_Dark_Medium]ToggleButton.toolbar.selectedBackground = $ToggleButton.toolbar.selectedBackground
|
||||||
|
|
||||||
|
[Gruvbox_Dark_Soft]Component.accentColor = lazy(TabbedPane.underlineColor)
|
||||||
[Gruvbox_Dark_Soft]MenuItem.checkBackground = @ijMenuCheckBackgroundL10
|
[Gruvbox_Dark_Soft]MenuItem.checkBackground = @ijMenuCheckBackgroundL10
|
||||||
[Gruvbox_Dark_Soft]MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundL10
|
[Gruvbox_Dark_Soft]MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundL10
|
||||||
[Gruvbox_Dark_Soft]ToggleButton.selectedBackground = $ToggleButton.selectedBackground
|
[Gruvbox_Dark_Soft]ToggleButton.selectedBackground = $ToggleButton.selectedBackground
|
||||||
[Gruvbox_Dark_Soft]ToggleButton.toolbar.selectedBackground = $ToggleButton.toolbar.selectedBackground
|
[Gruvbox_Dark_Soft]ToggleButton.toolbar.selectedBackground = $ToggleButton.toolbar.selectedBackground
|
||||||
|
|
||||||
[Hiberbee_Dark]TabbedPane.focusColor = #5A5A5A
|
[Hiberbee_Dark]TabbedPane.focusColor = #5A5A5A
|
||||||
[Hiberbee_Dark]ToggleButton.selectedBackground = $ToggleButton.selectedBackground
|
[Hiberbee_Dark]TabbedPane.selectedBackground = #434241
|
||||||
|
[Hiberbee_Dark]TabbedPane.selectedForeground = #70D7FF
|
||||||
[Hiberbee_Dark]ToggleButton.selectedBackground = $ToggleButton.selectedBackground
|
[Hiberbee_Dark]ToggleButton.selectedBackground = $ToggleButton.selectedBackground
|
||||||
[Hiberbee_Dark]ToggleButton.toolbar.selectedBackground = $ToggleButton.toolbar.selectedBackground
|
[Hiberbee_Dark]ToggleButton.toolbar.selectedBackground = $ToggleButton.toolbar.selectedBackground
|
||||||
|
|
||||||
|
[High_contrast]Component.accentColor = lazy(Component.focusColor)
|
||||||
[High_contrast]ToggleButton.selectedBackground = #fff
|
[High_contrast]ToggleButton.selectedBackground = #fff
|
||||||
[High_contrast]ToggleButton.selectedForeground = #000
|
[High_contrast]ToggleButton.selectedForeground = #000
|
||||||
[High_contrast]ToggleButton.disabledSelectedBackground = #444
|
[High_contrast]ToggleButton.disabledSelectedBackground = #444
|
||||||
[High_contrast]ToggleButton.toolbar.selectedBackground = #fff
|
[High_contrast]ToggleButton.toolbar.selectedBackground = #fff
|
||||||
|
[High_contrast][style]Button.inTextField = \
|
||||||
|
toolbar.hoverBackground: #444; \
|
||||||
|
toolbar.pressedBackground: #666; \
|
||||||
|
toolbar.selectedBackground: #fff
|
||||||
|
[High_contrast][style]ToggleButton.inTextField = $[High_contrast][style]Button.inTextField
|
||||||
|
|
||||||
|
[Light_Flat]Component.accentColor = lazy(TabbedPane.underlineColor)
|
||||||
[Light_Flat]TableHeader.background = #E5E5E9
|
[Light_Flat]TableHeader.background = #E5E5E9
|
||||||
|
|
||||||
[Monocai]MenuItem.checkBackground = @ijMenuCheckBackgroundL10
|
[Monocai]MenuItem.checkBackground = @ijMenuCheckBackgroundL10
|
||||||
@@ -175,6 +201,8 @@ ToggleButton.endBackground = $ToggleButton.background
|
|||||||
[Monocai]RadioButtonMenuItem.acceleratorForeground = @Monocai.acceleratorForeground
|
[Monocai]RadioButtonMenuItem.acceleratorForeground = @Monocai.acceleratorForeground
|
||||||
[Monocai]RadioButtonMenuItem.acceleratorSelectionForeground = @Monocai.acceleratorSelectionForeground
|
[Monocai]RadioButtonMenuItem.acceleratorSelectionForeground = @Monocai.acceleratorSelectionForeground
|
||||||
|
|
||||||
|
[Monokai_Pro]TitledBorder.titleColor = @foreground
|
||||||
|
|
||||||
[Nord]MenuItem.checkBackground = @ijMenuCheckBackgroundL10
|
[Nord]MenuItem.checkBackground = @ijMenuCheckBackgroundL10
|
||||||
[Nord]MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundL10
|
[Nord]MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundL10
|
||||||
|
|
||||||
@@ -182,8 +210,12 @@ ToggleButton.endBackground = $ToggleButton.background
|
|||||||
[One_Dark]MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundL10
|
[One_Dark]MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundL10
|
||||||
[One_Dark]Slider.focusedColor = fade(#568af2,40%)
|
[One_Dark]Slider.focusedColor = fade(#568af2,40%)
|
||||||
|
|
||||||
|
[Solarized_Dark---4lex4]Component.accentColor = lazy(TabbedPane.underlineColor)
|
||||||
[Solarized_Dark---4lex4]Slider.focusedColor = fade($Component.focusColor,80%,derived)
|
[Solarized_Dark---4lex4]Slider.focusedColor = fade($Component.focusColor,80%,derived)
|
||||||
|
|
||||||
|
[Solarized_Light---4lex4]Component.accentColor = lazy(TabbedPane.underlineColor)
|
||||||
|
|
||||||
|
[vuesion-theme]Component.accentColor = lazy(Button.default.endBackground)
|
||||||
[vuesion-theme]MenuItem.checkBackground = @ijMenuCheckBackgroundL10
|
[vuesion-theme]MenuItem.checkBackground = @ijMenuCheckBackgroundL10
|
||||||
[vuesion-theme]MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundL10
|
[vuesion-theme]MenuItem.underlineSelectionCheckBackground = @ijMenuCheckBackgroundL10
|
||||||
[vuesion-theme]Slider.trackValueColor = #ececee
|
[vuesion-theme]Slider.trackValueColor = #ececee
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,65 @@
|
|||||||
|
#
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
#---- FileChooser ----
|
||||||
|
|
||||||
|
#fields
|
||||||
|
FileChooser.lookInLabel.textAndMnemonic = Buscar &en:
|
||||||
|
FileChooser.saveInLabelText = Guardar en:
|
||||||
|
FileChooser.fileNameLabel.textAndMnemonic = &Nombre de fichero:
|
||||||
|
FileChooser.folderNameLabel.textAndMnemonic = &Nombre de carpeta:
|
||||||
|
FileChooser.filesOfTypeLabel.textAndMnemonic = Ficheros de &Tipo:
|
||||||
|
|
||||||
|
# toolbar
|
||||||
|
FileChooser.upFolderToolTipText = Subir un nivel
|
||||||
|
FileChooser.upFolderAccessibleName = Subir
|
||||||
|
FileChooser.homeFolderToolTipText = Inicio
|
||||||
|
FileChooser.homeFolderAccessibleName = Inicio
|
||||||
|
FileChooser.newFolderToolTipText = Crear nueva carpeta
|
||||||
|
FileChooser.newFolderAccessibleName = Nueva carpeta
|
||||||
|
FileChooser.listViewButtonToolTipText = Lista
|
||||||
|
FileChooser.listViewButtonAccessibleName = Lista
|
||||||
|
FileChooser.detailsViewButtonToolTipText = Detalles
|
||||||
|
FileChooser.detailsViewButtonAccessibleName = Detalles
|
||||||
|
|
||||||
|
# details table header
|
||||||
|
FileChooser.fileNameHeaderText = Nombre
|
||||||
|
FileChooser.fileSizeHeaderText = Tama\u00F1o
|
||||||
|
FileChooser.fileTypeHeaderText = Tipo
|
||||||
|
FileChooser.fileDateHeaderText = Modificado
|
||||||
|
FileChooser.fileAttrHeaderText = Atributos
|
||||||
|
|
||||||
|
# popup menu
|
||||||
|
FileChooser.viewMenuLabelText = Ver
|
||||||
|
FileChooser.refreshActionLabelText = Refrescar
|
||||||
|
FileChooser.newFolderActionLabelText = Nueva carpeta
|
||||||
|
FileChooser.listViewActionLabelText = Lista
|
||||||
|
FileChooser.detailsViewActionLabelText = Detalles
|
||||||
|
|
||||||
|
|
||||||
|
#---- SplitPaneDivider ----
|
||||||
|
|
||||||
|
SplitPaneDivider.collapseLeftToolTipText = Contraer Panel Izquierdo
|
||||||
|
SplitPaneDivider.collapseRightToolTipText = Contraer panel Derecho
|
||||||
|
SplitPaneDivider.collapseTopToolTipText = Contraer panel Superior
|
||||||
|
SplitPaneDivider.collapseBottomToolTipText = Contraer Panel Inferior
|
||||||
|
SplitPaneDivider.expandLeftToolTipText = Expandir Panel Izquierdo
|
||||||
|
SplitPaneDivider.expandRightToolTipText = Expandir Panel Derecho
|
||||||
|
SplitPaneDivider.expandTopToolTipText = Expandir Panel Superior
|
||||||
|
SplitPaneDivider.expandBottomToolTipText = Expandir Panel Inferior
|
||||||
|
|
||||||
|
|
||||||
|
#---- TabbedPane ----
|
||||||
|
|
||||||
|
TabbedPane.moreTabsButtonToolTipText = Mostrar Pesta\u00F1as Ocultas
|
||||||
@@ -96,19 +96,26 @@ public class TestFlatStyleableInfo
|
|||||||
"minimumWidth", int.class,
|
"minimumWidth", int.class,
|
||||||
|
|
||||||
"focusedBackground", Color.class,
|
"focusedBackground", Color.class,
|
||||||
|
"focusedForeground", Color.class,
|
||||||
"hoverBackground", Color.class,
|
"hoverBackground", Color.class,
|
||||||
|
"hoverForeground", Color.class,
|
||||||
"pressedBackground", Color.class,
|
"pressedBackground", Color.class,
|
||||||
|
"pressedForeground", Color.class,
|
||||||
"selectedBackground", Color.class,
|
"selectedBackground", Color.class,
|
||||||
"selectedForeground", Color.class,
|
"selectedForeground", Color.class,
|
||||||
"disabledBackground", Color.class,
|
"disabledBackground", Color.class,
|
||||||
"disabledText", Color.class,
|
"disabledText", Color.class,
|
||||||
"disabledSelectedBackground", Color.class,
|
"disabledSelectedBackground", Color.class,
|
||||||
|
"disabledSelectedForeground", Color.class,
|
||||||
|
|
||||||
"default.background", Color.class,
|
"default.background", Color.class,
|
||||||
"default.foreground", Color.class,
|
"default.foreground", Color.class,
|
||||||
"default.focusedBackground", Color.class,
|
"default.focusedBackground", Color.class,
|
||||||
|
"default.focusedForeground", Color.class,
|
||||||
"default.hoverBackground", Color.class,
|
"default.hoverBackground", Color.class,
|
||||||
|
"default.hoverForeground", Color.class,
|
||||||
"default.pressedBackground", Color.class,
|
"default.pressedBackground", Color.class,
|
||||||
|
"default.pressedForeground", Color.class,
|
||||||
"default.boldText", boolean.class,
|
"default.boldText", boolean.class,
|
||||||
|
|
||||||
"paintShadow", boolean.class,
|
"paintShadow", boolean.class,
|
||||||
@@ -118,8 +125,13 @@ public class TestFlatStyleableInfo
|
|||||||
|
|
||||||
"toolbar.spacingInsets", Insets.class,
|
"toolbar.spacingInsets", Insets.class,
|
||||||
"toolbar.hoverBackground", Color.class,
|
"toolbar.hoverBackground", Color.class,
|
||||||
|
"toolbar.hoverForeground", Color.class,
|
||||||
"toolbar.pressedBackground", Color.class,
|
"toolbar.pressedBackground", Color.class,
|
||||||
|
"toolbar.pressedForeground", Color.class,
|
||||||
"toolbar.selectedBackground", Color.class,
|
"toolbar.selectedBackground", Color.class,
|
||||||
|
"toolbar.selectedForeground", Color.class,
|
||||||
|
"toolbar.disabledSelectedBackground", Color.class,
|
||||||
|
"toolbar.disabledSelectedForeground", Color.class,
|
||||||
|
|
||||||
"buttonType", String.class,
|
"buttonType", String.class,
|
||||||
"squareSize", boolean.class,
|
"squareSize", boolean.class,
|
||||||
@@ -422,6 +434,10 @@ public class TestFlatStyleableInfo
|
|||||||
FlatPopupMenuUI ui = (FlatPopupMenuUI) c.getUI();
|
FlatPopupMenuUI ui = (FlatPopupMenuUI) c.getUI();
|
||||||
|
|
||||||
Map<String, Class<?>> expected = expectedMap(
|
Map<String, Class<?>> expected = expectedMap(
|
||||||
|
"arrowType", String.class,
|
||||||
|
"scrollArrowColor", Color.class,
|
||||||
|
"hoverScrollArrowBackground", Color.class,
|
||||||
|
|
||||||
"borderInsets", Insets.class,
|
"borderInsets", Insets.class,
|
||||||
"borderColor", Color.class
|
"borderColor", Color.class
|
||||||
);
|
);
|
||||||
@@ -539,6 +555,7 @@ public class TestFlatStyleableInfo
|
|||||||
"maximumThumbSize", Dimension.class,
|
"maximumThumbSize", Dimension.class,
|
||||||
"allowsAbsolutePositioning", boolean.class,
|
"allowsAbsolutePositioning", boolean.class,
|
||||||
|
|
||||||
|
"minimumButtonSize", Dimension.class,
|
||||||
"trackInsets", Insets.class,
|
"trackInsets", Insets.class,
|
||||||
"thumbInsets", Insets.class,
|
"thumbInsets", Insets.class,
|
||||||
"trackArc", int.class,
|
"trackArc", int.class,
|
||||||
@@ -688,6 +705,7 @@ public class TestFlatStyleableInfo
|
|||||||
"selectedBackground", Color.class,
|
"selectedBackground", Color.class,
|
||||||
"selectedForeground", Color.class,
|
"selectedForeground", Color.class,
|
||||||
"underlineColor", Color.class,
|
"underlineColor", Color.class,
|
||||||
|
"inactiveUnderlineColor", Color.class,
|
||||||
"disabledUnderlineColor", Color.class,
|
"disabledUnderlineColor", Color.class,
|
||||||
"hoverColor", Color.class,
|
"hoverColor", Color.class,
|
||||||
"focusColor", Color.class,
|
"focusColor", Color.class,
|
||||||
@@ -857,8 +875,11 @@ public class TestFlatStyleableInfo
|
|||||||
"tab.underlineColor", Color.class,
|
"tab.underlineColor", Color.class,
|
||||||
"tab.disabledUnderlineColor", Color.class,
|
"tab.disabledUnderlineColor", Color.class,
|
||||||
"tab.selectedBackground", Color.class,
|
"tab.selectedBackground", Color.class,
|
||||||
|
"tab.selectedForeground", Color.class,
|
||||||
"tab.hoverBackground", Color.class,
|
"tab.hoverBackground", Color.class,
|
||||||
"tab.focusBackground", Color.class
|
"tab.hoverForeground", Color.class,
|
||||||
|
"tab.focusBackground", Color.class,
|
||||||
|
"tab.focusForeground", Color.class
|
||||||
);
|
);
|
||||||
|
|
||||||
// FlatToggleButtonUI extends FlatButtonUI
|
// FlatToggleButtonUI extends FlatButtonUI
|
||||||
|
|||||||
@@ -221,19 +221,26 @@ public class TestFlatStyling
|
|||||||
ui.applyStyle( b, "minimumWidth: 100" );
|
ui.applyStyle( b, "minimumWidth: 100" );
|
||||||
|
|
||||||
ui.applyStyle( b, "focusedBackground: #fff" );
|
ui.applyStyle( b, "focusedBackground: #fff" );
|
||||||
|
ui.applyStyle( b, "focusedForeground: #fff" );
|
||||||
ui.applyStyle( b, "hoverBackground: #fff" );
|
ui.applyStyle( b, "hoverBackground: #fff" );
|
||||||
|
ui.applyStyle( b, "hoverForeground: #fff" );
|
||||||
ui.applyStyle( b, "pressedBackground: #fff" );
|
ui.applyStyle( b, "pressedBackground: #fff" );
|
||||||
|
ui.applyStyle( b, "pressedForeground: #fff" );
|
||||||
ui.applyStyle( b, "selectedBackground: #fff" );
|
ui.applyStyle( b, "selectedBackground: #fff" );
|
||||||
ui.applyStyle( b, "selectedForeground: #fff" );
|
ui.applyStyle( b, "selectedForeground: #fff" );
|
||||||
ui.applyStyle( b, "disabledBackground: #fff" );
|
ui.applyStyle( b, "disabledBackground: #fff" );
|
||||||
ui.applyStyle( b, "disabledText: #fff" );
|
ui.applyStyle( b, "disabledText: #fff" );
|
||||||
ui.applyStyle( b, "disabledSelectedBackground: #fff" );
|
ui.applyStyle( b, "disabledSelectedBackground: #fff" );
|
||||||
|
ui.applyStyle( b, "disabledSelectedForeground: #fff" );
|
||||||
|
|
||||||
ui.applyStyle( b, "default.background: #fff" );
|
ui.applyStyle( b, "default.background: #fff" );
|
||||||
ui.applyStyle( b, "default.foreground: #fff" );
|
ui.applyStyle( b, "default.foreground: #fff" );
|
||||||
ui.applyStyle( b, "default.focusedBackground: #fff" );
|
ui.applyStyle( b, "default.focusedBackground: #fff" );
|
||||||
|
ui.applyStyle( b, "default.focusedForeground: #fff" );
|
||||||
ui.applyStyle( b, "default.hoverBackground: #fff" );
|
ui.applyStyle( b, "default.hoverBackground: #fff" );
|
||||||
|
ui.applyStyle( b, "default.hoverForeground: #fff" );
|
||||||
ui.applyStyle( b, "default.pressedBackground: #fff" );
|
ui.applyStyle( b, "default.pressedBackground: #fff" );
|
||||||
|
ui.applyStyle( b, "default.pressedForeground: #fff" );
|
||||||
ui.applyStyle( b, "default.boldText: true" );
|
ui.applyStyle( b, "default.boldText: true" );
|
||||||
|
|
||||||
ui.applyStyle( b, "paintShadow: true" );
|
ui.applyStyle( b, "paintShadow: true" );
|
||||||
@@ -243,8 +250,13 @@ public class TestFlatStyling
|
|||||||
|
|
||||||
ui.applyStyle( b, "toolbar.spacingInsets: 1,2,3,4" );
|
ui.applyStyle( b, "toolbar.spacingInsets: 1,2,3,4" );
|
||||||
ui.applyStyle( b, "toolbar.hoverBackground: #fff" );
|
ui.applyStyle( b, "toolbar.hoverBackground: #fff" );
|
||||||
|
ui.applyStyle( b, "toolbar.hoverForeground: #fff" );
|
||||||
ui.applyStyle( b, "toolbar.pressedBackground: #fff" );
|
ui.applyStyle( b, "toolbar.pressedBackground: #fff" );
|
||||||
|
ui.applyStyle( b, "toolbar.pressedForeground: #fff" );
|
||||||
ui.applyStyle( b, "toolbar.selectedBackground: #fff" );
|
ui.applyStyle( b, "toolbar.selectedBackground: #fff" );
|
||||||
|
ui.applyStyle( b, "toolbar.selectedForeground: #fff" );
|
||||||
|
ui.applyStyle( b, "toolbar.disabledSelectedBackground: #fff" );
|
||||||
|
ui.applyStyle( b, "toolbar.disabledSelectedForeground: #fff" );
|
||||||
|
|
||||||
ui.applyStyle( b, "buttonType: help" );
|
ui.applyStyle( b, "buttonType: help" );
|
||||||
ui.applyStyle( b, "squareSize: true" );
|
ui.applyStyle( b, "squareSize: true" );
|
||||||
@@ -565,6 +577,10 @@ public class TestFlatStyling
|
|||||||
JPopupMenu c = new JPopupMenu();
|
JPopupMenu c = new JPopupMenu();
|
||||||
FlatPopupMenuUI ui = (FlatPopupMenuUI) c.getUI();
|
FlatPopupMenuUI ui = (FlatPopupMenuUI) c.getUI();
|
||||||
|
|
||||||
|
ui.applyStyle( "arrowType: chevron" );
|
||||||
|
ui.applyStyle( "scrollArrowColor: #fff" );
|
||||||
|
ui.applyStyle( "hoverScrollArrowBackground: #fff" );
|
||||||
|
|
||||||
ui.applyStyle( "borderInsets: 1,2,3,4" );
|
ui.applyStyle( "borderInsets: 1,2,3,4" );
|
||||||
ui.applyStyle( "borderColor: #fff" );
|
ui.applyStyle( "borderColor: #fff" );
|
||||||
|
|
||||||
@@ -684,6 +700,7 @@ public class TestFlatStyling
|
|||||||
ui.applyStyle( "maximumThumbSize: 1,2" );
|
ui.applyStyle( "maximumThumbSize: 1,2" );
|
||||||
ui.applyStyle( "allowsAbsolutePositioning: true" );
|
ui.applyStyle( "allowsAbsolutePositioning: true" );
|
||||||
|
|
||||||
|
ui.applyStyle( "minimumButtonSize: 1,2" );
|
||||||
ui.applyStyle( "trackInsets: 1,2,3,4" );
|
ui.applyStyle( "trackInsets: 1,2,3,4" );
|
||||||
ui.applyStyle( "thumbInsets: 1,2,3,4" );
|
ui.applyStyle( "thumbInsets: 1,2,3,4" );
|
||||||
ui.applyStyle( "trackArc: 5" );
|
ui.applyStyle( "trackArc: 5" );
|
||||||
@@ -857,6 +874,7 @@ public class TestFlatStyling
|
|||||||
ui.applyStyle( "selectedBackground: #fff" );
|
ui.applyStyle( "selectedBackground: #fff" );
|
||||||
ui.applyStyle( "selectedForeground: #fff" );
|
ui.applyStyle( "selectedForeground: #fff" );
|
||||||
ui.applyStyle( "underlineColor: #fff" );
|
ui.applyStyle( "underlineColor: #fff" );
|
||||||
|
ui.applyStyle( "inactiveUnderlineColor: #fff" );
|
||||||
ui.applyStyle( "disabledUnderlineColor: #fff" );
|
ui.applyStyle( "disabledUnderlineColor: #fff" );
|
||||||
ui.applyStyle( "hoverColor: #fff" );
|
ui.applyStyle( "hoverColor: #fff" );
|
||||||
ui.applyStyle( "focusColor: #fff" );
|
ui.applyStyle( "focusColor: #fff" );
|
||||||
@@ -1067,8 +1085,11 @@ public class TestFlatStyling
|
|||||||
ui.applyStyle( b, "tab.underlineColor: #fff" );
|
ui.applyStyle( b, "tab.underlineColor: #fff" );
|
||||||
ui.applyStyle( b, "tab.disabledUnderlineColor: #fff" );
|
ui.applyStyle( b, "tab.disabledUnderlineColor: #fff" );
|
||||||
ui.applyStyle( b, "tab.selectedBackground: #fff" );
|
ui.applyStyle( b, "tab.selectedBackground: #fff" );
|
||||||
|
ui.applyStyle( b, "tab.selectedForeground: #fff" );
|
||||||
ui.applyStyle( b, "tab.hoverBackground: #fff" );
|
ui.applyStyle( b, "tab.hoverBackground: #fff" );
|
||||||
|
ui.applyStyle( b, "tab.hoverForeground: #fff" );
|
||||||
ui.applyStyle( b, "tab.focusBackground: #fff" );
|
ui.applyStyle( b, "tab.focusBackground: #fff" );
|
||||||
|
ui.applyStyle( b, "tab.focusForeground: #fff" );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -38,8 +38,8 @@ import com.formdev.flatlaf.FlatLightLaf;
|
|||||||
import com.formdev.flatlaf.demo.HintManager.Hint;
|
import com.formdev.flatlaf.demo.HintManager.Hint;
|
||||||
import com.formdev.flatlaf.demo.extras.*;
|
import com.formdev.flatlaf.demo.extras.*;
|
||||||
import com.formdev.flatlaf.demo.intellijthemes.*;
|
import com.formdev.flatlaf.demo.intellijthemes.*;
|
||||||
import com.formdev.flatlaf.extras.FlatDesktop;
|
|
||||||
import com.formdev.flatlaf.extras.FlatAnimatedLafChange;
|
import com.formdev.flatlaf.extras.FlatAnimatedLafChange;
|
||||||
|
import com.formdev.flatlaf.extras.FlatDesktop;
|
||||||
import com.formdev.flatlaf.extras.FlatSVGIcon;
|
import com.formdev.flatlaf.extras.FlatSVGIcon;
|
||||||
import com.formdev.flatlaf.extras.FlatUIDefaultsInspector;
|
import com.formdev.flatlaf.extras.FlatUIDefaultsInspector;
|
||||||
import com.formdev.flatlaf.extras.components.FlatButton;
|
import com.formdev.flatlaf.extras.components.FlatButton;
|
||||||
@@ -82,13 +82,33 @@ class DemoFrame
|
|||||||
if( tabIndex >= 0 && tabIndex < tabbedPane.getTabCount() && tabIndex != tabbedPane.getSelectedIndex() )
|
if( tabIndex >= 0 && tabIndex < tabbedPane.getTabCount() && tabIndex != tabbedPane.getSelectedIndex() )
|
||||||
tabbedPane.setSelectedIndex( tabIndex );
|
tabbedPane.setSelectedIndex( tabIndex );
|
||||||
|
|
||||||
// hide some menu items on macOS
|
// macOS (see https://www.formdev.com/flatlaf/macos/)
|
||||||
if( SystemInfo.isMacOS ) {
|
if( SystemInfo.isMacOS ) {
|
||||||
|
// hide menu items that are in macOS application menu
|
||||||
exitMenuItem.setVisible( false );
|
exitMenuItem.setVisible( false );
|
||||||
aboutMenuItem.setVisible( false );
|
aboutMenuItem.setVisible( false );
|
||||||
|
|
||||||
// do not use HTML text on macOS
|
// do not use HTML text in menu items because this is not supported in macOS screen menu
|
||||||
htmlMenuItem.setText( "some text" );
|
htmlMenuItem.setText( "some text" );
|
||||||
|
|
||||||
|
if( SystemInfo.isMacFullWindowContentSupported ) {
|
||||||
|
// expand window content into window title bar and make title bar transparent
|
||||||
|
getRootPane().putClientProperty( "apple.awt.fullWindowContent", true );
|
||||||
|
getRootPane().putClientProperty( "apple.awt.transparentTitleBar", true );
|
||||||
|
|
||||||
|
// hide window title
|
||||||
|
if( SystemInfo.isJava_17_orLater )
|
||||||
|
getRootPane().putClientProperty( "apple.awt.windowTitleVisible", false );
|
||||||
|
else
|
||||||
|
setTitle( null );
|
||||||
|
|
||||||
|
// add gap to left side of toolbar
|
||||||
|
toolBar.add( Box.createHorizontalStrut( 70 ), 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
// enable full screen mode for this window (for Java 8 - 10; not necessary for Java 11+)
|
||||||
|
if( !SystemInfo.isJava_11_orLater )
|
||||||
|
getRootPane().putClientProperty( "apple.awt.fullscreenable", true );
|
||||||
}
|
}
|
||||||
|
|
||||||
// integrate into macOS screen menu
|
// integrate into macOS screen menu
|
||||||
@@ -322,8 +342,8 @@ class DemoFrame
|
|||||||
// add font families
|
// add font families
|
||||||
fontMenu.addSeparator();
|
fontMenu.addSeparator();
|
||||||
ArrayList<String> families = new ArrayList<>( Arrays.asList(
|
ArrayList<String> families = new ArrayList<>( Arrays.asList(
|
||||||
"Arial", "Cantarell", "Comic Sans MS", "Courier New", "DejaVu Sans",
|
"Arial", "Cantarell", "Comic Sans MS", "DejaVu Sans",
|
||||||
"Dialog", "Liberation Sans", "Monospaced", "Noto Sans", "Roboto",
|
"Dialog", "Liberation Sans", "Noto Sans", "Roboto",
|
||||||
"SansSerif", "Segoe UI", "Serif", "Tahoma", "Ubuntu", "Verdana" ) );
|
"SansSerif", "Segoe UI", "Serif", "Tahoma", "Ubuntu", "Verdana" ) );
|
||||||
if( !families.contains( currentFamily ) )
|
if( !families.contains( currentFamily ) )
|
||||||
families.add( currentFamily );
|
families.add( currentFamily );
|
||||||
@@ -433,9 +453,9 @@ class DemoFrame
|
|||||||
lafClass == FlatIntelliJLaf.class ||
|
lafClass == FlatIntelliJLaf.class ||
|
||||||
lafClass == FlatDarculaLaf.class;
|
lafClass == FlatDarculaLaf.class;
|
||||||
|
|
||||||
accentColorLabel.setEnabled( isAccentColorSupported );
|
accentColorLabel.setVisible( isAccentColorSupported );
|
||||||
for( int i = 0; i < accentColorButtons.length; i++ )
|
for( int i = 0; i < accentColorButtons.length; i++ )
|
||||||
accentColorButtons[i].setEnabled( isAccentColorSupported );
|
accentColorButtons[i].setVisible( isAccentColorSupported );
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initComponents() {
|
private void initComponents() {
|
||||||
@@ -464,6 +484,7 @@ class DemoFrame
|
|||||||
JMenuItem projectViewMenuItem = new JMenuItem();
|
JMenuItem projectViewMenuItem = new JMenuItem();
|
||||||
JMenuItem structureViewMenuItem = new JMenuItem();
|
JMenuItem structureViewMenuItem = new JMenuItem();
|
||||||
JMenuItem propertiesViewMenuItem = new JMenuItem();
|
JMenuItem propertiesViewMenuItem = new JMenuItem();
|
||||||
|
scrollingPopupMenu = new JMenu();
|
||||||
JMenuItem menuItem2 = new JMenuItem();
|
JMenuItem menuItem2 = new JMenuItem();
|
||||||
htmlMenuItem = new JMenuItem();
|
htmlMenuItem = new JMenuItem();
|
||||||
JRadioButtonMenuItem radioButtonMenuItem1 = new JRadioButtonMenuItem();
|
JRadioButtonMenuItem radioButtonMenuItem1 = new JRadioButtonMenuItem();
|
||||||
@@ -668,6 +689,12 @@ class DemoFrame
|
|||||||
}
|
}
|
||||||
viewMenu.add(menu1);
|
viewMenu.add(menu1);
|
||||||
|
|
||||||
|
//======== scrollingPopupMenu ========
|
||||||
|
{
|
||||||
|
scrollingPopupMenu.setText("Scrolling Popup Menu");
|
||||||
|
}
|
||||||
|
viewMenu.add(scrollingPopupMenu);
|
||||||
|
|
||||||
//---- menuItem2 ----
|
//---- menuItem2 ----
|
||||||
menuItem2.setText("Disabled Item");
|
menuItem2.setText("Disabled Item");
|
||||||
menuItem2.setEnabled(false);
|
menuItem2.setEnabled(false);
|
||||||
@@ -889,8 +916,17 @@ class DemoFrame
|
|||||||
copyMenuItem.addActionListener( new DefaultEditorKit.CopyAction() );
|
copyMenuItem.addActionListener( new DefaultEditorKit.CopyAction() );
|
||||||
pasteMenuItem.addActionListener( new DefaultEditorKit.PasteAction() );
|
pasteMenuItem.addActionListener( new DefaultEditorKit.PasteAction() );
|
||||||
|
|
||||||
if( FlatLaf.supportsNativeWindowDecorations() ) {
|
scrollingPopupMenu.add( "Large menus are scrollable" );
|
||||||
windowDecorationsCheckBoxMenuItem.setSelected( FlatLaf.isUseNativeWindowDecorations() );
|
scrollingPopupMenu.add( "Use mouse wheel to scroll" );
|
||||||
|
scrollingPopupMenu.add( "Or use up/down arrows at top/bottom" );
|
||||||
|
for( int i = 1; i <= 100; i++ )
|
||||||
|
scrollingPopupMenu.add( "Item " + i );
|
||||||
|
|
||||||
|
if( FlatLaf.supportsNativeWindowDecorations() || (SystemInfo.isLinux && JFrame.isDefaultLookAndFeelDecorated()) ) {
|
||||||
|
if( SystemInfo.isLinux )
|
||||||
|
unsupported( windowDecorationsCheckBoxMenuItem );
|
||||||
|
else
|
||||||
|
windowDecorationsCheckBoxMenuItem.setSelected( FlatLaf.isUseNativeWindowDecorations() );
|
||||||
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" ) );
|
||||||
@@ -931,6 +967,7 @@ class DemoFrame
|
|||||||
|
|
||||||
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
|
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
|
||||||
private JMenuItem exitMenuItem;
|
private JMenuItem exitMenuItem;
|
||||||
|
private JMenu scrollingPopupMenu;
|
||||||
private JMenuItem htmlMenuItem;
|
private JMenuItem htmlMenuItem;
|
||||||
private JMenu fontMenu;
|
private JMenu fontMenu;
|
||||||
private JMenu optionsMenu;
|
private JMenu optionsMenu;
|
||||||
|
|||||||
@@ -282,6 +282,13 @@ new FormModel {
|
|||||||
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) )
|
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "menuItemActionPerformed", true ) )
|
||||||
} )
|
} )
|
||||||
} )
|
} )
|
||||||
|
add( new FormContainer( "javax.swing.JMenu", new FormLayoutManager( class javax.swing.JMenu ) ) {
|
||||||
|
name: "scrollingPopupMenu"
|
||||||
|
"text": "Scrolling Popup Menu"
|
||||||
|
auxiliary() {
|
||||||
|
"JavaCodeGenerator.variableLocal": false
|
||||||
|
}
|
||||||
|
} )
|
||||||
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
add( new FormComponent( "javax.swing.JMenuItem" ) {
|
||||||
name: "menuItem2"
|
name: "menuItem2"
|
||||||
"text": "Disabled Item"
|
"text": "Disabled Item"
|
||||||
|
|||||||
@@ -17,6 +17,8 @@
|
|||||||
package com.formdev.flatlaf.demo;
|
package com.formdev.flatlaf.demo;
|
||||||
|
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
|
import javax.swing.JDialog;
|
||||||
|
import javax.swing.JFrame;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
import com.formdev.flatlaf.FlatLaf;
|
import com.formdev.flatlaf.FlatLaf;
|
||||||
import com.formdev.flatlaf.extras.FlatInspector;
|
import com.formdev.flatlaf.extras.FlatInspector;
|
||||||
@@ -34,7 +36,7 @@ public class FlatLafDemo
|
|||||||
static boolean screenshotsMode = Boolean.parseBoolean( System.getProperty( "flatlaf.demo.screenshotsMode" ) );
|
static boolean screenshotsMode = Boolean.parseBoolean( System.getProperty( "flatlaf.demo.screenshotsMode" ) );
|
||||||
|
|
||||||
public static void main( String[] args ) {
|
public static void main( String[] args ) {
|
||||||
// macOS
|
// macOS (see https://www.formdev.com/flatlaf/macos/)
|
||||||
if( SystemInfo.isMacOS ) {
|
if( SystemInfo.isMacOS ) {
|
||||||
// enable screen menu bar
|
// enable screen menu bar
|
||||||
// (moves menu bar from JFrame window to top of screen)
|
// (moves menu bar from JFrame window to top of screen)
|
||||||
@@ -49,9 +51,17 @@ public class FlatLafDemo
|
|||||||
// - "system": use current macOS appearance (light or dark)
|
// - "system": use current macOS appearance (light or dark)
|
||||||
// - "NSAppearanceNameAqua": use light appearance
|
// - "NSAppearanceNameAqua": use light appearance
|
||||||
// - "NSAppearanceNameDarkAqua": use dark appearance
|
// - "NSAppearanceNameDarkAqua": use dark appearance
|
||||||
|
// (needs to be set on main thread; setting it on AWT thread does not work)
|
||||||
System.setProperty( "apple.awt.application.appearance", "system" );
|
System.setProperty( "apple.awt.application.appearance", "system" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Linux
|
||||||
|
if( SystemInfo.isLinux ) {
|
||||||
|
// enable custom window decorations
|
||||||
|
JFrame.setDefaultLookAndFeelDecorated( true );
|
||||||
|
JDialog.setDefaultLookAndFeelDecorated( true );
|
||||||
|
}
|
||||||
|
|
||||||
if( FlatLafDemo.screenshotsMode && !SystemInfo.isJava_9_orLater && System.getProperty( "flatlaf.uiScale" ) == null )
|
if( FlatLafDemo.screenshotsMode && !SystemInfo.isJava_9_orLater && System.getProperty( "flatlaf.uiScale" ) == null )
|
||||||
System.setProperty( "flatlaf.uiScale", "2x" );
|
System.setProperty( "flatlaf.uiScale", "2x" );
|
||||||
|
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ public class IJThemesClassGenerator
|
|||||||
markdownTable.append( "-----|------\n" );
|
markdownTable.append( "-----|------\n" );
|
||||||
|
|
||||||
for( IJThemeInfo ti : themesManager.bundledThemes ) {
|
for( IJThemeInfo ti : themesManager.bundledThemes ) {
|
||||||
if( ti.sourceCodeUrl == null || ti.sourceCodePath == null )
|
if( ti.sourceCodeUrl == null )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
generateClass( ti, toPath, allInfos, markdownTable );
|
generateClass( ti, toPath, allInfos, markdownTable );
|
||||||
@@ -77,7 +77,7 @@ public class IJThemesClassGenerator
|
|||||||
themeName += " (Material)";
|
themeName += " (Material)";
|
||||||
|
|
||||||
StringBuilder buf = new StringBuilder();
|
StringBuilder buf = new StringBuilder();
|
||||||
for( String n : name.split( " " ) ) {
|
for( String n : name.split( "[ \\-]" ) ) {
|
||||||
if( n.length() == 0 || n.equals( "-" ) )
|
if( n.length() == 0 || n.equals( "-" ) )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|||||||
@@ -178,6 +178,13 @@
|
|||||||
"sourceCodeUrl": "https://github.com/bmikaili/intellij-monocai-theme",
|
"sourceCodeUrl": "https://github.com/bmikaili/intellij-monocai-theme",
|
||||||
"sourceCodePath": "blob/master/resources/Monocai.theme.json"
|
"sourceCodePath": "blob/master/resources/Monocai.theme.json"
|
||||||
},
|
},
|
||||||
|
"Monokai_Pro.default.theme.json": {
|
||||||
|
"name": "Monokai Pro",
|
||||||
|
"dark": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"licenseFile": "Monokai_Pro.LICENSE.txt",
|
||||||
|
"sourceCodeUrl": "https://github.com/subtheme-dev/monokai-pro"
|
||||||
|
},
|
||||||
"nord.theme.json": {
|
"nord.theme.json": {
|
||||||
"name": "Nord",
|
"name": "Nord",
|
||||||
"dark": true,
|
"dark": true,
|
||||||
@@ -225,6 +232,14 @@
|
|||||||
"sourceCodeUrl": "https://github.com/vuesion/intellij-theme",
|
"sourceCodeUrl": "https://github.com/vuesion/intellij-theme",
|
||||||
"sourceCodePath": "blob/master/resources/META-INF/vuesion_theme.theme.json"
|
"sourceCodePath": "blob/master/resources/META-INF/vuesion_theme.theme.json"
|
||||||
},
|
},
|
||||||
|
"Xcode-Dark.theme.json": {
|
||||||
|
"name": "Xcode-Dark",
|
||||||
|
"dark": true,
|
||||||
|
"license": "MIT",
|
||||||
|
"licenseFile": "Xcode-Dark.LICENSE.txt",
|
||||||
|
"sourceCodeUrl": "https://github.com/antelle/intellij-xcode-dark-theme",
|
||||||
|
"sourceCodePath": "blob/master/resources/Xcode-Dark.theme.json"
|
||||||
|
},
|
||||||
|
|
||||||
"material-theme-ui-lite/Arc Dark.theme.json": {
|
"material-theme-ui-lite/Arc Dark.theme.json": {
|
||||||
"name": "Material Theme UI Lite / Arc Dark",
|
"name": "Material Theme UI Lite / Arc Dark",
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ import javax.swing.plaf.UIResource;
|
|||||||
import javax.swing.text.JTextComponent;
|
import javax.swing.text.JTextComponent;
|
||||||
import com.formdev.flatlaf.FlatClientProperties;
|
import com.formdev.flatlaf.FlatClientProperties;
|
||||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||||
|
import com.formdev.flatlaf.ui.MigLayoutVisualPadding;
|
||||||
import com.formdev.flatlaf.util.SystemInfo;
|
import com.formdev.flatlaf.util.SystemInfo;
|
||||||
import com.formdev.flatlaf.util.UIScale;
|
import com.formdev.flatlaf.util.UIScale;
|
||||||
|
|
||||||
@@ -113,6 +114,7 @@ public class FlatInspector
|
|||||||
private int inspectParentLevel;
|
private int inspectParentLevel;
|
||||||
private boolean wasModifierKeyPressed;
|
private boolean wasModifierKeyPressed;
|
||||||
private boolean showClassHierarchy;
|
private boolean showClassHierarchy;
|
||||||
|
private long lastWhen;
|
||||||
|
|
||||||
private JComponent highlightFigure;
|
private JComponent highlightFigure;
|
||||||
private Popup popup;
|
private Popup popup;
|
||||||
@@ -131,8 +133,22 @@ public class FlatInspector
|
|||||||
(((KeyEvent)e).getModifiersEx() & KEY_MODIFIERS_MASK) == (keyStroke.getModifiers() & KEY_MODIFIERS_MASK) )
|
(((KeyEvent)e).getModifiersEx() & KEY_MODIFIERS_MASK) == (keyStroke.getModifiers() & KEY_MODIFIERS_MASK) )
|
||||||
{
|
{
|
||||||
Window activeWindow = KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow();
|
Window activeWindow = KeyboardFocusManager.getCurrentKeyboardFocusManager().getActiveWindow();
|
||||||
if( activeWindow instanceof RootPaneContainer ) {
|
RootPaneContainer rootPaneContainer = null;
|
||||||
JRootPane rootPane = ((RootPaneContainer)activeWindow).getRootPane();
|
if( activeWindow instanceof RootPaneContainer )
|
||||||
|
rootPaneContainer = (RootPaneContainer) activeWindow;
|
||||||
|
else {
|
||||||
|
// search for root pain container in children
|
||||||
|
// (e.g. for Swing embedded into SWT)
|
||||||
|
for( Component child : activeWindow.getComponents() ) {
|
||||||
|
if( child instanceof RootPaneContainer ) {
|
||||||
|
rootPaneContainer = (RootPaneContainer) child;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( rootPaneContainer != null ) {
|
||||||
|
JRootPane rootPane = rootPaneContainer.getRootPane();
|
||||||
FlatInspector inspector = (FlatInspector) rootPane.getClientProperty( FlatInspector.class );
|
FlatInspector inspector = (FlatInspector) rootPane.getClientProperty( FlatInspector.class );
|
||||||
if( inspector == null ) {
|
if( inspector == null ) {
|
||||||
inspector = new FlatInspector( rootPane );
|
inspector = new FlatInspector( rootPane );
|
||||||
@@ -172,6 +188,11 @@ public class FlatInspector
|
|||||||
if( keyCode == KeyEvent.VK_CONTROL || keyCode == KeyEvent.VK_SHIFT || keyCode == KeyEvent.VK_ALT )
|
if( keyCode == KeyEvent.VK_CONTROL || keyCode == KeyEvent.VK_SHIFT || keyCode == KeyEvent.VK_ALT )
|
||||||
wasModifierKeyPressed = true;
|
wasModifierKeyPressed = true;
|
||||||
} else if( id == KeyEvent.KEY_RELEASED && wasModifierKeyPressed ) {
|
} else if( id == KeyEvent.KEY_RELEASED && wasModifierKeyPressed ) {
|
||||||
|
// ignore duplicate events (for Swing embedded into SWT)
|
||||||
|
if( (keyEvent.getWhen() - lastWhen) <= 5 )
|
||||||
|
return;
|
||||||
|
lastWhen = keyEvent.getWhen();
|
||||||
|
|
||||||
if( keyCode == KeyEvent.VK_CONTROL ) {
|
if( keyCode == KeyEvent.VK_CONTROL ) {
|
||||||
inspectParentLevel++;
|
inspectParentLevel++;
|
||||||
int parentLevel = inspect( lastX, lastY );
|
int parentLevel = inspect( lastX, lastY );
|
||||||
@@ -464,6 +485,15 @@ public class FlatInspector
|
|||||||
if( margin != null )
|
if( margin != null )
|
||||||
appendRow( buf, "Margin", toString( margin ) );
|
appendRow( buf, "Margin", toString( margin ) );
|
||||||
|
|
||||||
|
if( c instanceof JComponent ) {
|
||||||
|
Object value = ((JComponent)c).getClientProperty( MigLayoutVisualPadding.VISUAL_PADDING_PROPERTY );
|
||||||
|
Insets visualPadding = (value instanceof int[])
|
||||||
|
? new Insets( ((int[])value)[0], ((int[])value)[1], ((int[])value)[2], ((int[])value)[3] )
|
||||||
|
: (value instanceof Insets ? (Insets) value : null);
|
||||||
|
if( visualPadding != null )
|
||||||
|
appendRow( buf, "Mig visual padding", toString( visualPadding ) );
|
||||||
|
}
|
||||||
|
|
||||||
Dimension prefSize = c.getPreferredSize();
|
Dimension prefSize = c.getPreferredSize();
|
||||||
Dimension minSize = c.getMinimumSize();
|
Dimension minSize = c.getMinimumSize();
|
||||||
Dimension maxSize = c.getMaximumSize();
|
Dimension maxSize = c.getMaximumSize();
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ package com.formdev.flatlaf.extras.components;
|
|||||||
|
|
||||||
import static com.formdev.flatlaf.FlatClientProperties.*;
|
import static com.formdev.flatlaf.FlatClientProperties.*;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import javax.swing.JToggleButton;
|
import javax.swing.*;
|
||||||
import com.formdev.flatlaf.extras.components.FlatButton.ButtonType;
|
import com.formdev.flatlaf.extras.components.FlatButton.ButtonType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -116,16 +116,37 @@ public class FlatToggleButton
|
|||||||
putClientProperty( OUTLINE, outline );
|
putClientProperty( OUTLINE, outline );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns placement of underline if toggle button type is {@link ButtonType#tab}.
|
||||||
|
* If underline placement is not specified, returns {@link #BOTTOM} as the default
|
||||||
|
* value.
|
||||||
|
*
|
||||||
|
* @since 2.3
|
||||||
|
*/
|
||||||
|
public int getTabUnderlinePlacement() {
|
||||||
|
return getClientPropertyInt( TAB_BUTTON_UNDERLINE_PLACEMENT, BOTTOM );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns height of underline if toggle button type is {@link ButtonType#tab}.
|
* Specifies placement of underline if toggle button type is {@link ButtonType#tab}.
|
||||||
|
*
|
||||||
|
* @param placement One of the following constants defined in SwingConstants:
|
||||||
|
* {@link #TOP}, {@link #LEFT}, {@link #BOTTOM}, or {@link #RIGHT}.
|
||||||
|
* @since 2.3
|
||||||
|
*/
|
||||||
|
public void setTabUnderlinePlacement( int placement ) {
|
||||||
|
putClientProperty( TAB_BUTTON_UNDERLINE_PLACEMENT, (placement >= 0) ? placement : null );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns thickness of underline if toggle button type is {@link ButtonType#tab}.
|
||||||
*/
|
*/
|
||||||
public int getTabUnderlineHeight() {
|
public int getTabUnderlineHeight() {
|
||||||
return getClientPropertyInt( TAB_BUTTON_UNDERLINE_HEIGHT, "ToggleButton.tab.underlineHeight" );
|
return getClientPropertyInt( TAB_BUTTON_UNDERLINE_HEIGHT, "ToggleButton.tab.underlineHeight" );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specifies height of underline if toggle button type is {@link ButtonType#tab}.
|
* Specifies thickness of underline if toggle button type is {@link ButtonType#tab}.
|
||||||
*/
|
*/
|
||||||
public void setTabUnderlineHeight( int tabUnderlineHeight ) {
|
public void setTabUnderlineHeight( int tabUnderlineHeight ) {
|
||||||
putClientProperty( TAB_BUTTON_UNDERLINE_HEIGHT, (tabUnderlineHeight >= 0) ? tabUnderlineHeight : null );
|
putClientProperty( TAB_BUTTON_UNDERLINE_HEIGHT, (tabUnderlineHeight >= 0) ? tabUnderlineHeight : null );
|
||||||
|
|||||||
@@ -65,12 +65,14 @@ Name | Class
|
|||||||
[Light Flat](https://github.com/nerzhulart/LightFlatTheme) | `com.formdev.flatlaf.intellijthemes.FlatLightFlatIJTheme`
|
[Light Flat](https://github.com/nerzhulart/LightFlatTheme) | `com.formdev.flatlaf.intellijthemes.FlatLightFlatIJTheme`
|
||||||
[Material Design Dark](https://github.com/xinkunZ/NotReallyMDTheme) | `com.formdev.flatlaf.intellijthemes.FlatMaterialDesignDarkIJTheme`
|
[Material Design Dark](https://github.com/xinkunZ/NotReallyMDTheme) | `com.formdev.flatlaf.intellijthemes.FlatMaterialDesignDarkIJTheme`
|
||||||
[Monocai](https://github.com/bmikaili/intellij-monocai-theme) | `com.formdev.flatlaf.intellijthemes.FlatMonocaiIJTheme`
|
[Monocai](https://github.com/bmikaili/intellij-monocai-theme) | `com.formdev.flatlaf.intellijthemes.FlatMonocaiIJTheme`
|
||||||
|
[Monokai Pro](https://github.com/subtheme-dev/monokai-pro) | `com.formdev.flatlaf.intellijthemes.FlatMonokaiProIJTheme`
|
||||||
[Nord](https://github.com/arcticicestudio/nord-jetbrains) | `com.formdev.flatlaf.intellijthemes.FlatNordIJTheme`
|
[Nord](https://github.com/arcticicestudio/nord-jetbrains) | `com.formdev.flatlaf.intellijthemes.FlatNordIJTheme`
|
||||||
[One Dark](https://github.com/one-dark/jetbrains-one-dark-theme) | `com.formdev.flatlaf.intellijthemes.FlatOneDarkIJTheme`
|
[One Dark](https://github.com/one-dark/jetbrains-one-dark-theme) | `com.formdev.flatlaf.intellijthemes.FlatOneDarkIJTheme`
|
||||||
[Solarized Dark](https://github.com/4lex4/intellij-platform-solarized) | `com.formdev.flatlaf.intellijthemes.FlatSolarizedDarkIJTheme`
|
[Solarized Dark](https://github.com/4lex4/intellij-platform-solarized) | `com.formdev.flatlaf.intellijthemes.FlatSolarizedDarkIJTheme`
|
||||||
[Solarized Light](https://github.com/4lex4/intellij-platform-solarized) | `com.formdev.flatlaf.intellijthemes.FlatSolarizedLightIJTheme`
|
[Solarized Light](https://github.com/4lex4/intellij-platform-solarized) | `com.formdev.flatlaf.intellijthemes.FlatSolarizedLightIJTheme`
|
||||||
[Spacegray](https://github.com/mturlo/intellij-spacegray) | `com.formdev.flatlaf.intellijthemes.FlatSpacegrayIJTheme`
|
[Spacegray](https://github.com/mturlo/intellij-spacegray) | `com.formdev.flatlaf.intellijthemes.FlatSpacegrayIJTheme`
|
||||||
[Vuesion](https://github.com/vuesion/intellij-theme) | `com.formdev.flatlaf.intellijthemes.FlatVuesionIJTheme`
|
[Vuesion](https://github.com/vuesion/intellij-theme) | `com.formdev.flatlaf.intellijthemes.FlatVuesionIJTheme`
|
||||||
|
[Xcode-Dark](https://github.com/antelle/intellij-xcode-dark-theme) | `com.formdev.flatlaf.intellijthemes.FlatXcodeDarkIJTheme`
|
||||||
|
|
||||||
Material Theme UI Lite:
|
Material Theme UI Lite:
|
||||||
|
|
||||||
|
|||||||
@@ -52,12 +52,14 @@ public class FlatAllIJThemes
|
|||||||
new FlatIJLookAndFeelInfo( "Light Flat", "com.formdev.flatlaf.intellijthemes.FlatLightFlatIJTheme", false ),
|
new FlatIJLookAndFeelInfo( "Light Flat", "com.formdev.flatlaf.intellijthemes.FlatLightFlatIJTheme", false ),
|
||||||
new FlatIJLookAndFeelInfo( "Material Design Dark", "com.formdev.flatlaf.intellijthemes.FlatMaterialDesignDarkIJTheme", true ),
|
new FlatIJLookAndFeelInfo( "Material Design Dark", "com.formdev.flatlaf.intellijthemes.FlatMaterialDesignDarkIJTheme", true ),
|
||||||
new FlatIJLookAndFeelInfo( "Monocai", "com.formdev.flatlaf.intellijthemes.FlatMonocaiIJTheme", true ),
|
new FlatIJLookAndFeelInfo( "Monocai", "com.formdev.flatlaf.intellijthemes.FlatMonocaiIJTheme", true ),
|
||||||
|
new FlatIJLookAndFeelInfo( "Monokai Pro", "com.formdev.flatlaf.intellijthemes.FlatMonokaiProIJTheme", true ),
|
||||||
new FlatIJLookAndFeelInfo( "Nord", "com.formdev.flatlaf.intellijthemes.FlatNordIJTheme", true ),
|
new FlatIJLookAndFeelInfo( "Nord", "com.formdev.flatlaf.intellijthemes.FlatNordIJTheme", true ),
|
||||||
new FlatIJLookAndFeelInfo( "One Dark", "com.formdev.flatlaf.intellijthemes.FlatOneDarkIJTheme", true ),
|
new FlatIJLookAndFeelInfo( "One Dark", "com.formdev.flatlaf.intellijthemes.FlatOneDarkIJTheme", true ),
|
||||||
new FlatIJLookAndFeelInfo( "Solarized Dark", "com.formdev.flatlaf.intellijthemes.FlatSolarizedDarkIJTheme", true ),
|
new FlatIJLookAndFeelInfo( "Solarized Dark", "com.formdev.flatlaf.intellijthemes.FlatSolarizedDarkIJTheme", true ),
|
||||||
new FlatIJLookAndFeelInfo( "Solarized Light", "com.formdev.flatlaf.intellijthemes.FlatSolarizedLightIJTheme", false ),
|
new FlatIJLookAndFeelInfo( "Solarized Light", "com.formdev.flatlaf.intellijthemes.FlatSolarizedLightIJTheme", false ),
|
||||||
new FlatIJLookAndFeelInfo( "Spacegray", "com.formdev.flatlaf.intellijthemes.FlatSpacegrayIJTheme", true ),
|
new FlatIJLookAndFeelInfo( "Spacegray", "com.formdev.flatlaf.intellijthemes.FlatSpacegrayIJTheme", true ),
|
||||||
new FlatIJLookAndFeelInfo( "Vuesion", "com.formdev.flatlaf.intellijthemes.FlatVuesionIJTheme", true ),
|
new FlatIJLookAndFeelInfo( "Vuesion", "com.formdev.flatlaf.intellijthemes.FlatVuesionIJTheme", true ),
|
||||||
|
new FlatIJLookAndFeelInfo( "Xcode-Dark", "com.formdev.flatlaf.intellijthemes.FlatXcodeDarkIJTheme", true ),
|
||||||
new FlatIJLookAndFeelInfo( "Arc Dark (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatArcDarkIJTheme", true ),
|
new FlatIJLookAndFeelInfo( "Arc Dark (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatArcDarkIJTheme", true ),
|
||||||
new FlatIJLookAndFeelInfo( "Arc Dark Contrast (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatArcDarkContrastIJTheme", true ),
|
new FlatIJLookAndFeelInfo( "Arc Dark Contrast (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatArcDarkContrastIJTheme", true ),
|
||||||
new FlatIJLookAndFeelInfo( "Atom One Dark (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatAtomOneDarkIJTheme", true ),
|
new FlatIJLookAndFeelInfo( "Atom One Dark (Material)", "com.formdev.flatlaf.intellijthemes.materialthemeuilite.FlatAtomOneDarkIJTheme", true ),
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 FormDev Software GmbH
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.formdev.flatlaf.intellijthemes;
|
||||||
|
|
||||||
|
//
|
||||||
|
// DO NOT MODIFY
|
||||||
|
// Generated with com.formdev.flatlaf.demo.intellijthemes.IJThemesClassGenerator
|
||||||
|
//
|
||||||
|
|
||||||
|
import com.formdev.flatlaf.IntelliJTheme;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Karl Tauber
|
||||||
|
*/
|
||||||
|
public class FlatMonokaiProIJTheme
|
||||||
|
extends IntelliJTheme.ThemeLaf
|
||||||
|
{
|
||||||
|
public static final String NAME = "Monokai Pro";
|
||||||
|
|
||||||
|
public static boolean setup() {
|
||||||
|
try {
|
||||||
|
return setup( new FlatMonokaiProIJTheme() );
|
||||||
|
} catch( RuntimeException ex ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void installLafInfo() {
|
||||||
|
installLafInfo( NAME, FlatMonokaiProIJTheme.class );
|
||||||
|
}
|
||||||
|
|
||||||
|
public FlatMonokaiProIJTheme() {
|
||||||
|
super( Utils.loadTheme( "Monokai_Pro.default.theme.json" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return NAME;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2020 FormDev Software GmbH
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.formdev.flatlaf.intellijthemes;
|
||||||
|
|
||||||
|
//
|
||||||
|
// DO NOT MODIFY
|
||||||
|
// Generated with com.formdev.flatlaf.demo.intellijthemes.IJThemesClassGenerator
|
||||||
|
//
|
||||||
|
|
||||||
|
import com.formdev.flatlaf.IntelliJTheme;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Karl Tauber
|
||||||
|
*/
|
||||||
|
public class FlatXcodeDarkIJTheme
|
||||||
|
extends IntelliJTheme.ThemeLaf
|
||||||
|
{
|
||||||
|
public static final String NAME = "Xcode-Dark";
|
||||||
|
|
||||||
|
public static boolean setup() {
|
||||||
|
try {
|
||||||
|
return setup( new FlatXcodeDarkIJTheme() );
|
||||||
|
} catch( RuntimeException ex ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void installLafInfo() {
|
||||||
|
installLafInfo( NAME, FlatXcodeDarkIJTheme.class );
|
||||||
|
}
|
||||||
|
|
||||||
|
public FlatXcodeDarkIJTheme() {
|
||||||
|
super( Utils.loadTheme( "Xcode-Dark.theme.json" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return NAME;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -127,7 +127,11 @@
|
|||||||
"secondaryForeground": "#7ac2cc"
|
"secondaryForeground": "#7ac2cc"
|
||||||
},
|
},
|
||||||
|
|
||||||
"List.background": "#eef0f4",
|
"List": {
|
||||||
|
"background": "#eef0f4",
|
||||||
|
"hoverBackground": "#dae6eb",
|
||||||
|
"hoverInactiveBackground": "#dae6eb"
|
||||||
|
},
|
||||||
|
|
||||||
"Notification": {
|
"Notification": {
|
||||||
"MoreButton.innerBorderColor": "#bec5cd",
|
"MoreButton.innerBorderColor": "#bec5cd",
|
||||||
@@ -143,6 +147,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"NotificationsToolwindow": {
|
||||||
|
"newNotification.background": "#dae6ebB3",
|
||||||
|
"newNotification.hoverBackground": "#dae6eb",
|
||||||
|
"Notification.hoverBackground": "#dae6eb"
|
||||||
|
},
|
||||||
|
|
||||||
"PasswordField.background": "#FFFFFF",
|
"PasswordField.background": "#FFFFFF",
|
||||||
|
|
||||||
"Plugins": {
|
"Plugins": {
|
||||||
@@ -151,7 +161,8 @@
|
|||||||
"SectionHeader.foreground": "#808080",
|
"SectionHeader.foreground": "#808080",
|
||||||
"SectionHeader.background": "#edeef2",
|
"SectionHeader.background": "#edeef2",
|
||||||
"Tab.selectedBackground": "#cacccf",
|
"Tab.selectedBackground": "#cacccf",
|
||||||
"Tab.hoverBackground": "#cacccf"
|
"Tab.hoverBackground": "#cacccf",
|
||||||
|
"hoverBackground": "#e6eef2"
|
||||||
},
|
},
|
||||||
|
|
||||||
"Popup": {
|
"Popup": {
|
||||||
@@ -249,7 +260,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
"Tree.background": "#eef0f4",
|
"Tree": {
|
||||||
|
"background": "#eef0f4",
|
||||||
|
"hoverBackground": "#dae6eb",
|
||||||
|
"hoverInactiveBackground": "#dae6eb",
|
||||||
|
"hash": "#d0d5db"
|
||||||
|
},
|
||||||
|
|
||||||
"WelcomeScreen": {
|
"WelcomeScreen": {
|
||||||
"Details.background": "#eef0f4",
|
"Details.background": "#eef0f4",
|
||||||
|
|||||||
@@ -120,7 +120,8 @@
|
|||||||
"DefaultTabs": {
|
"DefaultTabs": {
|
||||||
"underlineColor": "#9649cc",
|
"underlineColor": "#9649cc",
|
||||||
"inactiveUnderlineColor": "#877399",
|
"inactiveUnderlineColor": "#877399",
|
||||||
"hoverBackground": "#dfb3ff1a"
|
"hoverBackground": "#dfb3ff1a",
|
||||||
|
"borderColor": "#1a1721"
|
||||||
},
|
},
|
||||||
|
|
||||||
"DragAndDrop": {
|
"DragAndDrop": {
|
||||||
@@ -168,6 +169,11 @@
|
|||||||
"visitedForeground": "#7094FF"
|
"visitedForeground": "#7094FF"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"List": {
|
||||||
|
"hoverBackground": "#00000033",
|
||||||
|
"hoverInactiveBackground": "#00000033"
|
||||||
|
},
|
||||||
|
|
||||||
"MenuBar.borderColor": "#1a1721",
|
"MenuBar.borderColor": "#1a1721",
|
||||||
|
|
||||||
"NavBar.borderColor": "#1a1721",
|
"NavBar.borderColor": "#1a1721",
|
||||||
@@ -197,6 +203,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"NotificationsToolwindow": {
|
||||||
|
"newNotification.background": "#3D3952B3",
|
||||||
|
"newNotification.hoverBackground": "#3D3952",
|
||||||
|
"Notification.hoverBackground": "#3D3952"
|
||||||
|
},
|
||||||
|
|
||||||
"MemoryIndicator": {
|
"MemoryIndicator": {
|
||||||
"allocatedBackground": "#352140",
|
"allocatedBackground": "#352140",
|
||||||
"usedBackground": "#533473"
|
"usedBackground": "#533473"
|
||||||
@@ -211,6 +223,8 @@
|
|||||||
},
|
},
|
||||||
|
|
||||||
"Plugins": {
|
"Plugins": {
|
||||||
|
"hoverBackground": "#00000022",
|
||||||
|
|
||||||
"Tab": {
|
"Tab": {
|
||||||
"selectedForeground": "#D0D0D9",
|
"selectedForeground": "#D0D0D9",
|
||||||
"selectedBackground": "#593f73",
|
"selectedBackground": "#593f73",
|
||||||
@@ -284,6 +298,13 @@
|
|||||||
|
|
||||||
"SearchOption.selectedBackground": "#424885",
|
"SearchOption.selectedBackground": "#424885",
|
||||||
|
|
||||||
|
"SegmentedButton": {
|
||||||
|
"selectedButtonColor": "#45405C",
|
||||||
|
"focusedSelectedButtonColor": "#693687",
|
||||||
|
"selectedStartBorderColor": "#4E4C63",
|
||||||
|
"selectedEndBorderColor": "#4E4C63"
|
||||||
|
},
|
||||||
|
|
||||||
"SpeedSearch": {
|
"SpeedSearch": {
|
||||||
"foreground": "#D0D0D9",
|
"foreground": "#D0D0D9",
|
||||||
"borderColor": "#69418c",
|
"borderColor": "#69418c",
|
||||||
@@ -310,7 +331,8 @@
|
|||||||
|
|
||||||
"Table": {
|
"Table": {
|
||||||
"stripeColor": "#323242",
|
"stripeColor": "#323242",
|
||||||
"hoverBackground": "#00000028"
|
"hoverBackground": "#00000028",
|
||||||
|
"gridColor": "#1a1721"
|
||||||
},
|
},
|
||||||
|
|
||||||
"TextArea": {
|
"TextArea": {
|
||||||
@@ -360,7 +382,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
"Tree.rowHeight": 20,
|
"Tree": {
|
||||||
|
"rowHeight": 20,
|
||||||
|
"hash": "#4E4C63",
|
||||||
|
"hoverBackground": "#00000033",
|
||||||
|
"hoverInactiveBackground": "#00000033"
|
||||||
|
},
|
||||||
|
|
||||||
"ValidationTooltip": {
|
"ValidationTooltip": {
|
||||||
"errorBackground": "#802d43",
|
"errorBackground": "#802d43",
|
||||||
|
|||||||
@@ -38,6 +38,26 @@
|
|||||||
"pressedBackground": "hoverBackground",
|
"pressedBackground": "hoverBackground",
|
||||||
"pressedBorderColor": "hoverBackground"
|
"pressedBorderColor": "hoverBackground"
|
||||||
},
|
},
|
||||||
|
"Bookmark": {
|
||||||
|
"iconBackground": "accentColor",
|
||||||
|
"Mnemonic": {
|
||||||
|
"iconForeground": "primaryForeground",
|
||||||
|
"iconBackground": "#8d6b81",
|
||||||
|
"iconBorderColor": "accentColor"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"BookmarkMnemonicAssigned": {
|
||||||
|
"foreground": "primaryForeground",
|
||||||
|
"background": "#786299",
|
||||||
|
"borderColor": "secondaryAccentColor"
|
||||||
|
},
|
||||||
|
"BookmarkMnemonicAvailable": {
|
||||||
|
},
|
||||||
|
"BookmarkMnemonicCurrent": {
|
||||||
|
"foreground": "primaryForeground",
|
||||||
|
"background": "#8d6b81",
|
||||||
|
"borderColor": "accentColor"
|
||||||
|
},
|
||||||
"Button": {
|
"Button": {
|
||||||
"foreground": "primaryForeground",
|
"foreground": "primaryForeground",
|
||||||
"startBorderColor": "selectionBackground",
|
"startBorderColor": "selectionBackground",
|
||||||
@@ -90,7 +110,7 @@
|
|||||||
"inactiveWarningFocusColor": "#f1fa8c"
|
"inactiveWarningFocusColor": "#f1fa8c"
|
||||||
},
|
},
|
||||||
"DragAndDrop": {
|
"DragAndDrop": {
|
||||||
"areaBorderColor": "selectionBackground"
|
"borderColor": "selectionBackground"
|
||||||
},
|
},
|
||||||
"Editor": {
|
"Editor": {
|
||||||
"background": "secondaryBackground",
|
"background": "secondaryBackground",
|
||||||
|
|||||||
@@ -111,6 +111,11 @@
|
|||||||
"secondaryForeground": "#77a8d9"
|
"secondaryForeground": "#77a8d9"
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"List": {
|
||||||
|
"hoverBackground": "#00000010",
|
||||||
|
"hoverInactiveBackground": "#00000010"
|
||||||
|
},
|
||||||
|
|
||||||
"Notification": {
|
"Notification": {
|
||||||
"background": "#f7f8fa",
|
"background": "#f7f8fa",
|
||||||
"borderColor": "#D4D6D9",
|
"borderColor": "#D4D6D9",
|
||||||
@@ -131,6 +136,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"NotificationsToolwindow": {
|
||||||
|
"newNotification.background": "#dae9f7B3",
|
||||||
|
"newNotification.hoverBackground": "#00000009",
|
||||||
|
"Notification.hoverBackground": "#00000009"
|
||||||
|
},
|
||||||
|
|
||||||
"PasswordField.background": "#FFFFFF",
|
"PasswordField.background": "#FFFFFF",
|
||||||
|
|
||||||
"Plugins": {
|
"Plugins": {
|
||||||
@@ -140,7 +151,7 @@
|
|||||||
"Tab.selectedBackground": "#D5D6D7",
|
"Tab.selectedBackground": "#D5D6D7",
|
||||||
"Tab.hoverBackground": "#D5D6D7",
|
"Tab.hoverBackground": "#D5D6D7",
|
||||||
"lightSelectionBackground": "#E9EFF7",
|
"lightSelectionBackground": "#E9EFF7",
|
||||||
"hoverBackground": "#f7faff"
|
"hoverBackground": "#F8F8F8"
|
||||||
},
|
},
|
||||||
|
|
||||||
"Popup": {
|
"Popup": {
|
||||||
@@ -225,7 +236,11 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
"Tree.rowHeight": 22,
|
"Tree": {
|
||||||
|
"rowHeight": 22,
|
||||||
|
"hoverBackground": "#00000010",
|
||||||
|
"hoverInactiveBackground": "#00000010"
|
||||||
|
},
|
||||||
|
|
||||||
"VersionControl": {
|
"VersionControl": {
|
||||||
"Log.Commit.currentBranchBackground": "#e6f0f2",
|
"Log.Commit.currentBranchBackground": "#e6f0f2",
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
@@ -0,0 +1,684 @@
|
|||||||
|
{
|
||||||
|
"name": "Monokai Pro",
|
||||||
|
"dark": true,
|
||||||
|
"author": "Subtheme",
|
||||||
|
"editorScheme": "/schemes/default.xml",
|
||||||
|
"ui": {
|
||||||
|
"*": {
|
||||||
|
"acceleratorSelectionForeground": "#ffd866",
|
||||||
|
"background": "#2d2a2e",
|
||||||
|
"borderColor": "#363337",
|
||||||
|
"disabledBackground": "#221f22",
|
||||||
|
"disabledForeground": "#5b595c",
|
||||||
|
"disabledText": "#5b595c",
|
||||||
|
"focusColor": "#5b595c",
|
||||||
|
"focusedBorderColor": "#ffd866",
|
||||||
|
"foreground": "#fcfcfa",
|
||||||
|
"inactiveBackground": "#221f22",
|
||||||
|
"inactiveForeground": "#939293",
|
||||||
|
"infoForeground": "#939293",
|
||||||
|
"selectionBackground": "#403e41",
|
||||||
|
"selectionBackgroundInactive": "#403e41",
|
||||||
|
"selectionForeground": "#ffd866",
|
||||||
|
"selectionInactiveBackground": "#403e41",
|
||||||
|
"selectionInactiveForeground": "#ffd866",
|
||||||
|
"separatorColor": "#2d2a2e"
|
||||||
|
},
|
||||||
|
"ActionButton": {
|
||||||
|
"hoverBackground": "#363337",
|
||||||
|
"hoverBorderColor": "#363337",
|
||||||
|
"pressedBackground": "#363337",
|
||||||
|
"pressedBorderColor": "#363337"
|
||||||
|
},
|
||||||
|
"Borders": {
|
||||||
|
"ContrastBorderColor": "#363337",
|
||||||
|
"color": "#363337"
|
||||||
|
},
|
||||||
|
"Button": {
|
||||||
|
"arc": 0,
|
||||||
|
"background": "#403e41",
|
||||||
|
"default": {
|
||||||
|
"endBackground": "#403e41",
|
||||||
|
"endBorderColor": "#403e41",
|
||||||
|
"foreground": "#ffd866",
|
||||||
|
"focusColor": "#ffd866",
|
||||||
|
"focusedBorderColor": "#403e41",
|
||||||
|
"shadowColor": "#403e41",
|
||||||
|
"startBackground": "#403e41",
|
||||||
|
"startBorderColor": "#403e41"
|
||||||
|
},
|
||||||
|
"disabledBorderColor": "#403e41",
|
||||||
|
"disabledText": "#5b595c",
|
||||||
|
"endBackground": "#403e41",
|
||||||
|
"endBorderColor": "#403e41",
|
||||||
|
"focusedBorderColor": "#403e41",
|
||||||
|
"foreground": "#fcfcfa",
|
||||||
|
"shadowColor": "#403e41",
|
||||||
|
"shadowWidth": 0,
|
||||||
|
"startBackground": "#403e41",
|
||||||
|
"startBorderColor": "#403e41"
|
||||||
|
},
|
||||||
|
"CheckBox": {
|
||||||
|
"background": "#2d2a2e",
|
||||||
|
"disabledText": "#5b595c",
|
||||||
|
"foreground": "#fcfcfa",
|
||||||
|
"select": "#ffd866"
|
||||||
|
},
|
||||||
|
"CheckBoxMenuItem": {
|
||||||
|
"acceleratorForeground": "#939293",
|
||||||
|
"acceleratorSelectionForeground": "#939293",
|
||||||
|
"background": "#2d2a2e",
|
||||||
|
"disabledBackground": "#2d2a2e",
|
||||||
|
"disabledForeground": "#5b595c",
|
||||||
|
"foreground": "#fcfcfa",
|
||||||
|
"selectionBackground": "#403e41",
|
||||||
|
"selectionForeground": "#ffd866"
|
||||||
|
},
|
||||||
|
"ColorChooser": {
|
||||||
|
"background": "#2d2a2e",
|
||||||
|
"foreground": "#fcfcfa",
|
||||||
|
"swatchesDefaultRecentColor": "#fcfcfa"
|
||||||
|
},
|
||||||
|
"ComboBoxButton": {
|
||||||
|
"background": "#363337"
|
||||||
|
},
|
||||||
|
"ComboBox": {
|
||||||
|
"ArrowButton": {
|
||||||
|
"background": "#403e41",
|
||||||
|
"disabledIconColor": "#5b595c",
|
||||||
|
"iconColor": "#fcfcfa",
|
||||||
|
"nonEditableBackground": "#2d2a2e"
|
||||||
|
},
|
||||||
|
"background": "#363337",
|
||||||
|
"disabledBackground": "#221f22",
|
||||||
|
"disabledForeground": "#5b595c",
|
||||||
|
"foreground": "#fcfcfa",
|
||||||
|
"modifiedItemForeground": "#ffd866",
|
||||||
|
"nonEditableBackground": "#363337",
|
||||||
|
"selectionBackground": "#2d2a2e",
|
||||||
|
"selectionForeground": "#ffd866"
|
||||||
|
},
|
||||||
|
"ComboPopup": {
|
||||||
|
"border": "#2d2a2e"
|
||||||
|
},
|
||||||
|
"CompletionPopup": {
|
||||||
|
"foreground": "#fcfcfa",
|
||||||
|
"matchForeground": "#ffd866",
|
||||||
|
"selectionInactiveBackground": "#2d2a2e",
|
||||||
|
"selectionBackground": "#2d2a2e"
|
||||||
|
},
|
||||||
|
"Component": {
|
||||||
|
"arc": 4,
|
||||||
|
"borderColor": "#363337",
|
||||||
|
"disabledBorderColor": "#363337",
|
||||||
|
"focusColor": "#ffd866",
|
||||||
|
"focusedBorderColor": "#ffd866",
|
||||||
|
"hoverIconColor": "#ffd866",
|
||||||
|
"infoForeground": "#939293",
|
||||||
|
"iconColor": "#fcfcfa"
|
||||||
|
},
|
||||||
|
"Counter": {
|
||||||
|
"background": "#ffd866",
|
||||||
|
"foreground": "#19181a"
|
||||||
|
},
|
||||||
|
"Debugger": {
|
||||||
|
"Variables": {
|
||||||
|
"collectingDataForeground": "#939293",
|
||||||
|
"changedValueForeground": "#ffd866",
|
||||||
|
"errorMessageForeground": "#ff6188",
|
||||||
|
"evaluatingExpressionForeground": "#939293",
|
||||||
|
"exceptionForeground": "#78dce8",
|
||||||
|
"modifyingValueForeground": "#ffd866",
|
||||||
|
"valueForeground": "#ffd866"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"DebuggerTabs": {
|
||||||
|
"underlinedTabBackground": "#5b595c"
|
||||||
|
},
|
||||||
|
"DebuggerPopup": {
|
||||||
|
"borderColor": "#5b595c"
|
||||||
|
},
|
||||||
|
"DefaultTabs": {
|
||||||
|
"background": "#2d2a2e",
|
||||||
|
"borderColor": "#2d2a2e",
|
||||||
|
"hoverBackground": "#363337",
|
||||||
|
"inactiveUnderlineColor": "#ffd866",
|
||||||
|
"underlineColor": "#ffd866",
|
||||||
|
"underlinedTabBackground": "#2d2a2e",
|
||||||
|
"underlineHeight": 2
|
||||||
|
},
|
||||||
|
"DragAndDrop": {
|
||||||
|
"areaBackground": "#2d2a2e",
|
||||||
|
"areaBorderColor": "#2d2a2e",
|
||||||
|
"areaForeground": "#fcfcfa"
|
||||||
|
},
|
||||||
|
"Editor": {
|
||||||
|
"background": "#221f22",
|
||||||
|
"foreground": "#fcfcfa",
|
||||||
|
"shortcutForeground": "#939293"
|
||||||
|
},
|
||||||
|
"EditorPane": {
|
||||||
|
"background": "#221f22",
|
||||||
|
"caretForeground": "#ffd866",
|
||||||
|
"foreground": "#fcfcfa",
|
||||||
|
"inactiveBackground": "#2d2a2e",
|
||||||
|
"inactiveForeground": "#5b595c",
|
||||||
|
"selectionBackground": "#403e41",
|
||||||
|
"selectionForeground": "#ffd866"
|
||||||
|
},
|
||||||
|
"EditorTabs": {
|
||||||
|
"borderColor": "#363337",
|
||||||
|
"inactiveUnderlineColor": "#ffd866",
|
||||||
|
"underlineColor": "#ffd866",
|
||||||
|
"underlinedTabBackground": "#363337",
|
||||||
|
"underlinedTabForeground": "#c1c0c0"
|
||||||
|
},
|
||||||
|
"FileColor": {
|
||||||
|
"Yellow": "00000000"
|
||||||
|
},
|
||||||
|
"FormattedTextField": {
|
||||||
|
"background": "#363337",
|
||||||
|
"caretForeground": "#ffd866",
|
||||||
|
"foreground": "#fcfcfa",
|
||||||
|
"inactiveBackground": "#403e41",
|
||||||
|
"inactiveForeground": "#5b595c",
|
||||||
|
"selectionForeground": "#ffd866",
|
||||||
|
"selectionBackground": "#403e41"
|
||||||
|
},
|
||||||
|
"Group": {
|
||||||
|
"disabledSeparatorColor": "#2d2a2e",
|
||||||
|
"separatorColor": "#2d2a2e"
|
||||||
|
},
|
||||||
|
"GutterTooltip": {
|
||||||
|
"infoForeground": "#fcfcfa",
|
||||||
|
"lineSeparatorColor": "#2d2a2e"
|
||||||
|
},
|
||||||
|
"HelpTooltip": {
|
||||||
|
"borderColor": "#2d2a2e",
|
||||||
|
"infoForeground": "#939293"
|
||||||
|
},
|
||||||
|
"InformationHint": {
|
||||||
|
"borderColor": "#2d2a2e"
|
||||||
|
},
|
||||||
|
"InplaceRefactoringPopup": {
|
||||||
|
"borderColor": "#2d2a2e"
|
||||||
|
},
|
||||||
|
"Label": {
|
||||||
|
"background": "#2d2a2e",
|
||||||
|
"disabledForeground": "#5b595c",
|
||||||
|
"disabledText": "#5b595c",
|
||||||
|
"foreground": "#939293",
|
||||||
|
"infoForeground": "#939293",
|
||||||
|
"selectedForeground": "#ffd866"
|
||||||
|
},
|
||||||
|
"Link": {
|
||||||
|
"activeForeground": "#ffd866",
|
||||||
|
"hoverForeground": "#ffd866",
|
||||||
|
"pressedForeground": "#ffd866",
|
||||||
|
"secondaryForeground": "#939293",
|
||||||
|
"visitedForeground": "#ffd866"
|
||||||
|
},
|
||||||
|
"List": {
|
||||||
|
"background": "#221f22",
|
||||||
|
"foreground": "#fcfcfa",
|
||||||
|
"selectionBackground": "#363337",
|
||||||
|
"selectionForeground": "#ffd866",
|
||||||
|
"selectionInactiveBackground": "#363337",
|
||||||
|
"selectionInactiveForeground": "#ffd866"
|
||||||
|
},
|
||||||
|
"MemoryIndicator": {
|
||||||
|
"allocatedBackground": "#403e41",
|
||||||
|
"usedBackground": "#5b595c"
|
||||||
|
},
|
||||||
|
"Menu": {
|
||||||
|
"acceleratorForeground": "#939293",
|
||||||
|
"acceleratorSelectionForeground": "#fcfcfa",
|
||||||
|
"background": "#2d2a2e",
|
||||||
|
"borderColor": "#363337",
|
||||||
|
"disabledBackground": "#403e41",
|
||||||
|
"disabledForeground": "#5b595c",
|
||||||
|
"foreground": "#fcfcfa",
|
||||||
|
"separatorColor": "#2d2a2e",
|
||||||
|
"selectionForeground": "#ffd866"
|
||||||
|
},
|
||||||
|
"MenuBar": {
|
||||||
|
"borderColor": "#363337",
|
||||||
|
"disabledBackground": "#2d2a2e",
|
||||||
|
"disabledForeground": "#5b595c",
|
||||||
|
"foreground": "#fcfcfa",
|
||||||
|
"highlight": "#2d2a2e",
|
||||||
|
"selectionBackground": "#403e41",
|
||||||
|
"selectionForeground": "#ffd866",
|
||||||
|
"shadow": "#221f22"
|
||||||
|
},
|
||||||
|
"MenuItem": {
|
||||||
|
"acceleratorForeground": "#939293",
|
||||||
|
"background": "#2d2a2e",
|
||||||
|
"disabledBackground": "#2d2a2e",
|
||||||
|
"disabledForeground": "#5b595c",
|
||||||
|
"foreground": "#fcfcfa",
|
||||||
|
"selectionBackground": "#403e41",
|
||||||
|
"selectionForeground": "#ffd866"
|
||||||
|
},
|
||||||
|
"NavBar": {
|
||||||
|
"borderColor": "#363337"
|
||||||
|
},
|
||||||
|
"Notification": {
|
||||||
|
"background": "#363337",
|
||||||
|
"borderColor": "#221f22",
|
||||||
|
"errorBackground": "#221f22",
|
||||||
|
"errorBorderColor": "#221f22",
|
||||||
|
"foreground": "#fcfcfa",
|
||||||
|
"MoreButton": {
|
||||||
|
"background": "#403e41",
|
||||||
|
"foreground": "#fcfcfa",
|
||||||
|
"innerBorderColor": "#363337"
|
||||||
|
},
|
||||||
|
"ToolWindow": {
|
||||||
|
"errorBackground": "#363337",
|
||||||
|
"errorBorderColor": "#363337",
|
||||||
|
"informativeBackground": "#363337",
|
||||||
|
"informativeBorderColor": "#363337",
|
||||||
|
"warningBackground": "#363337",
|
||||||
|
"warningBorderColor": "#363337"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"OptionPane": {
|
||||||
|
"background": "#2d2a2e",
|
||||||
|
"foreground": "#fcfcfa",
|
||||||
|
"messageForeground": "#fcfcfa"
|
||||||
|
},
|
||||||
|
"Panel": {
|
||||||
|
"background": "#2d2a2e",
|
||||||
|
"foreground": "#939293"
|
||||||
|
},
|
||||||
|
"ParameterInfo": {
|
||||||
|
"background": "#403e41",
|
||||||
|
"borderColor": "#363337",
|
||||||
|
"currentOverloadBackground": "#403e41",
|
||||||
|
"currentParameterForeground": "#ffd866",
|
||||||
|
"disabledForeground": "#5b595c",
|
||||||
|
"foreground": "#fcfcfa",
|
||||||
|
"infoForeground": "#939293",
|
||||||
|
"lineSeparatorColor": "#363337"
|
||||||
|
},
|
||||||
|
"PasswordField": {
|
||||||
|
"background": "#403e41",
|
||||||
|
"capsLockIconColor": "#ffd866",
|
||||||
|
"caretForeground": "#ffd866",
|
||||||
|
"foreground": "#fcfcfa",
|
||||||
|
"inactiveForeground": "#5b595c",
|
||||||
|
"selectionBackground": "#5b595c",
|
||||||
|
"selectionForeground": "#ffd866"
|
||||||
|
},
|
||||||
|
"Plugins": {
|
||||||
|
"background": "#2d2a2e",
|
||||||
|
"disabledForeground": "#939293",
|
||||||
|
"eapTagBackground": "#5b595c",
|
||||||
|
"lightSelectionBackground": "#363337",
|
||||||
|
"hoverBackground": "#363337",
|
||||||
|
"tagForeground": "#ffd866",
|
||||||
|
"tagBackground": "#5b595c",
|
||||||
|
"Button": {
|
||||||
|
"installBackground": "#221f22",
|
||||||
|
"installBorderColor": "#221f22",
|
||||||
|
"installForeground": "#fcfcfa",
|
||||||
|
"installFocusedBackground": "#221f22",
|
||||||
|
"installFillForeground": "#939293",
|
||||||
|
"installFillBackground": "#221f22",
|
||||||
|
"updateBackground": "#221f22",
|
||||||
|
"updateBorderColor": "#221f22",
|
||||||
|
"updateForeground": "#fcfcfa"
|
||||||
|
},
|
||||||
|
"SearchField": {
|
||||||
|
"background": "#363337",
|
||||||
|
"borderColor": "#363337"
|
||||||
|
},
|
||||||
|
"SectionHeader": {
|
||||||
|
"background": "#2d2a2e",
|
||||||
|
"foreground": "#939293"
|
||||||
|
},
|
||||||
|
"Tab": {
|
||||||
|
"hoverBackground": "#363337",
|
||||||
|
"selectedForeground": "#fcfcfa",
|
||||||
|
"selectedBackground": "#363337"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Popup": {
|
||||||
|
"Advertiser": {
|
||||||
|
"background": "#2d2a2e",
|
||||||
|
"borderColor": "#2d2a2e",
|
||||||
|
"foreground": "#ffd866"
|
||||||
|
},
|
||||||
|
"borderColor": "#221f22",
|
||||||
|
"inactiveBorderColor": "#2d2a2e",
|
||||||
|
"innerBorderColor": "#2d2a2e",
|
||||||
|
"Header": {
|
||||||
|
"activeBackground": "#2d2a2e",
|
||||||
|
"inactiveBackground": "#221f22"
|
||||||
|
},
|
||||||
|
"paintBorder": true,
|
||||||
|
"separatorForeground": "#fcfcfa",
|
||||||
|
"separatorColor": "#2d2a2e",
|
||||||
|
"Toolbar": {
|
||||||
|
"background": "#221f22",
|
||||||
|
"borderColor": "#363337"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"PopupMenu": {
|
||||||
|
"background": "#2d2a2e",
|
||||||
|
"foreground": "#fcfcfa",
|
||||||
|
"translucentBackground": "#2d2a2e",
|
||||||
|
"selectionBackground": "#403e41"
|
||||||
|
},
|
||||||
|
"PopupMenuSeparator": {
|
||||||
|
"height": 10,
|
||||||
|
"stripeIndent": 5
|
||||||
|
},
|
||||||
|
"ProgressBar": {
|
||||||
|
"background": "#2d2a2e",
|
||||||
|
"foreground": "#ffd866",
|
||||||
|
"indeterminateEndColor": "#ffd866",
|
||||||
|
"indeterminateStartColor": "#ffd866",
|
||||||
|
"progressColor": "#ffd866",
|
||||||
|
"selectionBackground": "#5b595c",
|
||||||
|
"trackColor": "#5b595c"
|
||||||
|
},
|
||||||
|
"RadioButton": {
|
||||||
|
"background": "#2d2a2e",
|
||||||
|
"disabledText": "#5b595c",
|
||||||
|
"foreground": "#fcfcfa"
|
||||||
|
},
|
||||||
|
"RadioButtonMenuItem": {
|
||||||
|
"acceleratorForeground": "#939293",
|
||||||
|
"acceleratorSelectionForeground": "#939293",
|
||||||
|
"background": "#2d2a2e",
|
||||||
|
"disabledBackground": "#2d2a2e",
|
||||||
|
"disabledForeground": "#5b595c",
|
||||||
|
"foreground": "#fcfcfa",
|
||||||
|
"selectionBackground": "#403e41",
|
||||||
|
"selectionForeground": "#ffd866"
|
||||||
|
},
|
||||||
|
"SearchEverywhere": {
|
||||||
|
"Advertiser": {
|
||||||
|
"background": "#221f22",
|
||||||
|
"foreground": "#939293"
|
||||||
|
},
|
||||||
|
"Header": {
|
||||||
|
"background": "#2d2a2e"
|
||||||
|
},
|
||||||
|
"List": {
|
||||||
|
"separatorColor": "#2d2a2e",
|
||||||
|
"separatorForeground": "#939293"
|
||||||
|
},
|
||||||
|
"SearchField": {
|
||||||
|
"background": "#2d2a2e",
|
||||||
|
"borderColor": "#221f22",
|
||||||
|
"infoForeground": "#939293"
|
||||||
|
},
|
||||||
|
"Tab": {
|
||||||
|
"selectedForeground": "#ffd866",
|
||||||
|
"selectedBackground": "#5b595c"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"SearchMatch": {
|
||||||
|
"endBackground": "#ffd866",
|
||||||
|
"startBackground": "#ffd866"
|
||||||
|
},
|
||||||
|
"Separator": {
|
||||||
|
"separatorColor": "#363337"
|
||||||
|
},
|
||||||
|
"SidePanel": {
|
||||||
|
"background": "#221f22"
|
||||||
|
},
|
||||||
|
"Slider": {
|
||||||
|
"background": "#2d2a2e",
|
||||||
|
"buttonBorderColor": "#ffd866",
|
||||||
|
"buttonColor": "#ffd866",
|
||||||
|
"foreground": "#fcfcfa",
|
||||||
|
"tickColor": "#403e41",
|
||||||
|
"trackColor": "#403e41"
|
||||||
|
},
|
||||||
|
"SpeedSearch": {
|
||||||
|
"background": "#5b595c",
|
||||||
|
"borderColor": "#2d2a2e",
|
||||||
|
"errorForeground": "#fcfcfa",
|
||||||
|
"foreground": "#fcfcfa"
|
||||||
|
},
|
||||||
|
"Spinner": {
|
||||||
|
"background": "#2d2a2e"
|
||||||
|
},
|
||||||
|
"SplitPane": {
|
||||||
|
"background": "#2d2a2e",
|
||||||
|
"highlight": "#221f22"
|
||||||
|
},
|
||||||
|
"SplitPaneDivider": {
|
||||||
|
"draggingColor": "#403e41"
|
||||||
|
},
|
||||||
|
"StatusBar": {
|
||||||
|
"borderColor": "#363337",
|
||||||
|
"hoverBackground": "#363337"
|
||||||
|
},
|
||||||
|
"TabbedPane": {
|
||||||
|
"background": "#2d2a2e",
|
||||||
|
"contentAreaColor": "#5b595c",
|
||||||
|
"disabledForeground": "#5b595c",
|
||||||
|
"disabledUnderlineColor": "#5b595c",
|
||||||
|
"focus": "#403e41",
|
||||||
|
"focusColor": "#403e41",
|
||||||
|
"foreground": "#fcfcfa",
|
||||||
|
"hoverColor": "#363337",
|
||||||
|
"tabSelectionHeight": 2,
|
||||||
|
"underlineColor": "#ffd866"
|
||||||
|
},
|
||||||
|
"Table": {
|
||||||
|
"background": "#221f22",
|
||||||
|
"dropLineColor": "#ffd866",
|
||||||
|
"dropLineShortColor": "#ffd866",
|
||||||
|
"focusCellBackground": "#221f22",
|
||||||
|
"focusCellForeground": "#ffd866",
|
||||||
|
"foreground": "#fcfcfa",
|
||||||
|
"gridColor": "#221f22",
|
||||||
|
"lightSelectionForeground": "#ffd866",
|
||||||
|
"lightSelectionInactiveForeground": "#fcfcfa",
|
||||||
|
"lightSelectionInactiveBackground": "#363337",
|
||||||
|
"selectionBackground": "#363337",
|
||||||
|
"selectionForeground": "#ffd866",
|
||||||
|
"selectionInactiveBackground": "#363337",
|
||||||
|
"selectionInactiveForeground": "#fcfcfa",
|
||||||
|
"sortIconColor": "#fcfcfa",
|
||||||
|
"stripeColor": "#221f22"
|
||||||
|
},
|
||||||
|
"TableHeader": {
|
||||||
|
"background": "#2d2a2e",
|
||||||
|
"bottomSeparatorColor": "#363337",
|
||||||
|
"cellBorder": "4,0,4,0",
|
||||||
|
"foreground": "#fcfcfa",
|
||||||
|
"focusCellBackground": "#403e41",
|
||||||
|
"separatorColor": "#363337"
|
||||||
|
},
|
||||||
|
"textText": "#939293",
|
||||||
|
"TextArea": {
|
||||||
|
"background": "#363337",
|
||||||
|
"caretForeground": "#ffd866",
|
||||||
|
"foreground": "#fcfcfa",
|
||||||
|
"inactiveForeground": "#5b595c",
|
||||||
|
"selectionBackground": "#5b595c",
|
||||||
|
"selectionForeground": "#ffd866"
|
||||||
|
},
|
||||||
|
"TextField": {
|
||||||
|
"background": "#363337",
|
||||||
|
"caretForeground": "#ffd866",
|
||||||
|
"foreground": "#fcfcfa",
|
||||||
|
"inactiveForeground": "#5b595c",
|
||||||
|
"selectionBackground": "#5b595c",
|
||||||
|
"selectionForeground": "#ffd866"
|
||||||
|
},
|
||||||
|
"TextPane": {
|
||||||
|
"background": "#363337",
|
||||||
|
"caretForeground": "#ffd866",
|
||||||
|
"foreground": "#fcfcfa",
|
||||||
|
"inactiveForeground": "#5b595c",
|
||||||
|
"selectionBackground": "#5b595c",
|
||||||
|
"selectionForeground": "#ffd866"
|
||||||
|
},
|
||||||
|
"TitlePane": {
|
||||||
|
"background": "#221f22",
|
||||||
|
"Button.hoverBackground": "#5b595c",
|
||||||
|
"inactiveBackground": "#2d2a2e",
|
||||||
|
"infoForeground": "#939293",
|
||||||
|
"inactiveInfoForeground": "#939293"
|
||||||
|
},
|
||||||
|
"TitledBorder": {
|
||||||
|
"titleColor": "#2d2a2e"
|
||||||
|
},
|
||||||
|
"ToggleButton": {
|
||||||
|
"borderColor": "#403e41",
|
||||||
|
"buttonColor": "#fcfcfa",
|
||||||
|
"disabledText": "#5b595c",
|
||||||
|
"foreground": "#939293",
|
||||||
|
"offForeground": "#2d2a2e",
|
||||||
|
"offBackground": "#2d2a2e",
|
||||||
|
"onBackground": "#ffd866",
|
||||||
|
"onForeground": "#ffd866"
|
||||||
|
},
|
||||||
|
"ToolBar": {
|
||||||
|
"background": "#221f22",
|
||||||
|
"borderHandleColor": "#939293",
|
||||||
|
"floatingForeground": "#939293",
|
||||||
|
"foreground": "#fcfcfa"
|
||||||
|
},
|
||||||
|
"ToolTip": {
|
||||||
|
"Actions": {
|
||||||
|
"background": "#2d2a2e",
|
||||||
|
"infoForeground": "#939293"
|
||||||
|
},
|
||||||
|
"background": "#2d2a2e",
|
||||||
|
"borderColor": "#5b595c",
|
||||||
|
"foreground": "#fcfcfa",
|
||||||
|
"infoForeground": "#939293",
|
||||||
|
"shortcutForeground": "#939293"
|
||||||
|
},
|
||||||
|
"ToolWindow": {
|
||||||
|
"Button": {
|
||||||
|
"hoverBackground": "#363337",
|
||||||
|
"selectedForeground": "#ffd866",
|
||||||
|
"selectedBackground": "#363337"
|
||||||
|
},
|
||||||
|
"Header": {
|
||||||
|
"background": "#2d2a2e",
|
||||||
|
"borderColor": "#363337",
|
||||||
|
"inactiveBackground": "#2d2a2e"
|
||||||
|
},
|
||||||
|
"HeaderCloseButton": {
|
||||||
|
"background": "#2d2a2e"
|
||||||
|
},
|
||||||
|
"HeaderTab": {
|
||||||
|
"hoverBackground": "#363337",
|
||||||
|
"hoverInactiveBackground": "#363337",
|
||||||
|
"inactiveUnderlineColor": "#ffd866",
|
||||||
|
"selectedInactiveBackground": "#2d2a2e",
|
||||||
|
"underlineColor": "#ffd866",
|
||||||
|
"underlinedTabBackground": "#363337",
|
||||||
|
"underlinedTabInactiveBackground": "#363337"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Tree": {
|
||||||
|
"background": "#221f22",
|
||||||
|
"foreground": "#939293",
|
||||||
|
"hash": "#2d2a2e",
|
||||||
|
"modifiedItemForeground": "#ffd866",
|
||||||
|
"rowHeight": 22,
|
||||||
|
"selectionBackground": "#2d2a2e",
|
||||||
|
"selectionForeground": "#ffd866",
|
||||||
|
"selectionInactiveBackground": "#2d2a2e"
|
||||||
|
},
|
||||||
|
"UiDesigner": {
|
||||||
|
"Panel": {
|
||||||
|
"background": "#2d2a2e"
|
||||||
|
},
|
||||||
|
"Preview": {
|
||||||
|
"background": "#2d2a2e"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ValidationTooltip": {
|
||||||
|
"errorBackground": "#363337",
|
||||||
|
"errorBorderColor": "#363337",
|
||||||
|
"warningBackground": "#363337",
|
||||||
|
"warningBorderColor": "#363337"
|
||||||
|
},
|
||||||
|
"VersionControl": {
|
||||||
|
"FileHistory": {
|
||||||
|
"Commit": {
|
||||||
|
"selectedBranchBackground": "#2d2a2e"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"GitLog": {
|
||||||
|
"localBranchIconColor": "#ffd866",
|
||||||
|
"otherIconColor": "#939293",
|
||||||
|
"remoteBranchIconColor": "#fcfcfa",
|
||||||
|
"tagIconColor": "#939293"
|
||||||
|
},
|
||||||
|
"HgLog": {
|
||||||
|
"branchIconColor": "#ffd866",
|
||||||
|
"bookmarkIconColor": "#ffd866",
|
||||||
|
"closedBranchIconColor": "#5b595c",
|
||||||
|
"localTagIconColor": "#939293",
|
||||||
|
"mqTagIconColor": "#939293",
|
||||||
|
"tagIconColor": "#939293",
|
||||||
|
"tipIconColor": "#939293"
|
||||||
|
},
|
||||||
|
"Log": {
|
||||||
|
"Commit": {
|
||||||
|
"unmatchedForeground": "#939293",
|
||||||
|
"currentBranchBackground": "#363337"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"RefLabel": {
|
||||||
|
"foreground": "#ffd866",
|
||||||
|
"backgroundBase": "#5b595c"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"Viewport": {
|
||||||
|
"background": "#221f22",
|
||||||
|
"foreground": "#fcfcfa"
|
||||||
|
},
|
||||||
|
"WelcomeScreen": {
|
||||||
|
"background": "#2d2a2e",
|
||||||
|
"borderColor": "#363337",
|
||||||
|
"captionBackground": "#221f22",
|
||||||
|
"captionForeground": "#fcfcfa",
|
||||||
|
"footerBackground": "#221f22",
|
||||||
|
"footerForeground": "#fcfcfa",
|
||||||
|
"headerBackground": "#2d2a2e",
|
||||||
|
"headerForeground": "#fcfcfa",
|
||||||
|
"Projects": {
|
||||||
|
"background": "#221f22",
|
||||||
|
"selectionBackground": "#2d2a2e",
|
||||||
|
"selectionInactiveBackground": "#2d2a2e"
|
||||||
|
},
|
||||||
|
"separatorColor": "#363337"
|
||||||
|
},
|
||||||
|
"window": "#2d2a2e",
|
||||||
|
"Window": {
|
||||||
|
"border": "0,0,0,0,#363337"
|
||||||
|
},
|
||||||
|
"windowBorder": "#363337",
|
||||||
|
"windowText": "#939293"
|
||||||
|
},
|
||||||
|
"icons": {
|
||||||
|
"ColorPalette": {
|
||||||
|
"Checkbox.Background.Default.Dark": "##403e41",
|
||||||
|
"Checkbox.Background.Disabled.Dark": "##221f22",
|
||||||
|
"Checkbox.Background.Selected.Dark": "##403e41",
|
||||||
|
"Checkbox.Border.Default.Dark": "##403e41",
|
||||||
|
"Checkbox.Border.Disabled.Dark": "##221f22",
|
||||||
|
"Checkbox.Border.Selected.Dark": "##403e41",
|
||||||
|
"Checkbox.Focus.Thin.Default.Dark": "##403e41",
|
||||||
|
"Checkbox.Focus.Thin.Selected.Dark": "##221f22",
|
||||||
|
"Checkbox.Focus.Wide.Dark": "##403e41",
|
||||||
|
"Checkbox.Foreground.Disabled.Dark": "##939293",
|
||||||
|
"Checkbox.Foreground.Selected.Dark": "##fcfcfa"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2019 Antelle
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
@@ -0,0 +1,232 @@
|
|||||||
|
{
|
||||||
|
"name": "Xcode-Dark",
|
||||||
|
"dark": true,
|
||||||
|
"author": "Antelle",
|
||||||
|
"editorScheme": "/Xcode-Dark.xml",
|
||||||
|
"ui": {
|
||||||
|
"*": {
|
||||||
|
"background": "#323333",
|
||||||
|
"foreground": "#DFDFE0",
|
||||||
|
|
||||||
|
"infoForeground": "#A9A9AA",
|
||||||
|
|
||||||
|
"selectionBackground": "#1D7BED",
|
||||||
|
"selectionForeground": "#F9FCFF",
|
||||||
|
"selectionInactiveBackground": "#555657",
|
||||||
|
"selectionBackgroundInactive": "#555657",
|
||||||
|
|
||||||
|
"lightSelectionBackground": "#2B4059",
|
||||||
|
"lightSelectionForeground": "#FFFFFF",
|
||||||
|
"lightSelectionInactiveBackground": "#555657",
|
||||||
|
"lightSelectionInactiveForeground": "#DFDFE0",
|
||||||
|
|
||||||
|
"disabledBackground": "#323333",
|
||||||
|
"inactiveBackground": "#313233",
|
||||||
|
|
||||||
|
"disabledForeground": "#737374",
|
||||||
|
"disabledText": "#737374",
|
||||||
|
"inactiveForeground": "#737374",
|
||||||
|
|
||||||
|
"acceleratorForeground": "#D0D0D9",
|
||||||
|
"acceleratorSelectionForeground": "#D0D0D9",
|
||||||
|
|
||||||
|
"errorForeground": "#843937",
|
||||||
|
|
||||||
|
"borderColor": "#414141",
|
||||||
|
"disabledBorderColor": "#414141",
|
||||||
|
|
||||||
|
"focusColor": "#24648D",
|
||||||
|
"focusedBorderColor": "#4C8CB5",
|
||||||
|
|
||||||
|
"separatorForeground": "#5A5B5C",
|
||||||
|
"separatorColor": "#5A5B5C",
|
||||||
|
"lineSeparatorColor": "#5A5B5C",
|
||||||
|
|
||||||
|
"modifiedItemForeground": "#1E4D86"
|
||||||
|
},
|
||||||
|
|
||||||
|
"ActionButton": {
|
||||||
|
"hoverBackground": "#5A5B5C",
|
||||||
|
"hoverBorderColor": "#5A5B5C",
|
||||||
|
"pressedBackground": "#414141",
|
||||||
|
"pressedBorderColor": "#414141"
|
||||||
|
},
|
||||||
|
|
||||||
|
"Button": {
|
||||||
|
"startBackground": "#424242",
|
||||||
|
"endBackground": "#424242",
|
||||||
|
"startBorderColor": "#525252",
|
||||||
|
"endBorderColor": "#525252",
|
||||||
|
"shadowColor": "#363636",
|
||||||
|
|
||||||
|
"default": {
|
||||||
|
"foreground": "#DDE9FA",
|
||||||
|
"startBackground": "#206DE3",
|
||||||
|
"endBackground": "#1C61CA",
|
||||||
|
"startBorderColor": "#6099EC",
|
||||||
|
"endBorderColor": "#1C61CA",
|
||||||
|
"focusedBorderColor": "#45A1F4",
|
||||||
|
"focusColor": "#245F84",
|
||||||
|
"shadowColor": "#363636"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"Borders": {
|
||||||
|
"color": "#393A3B",
|
||||||
|
"ContrastBorderColor": "#4b4c4d"
|
||||||
|
},
|
||||||
|
|
||||||
|
"ComboBox": {
|
||||||
|
"nonEditableBackground": "#4f5051",
|
||||||
|
"background": "#414141",
|
||||||
|
"ArrowButton": {
|
||||||
|
"iconColor": "#DBDBDB",
|
||||||
|
"background": "#1E67D7",
|
||||||
|
"disabledIconColor": "#6B6B6C",
|
||||||
|
"nonEditableBackground": "#4f5051"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"ComboPopup.border": "1,1,1,1,3F3F3F",
|
||||||
|
|
||||||
|
"Component": {
|
||||||
|
"errorFocusColor": "#843937",
|
||||||
|
"inactiveErrorFocusColor": "#433239",
|
||||||
|
"warningFocusColor": "#8F7B2E",
|
||||||
|
"inactiveWarningFocusColor": "#434136",
|
||||||
|
"iconColor": "#DFDFE0",
|
||||||
|
"hoverIconColor": "#FFFFFF"
|
||||||
|
},
|
||||||
|
|
||||||
|
"Counter": {
|
||||||
|
"background": "#909090",
|
||||||
|
"foreground": "#000000"
|
||||||
|
},
|
||||||
|
|
||||||
|
"DebuggerPopup.borderColor": "#414141",
|
||||||
|
|
||||||
|
"DefaultTabs": {
|
||||||
|
"borderColor": "#484949",
|
||||||
|
"background": "#2A2B2B",
|
||||||
|
"inactiveUnderlineColor": "#24648D",
|
||||||
|
"hoverBackground": "#262727",
|
||||||
|
"underlineColor": "#1D7BED",
|
||||||
|
"underlineHeight": 2,
|
||||||
|
"underlinedTabBackground": "#3D3E3F"
|
||||||
|
},
|
||||||
|
|
||||||
|
"DragAndDrop": {
|
||||||
|
"areaForeground": "#DFDFE0",
|
||||||
|
"areaBackground": "#363737",
|
||||||
|
"areaBorderColor": "#414141"
|
||||||
|
},
|
||||||
|
|
||||||
|
"EditorTabs": {
|
||||||
|
"inactiveColoredFileBackground": "#2d281d"
|
||||||
|
},
|
||||||
|
|
||||||
|
"FileColor": {
|
||||||
|
"Yellow": "#3D3B37",
|
||||||
|
"Green": "#383C38",
|
||||||
|
"Blue": "#343A3E",
|
||||||
|
"Violet": "#3C3A3D",
|
||||||
|
"Orange": "#3D3A36",
|
||||||
|
"Rose": "#3D383B"
|
||||||
|
},
|
||||||
|
|
||||||
|
"Link": {
|
||||||
|
"activeForeground": "#428EE1",
|
||||||
|
"hoverForeground": "#7094FF",
|
||||||
|
"pressedForeground": "#FC4741",
|
||||||
|
"visitedForeground": "#7094FF"
|
||||||
|
},
|
||||||
|
|
||||||
|
"Notification": {
|
||||||
|
"errorForeground": "#DFDFE0",
|
||||||
|
"errorBackground": "#843937",
|
||||||
|
"errorBorderColor": "#982B31",
|
||||||
|
|
||||||
|
"MoreButton.innerBorderColor": "#4b4c4d",
|
||||||
|
|
||||||
|
"ToolWindow": {
|
||||||
|
"informativeForeground": "#DFDFE0",
|
||||||
|
"informativeBackground": "#225DA1",
|
||||||
|
"informativeBorderColor": "#1C61CA",
|
||||||
|
|
||||||
|
"warningForeground": "#DFDFE0",
|
||||||
|
"warningBackground": "#A98938",
|
||||||
|
"warningBorderColor": "#FEC42E",
|
||||||
|
|
||||||
|
"errorForeground": "#DFDFE0",
|
||||||
|
"errorBackground": "#843937",
|
||||||
|
"errorBorderColor": "#982B31"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"ProgressBar": {
|
||||||
|
"trackColor": "#252525",
|
||||||
|
"progressColor": "#CDCCCC",
|
||||||
|
"indeterminateStartColor": "#CDCCCC",
|
||||||
|
"indeterminateEndColor": "#B4B3B3",
|
||||||
|
"failedColor": "#DF1A21",
|
||||||
|
"failedEndColor": "#982B31",
|
||||||
|
"passedColor": "#3AA87B",
|
||||||
|
"passedEndColor": "#368E68"
|
||||||
|
},
|
||||||
|
|
||||||
|
"SearchMatch": {
|
||||||
|
"startBackground": "#f5bc2d",
|
||||||
|
"endBackground": "#e9b32b"
|
||||||
|
},
|
||||||
|
|
||||||
|
"SpeedSearch": {
|
||||||
|
"errorForeground": "#DF1A21"
|
||||||
|
},
|
||||||
|
|
||||||
|
"ToggleButton": {
|
||||||
|
"onBackground": "#1D7BED"
|
||||||
|
},
|
||||||
|
|
||||||
|
"CompletionPopup": {
|
||||||
|
"matchForeground": "#FDA14F",
|
||||||
|
"selectionBackground": "#1D7BED"
|
||||||
|
},
|
||||||
|
|
||||||
|
"Popup": {
|
||||||
|
"Header": {
|
||||||
|
"activeBackground": "#4A4E52",
|
||||||
|
"inactiveBackground": "#4A4E52"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"SearchEverywhere": {
|
||||||
|
"Tab": {
|
||||||
|
"selectedForeground": "#F9FCFF",
|
||||||
|
"selectedBackground": "#555A5E"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"icons": {
|
||||||
|
"ColorPalette": {
|
||||||
|
"Actions.Grey": "#969798",
|
||||||
|
"Actions.Red": "#FC545B",
|
||||||
|
"Actions.Yellow": "#e0c24c",
|
||||||
|
"Actions.Green": "#71bf47",
|
||||||
|
"Actions.Blue": "#3062d1",
|
||||||
|
"Actions.GreyInline.Dark": "#6F6F70",
|
||||||
|
|
||||||
|
"Objects.Grey": "#6F6F70",
|
||||||
|
"Objects.RedStatus": "#FC4741",
|
||||||
|
"Objects.Red": "#FC545B",
|
||||||
|
"Objects.Pink": "#F5539E",
|
||||||
|
"Objects.Yellow": "#e0c24c",
|
||||||
|
"Objects.Green": "#71bf47",
|
||||||
|
"Objects.Blue": "#3062d1",
|
||||||
|
"Objects.Purple": "#A453A5",
|
||||||
|
"Objects.BlackText": "#000000",
|
||||||
|
"Objects.YellowDark": "#89744D",
|
||||||
|
"Objects.GreenAndroid": "#5D7554"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user