mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2026-02-11 06:27:13 -06:00
Compare commits
151 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
10e2a5b1eb | ||
|
|
e675d1b7e2 | ||
|
|
499c4dadd5 | ||
|
|
f550f84acd | ||
|
|
8021f1a7fc | ||
|
|
d50fe606ee | ||
|
|
281f014aa0 | ||
|
|
2f6da3e84a | ||
|
|
f9accc2a7a | ||
|
|
fe15078bbd | ||
|
|
27d4b5eba7 | ||
|
|
e378576632 | ||
|
|
74909da110 | ||
|
|
655bf112ac | ||
|
|
5c3638a5a4 | ||
|
|
2459a3654b | ||
|
|
e9a3456cf5 | ||
|
|
2bcdf774ff | ||
|
|
ef01f23384 | ||
|
|
ab7bbb6593 | ||
|
|
f2dad88875 | ||
|
|
c474565ff5 | ||
|
|
fd9dbbd7e6 | ||
|
|
43ab095e0f | ||
|
|
41e2888bf1 | ||
|
|
e7d5e22960 | ||
|
|
3f3884193d | ||
|
|
dfccabc2b9 | ||
|
|
af7c181596 | ||
|
|
8e84112837 | ||
|
|
822cd16daa | ||
|
|
33ea84004d | ||
|
|
8dbbe20840 | ||
|
|
d990ccc4ab | ||
|
|
9f16249898 | ||
|
|
62fc3139cf | ||
|
|
452452dcc9 | ||
|
|
b6fb06bc65 | ||
|
|
aac6bd1b7c | ||
|
|
d260001cbd | ||
|
|
9c470d77cb | ||
|
|
269075657d | ||
|
|
d0029beb22 | ||
|
|
4b4837e3a1 | ||
|
|
d0160b8b6d | ||
|
|
ea351935b2 | ||
|
|
20ccc2951e | ||
|
|
6f9bad1bdf | ||
|
|
39a0d514a8 | ||
|
|
ad82c591cc | ||
|
|
32ceb168d5 | ||
|
|
16146f4c88 | ||
|
|
60febbf3f8 | ||
|
|
4960b30cfb | ||
|
|
56c161fea0 | ||
|
|
27c439d728 | ||
|
|
78d5e03a66 | ||
|
|
f25e647b6a | ||
|
|
e44212fc65 | ||
|
|
a483403774 | ||
|
|
69750dba19 | ||
|
|
af962b99be | ||
|
|
2399e54a4b | ||
|
|
aea5e8eb16 | ||
|
|
a3a60c1c4b | ||
|
|
c141cb6c6c | ||
|
|
62765ab6ca | ||
|
|
e4f7fed523 | ||
|
|
bf8cc268cc | ||
|
|
8450e74832 | ||
|
|
475b258e4a | ||
|
|
f20803ae57 | ||
|
|
3fcb17931a | ||
|
|
736c7b8377 | ||
|
|
05743e2d8b | ||
|
|
6cd2c7f26d | ||
|
|
469e5bd179 | ||
|
|
dbeb3f04e7 | ||
|
|
e9b17ac24a | ||
|
|
65fbcedaa4 | ||
|
|
c4183ada11 | ||
|
|
27f9614633 | ||
|
|
2211cc5596 | ||
|
|
46f0393648 | ||
|
|
b4c1a97687 | ||
|
|
adcef385b0 | ||
|
|
48e38b2855 | ||
|
|
2cc8327a08 | ||
|
|
404e80082c | ||
|
|
3fbc21347a | ||
|
|
d76f0e2241 | ||
|
|
e5fcc59805 | ||
|
|
de82dac873 | ||
|
|
a14ef72177 | ||
|
|
6ee5234351 | ||
|
|
398a041ddf | ||
|
|
02bb73c335 | ||
|
|
f37c4cdc4d | ||
|
|
d5c9bcddc8 | ||
|
|
f3f8c81518 | ||
|
|
a99ffd4821 | ||
|
|
7b5a9d9949 | ||
|
|
feb8d0591e | ||
|
|
2197808631 | ||
|
|
36b3ccc34f | ||
|
|
a5b69d712c | ||
|
|
8edcca9745 | ||
|
|
f3b1f4b608 | ||
|
|
879a8aaa6d | ||
|
|
900d005d89 | ||
|
|
c8225171a3 | ||
|
|
c513c052fc | ||
|
|
711c4dd2b5 | ||
|
|
81f1ebd1db | ||
|
|
c722934510 | ||
|
|
3ffe8e225d | ||
|
|
6d86cf8f9c | ||
|
|
e6e19110b2 | ||
|
|
b5c13bd1b3 | ||
|
|
b129fe437c | ||
|
|
645be4bfa3 | ||
|
|
321c49ee32 | ||
|
|
84db2f9b65 | ||
|
|
6ba1a419bc | ||
|
|
3de329a332 | ||
|
|
f175c36736 | ||
|
|
f1de65b471 | ||
|
|
5069013e6e | ||
|
|
c0642ed620 | ||
|
|
a145673dd1 | ||
|
|
223af48c09 | ||
|
|
d72cfc37d6 | ||
|
|
3ba8133890 | ||
|
|
a907cd7f46 | ||
|
|
3b740cb494 | ||
|
|
0f0f21a7b1 | ||
|
|
537f6703c0 | ||
|
|
da0c562ac2 | ||
|
|
0bef71907c | ||
|
|
0ebd43bc5f | ||
|
|
3092fced3c | ||
|
|
a02784fcba | ||
|
|
924abde89e | ||
|
|
f011468819 | ||
|
|
11f459d5b0 | ||
|
|
974f7d5d68 | ||
|
|
e60db4ff90 | ||
|
|
ebe1cd3367 | ||
|
|
30db9d13a5 | ||
|
|
368611359c | ||
|
|
746918c054 |
155
CHANGELOG.md
155
CHANGELOG.md
@@ -1,6 +1,161 @@
|
|||||||
FlatLaf Change Log
|
FlatLaf Change Log
|
||||||
==================
|
==================
|
||||||
|
|
||||||
|
## 0.25
|
||||||
|
|
||||||
|
- Hide menu mnemonics by default and show them only when <kbd>Alt</kbd> key is
|
||||||
|
pressed. (issue #43)
|
||||||
|
- Menu: Fixed vertical alignment of sub-menus. (issue #42)
|
||||||
|
- TabbedPane: In scroll-tab-layout, the cropped line is now hidden. (issue #40)
|
||||||
|
- Tree: UI default value `Tree.textBackground` now has a valid color and is no
|
||||||
|
longer `null`.
|
||||||
|
- Tree on macOS: Fixed <kbd>Left</kbd> and <kbd>Right</kbd> keys to collapse or
|
||||||
|
expand nodes.
|
||||||
|
- ComboBox on macOS: Fixed keyboard navigation and show/hide popup.
|
||||||
|
- Button and ToggleButton: Support per component minimum height (set client
|
||||||
|
property `JComponent.minimumHeight` to an integer). (issue #44)
|
||||||
|
- Button and ToggleButton: Do not apply minimum width if button border was
|
||||||
|
changed (is no longer an instance of `FlatButtonBorder`).
|
||||||
|
- ToggleButton: Renamed toggle button type "underline" to "tab" (value of client
|
||||||
|
property `JButton.buttonType` is now `tab`).
|
||||||
|
- ToggleButton: Support per component styling for tab-style toggle buttons with
|
||||||
|
client properties `JToggleButton.tab.underlineHeight` (integer),
|
||||||
|
`JToggleButton.tab.underlineColor` (Color) and
|
||||||
|
`JToggleButton.tab.selectedBackground` (Color). (issue #45)
|
||||||
|
- ToggleButton: No longer use focus width for tab-style toggle buttons to
|
||||||
|
compute component size, which reduces/fixes component size in "Flat IntelliJ"
|
||||||
|
and "Flat Darcula" themes.
|
||||||
|
- TabbedPane: Support per component tab height (set client property
|
||||||
|
`JTabbedPane.tabHeight` to an integer).
|
||||||
|
- ProgressBar: Support square painting (set client property
|
||||||
|
`JProgressBar.square` to `true`) and larger height even if no string is
|
||||||
|
painted (set client property `JProgressBar.largeHeight` to `true`).
|
||||||
|
|
||||||
|
|
||||||
|
## 0.24
|
||||||
|
|
||||||
|
- Support smooth scrolling with touchpads and high precision mouse wheels.
|
||||||
|
(issue #27)
|
||||||
|
- Changed `.properties` file loading order: Now all core `.properties` files are
|
||||||
|
loaded before loading addon `.properties` files. This makes it easier to
|
||||||
|
overwrite core values in addons. Also, addon loading order can be specified.
|
||||||
|
- TableHeader: Paint column borders if renderer has changed, but delegates to
|
||||||
|
the system default renderer (e.g. done in NetBeans).
|
||||||
|
- Label and ToolTip: Fixed font sizes for HTML headings.
|
||||||
|
- Button and ToggleButton: Support square button style (set client property
|
||||||
|
`JButton.buttonType` to `square`).
|
||||||
|
- ToggleButton: Support underline toggle button style (set client property
|
||||||
|
`JButton.buttonType` to `underline`).
|
||||||
|
- Button and TextComponent: Support per component minimum width (set client
|
||||||
|
property `JComponent.minimumWidth` to an integer).
|
||||||
|
- ScrollPane with Table: The border of buttons that are added to one of the four
|
||||||
|
scroll pane corners are now removed if the center component is a table. Also,
|
||||||
|
these corner buttons are made not focusable.
|
||||||
|
- Table: Replaced `Table.showGrid` with `Table.showHorizontalLines` and
|
||||||
|
`Table.showVerticalLines`. (issue #38)
|
||||||
|
- ProgressBar: Now uses blueish color for the progress part in "Flat Dark"
|
||||||
|
theme. In the "Flat Darcula" theme, it remains light gray.
|
||||||
|
- Improved Swing system colors `controlHighlight`, `controlLtHighlight`,
|
||||||
|
`controlShadow` and `controlDkShadow`.
|
||||||
|
|
||||||
|
|
||||||
|
## 0.23.1
|
||||||
|
|
||||||
|
- Tree: Fixed wide selection if scrolled horizontally.
|
||||||
|
- ComboBox: Fixed NPE in Oracle SQL Developer settings.
|
||||||
|
- IntelliJ Themes: Fixed checkbox colors in Material UI Lite dark themes.
|
||||||
|
|
||||||
|
|
||||||
|
## 0.23
|
||||||
|
|
||||||
|
- Updated colors in "Flat Light" and "Flat IntelliJ" themes with colors from
|
||||||
|
"IntelliJ Light Theme", which provides blue coloring that better matches
|
||||||
|
platform colors.
|
||||||
|
- Tree: Support wide selection (enabled by default).
|
||||||
|
- Table: Hide grid and changed intercell spacing to zero.
|
||||||
|
- List, Table and Tree: Added colors for drag-and-drop. Added "enable drag and
|
||||||
|
drop" checkbox to Demo on "Data Components" tab.
|
||||||
|
- List and Tree: Hide cell focus indicator (black rectangle) by default. Can be
|
||||||
|
enabled with `List.showCellFocusIndicator=true` /
|
||||||
|
`Tree.showCellFocusIndicator=true`, but then the cell focus indicator is shown
|
||||||
|
only if more than one item is selected.
|
||||||
|
- Table: Hide cell focus indicator (black rectangle) by default if none of the
|
||||||
|
selected cells is editable. Can be show always with
|
||||||
|
`Table.showCellFocusIndicator=true`.
|
||||||
|
- Support basic color functions in `.properties` files: `rgb(red,green,blue)`,
|
||||||
|
`rgba(red,green,blue,alpha)`, `hsl(hue,saturation,lightness)`,
|
||||||
|
`hsla(hue,saturation,lightness,alpha)`, `lighten(color,amount[,options])` and
|
||||||
|
`darken(color,amount[,options])`.
|
||||||
|
- Replaced prefix `@@` with `$` in `.properties` files.
|
||||||
|
- Fixed link color (in HTML text) and separator color in IntelliJ platform
|
||||||
|
themes.
|
||||||
|
- Use logging instead of printing errors to `System.err`.
|
||||||
|
- Updated IntelliJ Themes in demo to the latest versions.
|
||||||
|
- IntelliJ Themes: Fixed link and separator colors.
|
||||||
|
|
||||||
|
|
||||||
|
## 0.22
|
||||||
|
|
||||||
|
- TextComponent: Support placeholder text that is displayed if text field is
|
||||||
|
empty (set client property "JTextField.placeholderText" to a string).
|
||||||
|
- TextComponent: Scale caret width on HiDPI screens when running on Java 8.
|
||||||
|
- ProgressBar: If progress text is visible:
|
||||||
|
- use smaller font
|
||||||
|
- reduced height
|
||||||
|
- changed style to rounded rectangle
|
||||||
|
- fixed painting issues on low values
|
||||||
|
- ProgressBar: Support configure of arc with `ProgressBar.arc`.
|
||||||
|
- ProgressBar: Reduced thickness from 6 to 4.
|
||||||
|
- TabbedPane: Support background color for selected tabs
|
||||||
|
(`TabbedPane.selectedBackground`) and separators between tabs
|
||||||
|
(`TabbedPane.showTabSeparators`).
|
||||||
|
- CheckBox: changed `CheckBox.arc` from radius to diameter to be consistent with
|
||||||
|
`Button.arc` and `Component.arc`
|
||||||
|
- Button: Enabled `Button.defaultButtonFollowsFocus` on Windows, which allows
|
||||||
|
pressing focused button with <kbd>Enter</kbd> key (as in Windows LaF).
|
||||||
|
- Fixed clipped borders at 125%, 150% and 175% scaling when outer focus width is
|
||||||
|
zero (default in "Flat Light" and "Flat Dark" themes).
|
||||||
|
- On Mac show mnemonics only when <kbd>Ctrl</kbd> and <kbd>Alt</kbd> keys are
|
||||||
|
pressed. (issue #4)
|
||||||
|
|
||||||
|
|
||||||
|
## 0.21
|
||||||
|
|
||||||
|
- ScrollBar: Show decrease/increase arrow buttons if client property
|
||||||
|
"JScrollBar.showButtons" is set to `true` on `JScrollPane` or `JScrollBar`.
|
||||||
|
(issue #25)
|
||||||
|
- `FlatLaf.isNativeLookAndFeel()` now returns `false`.
|
||||||
|
- Button: Optionally support gradient borders, gradient backgrounds and shadows
|
||||||
|
for improved compatibility with IntelliJ platform themes (e.g. for Vuesion,
|
||||||
|
Spacegray and Material Design Dark themes).
|
||||||
|
- Button: Fixed help button styling in IntelliJ platform themes.
|
||||||
|
- ScrollPane: Paint disabled border if view component (e.g. JTextPane) is
|
||||||
|
disabled.
|
||||||
|
- Fixed Swing system colors in dark themes.
|
||||||
|
|
||||||
|
|
||||||
|
## 0.20
|
||||||
|
|
||||||
|
- Support using IntelliJ platform themes (.theme.json files).
|
||||||
|
- Support `JFileChooser`. (issue #5)
|
||||||
|
- Look and feel identifier returned by `FlatLaf.getID()` now always starts with
|
||||||
|
"FlatLaf". Use `UIManager.getLookAndFeel().getID().startsWith( "FlatLaf" )` to
|
||||||
|
check whether the current look and feel is FlatLaf.
|
||||||
|
- Fixed selection background of checkbox in table cell.
|
||||||
|
- Fixed color of links in HTML text.
|
||||||
|
- Fixed jittery submenu rendering on Mac. (issue #10)
|
||||||
|
- Fixed "cannot find symbol" error in NetBeans editor, when source/binary format
|
||||||
|
is set to JDK 9 (or later) in NetBeans project. (issue #13)
|
||||||
|
- Button: Make button square if button text is "..." or a single character.
|
||||||
|
- ComboBox: Fixed issues with NetBeans `org.openide.awt.ColorComboBox`
|
||||||
|
component.
|
||||||
|
- Hex color values in `.properties` files now must start with a `#` character.
|
||||||
|
- SwingX: Support `JXTitledPanel`. (issue #22)
|
||||||
|
- SwingX: Fixed too wide border when using date picker as table cell editor.
|
||||||
|
(issue #24)
|
||||||
|
- JIDE Common Layer: Fixed `JidePopup` border.
|
||||||
|
|
||||||
|
|
||||||
## 0.18
|
## 0.18
|
||||||
|
|
||||||
- TextField and TextArea: Do not apply minimum width if `columns` property is
|
- TextField and TextArea: Do not apply minimum width if `columns` property is
|
||||||
|
|||||||
14
README.md
14
README.md
@@ -16,6 +16,16 @@ IntelliJ IDEA 2019.2+ and uses almost the same colors and icons.
|
|||||||

|

|
||||||
|
|
||||||
|
|
||||||
|
IntelliJ Platform Themes
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
FlatLaf can use 3rd party themes created for IntelliJ Platform:
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
Demo
|
Demo
|
||||||
----
|
----
|
||||||
|
|
||||||
@@ -35,7 +45,7 @@ build script:
|
|||||||
|
|
||||||
groupId: com.formdev
|
groupId: com.formdev
|
||||||
artifactId: flatlaf
|
artifactId: flatlaf
|
||||||
version: 0.18
|
version: 0.25
|
||||||
|
|
||||||
Otherwise download `flatlaf-<version>.jar` here:
|
Otherwise download `flatlaf-<version>.jar` here:
|
||||||
|
|
||||||
@@ -46,7 +56,7 @@ Addons
|
|||||||
------
|
------
|
||||||
|
|
||||||
- [SwingX](flatlaf-swingx)
|
- [SwingX](flatlaf-swingx)
|
||||||
- [JIDE Common Layer](https://github.com/jidesoft/jide-oss)
|
- [JIDE Common Layer](flatlaf-jide-oss)
|
||||||
|
|
||||||
|
|
||||||
Documentation
|
Documentation
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
version = "0.18"
|
version = "0.25"
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
repositories {
|
repositories {
|
||||||
|
|||||||
4
flatlaf-core/README.md
Normal file
4
flatlaf-core/README.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
FlatLaf Core
|
||||||
|
============
|
||||||
|
|
||||||
|
This sub-project contains the FlatLaf core source code.
|
||||||
@@ -58,12 +58,7 @@ tasks {
|
|||||||
archiveBaseName.set( "flatlaf" )
|
archiveBaseName.set( "flatlaf" )
|
||||||
|
|
||||||
if( JavaVersion.current() >= JavaVersion.VERSION_1_9 ) {
|
if( JavaVersion.current() >= JavaVersion.VERSION_1_9 ) {
|
||||||
manifest.attributes(
|
from( sourceSets["module-info"].output ) {
|
||||||
"Multi-Release" to "true"
|
|
||||||
)
|
|
||||||
|
|
||||||
into( "META-INF/versions/9" ) {
|
|
||||||
from( sourceSets["module-info"].output )
|
|
||||||
include( "module-info.class" )
|
include( "module-info.class" )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf;
|
package com.formdev.flatlaf;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
|
|
||||||
@@ -24,18 +25,185 @@ import javax.swing.JComponent;
|
|||||||
*/
|
*/
|
||||||
public interface FlatClientProperties
|
public interface FlatClientProperties
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Specifies type of a button.
|
||||||
|
* <p>
|
||||||
|
* <strong>Components</strong> {@link javax.swing.JButton} and {@link javax.swing.JToggleButton}<br>
|
||||||
|
* <strong>Value type</strong> {@link java.lang.String}<br>
|
||||||
|
* <strong>Allowed Values</strong> {@link #BUTTON_TYPE_SQUARE} and {@link #BUTTON_TYPE_HELP}
|
||||||
|
*/
|
||||||
String BUTTON_TYPE = "JButton.buttonType";
|
String BUTTON_TYPE = "JButton.buttonType";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Paint the button with square edges.
|
||||||
|
* <p>
|
||||||
|
* <strong>Components</strong> {@link javax.swing.JButton} and {@link javax.swing.JToggleButton}
|
||||||
|
*
|
||||||
|
* @see #BUTTON_TYPE
|
||||||
|
*/
|
||||||
|
String BUTTON_TYPE_SQUARE = "square";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Paint the toggle button in tab style.
|
||||||
|
* <p>
|
||||||
|
* <strong>Components</strong> {@link javax.swing.JToggleButton}
|
||||||
|
*
|
||||||
|
* @see #TOGGLE_BUTTON_TYPE
|
||||||
|
*/
|
||||||
|
String BUTTON_TYPE_TAB = "tab";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Paint a help button (circle with question mark).
|
||||||
|
* <p>
|
||||||
|
* <strong>Components</strong> {@link javax.swing.JButton}
|
||||||
|
*
|
||||||
|
* @see #BUTTON_TYPE
|
||||||
|
*/
|
||||||
String BUTTON_TYPE_HELP = "help";
|
String BUTTON_TYPE_HELP = "help";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies selected state of a checkbox.
|
||||||
|
* <p>
|
||||||
|
* <strong>Component</strong> {@link javax.swing.JCheckBox}<br>
|
||||||
|
* <strong>Value type</strong> {@link java.lang.String}<br>
|
||||||
|
* <strong>Allowed Values</strong> {@link #SELECTED_STATE_INDETERMINATE}
|
||||||
|
*/
|
||||||
String SELECTED_STATE = "JButton.selectedState";
|
String SELECTED_STATE = "JButton.selectedState";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Paint an indeterminate state on a checkbox.
|
||||||
|
*
|
||||||
|
* @see #SELECTED_STATE
|
||||||
|
*/
|
||||||
String SELECTED_STATE_INDETERMINATE = "indeterminate";
|
String SELECTED_STATE_INDETERMINATE = "indeterminate";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies minimum width of a component.
|
||||||
|
* <p>
|
||||||
|
* <strong>Component</strong> {@link javax.swing.JButton}, {@link javax.swing.JToggleButton} and {@link javax.swing.text.JTextComponent}<br>
|
||||||
|
* <strong>Value type</strong> {@link java.lang.Integer}<br>
|
||||||
|
*/
|
||||||
|
String MINIMUM_WIDTH = "JComponent.minimumWidth";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies minimum height of a component.
|
||||||
|
* <p>
|
||||||
|
* <strong>Component</strong> {@link javax.swing.JButton} and {@link javax.swing.JToggleButton}<br>
|
||||||
|
* <strong>Value type</strong> {@link java.lang.Integer}<br>
|
||||||
|
*/
|
||||||
|
String MINIMUM_HEIGHT = "JComponent.minimumHeight";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies whether the progress bar has always the larger height even if no string is painted.
|
||||||
|
* <p>
|
||||||
|
* <strong>Component</strong> {@link javax.swing.JProgressBar}<br>
|
||||||
|
* <strong>Value type</strong> {@link java.lang.Boolean}
|
||||||
|
*/
|
||||||
|
String PROGRESS_BAR_LARGE_HEIGHT = "JProgressBar.largeHeight";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies whether the progress bar is paint with square edges.
|
||||||
|
* <p>
|
||||||
|
* <strong>Component</strong> {@link javax.swing.JProgressBar}<br>
|
||||||
|
* <strong>Value type</strong> {@link java.lang.Boolean}
|
||||||
|
*/
|
||||||
|
String PROGRESS_BAR_SQUARE = "JProgressBar.square";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies whether the decrease/increase arrow buttons of a scrollbar are shown.
|
||||||
|
* <p>
|
||||||
|
* <strong>Component</strong> {@link javax.swing.JScrollBar} or {@link javax.swing.JScrollPane}<br>
|
||||||
|
* <strong>Value type</strong> {@link java.lang.Boolean}
|
||||||
|
*/
|
||||||
|
String SCROLL_BAR_SHOW_BUTTONS = "JScrollBar.showButtons";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies whether separators are shown between tabs.
|
||||||
|
* <p>
|
||||||
|
* <strong>Component</strong> {@link javax.swing.JTabbedPane}<br>
|
||||||
|
* <strong>Value type</strong> {@link java.lang.Boolean}
|
||||||
|
*/
|
||||||
|
String TABBED_PANE_SHOW_TAB_SEPARATORS = "JTabbedPane.showTabSeparators";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies whether a full border is painted around a tabbed pane.
|
||||||
|
* <p>
|
||||||
|
* <strong>Component</strong> {@link javax.swing.JTabbedPane}<br>
|
||||||
|
* <strong>Value type</strong> {@link java.lang.Boolean}
|
||||||
|
*/
|
||||||
String TABBED_PANE_HAS_FULL_BORDER = "JTabbedPane.hasFullBorder";
|
String TABBED_PANE_HAS_FULL_BORDER = "JTabbedPane.hasFullBorder";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies the height of a tab.
|
||||||
|
* <p>
|
||||||
|
* <strong>Component</strong> {@link javax.swing.JTabbedPane}<br>
|
||||||
|
* <strong>Value type</strong> {@link java.lang.Integer}
|
||||||
|
*/
|
||||||
|
String TABBED_PANE_TAB_HEIGHT = "JTabbedPane.tabHeight";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Placeholder text that is only painted if the text field is empty.
|
||||||
|
* <p>
|
||||||
|
* <strong>Component</strong> {@link javax.swing.JTextField} or {@link javax.swing.JComboBox}<br>
|
||||||
|
* <strong>Value type</strong> {@link java.lang.String}
|
||||||
|
*/
|
||||||
|
String PLACEHOLDER_TEXT = "JTextField.placeholderText";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Height 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}
|
||||||
|
*/
|
||||||
|
String TAB_BUTTON_UNDERLINE_HEIGHT = "JToggleButton.tab.underlineHeight";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Color 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.awt.Color}
|
||||||
|
*/
|
||||||
|
String TAB_BUTTON_UNDERLINE_COLOR = "JToggleButton.tab.underlineColor";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Background color if selected and toggle button type is {@link #BUTTON_TYPE_TAB}.
|
||||||
|
* <p>
|
||||||
|
* <strong>Component</strong> {@link javax.swing.JToggleButton}<br>
|
||||||
|
* <strong>Value type</strong> {@link java.awt.Color}
|
||||||
|
*/
|
||||||
|
String TAB_BUTTON_SELECTED_BACKGROUND = "JToggleButton.tab.selectedBackground";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether a client property of a component has the given value.
|
* Checks whether a client property of a component has the given value.
|
||||||
*/
|
*/
|
||||||
static boolean clientPropertyEquals( JComponent c, String key, Object value ) {
|
static boolean clientPropertyEquals( JComponent c, String key, Object value ) {
|
||||||
return Objects.equals( c.getClientProperty( key ), value );
|
return Objects.equals( c.getClientProperty( key ), value );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether a client property of a component is a boolean and returns its value.
|
||||||
|
* If the client property is not set, or not a boolean, defaultValue is returned.
|
||||||
|
*/
|
||||||
|
static boolean clientPropertyBoolean( JComponent c, String key, boolean defaultValue ) {
|
||||||
|
Object value = c.getClientProperty( key );
|
||||||
|
return (value instanceof Boolean) ? (boolean) value : defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether a client property of a component is an integer and returns its value.
|
||||||
|
* If the client property is not set, or not an integer, defaultValue is returned.
|
||||||
|
*/
|
||||||
|
static int clientPropertyInt( JComponent c, String key, int defaultValue ) {
|
||||||
|
Object value = c.getClientProperty( key );
|
||||||
|
return (value instanceof Integer) ? (int) value : defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether a client property of a component is a color and returns its value.
|
||||||
|
* If the client property is not set, or not a color, defaultValue is returned.
|
||||||
|
*/
|
||||||
|
static Color clientPropertyColor( JComponent c, String key, Color defaultValue ) {
|
||||||
|
Object value = c.getClientProperty( key );
|
||||||
|
return (value instanceof Color) ? (Color) value : defaultValue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,11 +23,11 @@ import java.io.InputStream;
|
|||||||
*
|
*
|
||||||
* 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>
|
||||||
* If you extend this class in a addon JAR, you also have to add a text file named
|
* If you extend this class in a 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>
|
||||||
* See 'flatlaf-swingx' addon for an example
|
* See 'flatlaf-swingx' addon for an example
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
@@ -37,6 +37,26 @@ public abstract class FlatDefaultsAddon
|
|||||||
/**
|
/**
|
||||||
* Finds an addon .properties file for the given LaF class and returns
|
* Finds an addon .properties file for the given LaF class and returns
|
||||||
* it as input stream. Or {@code null} if not found.
|
* it as input stream. Or {@code null} if not found.
|
||||||
|
* <p>
|
||||||
|
* This default implementation finds addon .properties file for the given LaF class
|
||||||
|
* in the same package as the subclass.
|
||||||
|
* <p>
|
||||||
|
* Override this method to load addon .properties files from other locations.
|
||||||
*/
|
*/
|
||||||
public abstract InputStream getDefaults( Class<?> lafClass );
|
public InputStream getDefaults( Class<?> lafClass ) {
|
||||||
|
Class<?> addonClass = this.getClass();
|
||||||
|
String propertiesName = '/' + addonClass.getPackage().getName().replace( '.', '/' )
|
||||||
|
+ '/' + lafClass.getSimpleName() + ".properties";
|
||||||
|
return addonClass.getResourceAsStream( propertiesName );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the priority used to sort addon loading.
|
||||||
|
* The order is only important if you want overwrite UI defaults of other addons.
|
||||||
|
* Lower numbers mean higher priority.
|
||||||
|
* Returns 10000 by default.
|
||||||
|
*/
|
||||||
|
public int getPriority() {
|
||||||
|
return 10000;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,18 +28,29 @@ import java.awt.Window;
|
|||||||
import java.awt.event.KeyEvent;
|
import java.awt.event.KeyEvent;
|
||||||
import java.beans.PropertyChangeEvent;
|
import java.beans.PropertyChangeEvent;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
import javax.swing.AbstractButton;
|
import javax.swing.AbstractButton;
|
||||||
|
import javax.swing.InputMap;
|
||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JRootPane;
|
||||||
import javax.swing.JTabbedPane;
|
import javax.swing.JTabbedPane;
|
||||||
|
import javax.swing.KeyStroke;
|
||||||
import javax.swing.LookAndFeel;
|
import javax.swing.LookAndFeel;
|
||||||
|
import javax.swing.PopupFactory;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.UIDefaults;
|
import javax.swing.UIDefaults;
|
||||||
|
import javax.swing.UIDefaults.LazyValue;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import javax.swing.UnsupportedLookAndFeelException;
|
import javax.swing.UnsupportedLookAndFeelException;
|
||||||
|
import javax.swing.plaf.ColorUIResource;
|
||||||
import javax.swing.plaf.FontUIResource;
|
import javax.swing.plaf.FontUIResource;
|
||||||
import javax.swing.plaf.basic.BasicLookAndFeel;
|
import javax.swing.plaf.basic.BasicLookAndFeel;
|
||||||
import javax.swing.plaf.metal.MetalLookAndFeel;
|
import javax.swing.plaf.metal.MetalLookAndFeel;
|
||||||
|
import javax.swing.text.html.HTMLEditorKit;
|
||||||
import com.formdev.flatlaf.util.SystemInfo;
|
import com.formdev.flatlaf.util.SystemInfo;
|
||||||
import com.formdev.flatlaf.util.UIScale;
|
import com.formdev.flatlaf.util.UIScale;
|
||||||
|
|
||||||
@@ -51,34 +62,47 @@ import com.formdev.flatlaf.util.UIScale;
|
|||||||
public abstract class FlatLaf
|
public abstract class FlatLaf
|
||||||
extends BasicLookAndFeel
|
extends BasicLookAndFeel
|
||||||
{
|
{
|
||||||
|
static final Logger LOG = Logger.getLogger( FlatLaf.class.getName() );
|
||||||
|
|
||||||
private BasicLookAndFeel base;
|
private BasicLookAndFeel base;
|
||||||
|
|
||||||
private String desktopPropertyName;
|
private String desktopPropertyName;
|
||||||
private PropertyChangeListener desktopPropertyListener;
|
private PropertyChangeListener desktopPropertyListener;
|
||||||
|
|
||||||
private KeyEventPostProcessor mnemonicListener;
|
private KeyEventPostProcessor mnemonicListener;
|
||||||
private static boolean altKeyPressed;
|
private static boolean showMnemonics;
|
||||||
|
private static WeakReference<Window> lastShowMnemonicWindow;
|
||||||
|
|
||||||
|
private Consumer<UIDefaults> postInitialization;
|
||||||
|
|
||||||
public static boolean install( LookAndFeel newLookAndFeel ) {
|
public static boolean install( LookAndFeel newLookAndFeel ) {
|
||||||
try {
|
try {
|
||||||
UIManager.setLookAndFeel( newLookAndFeel );
|
UIManager.setLookAndFeel( newLookAndFeel );
|
||||||
return true;
|
return true;
|
||||||
} catch( Exception ex ) {
|
} catch( Exception ex ) {
|
||||||
System.err.println( "Failed to initialize look and feel " + newLookAndFeel.getClass().getName() );
|
LOG.log( Level.SEVERE, "FlatLaf: Failed to initialize look and feel '" + newLookAndFeel.getClass().getName() + "'.", ex );
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the look and feel identifier.
|
||||||
|
* <p>
|
||||||
|
* Syntax: "FlatLaf - ${theme-name}"
|
||||||
|
* <p>
|
||||||
|
* Use {@code UIManager.getLookAndFeel().getID().startsWith( "FlatLaf" )}
|
||||||
|
* to check whether the current look and feel is FlatLaf.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public String getID() {
|
public String getID() {
|
||||||
return getName();
|
return "FlatLaf - " + getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract boolean isDark();
|
public abstract boolean isDark();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isNativeLookAndFeel() {
|
public boolean isNativeLookAndFeel() {
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -92,10 +116,14 @@ public abstract class FlatLaf
|
|||||||
|
|
||||||
super.initialize();
|
super.initialize();
|
||||||
|
|
||||||
|
// make sure that a plain popup factory is used (otherwise sub-menu rendering
|
||||||
|
// is "jittery" on Mac, where AquaLookAndFeel installs its own popup factory)
|
||||||
|
if( PopupFactory.getSharedInstance().getClass() != PopupFactory.class )
|
||||||
|
PopupFactory.setSharedInstance( new PopupFactory() );
|
||||||
|
|
||||||
// add mnemonic listener
|
// add mnemonic listener
|
||||||
mnemonicListener = e -> {
|
mnemonicListener = e -> {
|
||||||
if( e.getKeyCode() == KeyEvent.VK_ALT )
|
checkShowMnemonics( e );
|
||||||
altKeyChanged( e.getID() == KeyEvent.KEY_PRESSED );
|
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventPostProcessor( mnemonicListener );
|
KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventPostProcessor( mnemonicListener );
|
||||||
@@ -117,6 +145,18 @@ public abstract class FlatLaf
|
|||||||
};
|
};
|
||||||
Toolkit.getDefaultToolkit().addPropertyChangeListener( desktopPropertyName, desktopPropertyListener );
|
Toolkit.getDefaultToolkit().addPropertyChangeListener( desktopPropertyName, desktopPropertyListener );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Following code should be ideally in initialize(), but needs color from UI defaults.
|
||||||
|
// Do not move this code to getDefaults() to avoid side effects in the case that
|
||||||
|
// getDefaults() is directly invoked from 3rd party code. E.g. `new FlatLightLaf().getDefaults()`.
|
||||||
|
postInitialization = defaults -> {
|
||||||
|
// update link color in HTML text
|
||||||
|
Color linkColor = defaults.getColor( "Component.linkColor" );
|
||||||
|
if( linkColor != null ) {
|
||||||
|
new HTMLEditorKit().getStyleSheet().addRule(
|
||||||
|
String.format( "a { color: #%06x; }", linkColor.getRGB() & 0xffffff ) );
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -134,6 +174,10 @@ public abstract class FlatLaf
|
|||||||
mnemonicListener = null;
|
mnemonicListener = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// restore default link color
|
||||||
|
new HTMLEditorKit().getStyleSheet().addRule( "a { color: blue; }" );
|
||||||
|
postInitialization = null;
|
||||||
|
|
||||||
if( base != null )
|
if( base != null )
|
||||||
base.uninitialize();
|
base.uninitialize();
|
||||||
|
|
||||||
@@ -148,10 +192,11 @@ public abstract class FlatLaf
|
|||||||
if( base == null ) {
|
if( base == null ) {
|
||||||
if( SystemInfo.IS_MAC ) {
|
if( SystemInfo.IS_MAC ) {
|
||||||
// use Mac Aqua LaF as base
|
// use Mac Aqua LaF as base
|
||||||
|
String aquaLafClassName = "com.apple.laf.AquaLookAndFeel";
|
||||||
try {
|
try {
|
||||||
base = (BasicLookAndFeel) Class.forName( "com.apple.laf.AquaLookAndFeel" ).newInstance();
|
base = (BasicLookAndFeel) Class.forName( aquaLafClassName ).newInstance();
|
||||||
} catch( Exception ex ) {
|
} catch( Exception ex ) {
|
||||||
ex.printStackTrace();
|
LOG.log( Level.SEVERE, "FlatLaf: Failed to initialize base look and feel '" + aquaLafClassName + "'.", ex );
|
||||||
throw new IllegalStateException();
|
throw new IllegalStateException();
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
@@ -164,6 +209,9 @@ public abstract class FlatLaf
|
|||||||
public UIDefaults getDefaults() {
|
public UIDefaults getDefaults() {
|
||||||
UIDefaults defaults = getBase().getDefaults();
|
UIDefaults defaults = getBase().getDefaults();
|
||||||
|
|
||||||
|
// add Metal resource bundle, which is required for FlatFileChooserUI
|
||||||
|
defaults.addResourceBundle( "com.sun.swing.internal.plaf.metal.resources.metal" );
|
||||||
|
|
||||||
// initialize some defaults (for overriding) that are used in basic UI delegates,
|
// initialize some defaults (for overriding) that are used in basic UI delegates,
|
||||||
// but are not set in MetalLookAndFeel or BasicLookAndFeel
|
// but are not set in MetalLookAndFeel or BasicLookAndFeel
|
||||||
Color control = defaults.getColor( "control" );
|
Color control = defaults.getColor( "control" );
|
||||||
@@ -186,15 +234,36 @@ public abstract class FlatLaf
|
|||||||
Object aquaMenuBarUI = useScreenMenuBar ? defaults.get( "MenuBarUI" ) : null;
|
Object aquaMenuBarUI = useScreenMenuBar ? defaults.get( "MenuBarUI" ) : null;
|
||||||
|
|
||||||
initFonts( defaults );
|
initFonts( defaults );
|
||||||
|
initIconColors( defaults, isDark() );
|
||||||
|
initInputMaps( defaults );
|
||||||
|
|
||||||
|
// load defaults from properties
|
||||||
|
List<Class<?>> lafClassesForDefaultsLoading = getLafClassesForDefaultsLoading();
|
||||||
|
if( lafClassesForDefaultsLoading != null )
|
||||||
|
UIDefaultsLoader.loadDefaultsFromProperties( lafClassesForDefaultsLoading, defaults );
|
||||||
|
else
|
||||||
UIDefaultsLoader.loadDefaultsFromProperties( getClass(), defaults );
|
UIDefaultsLoader.loadDefaultsFromProperties( getClass(), defaults );
|
||||||
|
|
||||||
// use Aqua MenuBarUI if Mac screen menubar is enabled
|
// use Aqua MenuBarUI if Mac screen menubar is enabled
|
||||||
if( useScreenMenuBar )
|
if( useScreenMenuBar )
|
||||||
defaults.put( "MenuBarUI", aquaMenuBarUI );
|
defaults.put( "MenuBarUI", aquaMenuBarUI );
|
||||||
|
|
||||||
|
invokePostInitialization( defaults );
|
||||||
|
|
||||||
return defaults;
|
return defaults;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void invokePostInitialization( UIDefaults defaults ) {
|
||||||
|
if( postInitialization != null ) {
|
||||||
|
postInitialization.accept( defaults );
|
||||||
|
postInitialization = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Class<?>> getLafClassesForDefaultsLoading() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private void initFonts( UIDefaults defaults ) {
|
private void initFonts( UIDefaults defaults ) {
|
||||||
FontUIResource uiFont = null;
|
FontUIResource uiFont = null;
|
||||||
|
|
||||||
@@ -229,17 +298,106 @@ public abstract class FlatLaf
|
|||||||
defaults.put( key, uiFont );
|
defaults.put( key, uiFont );
|
||||||
}
|
}
|
||||||
defaults.put( "MenuItem.acceleratorFont", uiFont );
|
defaults.put( "MenuItem.acceleratorFont", uiFont );
|
||||||
|
|
||||||
|
// use smaller font for progress bar
|
||||||
|
defaults.put( "ProgressBar.font", UIScale.scaleFont( uiFont, 0.85f ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<String> split( String str, char delim ) {
|
/**
|
||||||
return UIDefaultsLoader.split( str, delim );
|
* Adds the default color palette for action icons and object icons to the given UIDefaults.
|
||||||
|
* <p>
|
||||||
|
* This method is public and static to allow using the color palette with
|
||||||
|
* other LaFs (e.g. Windows LaF). To do so invoke:
|
||||||
|
* {@code FlatLaf.initIconColors( UIManager.getLookAndFeelDefaults(), false );}
|
||||||
|
* after
|
||||||
|
* {@code UIManager.setLookAndFeel( ... );}.
|
||||||
|
* <p>
|
||||||
|
* The colors are based on IntelliJ Platform
|
||||||
|
* <a href="https://jetbrains.design/intellij/principles/icons/#action-icons">Action icons</a>
|
||||||
|
* and
|
||||||
|
* <a href="https://jetbrains.design/intellij/principles/icons/#noun-icons">Noun icons</a>
|
||||||
|
*/
|
||||||
|
public static void initIconColors( UIDefaults defaults, boolean dark ) {
|
||||||
|
// colors for action icons
|
||||||
|
// see https://jetbrains.design/intellij/principles/icons/#action-icons
|
||||||
|
defaults.put( "Actions.Red", new ColorUIResource( !dark ? 0xDB5860 : 0xC75450 ) );
|
||||||
|
defaults.put( "Actions.Yellow", new ColorUIResource( !dark ? 0xEDA200 : 0xF0A732 ) );
|
||||||
|
defaults.put( "Actions.Green", new ColorUIResource( !dark ? 0x59A869 : 0x499C54 ) );
|
||||||
|
defaults.put( "Actions.Blue", new ColorUIResource( !dark ? 0x389FD6 : 0x3592C4 ) );
|
||||||
|
defaults.put( "Actions.Grey", new ColorUIResource( !dark ? 0x6E6E6E : 0xAFB1B3 ) );
|
||||||
|
defaults.put( "Actions.GreyInline", new ColorUIResource( !dark ? 0x7F8B91 : 0x7F8B91 ) );
|
||||||
|
|
||||||
|
// colors for object icons
|
||||||
|
// see https://jetbrains.design/intellij/principles/icons/#noun-icons
|
||||||
|
defaults.put( "Objects.Grey", new ColorUIResource( 0x9AA7B0 ) );
|
||||||
|
defaults.put( "Objects.Blue", new ColorUIResource( 0x40B6E0 ) );
|
||||||
|
defaults.put( "Objects.Green", new ColorUIResource( 0x62B543 ) );
|
||||||
|
defaults.put( "Objects.Yellow", new ColorUIResource( 0xF4AF3D ) );
|
||||||
|
defaults.put( "Objects.YellowDark", new ColorUIResource( 0xD9A343 ) );
|
||||||
|
defaults.put( "Objects.Purple", new ColorUIResource( 0xB99BF8 ) );
|
||||||
|
defaults.put( "Objects.Pink", new ColorUIResource( 0xF98B9E ) );
|
||||||
|
defaults.put( "Objects.Red", new ColorUIResource( 0xF26522 ) );
|
||||||
|
defaults.put( "Objects.RedStatus", new ColorUIResource( 0xE05555 ) );
|
||||||
|
defaults.put( "Objects.GreenAndroid", new ColorUIResource( 0xA4C639 ) );
|
||||||
|
defaults.put( "Objects.BlackText", new ColorUIResource( 0x231F20 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initInputMaps( UIDefaults defaults ) {
|
||||||
|
if( SystemInfo.IS_MAC ) {
|
||||||
|
// AquaLookAndFeel (the base for UI defaults on macOS) uses special
|
||||||
|
// action keys (e.g. "aquaExpandNode") for some macOS specific behaviour.
|
||||||
|
// Those action keys are not available in FlatLaf, which makes it
|
||||||
|
// necessary to make some modifications.
|
||||||
|
|
||||||
|
// combobox
|
||||||
|
defaults.put( "ComboBox.ancestorInputMap", new UIDefaults.LazyInputMap( new Object[] {
|
||||||
|
"ESCAPE", "hidePopup",
|
||||||
|
"PAGE_UP", "pageUpPassThrough",
|
||||||
|
"PAGE_DOWN", "pageDownPassThrough",
|
||||||
|
"HOME", "homePassThrough",
|
||||||
|
"END", "endPassThrough",
|
||||||
|
"DOWN", "selectNext",
|
||||||
|
"KP_DOWN", "selectNext",
|
||||||
|
"SPACE", "spacePopup",
|
||||||
|
"ENTER", "enterPressed",
|
||||||
|
"UP", "selectPrevious",
|
||||||
|
"KP_UP", "selectPrevious"
|
||||||
|
} ) );
|
||||||
|
|
||||||
|
// tree node expanding/collapsing
|
||||||
|
modifyInputMap( defaults, "Tree.focusInputMap",
|
||||||
|
"RIGHT", "selectChild",
|
||||||
|
"KP_RIGHT", "selectChild",
|
||||||
|
"LEFT", "selectParent",
|
||||||
|
"KP_LEFT", "selectParent",
|
||||||
|
"shift RIGHT", null,
|
||||||
|
"shift KP_RIGHT", null,
|
||||||
|
"shift LEFT", null,
|
||||||
|
"shift KP_LEFT", null,
|
||||||
|
"ctrl LEFT", null,
|
||||||
|
"ctrl KP_LEFT", null,
|
||||||
|
"ctrl RIGHT", null,
|
||||||
|
"ctrl KP_RIGHT", null
|
||||||
|
);
|
||||||
|
defaults.put( "Tree.focusInputMap.RightToLeft", new UIDefaults.LazyInputMap( new Object[] {
|
||||||
|
"RIGHT", "selectParent",
|
||||||
|
"KP_RIGHT", "selectParent",
|
||||||
|
"LEFT", "selectChild",
|
||||||
|
"KP_LEFT", "selectChild"
|
||||||
|
} ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void modifyInputMap( UIDefaults defaults, String key, Object... bindings ) {
|
||||||
|
// Note: not using `defaults.get(key)` here because this would resolve the lazy value
|
||||||
|
defaults.put( key, new LazyModifyInputMap( defaults.remove( key ), bindings ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void reSetLookAndFeel() {
|
private static void reSetLookAndFeel() {
|
||||||
EventQueue.invokeLater( () -> {
|
EventQueue.invokeLater( () -> {
|
||||||
|
LookAndFeel lookAndFeel = UIManager.getLookAndFeel();
|
||||||
try {
|
try {
|
||||||
// re-set current LaF
|
// re-set current LaF
|
||||||
LookAndFeel lookAndFeel = UIManager.getLookAndFeel();
|
|
||||||
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 ourself because old and new LaF are the same
|
||||||
@@ -250,7 +408,7 @@ public abstract class FlatLaf
|
|||||||
// update UI
|
// update UI
|
||||||
updateUI();
|
updateUI();
|
||||||
} catch( UnsupportedLookAndFeelException ex ) {
|
} catch( UnsupportedLookAndFeelException ex ) {
|
||||||
ex.printStackTrace();
|
LOG.log( Level.SEVERE, "FlatLaf: Failed to reinitialize look and feel '" + lookAndFeel.getClass().getName() + "'.", ex );
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
@@ -265,35 +423,61 @@ public abstract class FlatLaf
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isShowMnemonics() {
|
public static boolean isShowMnemonics() {
|
||||||
return altKeyPressed || !UIManager.getBoolean( "Component.hideMnemonics" );
|
return showMnemonics || !UIManager.getBoolean( "Component.hideMnemonics" );
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void altKeyChanged( boolean pressed ) {
|
private static void checkShowMnemonics( KeyEvent e ) {
|
||||||
if( pressed == altKeyPressed )
|
int keyCode = e.getKeyCode();
|
||||||
|
if( SystemInfo.IS_MAC ) {
|
||||||
|
// Ctrl+Alt keys must be pressed on Mac
|
||||||
|
if( keyCode == KeyEvent.VK_CONTROL || keyCode == KeyEvent.VK_ALT )
|
||||||
|
showMnemonics( e.getID() == KeyEvent.KEY_PRESSED && e.isControlDown() && e.isAltDown(), e.getComponent() );
|
||||||
|
} else {
|
||||||
|
// Alt key must be pressed on Windows and Linux
|
||||||
|
if( keyCode == KeyEvent.VK_ALT )
|
||||||
|
showMnemonics( e.getID() == KeyEvent.KEY_PRESSED, e.getComponent() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void showMnemonics( boolean show, Component c ) {
|
||||||
|
if( show == showMnemonics )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
altKeyPressed = pressed;
|
showMnemonics = show;
|
||||||
|
|
||||||
// check whether it is necessary to repaint
|
// check whether it is necessary to repaint
|
||||||
if( !UIManager.getBoolean( "Component.hideMnemonics" ) )
|
if( !UIManager.getBoolean( "Component.hideMnemonics" ) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// get focus owner
|
if( show ) {
|
||||||
Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
|
// get root pane
|
||||||
if( focusOwner == null )
|
JRootPane rootPane = SwingUtilities.getRootPane( c );
|
||||||
|
if( rootPane == null )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// get focused window
|
// get window
|
||||||
Window window = SwingUtilities.windowForComponent( focusOwner );
|
Window window = SwingUtilities.getWindowAncestor( rootPane );
|
||||||
if( window == null )
|
if( window == null )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// repaint components with mnemonics in focused window
|
// repaint components with mnemonics in focused window
|
||||||
repaintMnemonics( window );
|
repaintMnemonics( window );
|
||||||
|
|
||||||
|
lastShowMnemonicWindow = new WeakReference<>( window );
|
||||||
|
} else if( lastShowMnemonicWindow != null ) {
|
||||||
|
Window window = lastShowMnemonicWindow.get();
|
||||||
|
if( window != null )
|
||||||
|
repaintMnemonics( window );
|
||||||
|
|
||||||
|
lastShowMnemonicWindow = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void repaintMnemonics( Container container ) {
|
private static void repaintMnemonics( Container container ) {
|
||||||
for( Component c : container.getComponents() ) {
|
for( Component c : container.getComponents() ) {
|
||||||
|
if( !c.isVisible() )
|
||||||
|
continue;
|
||||||
|
|
||||||
if( hasMnemonic( c ) )
|
if( hasMnemonic( c ) )
|
||||||
c.repaint();
|
c.repaint();
|
||||||
|
|
||||||
@@ -320,4 +504,40 @@ public abstract class FlatLaf
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---- class LazyModifyInputMap -------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes a (lazy) base input map and lazily applies modifications to it specified in bindings.
|
||||||
|
*/
|
||||||
|
private static class LazyModifyInputMap
|
||||||
|
implements LazyValue
|
||||||
|
{
|
||||||
|
private final Object baseInputMap;
|
||||||
|
private final Object[] bindings;
|
||||||
|
|
||||||
|
public LazyModifyInputMap( Object baseInputMap, Object[] bindings ) {
|
||||||
|
this.baseInputMap = baseInputMap;
|
||||||
|
this.bindings = bindings;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object createValue( UIDefaults table ) {
|
||||||
|
// get base input map
|
||||||
|
InputMap inputMap = (baseInputMap instanceof LazyValue)
|
||||||
|
? (InputMap) ((LazyValue)baseInputMap).createValue( table )
|
||||||
|
: (InputMap) baseInputMap;
|
||||||
|
|
||||||
|
// modify input map (replace or remove)
|
||||||
|
for( int i = 0; i < bindings.length; i += 2 ) {
|
||||||
|
KeyStroke keyStroke = KeyStroke.getKeyStroke( (String) bindings[i] );
|
||||||
|
if( bindings[i + 1] != null )
|
||||||
|
inputMap.put( keyStroke, bindings[i + 1] );
|
||||||
|
else
|
||||||
|
inputMap.remove( keyStroke );
|
||||||
|
}
|
||||||
|
|
||||||
|
return inputMap;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,537 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 FormDev Software GmbH
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.formdev.flatlaf;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Enumeration;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import javax.swing.UIDefaults;
|
||||||
|
import javax.swing.plaf.ColorUIResource;
|
||||||
|
import com.formdev.flatlaf.json.Json;
|
||||||
|
import com.formdev.flatlaf.json.ParseException;
|
||||||
|
import com.formdev.flatlaf.util.StringUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class supports loading IntelliJ .theme.json files and using them as a Laf.
|
||||||
|
*
|
||||||
|
* .theme.json files are used by Theme plugins for IntelliJ IDEA and other
|
||||||
|
* JetBrains IDEs that are based on IntelliJ platform.
|
||||||
|
*
|
||||||
|
* Here you can find IntelliJ Theme plugins:
|
||||||
|
* https://plugins.jetbrains.com/search?tags=Theme
|
||||||
|
*
|
||||||
|
* The IntelliJ .theme.json file are documented here:
|
||||||
|
* http://www.jetbrains.org/intellij/sdk/docs/reference_guide/ui_themes/themes_customize.html
|
||||||
|
*
|
||||||
|
* @author Karl Tauber
|
||||||
|
*/
|
||||||
|
public class IntelliJTheme
|
||||||
|
{
|
||||||
|
public final String name;
|
||||||
|
public final boolean dark;
|
||||||
|
public final String author;
|
||||||
|
|
||||||
|
private final Map<String, String> colors;
|
||||||
|
private final Map<String, Object> ui;
|
||||||
|
private final Map<String, Object> icons;
|
||||||
|
|
||||||
|
private Map<String, ColorUIResource> namedColors = Collections.emptyMap();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads a IntelliJ .theme.json file from the given input stream,
|
||||||
|
* creates a Laf instance for it and installs it.
|
||||||
|
*
|
||||||
|
* The input stream is automatically closed.
|
||||||
|
* Using a buffered input stream is not necessary.
|
||||||
|
*/
|
||||||
|
public static boolean install( InputStream in ) {
|
||||||
|
try {
|
||||||
|
return FlatLaf.install( createLaf( in ) );
|
||||||
|
} catch( Exception ex ) {
|
||||||
|
FlatLaf.LOG.log( Level.SEVERE, "FlatLaf: Failed to load IntelliJ theme", ex );
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads a IntelliJ .theme.json file from the given input stream and
|
||||||
|
* creates a Laf instance for it.
|
||||||
|
*
|
||||||
|
* The input stream is automatically closed.
|
||||||
|
* Using a buffered input stream is not necessary.
|
||||||
|
*/
|
||||||
|
public static FlatLaf createLaf( InputStream in )
|
||||||
|
throws IOException, ParseException
|
||||||
|
{
|
||||||
|
return createLaf( new IntelliJTheme( in ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a Laf instance for the given IntelliJ theme.
|
||||||
|
*/
|
||||||
|
public static FlatLaf createLaf( IntelliJTheme theme ) {
|
||||||
|
return new ThemeLaf( theme );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads a IntelliJ .theme.json file from the given input stream.
|
||||||
|
*
|
||||||
|
* The input stream is automatically closed.
|
||||||
|
* Using a buffered input stream is not necessary.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings( "unchecked" )
|
||||||
|
public IntelliJTheme( InputStream in )
|
||||||
|
throws IOException, ParseException
|
||||||
|
{
|
||||||
|
Map<String, Object> json;
|
||||||
|
try( Reader reader = new InputStreamReader( in, StandardCharsets.UTF_8 ) ) {
|
||||||
|
json = (Map<String, Object>) Json.parse( reader );
|
||||||
|
}
|
||||||
|
|
||||||
|
name = (String) json.get( "name" );
|
||||||
|
dark = Boolean.parseBoolean( (String) json.get( "dark" ) );
|
||||||
|
author = (String) json.get( "author" );
|
||||||
|
|
||||||
|
colors = (Map<String, String>) json.get( "colors" );
|
||||||
|
ui = (Map<String, Object>) json.get( "ui" );
|
||||||
|
icons = (Map<String, Object>) json.get( "icons" );
|
||||||
|
}
|
||||||
|
|
||||||
|
private void applyProperties( UIDefaults defaults ) {
|
||||||
|
if( ui == null )
|
||||||
|
return;
|
||||||
|
|
||||||
|
defaults.put( "Component.isIntelliJTheme", true );
|
||||||
|
|
||||||
|
// enable button shadows
|
||||||
|
defaults.put( "Button.paintShadow", true );
|
||||||
|
defaults.put( "Button.shadowWidth", dark ? 2 : 1 );
|
||||||
|
|
||||||
|
loadNamedColors( defaults );
|
||||||
|
|
||||||
|
// convert Json "ui" structure to UI defaults
|
||||||
|
ArrayList<Object> defaultsKeysCache = new ArrayList<>();
|
||||||
|
Set<String> uiKeys = new HashSet<>();
|
||||||
|
for( Map.Entry<String, Object> e : ui.entrySet() )
|
||||||
|
apply( e.getKey(), e.getValue(), defaults, defaultsKeysCache, uiKeys );
|
||||||
|
|
||||||
|
applyColorPalette( defaults );
|
||||||
|
applyCheckBoxColors( defaults );
|
||||||
|
|
||||||
|
// IDEA uses a SVG icon for the help button, but paints the background with Button.startBackground and Button.endBackground
|
||||||
|
Object helpButtonBackground = defaults.get( "Button.startBackground" );
|
||||||
|
Object helpButtonBorderColor = defaults.get( "Button.startBorderColor" );
|
||||||
|
if( helpButtonBackground == null )
|
||||||
|
helpButtonBackground = defaults.get( "Button.background" );
|
||||||
|
if( helpButtonBorderColor == null )
|
||||||
|
helpButtonBorderColor = defaults.get( "Button.borderColor" );
|
||||||
|
defaults.put( "HelpButton.background", helpButtonBackground );
|
||||||
|
defaults.put( "HelpButton.borderColor", helpButtonBorderColor );
|
||||||
|
defaults.put( "HelpButton.disabledBackground", defaults.get( "Panel.background" ) );
|
||||||
|
defaults.put( "HelpButton.disabledBorderColor", defaults.get( "Button.disabledBorderColor" ) );
|
||||||
|
defaults.put( "HelpButton.focusedBorderColor", defaults.get( "Button.focusedBorderColor" ) );
|
||||||
|
defaults.put( "HelpButton.focusedBackground", defaults.get( "Button.focusedBackground" ) );
|
||||||
|
|
||||||
|
// IDEA uses TextField.background for editable ComboBox and Spinner
|
||||||
|
defaults.put( "ComboBox.editableBackground", defaults.get( "TextField.background" ) );
|
||||||
|
defaults.put( "Spinner.background", defaults.get( "TextField.background" ) );
|
||||||
|
|
||||||
|
// Spinner arrow button always has same colors as ComboBox arrow button
|
||||||
|
defaults.put( "Spinner.buttonBackground", defaults.get( "ComboBox.buttonEditableBackground" ) );
|
||||||
|
defaults.put( "Spinner.buttonArrowColor", defaults.get( "ComboBox.buttonArrowColor" ) );
|
||||||
|
defaults.put( "Spinner.buttonDisabledArrowColor", defaults.get( "ComboBox.buttonDisabledArrowColor" ) );
|
||||||
|
|
||||||
|
// some themes specify colors for TextField.background, but forget to specify it for other components
|
||||||
|
// (probably because those components are not used in IntelliJ)
|
||||||
|
if( uiKeys.contains( "TextField.background" ) ) {
|
||||||
|
Object textFieldBackground = defaults.get( "TextField.background" );
|
||||||
|
if( !uiKeys.contains( "FormattedTextField.background" ) )
|
||||||
|
defaults.put( "FormattedTextField.background", textFieldBackground );
|
||||||
|
if( !uiKeys.contains( "PasswordField.background" ) )
|
||||||
|
defaults.put( "PasswordField.background", textFieldBackground );
|
||||||
|
if( !uiKeys.contains( "EditorPane.background" ) )
|
||||||
|
defaults.put( "EditorPane.background", textFieldBackground );
|
||||||
|
if( !uiKeys.contains( "TextArea.background" ) )
|
||||||
|
defaults.put( "TextArea.background", textFieldBackground );
|
||||||
|
if( !uiKeys.contains( "TextPane.background" ) )
|
||||||
|
defaults.put( "TextPane.background", textFieldBackground );
|
||||||
|
if( !uiKeys.contains( "Spinner.background" ) )
|
||||||
|
defaults.put( "Spinner.background", textFieldBackground );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* http://www.jetbrains.org/intellij/sdk/docs/reference_guide/ui_themes/themes_customize.html#defining-named-colors
|
||||||
|
*/
|
||||||
|
private void loadNamedColors( UIDefaults defaults ) {
|
||||||
|
if( colors == null )
|
||||||
|
return;
|
||||||
|
|
||||||
|
namedColors = new HashMap<>();
|
||||||
|
|
||||||
|
for( Map.Entry<String, String> e : colors.entrySet() ) {
|
||||||
|
String value = e.getValue();
|
||||||
|
ColorUIResource color = UIDefaultsLoader.parseColor( value );
|
||||||
|
if( color != null ) {
|
||||||
|
String key = e.getKey();
|
||||||
|
namedColors.put( key, color );
|
||||||
|
defaults.put( "ColorPalette." + e.getKey(), color );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* http://www.jetbrains.org/intellij/sdk/docs/reference_guide/ui_themes/themes_customize.html#custom-ui-control-colors
|
||||||
|
*/
|
||||||
|
@SuppressWarnings( "unchecked" )
|
||||||
|
private void apply( String key, Object value, UIDefaults defaults, ArrayList<Object> defaultsKeysCache, Set<String> uiKeys ) {
|
||||||
|
if( value instanceof Map ) {
|
||||||
|
for( Map.Entry<String, Object> e : ((Map<String, Object>)value).entrySet() )
|
||||||
|
apply( key + '.' + e.getKey(), e.getValue(), defaults, defaultsKeysCache, uiKeys );
|
||||||
|
} else {
|
||||||
|
uiKeys.add( key );
|
||||||
|
|
||||||
|
// map keys
|
||||||
|
key = uiKeyMapping.getOrDefault( key, key );
|
||||||
|
if( key.isEmpty() )
|
||||||
|
return; // ignore key
|
||||||
|
|
||||||
|
String valueStr = value.toString();
|
||||||
|
|
||||||
|
// map named colors
|
||||||
|
Object uiValue = namedColors.get( valueStr );
|
||||||
|
|
||||||
|
// parse value
|
||||||
|
if( uiValue == null ) {
|
||||||
|
// fix errors (missing '#' for colors)
|
||||||
|
if( !valueStr.startsWith( "#" ) && (key.endsWith( "ground" ) || key.endsWith( "Color" )) )
|
||||||
|
valueStr = fixColorIfValid( "#" + valueStr, valueStr );
|
||||||
|
else if( valueStr.startsWith( "##" ) )
|
||||||
|
valueStr = fixColorIfValid( valueStr.substring( 1 ), valueStr );
|
||||||
|
else if( key.endsWith( ".border" ) || key.endsWith( "Border" ) ) {
|
||||||
|
List<String> parts = StringUtils.split( valueStr, ',' );
|
||||||
|
if( parts.size() == 5 && !parts.get( 4 ).startsWith( "#" ) ) {
|
||||||
|
parts.set( 4, "#" + parts.get( 4 ) );
|
||||||
|
valueStr = String.join( ",", parts );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse value
|
||||||
|
try {
|
||||||
|
uiValue = UIDefaultsLoader.parseValue( key, valueStr );
|
||||||
|
} catch( RuntimeException ex ) {
|
||||||
|
UIDefaultsLoader.logParseError( Level.CONFIG, key, valueStr, ex );
|
||||||
|
return; // ignore invalid value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( key.startsWith( "*." ) ) {
|
||||||
|
// wildcard
|
||||||
|
String tail = key.substring( 1 );
|
||||||
|
|
||||||
|
// because we can not iterate over the UI defaults keys while
|
||||||
|
// modifying UI defaults in the same loop, we have to copy the keys
|
||||||
|
if( defaultsKeysCache.size() != defaults.size() ) {
|
||||||
|
defaultsKeysCache.clear();
|
||||||
|
Enumeration<Object> e = defaults.keys();
|
||||||
|
while( e.hasMoreElements() )
|
||||||
|
defaultsKeysCache.add( e.nextElement() );
|
||||||
|
}
|
||||||
|
|
||||||
|
// replace all values in UI defaults that match the wildcard key
|
||||||
|
for( Object k : defaultsKeysCache ) {
|
||||||
|
if( k instanceof String ) {
|
||||||
|
// support replacing of mapped keys
|
||||||
|
// (e.g. set ComboBox.buttonEditableBackground to *.background
|
||||||
|
// because it is mapped from ComboBox.ArrowButton.background)
|
||||||
|
String km = uiKeyInverseMapping.getOrDefault( k, (String) k );
|
||||||
|
if( km.endsWith( tail ) && !noWildcardReplace.contains( k ) && !((String)k).startsWith( "CheckBox.icon." ) )
|
||||||
|
defaults.put( k, uiValue );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
defaults.put( key, uiValue );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String fixColorIfValid( String newColorStr, String colorStr ) {
|
||||||
|
try {
|
||||||
|
// check whether it is valid
|
||||||
|
UIDefaultsLoader.parseColorRGBA( newColorStr );
|
||||||
|
|
||||||
|
return newColorStr;
|
||||||
|
} catch( IllegalArgumentException ex ) {
|
||||||
|
return colorStr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void applyColorPalette( UIDefaults defaults ) {
|
||||||
|
if( icons == null )
|
||||||
|
return;
|
||||||
|
|
||||||
|
Object palette = icons.get( "ColorPalette" );
|
||||||
|
if( !(palette instanceof Map) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
@SuppressWarnings( "unchecked" )
|
||||||
|
Map<String, Object> colorPalette = (Map<String, Object>) palette;
|
||||||
|
for( Map.Entry<String, Object> e : colorPalette.entrySet() ) {
|
||||||
|
String key = e.getKey();
|
||||||
|
Object value = e.getValue();
|
||||||
|
if( key.startsWith( "Checkbox." ) || !(value instanceof String) )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if( dark )
|
||||||
|
key = StringUtils.removeTrailing( key, ".Dark" );
|
||||||
|
|
||||||
|
ColorUIResource color = toColor( (String) value );
|
||||||
|
if( color != null )
|
||||||
|
defaults.put( key, color );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ColorUIResource toColor( String value ) {
|
||||||
|
// map named colors
|
||||||
|
ColorUIResource color = namedColors.get( value );
|
||||||
|
|
||||||
|
// parse color
|
||||||
|
return (color != null) ? color : UIDefaultsLoader.parseColor( value );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Because IDEA uses SVGs for check boxes and radio buttons the colors for
|
||||||
|
* this two components are specified in "icons > ColorPalette".
|
||||||
|
* FlatLaf uses vector icons and expects colors for the two components in UI defaults.
|
||||||
|
*/
|
||||||
|
private void applyCheckBoxColors( UIDefaults defaults ) {
|
||||||
|
if( icons == null )
|
||||||
|
return;
|
||||||
|
|
||||||
|
Object palette = icons.get( "ColorPalette" );
|
||||||
|
if( !(palette instanceof Map) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
boolean checkboxModified = false;
|
||||||
|
@SuppressWarnings( "unchecked" )
|
||||||
|
Map<String, Object> colorPalette = (Map<String, Object>) palette;
|
||||||
|
for( Map.Entry<String, Object> e : colorPalette.entrySet() ) {
|
||||||
|
String key = e.getKey();
|
||||||
|
Object value = e.getValue();
|
||||||
|
if( !key.startsWith( "Checkbox." ) || !(value instanceof String) )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if( key.equals( "Checkbox.Background.Default" ) ||
|
||||||
|
key.equals( "Checkbox.Foreground.Selected" ) )
|
||||||
|
{
|
||||||
|
// This two keys do not work correctly in IDEA because they
|
||||||
|
// map SVG color "#ffffff" to another color, but checkBox.svg and
|
||||||
|
// radio.svg (in package com.intellij.ide.ui.laf.icons.intellij)
|
||||||
|
// use "#fff". So use white to get same appearance as in IDEA.
|
||||||
|
value = "#ffffff";
|
||||||
|
}
|
||||||
|
|
||||||
|
String key2 = checkboxDuplicateColors.get( key );
|
||||||
|
|
||||||
|
if( dark )
|
||||||
|
key = StringUtils.removeTrailing( key, ".Dark" );
|
||||||
|
|
||||||
|
String newKey = checkboxKeyMapping.get( key );
|
||||||
|
if( newKey != null ) {
|
||||||
|
ColorUIResource color = toColor( (String) value );
|
||||||
|
if( color != null ) {
|
||||||
|
defaults.put( newKey, color );
|
||||||
|
|
||||||
|
if( key2 != null ) {
|
||||||
|
// When IDEA replaces colors in SVGs it uses color values and not the keys
|
||||||
|
// from com.intellij.ide.ui.UITheme.colorPalette, but there are some keys that
|
||||||
|
// have same color value:
|
||||||
|
// - Checkbox.Background.Default.Dark has same color as Checkbox.Background.Selected.Dark
|
||||||
|
// - Checkbox.Border.Default.Dark has same color as Checkbox.Border.Selected.Dark
|
||||||
|
// - Checkbox.Focus.Thin.Default.Dark has same color as Checkbox.Focus.Thin.Selected.Dark
|
||||||
|
//
|
||||||
|
// So if only e.g. Checkbox.Background.Default.Dark is specified in .theme.json,
|
||||||
|
// then this color is also used for Checkbox.Background.Selected.Dark.
|
||||||
|
//
|
||||||
|
// If Checkbox.Background.Default.Dark and Checkbox.Background.Selected.Dark
|
||||||
|
// are specified in .theme.json, then the later specified is used for both.
|
||||||
|
if( dark )
|
||||||
|
key2 = StringUtils.removeTrailing( key2, ".Dark" );
|
||||||
|
|
||||||
|
String newKey2 = checkboxKeyMapping.get( key2 );
|
||||||
|
if( newKey2 != null )
|
||||||
|
defaults.put( newKey2, color );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
checkboxModified = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove hover and pressed colors
|
||||||
|
if( checkboxModified ) {
|
||||||
|
defaults.remove( "CheckBox.icon.hoverBorderColor" );
|
||||||
|
defaults.remove( "CheckBox.icon.focusedBackground" );
|
||||||
|
defaults.remove( "CheckBox.icon.hoverBackground" );
|
||||||
|
defaults.remove( "CheckBox.icon.pressedBackground" );
|
||||||
|
defaults.remove( "CheckBox.icon.selectedHoverBackground" );
|
||||||
|
defaults.remove( "CheckBox.icon.selectedPressedBackground" );
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy values
|
||||||
|
for( Map.Entry<String, String> e : uiKeyCopying.entrySet() )
|
||||||
|
defaults.put( e.getKey(), defaults.get( e.getValue() ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Map<String, String> uiKeyMapping = new HashMap<>();
|
||||||
|
private static Map<String, String> uiKeyCopying = new HashMap<>();
|
||||||
|
private static Map<String, String> uiKeyInverseMapping = new HashMap<>();
|
||||||
|
private static Map<String, String> checkboxKeyMapping = new HashMap<>();
|
||||||
|
private static Map<String, String> checkboxDuplicateColors = new HashMap<>();
|
||||||
|
private static Set<String> noWildcardReplace = new HashSet<>();
|
||||||
|
|
||||||
|
static {
|
||||||
|
// ComboBox
|
||||||
|
uiKeyMapping.put( "ComboBox.background", "" ); // ignore
|
||||||
|
uiKeyMapping.put( "ComboBox.nonEditableBackground", "ComboBox.background" );
|
||||||
|
uiKeyMapping.put( "ComboBox.ArrowButton.background", "ComboBox.buttonEditableBackground" );
|
||||||
|
uiKeyMapping.put( "ComboBox.ArrowButton.disabledIconColor", "ComboBox.buttonDisabledArrowColor" );
|
||||||
|
uiKeyMapping.put( "ComboBox.ArrowButton.iconColor", "ComboBox.buttonArrowColor" );
|
||||||
|
uiKeyMapping.put( "ComboBox.ArrowButton.nonEditableBackground", "ComboBox.buttonBackground" );
|
||||||
|
|
||||||
|
// Link
|
||||||
|
uiKeyMapping.put( "Link.activeForeground", "Component.linkColor" );
|
||||||
|
|
||||||
|
// ProgressBar
|
||||||
|
uiKeyMapping.put( "ProgressBar.background", "" ); // ignore
|
||||||
|
uiKeyMapping.put( "ProgressBar.foreground", "" ); // ignore
|
||||||
|
uiKeyMapping.put( "ProgressBar.trackColor", "ProgressBar.background" );
|
||||||
|
uiKeyMapping.put( "ProgressBar.progressColor", "ProgressBar.foreground" );
|
||||||
|
|
||||||
|
// ScrollBar
|
||||||
|
uiKeyMapping.put( "ScrollBar.trackColor", "ScrollBar.track" );
|
||||||
|
uiKeyMapping.put( "ScrollBar.thumbColor", "ScrollBar.thumb" );
|
||||||
|
|
||||||
|
// Separator
|
||||||
|
uiKeyMapping.put( "Separator.separatorColor", "Separator.foreground" );
|
||||||
|
|
||||||
|
// Slider
|
||||||
|
uiKeyMapping.put( "Slider.trackWidth", "" ); // ignore (used in Material Theme UI Lite)
|
||||||
|
|
||||||
|
for( Map.Entry<String, String> e : uiKeyMapping.entrySet() )
|
||||||
|
uiKeyInverseMapping.put( e.getValue(), e.getKey() );
|
||||||
|
|
||||||
|
uiKeyCopying.put( "ToggleButton.tab.underlineColor", "TabbedPane.underlineColor" );
|
||||||
|
uiKeyCopying.put( "ToggleButton.tab.disabledUnderlineColor", "TabbedPane.disabledUnderlineColor" );
|
||||||
|
uiKeyCopying.put( "ToggleButton.tab.selectedBackground", "TabbedPane.selectedBackground" );
|
||||||
|
uiKeyCopying.put( "ToggleButton.tab.hoverBackground", "TabbedPane.hoverColor" );
|
||||||
|
uiKeyCopying.put( "ToggleButton.tab.focusBackground", "TabbedPane.focusColor" );
|
||||||
|
|
||||||
|
checkboxKeyMapping.put( "Checkbox.Background.Default", "CheckBox.icon.background" );
|
||||||
|
checkboxKeyMapping.put( "Checkbox.Background.Disabled", "CheckBox.icon.disabledBackground" );
|
||||||
|
checkboxKeyMapping.put( "Checkbox.Border.Default", "CheckBox.icon.borderColor" );
|
||||||
|
checkboxKeyMapping.put( "Checkbox.Border.Disabled", "CheckBox.icon.disabledBorderColor" );
|
||||||
|
checkboxKeyMapping.put( "Checkbox.Focus.Thin.Default", "CheckBox.icon.focusedBorderColor" );
|
||||||
|
checkboxKeyMapping.put( "Checkbox.Focus.Wide", "CheckBox.icon.focusedColor" );
|
||||||
|
checkboxKeyMapping.put( "Checkbox.Foreground.Disabled", "CheckBox.icon.disabledCheckmarkColor" );
|
||||||
|
checkboxKeyMapping.put( "Checkbox.Background.Selected", "CheckBox.icon.selectedBackground" );
|
||||||
|
checkboxKeyMapping.put( "Checkbox.Border.Selected", "CheckBox.icon.selectedBorderColor" );
|
||||||
|
checkboxKeyMapping.put( "Checkbox.Foreground.Selected", "CheckBox.icon.checkmarkColor" );
|
||||||
|
checkboxKeyMapping.put( "Checkbox.Focus.Thin.Selected", "CheckBox.icon.selectedFocusedBorderColor" );
|
||||||
|
|
||||||
|
checkboxDuplicateColors.put( "Checkbox.Background.Default.Dark", "Checkbox.Background.Selected.Dark" );
|
||||||
|
checkboxDuplicateColors.put( "Checkbox.Border.Default.Dark", "Checkbox.Border.Selected.Dark" );
|
||||||
|
checkboxDuplicateColors.put( "Checkbox.Focus.Thin.Default.Dark", "Checkbox.Focus.Thin.Selected.Dark" );
|
||||||
|
@SuppressWarnings( "unchecked" )
|
||||||
|
Map.Entry<String, String>[] entries = checkboxDuplicateColors.entrySet().toArray( new Map.Entry[checkboxDuplicateColors.size()] );
|
||||||
|
for( Map.Entry<String, String> e : entries )
|
||||||
|
checkboxDuplicateColors.put( e.getValue(), e.getKey() );
|
||||||
|
|
||||||
|
// because FlatLaf uses Button.background and Button.borderColor,
|
||||||
|
// but IDEA uses Button.startBackground and Button.startBorderColor,
|
||||||
|
// our default button background and border colors may be replaced by
|
||||||
|
// wildcard *.background and *.borderColor colors
|
||||||
|
noWildcardReplace.add( "Button.background" );
|
||||||
|
noWildcardReplace.add( "Button.borderColor" );
|
||||||
|
noWildcardReplace.add( "Button.default.background" );
|
||||||
|
noWildcardReplace.add( "Button.default.borderColor" );
|
||||||
|
noWildcardReplace.add( "ToggleButton.background" );
|
||||||
|
}
|
||||||
|
|
||||||
|
//---- class ThemeLaf -----------------------------------------------------
|
||||||
|
|
||||||
|
public static class ThemeLaf
|
||||||
|
extends FlatLaf
|
||||||
|
{
|
||||||
|
private final IntelliJTheme theme;
|
||||||
|
|
||||||
|
public ThemeLaf( IntelliJTheme theme ) {
|
||||||
|
this.theme = theme;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return theme.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getDescription() {
|
||||||
|
return theme.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDark() {
|
||||||
|
return theme.dark;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IntelliJTheme getTheme() {
|
||||||
|
return theme;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UIDefaults getDefaults() {
|
||||||
|
UIDefaults defaults = super.getDefaults();
|
||||||
|
theme.applyProperties( defaults );
|
||||||
|
super.invokePostInitialization( defaults );
|
||||||
|
return defaults;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
void invokePostInitialization( UIDefaults defaults ) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
ArrayList<Class<?>> getLafClassesForDefaultsLoading() {
|
||||||
|
ArrayList<Class<?>> lafClasses = new ArrayList<>();
|
||||||
|
lafClasses.add( FlatLaf.class );
|
||||||
|
lafClasses.add( theme.dark ? FlatDarkLaf.class : FlatLightLaf.class );
|
||||||
|
lafClasses.add( theme.dark ? FlatDarculaLaf.class : FlatIntelliJLaf.class );
|
||||||
|
lafClasses.add( ThemeLaf.class );
|
||||||
|
return lafClasses;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -27,7 +27,9 @@ import java.util.ArrayList;
|
|||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
|
import java.util.logging.Level;
|
||||||
import javax.swing.text.StyleContext;
|
import javax.swing.text.StyleContext;
|
||||||
|
import com.formdev.flatlaf.util.StringUtils;
|
||||||
import com.formdev.flatlaf.util.SystemInfo;
|
import com.formdev.flatlaf.util.SystemInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -151,7 +153,7 @@ class LinuxFontPolicy
|
|||||||
int size = 10;
|
int size = 10;
|
||||||
|
|
||||||
if( generalFont != null ) {
|
if( generalFont != null ) {
|
||||||
List<String> strs = FlatLaf.split( generalFont, ',' );
|
List<String> strs = StringUtils.split( generalFont, ',' );
|
||||||
try {
|
try {
|
||||||
family = strs.get( 0 );
|
family = strs.get( 0 );
|
||||||
size = Integer.parseInt( strs.get( 1 ) );
|
size = Integer.parseInt( strs.get( 1 ) );
|
||||||
@@ -160,7 +162,7 @@ class LinuxFontPolicy
|
|||||||
if( "1".equals( strs.get( 5 ) ) )
|
if( "1".equals( strs.get( 5 ) ) )
|
||||||
style |= Font.ITALIC;
|
style |= Font.ITALIC;
|
||||||
} catch( RuntimeException ex ) {
|
} catch( RuntimeException ex ) {
|
||||||
ex.printStackTrace();
|
FlatLaf.LOG.log( Level.CONFIG, "FlatLaf: Failed to parse 'font=" + generalFont + "'.", ex );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,7 +176,7 @@ class LinuxFontPolicy
|
|||||||
if( dpi < 50 )
|
if( dpi < 50 )
|
||||||
dpi = 50;
|
dpi = 50;
|
||||||
} catch( NumberFormatException ex ) {
|
} catch( NumberFormatException ex ) {
|
||||||
ex.printStackTrace();
|
FlatLaf.LOG.log( Level.CONFIG, "FlatLaf: Failed to parse 'forceFontDPI=" + forceFontDPI + "'.", ex );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,7 +215,7 @@ class LinuxFontPolicy
|
|||||||
while( (line = reader.readLine()) != null )
|
while( (line = reader.readLine()) != null )
|
||||||
lines.add( line );
|
lines.add( line );
|
||||||
} catch( IOException ex ) {
|
} catch( IOException ex ) {
|
||||||
ex.printStackTrace();
|
FlatLaf.LOG.log( Level.CONFIG, "FlatLaf: Failed to read '" + filename + "'.", ex );
|
||||||
}
|
}
|
||||||
return lines;
|
return lines;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import java.awt.Insets;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
@@ -29,7 +30,10 @@ import java.util.Map;
|
|||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.ServiceLoader;
|
import java.util.ServiceLoader;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
import java.util.logging.Level;
|
||||||
import javax.swing.UIDefaults;
|
import javax.swing.UIDefaults;
|
||||||
|
import javax.swing.UIManager;
|
||||||
|
import javax.swing.UIDefaults.ActiveValue;
|
||||||
import javax.swing.UIDefaults.LazyValue;
|
import javax.swing.UIDefaults.LazyValue;
|
||||||
import javax.swing.plaf.ColorUIResource;
|
import javax.swing.plaf.ColorUIResource;
|
||||||
import javax.swing.plaf.DimensionUIResource;
|
import javax.swing.plaf.DimensionUIResource;
|
||||||
@@ -38,7 +42,10 @@ import com.formdev.flatlaf.ui.FlatEmptyBorder;
|
|||||||
import com.formdev.flatlaf.ui.FlatLineBorder;
|
import com.formdev.flatlaf.ui.FlatLineBorder;
|
||||||
import com.formdev.flatlaf.util.ColorFunctions;
|
import com.formdev.flatlaf.util.ColorFunctions;
|
||||||
import com.formdev.flatlaf.util.DerivedColor;
|
import com.formdev.flatlaf.util.DerivedColor;
|
||||||
import com.formdev.flatlaf.util.ScaledNumber;
|
import com.formdev.flatlaf.util.HSLColor;
|
||||||
|
import com.formdev.flatlaf.util.StringUtils;
|
||||||
|
import com.formdev.flatlaf.util.SystemInfo;
|
||||||
|
import com.formdev.flatlaf.util.UIScale;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load UI defaults from properties files associated to Flat LaF classes and add to UI defaults.
|
* Load UI defaults from properties files associated to Flat LaF classes and add to UI defaults.
|
||||||
@@ -56,7 +63,9 @@ class UIDefaultsLoader
|
|||||||
private static final String TYPE_PREFIX = "{";
|
private static final String TYPE_PREFIX = "{";
|
||||||
private static final String TYPE_PREFIX_END = "}";
|
private static final String TYPE_PREFIX_END = "}";
|
||||||
private static final String VARIABLE_PREFIX = "@";
|
private static final String VARIABLE_PREFIX = "@";
|
||||||
|
@Deprecated
|
||||||
private static final String REF_PREFIX = VARIABLE_PREFIX + "@";
|
private static final String REF_PREFIX = VARIABLE_PREFIX + "@";
|
||||||
|
private static final String PROPERTY_PREFIX = "$";
|
||||||
private static final String OPTIONAL_PREFIX = "?";
|
private static final String OPTIONAL_PREFIX = "?";
|
||||||
private static final String GLOBAL_PREFIX = "*.";
|
private static final String GLOBAL_PREFIX = "*.";
|
||||||
|
|
||||||
@@ -70,20 +79,31 @@ class UIDefaultsLoader
|
|||||||
lafClasses.add( 0, lafClass );
|
lafClasses.add( 0, lafClass );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loadDefaultsFromProperties( lafClasses, defaults );
|
||||||
|
}
|
||||||
|
|
||||||
|
static void loadDefaultsFromProperties( List<Class<?>> lafClasses, UIDefaults defaults ) {
|
||||||
try {
|
try {
|
||||||
// load properties files
|
// load core properties files
|
||||||
Properties properties = new Properties();
|
Properties properties = new Properties();
|
||||||
ServiceLoader<FlatDefaultsAddon> addonLoader = ServiceLoader.load( FlatDefaultsAddon.class );
|
|
||||||
for( Class<?> lafClass : lafClasses ) {
|
for( Class<?> lafClass : lafClasses ) {
|
||||||
// load core properties
|
String propertiesName = '/' + lafClass.getName().replace( '.', '/' ) + ".properties";
|
||||||
String propertiesName = "/" + lafClass.getName().replace( '.', '/' ) + ".properties";
|
|
||||||
try( InputStream in = lafClass.getResourceAsStream( propertiesName ) ) {
|
try( InputStream in = lafClass.getResourceAsStream( propertiesName ) ) {
|
||||||
if( in != null )
|
if( in != null )
|
||||||
properties.load( in );
|
properties.load( in );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// get addons and sort them by priority
|
||||||
|
ServiceLoader<FlatDefaultsAddon> addonLoader = ServiceLoader.load( FlatDefaultsAddon.class );
|
||||||
|
List<FlatDefaultsAddon> addonList = new ArrayList<>();
|
||||||
|
for( FlatDefaultsAddon addon : addonLoader )
|
||||||
|
addonList.add( addon );
|
||||||
|
addonList.sort( (addon1, addon2) -> addon1.getPriority() - addon2.getPriority() );
|
||||||
|
|
||||||
// load properties from addons
|
// load properties from addons
|
||||||
for( FlatDefaultsAddon addon : addonLoader ) {
|
for( FlatDefaultsAddon addon : addonList ) {
|
||||||
|
for( Class<?> lafClass : lafClasses ) {
|
||||||
try( InputStream in = addon.getDefaults( lafClass ) ) {
|
try( InputStream in = addon.getDefaults( lafClass ) ) {
|
||||||
if( in != null )
|
if( in != null )
|
||||||
properties.load( in );
|
properties.load( in );
|
||||||
@@ -91,6 +111,35 @@ class UIDefaultsLoader
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// collect addon class loaders
|
||||||
|
List<ClassLoader> addonClassLoaders = new ArrayList<>();
|
||||||
|
for( FlatDefaultsAddon addon : addonList ) {
|
||||||
|
ClassLoader addonClassLoader = addon.getClass().getClassLoader();
|
||||||
|
if( !addonClassLoaders.contains( addonClassLoader ) )
|
||||||
|
addonClassLoaders.add( addonClassLoader );
|
||||||
|
}
|
||||||
|
|
||||||
|
// collect all platform specific keys (but do not modify properties)
|
||||||
|
ArrayList<String> platformSpecificKeys = new ArrayList<>();
|
||||||
|
for( Object key : properties.keySet() ) {
|
||||||
|
if( ((String)key).startsWith( "[" ) )
|
||||||
|
platformSpecificKeys.add( (String) key );
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove platform specific properties and re-add only properties
|
||||||
|
// for current platform, but with platform prefix removed
|
||||||
|
if( !platformSpecificKeys.isEmpty() ) {
|
||||||
|
String platformPrefix =
|
||||||
|
SystemInfo.IS_WINDOWS ? "[win]" :
|
||||||
|
SystemInfo.IS_MAC ? "[mac]" :
|
||||||
|
SystemInfo.IS_LINUX ? "[linux]" : "[unknown]";
|
||||||
|
for( String key : platformSpecificKeys ) {
|
||||||
|
Object value = properties.remove( key );
|
||||||
|
if( key.startsWith( platformPrefix ) )
|
||||||
|
properties.put( key.substring( platformPrefix.length() ), value );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Function<String, String> resolver = value -> {
|
Function<String, String> resolver = value -> {
|
||||||
return resolveValue( properties, value );
|
return resolveValue( properties, value );
|
||||||
};
|
};
|
||||||
@@ -104,9 +153,9 @@ class UIDefaultsLoader
|
|||||||
|
|
||||||
String value = resolveValue( properties, (String) e.getValue() );
|
String value = resolveValue( properties, (String) e.getValue() );
|
||||||
try {
|
try {
|
||||||
globals.put( key.substring( GLOBAL_PREFIX.length() ), parseValue( key, value, resolver ) );
|
globals.put( key.substring( GLOBAL_PREFIX.length() ), parseValue( key, value, resolver, addonClassLoaders ) );
|
||||||
} catch( RuntimeException ex ) {
|
} catch( RuntimeException ex ) {
|
||||||
logParseError( key, value, ex );
|
logParseError( Level.SEVERE, key, value, ex );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,27 +178,31 @@ class UIDefaultsLoader
|
|||||||
|
|
||||||
String value = resolveValue( properties, (String) e.getValue() );
|
String value = resolveValue( properties, (String) e.getValue() );
|
||||||
try {
|
try {
|
||||||
defaults.put( key, parseValue( key, value, resolver ) );
|
defaults.put( key, parseValue( key, value, resolver, addonClassLoaders ) );
|
||||||
} catch( RuntimeException ex ) {
|
} catch( RuntimeException ex ) {
|
||||||
logParseError( key, value, ex );
|
logParseError( Level.SEVERE, key, value, ex );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch( IOException ex ) {
|
} catch( IOException ex ) {
|
||||||
ex.printStackTrace();
|
FlatLaf.LOG.log( Level.SEVERE, "FlatLaf: Failed to load properties files.", ex );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void logParseError( String key, String value, RuntimeException ex ) {
|
static void logParseError( Level level, String key, String value, RuntimeException ex ) {
|
||||||
System.err.println( "Failed to parse: '" + key + '=' + value + '\'' );
|
FlatLaf.LOG.log( level, "FlatLaf: Failed to parse: '" + key + '=' + value + '\'', ex );
|
||||||
System.err.println( " " + ex.getMessage() );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String resolveValue( Properties properties, String value ) {
|
private static String resolveValue( Properties properties, String value ) {
|
||||||
if( !value.startsWith( VARIABLE_PREFIX ) )
|
if( value.startsWith( PROPERTY_PREFIX ) )
|
||||||
|
value = value.substring( PROPERTY_PREFIX.length() );
|
||||||
|
else if( !value.startsWith( VARIABLE_PREFIX ) )
|
||||||
return value;
|
return value;
|
||||||
|
|
||||||
if( value.startsWith( REF_PREFIX ) )
|
// for compatibility
|
||||||
|
if( value.startsWith( REF_PREFIX ) ) {
|
||||||
|
FlatLaf.LOG.log( Level.WARNING, "FlatLaf: Usage of '@@' in .properties files is deprecated. Use '$' instead." );
|
||||||
value = value.substring( REF_PREFIX.length() );
|
value = value.substring( REF_PREFIX.length() );
|
||||||
|
}
|
||||||
|
|
||||||
boolean optional = false;
|
boolean optional = false;
|
||||||
if( value.startsWith( OPTIONAL_PREFIX ) ) {
|
if( value.startsWith( OPTIONAL_PREFIX ) ) {
|
||||||
@@ -162,15 +215,19 @@ class UIDefaultsLoader
|
|||||||
if( optional )
|
if( optional )
|
||||||
return "null";
|
return "null";
|
||||||
|
|
||||||
throw new IllegalArgumentException( "variable or reference '" + value + "' not found" );
|
throw new IllegalArgumentException( "variable or property '" + value + "' not found" );
|
||||||
}
|
}
|
||||||
|
|
||||||
return resolveValue( properties, newValue );
|
return resolveValue( properties, newValue );
|
||||||
}
|
}
|
||||||
|
|
||||||
private enum ValueType { UNKNOWN, STRING, INTEGER, BORDER, ICON, INSETS, SIZE, COLOR, SCALEDNUMBER }
|
private enum ValueType { UNKNOWN, STRING, INTEGER, FLOAT, BORDER, ICON, INSETS, DIMENSION, COLOR, SCALEDINTEGER, INSTANCE, CLASS }
|
||||||
|
|
||||||
private static Object parseValue( String key, String value, Function<String, String> resolver ) {
|
static Object parseValue( String key, String value ) {
|
||||||
|
return parseValue( key, value, v -> v, Collections.emptyList() );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Object parseValue( String key, String value, Function<String, String> resolver, List<ClassLoader> addonClassLoaders ) {
|
||||||
value = value.trim();
|
value = value.trim();
|
||||||
|
|
||||||
// null, false, true
|
// null, false, true
|
||||||
@@ -180,10 +237,24 @@ class UIDefaultsLoader
|
|||||||
case "true": return true;
|
case "true": return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check for function "lazy"
|
||||||
|
// Syntax: lazy(uiKey)
|
||||||
|
if( value.startsWith( "lazy(" ) && value.endsWith( ")" ) ) {
|
||||||
|
String uiKey = value.substring( 5, value.length() - 1 ).trim();
|
||||||
|
return (LazyValue) t -> {
|
||||||
|
return lazyUIManagerGet( uiKey );
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
ValueType valueType = ValueType.UNKNOWN;
|
ValueType valueType = ValueType.UNKNOWN;
|
||||||
|
|
||||||
// check whether value type is specified in the value
|
// check whether value type is specified in the value
|
||||||
if( value.startsWith( TYPE_PREFIX ) ) {
|
if( value.startsWith( "#" ) )
|
||||||
|
valueType = ValueType.COLOR;
|
||||||
|
else if( value.startsWith( "\"" ) && value.endsWith( "\"" ) ) {
|
||||||
|
valueType = ValueType.STRING;
|
||||||
|
value = value.substring( 1, value.length() - 1 );
|
||||||
|
} else if( value.startsWith( TYPE_PREFIX ) ) {
|
||||||
int end = value.indexOf( TYPE_PREFIX_END );
|
int end = value.indexOf( TYPE_PREFIX_END );
|
||||||
if( end != -1 ) {
|
if( end != -1 ) {
|
||||||
try {
|
try {
|
||||||
@@ -200,7 +271,9 @@ class UIDefaultsLoader
|
|||||||
|
|
||||||
// determine value type from key
|
// determine value type from key
|
||||||
if( valueType == ValueType.UNKNOWN ) {
|
if( valueType == ValueType.UNKNOWN ) {
|
||||||
if( key.endsWith( ".border" ) || key.endsWith( "Border" ) )
|
if( key.endsWith( "ground" ) || key.endsWith( "Color" ) )
|
||||||
|
valueType = ValueType.COLOR;
|
||||||
|
else if( key.endsWith( ".border" ) || key.endsWith( "Border" ) )
|
||||||
valueType = ValueType.BORDER;
|
valueType = ValueType.BORDER;
|
||||||
else if( key.endsWith( ".icon" ) || key.endsWith( "Icon" ) )
|
else if( key.endsWith( ".icon" ) || key.endsWith( "Icon" ) )
|
||||||
valueType = ValueType.ICON;
|
valueType = ValueType.ICON;
|
||||||
@@ -208,25 +281,30 @@ class UIDefaultsLoader
|
|||||||
key.endsWith( "Margins" ) || key.endsWith( "Insets" ) )
|
key.endsWith( "Margins" ) || key.endsWith( "Insets" ) )
|
||||||
valueType = ValueType.INSETS;
|
valueType = ValueType.INSETS;
|
||||||
else if( key.endsWith( "Size" ) )
|
else if( key.endsWith( "Size" ) )
|
||||||
valueType = ValueType.SIZE;
|
valueType = ValueType.DIMENSION;
|
||||||
else if( key.endsWith( "Width" ) || key.endsWith( "Height" ) )
|
else if( key.endsWith( "Width" ) || key.endsWith( "Height" ) )
|
||||||
valueType = ValueType.INTEGER;
|
valueType = ValueType.INTEGER;
|
||||||
|
else if( key.endsWith( "UI" ) )
|
||||||
|
valueType = ValueType.STRING;
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse value
|
// parse value
|
||||||
switch( valueType ) {
|
switch( valueType ) {
|
||||||
case STRING: return value;
|
case STRING: return value;
|
||||||
case INTEGER: return parseInteger( value, true );
|
case INTEGER: return parseInteger( value, true );
|
||||||
case BORDER: return parseBorder( value, resolver );
|
case FLOAT: return parseFloat( value, true );
|
||||||
case ICON: return parseInstance( value );
|
case BORDER: return parseBorder( value, resolver, addonClassLoaders );
|
||||||
|
case ICON: return parseInstance( value, addonClassLoaders );
|
||||||
case INSETS: return parseInsets( value );
|
case INSETS: return parseInsets( value );
|
||||||
case SIZE: return parseSize( value );
|
case DIMENSION: return parseDimension( value );
|
||||||
case COLOR: return parseColor( value, true );
|
case COLOR: return parseColorOrFunction( value, resolver, true );
|
||||||
case SCALEDNUMBER: return parseScaledNumber( value );
|
case SCALEDINTEGER: return parseScaledInteger( value );
|
||||||
|
case INSTANCE: return parseInstance( value, addonClassLoaders );
|
||||||
|
case CLASS: return parseClass( value, addonClassLoaders );
|
||||||
case UNKNOWN:
|
case UNKNOWN:
|
||||||
default:
|
default:
|
||||||
// colors
|
// colors
|
||||||
ColorUIResource color = parseColor( value, false );
|
Object color = parseColorOrFunction( value, resolver, false );
|
||||||
if( color != null )
|
if( color != null )
|
||||||
return color;
|
return color;
|
||||||
|
|
||||||
@@ -235,18 +313,23 @@ class UIDefaultsLoader
|
|||||||
if( integer != null )
|
if( integer != null )
|
||||||
return integer;
|
return integer;
|
||||||
|
|
||||||
|
// float
|
||||||
|
Float f = parseFloat( value, false );
|
||||||
|
if( f != null )
|
||||||
|
return f;
|
||||||
|
|
||||||
// string
|
// string
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Object parseBorder( String value, Function<String, String> resolver ) {
|
private static Object parseBorder( String value, Function<String, String> resolver, List<ClassLoader> addonClassLoaders ) {
|
||||||
if( value.indexOf( ',' ) >= 0 ) {
|
if( value.indexOf( ',' ) >= 0 ) {
|
||||||
// top,left,bottom,right[,lineColor]
|
// top,left,bottom,right[,lineColor]
|
||||||
List<String> parts = split( value, ',' );
|
List<String> parts = split( value, ',' );
|
||||||
Insets insets = parseInsets( value );
|
Insets insets = parseInsets( value );
|
||||||
ColorUIResource lineColor = (parts.size() == 5)
|
ColorUIResource lineColor = (parts.size() == 5)
|
||||||
? parseColor( resolver.apply( parts.get( 4 ) ), true )
|
? (ColorUIResource) parseColorOrFunction( resolver.apply( parts.get( 4 ) ), resolver, true )
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
return (LazyValue) t -> {
|
return (LazyValue) t -> {
|
||||||
@@ -255,20 +338,49 @@ class UIDefaultsLoader
|
|||||||
: new FlatEmptyBorder( insets );
|
: new FlatEmptyBorder( insets );
|
||||||
};
|
};
|
||||||
} else
|
} else
|
||||||
return parseInstance( value );
|
return parseInstance( value, addonClassLoaders );
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Object parseInstance( String value ) {
|
private static Object parseInstance( String value, List<ClassLoader> addonClassLoaders ) {
|
||||||
return (LazyValue) t -> {
|
return (LazyValue) t -> {
|
||||||
try {
|
try {
|
||||||
return Class.forName( value ).newInstance();
|
return findClass( value, addonClassLoaders ).newInstance();
|
||||||
} catch( InstantiationException | IllegalAccessException | ClassNotFoundException ex ) {
|
} catch( InstantiationException | IllegalAccessException | ClassNotFoundException ex ) {
|
||||||
ex.printStackTrace();
|
FlatLaf.LOG.log( Level.SEVERE, "FlatLaf: Failed to instantiate '" + value + "'.", ex );
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Object parseClass( String value, List<ClassLoader> addonClassLoaders ) {
|
||||||
|
return (LazyValue) t -> {
|
||||||
|
try {
|
||||||
|
return findClass( value, addonClassLoaders );
|
||||||
|
} catch( ClassNotFoundException ex ) {
|
||||||
|
FlatLaf.LOG.log( Level.SEVERE, "FlatLaf: Failed to find class '" + value + "'.", ex );
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Class<?> findClass( String className, List<ClassLoader> addonClassLoaders )
|
||||||
|
throws ClassNotFoundException
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
return Class.forName( className );
|
||||||
|
} catch( ClassNotFoundException ex ) {
|
||||||
|
// search in addons class loaders
|
||||||
|
for( ClassLoader addonClassLoader : addonClassLoaders ) {
|
||||||
|
try {
|
||||||
|
return addonClassLoader.loadClass( className );
|
||||||
|
} catch( ClassNotFoundException ex2 ) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static Insets parseInsets( String value ) {
|
private static Insets parseInsets( String value ) {
|
||||||
List<String> numbers = split( value, ',' );
|
List<String> numbers = split( value, ',' );
|
||||||
try {
|
try {
|
||||||
@@ -282,7 +394,7 @@ class UIDefaultsLoader
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Dimension parseSize( String value ) {
|
private static Dimension parseDimension( String value ) {
|
||||||
List<String> numbers = split( value, ',' );
|
List<String> numbers = split( value, ',' );
|
||||||
try {
|
try {
|
||||||
return new DimensionUIResource(
|
return new DimensionUIResource(
|
||||||
@@ -293,20 +405,24 @@ class UIDefaultsLoader
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ColorUIResource parseColor( String value, boolean reportError ) {
|
private static Object parseColorOrFunction( String value, Function<String, String> resolver, boolean reportError ) {
|
||||||
if( value.endsWith( ")" ) )
|
if( value.endsWith( ")" ) )
|
||||||
return parseColorFunctions( value, reportError );
|
return parseColorFunctions( value, resolver, reportError );
|
||||||
|
|
||||||
|
return parseColor( value, reportError );
|
||||||
|
}
|
||||||
|
|
||||||
|
static ColorUIResource parseColor( String value ) {
|
||||||
|
return parseColor( value, false );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static ColorUIResource parseColor( String value, boolean reportError ) {
|
||||||
try {
|
try {
|
||||||
int rgb = Integer.parseInt( value, 16 );
|
int rgba = parseColorRGBA( value );
|
||||||
if( value.length() == 6 )
|
return ((rgba & 0xff000000) == 0xff000000)
|
||||||
return new ColorUIResource( rgb );
|
? new ColorUIResource( rgba )
|
||||||
if( value.length() == 8 )
|
: new ColorUIResource( new Color( rgba, true ) );
|
||||||
return new ColorUIResource( new Color( rgb, true ) );
|
} catch( IllegalArgumentException ex ) {
|
||||||
|
|
||||||
if( reportError )
|
|
||||||
throw new NumberFormatException( value );
|
|
||||||
} catch( NumberFormatException ex ) {
|
|
||||||
if( reportError )
|
if( reportError )
|
||||||
throw new IllegalArgumentException( "invalid color '" + value + "'" );
|
throw new IllegalArgumentException( "invalid color '" + value + "'" );
|
||||||
|
|
||||||
@@ -315,7 +431,51 @@ class UIDefaultsLoader
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ColorUIResource parseColorFunctions( String value, boolean reportError ) {
|
/**
|
||||||
|
* Parses a hex color in {@code #RGB}, {@code #RGBA}, {@code #RRGGBB} or {@code #RRGGBBAA}
|
||||||
|
* format and returns it as {@code rgba} integer suitable for {@link java.awt.Color},
|
||||||
|
* which includes alpha component in bits 24-31.
|
||||||
|
*
|
||||||
|
* @throws IllegalArgumentException
|
||||||
|
*/
|
||||||
|
static int parseColorRGBA( String value ) {
|
||||||
|
int len = value.length();
|
||||||
|
if( (len != 4 && len != 5 && len != 7 && len != 9) || value.charAt( 0 ) != '#' )
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
|
||||||
|
// parse hex
|
||||||
|
int n = 0;
|
||||||
|
for( int i = 1; i < len; i++ ) {
|
||||||
|
char ch = value.charAt( i );
|
||||||
|
|
||||||
|
int digit;
|
||||||
|
if( ch >= '0' && ch <= '9' )
|
||||||
|
digit = ch - '0';
|
||||||
|
else if( ch >= 'a' && ch <= 'f' )
|
||||||
|
digit = ch - 'a' + 10;
|
||||||
|
else if( ch >= 'A' && ch <= 'F' )
|
||||||
|
digit = ch - 'A' + 10;
|
||||||
|
else
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
|
||||||
|
n = (n << 4) | digit;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( len <= 5 ) {
|
||||||
|
// double nibbles
|
||||||
|
int n1 = n & 0xf000;
|
||||||
|
int n2 = n & 0xf00;
|
||||||
|
int n3 = n & 0xf0;
|
||||||
|
int n4 = n & 0xf;
|
||||||
|
n = (n1 << 16) | (n1 << 12) | (n2 << 12) | (n2 << 8) | (n3 << 8) | (n3 << 4) | (n4 << 4) | n4;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (len == 4 || len == 7)
|
||||||
|
? (0xff000000 | n) // set alpha to 255
|
||||||
|
: (((n >> 8) & 0xffffff) | ((n & 0xff) << 24)); // move alpha from lowest to highest byte
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Object parseColorFunctions( String value, Function<String, String> resolver, boolean reportError ) {
|
||||||
int paramsStart = value.indexOf( '(' );
|
int paramsStart = value.indexOf( '(' );
|
||||||
if( paramsStart < 0 ) {
|
if( paramsStart < 0 ) {
|
||||||
if( reportError )
|
if( reportError )
|
||||||
@@ -324,37 +484,99 @@ class UIDefaultsLoader
|
|||||||
}
|
}
|
||||||
|
|
||||||
String function = value.substring( 0, paramsStart ).trim();
|
String function = value.substring( 0, paramsStart ).trim();
|
||||||
List<String> params = split( value.substring( paramsStart + 1, value.length() - 1 ), ',' );
|
List<String> params = splitFunctionParams( value.substring( paramsStart + 1, value.length() - 1 ), ',' );
|
||||||
if( params.isEmpty() )
|
if( params.isEmpty() )
|
||||||
throw new IllegalArgumentException( "missing parameters in function '" + value + "'" );
|
throw new IllegalArgumentException( "missing parameters in function '" + value + "'" );
|
||||||
|
|
||||||
switch( function ) {
|
switch( function ) {
|
||||||
case "lighten": return parseColorLightenOrDarken( true, params, reportError );
|
case "rgb": return parseColorRgbOrRgba( false, params );
|
||||||
case "darken": return parseColorLightenOrDarken( false, params, reportError );
|
case "rgba": return parseColorRgbOrRgba( true, params );
|
||||||
|
case "hsl": return parseColorHslOrHsla( false, params );
|
||||||
|
case "hsla": return parseColorHslOrHsla( true, params );
|
||||||
|
case "lighten": return parseColorLightenOrDarken( true, params, resolver, reportError );
|
||||||
|
case "darken": return parseColorLightenOrDarken( false, params, resolver, reportError );
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new IllegalArgumentException( "unknown color function '" + value + "'" );
|
throw new IllegalArgumentException( "unknown color function '" + value + "'" );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Syntax: lighten(amount[,options]) or darken(amount[,options])
|
* Syntax: rgb(red,green,blue) or rgba(red,green,blue,alpha)
|
||||||
* - amount: percentage 0-100%
|
* - red: an integer 0-255
|
||||||
* - options: [relative] [autoInverse]
|
* - green: an integer 0-255
|
||||||
|
* - blue: an integer 0-255
|
||||||
|
* - alpha: an integer 0-255
|
||||||
*/
|
*/
|
||||||
private static ColorUIResource parseColorLightenOrDarken( boolean lighten, List<String> params, boolean reportError ) {
|
private static ColorUIResource parseColorRgbOrRgba( boolean hasAlpha, List<String> params ) {
|
||||||
int amount = parsePercentage( params.get( 0 ) );
|
int red = parseInteger( params.get( 0 ), 0, 255 );
|
||||||
boolean relative = false;
|
int green = parseInteger( params.get( 1 ), 0, 255 );
|
||||||
boolean autoInverse = false;
|
int blue = parseInteger( params.get( 2 ), 0, 255 );
|
||||||
|
int alpha = hasAlpha ? parseInteger( params.get( 3 ), 0, 255 ) : 255;
|
||||||
|
|
||||||
if( params.size() >= 2 ) {
|
return hasAlpha
|
||||||
String options = params.get( 1 );
|
? new ColorUIResource( new Color( red, green, blue, alpha ) )
|
||||||
relative = options.contains( "relative" );
|
: new ColorUIResource( red, green, blue );
|
||||||
autoInverse = options.contains( "autoInverse" );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return new DerivedColor( lighten
|
/**
|
||||||
|
* Syntax: hsl(hue,saturation,lightness) or hsla(hue,saturation,lightness,alpha)
|
||||||
|
* - hue: an integer 0-360 representing degrees
|
||||||
|
* - saturation: a percentage 0-100%
|
||||||
|
* - lightness: a percentage 0-100%
|
||||||
|
* - alpha: a percentage 0-100%
|
||||||
|
*/
|
||||||
|
private static ColorUIResource parseColorHslOrHsla( boolean hasAlpha, List<String> params ) {
|
||||||
|
int hue = parseInteger( params.get( 0 ), 0, 360 );
|
||||||
|
int saturation = parsePercentage( params.get( 1 ) );
|
||||||
|
int lightness = parsePercentage( params.get( 2 ) );
|
||||||
|
int alpha = hasAlpha ? parsePercentage( params.get( 3 ) ) : 100;
|
||||||
|
|
||||||
|
float[] hsl = new float[] { hue, saturation, lightness };
|
||||||
|
return new ColorUIResource( HSLColor.toRGB( hsl, alpha / 100f ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Syntax: lighten([color,]amount[,options]) or darken([color,]amount[,options])
|
||||||
|
* - color: a color (e.g. #f00) or a color function
|
||||||
|
* - amount: percentage 0-100%
|
||||||
|
* - options: [relative] [autoInverse] [lazy]
|
||||||
|
*/
|
||||||
|
private static Object parseColorLightenOrDarken( boolean lighten, List<String> params,
|
||||||
|
Function<String, String> resolver, boolean reportError )
|
||||||
|
{
|
||||||
|
boolean isDerived = params.get( 0 ).endsWith( "%" );
|
||||||
|
String colorStr = isDerived ? null : params.get( 0 );
|
||||||
|
int nextParam = isDerived ? 0 : 1;
|
||||||
|
int amount = parsePercentage( params.get( nextParam++ ) );
|
||||||
|
boolean relative = false;
|
||||||
|
boolean autoInverse = false;
|
||||||
|
boolean lazy = false;
|
||||||
|
|
||||||
|
if( params.size() > nextParam ) {
|
||||||
|
String options = params.get( nextParam++ );
|
||||||
|
relative = options.contains( "relative" );
|
||||||
|
autoInverse = options.contains( "autoInverse" );
|
||||||
|
lazy = options.contains( "lazy" );
|
||||||
|
}
|
||||||
|
|
||||||
|
ColorFunctions.ColorFunction function = lighten
|
||||||
? new ColorFunctions.Lighten( amount, relative, autoInverse )
|
? new ColorFunctions.Lighten( amount, relative, autoInverse )
|
||||||
: new ColorFunctions.Darken( amount, relative, autoInverse ) );
|
: new ColorFunctions.Darken( amount, relative, autoInverse );
|
||||||
|
|
||||||
|
if( isDerived )
|
||||||
|
return new DerivedColor( function );
|
||||||
|
|
||||||
|
if( lazy ) {
|
||||||
|
return (LazyValue) t -> {
|
||||||
|
Object color = lazyUIManagerGet( colorStr );
|
||||||
|
return (color instanceof Color)
|
||||||
|
? new ColorUIResource( ColorFunctions.applyFunctions( (Color) color, function ) )
|
||||||
|
: null;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
ColorUIResource color = (ColorUIResource) parseColorOrFunction( resolver.apply( colorStr ), resolver, reportError );
|
||||||
|
return new ColorUIResource( ColorFunctions.applyFunctions( color, function ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int parsePercentage( String value ) {
|
private static int parsePercentage( String value ) {
|
||||||
@@ -373,6 +595,13 @@ class UIDefaultsLoader
|
|||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Integer parseInteger( String value, int min, int max ) {
|
||||||
|
Integer integer = parseInteger( value, true );
|
||||||
|
if( integer.intValue() < min || integer.intValue() > max )
|
||||||
|
throw new NumberFormatException( "integer '" + value + "' out of range (" + min + '-' + max + ')' );
|
||||||
|
return integer;
|
||||||
|
}
|
||||||
|
|
||||||
private static Integer parseInteger( String value, boolean reportError ) {
|
private static Integer parseInteger( String value, boolean reportError ) {
|
||||||
try {
|
try {
|
||||||
return Integer.parseInt( value );
|
return Integer.parseInt( value );
|
||||||
@@ -383,25 +612,76 @@ class UIDefaultsLoader
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ScaledNumber parseScaledNumber( String value ) {
|
private static Float parseFloat( String value, boolean reportError ) {
|
||||||
try {
|
try {
|
||||||
return new ScaledNumber( Integer.parseInt( value ) );
|
return Float.parseFloat( value );
|
||||||
} catch( NumberFormatException ex ) {
|
} catch( NumberFormatException ex ) {
|
||||||
throw new NumberFormatException( "invalid integer '" + value + "'" );
|
if( reportError )
|
||||||
|
throw new NumberFormatException( "invalid float '" + value + "'" );
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
static List<String> split( String str, char delim ) {
|
private static ActiveValue parseScaledInteger( String value ) {
|
||||||
ArrayList<String> strs = new ArrayList<>();
|
int val = parseInteger( value, true );
|
||||||
int delimIndex = str.indexOf( delim );
|
return (ActiveValue) t -> {
|
||||||
int index = 0;
|
return UIScale.scale( val );
|
||||||
while( delimIndex >= 0 ) {
|
};
|
||||||
strs.add( str.substring( index, delimIndex ) );
|
|
||||||
index = delimIndex + 1;
|
|
||||||
delimIndex = str.indexOf( delim, index );
|
|
||||||
}
|
}
|
||||||
strs.add( str.substring( index ) );
|
|
||||||
|
/**
|
||||||
|
* Split string and trim parts.
|
||||||
|
*/
|
||||||
|
private static List<String> split( String str, char delim ) {
|
||||||
|
List<String> result = StringUtils.split( str, delim );
|
||||||
|
|
||||||
|
// trim strings
|
||||||
|
int size = result.size();
|
||||||
|
for( int i = 0; i < size; i++ )
|
||||||
|
result.set( i, result.get( i ).trim() );
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Splits function parameters and allows using functions as parameters.
|
||||||
|
* In other words: Delimiters surrounded by '(' and ')' are ignored.
|
||||||
|
*/
|
||||||
|
private static List<String> splitFunctionParams( String str, char delim ) {
|
||||||
|
ArrayList<String> strs = new ArrayList<>();
|
||||||
|
int nestLevel = 0;
|
||||||
|
int start = 0;
|
||||||
|
int strlen = str.length();
|
||||||
|
for( int i = 0; i < strlen; i++ ) {
|
||||||
|
char ch = str.charAt( i );
|
||||||
|
if( ch == '(' )
|
||||||
|
nestLevel++;
|
||||||
|
else if( ch == ')' )
|
||||||
|
nestLevel--;
|
||||||
|
else if( nestLevel == 0 && ch == delim ) {
|
||||||
|
strs.add( str.substring( start, i ).trim() );
|
||||||
|
start = i + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
strs.add( str.substring( start ).trim() );
|
||||||
|
|
||||||
return strs;
|
return strs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For use in LazyValue to get value for given key from UIManager and report error
|
||||||
|
* if not found. If key is prefixed by '?', then no error is reported.
|
||||||
|
*/
|
||||||
|
private static Object lazyUIManagerGet( String uiKey ) {
|
||||||
|
boolean optional = false;
|
||||||
|
if( uiKey.startsWith( OPTIONAL_PREFIX ) ) {
|
||||||
|
uiKey = uiKey.substring( OPTIONAL_PREFIX.length() );
|
||||||
|
optional = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Object value = UIManager.get( uiKey );
|
||||||
|
if( value == null && !optional )
|
||||||
|
FlatLaf.LOG.log( Level.SEVERE, "FlatLaf: '" + uiKey + "' not found in UI defaults." );
|
||||||
|
return value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,15 +16,18 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf.icons;
|
package com.formdev.flatlaf.icons;
|
||||||
|
|
||||||
|
import java.awt.BasicStroke;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.geom.Path2D;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* "ascendingSort" icon for {@link javax.swing.table.JTableHeader}.
|
* "ascendingSort" icon for {@link javax.swing.table.JTableHeader}.
|
||||||
*
|
*
|
||||||
|
* @uiDefault Component.arrowType String triangle (default) or chevron
|
||||||
* @uiDefault Table.sortIconColor Color
|
* @uiDefault Table.sortIconColor Color
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
@@ -32,6 +35,7 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
|
|||||||
public class FlatAscendingSortIcon
|
public class FlatAscendingSortIcon
|
||||||
extends FlatAbstractIcon
|
extends FlatAbstractIcon
|
||||||
{
|
{
|
||||||
|
protected final boolean chevron = "chevron".equals( UIManager.getString( "Component.arrowType" ) );
|
||||||
protected final Color sortIconColor = UIManager.getColor( "Table.sortIconColor" );
|
protected final Color sortIconColor = UIManager.getColor( "Table.sortIconColor" );
|
||||||
|
|
||||||
public FlatAscendingSortIcon() {
|
public FlatAscendingSortIcon() {
|
||||||
@@ -41,6 +45,14 @@ public class FlatAscendingSortIcon
|
|||||||
@Override
|
@Override
|
||||||
protected void paintIcon( Component c, Graphics2D g ) {
|
protected void paintIcon( Component c, Graphics2D g ) {
|
||||||
g.setColor( sortIconColor );
|
g.setColor( sortIconColor );
|
||||||
g.fill( FlatUIUtils.createPath( 0.5,5, 9.5,5, 5,0 ) );
|
if( chevron ) {
|
||||||
|
// chevron arrow
|
||||||
|
Path2D path = FlatUIUtils.createPath( false, 1,5, 5,1, 9,5 );
|
||||||
|
g.setStroke( new BasicStroke( 1f ) );
|
||||||
|
g.draw( path );
|
||||||
|
} else {
|
||||||
|
// triangle arrow
|
||||||
|
g.fill( FlatUIUtils.createPath( 0.5,5, 5,0, 9.5,5 ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
|
|||||||
*
|
*
|
||||||
* @uiDefault Component.focusWidth int
|
* @uiDefault Component.focusWidth int
|
||||||
* @uiDefault Component.focusColor Color
|
* @uiDefault Component.focusColor Color
|
||||||
|
* @uiDefault CheckBox.icon.focusedColor Color optional; defaults to Component.focusColor
|
||||||
* @uiDefault CheckBox.icon.borderColor Color
|
* @uiDefault CheckBox.icon.borderColor Color
|
||||||
* @uiDefault CheckBox.icon.disabledBorderColor Color
|
* @uiDefault CheckBox.icon.disabledBorderColor Color
|
||||||
* @uiDefault CheckBox.icon.selectedBorderColor Color
|
* @uiDefault CheckBox.icon.selectedBorderColor Color
|
||||||
@@ -61,8 +62,9 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
|
|||||||
public class FlatCheckBoxIcon
|
public class FlatCheckBoxIcon
|
||||||
extends FlatAbstractIcon
|
extends FlatAbstractIcon
|
||||||
{
|
{
|
||||||
protected final int focusWidth = UIManager.getInt( "Component.focusWidth" );
|
public final int focusWidth = UIManager.getInt( "Component.focusWidth" );
|
||||||
protected final Color focusColor = UIManager.getColor( "Component.focusColor" );
|
protected final Color focusColor = FlatUIUtils.getUIColor( "CheckBox.icon.focusedColor",
|
||||||
|
UIManager.getColor( "Component.focusColor" ) );
|
||||||
protected final int arc = FlatUIUtils.getUIInt( "CheckBox.arc", 2 );
|
protected final int arc = FlatUIUtils.getUIInt( "CheckBox.arc", 2 );
|
||||||
|
|
||||||
protected final Color borderColor = UIManager.getColor( "CheckBox.icon.borderColor" );
|
protected final Color borderColor = UIManager.getColor( "CheckBox.icon.borderColor" );
|
||||||
@@ -131,17 +133,17 @@ public class FlatCheckBoxIcon
|
|||||||
protected void paintFocusBorder( Graphics2D g2 ) {
|
protected void paintFocusBorder( Graphics2D g2 ) {
|
||||||
// the outline focus border is painted outside of the icon
|
// the outline focus border is painted outside of the icon
|
||||||
int wh = ICON_SIZE - 1 + (focusWidth * 2);
|
int wh = ICON_SIZE - 1 + (focusWidth * 2);
|
||||||
int arcwh = (arc + focusWidth) * 2;
|
int arcwh = arc + (focusWidth * 2);
|
||||||
g2.fillRoundRect( -focusWidth + 1, -focusWidth, wh, wh, arcwh, arcwh );
|
g2.fillRoundRect( -focusWidth + 1, -focusWidth, wh, wh, arcwh, arcwh );
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void paintBorder( Graphics2D g2 ) {
|
protected void paintBorder( Graphics2D g2 ) {
|
||||||
int arcwh = arc * 2;
|
int arcwh = arc;
|
||||||
g2.fillRoundRect( 1, 0, 14, 14, arcwh, arcwh );
|
g2.fillRoundRect( 1, 0, 14, 14, arcwh, arcwh );
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void paintBackground( Graphics2D g2 ) {
|
protected void paintBackground( Graphics2D g2 ) {
|
||||||
int arcwh = (arc * 2) - 1;
|
int arcwh = arc - 1;
|
||||||
g2.fillRoundRect( 2, 1, 12, 12, arcwh, arcwh );
|
g2.fillRoundRect( 2, 1, 12, 12, arcwh, arcwh );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,15 +16,18 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf.icons;
|
package com.formdev.flatlaf.icons;
|
||||||
|
|
||||||
|
import java.awt.BasicStroke;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.geom.Path2D;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* "descendingSort" icon for {@link javax.swing.table.JTableHeader}.
|
* "descendingSort" icon for {@link javax.swing.table.JTableHeader}.
|
||||||
*
|
*
|
||||||
|
* @uiDefault Component.arrowType String triangle (default) or chevron
|
||||||
* @uiDefault Table.sortIconColor Color
|
* @uiDefault Table.sortIconColor Color
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
@@ -32,6 +35,7 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
|
|||||||
public class FlatDescendingSortIcon
|
public class FlatDescendingSortIcon
|
||||||
extends FlatAbstractIcon
|
extends FlatAbstractIcon
|
||||||
{
|
{
|
||||||
|
protected final boolean chevron = "chevron".equals( UIManager.getString( "Component.arrowType" ) );
|
||||||
protected final Color sortIconColor = UIManager.getColor( "Table.sortIconColor" );
|
protected final Color sortIconColor = UIManager.getColor( "Table.sortIconColor" );
|
||||||
|
|
||||||
public FlatDescendingSortIcon() {
|
public FlatDescendingSortIcon() {
|
||||||
@@ -41,6 +45,14 @@ public class FlatDescendingSortIcon
|
|||||||
@Override
|
@Override
|
||||||
protected void paintIcon( Component c, Graphics2D g ) {
|
protected void paintIcon( Component c, Graphics2D g ) {
|
||||||
g.setColor( sortIconColor );
|
g.setColor( sortIconColor );
|
||||||
g.fill( FlatUIUtils.createPath( 0.5,0, 9.5,0, 5,5 ) );
|
if( chevron ) {
|
||||||
|
// chevron arrow
|
||||||
|
Path2D path = FlatUIUtils.createPath( false, 1,1, 5,5, 9,1 );
|
||||||
|
g.setStroke( new BasicStroke( 1f ) );
|
||||||
|
g.draw( path );
|
||||||
|
} else {
|
||||||
|
// triangle arrow
|
||||||
|
g.fill( FlatUIUtils.createPath( 0.5,0, 5,5, 9.5,0 ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import javax.swing.UIManager;
|
|||||||
/**
|
/**
|
||||||
* "details view" icon for {@link javax.swing.JFileChooser}.
|
* "details view" icon for {@link javax.swing.JFileChooser}.
|
||||||
*
|
*
|
||||||
* @uiDefault FileChooser.icon.detailsViewColor Color
|
* @uiDefault Actions.Grey Color
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
@@ -31,7 +31,7 @@ public class FlatFileChooserDetailsViewIcon
|
|||||||
extends FlatAbstractIcon
|
extends FlatAbstractIcon
|
||||||
{
|
{
|
||||||
public FlatFileChooserDetailsViewIcon() {
|
public FlatFileChooserDetailsViewIcon() {
|
||||||
super( 16, 16, UIManager.getColor( "FileChooser.icon.detailsViewColor" ) );
|
super( 16, 16, UIManager.getColor( "Actions.Grey" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
|
|||||||
/**
|
/**
|
||||||
* "home folder" icon for {@link javax.swing.JFileChooser}.
|
* "home folder" icon for {@link javax.swing.JFileChooser}.
|
||||||
*
|
*
|
||||||
* @uiDefault FileChooser.icon.homeFolderColor Color
|
* @uiDefault Actions.Grey Color
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
@@ -32,7 +32,7 @@ public class FlatFileChooserHomeFolderIcon
|
|||||||
extends FlatAbstractIcon
|
extends FlatAbstractIcon
|
||||||
{
|
{
|
||||||
public FlatFileChooserHomeFolderIcon() {
|
public FlatFileChooserHomeFolderIcon() {
|
||||||
super( 16, 16, UIManager.getColor( "FileChooser.icon.homeFolderColor" ) );
|
super( 16, 16, UIManager.getColor( "Actions.Grey" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import javax.swing.UIManager;
|
|||||||
/**
|
/**
|
||||||
* "list view" icon for {@link javax.swing.JFileChooser}.
|
* "list view" icon for {@link javax.swing.JFileChooser}.
|
||||||
*
|
*
|
||||||
* @uiDefault FileChooser.icon.listViewColor Color
|
* @uiDefault Actions.Grey Color
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
@@ -31,7 +31,7 @@ public class FlatFileChooserListViewIcon
|
|||||||
extends FlatAbstractIcon
|
extends FlatAbstractIcon
|
||||||
{
|
{
|
||||||
public FlatFileChooserListViewIcon() {
|
public FlatFileChooserListViewIcon() {
|
||||||
super( 16, 16, UIManager.getColor( "FileChooser.icon.listViewColor" ) );
|
super( 16, 16, UIManager.getColor( "Actions.Grey" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
|
|||||||
/**
|
/**
|
||||||
* "new folder" icon for {@link javax.swing.JFileChooser}.
|
* "new folder" icon for {@link javax.swing.JFileChooser}.
|
||||||
*
|
*
|
||||||
* @uiDefault FileChooser.icon.newFolderColor Color
|
* @uiDefault Actions.Grey Color
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
@@ -32,7 +32,7 @@ public class FlatFileChooserNewFolderIcon
|
|||||||
extends FlatAbstractIcon
|
extends FlatAbstractIcon
|
||||||
{
|
{
|
||||||
public FlatFileChooserNewFolderIcon() {
|
public FlatFileChooserNewFolderIcon() {
|
||||||
super( 16, 16, UIManager.getColor( "FileChooser.icon.newFolderColor" ) );
|
super( 16, 16, UIManager.getColor( "Actions.Grey" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf.icons;
|
package com.formdev.flatlaf.icons;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
@@ -24,15 +25,18 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
|
|||||||
/**
|
/**
|
||||||
* "up folder" icon for {@link javax.swing.JFileChooser}.
|
* "up folder" icon for {@link javax.swing.JFileChooser}.
|
||||||
*
|
*
|
||||||
* @uiDefault FileChooser.icon.upFolderColor Color
|
* @uiDefault Actions.Grey Color
|
||||||
|
* @uiDefault Actions.Blue Color
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
public class FlatFileChooserUpFolderIcon
|
public class FlatFileChooserUpFolderIcon
|
||||||
extends FlatAbstractIcon
|
extends FlatAbstractIcon
|
||||||
{
|
{
|
||||||
|
private final Color blueColor = UIManager.getColor( "Actions.Blue" );
|
||||||
|
|
||||||
public FlatFileChooserUpFolderIcon() {
|
public FlatFileChooserUpFolderIcon() {
|
||||||
super( 16, 16, UIManager.getColor( "FileChooser.icon.upFolderColor" ) );
|
super( 16, 16, UIManager.getColor( "Actions.Grey" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -47,6 +51,8 @@ public class FlatFileChooserUpFolderIcon
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
g.fill( FlatUIUtils.createPath( 2,3, 5.5,3, 7,5, 9,5, 9,9, 13,9, 13,5, 14,5, 14,13, 2,13 ) );
|
g.fill( FlatUIUtils.createPath( 2,3, 5.5,3, 7,5, 9,5, 9,9, 13,9, 13,5, 14,5, 14,13, 2,13 ) );
|
||||||
|
|
||||||
|
g.setColor( blueColor );
|
||||||
g.fill( FlatUIUtils.createPath( 12,4, 12,8, 10,8, 10,4, 8,4, 11,1, 14,4, 12,4 ) );
|
g.fill( FlatUIUtils.createPath( 12,4, 12,8, 10,8, 10,4, 8,4, 11,1, 14,4, 12,4 ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import javax.swing.UIManager;
|
|||||||
/**
|
/**
|
||||||
* "computer" icon for {@link javax.swing.JFileChooser}.
|
* "computer" icon for {@link javax.swing.JFileChooser}.
|
||||||
*
|
*
|
||||||
* @uiDefault FileView.icon.computerColor Color
|
* @uiDefault Objects.Grey Color
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
@@ -33,7 +33,7 @@ public class FlatFileViewComputerIcon
|
|||||||
extends FlatAbstractIcon
|
extends FlatAbstractIcon
|
||||||
{
|
{
|
||||||
public FlatFileViewComputerIcon() {
|
public FlatFileViewComputerIcon() {
|
||||||
super( 16, 16, UIManager.getColor( "FileView.icon.computerColor" ) );
|
super( 16, 16, UIManager.getColor( "Objects.Grey" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
|
|||||||
/**
|
/**
|
||||||
* "directory" icon for {@link javax.swing.JFileChooser}.
|
* "directory" icon for {@link javax.swing.JFileChooser}.
|
||||||
*
|
*
|
||||||
* @uiDefault FileView.icon.directoryColor Color
|
* @uiDefault Objects.Grey Color
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
@@ -32,7 +32,7 @@ public class FlatFileViewDirectoryIcon
|
|||||||
extends FlatAbstractIcon
|
extends FlatAbstractIcon
|
||||||
{
|
{
|
||||||
public FlatFileViewDirectoryIcon() {
|
public FlatFileViewDirectoryIcon() {
|
||||||
super( 16, 16, UIManager.getColor( "FileView.icon.directoryColor" ) );
|
super( 16, 16, UIManager.getColor( "Objects.Grey" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
|
|||||||
/**
|
/**
|
||||||
* "file" icon for {@link javax.swing.JFileChooser}.
|
* "file" icon for {@link javax.swing.JFileChooser}.
|
||||||
*
|
*
|
||||||
* @uiDefault FileView.icon.fileColor Color
|
* @uiDefault Objects.Grey Color
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
@@ -32,7 +32,7 @@ public class FlatFileViewFileIcon
|
|||||||
extends FlatAbstractIcon
|
extends FlatAbstractIcon
|
||||||
{
|
{
|
||||||
public FlatFileViewFileIcon() {
|
public FlatFileViewFileIcon() {
|
||||||
super( 16, 16, UIManager.getColor( "FileView.icon.fileColor" ) );
|
super( 16, 16, UIManager.getColor( "Objects.Grey" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
|
|||||||
/**
|
/**
|
||||||
* "floppy drive" icon for {@link javax.swing.JFileChooser}.
|
* "floppy drive" icon for {@link javax.swing.JFileChooser}.
|
||||||
*
|
*
|
||||||
* @uiDefault FileView.icon.floppyDriveColor Color
|
* @uiDefault Objects.Grey Color
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
@@ -33,7 +33,7 @@ public class FlatFileViewFloppyDriveIcon
|
|||||||
extends FlatAbstractIcon
|
extends FlatAbstractIcon
|
||||||
{
|
{
|
||||||
public FlatFileViewFloppyDriveIcon() {
|
public FlatFileViewFloppyDriveIcon() {
|
||||||
super( 16, 16, UIManager.getColor( "FileView.icon.floppyDriveColor" ) );
|
super( 16, 16, UIManager.getColor( "Objects.Grey" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import javax.swing.UIManager;
|
|||||||
/**
|
/**
|
||||||
* "hard drive" icon for {@link javax.swing.JFileChooser}.
|
* "hard drive" icon for {@link javax.swing.JFileChooser}.
|
||||||
*
|
*
|
||||||
* @uiDefault FileView.icon.hardDriveColor Color
|
* @uiDefault Objects.Grey Color
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
@@ -33,7 +33,7 @@ public class FlatFileViewHardDriveIcon
|
|||||||
extends FlatAbstractIcon
|
extends FlatAbstractIcon
|
||||||
{
|
{
|
||||||
public FlatFileViewHardDriveIcon() {
|
public FlatFileViewHardDriveIcon() {
|
||||||
super( 16, 16, UIManager.getColor( "FileView.icon.hardDriveColor" ) );
|
super( 16, 16, UIManager.getColor( "Objects.Grey" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 FormDev Software GmbH
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.formdev.flatlaf.icons;
|
||||||
|
|
||||||
|
import java.awt.BasicStroke;
|
||||||
|
import java.awt.Component;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.geom.Line2D;
|
||||||
|
import java.awt.geom.Path2D;
|
||||||
|
import javax.swing.UIManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* "close" icon for {@link javax.swing.JInternalFrame}.
|
||||||
|
*
|
||||||
|
* @uiDefault InternalFrame.iconColor Color
|
||||||
|
*
|
||||||
|
* @author Karl Tauber
|
||||||
|
*/
|
||||||
|
public class FlatInternalFrameCloseIcon
|
||||||
|
extends FlatAbstractIcon
|
||||||
|
{
|
||||||
|
public FlatInternalFrameCloseIcon() {
|
||||||
|
super( 16, 16, UIManager.getColor( "InternalFrame.iconColor" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void paintIcon( Component c, Graphics2D g ) {
|
||||||
|
float mx = 8;
|
||||||
|
float my = 8;
|
||||||
|
float r = 3.25f;
|
||||||
|
|
||||||
|
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD );
|
||||||
|
path.append( new Line2D.Float( mx - r, my - r, mx + r, my + r ), false );
|
||||||
|
path.append( new Line2D.Float( mx - r, my + r, mx + r, my - r ), false );
|
||||||
|
g.setStroke( new BasicStroke( 1f ) );
|
||||||
|
g.draw( path );
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 FormDev Software GmbH
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.formdev.flatlaf.icons;
|
||||||
|
|
||||||
|
import java.awt.Component;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import javax.swing.UIManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* "iconify" icon for {@link javax.swing.JInternalFrame}.
|
||||||
|
*
|
||||||
|
* @uiDefault InternalFrame.iconColor Color
|
||||||
|
*
|
||||||
|
* @author Karl Tauber
|
||||||
|
*/
|
||||||
|
public class FlatInternalFrameIconifyIcon
|
||||||
|
extends FlatAbstractIcon
|
||||||
|
{
|
||||||
|
public FlatInternalFrameIconifyIcon() {
|
||||||
|
super( 16, 16, UIManager.getColor( "InternalFrame.iconColor" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void paintIcon( Component c, Graphics2D g ) {
|
||||||
|
g.fillRect( 3, 8, 10, 1 );
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 FormDev Software GmbH
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.formdev.flatlaf.icons;
|
||||||
|
|
||||||
|
import java.awt.Component;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import javax.swing.UIManager;
|
||||||
|
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* "maximize" icon for {@link javax.swing.JInternalFrame}.
|
||||||
|
*
|
||||||
|
* @uiDefault InternalFrame.iconColor Color
|
||||||
|
*
|
||||||
|
* @author Karl Tauber
|
||||||
|
*/
|
||||||
|
public class FlatInternalFrameMaximizeIcon
|
||||||
|
extends FlatAbstractIcon
|
||||||
|
{
|
||||||
|
public FlatInternalFrameMaximizeIcon() {
|
||||||
|
super( 16, 16, UIManager.getColor( "InternalFrame.iconColor" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void paintIcon( Component c, Graphics2D g ) {
|
||||||
|
g.fill( FlatUIUtils.createRectangle( 3, 3, 10, 10, 1 ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 FormDev Software GmbH
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.formdev.flatlaf.icons;
|
||||||
|
|
||||||
|
import java.awt.Component;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.geom.Area;
|
||||||
|
import java.awt.geom.Path2D;
|
||||||
|
import java.awt.geom.Rectangle2D;
|
||||||
|
import javax.swing.UIManager;
|
||||||
|
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* "minimize" (actually "restore") icon for {@link javax.swing.JInternalFrame}.
|
||||||
|
*
|
||||||
|
* @uiDefault InternalFrame.iconColor Color
|
||||||
|
*
|
||||||
|
* @author Karl Tauber
|
||||||
|
*/
|
||||||
|
public class FlatInternalFrameMinimizeIcon
|
||||||
|
extends FlatAbstractIcon
|
||||||
|
{
|
||||||
|
public FlatInternalFrameMinimizeIcon() {
|
||||||
|
super( 16, 16, UIManager.getColor( "InternalFrame.iconColor" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void paintIcon( Component c, Graphics2D g ) {
|
||||||
|
Path2D r1 = FlatUIUtils.createRectangle( 5, 3, 8, 8, 1 );
|
||||||
|
Path2D r2 = FlatUIUtils.createRectangle( 3, 5, 8, 8, 1 );
|
||||||
|
|
||||||
|
Area area = new Area( r1 );
|
||||||
|
area.subtract( new Area( new Rectangle2D.Float( 3, 5, 8, 8 ) ) );
|
||||||
|
g.fill( area );
|
||||||
|
|
||||||
|
g.fill( r2 );
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -60,7 +60,7 @@ public class FlatMenuArrowIcon
|
|||||||
g.draw( path );
|
g.draw( path );
|
||||||
} else {
|
} else {
|
||||||
// triangle arrow
|
// triangle arrow
|
||||||
g.fill( FlatUIUtils.createPath( 0,0.5, 0,9.5, 5,5 ) );
|
g.fill( FlatUIUtils.createPath( 0,0.5, 5,5, 0,9.5 ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,11 +22,12 @@ import java.awt.Graphics2D;
|
|||||||
import java.awt.Shape;
|
import java.awt.Shape;
|
||||||
import java.awt.geom.Path2D;
|
import java.awt.geom.Path2D;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
|
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class for icons for {@link javax.swing.JOptionPane}.
|
* Base class for icons for {@link javax.swing.JOptionPane}.
|
||||||
*
|
*
|
||||||
* @uiDefault OptionPane.icon.foreground Color
|
* @uiDefault OptionPane.icon.foreground Color default is transparent
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
@@ -35,8 +36,8 @@ public abstract class FlatOptionPaneAbstractIcon
|
|||||||
{
|
{
|
||||||
protected final Color foreground = UIManager.getColor( "OptionPane.icon.foreground" );
|
protected final Color foreground = UIManager.getColor( "OptionPane.icon.foreground" );
|
||||||
|
|
||||||
protected FlatOptionPaneAbstractIcon( String colorKey ) {
|
protected FlatOptionPaneAbstractIcon( String colorKey, String defaultColorKey ) {
|
||||||
super( 32, 32, UIManager.getColor( colorKey ) );
|
super( 32, 32, FlatUIUtils.getUIColor( colorKey, defaultColorKey ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -24,7 +24,8 @@ import java.awt.geom.Rectangle2D;
|
|||||||
/**
|
/**
|
||||||
* "Error" icon for {@link javax.swing.JOptionPane}.
|
* "Error" icon for {@link javax.swing.JOptionPane}.
|
||||||
*
|
*
|
||||||
* @uiDefault OptionPane.icon.errorColor Color
|
* @uiDefault OptionPane.icon.errorColor Color optional; defaults to Actions.Red
|
||||||
|
* @uiDefault Actions.Red Color
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
@@ -32,7 +33,7 @@ public class FlatOptionPaneErrorIcon
|
|||||||
extends FlatOptionPaneAbstractIcon
|
extends FlatOptionPaneAbstractIcon
|
||||||
{
|
{
|
||||||
public FlatOptionPaneErrorIcon() {
|
public FlatOptionPaneErrorIcon() {
|
||||||
super( "OptionPane.icon.errorColor" );
|
super( "OptionPane.icon.errorColor", "Actions.Red" );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -24,7 +24,8 @@ import java.awt.geom.Rectangle2D;
|
|||||||
/**
|
/**
|
||||||
* "Information" icon for {@link javax.swing.JOptionPane}.
|
* "Information" icon for {@link javax.swing.JOptionPane}.
|
||||||
*
|
*
|
||||||
* @uiDefault OptionPane.icon.informationColor Color
|
* @uiDefault OptionPane.icon.informationColor Color optional; defaults to Actions.Blue
|
||||||
|
* @uiDefault Actions.Blue Color
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
@@ -32,7 +33,7 @@ public class FlatOptionPaneInformationIcon
|
|||||||
extends FlatOptionPaneAbstractIcon
|
extends FlatOptionPaneAbstractIcon
|
||||||
{
|
{
|
||||||
public FlatOptionPaneInformationIcon() {
|
public FlatOptionPaneInformationIcon() {
|
||||||
super( "OptionPane.icon.informationColor" );
|
super( "OptionPane.icon.informationColor", "Actions.Blue" );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -24,7 +24,8 @@ import java.awt.geom.Rectangle2D;
|
|||||||
/**
|
/**
|
||||||
* "Question" icon for {@link javax.swing.JOptionPane}.
|
* "Question" icon for {@link javax.swing.JOptionPane}.
|
||||||
*
|
*
|
||||||
* @uiDefault OptionPane.icon.questionColor Color
|
* @uiDefault OptionPane.icon.questionColor Color optional; defaults to Actions.Blue
|
||||||
|
* @uiDefault Actions.Blue Color
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
@@ -32,7 +33,7 @@ public class FlatOptionPaneQuestionIcon
|
|||||||
extends FlatOptionPaneAbstractIcon
|
extends FlatOptionPaneAbstractIcon
|
||||||
{
|
{
|
||||||
public FlatOptionPaneQuestionIcon() {
|
public FlatOptionPaneQuestionIcon() {
|
||||||
super( "OptionPane.icon.questionColor" );
|
super( "OptionPane.icon.questionColor", "Actions.Blue" );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -24,7 +24,8 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
|
|||||||
/**
|
/**
|
||||||
* "Warning" icon for {@link javax.swing.JOptionPane}.
|
* "Warning" icon for {@link javax.swing.JOptionPane}.
|
||||||
*
|
*
|
||||||
* @uiDefault OptionPane.icon.warningColor Color
|
* @uiDefault OptionPane.icon.warningColor Color optional; defaults to Actions.Yellow
|
||||||
|
* @uiDefault Actions.Yellow Color
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
@@ -32,7 +33,7 @@ public class FlatOptionPaneWarningIcon
|
|||||||
extends FlatOptionPaneAbstractIcon
|
extends FlatOptionPaneAbstractIcon
|
||||||
{
|
{
|
||||||
public FlatOptionPaneWarningIcon() {
|
public FlatOptionPaneWarningIcon() {
|
||||||
super( "OptionPane.icon.warningColor" );
|
super( "OptionPane.icon.warningColor", "Actions.Yellow" );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
100
flatlaf-core/src/main/java/com/formdev/flatlaf/json/Json.java
Normal file
100
flatlaf-core/src/main/java/com/formdev/flatlaf/json/Json.java
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 FormDev Software GmbH
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.formdev.flatlaf.json;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Karl Tauber
|
||||||
|
*/
|
||||||
|
public class Json
|
||||||
|
{
|
||||||
|
public static Object parse( Reader reader )
|
||||||
|
throws IOException, ParseException
|
||||||
|
{
|
||||||
|
DefaultHandler handler = new DefaultHandler();
|
||||||
|
new JsonParser( handler ).parse( reader );
|
||||||
|
return handler.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
//---- class DefaultHandler -----------------------------------------------
|
||||||
|
|
||||||
|
static class DefaultHandler
|
||||||
|
extends JsonHandler<List<Object>, Map<String, Object>>
|
||||||
|
{
|
||||||
|
private Object value;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Object> startArray() {
|
||||||
|
return new ArrayList<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> startObject() {
|
||||||
|
return new LinkedHashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void endNull() {
|
||||||
|
value = "null";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void endBoolean( boolean bool ) {
|
||||||
|
value = bool ? "true" : "false";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void endString( String string ) {
|
||||||
|
value = string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void endNumber( String string ) {
|
||||||
|
value = string;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void endArray( List<Object> array ) {
|
||||||
|
value = array;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void endObject( Map<String, Object> object ) {
|
||||||
|
value = object;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void endArrayValue( List<Object> array ) {
|
||||||
|
array.add( value );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void endObjectValue( Map<String, Object> object, String name ) {
|
||||||
|
object.put( name, value );
|
||||||
|
}
|
||||||
|
|
||||||
|
Object getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,266 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2016 EclipseSource.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
// from https://github.com/ralfstx/minimal-json
|
||||||
|
|
||||||
|
package com.formdev.flatlaf.json;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A handler for parser events. Instances of this class can be given to a {@link JsonParser}. The
|
||||||
|
* parser will then call the methods of the given handler while reading the input.
|
||||||
|
* <p>
|
||||||
|
* The default implementations of these methods do nothing. Subclasses may override only those
|
||||||
|
* methods they are interested in. They can use <code>getLocation()</code> to access the current
|
||||||
|
* character position of the parser at any point. The <code>start*</code> methods will be called
|
||||||
|
* while the location points to the first character of the parsed element. The <code>end*</code>
|
||||||
|
* methods will be called while the location points to the character position that directly follows
|
||||||
|
* the last character of the parsed element. Example:
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* ["lorem ipsum"]
|
||||||
|
* ^ ^
|
||||||
|
* startString endString
|
||||||
|
* </pre>
|
||||||
|
* <p>
|
||||||
|
* Subclasses that build an object representation of the parsed JSON can return arbitrary handler
|
||||||
|
* objects for JSON arrays and JSON objects in {@link #startArray()} and {@link #startObject()}.
|
||||||
|
* These handler objects will then be provided in all subsequent parser events for this particular
|
||||||
|
* array or object. They can be used to keep track the elements of a JSON array or object.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param <A>
|
||||||
|
* The type of handlers used for JSON arrays
|
||||||
|
* @param <O>
|
||||||
|
* The type of handlers used for JSON objects
|
||||||
|
* @see JsonParser
|
||||||
|
*/
|
||||||
|
abstract class JsonHandler<A, O> {
|
||||||
|
|
||||||
|
JsonParser parser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current parser location.
|
||||||
|
*
|
||||||
|
* @return the current parser location
|
||||||
|
*/
|
||||||
|
protected Location getLocation() {
|
||||||
|
return parser.getLocation();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates the beginning of a <code>null</code> literal in the JSON input. This method will be
|
||||||
|
* called when reading the first character of the literal.
|
||||||
|
*/
|
||||||
|
public void startNull() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates the end of a <code>null</code> literal in the JSON input. This method will be called
|
||||||
|
* after reading the last character of the literal.
|
||||||
|
*/
|
||||||
|
public void endNull() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates the beginning of a boolean literal (<code>true</code> or <code>false</code>) in the
|
||||||
|
* JSON input. This method will be called when reading the first character of the literal.
|
||||||
|
*/
|
||||||
|
public void startBoolean() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates the end of a boolean literal (<code>true</code> or <code>false</code>) in the JSON
|
||||||
|
* input. This method will be called after reading the last character of the literal.
|
||||||
|
*
|
||||||
|
* @param value
|
||||||
|
* the parsed boolean value
|
||||||
|
*/
|
||||||
|
public void endBoolean(boolean value) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates the beginning of a string in the JSON input. This method will be called when reading
|
||||||
|
* the opening double quote character (<code>'"'</code>).
|
||||||
|
*/
|
||||||
|
public void startString() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates the end of a string in the JSON input. This method will be called after reading the
|
||||||
|
* closing double quote character (<code>'"'</code>).
|
||||||
|
*
|
||||||
|
* @param string
|
||||||
|
* the parsed string
|
||||||
|
*/
|
||||||
|
public void endString(String string) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates the beginning of a number in the JSON input. This method will be called when reading
|
||||||
|
* the first character of the number.
|
||||||
|
*/
|
||||||
|
public void startNumber() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates the end of a number in the JSON input. This method will be called after reading the
|
||||||
|
* last character of the number.
|
||||||
|
*
|
||||||
|
* @param string
|
||||||
|
* the parsed number string
|
||||||
|
*/
|
||||||
|
public void endNumber(String string) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates the beginning of an array in the JSON input. This method will be called when reading
|
||||||
|
* the opening square bracket character (<code>'['</code>).
|
||||||
|
* <p>
|
||||||
|
* This method may return an object to handle subsequent parser events for this array. This array
|
||||||
|
* handler will then be provided in all calls to {@link #startArrayValue(Object)
|
||||||
|
* startArrayValue()}, {@link #endArrayValue(Object) endArrayValue()}, and
|
||||||
|
* {@link #endArray(Object) endArray()} for this array.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @return a handler for this array, or <code>null</code> if not needed
|
||||||
|
*/
|
||||||
|
public A startArray() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates the end of an array in the JSON input. This method will be called after reading the
|
||||||
|
* closing square bracket character (<code>']'</code>).
|
||||||
|
*
|
||||||
|
* @param array
|
||||||
|
* the array handler returned from {@link #startArray()}, or <code>null</code> if not
|
||||||
|
* provided
|
||||||
|
*/
|
||||||
|
public void endArray(A array) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates the beginning of an array element in the JSON input. This method will be called when
|
||||||
|
* reading the first character of the element, just before the call to the <code>start</code>
|
||||||
|
* method for the specific element type ({@link #startString()}, {@link #startNumber()}, etc.).
|
||||||
|
*
|
||||||
|
* @param array
|
||||||
|
* the array handler returned from {@link #startArray()}, or <code>null</code> if not
|
||||||
|
* provided
|
||||||
|
*/
|
||||||
|
public void startArrayValue(A array) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates the end of an array element in the JSON input. This method will be called after
|
||||||
|
* reading the last character of the element value, just after the <code>end</code> method for the
|
||||||
|
* specific element type (like {@link #endString(String) endString()}, {@link #endNumber(String)
|
||||||
|
* endNumber()}, etc.).
|
||||||
|
*
|
||||||
|
* @param array
|
||||||
|
* the array handler returned from {@link #startArray()}, or <code>null</code> if not
|
||||||
|
* provided
|
||||||
|
*/
|
||||||
|
public void endArrayValue(A array) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates the beginning of an object in the JSON input. This method will be called when reading
|
||||||
|
* the opening curly bracket character (<code>'{'</code>).
|
||||||
|
* <p>
|
||||||
|
* This method may return an object to handle subsequent parser events for this object. This
|
||||||
|
* object handler will be provided in all calls to {@link #startObjectName(Object)
|
||||||
|
* startObjectName()}, {@link #endObjectName(Object, String) endObjectName()},
|
||||||
|
* {@link #startObjectValue(Object, String) startObjectValue()},
|
||||||
|
* {@link #endObjectValue(Object, String) endObjectValue()}, and {@link #endObject(Object)
|
||||||
|
* endObject()} for this object.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @return a handler for this object, or <code>null</code> if not needed
|
||||||
|
*/
|
||||||
|
public O startObject() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates the end of an object in the JSON input. This method will be called after reading the
|
||||||
|
* closing curly bracket character (<code>'}'</code>).
|
||||||
|
*
|
||||||
|
* @param object
|
||||||
|
* the object handler returned from {@link #startObject()}, or null if not provided
|
||||||
|
*/
|
||||||
|
public void endObject(O object) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates the beginning of the name of an object member in the JSON input. This method will be
|
||||||
|
* called when reading the opening quote character ('"') of the member name.
|
||||||
|
*
|
||||||
|
* @param object
|
||||||
|
* the object handler returned from {@link #startObject()}, or <code>null</code> if not
|
||||||
|
* provided
|
||||||
|
*/
|
||||||
|
public void startObjectName(O object) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates the end of an object member name in the JSON input. This method will be called after
|
||||||
|
* reading the closing quote character (<code>'"'</code>) of the member name.
|
||||||
|
*
|
||||||
|
* @param object
|
||||||
|
* the object handler returned from {@link #startObject()}, or null if not provided
|
||||||
|
* @param name
|
||||||
|
* the parsed member name
|
||||||
|
*/
|
||||||
|
public void endObjectName(O object, String name) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates the beginning of the name of an object member in the JSON input. This method will be
|
||||||
|
* called when reading the opening quote character ('"') of the member name.
|
||||||
|
*
|
||||||
|
* @param object
|
||||||
|
* the object handler returned from {@link #startObject()}, or <code>null</code> if not
|
||||||
|
* provided
|
||||||
|
* @param name
|
||||||
|
* the member name
|
||||||
|
*/
|
||||||
|
public void startObjectValue(O object, String name) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates the end of an object member value in the JSON input. This method will be called after
|
||||||
|
* reading the last character of the member value, just after the <code>end</code> method for the
|
||||||
|
* specific member type (like {@link #endString(String) endString()}, {@link #endNumber(String)
|
||||||
|
* endNumber()}, etc.).
|
||||||
|
*
|
||||||
|
* @param object
|
||||||
|
* the object handler returned from {@link #startObject()}, or null if not provided
|
||||||
|
* @param name
|
||||||
|
* the parsed member name
|
||||||
|
*/
|
||||||
|
public void endObjectValue(O object, String name) {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,514 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2013, 2016 EclipseSource.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
// from https://github.com/ralfstx/minimal-json
|
||||||
|
|
||||||
|
package com.formdev.flatlaf.json;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Reader;
|
||||||
|
import java.io.StringReader;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A streaming parser for JSON text. The parser reports all events to a given handler.
|
||||||
|
*/
|
||||||
|
class JsonParser {
|
||||||
|
|
||||||
|
private static final int MAX_NESTING_LEVEL = 1000;
|
||||||
|
private static final int MIN_BUFFER_SIZE = 10;
|
||||||
|
private static final int DEFAULT_BUFFER_SIZE = 1024;
|
||||||
|
|
||||||
|
private final JsonHandler<Object, Object> handler;
|
||||||
|
private Reader reader;
|
||||||
|
private char[] buffer;
|
||||||
|
private int bufferOffset;
|
||||||
|
private int index;
|
||||||
|
private int fill;
|
||||||
|
private int line;
|
||||||
|
private int lineOffset;
|
||||||
|
private int current;
|
||||||
|
private StringBuilder captureBuffer;
|
||||||
|
private int captureStart;
|
||||||
|
private int nestingLevel;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* | bufferOffset
|
||||||
|
* v
|
||||||
|
* [a|b|c|d|e|f|g|h|i|j|k|l|m|n|o|p|q|r|s|t] < input
|
||||||
|
* [l|m|n|o|p|q|r|s|t|?|?] < buffer
|
||||||
|
* ^ ^
|
||||||
|
* | index fill
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new JsonParser with the given handler. The parser will report all parser events to
|
||||||
|
* this handler.
|
||||||
|
*
|
||||||
|
* @param handler
|
||||||
|
* the handler to process parser events
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public JsonParser(JsonHandler<?, ?> handler) {
|
||||||
|
if (handler == null) {
|
||||||
|
throw new NullPointerException("handler is null");
|
||||||
|
}
|
||||||
|
this.handler = (JsonHandler<Object, Object>)handler;
|
||||||
|
handler.parser = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the given input string. The input must contain a valid JSON value, optionally padded
|
||||||
|
* with whitespace.
|
||||||
|
*
|
||||||
|
* @param string
|
||||||
|
* the input string, must be valid JSON
|
||||||
|
* @throws ParseException
|
||||||
|
* if the input is not valid JSON
|
||||||
|
*/
|
||||||
|
public void parse(String string) {
|
||||||
|
if (string == null) {
|
||||||
|
throw new NullPointerException("string is null");
|
||||||
|
}
|
||||||
|
int bufferSize = Math.max(MIN_BUFFER_SIZE, Math.min(DEFAULT_BUFFER_SIZE, string.length()));
|
||||||
|
try {
|
||||||
|
parse(new StringReader(string), bufferSize);
|
||||||
|
} catch (IOException exception) {
|
||||||
|
// StringReader does not throw IOException
|
||||||
|
throw new RuntimeException(exception);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads the entire input from the given reader and parses it as JSON. The input must contain a
|
||||||
|
* valid JSON value, optionally padded with whitespace.
|
||||||
|
* <p>
|
||||||
|
* Characters are read in chunks into a default-sized input buffer. Hence, wrapping a reader in an
|
||||||
|
* additional <code>BufferedReader</code> likely won't improve reading performance.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param reader
|
||||||
|
* the reader to read the input from
|
||||||
|
* @throws IOException
|
||||||
|
* if an I/O error occurs in the reader
|
||||||
|
* @throws ParseException
|
||||||
|
* if the input is not valid JSON
|
||||||
|
*/
|
||||||
|
public void parse(Reader reader) throws IOException {
|
||||||
|
parse(reader, DEFAULT_BUFFER_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads the entire input from the given reader and parses it as JSON. The input must contain a
|
||||||
|
* valid JSON value, optionally padded with whitespace.
|
||||||
|
* <p>
|
||||||
|
* Characters are read in chunks into an input buffer of the given size. Hence, wrapping a reader
|
||||||
|
* in an additional <code>BufferedReader</code> likely won't improve reading performance.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @param reader
|
||||||
|
* the reader to read the input from
|
||||||
|
* @param buffersize
|
||||||
|
* the size of the input buffer in chars
|
||||||
|
* @throws IOException
|
||||||
|
* if an I/O error occurs in the reader
|
||||||
|
* @throws ParseException
|
||||||
|
* if the input is not valid JSON
|
||||||
|
*/
|
||||||
|
public void parse(Reader reader, int buffersize) throws IOException {
|
||||||
|
if (reader == null) {
|
||||||
|
throw new NullPointerException("reader is null");
|
||||||
|
}
|
||||||
|
if (buffersize <= 0) {
|
||||||
|
throw new IllegalArgumentException("buffersize is zero or negative");
|
||||||
|
}
|
||||||
|
this.reader = reader;
|
||||||
|
buffer = new char[buffersize];
|
||||||
|
bufferOffset = 0;
|
||||||
|
index = 0;
|
||||||
|
fill = 0;
|
||||||
|
line = 1;
|
||||||
|
lineOffset = 0;
|
||||||
|
current = 0;
|
||||||
|
captureStart = -1;
|
||||||
|
read();
|
||||||
|
skipWhiteSpace();
|
||||||
|
readValue();
|
||||||
|
skipWhiteSpace();
|
||||||
|
if (!isEndOfText()) {
|
||||||
|
throw error("Unexpected character");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readValue() throws IOException {
|
||||||
|
switch (current) {
|
||||||
|
case 'n':
|
||||||
|
readNull();
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
readTrue();
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
readFalse();
|
||||||
|
break;
|
||||||
|
case '"':
|
||||||
|
readString();
|
||||||
|
break;
|
||||||
|
case '[':
|
||||||
|
readArray();
|
||||||
|
break;
|
||||||
|
case '{':
|
||||||
|
readObject();
|
||||||
|
break;
|
||||||
|
case '-':
|
||||||
|
case '0':
|
||||||
|
case '1':
|
||||||
|
case '2':
|
||||||
|
case '3':
|
||||||
|
case '4':
|
||||||
|
case '5':
|
||||||
|
case '6':
|
||||||
|
case '7':
|
||||||
|
case '8':
|
||||||
|
case '9':
|
||||||
|
readNumber();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw expected("value");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readArray() throws IOException {
|
||||||
|
Object array = handler.startArray();
|
||||||
|
read();
|
||||||
|
if (++nestingLevel > MAX_NESTING_LEVEL) {
|
||||||
|
throw error("Nesting too deep");
|
||||||
|
}
|
||||||
|
skipWhiteSpace();
|
||||||
|
if (readChar(']')) {
|
||||||
|
nestingLevel--;
|
||||||
|
handler.endArray(array);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
skipWhiteSpace();
|
||||||
|
handler.startArrayValue(array);
|
||||||
|
readValue();
|
||||||
|
handler.endArrayValue(array);
|
||||||
|
skipWhiteSpace();
|
||||||
|
} while (readChar(','));
|
||||||
|
if (!readChar(']')) {
|
||||||
|
throw expected("',' or ']'");
|
||||||
|
}
|
||||||
|
nestingLevel--;
|
||||||
|
handler.endArray(array);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readObject() throws IOException {
|
||||||
|
Object object = handler.startObject();
|
||||||
|
read();
|
||||||
|
if (++nestingLevel > MAX_NESTING_LEVEL) {
|
||||||
|
throw error("Nesting too deep");
|
||||||
|
}
|
||||||
|
skipWhiteSpace();
|
||||||
|
if (readChar('}')) {
|
||||||
|
nestingLevel--;
|
||||||
|
handler.endObject(object);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
skipWhiteSpace();
|
||||||
|
handler.startObjectName(object);
|
||||||
|
String name = readName();
|
||||||
|
handler.endObjectName(object, name);
|
||||||
|
skipWhiteSpace();
|
||||||
|
if (!readChar(':')) {
|
||||||
|
throw expected("':'");
|
||||||
|
}
|
||||||
|
skipWhiteSpace();
|
||||||
|
handler.startObjectValue(object, name);
|
||||||
|
readValue();
|
||||||
|
handler.endObjectValue(object, name);
|
||||||
|
skipWhiteSpace();
|
||||||
|
} while (readChar(','));
|
||||||
|
if (!readChar('}')) {
|
||||||
|
throw expected("',' or '}'");
|
||||||
|
}
|
||||||
|
nestingLevel--;
|
||||||
|
handler.endObject(object);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String readName() throws IOException {
|
||||||
|
if (current != '"') {
|
||||||
|
throw expected("name");
|
||||||
|
}
|
||||||
|
return readStringInternal();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readNull() throws IOException {
|
||||||
|
handler.startNull();
|
||||||
|
read();
|
||||||
|
readRequiredChar('u');
|
||||||
|
readRequiredChar('l');
|
||||||
|
readRequiredChar('l');
|
||||||
|
handler.endNull();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readTrue() throws IOException {
|
||||||
|
handler.startBoolean();
|
||||||
|
read();
|
||||||
|
readRequiredChar('r');
|
||||||
|
readRequiredChar('u');
|
||||||
|
readRequiredChar('e');
|
||||||
|
handler.endBoolean(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readFalse() throws IOException {
|
||||||
|
handler.startBoolean();
|
||||||
|
read();
|
||||||
|
readRequiredChar('a');
|
||||||
|
readRequiredChar('l');
|
||||||
|
readRequiredChar('s');
|
||||||
|
readRequiredChar('e');
|
||||||
|
handler.endBoolean(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readRequiredChar(char ch) throws IOException {
|
||||||
|
if (!readChar(ch)) {
|
||||||
|
throw expected("'" + ch + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readString() throws IOException {
|
||||||
|
handler.startString();
|
||||||
|
handler.endString(readStringInternal());
|
||||||
|
}
|
||||||
|
|
||||||
|
private String readStringInternal() throws IOException {
|
||||||
|
read();
|
||||||
|
startCapture();
|
||||||
|
while (current != '"') {
|
||||||
|
if (current == '\\') {
|
||||||
|
pauseCapture();
|
||||||
|
readEscape();
|
||||||
|
startCapture();
|
||||||
|
} else if (current < 0x20) {
|
||||||
|
throw expected("valid string character");
|
||||||
|
} else {
|
||||||
|
read();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String string = endCapture();
|
||||||
|
read();
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readEscape() throws IOException {
|
||||||
|
read();
|
||||||
|
switch (current) {
|
||||||
|
case '"':
|
||||||
|
case '/':
|
||||||
|
case '\\':
|
||||||
|
captureBuffer.append((char)current);
|
||||||
|
break;
|
||||||
|
case 'b':
|
||||||
|
captureBuffer.append('\b');
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
captureBuffer.append('\f');
|
||||||
|
break;
|
||||||
|
case 'n':
|
||||||
|
captureBuffer.append('\n');
|
||||||
|
break;
|
||||||
|
case 'r':
|
||||||
|
captureBuffer.append('\r');
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
captureBuffer.append('\t');
|
||||||
|
break;
|
||||||
|
case 'u':
|
||||||
|
char[] hexChars = new char[4];
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
read();
|
||||||
|
if (!isHexDigit()) {
|
||||||
|
throw expected("hexadecimal digit");
|
||||||
|
}
|
||||||
|
hexChars[i] = (char)current;
|
||||||
|
}
|
||||||
|
captureBuffer.append((char)Integer.parseInt(new String(hexChars), 16));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw expected("valid escape sequence");
|
||||||
|
}
|
||||||
|
read();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readNumber() throws IOException {
|
||||||
|
handler.startNumber();
|
||||||
|
startCapture();
|
||||||
|
readChar('-');
|
||||||
|
int firstDigit = current;
|
||||||
|
if (!readDigit()) {
|
||||||
|
throw expected("digit");
|
||||||
|
}
|
||||||
|
if (firstDigit != '0') {
|
||||||
|
while (readDigit()) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
readFraction();
|
||||||
|
readExponent();
|
||||||
|
handler.endNumber(endCapture());
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean readFraction() throws IOException {
|
||||||
|
if (!readChar('.')) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!readDigit()) {
|
||||||
|
throw expected("digit");
|
||||||
|
}
|
||||||
|
while (readDigit()) {
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean readExponent() throws IOException {
|
||||||
|
if (!readChar('e') && !readChar('E')) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (!readChar('+')) {
|
||||||
|
readChar('-');
|
||||||
|
}
|
||||||
|
if (!readDigit()) {
|
||||||
|
throw expected("digit");
|
||||||
|
}
|
||||||
|
while (readDigit()) {
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean readChar(char ch) throws IOException {
|
||||||
|
if (current != ch) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
read();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean readDigit() throws IOException {
|
||||||
|
if (!isDigit()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
read();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void skipWhiteSpace() throws IOException {
|
||||||
|
while (isWhiteSpace()) {
|
||||||
|
read();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void read() throws IOException {
|
||||||
|
if (index == fill) {
|
||||||
|
if (captureStart != -1) {
|
||||||
|
captureBuffer.append(buffer, captureStart, fill - captureStart);
|
||||||
|
captureStart = 0;
|
||||||
|
}
|
||||||
|
bufferOffset += fill;
|
||||||
|
fill = reader.read(buffer, 0, buffer.length);
|
||||||
|
index = 0;
|
||||||
|
if (fill == -1) {
|
||||||
|
current = -1;
|
||||||
|
index++;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (current == '\n') {
|
||||||
|
line++;
|
||||||
|
lineOffset = bufferOffset + index;
|
||||||
|
}
|
||||||
|
current = buffer[index++];
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startCapture() {
|
||||||
|
if (captureBuffer == null) {
|
||||||
|
captureBuffer = new StringBuilder();
|
||||||
|
}
|
||||||
|
captureStart = index - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void pauseCapture() {
|
||||||
|
int end = current == -1 ? index : index - 1;
|
||||||
|
captureBuffer.append(buffer, captureStart, end - captureStart);
|
||||||
|
captureStart = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String endCapture() {
|
||||||
|
int start = captureStart;
|
||||||
|
int end = index - 1;
|
||||||
|
captureStart = -1;
|
||||||
|
if (captureBuffer.length() > 0) {
|
||||||
|
captureBuffer.append(buffer, start, end - start);
|
||||||
|
String captured = captureBuffer.toString();
|
||||||
|
captureBuffer.setLength(0);
|
||||||
|
return captured;
|
||||||
|
}
|
||||||
|
return new String(buffer, start, end - start);
|
||||||
|
}
|
||||||
|
|
||||||
|
Location getLocation() {
|
||||||
|
int offset = bufferOffset + index - 1;
|
||||||
|
int column = offset - lineOffset + 1;
|
||||||
|
return new Location(offset, line, column);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ParseException expected(String expected) {
|
||||||
|
if (isEndOfText()) {
|
||||||
|
return error("Unexpected end of input");
|
||||||
|
}
|
||||||
|
return error("Expected " + expected);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ParseException error(String message) {
|
||||||
|
return new ParseException(message, getLocation());
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isWhiteSpace() {
|
||||||
|
return current == ' ' || current == '\t' || current == '\n' || current == '\r';
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isDigit() {
|
||||||
|
return current >= '0' && current <= '9';
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isHexDigit() {
|
||||||
|
return current >= '0' && current <= '9'
|
||||||
|
|| current >= 'a' && current <= 'f'
|
||||||
|
|| current >= 'A' && current <= 'F';
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isEndOfText() {
|
||||||
|
return current == -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2016 EclipseSource.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
// from https://github.com/ralfstx/minimal-json
|
||||||
|
|
||||||
|
package com.formdev.flatlaf.json;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An immutable object that represents a location in the parsed text.
|
||||||
|
*/
|
||||||
|
public class Location {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The absolute character index, starting at 0.
|
||||||
|
*/
|
||||||
|
public final int offset;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The line number, starting at 1.
|
||||||
|
*/
|
||||||
|
public final int line;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The column number, starting at 1.
|
||||||
|
*/
|
||||||
|
public final int column;
|
||||||
|
|
||||||
|
Location(int offset, int line, int column) {
|
||||||
|
this.offset = offset;
|
||||||
|
this.column = column;
|
||||||
|
this.line = line;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return line + ":" + column;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (getClass() != obj.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Location other = (Location)obj;
|
||||||
|
return offset == other.offset && column == other.column && line == other.line;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2013, 2016 EclipseSource.
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
// from https://github.com/ralfstx/minimal-json
|
||||||
|
|
||||||
|
package com.formdev.flatlaf.json;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An unchecked exception to indicate that an input does not qualify as valid JSON.
|
||||||
|
*/
|
||||||
|
public class ParseException extends RuntimeException {
|
||||||
|
|
||||||
|
private final Location location;
|
||||||
|
|
||||||
|
ParseException(String message, Location location) {
|
||||||
|
super(message + " at " + location);
|
||||||
|
this.location = location;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the location at which the error occurred.
|
||||||
|
*
|
||||||
|
* @return the error location
|
||||||
|
*/
|
||||||
|
public Location getLocation() {
|
||||||
|
return location;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the absolute character index at which the error occurred. The offset of the first
|
||||||
|
* character of a document is 0.
|
||||||
|
*
|
||||||
|
* @return the character offset at which the error occurred, will be >= 0
|
||||||
|
* @deprecated Use {@link #getLocation()} instead
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public int getOffset() {
|
||||||
|
return location.offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the line number in which the error occurred. The number of the first line is 1.
|
||||||
|
*
|
||||||
|
* @return the line in which the error occurred, will be >= 1
|
||||||
|
* @deprecated Use {@link #getLocation()} instead
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public int getLine() {
|
||||||
|
return location.line;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the column number at which the error occurred, i.e. the number of the character in its
|
||||||
|
* line. The number of the first character of a line is 1.
|
||||||
|
*
|
||||||
|
* @return the column in which the error occurred, will be >= 1
|
||||||
|
* @deprecated Use {@link #getLocation()} instead
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public int getColumn() {
|
||||||
|
return location.column;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -38,12 +38,15 @@ public class FlatArrowButton
|
|||||||
extends BasicArrowButton
|
extends BasicArrowButton
|
||||||
implements UIResource
|
implements UIResource
|
||||||
{
|
{
|
||||||
|
public static final int DEFAULT_ARROW_WIDTH = 8;
|
||||||
|
|
||||||
private final boolean chevron;
|
private final boolean chevron;
|
||||||
private final Color foreground;
|
private final Color foreground;
|
||||||
private final Color disabledForeground;
|
private final Color disabledForeground;
|
||||||
private final Color hoverForeground;
|
private final Color hoverForeground;
|
||||||
private final Color hoverBackground;
|
private final Color hoverBackground;
|
||||||
|
|
||||||
|
private int arrowWidth = DEFAULT_ARROW_WIDTH;
|
||||||
private int xOffset = 0;
|
private int xOffset = 0;
|
||||||
private int yOffset = 0;
|
private int yOffset = 0;
|
||||||
|
|
||||||
@@ -80,6 +83,14 @@ public class FlatArrowButton
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getArrowWidth() {
|
||||||
|
return arrowWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setArrowWidth( int arrowWidth ) {
|
||||||
|
this.arrowWidth = arrowWidth;
|
||||||
|
}
|
||||||
|
|
||||||
protected boolean isHover() {
|
protected boolean isHover() {
|
||||||
return hover;
|
return hover;
|
||||||
}
|
}
|
||||||
@@ -128,8 +139,8 @@ public class FlatArrowButton
|
|||||||
int direction = getDirection();
|
int direction = getDirection();
|
||||||
boolean vert = (direction == NORTH || direction == SOUTH);
|
boolean vert = (direction == NORTH || direction == SOUTH);
|
||||||
|
|
||||||
int w = scale( chevron ? 8 : 9 );
|
int w = scale( arrowWidth + (chevron ? 0 : 1) );
|
||||||
int h = scale( chevron ? 4 : 5 );
|
int h = scale( (arrowWidth / 2) + (chevron ? 0 : 1) );
|
||||||
int rw = vert ? w : h;
|
int rw = vert ? w : h;
|
||||||
int rh = vert ? h : w;
|
int rh = vert ? h : w;
|
||||||
int x = Math.round( (width - rw) / 2f + scale( (float) xOffset ) );
|
int x = Math.round( (width - rw) / 2f + scale( (float) xOffset ) );
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import java.awt.Graphics;
|
|||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.awt.Insets;
|
import java.awt.Insets;
|
||||||
import java.awt.KeyboardFocusManager;
|
import java.awt.KeyboardFocusManager;
|
||||||
|
import java.awt.Paint;
|
||||||
import javax.swing.JComboBox;
|
import javax.swing.JComboBox;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
import javax.swing.JScrollPane;
|
import javax.swing.JScrollPane;
|
||||||
@@ -47,7 +48,7 @@ import javax.swing.text.JTextComponent;
|
|||||||
* {@link FlatUIUtils#paintParentBackground} to paint the empty space correctly.
|
* {@link FlatUIUtils#paintParentBackground} to paint the empty space correctly.
|
||||||
*
|
*
|
||||||
* @uiDefault Component.focusWidth int
|
* @uiDefault Component.focusWidth int
|
||||||
* @uiDefault Component.innerFocusWidth int
|
* @uiDefault Component.innerFocusWidth int or float
|
||||||
* @uiDefault Component.focusColor Color
|
* @uiDefault Component.focusColor Color
|
||||||
* @uiDefault Component.borderColor Color
|
* @uiDefault Component.borderColor Color
|
||||||
* @uiDefault Component.disabledBorderColor Color
|
* @uiDefault Component.disabledBorderColor Color
|
||||||
@@ -59,7 +60,7 @@ public class FlatBorder
|
|||||||
extends BasicBorders.MarginBorder
|
extends BasicBorders.MarginBorder
|
||||||
{
|
{
|
||||||
protected final int focusWidth = UIManager.getInt( "Component.focusWidth" );
|
protected final int focusWidth = UIManager.getInt( "Component.focusWidth" );
|
||||||
protected final int innerFocusWidth = UIManager.getInt( "Component.innerFocusWidth" );
|
protected final float innerFocusWidth = FlatUIUtils.getUIFloat( "Component.innerFocusWidth", 0 );
|
||||||
protected final Color focusColor = UIManager.getColor( "Component.focusColor" );
|
protected final Color focusColor = UIManager.getColor( "Component.focusColor" );
|
||||||
protected final Color borderColor = UIManager.getColor( "Component.borderColor" );
|
protected final Color borderColor = UIManager.getColor( "Component.borderColor" );
|
||||||
protected final Color disabledBorderColor = UIManager.getColor( "Component.disabledBorderColor" );
|
protected final Color disabledBorderColor = UIManager.getColor( "Component.disabledBorderColor" );
|
||||||
@@ -71,19 +72,21 @@ public class FlatBorder
|
|||||||
try {
|
try {
|
||||||
FlatUIUtils.setRenderingHints( g2 );
|
FlatUIUtils.setRenderingHints( g2 );
|
||||||
|
|
||||||
boolean isCellEditor = FlatUIUtils.isTableCellEditor( c );
|
boolean isCellEditor = isTableCellEditor( c );
|
||||||
float focusWidth = isCellEditor ? 0 : getFocusWidth();
|
float focusWidth = isCellEditor ? 0 : getFocusWidth( c );
|
||||||
float borderWidth = getBorderWidth( c );
|
float borderWidth = getBorderWidth( c );
|
||||||
float arc = isCellEditor ? 0 : getArc();
|
float arc = isCellEditor ? 0 : getArc( c );
|
||||||
|
|
||||||
if( isFocused( c ) ) {
|
if( isFocused( c ) ) {
|
||||||
|
float innerFocusWidth = !(c instanceof JScrollPane) ? this.innerFocusWidth : 0;
|
||||||
|
|
||||||
g2.setColor( getFocusColor( c ) );
|
g2.setColor( getFocusColor( c ) );
|
||||||
FlatUIUtils.paintOutlineBorder( g2, x, y, width, height, focusWidth,
|
FlatUIUtils.paintComponentOuterBorder( g2, x, y, width, height, focusWidth,
|
||||||
getLineWidth() + scale( (float) innerFocusWidth ), arc );
|
getLineWidth( c ) + scale( innerFocusWidth ), arc );
|
||||||
}
|
}
|
||||||
|
|
||||||
g2.setColor( getBorderColor( c ) );
|
g2.setPaint( getBorderColor( c ) );
|
||||||
FlatUIUtils.drawRoundRectangle( g2, x, y, width, height, focusWidth, borderWidth, arc );
|
FlatUIUtils.paintComponentBorder( g2, x, y, width, height, focusWidth, borderWidth, arc );
|
||||||
} finally {
|
} finally {
|
||||||
g2.dispose();
|
g2.dispose();
|
||||||
}
|
}
|
||||||
@@ -93,13 +96,24 @@ public class FlatBorder
|
|||||||
return focusColor;
|
return focusColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Color getBorderColor( Component c ) {
|
protected Paint getBorderColor( Component c ) {
|
||||||
boolean enabled = c.isEnabled() && (!(c instanceof JTextComponent) || ((JTextComponent)c).isEditable());
|
return isEnabled( c )
|
||||||
return enabled
|
|
||||||
? (isFocused( c ) ? focusedBorderColor : borderColor)
|
? (isFocused( c ) ? focusedBorderColor : borderColor)
|
||||||
: disabledBorderColor;
|
: disabledBorderColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected boolean isEnabled( Component c ) {
|
||||||
|
if( c instanceof JScrollPane ) {
|
||||||
|
// check whether view component is disabled
|
||||||
|
JViewport viewport = ((JScrollPane)c).getViewport();
|
||||||
|
Component view = (viewport != null) ? viewport.getView() : null;
|
||||||
|
if( view != null && !isEnabled( view ) )
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.isEnabled() && (!(c instanceof JTextComponent) || ((JTextComponent)c).isEditable());
|
||||||
|
}
|
||||||
|
|
||||||
protected boolean isFocused( Component c ) {
|
protected boolean isFocused( Component c ) {
|
||||||
if( c instanceof JScrollPane ) {
|
if( c instanceof JScrollPane ) {
|
||||||
JViewport viewport = ((JScrollPane)c).getViewport();
|
JViewport viewport = ((JScrollPane)c).getViewport();
|
||||||
@@ -132,10 +146,14 @@ public class FlatBorder
|
|||||||
return c.hasFocus();
|
return c.hasFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected boolean isTableCellEditor( Component c ) {
|
||||||
|
return FlatUIUtils.isTableCellEditor( c );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Insets getBorderInsets( Component c, Insets insets ) {
|
public Insets getBorderInsets( Component c, Insets insets ) {
|
||||||
boolean isCellEditor = FlatUIUtils.isTableCellEditor( c );
|
boolean isCellEditor = isTableCellEditor( c );
|
||||||
float ow = (isCellEditor ? 0 : getFocusWidth()) + getLineWidth();
|
float ow = (isCellEditor ? 0 : getFocusWidth( c )) + getLineWidth( c );
|
||||||
|
|
||||||
insets = super.getBorderInsets( c, insets );
|
insets = super.getBorderInsets( c, insets );
|
||||||
insets.top = Math.round( scale( (float) insets.top ) + ow );
|
insets.top = Math.round( scale( (float) insets.top ) + ow );
|
||||||
@@ -145,19 +163,19 @@ public class FlatBorder
|
|||||||
return insets;
|
return insets;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected float getFocusWidth() {
|
protected float getFocusWidth( Component c ) {
|
||||||
return scale( (float) focusWidth );
|
return scale( (float) focusWidth );
|
||||||
}
|
}
|
||||||
|
|
||||||
protected float getLineWidth() {
|
protected float getLineWidth( Component c ) {
|
||||||
return scale( 1f );
|
return scale( 1f );
|
||||||
}
|
}
|
||||||
|
|
||||||
protected float getBorderWidth( Component c ) {
|
protected float getBorderWidth( Component c ) {
|
||||||
return getLineWidth();
|
return getLineWidth( c );
|
||||||
}
|
}
|
||||||
|
|
||||||
protected float getArc() {
|
protected float getArc( Component c ) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,8 +19,10 @@ package com.formdev.flatlaf.ui;
|
|||||||
import static com.formdev.flatlaf.util.UIScale.scale;
|
import static com.formdev.flatlaf.util.UIScale.scale;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
|
import java.awt.GradientPaint;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.awt.Insets;
|
import java.awt.Insets;
|
||||||
|
import java.awt.Paint;
|
||||||
import javax.swing.JButton;
|
import javax.swing.JButton;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import javax.swing.plaf.UIResource;
|
import javax.swing.plaf.UIResource;
|
||||||
@@ -29,10 +31,14 @@ import javax.swing.plaf.UIResource;
|
|||||||
* Border for {@link javax.swing.JButton}.
|
* Border for {@link javax.swing.JButton}.
|
||||||
*
|
*
|
||||||
* @uiDefault Button.borderColor Color
|
* @uiDefault Button.borderColor Color
|
||||||
|
* @uiDefault Button.startBorderColor Color optional; if set, a gradient paint is used and Button.borderColor is ignored
|
||||||
|
* @uiDefault Button.endBorderColor Color optional; if set, a gradient paint is used
|
||||||
* @uiDefault Button.disabledBorderColor Color
|
* @uiDefault Button.disabledBorderColor Color
|
||||||
* @uiDefault Button.focusedBorderColor Color
|
* @uiDefault Button.focusedBorderColor Color
|
||||||
* @uiDefault Button.hoverBorderColor Color optional
|
* @uiDefault Button.hoverBorderColor Color optional
|
||||||
* @uiDefault Button.default.borderColor Color
|
* @uiDefault Button.default.borderColor Color
|
||||||
|
* @uiDefault Button.default.startBorderColor Color optional; if set, a gradient paint is used and Button.default.borderColor is ignored
|
||||||
|
* @uiDefault Button.default.endBorderColor Color optional; if set, a gradient paint is used
|
||||||
* @uiDefault Button.default.hoverBorderColor Color optional
|
* @uiDefault Button.default.hoverBorderColor Color optional
|
||||||
* @uiDefault Button.default.focusedBorderColor Color
|
* @uiDefault Button.default.focusedBorderColor Color
|
||||||
* @uiDefault Button.default.focusColor Color
|
* @uiDefault Button.default.focusColor Color
|
||||||
@@ -44,11 +50,13 @@ import javax.swing.plaf.UIResource;
|
|||||||
public class FlatButtonBorder
|
public class FlatButtonBorder
|
||||||
extends FlatBorder
|
extends FlatBorder
|
||||||
{
|
{
|
||||||
protected final Color borderColor = UIManager.getColor( "Button.borderColor" );
|
protected final Color borderColor = FlatUIUtils.getUIColor( "Button.startBorderColor", "Button.borderColor" );
|
||||||
|
protected final Color endBorderColor = UIManager.getColor( "Button.endBorderColor" );
|
||||||
protected final Color disabledBorderColor = UIManager.getColor( "Button.disabledBorderColor" );
|
protected final Color disabledBorderColor = UIManager.getColor( "Button.disabledBorderColor" );
|
||||||
protected final Color focusedBorderColor = UIManager.getColor( "Button.focusedBorderColor" );
|
protected final Color focusedBorderColor = UIManager.getColor( "Button.focusedBorderColor" );
|
||||||
protected final Color hoverBorderColor = UIManager.getColor( "Button.hoverBorderColor" );
|
protected final Color hoverBorderColor = UIManager.getColor( "Button.hoverBorderColor" );
|
||||||
protected final Color defaultBorderColor = UIManager.getColor( "Button.default.borderColor" );
|
protected final Color defaultBorderColor = FlatUIUtils.getUIColor( "Button.default.startBorderColor", "Button.default.borderColor" );
|
||||||
|
protected final Color defaultEndBorderColor = UIManager.getColor( "Button.default.endBorderColor" );
|
||||||
protected final Color defaultHoverBorderColor = UIManager.getColor( "Button.default.hoverBorderColor" );
|
protected final Color defaultHoverBorderColor = UIManager.getColor( "Button.default.hoverBorderColor" );
|
||||||
protected final Color defaultFocusedBorderColor = UIManager.getColor( "Button.default.focusedBorderColor" );
|
protected final Color defaultFocusedBorderColor = UIManager.getColor( "Button.default.focusedBorderColor" );
|
||||||
protected final Color defaultFocusColor = UIManager.getColor( "Button.default.focusColor" );
|
protected final Color defaultFocusColor = UIManager.getColor( "Button.default.focusColor" );
|
||||||
@@ -57,7 +65,7 @@ public class FlatButtonBorder
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
|
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
|
||||||
if( FlatButtonUI.isContentAreaFilled( c ) && !FlatButtonUI.isHelpButton( c ) )
|
if( FlatButtonUI.isContentAreaFilled( c ) && !FlatButtonUI.isHelpButton( c ) && !FlatToggleButtonUI.isTabButton( c ) )
|
||||||
super.paintBorder( c, g, x, y, width, height );
|
super.paintBorder( c, g, x, y, width, height );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,14 +75,22 @@ public class FlatButtonBorder
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Color getBorderColor( Component c ) {
|
protected Paint getBorderColor( Component c ) {
|
||||||
boolean def = FlatButtonUI.isDefaultButton( c );
|
boolean def = FlatButtonUI.isDefaultButton( c );
|
||||||
return FlatButtonUI.buttonStateColor( c,
|
Paint color = FlatButtonUI.buttonStateColor( c,
|
||||||
def ? defaultBorderColor : borderColor,
|
def ? defaultBorderColor : borderColor,
|
||||||
disabledBorderColor,
|
disabledBorderColor,
|
||||||
def ? defaultFocusedBorderColor : focusedBorderColor,
|
def ? defaultFocusedBorderColor : focusedBorderColor,
|
||||||
def ? defaultHoverBorderColor : hoverBorderColor,
|
def ? defaultHoverBorderColor : hoverBorderColor,
|
||||||
null );
|
null );
|
||||||
|
|
||||||
|
// change to gradient paint if start/end colors are specified
|
||||||
|
Color startBg = def ? defaultBorderColor : borderColor;
|
||||||
|
Color endBg = def ? defaultEndBorderColor : endBorderColor;
|
||||||
|
if( color == startBg && endBg != null && !startBg.equals( endBg ) )
|
||||||
|
color = new GradientPaint( 0, 0, startBg, 0, c.getHeight(), endBg );
|
||||||
|
|
||||||
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -88,13 +104,18 @@ public class FlatButtonBorder
|
|||||||
return insets;
|
return insets;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected float getFocusWidth( Component c ) {
|
||||||
|
return FlatToggleButtonUI.isTabButton( c ) ? 0 : super.getFocusWidth(c );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected float getBorderWidth( Component c ) {
|
protected float getBorderWidth( Component c ) {
|
||||||
return FlatButtonUI.isDefaultButton( c ) ? scale( (float) defaultBorderWidth ) : super.getBorderWidth( c );
|
return FlatButtonUI.isDefaultButton( c ) ? scale( (float) defaultBorderWidth ) : super.getBorderWidth( c );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected float getArc() {
|
protected float getArc( Component c ) {
|
||||||
return scale( (float) arc );
|
return FlatButtonUI.isSquareButton( c ) ? 0 : scale( (float) arc );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,9 +23,12 @@ import java.awt.Component;
|
|||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.Font;
|
import java.awt.Font;
|
||||||
import java.awt.FontMetrics;
|
import java.awt.FontMetrics;
|
||||||
|
import java.awt.GradientPaint;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.awt.Rectangle;
|
import java.awt.Rectangle;
|
||||||
|
import java.awt.geom.RoundRectangle2D;
|
||||||
|
import java.beans.PropertyChangeEvent;
|
||||||
import javax.swing.AbstractButton;
|
import javax.swing.AbstractButton;
|
||||||
import javax.swing.ButtonModel;
|
import javax.swing.ButtonModel;
|
||||||
import javax.swing.Icon;
|
import javax.swing.Icon;
|
||||||
@@ -37,28 +40,47 @@ import javax.swing.UIManager;
|
|||||||
import javax.swing.border.Border;
|
import javax.swing.border.Border;
|
||||||
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.BasicButtonListener;
|
||||||
import javax.swing.plaf.basic.BasicButtonUI;
|
import javax.swing.plaf.basic.BasicButtonUI;
|
||||||
import com.formdev.flatlaf.FlatLaf;
|
import com.formdev.flatlaf.FlatLaf;
|
||||||
|
import com.formdev.flatlaf.util.UIScale;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JButton}.
|
* Provides the Flat LaF UI delegate for {@link javax.swing.JButton}.
|
||||||
*
|
*
|
||||||
* TODO document used UI defaults of superclass
|
* <!-- BasicButtonUI -->
|
||||||
|
*
|
||||||
|
* @uiDefault Button.font Font
|
||||||
|
* @uiDefault Button.background Color
|
||||||
|
* @uiDefault Button.foreground Color
|
||||||
|
* @uiDefault Button.border Border
|
||||||
|
* @uiDefault Button.margin Insets
|
||||||
|
* @uiDefault Button.rollover boolean
|
||||||
|
*
|
||||||
|
* <!-- FlatButtonUI -->
|
||||||
*
|
*
|
||||||
* @uiDefault Component.focusWidth int
|
* @uiDefault Component.focusWidth int
|
||||||
* @uiDefault Button.arc int
|
* @uiDefault Button.arc int
|
||||||
* @uiDefault Button.minimumWidth int
|
* @uiDefault Button.minimumWidth int
|
||||||
* @uiDefault Button.iconTextGap int
|
* @uiDefault Button.iconTextGap int
|
||||||
|
* @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.focusedBackground Color optional
|
* @uiDefault Button.focusedBackground Color optional
|
||||||
* @uiDefault Button.hoverBackground Color optional
|
* @uiDefault Button.hoverBackground Color optional
|
||||||
* @uiDefault Button.pressedBackground Color optional
|
* @uiDefault Button.pressedBackground Color optional
|
||||||
* @uiDefault Button.disabledText Color
|
* @uiDefault Button.disabledText Color
|
||||||
* @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.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.hoverBackground Color optional
|
* @uiDefault Button.default.hoverBackground Color optional
|
||||||
* @uiDefault Button.default.pressedBackground Color optional
|
* @uiDefault Button.default.pressedBackground Color optional
|
||||||
* @uiDefault Button.default.boldText boolean
|
* @uiDefault Button.default.boldText boolean
|
||||||
|
* @uiDefault Button.paintShadow boolean default is false
|
||||||
|
* @uiDefault Button.shadowWidth int default is 2
|
||||||
|
* @uiDefault Button.shadowColor Color optional
|
||||||
|
* @uiDefault Button.default.shadowColor Color optional
|
||||||
* @uiDefault Button.toolbar.hoverBackground Color
|
* @uiDefault Button.toolbar.hoverBackground Color
|
||||||
* @uiDefault Button.toolbar.pressedBackground Color
|
* @uiDefault Button.toolbar.pressedBackground Color
|
||||||
*
|
*
|
||||||
@@ -72,18 +94,25 @@ public class FlatButtonUI
|
|||||||
protected int minimumWidth;
|
protected int minimumWidth;
|
||||||
protected int iconTextGap;
|
protected int iconTextGap;
|
||||||
|
|
||||||
|
protected Color startBackground;
|
||||||
|
protected Color endBackground;
|
||||||
protected Color focusedBackground;
|
protected Color focusedBackground;
|
||||||
protected Color hoverBackground;
|
protected Color hoverBackground;
|
||||||
protected Color pressedBackground;
|
protected Color pressedBackground;
|
||||||
protected Color disabledText;
|
protected Color disabledText;
|
||||||
|
|
||||||
protected Color defaultBackground;
|
protected Color defaultBackground;
|
||||||
|
protected Color defaultEndBackground;
|
||||||
protected Color defaultForeground;
|
protected Color defaultForeground;
|
||||||
protected Color defaultFocusedBackground;
|
protected Color defaultFocusedBackground;
|
||||||
protected Color defaultHoverBackground;
|
protected Color defaultHoverBackground;
|
||||||
protected Color defaultPressedBackground;
|
protected Color defaultPressedBackground;
|
||||||
protected boolean defaultBoldText;
|
protected boolean defaultBoldText;
|
||||||
|
|
||||||
|
protected int shadowWidth;
|
||||||
|
protected Color shadowColor;
|
||||||
|
protected Color defaultShadowColor;
|
||||||
|
|
||||||
protected Color toolbarHoverBackground;
|
protected Color toolbarHoverBackground;
|
||||||
protected Color toolbarPressedBackground;
|
protected Color toolbarPressedBackground;
|
||||||
|
|
||||||
@@ -107,16 +136,29 @@ public class FlatButtonUI
|
|||||||
String prefix = getPropertyPrefix();
|
String prefix = getPropertyPrefix();
|
||||||
|
|
||||||
focusWidth = UIManager.getInt( "Component.focusWidth" );
|
focusWidth = UIManager.getInt( "Component.focusWidth" );
|
||||||
arc = UIManager.getInt( prefix + "arc" );
|
arc = UIManager.getInt( "Button.arc" );
|
||||||
minimumWidth = UIManager.getInt( prefix + "minimumWidth" );
|
minimumWidth = UIManager.getInt( prefix + "minimumWidth" );
|
||||||
iconTextGap = FlatUIUtils.getUIInt( prefix + "iconTextGap", 4 );
|
iconTextGap = FlatUIUtils.getUIInt( prefix + "iconTextGap", 4 );
|
||||||
|
|
||||||
|
startBackground = UIManager.getColor( prefix + "startBackground" );
|
||||||
|
endBackground = UIManager.getColor( prefix + "endBackground" );
|
||||||
focusedBackground = UIManager.getColor( prefix + "focusedBackground" );
|
focusedBackground = UIManager.getColor( prefix + "focusedBackground" );
|
||||||
hoverBackground = UIManager.getColor( prefix + "hoverBackground" );
|
hoverBackground = UIManager.getColor( prefix + "hoverBackground" );
|
||||||
pressedBackground = UIManager.getColor( prefix + "pressedBackground" );
|
pressedBackground = UIManager.getColor( prefix + "pressedBackground" );
|
||||||
disabledText = UIManager.getColor( prefix + "disabledText" );
|
disabledText = UIManager.getColor( prefix + "disabledText" );
|
||||||
|
|
||||||
defaultBackground = UIManager.getColor( "Button.default.background" );
|
if( UIManager.getBoolean( "Button.paintShadow" ) ) {
|
||||||
|
shadowWidth = FlatUIUtils.getUIInt( "Button.shadowWidth", 2 );
|
||||||
|
shadowColor = UIManager.getColor( "Button.shadowColor" );
|
||||||
|
defaultShadowColor = UIManager.getColor( "Button.default.shadowColor" );
|
||||||
|
} else {
|
||||||
|
shadowWidth = 0;
|
||||||
|
shadowColor = null;
|
||||||
|
defaultShadowColor = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultBackground = FlatUIUtils.getUIColor( "Button.default.startBackground", "Button.default.background" );
|
||||||
|
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" );
|
||||||
defaultHoverBackground = UIManager.getColor( "Button.default.hoverBackground" );
|
defaultHoverBackground = UIManager.getColor( "Button.default.hoverBackground" );
|
||||||
@@ -131,10 +173,16 @@ public class FlatButtonUI
|
|||||||
defaults_initialized = true;
|
defaults_initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( startBackground != null ) {
|
||||||
|
Color bg = b.getBackground();
|
||||||
|
if( bg == null || bg instanceof UIResource )
|
||||||
|
b.setBackground( startBackground );
|
||||||
|
}
|
||||||
|
|
||||||
LookAndFeel.installProperty( b, "opaque", false );
|
LookAndFeel.installProperty( b, "opaque", false );
|
||||||
LookAndFeel.installProperty( b, "iconTextGap", scale( iconTextGap ) );
|
LookAndFeel.installProperty( b, "iconTextGap", scale( iconTextGap ) );
|
||||||
|
|
||||||
MigLayoutVisualPadding.install( b, focusWidth );
|
MigLayoutVisualPadding.install( b, getFocusWidth( b ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -145,6 +193,26 @@ public class FlatButtonUI
|
|||||||
defaults_initialized = false;
|
defaults_initialized = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected BasicButtonListener createButtonListener( AbstractButton b ) {
|
||||||
|
return new BasicButtonListener( b ) {
|
||||||
|
@Override
|
||||||
|
public void propertyChange( PropertyChangeEvent e ) {
|
||||||
|
super.propertyChange( e );
|
||||||
|
FlatButtonUI.this.propertyChange( b, e );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void propertyChange( AbstractButton b, PropertyChangeEvent e ) {
|
||||||
|
switch( e.getPropertyName() ) {
|
||||||
|
case MINIMUM_WIDTH:
|
||||||
|
case MINIMUM_HEIGHT:
|
||||||
|
b.revalidate();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static boolean isContentAreaFilled( Component c ) {
|
static boolean isContentAreaFilled( Component c ) {
|
||||||
return !(c instanceof AbstractButton) || ((AbstractButton)c).isContentAreaFilled();
|
return !(c instanceof AbstractButton) || ((AbstractButton)c).isContentAreaFilled();
|
||||||
}
|
}
|
||||||
@@ -154,10 +222,17 @@ public class FlatButtonUI
|
|||||||
}
|
}
|
||||||
|
|
||||||
static boolean isIconOnlyButton( Component c ) {
|
static boolean isIconOnlyButton( Component c ) {
|
||||||
String text;
|
if( !(c instanceof JButton) )
|
||||||
return c instanceof JButton &&
|
return false;
|
||||||
((JButton)c).getIcon() != null &&
|
|
||||||
((text = ((JButton)c).getText()) == null || text.isEmpty());
|
Icon icon = ((JButton)c).getIcon();
|
||||||
|
String text = ((JButton)c).getText();
|
||||||
|
return (icon != null && (text == null || text.isEmpty())) ||
|
||||||
|
(icon == null && text != null && ("...".equals( text ) || text.length() == 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean isSquareButton( Component c ) {
|
||||||
|
return c instanceof AbstractButton && clientPropertyEquals( (AbstractButton) c, BUTTON_TYPE, BUTTON_TYPE_SQUARE );
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean isHelpButton( Component c ) {
|
static boolean isHelpButton( Component c ) {
|
||||||
@@ -179,7 +254,13 @@ public class FlatButtonUI
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( isContentAreaFilled( c ) ) {
|
if( isContentAreaFilled( c ) )
|
||||||
|
paintBackground( g, c );
|
||||||
|
|
||||||
|
paint( g, c );
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void paintBackground( Graphics g, JComponent c ) {
|
||||||
Color background = getBackground( c );
|
Color background = getBackground( c );
|
||||||
if( background != null ) {
|
if( background != null ) {
|
||||||
Graphics2D g2 = (Graphics2D) g.create();
|
Graphics2D g2 = (Graphics2D) g.create();
|
||||||
@@ -187,20 +268,33 @@ public class FlatButtonUI
|
|||||||
FlatUIUtils.setRenderingHints( g2 );
|
FlatUIUtils.setRenderingHints( g2 );
|
||||||
|
|
||||||
Border border = c.getBorder();
|
Border border = c.getBorder();
|
||||||
float focusWidth = (border instanceof FlatBorder) ? scale( (float) this.focusWidth ) : 0;
|
float focusWidth = (border instanceof FlatBorder) ? scale( (float) getFocusWidth( c ) ) : 0;
|
||||||
float arc = (border instanceof FlatButtonBorder || isToolBarButton( c )) ? scale( (float) this.arc ) : 0;
|
float arc = ((border instanceof FlatButtonBorder && !isSquareButton( c )) || isToolBarButton( c ))
|
||||||
|
? scale( (float) this.arc ) : 0;
|
||||||
|
boolean def = isDefaultButton( c );
|
||||||
|
|
||||||
FlatUIUtils.setColor( g2, background, isDefaultButton(c) ? defaultBackground : c.getBackground() );
|
// paint shadow
|
||||||
FlatUIUtils.fillRoundRectangle( g2, 0, 0, c.getWidth(), c.getHeight(), focusWidth, arc );
|
Color shadowColor = def ? defaultShadowColor : this.shadowColor;
|
||||||
|
if( shadowColor != null && shadowWidth > 0 && focusWidth > 0 && !c.hasFocus() && c.isEnabled() ) {
|
||||||
|
g2.setColor( shadowColor );
|
||||||
|
g2.fill( new RoundRectangle2D.Float( focusWidth, focusWidth + UIScale.scale( (float) shadowWidth ),
|
||||||
|
c.getWidth() - focusWidth * 2, c.getHeight() - focusWidth * 2, arc, arc ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// paint background
|
||||||
|
Color startBg = def ? defaultBackground : startBackground;
|
||||||
|
Color endBg = def ? defaultEndBackground : endBackground;
|
||||||
|
if( background == startBg && endBg != null && !startBg.equals( endBg ) )
|
||||||
|
g2.setPaint( new GradientPaint( 0, 0, startBg, 0, c.getHeight(), endBg ) );
|
||||||
|
else
|
||||||
|
FlatUIUtils.setColor( g2, background, def ? defaultBackground : c.getBackground() );
|
||||||
|
FlatUIUtils.paintComponentBackground( g2, 0, 0, c.getWidth(), c.getHeight(), focusWidth, arc );
|
||||||
} finally {
|
} finally {
|
||||||
g2.dispose();
|
g2.dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
paint( g, c );
|
|
||||||
}
|
|
||||||
|
|
||||||
@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 ) )
|
||||||
@@ -286,10 +380,20 @@ public class FlatButtonUI
|
|||||||
|
|
||||||
Dimension prefSize = super.getPreferredSize( c );
|
Dimension prefSize = super.getPreferredSize( c );
|
||||||
|
|
||||||
// apply minimum width, if not in toolbar and not a icon-only button
|
// make button square if it is a icon-only button
|
||||||
if( !isToolBarButton( c ) && !isIconOnlyButton( c ) )
|
// or apply minimum width, if not in toolbar and not a icon-only button
|
||||||
prefSize.width = Math.max( prefSize.width, scale( minimumWidth + (focusWidth * 2) ) );
|
if( isIconOnlyButton( c ) )
|
||||||
|
prefSize.width = Math.max( prefSize.width, prefSize.height );
|
||||||
|
else if( !isToolBarButton( c ) && c.getBorder() instanceof FlatButtonBorder ) {
|
||||||
|
int focusWidth = getFocusWidth( c );
|
||||||
|
prefSize.width = Math.max( prefSize.width, scale( FlatUIUtils.minimumWidth( c, minimumWidth ) + (focusWidth * 2) ) );
|
||||||
|
prefSize.height = Math.max( prefSize.height, scale( FlatUIUtils.minimumHeight( c, 0 ) + (focusWidth * 2) ) );
|
||||||
|
}
|
||||||
|
|
||||||
return prefSize;
|
return prefSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected int getFocusWidth( JComponent c ) {
|
||||||
|
return focusWidth;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,14 +17,37 @@
|
|||||||
package com.formdev.flatlaf.ui;
|
package com.formdev.flatlaf.ui;
|
||||||
|
|
||||||
import static com.formdev.flatlaf.util.UIScale.scale;
|
import static com.formdev.flatlaf.util.UIScale.scale;
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import java.awt.Rectangle;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
|
import javax.swing.JMenuItem;
|
||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
import javax.swing.plaf.basic.BasicCheckBoxMenuItemUI;
|
import javax.swing.plaf.basic.BasicCheckBoxMenuItemUI;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JCheckBoxMenuItem}.
|
* Provides the Flat LaF UI delegate for {@link javax.swing.JCheckBoxMenuItem}.
|
||||||
*
|
*
|
||||||
|
* <!-- BasicCheckBoxMenuItemUI -->
|
||||||
|
*
|
||||||
|
* @uiDefault CheckBoxMenuItem.font Font
|
||||||
|
* @uiDefault CheckBoxMenuItem.background Color
|
||||||
|
* @uiDefault CheckBoxMenuItem.foreground Color
|
||||||
|
* @uiDefault CheckBoxMenuItem.disabledForeground Color
|
||||||
|
* @uiDefault CheckBoxMenuItem.selectionBackground Color
|
||||||
|
* @uiDefault CheckBoxMenuItem.selectionForeground Color
|
||||||
|
* @uiDefault CheckBoxMenuItem.acceleratorForeground Color
|
||||||
|
* @uiDefault CheckBoxMenuItem.acceleratorSelectionForeground Color
|
||||||
|
* @uiDefault MenuItem.acceleratorFont Font defaults to MenuItem.font
|
||||||
|
* @uiDefault MenuItem.acceleratorDelimiter String
|
||||||
|
* @uiDefault CheckBoxMenuItem.border Border
|
||||||
|
* @uiDefault CheckBoxMenuItem.borderPainted boolean
|
||||||
|
* @uiDefault CheckBoxMenuItem.margin Insets
|
||||||
|
* @uiDefault CheckBoxMenuItem.arrowIcon Icon
|
||||||
|
* @uiDefault CheckBoxMenuItem.checkIcon Icon
|
||||||
|
* @uiDefault CheckBoxMenuItem.opaque boolean
|
||||||
|
* @uiDefault CheckBoxMenuItem.evenHeight boolean
|
||||||
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
public class FlatCheckBoxMenuItemUI
|
public class FlatCheckBoxMenuItemUI
|
||||||
@@ -54,4 +77,9 @@ public class FlatCheckBoxMenuItemUI
|
|||||||
defaultTextIconGap = scale( defaultTextIconGap );
|
defaultTextIconGap = scale( defaultTextIconGap );
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void paintText( Graphics g, JMenuItem menuItem, Rectangle textRect, String text ) {
|
||||||
|
FlatMenuItemUI.paintText( g, menuItem, textRect, text, disabledForeground, selectionForeground );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,6 +22,21 @@ import javax.swing.plaf.ComponentUI;
|
|||||||
/**
|
/**
|
||||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JCheckBox}.
|
* Provides the Flat LaF UI delegate for {@link javax.swing.JCheckBox}.
|
||||||
*
|
*
|
||||||
|
* <!-- BasicRadioButtonUI -->
|
||||||
|
*
|
||||||
|
* @uiDefault CheckBox.font Font
|
||||||
|
* @uiDefault CheckBox.background Color
|
||||||
|
* @uiDefault CheckBox.foreground Color
|
||||||
|
* @uiDefault CheckBox.border Border
|
||||||
|
* @uiDefault CheckBox.margin Insets
|
||||||
|
* @uiDefault CheckBox.rollover boolean
|
||||||
|
* @uiDefault CheckBox.icon Icon
|
||||||
|
*
|
||||||
|
* <!-- FlatRadioButtonUI -->
|
||||||
|
*
|
||||||
|
* @uiDefault CheckBox.iconTextGap int
|
||||||
|
* @uiDefault CheckBox.disabledText Color
|
||||||
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
public class FlatCheckBoxUI
|
public class FlatCheckBoxUI
|
||||||
|
|||||||
@@ -26,6 +26,11 @@ import com.formdev.flatlaf.util.UIScale;
|
|||||||
/**
|
/**
|
||||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JColorChooser}.
|
* Provides the Flat LaF UI delegate for {@link javax.swing.JColorChooser}.
|
||||||
*
|
*
|
||||||
|
* <!-- BasicColorChooserUI -->
|
||||||
|
*
|
||||||
|
* @uiDefault ColorChooser.font Font
|
||||||
|
* @uiDefault ColorChooser.background Color
|
||||||
|
* @uiDefault ColorChooser.foreground Color
|
||||||
* @uiDefault ColorChooser.showPreviewPanelText boolean
|
* @uiDefault ColorChooser.showPreviewPanelText boolean
|
||||||
* @uiDefault ColorChooser.swatchesSwatchSize Dimension
|
* @uiDefault ColorChooser.swatchesSwatchSize Dimension
|
||||||
* @uiDefault ColorChooser.swatchesRecentSwatchSize Dimension
|
* @uiDefault ColorChooser.swatchesRecentSwatchSize Dimension
|
||||||
|
|||||||
@@ -28,18 +28,25 @@ import java.awt.Insets;
|
|||||||
import java.awt.LayoutManager;
|
import java.awt.LayoutManager;
|
||||||
import java.awt.Rectangle;
|
import java.awt.Rectangle;
|
||||||
import java.awt.Shape;
|
import java.awt.Shape;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
import java.awt.event.FocusEvent;
|
import java.awt.event.FocusEvent;
|
||||||
import java.awt.event.FocusListener;
|
import java.awt.event.FocusListener;
|
||||||
import java.awt.event.MouseListener;
|
import java.awt.event.MouseListener;
|
||||||
import java.awt.geom.Rectangle2D;
|
import java.awt.geom.Rectangle2D;
|
||||||
import java.beans.PropertyChangeEvent;
|
import java.beans.PropertyChangeEvent;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
import javax.swing.AbstractAction;
|
||||||
import javax.swing.BorderFactory;
|
import javax.swing.BorderFactory;
|
||||||
|
import javax.swing.DefaultListCellRenderer;
|
||||||
|
import javax.swing.InputMap;
|
||||||
import javax.swing.JButton;
|
import javax.swing.JButton;
|
||||||
import javax.swing.JComboBox;
|
import javax.swing.JComboBox;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
import javax.swing.JList;
|
import javax.swing.JList;
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.KeyStroke;
|
||||||
import javax.swing.ListCellRenderer;
|
import javax.swing.ListCellRenderer;
|
||||||
import javax.swing.LookAndFeel;
|
import javax.swing.LookAndFeel;
|
||||||
import javax.swing.SwingConstants;
|
import javax.swing.SwingConstants;
|
||||||
@@ -51,18 +58,31 @@ import javax.swing.plaf.basic.BasicComboBoxUI;
|
|||||||
import javax.swing.plaf.basic.BasicComboPopup;
|
import javax.swing.plaf.basic.BasicComboPopup;
|
||||||
import javax.swing.plaf.basic.ComboPopup;
|
import javax.swing.plaf.basic.ComboPopup;
|
||||||
import javax.swing.text.JTextComponent;
|
import javax.swing.text.JTextComponent;
|
||||||
|
import com.formdev.flatlaf.FlatClientProperties;
|
||||||
|
import com.formdev.flatlaf.util.SystemInfo;
|
||||||
import com.formdev.flatlaf.util.UIScale;
|
import com.formdev.flatlaf.util.UIScale;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JComboBox}.
|
* Provides the Flat LaF UI delegate for {@link javax.swing.JComboBox}.
|
||||||
*
|
*
|
||||||
* TODO document used UI defaults of superclass
|
* <!-- BasicComboBoxUI -->
|
||||||
|
*
|
||||||
|
* @uiDefault ComboBox.font Font
|
||||||
|
* @uiDefault ComboBox.background Color
|
||||||
|
* @uiDefault ComboBox.foreground Color
|
||||||
|
* @uiDefault ComboBox.border Border
|
||||||
|
* @uiDefault ComboBox.padding Insets
|
||||||
|
* @uiDefault ComboBox.squareButton boolean default is true
|
||||||
|
*
|
||||||
|
* <!-- FlatComboBoxUI -->
|
||||||
*
|
*
|
||||||
* @uiDefault Component.focusWidth int
|
* @uiDefault Component.focusWidth int
|
||||||
* @uiDefault Component.arc int
|
* @uiDefault Component.arc int
|
||||||
* @uiDefault Component.arrowType String triangle (default) or chevron
|
* @uiDefault Component.arrowType String triangle (default) or chevron
|
||||||
|
* @uiDefault Component.isIntelliJTheme boolean
|
||||||
* @uiDefault Component.borderColor Color
|
* @uiDefault Component.borderColor Color
|
||||||
* @uiDefault Component.disabledBorderColor Color
|
* @uiDefault Component.disabledBorderColor Color
|
||||||
|
* @uiDefault ComboBox.editableBackground Color optional; defaults to ComboBox.background
|
||||||
* @uiDefault ComboBox.disabledBackground Color
|
* @uiDefault ComboBox.disabledBackground Color
|
||||||
* @uiDefault ComboBox.disabledForeground Color
|
* @uiDefault ComboBox.disabledForeground Color
|
||||||
* @uiDefault ComboBox.buttonBackground Color
|
* @uiDefault ComboBox.buttonBackground Color
|
||||||
@@ -79,9 +99,11 @@ public class FlatComboBoxUI
|
|||||||
protected int focusWidth;
|
protected int focusWidth;
|
||||||
protected int arc;
|
protected int arc;
|
||||||
protected String arrowType;
|
protected String arrowType;
|
||||||
|
protected boolean isIntelliJTheme;
|
||||||
protected Color borderColor;
|
protected Color borderColor;
|
||||||
protected Color disabledBorderColor;
|
protected Color disabledBorderColor;
|
||||||
|
|
||||||
|
protected Color editableBackground;
|
||||||
protected Color disabledBackground;
|
protected Color disabledBackground;
|
||||||
protected Color disabledForeground;
|
protected Color disabledForeground;
|
||||||
|
|
||||||
@@ -94,6 +116,8 @@ public class FlatComboBoxUI
|
|||||||
private MouseListener hoverListener;
|
private MouseListener hoverListener;
|
||||||
private boolean hover;
|
private boolean hover;
|
||||||
|
|
||||||
|
private WeakReference<Component> lastRendererComponent;
|
||||||
|
|
||||||
public static ComponentUI createUI( JComponent c ) {
|
public static ComponentUI createUI( JComponent c ) {
|
||||||
return new FlatComboBoxUI();
|
return new FlatComboBoxUI();
|
||||||
}
|
}
|
||||||
@@ -129,9 +153,11 @@ public class FlatComboBoxUI
|
|||||||
focusWidth = UIManager.getInt( "Component.focusWidth" );
|
focusWidth = UIManager.getInt( "Component.focusWidth" );
|
||||||
arc = UIManager.getInt( "Component.arc" );
|
arc = UIManager.getInt( "Component.arc" );
|
||||||
arrowType = UIManager.getString( "Component.arrowType" );
|
arrowType = UIManager.getString( "Component.arrowType" );
|
||||||
|
isIntelliJTheme = UIManager.getBoolean( "Component.isIntelliJTheme" );
|
||||||
borderColor = UIManager.getColor( "Component.borderColor" );
|
borderColor = UIManager.getColor( "Component.borderColor" );
|
||||||
disabledBorderColor = UIManager.getColor( "Component.disabledBorderColor" );
|
disabledBorderColor = UIManager.getColor( "Component.disabledBorderColor" );
|
||||||
|
|
||||||
|
editableBackground = UIManager.getColor( "ComboBox.editableBackground" );
|
||||||
disabledBackground = UIManager.getColor( "ComboBox.disabledBackground" );
|
disabledBackground = UIManager.getColor( "ComboBox.disabledBackground" );
|
||||||
disabledForeground = UIManager.getColor( "ComboBox.disabledForeground" );
|
disabledForeground = UIManager.getColor( "ComboBox.disabledForeground" );
|
||||||
|
|
||||||
@@ -154,6 +180,7 @@ public class FlatComboBoxUI
|
|||||||
borderColor = null;
|
borderColor = null;
|
||||||
disabledBorderColor = null;
|
disabledBorderColor = null;
|
||||||
|
|
||||||
|
editableBackground = null;
|
||||||
disabledBackground = null;
|
disabledBackground = null;
|
||||||
disabledForeground = null;
|
disabledForeground = null;
|
||||||
|
|
||||||
@@ -220,7 +247,8 @@ public class FlatComboBoxUI
|
|||||||
} else if( editor != null && source == comboBox && propertyName == "componentOrientation" ) {
|
} else if( editor != null && source == comboBox && propertyName == "componentOrientation" ) {
|
||||||
ComponentOrientation o = (ComponentOrientation) e.getNewValue();
|
ComponentOrientation o = (ComponentOrientation) e.getNewValue();
|
||||||
editor.applyComponentOrientation( o );
|
editor.applyComponentOrientation( o );
|
||||||
}
|
} else if( editor != null && FlatClientProperties.PLACEHOLDER_TEXT.equals( propertyName ) )
|
||||||
|
editor.repaint();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -249,6 +277,18 @@ public class FlatComboBoxUI
|
|||||||
editor.applyComponentOrientation( comboBox.getComponentOrientation() );
|
editor.applyComponentOrientation( comboBox.getComponentOrientation() );
|
||||||
|
|
||||||
updateEditorColors();
|
updateEditorColors();
|
||||||
|
|
||||||
|
// macOS
|
||||||
|
if( SystemInfo.IS_MAC && editor instanceof JTextComponent ) {
|
||||||
|
// delegate actions from editor text field to combobox, which is necessary
|
||||||
|
// because text field on macOS (based on Aqua LaF UI defaults)
|
||||||
|
// already handle those keys
|
||||||
|
InputMap inputMap = ((JTextComponent)editor).getInputMap();
|
||||||
|
new EditorDelegateAction( inputMap, KeyStroke.getKeyStroke( "UP" ) );
|
||||||
|
new EditorDelegateAction( inputMap, KeyStroke.getKeyStroke( "KP_UP" ) );
|
||||||
|
new EditorDelegateAction( inputMap, KeyStroke.getKeyStroke( "DOWN" ) );
|
||||||
|
new EditorDelegateAction( inputMap, KeyStroke.getKeyStroke( "KP_DOWN" ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateEditorColors() {
|
private void updateEditorColors() {
|
||||||
@@ -294,8 +334,10 @@ public class FlatComboBoxUI
|
|||||||
boolean isLeftToRight = comboBox.getComponentOrientation().isLeftToRight();
|
boolean isLeftToRight = comboBox.getComponentOrientation().isLeftToRight();
|
||||||
|
|
||||||
// paint background
|
// paint background
|
||||||
g2.setColor( enabled ? c.getBackground() : disabledBackground );
|
g2.setColor( enabled
|
||||||
FlatUIUtils.fillRoundRectangle( g2, 0, 0, width, height, focusWidth, arc );
|
? (editableBackground != null && comboBox.isEditable() ? editableBackground : c.getBackground())
|
||||||
|
: getDisabledBackground( comboBox ) );
|
||||||
|
FlatUIUtils.paintComponentBackground( g2, 0, 0, width, height, focusWidth, arc );
|
||||||
|
|
||||||
// paint arrow button background
|
// paint arrow button background
|
||||||
if( enabled ) {
|
if( enabled ) {
|
||||||
@@ -305,7 +347,7 @@ public class FlatComboBoxUI
|
|||||||
g2.clipRect( arrowX, 0, width - arrowX, height );
|
g2.clipRect( arrowX, 0, width - arrowX, height );
|
||||||
else
|
else
|
||||||
g2.clipRect( 0, 0, arrowX + arrowWidth, height );
|
g2.clipRect( 0, 0, arrowX + arrowWidth, height );
|
||||||
FlatUIUtils.fillRoundRectangle( g2, 0, 0, width, height, focusWidth, arc );
|
FlatUIUtils.paintComponentBackground( g2, 0, 0, width, height, focusWidth, arc );
|
||||||
g2.setClip( oldClip );
|
g2.setClip( oldClip );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -314,7 +356,7 @@ public class FlatComboBoxUI
|
|||||||
g2.setColor( enabled ? borderColor : disabledBorderColor );
|
g2.setColor( enabled ? borderColor : disabledBorderColor );
|
||||||
float lw = scale( 1f );
|
float lw = scale( 1f );
|
||||||
float lx = isLeftToRight ? arrowX : arrowX + arrowWidth - lw;
|
float lx = isLeftToRight ? arrowX : arrowX + arrowWidth - lw;
|
||||||
g2.fill( new Rectangle2D.Float( lx, focusWidth, lw, height - (focusWidth * 2) ) );
|
g2.fill( new Rectangle2D.Float( lx, focusWidth, lw, height - 1 - (focusWidth * 2)) );
|
||||||
}
|
}
|
||||||
|
|
||||||
paint( g, c );
|
paint( g, c );
|
||||||
@@ -324,15 +366,17 @@ public class FlatComboBoxUI
|
|||||||
@SuppressWarnings( "unchecked" )
|
@SuppressWarnings( "unchecked" )
|
||||||
public void paintCurrentValue( Graphics g, Rectangle bounds, boolean hasFocus ) {
|
public void paintCurrentValue( Graphics g, Rectangle bounds, boolean hasFocus ) {
|
||||||
ListCellRenderer<Object> renderer = comboBox.getRenderer();
|
ListCellRenderer<Object> renderer = comboBox.getRenderer();
|
||||||
CellPaddingBorder.uninstall( renderer );
|
uninstallCellPaddingBorder( renderer );
|
||||||
|
if( renderer == null )
|
||||||
|
renderer = new DefaultListCellRenderer();
|
||||||
Component c = renderer.getListCellRendererComponent( listBox, comboBox.getSelectedItem(), -1, false, false );
|
Component c = renderer.getListCellRendererComponent( listBox, comboBox.getSelectedItem(), -1, false, false );
|
||||||
c.setFont( comboBox.getFont() );
|
c.setFont( comboBox.getFont() );
|
||||||
c.applyComponentOrientation( comboBox.getComponentOrientation() );
|
c.applyComponentOrientation( comboBox.getComponentOrientation() );
|
||||||
CellPaddingBorder.uninstall( c );
|
uninstallCellPaddingBorder( c );
|
||||||
|
|
||||||
boolean enabled = comboBox.isEnabled();
|
boolean enabled = comboBox.isEnabled();
|
||||||
c.setForeground( enabled ? comboBox.getForeground() : disabledForeground );
|
c.setForeground( enabled ? comboBox.getForeground() : disabledForeground );
|
||||||
c.setBackground( enabled ? comboBox.getBackground() : disabledBackground );
|
c.setBackground( enabled ? comboBox.getBackground() : getDisabledBackground( comboBox ) );
|
||||||
|
|
||||||
boolean shouldValidate = (c instanceof JPanel);
|
boolean shouldValidate = (c instanceof JPanel);
|
||||||
if( padding != null )
|
if( padding != null )
|
||||||
@@ -349,10 +393,38 @@ public class FlatComboBoxUI
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void paintCurrentValueBackground( Graphics g, Rectangle bounds, boolean hasFocus ) {
|
public void paintCurrentValueBackground( Graphics g, Rectangle bounds, boolean hasFocus ) {
|
||||||
g.setColor( comboBox.isEnabled() ? comboBox.getBackground() : disabledBackground );
|
g.setColor( comboBox.isEnabled() ? comboBox.getBackground() : getDisabledBackground( comboBox ) );
|
||||||
g.fillRect( bounds.x, bounds.y, bounds.width, bounds.height );
|
g.fillRect( bounds.x, bounds.y, bounds.width, bounds.height );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Color getDisabledBackground( JComponent c ) {
|
||||||
|
return isIntelliJTheme ? FlatUIUtils.getParentBackground( c ) : disabledBackground;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Dimension getDefaultSize() {
|
||||||
|
@SuppressWarnings( "unchecked" )
|
||||||
|
ListCellRenderer<Object> renderer = comboBox.getRenderer();
|
||||||
|
uninstallCellPaddingBorder( renderer );
|
||||||
|
|
||||||
|
Dimension size = super.getDefaultSize();
|
||||||
|
|
||||||
|
uninstallCellPaddingBorder( renderer );
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Dimension getDisplaySize() {
|
||||||
|
@SuppressWarnings( "unchecked" )
|
||||||
|
ListCellRenderer<Object> renderer = comboBox.getRenderer();
|
||||||
|
uninstallCellPaddingBorder( renderer );
|
||||||
|
|
||||||
|
Dimension displaySize = super.getDisplaySize();
|
||||||
|
|
||||||
|
uninstallCellPaddingBorder( renderer );
|
||||||
|
return displaySize;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Dimension getSizeForComponent( Component comp ) {
|
protected Dimension getSizeForComponent( Component comp ) {
|
||||||
Dimension size = super.getSizeForComponent( comp );
|
Dimension size = super.getSizeForComponent( comp );
|
||||||
@@ -376,6 +448,14 @@ public class FlatComboBoxUI
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void uninstallCellPaddingBorder( Object o ) {
|
||||||
|
CellPaddingBorder.uninstall( o );
|
||||||
|
if( lastRendererComponent != null ) {
|
||||||
|
CellPaddingBorder.uninstall( lastRendererComponent );
|
||||||
|
lastRendererComponent = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//---- class FlatComboPopup -----------------------------------------------
|
//---- class FlatComboPopup -----------------------------------------------
|
||||||
|
|
||||||
@SuppressWarnings( { "rawtypes", "unchecked" } )
|
@SuppressWarnings( { "rawtypes", "unchecked" } )
|
||||||
@@ -459,7 +539,10 @@ public class FlatComboBoxUI
|
|||||||
{
|
{
|
||||||
ListCellRenderer renderer = comboBox.getRenderer();
|
ListCellRenderer renderer = comboBox.getRenderer();
|
||||||
CellPaddingBorder.uninstall( renderer );
|
CellPaddingBorder.uninstall( renderer );
|
||||||
|
CellPaddingBorder.uninstall( lastRendererComponent );
|
||||||
|
|
||||||
|
if( renderer == null )
|
||||||
|
renderer = new DefaultListCellRenderer();
|
||||||
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() );
|
||||||
|
|
||||||
@@ -469,6 +552,8 @@ public class FlatComboBoxUI
|
|||||||
paddingBorder.install( (JComponent) c );
|
paddingBorder.install( (JComponent) c );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lastRendererComponent = (c != renderer) ? new WeakReference<>( c ) : null;
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -503,6 +588,9 @@ public class FlatComboBoxUI
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void uninstall( Object o ) {
|
static void uninstall( Object o ) {
|
||||||
|
if( o instanceof WeakReference )
|
||||||
|
o = ((WeakReference<?>)o).get();
|
||||||
|
|
||||||
if( !(o instanceof JComponent) )
|
if( !(o instanceof JComponent) )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -538,4 +626,31 @@ public class FlatComboBoxUI
|
|||||||
rendererBorder.paintBorder( c, g, x, y, width, height );
|
rendererBorder.paintBorder( c, g, x, y, width, height );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---- class EditorDelegateAction -----------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delegates actions from editor text field to combobox.
|
||||||
|
*/
|
||||||
|
private class EditorDelegateAction
|
||||||
|
extends AbstractAction
|
||||||
|
{
|
||||||
|
private final KeyStroke keyStroke;
|
||||||
|
|
||||||
|
EditorDelegateAction( InputMap inputMap, KeyStroke keyStroke ) {
|
||||||
|
this.keyStroke = keyStroke;
|
||||||
|
|
||||||
|
// add to input map
|
||||||
|
inputMap.put( keyStroke, this );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed( ActionEvent e ) {
|
||||||
|
ActionListener action = comboBox.getActionForKeyStroke( keyStroke );
|
||||||
|
if( action != null ) {
|
||||||
|
action.actionPerformed( new ActionEvent( comboBox, e.getID(),
|
||||||
|
e.getActionCommand(), e.getWhen(), e.getModifiers() ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,18 +18,37 @@ package com.formdev.flatlaf.ui;
|
|||||||
|
|
||||||
import static com.formdev.flatlaf.util.UIScale.scale;
|
import static com.formdev.flatlaf.util.UIScale.scale;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Graphics;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
import javax.swing.JEditorPane;
|
import javax.swing.JEditorPane;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
|
import javax.swing.plaf.UIResource;
|
||||||
import javax.swing.plaf.basic.BasicEditorPaneUI;
|
import javax.swing.plaf.basic.BasicEditorPaneUI;
|
||||||
|
import javax.swing.text.JTextComponent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JEditorPane}.
|
* Provides the Flat LaF UI delegate for {@link javax.swing.JEditorPane}.
|
||||||
*
|
*
|
||||||
* TODO document used UI defaults of superclass
|
* <!-- BasicEditorPaneUI -->
|
||||||
|
*
|
||||||
|
* @uiDefault EditorPane.font Font
|
||||||
|
* @uiDefault EditorPane.background Color also used if not editable
|
||||||
|
* @uiDefault EditorPane.foreground Color
|
||||||
|
* @uiDefault EditorPane.caretForeground Color
|
||||||
|
* @uiDefault EditorPane.selectionBackground Color
|
||||||
|
* @uiDefault EditorPane.selectionForeground Color
|
||||||
|
* @uiDefault EditorPane.disabledBackground Color used if not enabled
|
||||||
|
* @uiDefault EditorPane.inactiveBackground Color used if not editable
|
||||||
|
* @uiDefault EditorPane.inactiveForeground Color used if not enabled (yes, this is confusing; this should be named disabledForeground)
|
||||||
|
* @uiDefault EditorPane.border Border
|
||||||
|
* @uiDefault EditorPane.margin Insets
|
||||||
|
* @uiDefault EditorPane.caretBlinkRate int default is 500 milliseconds
|
||||||
|
*
|
||||||
|
* <!-- FlatEditorPaneUI -->
|
||||||
*
|
*
|
||||||
* @uiDefault Component.minimumWidth int
|
* @uiDefault Component.minimumWidth int
|
||||||
|
* @uiDefault Component.isIntelliJTheme boolean
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
@@ -37,6 +56,7 @@ public class FlatEditorPaneUI
|
|||||||
extends BasicEditorPaneUI
|
extends BasicEditorPaneUI
|
||||||
{
|
{
|
||||||
protected int minimumWidth;
|
protected int minimumWidth;
|
||||||
|
protected boolean isIntelliJTheme;
|
||||||
|
|
||||||
private Object oldHonorDisplayProperties;
|
private Object oldHonorDisplayProperties;
|
||||||
|
|
||||||
@@ -49,6 +69,7 @@ public class FlatEditorPaneUI
|
|||||||
super.installDefaults();
|
super.installDefaults();
|
||||||
|
|
||||||
minimumWidth = UIManager.getInt( "Component.minimumWidth" );
|
minimumWidth = UIManager.getInt( "Component.minimumWidth" );
|
||||||
|
isIntelliJTheme = UIManager.getBoolean( "Component.isIntelliJTheme" );
|
||||||
|
|
||||||
// use component font and foreground for HTML text
|
// use component font and foreground for HTML text
|
||||||
oldHonorDisplayProperties = getComponent().getClientProperty( JEditorPane.HONOR_DISPLAY_PROPERTIES );
|
oldHonorDisplayProperties = getComponent().getClientProperty( JEditorPane.HONOR_DISPLAY_PROPERTIES );
|
||||||
@@ -77,7 +98,21 @@ public class FlatEditorPaneUI
|
|||||||
// and subtract 1px border line width.
|
// and subtract 1px border line width.
|
||||||
// Using "(scale( 1 ) * 2)" instead of "scale( 2 )" to deal with rounding
|
// Using "(scale( 1 ) * 2)" instead of "scale( 2 )" to deal with rounding
|
||||||
// issues. E.g. at scale factor 1.5 the first returns 4, but the second 3.
|
// issues. E.g. at scale factor 1.5 the first returns 4, but the second 3.
|
||||||
|
int minimumWidth = FlatUIUtils.minimumWidth( getComponent(), this.minimumWidth );
|
||||||
size.width = Math.max( size.width, scale( minimumWidth ) - (scale( 1 ) * 2) );
|
size.width = Math.max( size.width, scale( minimumWidth ) - (scale( 1 ) * 2) );
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void paintBackground( Graphics g ) {
|
||||||
|
JTextComponent c = getComponent();
|
||||||
|
|
||||||
|
// for compatibility with IntelliJ themes
|
||||||
|
if( isIntelliJTheme && (!c.isEnabled() || !c.isEditable()) && (c.getBackground() instanceof UIResource) ) {
|
||||||
|
FlatUIUtils.paintParentBackground( g, c );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
super.paintBackground( g );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,122 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 FormDev Software GmbH
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.formdev.flatlaf.ui;
|
||||||
|
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import javax.swing.JComponent;
|
||||||
|
import javax.swing.JFileChooser;
|
||||||
|
import javax.swing.plaf.ComponentUI;
|
||||||
|
import javax.swing.plaf.metal.MetalFileChooserUI;
|
||||||
|
import com.formdev.flatlaf.util.UIScale;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides the Flat LaF UI delegate for {@link javax.swing.JFileChooser}.
|
||||||
|
*
|
||||||
|
* <!-- BasicFileChooserUI -->
|
||||||
|
*
|
||||||
|
* @uiDefault FileView.directoryIcon Icon
|
||||||
|
* @uiDefault FileView.fileIcon Icon
|
||||||
|
* @uiDefault FileView.computerIcon Icon
|
||||||
|
* @uiDefault FileView.hardDriveIcon Icon
|
||||||
|
* @uiDefault FileView.floppyDriveIcon Icon
|
||||||
|
*
|
||||||
|
* @uiDefault FileChooser.newFolderIcon Icon
|
||||||
|
* @uiDefault FileChooser.upFolderIcon Icon
|
||||||
|
* @uiDefault FileChooser.homeFolderIcon Icon
|
||||||
|
* @uiDefault FileChooser.detailsViewIcon Icon
|
||||||
|
* @uiDefault FileChooser.listViewIcon Icon
|
||||||
|
* @uiDefault FileChooser.viewMenuIcon Icon
|
||||||
|
*
|
||||||
|
* @uiDefault FileChooser.usesSingleFilePane boolean
|
||||||
|
* @uiDefault FileChooser.readOnly boolean if true, "New Folder" is disabled
|
||||||
|
*
|
||||||
|
* @uiDefault FileChooser.newFolderErrorText String
|
||||||
|
* @uiDefault FileChooser.newFolderErrorSeparator String
|
||||||
|
* @uiDefault FileChooser.newFolderParentDoesntExistTitleText String
|
||||||
|
* @uiDefault FileChooser.newFolderParentDoesntExistText String
|
||||||
|
* @uiDefault FileChooser.fileDescriptionText String
|
||||||
|
* @uiDefault FileChooser.directoryDescriptionText String
|
||||||
|
* @uiDefault FileChooser.saveButtonText String
|
||||||
|
* @uiDefault FileChooser.openButtonText String
|
||||||
|
* @uiDefault FileChooser.saveDialogTitleText String
|
||||||
|
* @uiDefault FileChooser.openDialogTitleText String
|
||||||
|
* @uiDefault FileChooser.cancelButtonText String
|
||||||
|
* @uiDefault FileChooser.updateButtonText String
|
||||||
|
* @uiDefault FileChooser.helpButtonText String
|
||||||
|
* @uiDefault FileChooser.directoryOpenButtonText String
|
||||||
|
*
|
||||||
|
* @uiDefault FileChooser.saveButtonMnemonic String
|
||||||
|
* @uiDefault FileChooser.openButtonMnemonic String
|
||||||
|
* @uiDefault FileChooser.cancelButtonMnemonic String
|
||||||
|
* @uiDefault FileChooser.updateButtonMnemonic String
|
||||||
|
* @uiDefault FileChooser.helpButtonMnemonic String
|
||||||
|
* @uiDefault FileChooser.directoryOpenButtonMnemonic String
|
||||||
|
*
|
||||||
|
* @uiDefault FileChooser.saveButtonToolTipText String
|
||||||
|
* @uiDefault FileChooser.openButtonToolTipText String
|
||||||
|
* @uiDefault FileChooser.cancelButtonToolTipText String
|
||||||
|
* @uiDefault FileChooser.updateButtonToolTipText String
|
||||||
|
* @uiDefault FileChooser.helpButtonToolTipText String
|
||||||
|
* @uiDefault FileChooser.directoryOpenButtonToolTipText String
|
||||||
|
*
|
||||||
|
* @uiDefault FileChooser.acceptAllFileFilterText String
|
||||||
|
*
|
||||||
|
* <!-- MetalFileChooserUI -->
|
||||||
|
*
|
||||||
|
* @uiDefault FileChooser.lookInLabelMnemonic String
|
||||||
|
* @uiDefault FileChooser.lookInLabelText String
|
||||||
|
* @uiDefault FileChooser.saveInLabelText String
|
||||||
|
* @uiDefault FileChooser.fileNameLabelMnemonic String
|
||||||
|
* @uiDefault FileChooser.fileNameLabelText String
|
||||||
|
* @uiDefault FileChooser.folderNameLabelMnemonic String
|
||||||
|
* @uiDefault FileChooser.folderNameLabelText String
|
||||||
|
* @uiDefault FileChooser.filesOfTypeLabelMnemonic String
|
||||||
|
* @uiDefault FileChooser.filesOfTypeLabelText String
|
||||||
|
* @uiDefault FileChooser.upFolderToolTipText String
|
||||||
|
* @uiDefault FileChooser.upFolderAccessibleName String
|
||||||
|
* @uiDefault FileChooser.homeFolderToolTipText String
|
||||||
|
* @uiDefault FileChooser.homeFolderAccessibleName String
|
||||||
|
* @uiDefault FileChooser.newFolderToolTipText String
|
||||||
|
* @uiDefault FileChooser.newFolderAccessibleName String
|
||||||
|
* @uiDefault FileChooser.listViewButtonToolTipText String
|
||||||
|
* @uiDefault FileChooser.listViewButtonAccessibleName String
|
||||||
|
* @uiDefault FileChooser.detailsViewButtonToolTipText String
|
||||||
|
* @uiDefault FileChooser.detailsViewButtonAccessibleName String
|
||||||
|
*
|
||||||
|
* @author Karl Tauber
|
||||||
|
*/
|
||||||
|
public class FlatFileChooserUI
|
||||||
|
extends MetalFileChooserUI
|
||||||
|
{
|
||||||
|
public static ComponentUI createUI( JComponent c ) {
|
||||||
|
return new FlatFileChooserUI( (JFileChooser) c );
|
||||||
|
}
|
||||||
|
|
||||||
|
public FlatFileChooserUI( JFileChooser filechooser ) {
|
||||||
|
super( filechooser );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dimension getPreferredSize( JComponent c ) {
|
||||||
|
return UIScale.scale( super.getPreferredSize( c ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dimension getMinimumSize( JComponent c ) {
|
||||||
|
return UIScale.scale( super.getMinimumSize( c ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,6 +22,28 @@ import javax.swing.plaf.ComponentUI;
|
|||||||
/**
|
/**
|
||||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JFormattedTextField}.
|
* Provides the Flat LaF UI delegate for {@link javax.swing.JFormattedTextField}.
|
||||||
*
|
*
|
||||||
|
* <!-- BasicTextFieldUI -->
|
||||||
|
*
|
||||||
|
* @uiDefault FormattedTextField.font Font
|
||||||
|
* @uiDefault FormattedTextField.background Color
|
||||||
|
* @uiDefault FormattedTextField.foreground Color also used if not editable
|
||||||
|
* @uiDefault FormattedTextField.caretForeground Color
|
||||||
|
* @uiDefault FormattedTextField.selectionBackground Color
|
||||||
|
* @uiDefault FormattedTextField.selectionForeground Color
|
||||||
|
* @uiDefault FormattedTextField.disabledBackground Color used if not enabled
|
||||||
|
* @uiDefault FormattedTextField.inactiveBackground Color used if not editable
|
||||||
|
* @uiDefault FormattedTextField.inactiveForeground Color used if not enabled (yes, this is confusing; this should be named disabledForeground)
|
||||||
|
* @uiDefault FormattedTextField.border Border
|
||||||
|
* @uiDefault FormattedTextField.margin Insets
|
||||||
|
* @uiDefault FormattedTextField.caretBlinkRate int default is 500 milliseconds
|
||||||
|
*
|
||||||
|
* <!-- FlatTextFieldUI -->
|
||||||
|
*
|
||||||
|
* @uiDefault Component.focusWidth int
|
||||||
|
* @uiDefault Component.minimumWidth int
|
||||||
|
* @uiDefault Component.isIntelliJTheme boolean
|
||||||
|
* @uiDefault FormattedTextField.placeholderForeground Color
|
||||||
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
public class FlatFormattedTextFieldUI
|
public class FlatFormattedTextFieldUI
|
||||||
|
|||||||
@@ -20,12 +20,14 @@ import java.awt.Color;
|
|||||||
import java.awt.FontMetrics;
|
import java.awt.FontMetrics;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.awt.Rectangle;
|
import java.awt.Rectangle;
|
||||||
|
import java.beans.PropertyChangeEvent;
|
||||||
import javax.swing.Icon;
|
import javax.swing.Icon;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
import javax.swing.JLabel;
|
import javax.swing.JLabel;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
|
import javax.swing.plaf.basic.BasicHTML;
|
||||||
import javax.swing.plaf.basic.BasicLabelUI;
|
import javax.swing.plaf.basic.BasicLabelUI;
|
||||||
import com.formdev.flatlaf.FlatLaf;
|
import com.formdev.flatlaf.FlatLaf;
|
||||||
import com.formdev.flatlaf.util.UIScale;
|
import com.formdev.flatlaf.util.UIScale;
|
||||||
@@ -33,10 +35,15 @@ import com.formdev.flatlaf.util.UIScale;
|
|||||||
/**
|
/**
|
||||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JLabel}.
|
* Provides the Flat LaF UI delegate for {@link javax.swing.JLabel}.
|
||||||
*
|
*
|
||||||
|
* <!-- BasicLabelUI -->
|
||||||
|
*
|
||||||
|
* @uiDefault Label.font Font
|
||||||
* @uiDefault Label.background Color only used if opaque
|
* @uiDefault Label.background Color only used if opaque
|
||||||
* @uiDefault Label.foreground Color
|
* @uiDefault Label.foreground Color
|
||||||
|
*
|
||||||
|
* <!-- FlatLabelUI -->
|
||||||
|
*
|
||||||
* @uiDefault Label.disabledForeground Color
|
* @uiDefault Label.disabledForeground Color
|
||||||
* @uiDefault Label.font Font
|
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
@@ -72,6 +79,51 @@ public class FlatLabelUI
|
|||||||
defaults_initialized = false;
|
defaults_initialized = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void installComponents( JLabel c ) {
|
||||||
|
super.installComponents( c );
|
||||||
|
|
||||||
|
// update HTML renderer if necessary
|
||||||
|
updateHTMLRenderer( c, c.getText(), false );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void propertyChange( PropertyChangeEvent e ) {
|
||||||
|
String name = e.getPropertyName();
|
||||||
|
if( name == "text" || name == "font" || name == "foreground" ) {
|
||||||
|
JLabel label = (JLabel) e.getSource();
|
||||||
|
updateHTMLRenderer( label, label.getText(), true );
|
||||||
|
} else
|
||||||
|
super.propertyChange( e );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether text contains HTML headings and adds a special CSS rule to
|
||||||
|
* re-calculate heading font sizes based on current component font size.
|
||||||
|
*/
|
||||||
|
static void updateHTMLRenderer( JComponent c, String text, boolean always ) {
|
||||||
|
if( BasicHTML.isHTMLString( text ) &&
|
||||||
|
c.getClientProperty( "html.disable" ) != Boolean.TRUE &&
|
||||||
|
text.contains( "<h" ) &&
|
||||||
|
(text.contains( "<h1" ) || text.contains( "<h2" ) || text.contains( "<h3" ) ||
|
||||||
|
text.contains( "<h4" ) || text.contains( "<h5" ) || text.contains( "<h6" )) )
|
||||||
|
{
|
||||||
|
int headIndex = text.indexOf( "<head>" );
|
||||||
|
|
||||||
|
String style = "<style>BASE_SIZE " + c.getFont().getSize() + "</style>";
|
||||||
|
if( headIndex < 0 )
|
||||||
|
style = "<head>" + style + "</head>";
|
||||||
|
|
||||||
|
int insertIndex = headIndex >= 0 ? (headIndex + "<head>".length()) : "<html>".length();
|
||||||
|
text = text.substring( 0, insertIndex )
|
||||||
|
+ style
|
||||||
|
+ text.substring( insertIndex );
|
||||||
|
} else if( !always )
|
||||||
|
return; // not necessary to invoke BasicHTML.updateRenderer()
|
||||||
|
|
||||||
|
BasicHTML.updateRenderer( c, text );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void paintEnabledText( JLabel l, Graphics g, String s, int textX, int textY ) {
|
protected void paintEnabledText( JLabel l, Graphics g, String s, int textX, int textY ) {
|
||||||
int mnemIndex = FlatLaf.isShowMnemonics() ? l.getDisplayedMnemonicIndex() : -1;
|
int mnemIndex = FlatLaf.isShowMnemonics() ? l.getDisplayedMnemonicIndex() : -1;
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ public class FlatLineBorder
|
|||||||
try {
|
try {
|
||||||
FlatUIUtils.setRenderingHints( g2 );
|
FlatUIUtils.setRenderingHints( g2 );
|
||||||
g2.setColor( lineColor );
|
g2.setColor( lineColor );
|
||||||
FlatUIUtils.drawRoundRectangle( g2, x, y, width, height, 0f, scale( 1f ), 0f );
|
FlatUIUtils.paintComponentBorder( g2, x, y, width, height, 0f, scale( 1f ), 0f );
|
||||||
} finally {
|
} finally {
|
||||||
g2.dispose();
|
g2.dispose();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,88 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 FormDev Software GmbH
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.formdev.flatlaf.ui;
|
||||||
|
|
||||||
|
import java.awt.Component;
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import javax.swing.JList;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
|
import javax.swing.UIManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cell border for {@link javax.swing.DefaultListCellRenderer}
|
||||||
|
* (used by {@link javax.swing.JList}).
|
||||||
|
* <p>
|
||||||
|
* Uses separate cell margins from UI defaults to allow easy customizing.
|
||||||
|
*
|
||||||
|
* @author Karl Tauber
|
||||||
|
*/
|
||||||
|
public class FlatListCellBorder
|
||||||
|
extends FlatLineBorder
|
||||||
|
{
|
||||||
|
final boolean showCellFocusIndicator = UIManager.getBoolean( "List.showCellFocusIndicator" );
|
||||||
|
|
||||||
|
protected FlatListCellBorder() {
|
||||||
|
super( UIManager.getInsets( "List.cellMargins" ), UIManager.getColor( "List.cellFocusColor" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
//---- class Default ------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Border for unselected cell that uses margins, but does not paint focus indicator border.
|
||||||
|
*/
|
||||||
|
public static class Default
|
||||||
|
extends FlatListCellBorder
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
|
||||||
|
// do not paint focus indicator border
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//---- class Focused ------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Border for focused unselected cell that uses margins and paints focus indicator border.
|
||||||
|
*/
|
||||||
|
public static class Focused
|
||||||
|
extends FlatListCellBorder
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//---- class Selected -----------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Border for selected cell that uses margins and paints focus indicator border
|
||||||
|
* if enabled (List.showCellFocusIndicator=true) and exactly one item is selected.
|
||||||
|
*/
|
||||||
|
public static class Selected
|
||||||
|
extends FlatListCellBorder
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
|
||||||
|
if( !showCellFocusIndicator )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// paint focus indicator border only if exactly one item is selected
|
||||||
|
JList<?> list = (JList<?>) SwingUtilities.getAncestorOfClass( JList.class, c );
|
||||||
|
if( list != null && list.getMinSelectionIndex() == list.getMaxSelectionIndex() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
super.paintBorder( c, g, x, y, width, height );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -27,11 +27,37 @@ import javax.swing.plaf.basic.BasicListUI;
|
|||||||
/**
|
/**
|
||||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JList}.
|
* Provides the Flat LaF UI delegate for {@link javax.swing.JList}.
|
||||||
*
|
*
|
||||||
* TODO document used UI defaults of superclass
|
* <!-- BasicListUI -->
|
||||||
|
*
|
||||||
|
* @uiDefault List.font Font
|
||||||
|
* @uiDefault List.background Color
|
||||||
|
* @uiDefault List.foreground Color
|
||||||
|
* @uiDefault List.selectionBackground Color
|
||||||
|
* @uiDefault List.selectionForeground Color
|
||||||
|
* @uiDefault List.dropLineColor Color
|
||||||
|
* @uiDefault List.border Border
|
||||||
|
* @uiDefault List.cellRenderer ListCellRenderer
|
||||||
|
* @uiDefault FileChooser.listFont Font used if client property List.isFileList is true
|
||||||
|
*
|
||||||
|
* <!-- DefaultListCellRenderer -->
|
||||||
|
*
|
||||||
|
* @uiDefault List.cellNoFocusBorder Border
|
||||||
|
* @uiDefault List.focusCellHighlightBorder Border
|
||||||
|
* @uiDefault List.focusSelectedCellHighlightBorder Border
|
||||||
|
* @uiDefault List.dropCellBackground Color
|
||||||
|
* @uiDefault List.dropCellForeground Color
|
||||||
|
*
|
||||||
|
* <!-- FlatListUI -->
|
||||||
*
|
*
|
||||||
* @uiDefault List.selectionInactiveBackground Color
|
* @uiDefault List.selectionInactiveBackground Color
|
||||||
* @uiDefault List.selectionInactiveForeground Color
|
* @uiDefault List.selectionInactiveForeground Color
|
||||||
*
|
*
|
||||||
|
* <!-- FlatListCellBorder -->
|
||||||
|
*
|
||||||
|
* @uiDefault List.cellMargins Insets
|
||||||
|
* @uiDefault List.cellFocusColor Color
|
||||||
|
* @uiDefault List.showCellFocusIndicator boolean
|
||||||
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
public class FlatListUI
|
public class FlatListUI
|
||||||
|
|||||||
@@ -23,6 +23,13 @@ import javax.swing.plaf.basic.BasicMenuBarUI;
|
|||||||
/**
|
/**
|
||||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JMenuBar}.
|
* Provides the Flat LaF UI delegate for {@link javax.swing.JMenuBar}.
|
||||||
*
|
*
|
||||||
|
* <!-- BasicMenuBarUI -->
|
||||||
|
*
|
||||||
|
* @uiDefault MenuBar.font Font
|
||||||
|
* @uiDefault MenuBar.background Color
|
||||||
|
* @uiDefault MenuBar.foreground Color
|
||||||
|
* @uiDefault MenuBar.border Border
|
||||||
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
public class FlatMenuBarUI
|
public class FlatMenuBarUI
|
||||||
|
|||||||
@@ -17,14 +17,42 @@
|
|||||||
package com.formdev.flatlaf.ui;
|
package com.formdev.flatlaf.ui;
|
||||||
|
|
||||||
import static com.formdev.flatlaf.util.UIScale.scale;
|
import static com.formdev.flatlaf.util.UIScale.scale;
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.FontMetrics;
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import java.awt.Rectangle;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
|
import javax.swing.ButtonModel;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
|
import javax.swing.JMenu;
|
||||||
|
import javax.swing.JMenuItem;
|
||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
import javax.swing.plaf.basic.BasicMenuItemUI;
|
import javax.swing.plaf.basic.BasicMenuItemUI;
|
||||||
|
import com.formdev.flatlaf.FlatLaf;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JMenuItem}.
|
* Provides the Flat LaF UI delegate for {@link javax.swing.JMenuItem}.
|
||||||
*
|
*
|
||||||
|
* <!-- BasicMenuItemUI -->
|
||||||
|
*
|
||||||
|
* @uiDefault MenuItem.font Font
|
||||||
|
* @uiDefault MenuItem.background Color
|
||||||
|
* @uiDefault MenuItem.foreground Color
|
||||||
|
* @uiDefault MenuItem.disabledForeground Color
|
||||||
|
* @uiDefault MenuItem.selectionBackground Color
|
||||||
|
* @uiDefault MenuItem.selectionForeground Color
|
||||||
|
* @uiDefault MenuItem.acceleratorForeground Color
|
||||||
|
* @uiDefault MenuItem.acceleratorSelectionForeground Color
|
||||||
|
* @uiDefault MenuItem.acceleratorFont Font defaults to MenuItem.font
|
||||||
|
* @uiDefault MenuItem.acceleratorDelimiter String
|
||||||
|
* @uiDefault MenuItem.border Border
|
||||||
|
* @uiDefault MenuItem.borderPainted boolean
|
||||||
|
* @uiDefault MenuItem.margin Insets
|
||||||
|
* @uiDefault MenuItem.arrowIcon Icon
|
||||||
|
* @uiDefault MenuItem.checkIcon Icon
|
||||||
|
* @uiDefault MenuItem.opaque boolean
|
||||||
|
* @uiDefault MenuItem.evenHeight boolean
|
||||||
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
public class FlatMenuItemUI
|
public class FlatMenuItemUI
|
||||||
@@ -54,4 +82,26 @@ public class FlatMenuItemUI
|
|||||||
defaultTextIconGap = scale( defaultTextIconGap );
|
defaultTextIconGap = scale( defaultTextIconGap );
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void paintText( Graphics g, JMenuItem menuItem, Rectangle textRect, String text ) {
|
||||||
|
paintText( g, menuItem, textRect, text, disabledForeground, selectionForeground );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void paintText( Graphics g, JMenuItem menuItem, Rectangle textRect,
|
||||||
|
String text, Color disabledForeground, Color selectionForeground )
|
||||||
|
{
|
||||||
|
FontMetrics fm = menuItem.getFontMetrics( menuItem.getFont() );
|
||||||
|
int mnemonicIndex = FlatLaf.isShowMnemonics() ? menuItem.getDisplayedMnemonicIndex() : -1;
|
||||||
|
|
||||||
|
ButtonModel model = menuItem.getModel();
|
||||||
|
g.setColor( !model.isEnabled()
|
||||||
|
? disabledForeground
|
||||||
|
: (model.isArmed() || (menuItem instanceof JMenu && model.isSelected())
|
||||||
|
? selectionForeground
|
||||||
|
: menuItem.getForeground()) );
|
||||||
|
|
||||||
|
FlatUIUtils.drawStringUnderlineCharAt( menuItem, g, text, mnemonicIndex,
|
||||||
|
textRect.x, textRect.y + fm.getAscent() );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,14 +17,40 @@
|
|||||||
package com.formdev.flatlaf.ui;
|
package com.formdev.flatlaf.ui;
|
||||||
|
|
||||||
import static com.formdev.flatlaf.util.UIScale.scale;
|
import static com.formdev.flatlaf.util.UIScale.scale;
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import java.awt.Rectangle;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
|
import javax.swing.JMenuItem;
|
||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
import javax.swing.plaf.basic.BasicMenuUI;
|
import javax.swing.plaf.basic.BasicMenuUI;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JMenu}.
|
* Provides the Flat LaF UI delegate for {@link javax.swing.JMenu}.
|
||||||
*
|
*
|
||||||
|
* <!-- BasicMenuUI -->
|
||||||
|
*
|
||||||
|
* @uiDefault Menu.font Font
|
||||||
|
* @uiDefault Menu.background Color
|
||||||
|
* @uiDefault Menu.foreground Color
|
||||||
|
* @uiDefault Menu.disabledForeground Color
|
||||||
|
* @uiDefault Menu.selectionBackground Color
|
||||||
|
* @uiDefault Menu.selectionForeground Color
|
||||||
|
* @uiDefault Menu.acceleratorForeground Color
|
||||||
|
* @uiDefault Menu.acceleratorSelectionForeground Color
|
||||||
|
* @uiDefault MenuItem.acceleratorFont Font defaults to MenuItem.font
|
||||||
|
* @uiDefault MenuItem.acceleratorDelimiter String
|
||||||
|
* @uiDefault Menu.border Border
|
||||||
|
* @uiDefault Menu.borderPainted boolean
|
||||||
|
* @uiDefault Menu.margin Insets
|
||||||
|
* @uiDefault Menu.arrowIcon Icon
|
||||||
|
* @uiDefault Menu.checkIcon Icon
|
||||||
|
* @uiDefault Menu.opaque boolean
|
||||||
|
* @uiDefault Menu.evenHeight boolean
|
||||||
|
* @uiDefault Menu.crossMenuMnemonic boolean default is false
|
||||||
|
* @uiDefault Menu.useMenuBarBackgroundForTopLevel boolean default is false
|
||||||
|
* @uiDefault MenuBar.background Color used if Menu.useMenuBarBackgroundForTopLevel is true
|
||||||
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
public class FlatMenuUI
|
public class FlatMenuUI
|
||||||
@@ -54,4 +80,9 @@ public class FlatMenuUI
|
|||||||
defaultTextIconGap = scale( defaultTextIconGap );
|
defaultTextIconGap = scale( defaultTextIconGap );
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void paintText( Graphics g, JMenuItem menuItem, Rectangle textRect, String text ) {
|
||||||
|
FlatMenuItemUI.paintText( g, menuItem, textRect, text, disabledForeground, selectionForeground );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,10 +19,15 @@ package com.formdev.flatlaf.ui;
|
|||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Container;
|
import java.awt.Container;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Graphics;
|
||||||
import java.awt.GridBagConstraints;
|
import java.awt.GridBagConstraints;
|
||||||
|
import java.awt.Insets;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
|
import javax.swing.JPanel;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
|
import javax.swing.border.Border;
|
||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
|
import javax.swing.plaf.UIResource;
|
||||||
import javax.swing.plaf.basic.BasicHTML;
|
import javax.swing.plaf.basic.BasicHTML;
|
||||||
import javax.swing.plaf.basic.BasicOptionPaneUI;
|
import javax.swing.plaf.basic.BasicOptionPaneUI;
|
||||||
import com.formdev.flatlaf.util.UIScale;
|
import com.formdev.flatlaf.util.UIScale;
|
||||||
@@ -30,17 +35,19 @@ import com.formdev.flatlaf.util.UIScale;
|
|||||||
/**
|
/**
|
||||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JOptionPane}.
|
* Provides the Flat LaF UI delegate for {@link javax.swing.JOptionPane}.
|
||||||
*
|
*
|
||||||
|
* <!-- BasicOptionPaneUI -->
|
||||||
|
*
|
||||||
|
* @uiDefault OptionPane.font Font unused
|
||||||
|
* @uiDefault OptionPane.background Color
|
||||||
|
* @uiDefault OptionPane.foreground Color unused
|
||||||
* @uiDefault OptionPane.border Border
|
* @uiDefault OptionPane.border Border
|
||||||
* @uiDefault OptionPane.messageAreaBorder Border
|
* @uiDefault OptionPane.messageAreaBorder Border
|
||||||
* @uiDefault OptionPane.buttonAreaBorder Border
|
* @uiDefault OptionPane.buttonAreaBorder Border
|
||||||
* @uiDefault OptionPane.messageForeground Color
|
* @uiDefault OptionPane.messageForeground Color optional; defaults to Label.foreground
|
||||||
* @uiDefault OptionPane.messageFont Font
|
* @uiDefault OptionPane.messageFont Font optional; defaults to Label.font
|
||||||
* @uiDefault OptionPane.buttonFont Font
|
* @uiDefault OptionPane.buttonFont Font optional; defaults to Button.font
|
||||||
*
|
*
|
||||||
* @uiDefault OptionPane.minimumSize Dimension
|
* @uiDefault OptionPane.minimumSize Dimension
|
||||||
* @uiDefault OptionPane.maxCharactersPerLine int
|
|
||||||
* @uiDefault OptionPane.iconMessageGap int
|
|
||||||
* @uiDefault OptionPane.messagePadding int
|
|
||||||
* @uiDefault OptionPane.buttonPadding int
|
* @uiDefault OptionPane.buttonPadding int
|
||||||
* @uiDefault OptionPane.buttonMinimumWidth int -1=disabled
|
* @uiDefault OptionPane.buttonMinimumWidth int -1=disabled
|
||||||
* @uiDefault OptionPane.sameSizeButtons boolean if true, gives all buttons same size
|
* @uiDefault OptionPane.sameSizeButtons boolean if true, gives all buttons same size
|
||||||
@@ -53,6 +60,25 @@ import com.formdev.flatlaf.util.UIScale;
|
|||||||
* @uiDefault OptionPane.questionIcon Icon
|
* @uiDefault OptionPane.questionIcon Icon
|
||||||
* @uiDefault OptionPane.warningIcon Icon
|
* @uiDefault OptionPane.warningIcon Icon
|
||||||
*
|
*
|
||||||
|
* @uiDefault OptionPane.okButtonText String
|
||||||
|
* @uiDefault OptionPane.okButtonMnemonic String
|
||||||
|
* @uiDefault OptionPane.okIcon Icon
|
||||||
|
* @uiDefault OptionPane.cancelButtonText String
|
||||||
|
* @uiDefault OptionPane.cancelButtonMnemonic String
|
||||||
|
* @uiDefault OptionPane.cancelIcon Icon
|
||||||
|
* @uiDefault OptionPane.yesButtonText String
|
||||||
|
* @uiDefault OptionPane.yesButtonMnemonic String
|
||||||
|
* @uiDefault OptionPane.yesIcon Icon
|
||||||
|
* @uiDefault OptionPane.noButtonText String
|
||||||
|
* @uiDefault OptionPane.noButtonMnemonic String
|
||||||
|
* @uiDefault OptionPane.noIcon Icon
|
||||||
|
*
|
||||||
|
* <!-- FlatOptionPaneUI -->
|
||||||
|
*
|
||||||
|
* @uiDefault OptionPane.iconMessageGap int
|
||||||
|
* @uiDefault OptionPane.messagePadding int
|
||||||
|
* @uiDefault OptionPane.maxCharactersPerLine int
|
||||||
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
public class FlatOptionPaneUI
|
public class FlatOptionPaneUI
|
||||||
@@ -77,6 +103,13 @@ public class FlatOptionPaneUI
|
|||||||
focusWidth = UIManager.getInt( "Component.focusWidth" );
|
focusWidth = UIManager.getInt( "Component.focusWidth" );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void installComponents() {
|
||||||
|
super.installComponents();
|
||||||
|
|
||||||
|
updateChildPanels( optionPane );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Dimension getMinimumOptionPaneSize() {
|
public Dimension getMinimumOptionPaneSize() {
|
||||||
return UIScale.scale( super.getMinimumOptionPaneSize() );
|
return UIScale.scale( super.getMinimumOptionPaneSize() );
|
||||||
@@ -130,6 +163,26 @@ public class FlatOptionPaneUI
|
|||||||
super.addMessageComponents( container, cons, msg, maxll, internallyCreated );
|
super.addMessageComponents( container, cons, msg, maxll, internallyCreated );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateChildPanels( Container c ) {
|
||||||
|
for( Component child : c.getComponents() ) {
|
||||||
|
if( child instanceof JPanel ) {
|
||||||
|
JPanel panel = (JPanel)child;
|
||||||
|
|
||||||
|
// make sub-panel non-opaque for OptionPane.background
|
||||||
|
panel.setOpaque( false );
|
||||||
|
|
||||||
|
// use non-UIResource borders to avoid that they are replaced when switching LaF
|
||||||
|
Border border = panel.getBorder();
|
||||||
|
if( border instanceof UIResource )
|
||||||
|
panel.setBorder( new NonUIResourceBorder( border ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( child instanceof Container ) {
|
||||||
|
updateChildPanels( (Container) child );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Component findByName( Container c, String name ) {
|
private Component findByName( Container c, String name ) {
|
||||||
for( Component child : c.getComponents() ) {
|
for( Component child : c.getComponents() ) {
|
||||||
if( name.equals( child.getName() ) )
|
if( name.equals( child.getName() ) )
|
||||||
@@ -143,4 +196,31 @@ public class FlatOptionPaneUI
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//---- class NonUIResourceBorder ------------------------------------------
|
||||||
|
|
||||||
|
private static class NonUIResourceBorder
|
||||||
|
implements Border
|
||||||
|
{
|
||||||
|
private final Border delegate;
|
||||||
|
|
||||||
|
NonUIResourceBorder( Border delegate ) {
|
||||||
|
this.delegate = delegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
|
||||||
|
delegate.paintBorder( c, g, x, y, width, height );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Insets getBorderInsets( Component c ) {
|
||||||
|
return delegate.getBorderInsets( c );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isBorderOpaque() {
|
||||||
|
return delegate.isBorderOpaque();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,23 +17,44 @@
|
|||||||
package com.formdev.flatlaf.ui;
|
package com.formdev.flatlaf.ui;
|
||||||
|
|
||||||
import static com.formdev.flatlaf.util.UIScale.scale;
|
import static com.formdev.flatlaf.util.UIScale.scale;
|
||||||
|
import java.awt.Color;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.awt.event.FocusListener;
|
import java.awt.event.FocusListener;
|
||||||
|
import java.beans.PropertyChangeEvent;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
import javax.swing.LookAndFeel;
|
import javax.swing.LookAndFeel;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
import javax.swing.plaf.basic.BasicPasswordFieldUI;
|
import javax.swing.plaf.basic.BasicPasswordFieldUI;
|
||||||
|
import com.formdev.flatlaf.FlatClientProperties;
|
||||||
import com.formdev.flatlaf.util.SystemInfo;
|
import com.formdev.flatlaf.util.SystemInfo;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JPasswordField}.
|
* Provides the Flat LaF UI delegate for {@link javax.swing.JPasswordField}.
|
||||||
*
|
*
|
||||||
* TODO document used UI defaults of superclass
|
* <!-- BasicPasswordFieldUI -->
|
||||||
|
*
|
||||||
|
* @uiDefault PasswordField.font Font
|
||||||
|
* @uiDefault PasswordField.background Color
|
||||||
|
* @uiDefault PasswordField.foreground Color also used if not editable
|
||||||
|
* @uiDefault PasswordField.caretForeground Color
|
||||||
|
* @uiDefault PasswordField.selectionBackground Color
|
||||||
|
* @uiDefault PasswordField.selectionForeground Color
|
||||||
|
* @uiDefault PasswordField.disabledBackground Color used if not enabled
|
||||||
|
* @uiDefault PasswordField.inactiveBackground Color used if not editable
|
||||||
|
* @uiDefault PasswordField.inactiveForeground Color used if not enabled (yes, this is confusing; this should be named disabledForeground)
|
||||||
|
* @uiDefault PasswordField.border Border
|
||||||
|
* @uiDefault PasswordField.margin Insets
|
||||||
|
* @uiDefault PasswordField.echoChar character
|
||||||
|
* @uiDefault PasswordField.caretBlinkRate int default is 500 milliseconds
|
||||||
|
*
|
||||||
|
* <!-- FlatPasswordFieldUI -->
|
||||||
*
|
*
|
||||||
* @uiDefault Component.focusWidth int
|
* @uiDefault Component.focusWidth int
|
||||||
* @uiDefault Component.minimumWidth int
|
* @uiDefault Component.minimumWidth int
|
||||||
|
* @uiDefault Component.isIntelliJTheme boolean
|
||||||
|
* @uiDefault PasswordField.placeholderForeground Color
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
@@ -42,6 +63,8 @@ public class FlatPasswordFieldUI
|
|||||||
{
|
{
|
||||||
protected int focusWidth;
|
protected int focusWidth;
|
||||||
protected int minimumWidth;
|
protected int minimumWidth;
|
||||||
|
protected boolean isIntelliJTheme;
|
||||||
|
protected Color placeholderForeground;
|
||||||
|
|
||||||
private FocusListener focusListener;
|
private FocusListener focusListener;
|
||||||
|
|
||||||
@@ -57,8 +80,11 @@ public class FlatPasswordFieldUI
|
|||||||
if( SystemInfo.IS_MAC )
|
if( SystemInfo.IS_MAC )
|
||||||
LookAndFeel.installProperty( getComponent(), "echoChar", '\u2022' );
|
LookAndFeel.installProperty( getComponent(), "echoChar", '\u2022' );
|
||||||
|
|
||||||
|
String prefix = getPropertyPrefix();
|
||||||
focusWidth = UIManager.getInt( "Component.focusWidth" );
|
focusWidth = UIManager.getInt( "Component.focusWidth" );
|
||||||
minimumWidth = UIManager.getInt( "Component.minimumWidth" );
|
minimumWidth = UIManager.getInt( "Component.minimumWidth" );
|
||||||
|
isIntelliJTheme = UIManager.getBoolean( "Component.isIntelliJTheme" );
|
||||||
|
placeholderForeground = UIManager.getColor( prefix + ".placeholderForeground" );
|
||||||
|
|
||||||
LookAndFeel.installProperty( getComponent(), "opaque", focusWidth == 0 );
|
LookAndFeel.installProperty( getComponent(), "opaque", focusWidth == 0 );
|
||||||
|
|
||||||
@@ -69,6 +95,8 @@ public class FlatPasswordFieldUI
|
|||||||
protected void uninstallDefaults() {
|
protected void uninstallDefaults() {
|
||||||
super.uninstallDefaults();
|
super.uninstallDefaults();
|
||||||
|
|
||||||
|
placeholderForeground = null;
|
||||||
|
|
||||||
MigLayoutVisualPadding.uninstall( getComponent() );
|
MigLayoutVisualPadding.uninstall( getComponent() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,9 +116,18 @@ public class FlatPasswordFieldUI
|
|||||||
focusListener = null;
|
focusListener = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void propertyChange( PropertyChangeEvent e ) {
|
||||||
|
super.propertyChange( e );
|
||||||
|
|
||||||
|
if( FlatClientProperties.PLACEHOLDER_TEXT.equals( e.getPropertyName() ) )
|
||||||
|
getComponent().repaint();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void paintSafely( Graphics g ) {
|
protected void paintSafely( Graphics g ) {
|
||||||
FlatTextFieldUI.paintBackground( g, getComponent(), focusWidth );
|
FlatTextFieldUI.paintBackground( g, getComponent(), focusWidth, isIntelliJTheme );
|
||||||
|
FlatTextFieldUI.paintPlaceholder( g, getComponent(), placeholderForeground );
|
||||||
super.paintSafely( g );
|
super.paintSafely( g );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,6 +147,7 @@ public class FlatPasswordFieldUI
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Dimension applyMinimumWidth( Dimension size, JComponent c ) {
|
private Dimension applyMinimumWidth( Dimension size, JComponent c ) {
|
||||||
|
int minimumWidth = FlatUIUtils.minimumWidth( getComponent(), this.minimumWidth );
|
||||||
int focusWidth = (c.getBorder() instanceof FlatBorder) ? this.focusWidth : 0;
|
int focusWidth = (c.getBorder() instanceof FlatBorder) ? this.focusWidth : 0;
|
||||||
size.width = Math.max( size.width, scale( minimumWidth + (focusWidth * 2) ) );
|
size.width = Math.max( size.width, scale( minimumWidth + (focusWidth * 2) ) );
|
||||||
return size;
|
return size;
|
||||||
|
|||||||
@@ -22,6 +22,17 @@ import javax.swing.plaf.ComponentUI;
|
|||||||
/**
|
/**
|
||||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JPopupMenu.Separator}.
|
* Provides the Flat LaF UI delegate for {@link javax.swing.JPopupMenu.Separator}.
|
||||||
*
|
*
|
||||||
|
* <!-- BasicSeparatorUI -->
|
||||||
|
*
|
||||||
|
* @uiDefault PopupMenuSeparator.background Color unused
|
||||||
|
* @uiDefault PopupMenuSeparator.foreground Color
|
||||||
|
*
|
||||||
|
* <!-- FlatSeparatorUI -->
|
||||||
|
*
|
||||||
|
* @uiDefault PopupMenuSeparator.height int height (or width) of the component; may be larger than stripe
|
||||||
|
* @uiDefault PopupMenuSeparator.stripeWidth int width of the stripe
|
||||||
|
* @uiDefault PopupMenuSeparator.stripeIndent int indent of stripe from top (or left); allows positioning of stripe within component
|
||||||
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
public class FlatPopupMenuSeparatorUI
|
public class FlatPopupMenuSeparatorUI
|
||||||
|
|||||||
@@ -23,6 +23,13 @@ import javax.swing.plaf.basic.BasicPopupMenuUI;
|
|||||||
/**
|
/**
|
||||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JPopupMenu}.
|
* Provides the Flat LaF UI delegate for {@link javax.swing.JPopupMenu}.
|
||||||
*
|
*
|
||||||
|
* <!-- BasicPopupMenuUI -->
|
||||||
|
*
|
||||||
|
* @uiDefault PopupMenu.font Font
|
||||||
|
* @uiDefault PopupMenu.background Color
|
||||||
|
* @uiDefault PopupMenu.foreground Color
|
||||||
|
* @uiDefault PopupMenu.border Border
|
||||||
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
public class FlatPopupMenuUI
|
public class FlatPopupMenuUI
|
||||||
|
|||||||
@@ -16,14 +16,19 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf.ui;
|
package com.formdev.flatlaf.ui;
|
||||||
|
|
||||||
|
import static com.formdev.flatlaf.FlatClientProperties.*;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
|
import java.awt.FontMetrics;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.awt.Insets;
|
import java.awt.Insets;
|
||||||
|
import java.awt.geom.Area;
|
||||||
import java.awt.geom.RoundRectangle2D;
|
import java.awt.geom.RoundRectangle2D;
|
||||||
|
import java.beans.PropertyChangeListener;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
import javax.swing.JProgressBar;
|
import javax.swing.JProgressBar;
|
||||||
import javax.swing.LookAndFeel;
|
import javax.swing.LookAndFeel;
|
||||||
|
import javax.swing.UIManager;
|
||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
import javax.swing.plaf.basic.BasicProgressBarUI;
|
import javax.swing.plaf.basic.BasicProgressBarUI;
|
||||||
import com.formdev.flatlaf.util.UIScale;
|
import com.formdev.flatlaf.util.UIScale;
|
||||||
@@ -31,11 +36,34 @@ import com.formdev.flatlaf.util.UIScale;
|
|||||||
/**
|
/**
|
||||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JProgressBar}.
|
* Provides the Flat LaF UI delegate for {@link javax.swing.JProgressBar}.
|
||||||
*
|
*
|
||||||
|
* <!-- BasicProgressBarUI -->
|
||||||
|
*
|
||||||
|
* @uiDefault ProgressBar.font Font
|
||||||
|
* @uiDefault ProgressBar.background Color
|
||||||
|
* @uiDefault ProgressBar.foreground Color
|
||||||
|
* @uiDefault ProgressBar.selectionBackground Color
|
||||||
|
* @uiDefault ProgressBar.selectionForeground Color
|
||||||
|
* @uiDefault ProgressBar.border Border
|
||||||
|
* @uiDefault ProgressBar.horizontalSize Dimension default is 146,12
|
||||||
|
* @uiDefault ProgressBar.verticalSize Dimension default is 12,146
|
||||||
|
* @uiDefault ProgressBar.repaintInterval int default is 50 milliseconds
|
||||||
|
* @uiDefault ProgressBar.cycleTime int default is 3000 milliseconds
|
||||||
|
*
|
||||||
|
* <!-- FlatProgressBarUI -->
|
||||||
|
*
|
||||||
|
* @uiDefault ProgressBar.arc int
|
||||||
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
public class FlatProgressBarUI
|
public class FlatProgressBarUI
|
||||||
extends BasicProgressBarUI
|
extends BasicProgressBarUI
|
||||||
{
|
{
|
||||||
|
protected int arc;
|
||||||
|
protected Dimension horizontalSize;
|
||||||
|
protected Dimension verticalSize;
|
||||||
|
|
||||||
|
private PropertyChangeListener propertyChangeListener;
|
||||||
|
|
||||||
public static ComponentUI createUI( JComponent c ) {
|
public static ComponentUI createUI( JComponent c ) {
|
||||||
return new FlatProgressBarUI();
|
return new FlatProgressBarUI();
|
||||||
}
|
}
|
||||||
@@ -45,16 +73,61 @@ public class FlatProgressBarUI
|
|||||||
super.installDefaults();
|
super.installDefaults();
|
||||||
|
|
||||||
LookAndFeel.installProperty( progressBar, "opaque", false );
|
LookAndFeel.installProperty( progressBar, "opaque", false );
|
||||||
|
|
||||||
|
arc = UIManager.getInt( "ProgressBar.arc" );
|
||||||
|
horizontalSize = UIManager.getDimension( "ProgressBar.horizontalSize" );
|
||||||
|
verticalSize = UIManager.getDimension( "ProgressBar.verticalSize" );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void installListeners() {
|
||||||
|
super.installListeners();
|
||||||
|
|
||||||
|
propertyChangeListener = e -> {
|
||||||
|
switch( e.getPropertyName() ) {
|
||||||
|
case PROGRESS_BAR_LARGE_HEIGHT:
|
||||||
|
case PROGRESS_BAR_SQUARE:
|
||||||
|
progressBar.revalidate();
|
||||||
|
progressBar.repaint();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
progressBar.addPropertyChangeListener( propertyChangeListener );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void uninstallListeners() {
|
||||||
|
super.uninstallListeners();
|
||||||
|
|
||||||
|
progressBar.removePropertyChangeListener( propertyChangeListener );
|
||||||
|
propertyChangeListener = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dimension getPreferredSize( JComponent c ) {
|
||||||
|
Dimension size = super.getPreferredSize( c );
|
||||||
|
|
||||||
|
if( progressBar.isStringPainted() || clientPropertyBoolean( c, PROGRESS_BAR_LARGE_HEIGHT, false ) ) {
|
||||||
|
// recalculate progress height/width to make it smaller
|
||||||
|
Insets insets = progressBar.getInsets();
|
||||||
|
FontMetrics fm = progressBar.getFontMetrics( progressBar.getFont() );
|
||||||
|
if( progressBar.getOrientation() == JProgressBar.HORIZONTAL )
|
||||||
|
size.height = Math.max( fm.getHeight() + insets.top + insets.bottom, getPreferredInnerHorizontal().height );
|
||||||
|
else
|
||||||
|
size.width = Math.max( fm.getHeight() + insets.left + insets.right, getPreferredInnerVertical().width );
|
||||||
|
}
|
||||||
|
|
||||||
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Dimension getPreferredInnerHorizontal() {
|
protected Dimension getPreferredInnerHorizontal() {
|
||||||
return UIScale.scale( super.getPreferredInnerHorizontal() );
|
return UIScale.scale( horizontalSize );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Dimension getPreferredInnerVertical() {
|
protected Dimension getPreferredInnerVertical() {
|
||||||
return UIScale.scale( super.getPreferredInnerVertical() );
|
return UIScale.scale( verticalSize );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -77,13 +150,16 @@ public class FlatProgressBarUI
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
boolean horizontal = (progressBar.getOrientation() == JProgressBar.HORIZONTAL);
|
boolean horizontal = (progressBar.getOrientation() == JProgressBar.HORIZONTAL);
|
||||||
int arc = horizontal ? height : width;
|
int arc = clientPropertyBoolean( c, PROGRESS_BAR_SQUARE, false )
|
||||||
|
? 0
|
||||||
|
: Math.min( UIScale.scale( this.arc ), horizontal ? height : width );
|
||||||
|
|
||||||
FlatUIUtils.setRenderingHints( (Graphics2D) g );
|
FlatUIUtils.setRenderingHints( (Graphics2D) g );
|
||||||
|
|
||||||
// paint track
|
// paint track
|
||||||
|
RoundRectangle2D.Float trackShape = new RoundRectangle2D.Float( x, y, width, height, arc, arc );
|
||||||
g.setColor( progressBar.getBackground() );
|
g.setColor( progressBar.getBackground() );
|
||||||
((Graphics2D)g).fill( new RoundRectangle2D.Float( x, y, width, height, arc, arc ) );
|
((Graphics2D)g).fill( trackShape );
|
||||||
|
|
||||||
// paint progress
|
// paint progress
|
||||||
if( progressBar.isIndeterminate() ) {
|
if( progressBar.isIndeterminate() ) {
|
||||||
@@ -99,11 +175,19 @@ public class FlatProgressBarUI
|
|||||||
} else {
|
} else {
|
||||||
int amountFull = getAmountFull( insets, width, height );
|
int amountFull = getAmountFull( insets, width, height );
|
||||||
|
|
||||||
g.setColor( progressBar.getForeground() );
|
RoundRectangle2D.Float progressShape = horizontal
|
||||||
((Graphics2D)g).fill( horizontal
|
|
||||||
? new RoundRectangle2D.Float( c.getComponentOrientation().isLeftToRight() ? x : x + (width - amountFull),
|
? new RoundRectangle2D.Float( c.getComponentOrientation().isLeftToRight() ? x : x + (width - amountFull),
|
||||||
y, amountFull, height, arc, arc )
|
y, amountFull, height, arc, arc )
|
||||||
: new RoundRectangle2D.Float( x, y + (height - amountFull), width, amountFull, arc, arc ) );
|
: new RoundRectangle2D.Float( x, y + (height - amountFull), width, amountFull, arc, arc );
|
||||||
|
|
||||||
|
g.setColor( progressBar.getForeground() );
|
||||||
|
if( amountFull < (horizontal ? height : width) ) {
|
||||||
|
// special painting for low amounts to avoid painting outside of track
|
||||||
|
Area area = new Area( trackShape );
|
||||||
|
area.intersect( new Area( progressShape ) );
|
||||||
|
((Graphics2D)g).fill( area );
|
||||||
|
} else
|
||||||
|
((Graphics2D)g).fill( progressShape );
|
||||||
|
|
||||||
if( progressBar.isStringPainted() )
|
if( progressBar.isStringPainted() )
|
||||||
paintString( g, x, y, width, height, amountFull, insets );
|
paintString( g, x, y, width, height, amountFull, insets );
|
||||||
|
|||||||
@@ -17,14 +17,37 @@
|
|||||||
package com.formdev.flatlaf.ui;
|
package com.formdev.flatlaf.ui;
|
||||||
|
|
||||||
import static com.formdev.flatlaf.util.UIScale.scale;
|
import static com.formdev.flatlaf.util.UIScale.scale;
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import java.awt.Rectangle;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
|
import javax.swing.JMenuItem;
|
||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
import javax.swing.plaf.basic.BasicRadioButtonMenuItemUI;
|
import javax.swing.plaf.basic.BasicRadioButtonMenuItemUI;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JRadioButtonMenuItem}.
|
* Provides the Flat LaF UI delegate for {@link javax.swing.JRadioButtonMenuItem}.
|
||||||
*
|
*
|
||||||
|
* <!-- BasicRadioButtonMenuItemUI -->
|
||||||
|
*
|
||||||
|
* @uiDefault RadioButtonMenuItem.font Font
|
||||||
|
* @uiDefault RadioButtonMenuItem.background Color
|
||||||
|
* @uiDefault RadioButtonMenuItem.foreground Color
|
||||||
|
* @uiDefault RadioButtonMenuItem.disabledForeground Color
|
||||||
|
* @uiDefault RadioButtonMenuItem.selectionBackground Color
|
||||||
|
* @uiDefault RadioButtonMenuItem.selectionForeground Color
|
||||||
|
* @uiDefault RadioButtonMenuItem.acceleratorForeground Color
|
||||||
|
* @uiDefault RadioButtonMenuItem.acceleratorSelectionForeground Color
|
||||||
|
* @uiDefault MenuItem.acceleratorFont Font defaults to MenuItem.font
|
||||||
|
* @uiDefault MenuItem.acceleratorDelimiter String
|
||||||
|
* @uiDefault RadioButtonMenuItem.border Border
|
||||||
|
* @uiDefault RadioButtonMenuItem.borderPainted boolean
|
||||||
|
* @uiDefault RadioButtonMenuItem.margin Insets
|
||||||
|
* @uiDefault RadioButtonMenuItem.arrowIcon Icon
|
||||||
|
* @uiDefault RadioButtonMenuItem.checkIcon Icon
|
||||||
|
* @uiDefault RadioButtonMenuItem.opaque boolean
|
||||||
|
* @uiDefault RadioButtonMenuItem.evenHeight boolean
|
||||||
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
public class FlatRadioButtonMenuItemUI
|
public class FlatRadioButtonMenuItemUI
|
||||||
@@ -54,4 +77,9 @@ public class FlatRadioButtonMenuItemUI
|
|||||||
defaultTextIconGap = scale( defaultTextIconGap );
|
defaultTextIconGap = scale( defaultTextIconGap );
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void paintText( Graphics g, JMenuItem menuItem, Rectangle textRect, String text ) {
|
||||||
|
FlatMenuItemUI.paintText( g, menuItem, textRect, text, disabledForeground, selectionForeground );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,22 +18,38 @@ package com.formdev.flatlaf.ui;
|
|||||||
|
|
||||||
import static com.formdev.flatlaf.util.UIScale.scale;
|
import static com.formdev.flatlaf.util.UIScale.scale;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
|
import java.awt.Dimension;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
|
import java.awt.Insets;
|
||||||
import java.awt.Rectangle;
|
import java.awt.Rectangle;
|
||||||
import javax.swing.AbstractButton;
|
import javax.swing.AbstractButton;
|
||||||
|
import javax.swing.CellRendererPane;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
import javax.swing.LookAndFeel;
|
import javax.swing.LookAndFeel;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
|
import javax.swing.plaf.UIResource;
|
||||||
import javax.swing.plaf.basic.BasicRadioButtonUI;
|
import javax.swing.plaf.basic.BasicRadioButtonUI;
|
||||||
|
import com.formdev.flatlaf.icons.FlatCheckBoxIcon;
|
||||||
|
import com.formdev.flatlaf.util.UIScale;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JRadioButton}.
|
* Provides the Flat LaF UI delegate for {@link javax.swing.JRadioButton}.
|
||||||
*
|
*
|
||||||
* TODO document used UI defaults of superclass
|
* <!-- BasicRadioButtonUI -->
|
||||||
*
|
*
|
||||||
* @uiDefault Button.iconTextGap int
|
* @uiDefault RadioButton.font Font
|
||||||
* @uiDefault Button.disabledText Color
|
* @uiDefault RadioButton.background Color
|
||||||
|
* @uiDefault RadioButton.foreground Color
|
||||||
|
* @uiDefault RadioButton.border Border
|
||||||
|
* @uiDefault RadioButton.margin Insets
|
||||||
|
* @uiDefault RadioButton.rollover boolean
|
||||||
|
* @uiDefault RadioButton.icon Icon
|
||||||
|
*
|
||||||
|
* <!-- FlatRadioButtonUI -->
|
||||||
|
*
|
||||||
|
* @uiDefault RadioButton.iconTextGap int
|
||||||
|
* @uiDefault RadioButton.disabledText Color
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
@@ -80,8 +96,73 @@ public class FlatRadioButtonUI
|
|||||||
defaults_initialized = false;
|
defaults_initialized = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Insets tempInsets = new Insets( 0, 0, 0, 0 );
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dimension getPreferredSize( JComponent c ) {
|
||||||
|
Dimension size = super.getPreferredSize( c );
|
||||||
|
|
||||||
|
// small insets fix
|
||||||
|
int focusWidth = getIconFocusWidth( c );
|
||||||
|
if( focusWidth > 0 ) {
|
||||||
|
// 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.
|
||||||
|
// Otherwise the component may be too small and outer focus border may be cut off.
|
||||||
|
Insets insets = c.getInsets( tempInsets );
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void paint( Graphics g, JComponent c ) {
|
||||||
|
// fill background even if opaque if
|
||||||
|
// - used as cell renderer (because of selection background)
|
||||||
|
// - if background was explicitly set to a non-UIResource color
|
||||||
|
if( !c.isOpaque() &&
|
||||||
|
(c.getParent() instanceof CellRendererPane || !(c.getBackground() instanceof UIResource)) )
|
||||||
|
{
|
||||||
|
g.setColor( c.getBackground() );
|
||||||
|
g.fillRect( 0, 0, c.getWidth(), c.getHeight() );
|
||||||
|
}
|
||||||
|
|
||||||
|
// small insets fix
|
||||||
|
int focusWidth = getIconFocusWidth( c );
|
||||||
|
if( focusWidth > 0 ) {
|
||||||
|
boolean ltr = c.getComponentOrientation().isLeftToRight();
|
||||||
|
Insets insets = c.getInsets( tempInsets );
|
||||||
|
int leftOrRightInset = ltr ? insets.left : insets.right;
|
||||||
|
if( focusWidth > leftOrRightInset ) {
|
||||||
|
// The left (or right) inset is smaller than the focus width, which may be
|
||||||
|
// the case if insets were explicitly reduced (e.g. with an EmptyBorder).
|
||||||
|
// In this case the width has been increased in getPreferredSize() and
|
||||||
|
// here it is necessary to fix icon and text painting location.
|
||||||
|
int offset = focusWidth - leftOrRightInset;
|
||||||
|
if( !ltr )
|
||||||
|
offset = -offset;
|
||||||
|
|
||||||
|
// move the graphics origin to the left (or right)
|
||||||
|
g.translate( offset, 0 );
|
||||||
|
super.paint( g, c );
|
||||||
|
g.translate( -offset, 0 );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
super.paint( g, c );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void paintText( Graphics g, AbstractButton b, Rectangle textRect, String text ) {
|
protected void paintText( Graphics g, AbstractButton b, Rectangle textRect, String text ) {
|
||||||
FlatButtonUI.paintText( g, b, textRect, text, b.isEnabled() ? b.getForeground() : disabledText );
|
FlatButtonUI.paintText( g, b, textRect, text, b.isEnabled() ? b.getForeground() : disabledText );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int getIconFocusWidth( JComponent c ) {
|
||||||
|
AbstractButton b = (AbstractButton) c;
|
||||||
|
return (b.getIcon() == null && getDefaultIcon() instanceof FlatCheckBoxIcon)
|
||||||
|
? UIScale.scale( ((FlatCheckBoxIcon)getDefaultIcon()).focusWidth )
|
||||||
|
: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
package com.formdev.flatlaf.ui;
|
package com.formdev.flatlaf.ui;
|
||||||
|
|
||||||
import static com.formdev.flatlaf.util.UIScale.scale;
|
import static com.formdev.flatlaf.util.UIScale.scale;
|
||||||
|
import java.awt.Component;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -32,7 +33,7 @@ public class FlatRoundBorder
|
|||||||
protected final int arc = UIManager.getInt( "Component.arc" );
|
protected final int arc = UIManager.getInt( "Component.arc" );
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected float getArc() {
|
protected float getArc( Component c ) {
|
||||||
return scale( (float) arc );
|
return scale( (float) arc );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,26 +22,40 @@ import java.awt.Graphics;
|
|||||||
import java.awt.Rectangle;
|
import java.awt.Rectangle;
|
||||||
import java.awt.event.MouseAdapter;
|
import java.awt.event.MouseAdapter;
|
||||||
import java.awt.event.MouseEvent;
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.beans.PropertyChangeEvent;
|
||||||
|
import java.beans.PropertyChangeListener;
|
||||||
|
import java.util.Objects;
|
||||||
import javax.swing.JButton;
|
import javax.swing.JButton;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
|
import javax.swing.JScrollPane;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
import javax.swing.plaf.basic.BasicScrollBarUI;
|
import javax.swing.plaf.basic.BasicScrollBarUI;
|
||||||
|
import com.formdev.flatlaf.FlatClientProperties;
|
||||||
import com.formdev.flatlaf.util.UIScale;
|
import com.formdev.flatlaf.util.UIScale;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JScrollBar}.
|
* Provides the Flat LaF UI delegate for {@link javax.swing.JScrollBar}.
|
||||||
*
|
*
|
||||||
|
* <!-- BasicScrollBarUI -->
|
||||||
|
*
|
||||||
* @uiDefault ScrollBar.background Color
|
* @uiDefault ScrollBar.background Color
|
||||||
* @uiDefault ScrollBar.foreground Color
|
* @uiDefault ScrollBar.foreground Color
|
||||||
* @uiDefault ScrollBar.track Color
|
* @uiDefault ScrollBar.track Color
|
||||||
* @uiDefault ScrollBar.thumb Color
|
* @uiDefault ScrollBar.thumb Color
|
||||||
|
* @uiDefault ScrollBar.width int
|
||||||
|
* @uiDefault ScrollBar.minimumThumbSize Dimension
|
||||||
|
* @uiDefault ScrollBar.maximumThumbSize Dimension
|
||||||
|
* @uiDefault ScrollBar.allowsAbsolutePositioning boolean
|
||||||
|
*
|
||||||
|
* <!-- FlatScrollBarUI -->
|
||||||
|
*
|
||||||
* @uiDefault ScrollBar.hoverTrackColor Color
|
* @uiDefault ScrollBar.hoverTrackColor Color
|
||||||
* @uiDefault ScrollBar.hoverThumbColor Color
|
* @uiDefault ScrollBar.hoverThumbColor Color
|
||||||
* @uiDefault ScrollBar.width int
|
* @uiDefault Component.arrowType String triangle (default) or chevron
|
||||||
* @uiDefault ScrollBar.minimumThumbSize Insets
|
* @uiDefault ScrollBar.showButtons boolean
|
||||||
* @uiDefault ScrollBar.maximumThumbSize Insets
|
* @uiDefault ScrollBar.buttonArrowColor Color
|
||||||
* @uiDefault ScrollBar.allowsAbsolutePositioning boolean
|
* @uiDefault ScrollBar.buttonDisabledArrowColor Color
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
@@ -51,6 +65,11 @@ public class FlatScrollBarUI
|
|||||||
protected Color hoverTrackColor;
|
protected Color hoverTrackColor;
|
||||||
protected Color hoverThumbColor;
|
protected Color hoverThumbColor;
|
||||||
|
|
||||||
|
protected boolean showButtons;
|
||||||
|
protected String arrowType;
|
||||||
|
protected Color buttonArrowColor;
|
||||||
|
protected Color buttonDisabledArrowColor;
|
||||||
|
|
||||||
private MouseAdapter hoverListener;
|
private MouseAdapter hoverListener;
|
||||||
private boolean hoverTrack;
|
private boolean hoverTrack;
|
||||||
private boolean hoverThumb;
|
private boolean hoverThumb;
|
||||||
@@ -83,6 +102,11 @@ public class FlatScrollBarUI
|
|||||||
|
|
||||||
hoverTrackColor = UIManager.getColor( "ScrollBar.hoverTrackColor" );
|
hoverTrackColor = UIManager.getColor( "ScrollBar.hoverTrackColor" );
|
||||||
hoverThumbColor = UIManager.getColor( "ScrollBar.hoverThumbColor" );
|
hoverThumbColor = UIManager.getColor( "ScrollBar.hoverThumbColor" );
|
||||||
|
|
||||||
|
showButtons = UIManager.getBoolean( "ScrollBar.showButtons" );
|
||||||
|
arrowType = UIManager.getString( "Component.arrowType" );
|
||||||
|
buttonArrowColor = UIManager.getColor( "ScrollBar.buttonArrowColor" );
|
||||||
|
buttonDisabledArrowColor = UIManager.getColor( "ScrollBar.buttonDisabledArrowColor" );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -91,6 +115,24 @@ public class FlatScrollBarUI
|
|||||||
|
|
||||||
hoverTrackColor = null;
|
hoverTrackColor = null;
|
||||||
hoverThumbColor = null;
|
hoverThumbColor = null;
|
||||||
|
|
||||||
|
buttonArrowColor = null;
|
||||||
|
buttonDisabledArrowColor = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected PropertyChangeListener createPropertyChangeListener() {
|
||||||
|
return new BasicScrollBarUI.PropertyChangeHandler() {
|
||||||
|
@Override
|
||||||
|
public void propertyChange( PropertyChangeEvent e ) {
|
||||||
|
super.propertyChange( e );
|
||||||
|
|
||||||
|
if( FlatClientProperties.SCROLL_BAR_SHOW_BUTTONS.equals( e.getPropertyName() ) ) {
|
||||||
|
scrollbar.revalidate();
|
||||||
|
scrollbar.repaint();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -100,24 +142,50 @@ public class FlatScrollBarUI
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected JButton createDecreaseButton( int orientation ) {
|
protected JButton createDecreaseButton( int orientation ) {
|
||||||
return createInvisibleButton();
|
return createArrowButton( orientation );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected JButton createIncreaseButton( int orientation ) {
|
protected JButton createIncreaseButton( int orientation ) {
|
||||||
return createInvisibleButton();
|
return createArrowButton( orientation );
|
||||||
}
|
}
|
||||||
|
|
||||||
private JButton createInvisibleButton() {
|
private JButton createArrowButton( int orientation ) {
|
||||||
JButton button = new JButton();
|
FlatArrowButton button = new FlatArrowButton( orientation,
|
||||||
button.setMinimumSize( new Dimension() );
|
arrowType, buttonArrowColor, buttonDisabledArrowColor, null, hoverTrackColor )
|
||||||
button.setMaximumSize( new Dimension() );
|
{
|
||||||
button.setPreferredSize( new Dimension() );
|
@Override
|
||||||
|
public Dimension getPreferredSize() {
|
||||||
|
if( isShowButtons() ) {
|
||||||
|
int w = UIScale.scale( scrollBarWidth );
|
||||||
|
return new Dimension( w, w );
|
||||||
|
} else
|
||||||
|
return new Dimension();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dimension getMinimumSize() {
|
||||||
|
return isShowButtons() ? super.getMinimumSize() : new Dimension();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Dimension getMaximumSize() {
|
||||||
|
return isShowButtons() ? super.getMaximumSize() : new Dimension();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
button.setArrowWidth( FlatArrowButton.DEFAULT_ARROW_WIDTH - 2 );
|
||||||
button.setFocusable( false );
|
button.setFocusable( false );
|
||||||
button.setRequestFocusEnabled( false );
|
button.setRequestFocusEnabled( false );
|
||||||
return button;
|
return button;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isShowButtons() {
|
||||||
|
Object showButtons = scrollbar.getClientProperty( FlatClientProperties.SCROLL_BAR_SHOW_BUTTONS );
|
||||||
|
if( showButtons == null && scrollbar.getParent() instanceof JScrollPane )
|
||||||
|
showButtons = ((JScrollPane)scrollbar.getParent()).getClientProperty( FlatClientProperties.SCROLL_BAR_SHOW_BUTTONS );
|
||||||
|
return (showButtons != null) ? Objects.equals( showButtons, true ) : this.showButtons;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void paintDecreaseHighlight( Graphics g ) {
|
protected void paintDecreaseHighlight( Graphics g ) {
|
||||||
// do not paint
|
// do not paint
|
||||||
|
|||||||
@@ -14,27 +14,57 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Smooth scrolling code partly based on code from IntelliJ IDEA Community Edition,
|
||||||
|
* which is licensed under the Apache 2.0 license. Copyright 2000-2016 JetBrains s.r.o.
|
||||||
|
* See: https://github.com/JetBrains/intellij-community/blob/31e1b5a8e43219b9571951bab6457cfb3012e3ef/platform/platform-api/src/com/intellij/ui/components/SmoothScrollPane.java#L141-L185
|
||||||
|
*
|
||||||
|
*/
|
||||||
package com.formdev.flatlaf.ui;
|
package com.formdev.flatlaf.ui;
|
||||||
|
|
||||||
import java.awt.Component;
|
import java.awt.Component;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.awt.Insets;
|
import java.awt.Insets;
|
||||||
|
import java.awt.Rectangle;
|
||||||
import java.awt.event.ContainerEvent;
|
import java.awt.event.ContainerEvent;
|
||||||
import java.awt.event.ContainerListener;
|
import java.awt.event.ContainerListener;
|
||||||
import java.awt.event.FocusEvent;
|
import java.awt.event.FocusEvent;
|
||||||
import java.awt.event.FocusListener;
|
import java.awt.event.FocusListener;
|
||||||
|
import java.awt.event.MouseWheelEvent;
|
||||||
|
import java.awt.event.MouseWheelListener;
|
||||||
import java.beans.PropertyChangeEvent;
|
import java.beans.PropertyChangeEvent;
|
||||||
|
import java.beans.PropertyChangeListener;
|
||||||
|
import javax.swing.BorderFactory;
|
||||||
|
import javax.swing.JButton;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
|
import javax.swing.JScrollBar;
|
||||||
import javax.swing.JScrollPane;
|
import javax.swing.JScrollPane;
|
||||||
|
import javax.swing.JTable;
|
||||||
import javax.swing.JViewport;
|
import javax.swing.JViewport;
|
||||||
import javax.swing.LookAndFeel;
|
import javax.swing.LookAndFeel;
|
||||||
|
import javax.swing.ScrollPaneConstants;
|
||||||
|
import javax.swing.Scrollable;
|
||||||
|
import javax.swing.SwingConstants;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
import javax.swing.plaf.basic.BasicScrollPaneUI;
|
import javax.swing.plaf.basic.BasicScrollPaneUI;
|
||||||
|
import com.formdev.flatlaf.FlatClientProperties;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JScrollPane}.
|
* Provides the Flat LaF UI delegate for {@link javax.swing.JScrollPane}.
|
||||||
*
|
*
|
||||||
|
* <!-- BasicScrollPaneUI -->
|
||||||
|
*
|
||||||
|
* @uiDefault ScrollPane.font Font unused
|
||||||
|
* @uiDefault ScrollPane.background Color
|
||||||
|
* @uiDefault ScrollPane.foreground Color unused
|
||||||
|
* @uiDefault ScrollPane.border Border
|
||||||
|
* @uiDefault ScrollPane.viewportBorder Border
|
||||||
|
*
|
||||||
|
* <!-- FlatScrollPaneUI -->
|
||||||
|
*
|
||||||
|
* @uiDefault ScrollPane.smoothScrolling boolean
|
||||||
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
public class FlatScrollPaneUI
|
public class FlatScrollPaneUI
|
||||||
@@ -79,7 +109,172 @@ public class FlatScrollPaneUI
|
|||||||
handler = null;
|
handler = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Handler getHandler() {
|
@Override
|
||||||
|
protected MouseWheelListener createMouseWheelListener() {
|
||||||
|
return new BasicScrollPaneUI.MouseWheelHandler() {
|
||||||
|
@Override
|
||||||
|
public void mouseWheelMoved( MouseWheelEvent e ) {
|
||||||
|
// Note: Getting UI value "ScrollPane.smoothScrolling" here to allow
|
||||||
|
// applications to turn smooth scrolling on or off at any time
|
||||||
|
// (e.g. in application options dialog).
|
||||||
|
if( UIManager.getBoolean( "ScrollPane.smoothScrolling" ) &&
|
||||||
|
scrollpane.isWheelScrollingEnabled() &&
|
||||||
|
e.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL &&
|
||||||
|
e.getPreciseWheelRotation() != 0 &&
|
||||||
|
e.getPreciseWheelRotation() != e.getWheelRotation() )
|
||||||
|
{
|
||||||
|
mouseWheelMovedSmooth( e );
|
||||||
|
} else
|
||||||
|
super.mouseWheelMoved( e );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final double EPSILON = 1e-5d;
|
||||||
|
|
||||||
|
private void mouseWheelMovedSmooth( MouseWheelEvent e ) {
|
||||||
|
// return if there is no viewport
|
||||||
|
JViewport viewport = scrollpane.getViewport();
|
||||||
|
if( viewport == null )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// find scrollbar to scroll
|
||||||
|
JScrollBar scrollbar = scrollpane.getVerticalScrollBar();
|
||||||
|
if( scrollbar == null || !scrollbar.isVisible() || e.isShiftDown() ) {
|
||||||
|
scrollbar = scrollpane.getHorizontalScrollBar();
|
||||||
|
if( scrollbar == null || !scrollbar.isVisible() )
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// consume event
|
||||||
|
e.consume();
|
||||||
|
|
||||||
|
// get precise wheel rotation
|
||||||
|
double rotation = e.getPreciseWheelRotation();
|
||||||
|
|
||||||
|
// get unit and block increment
|
||||||
|
int unitIncrement;
|
||||||
|
int blockIncrement;
|
||||||
|
int orientation = scrollbar.getOrientation();
|
||||||
|
Component view = viewport.getView();
|
||||||
|
if( view instanceof Scrollable ) {
|
||||||
|
Scrollable scrollable = (Scrollable) view;
|
||||||
|
|
||||||
|
// Use (0, 0) view position to obtain constant unit increment of first item
|
||||||
|
// (which might otherwise be variable on smaller-than-unit scrolling).
|
||||||
|
Rectangle visibleRect = new Rectangle( viewport.getViewSize() );
|
||||||
|
unitIncrement = scrollable.getScrollableUnitIncrement( visibleRect, orientation, 1 );
|
||||||
|
blockIncrement = scrollable.getScrollableBlockIncrement( visibleRect, orientation, 1 );
|
||||||
|
|
||||||
|
if( unitIncrement > 0 ) {
|
||||||
|
// For the case that the first item (e.g. in a list) is larger
|
||||||
|
// than the other items, get the unit increment of the second item
|
||||||
|
// and use the smaller one.
|
||||||
|
if( orientation == SwingConstants.VERTICAL ) {
|
||||||
|
visibleRect.y += unitIncrement;
|
||||||
|
visibleRect.height -= unitIncrement;
|
||||||
|
} else {
|
||||||
|
visibleRect.x += unitIncrement;
|
||||||
|
visibleRect.width -= unitIncrement;
|
||||||
|
}
|
||||||
|
int unitIncrement2 = scrollable.getScrollableUnitIncrement( visibleRect, orientation, 1 );
|
||||||
|
if( unitIncrement2 > 0 )
|
||||||
|
unitIncrement = Math.min( unitIncrement, unitIncrement2 );
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
int direction = rotation < 0 ? -1 : 1;
|
||||||
|
unitIncrement = scrollbar.getUnitIncrement( direction );
|
||||||
|
blockIncrement = scrollbar.getBlockIncrement( direction );
|
||||||
|
}
|
||||||
|
|
||||||
|
// limit scroll amount (number of units to scroll) for small viewports
|
||||||
|
// (e.g. vertical scrolling in file chooser)
|
||||||
|
int scrollAmount = e.getScrollAmount();
|
||||||
|
int viewportWH = (orientation == SwingConstants.VERTICAL)
|
||||||
|
? viewport.getHeight()
|
||||||
|
: viewport.getWidth();
|
||||||
|
if( unitIncrement * scrollAmount > viewportWH )
|
||||||
|
scrollAmount = Math.max( viewportWH / unitIncrement, 1 );
|
||||||
|
|
||||||
|
// compute relative delta
|
||||||
|
double delta = rotation * scrollAmount * unitIncrement;
|
||||||
|
boolean adjustDelta = Math.abs( rotation ) < (1.0 + EPSILON);
|
||||||
|
double adjustedDelta = adjustDelta
|
||||||
|
? Math.max( -blockIncrement, Math.min( delta, blockIncrement ) )
|
||||||
|
: delta;
|
||||||
|
|
||||||
|
// compute new value
|
||||||
|
int value = scrollbar.getValue();
|
||||||
|
double minDelta = scrollbar.getMinimum() - value;
|
||||||
|
double maxDelta = scrollbar.getMaximum() - scrollbar.getModel().getExtent() - value;
|
||||||
|
double boundedDelta = Math.max( minDelta, Math.min( adjustedDelta, maxDelta ) );
|
||||||
|
int newValue = value + (int) Math.round( boundedDelta );
|
||||||
|
|
||||||
|
// set new value
|
||||||
|
if( newValue != value )
|
||||||
|
scrollbar.setValue( newValue );
|
||||||
|
|
||||||
|
/*debug
|
||||||
|
System.out.println( String.format( "%4d %9f / %4d %4d / %12f %5s %12f / %4d %4d %4d / %12f %12f %12f / %4d",
|
||||||
|
e.getWheelRotation(),
|
||||||
|
e.getPreciseWheelRotation(),
|
||||||
|
unitIncrement,
|
||||||
|
blockIncrement,
|
||||||
|
delta,
|
||||||
|
adjustDelta,
|
||||||
|
adjustedDelta,
|
||||||
|
value,
|
||||||
|
scrollbar.getMinimum(),
|
||||||
|
scrollbar.getMaximum(),
|
||||||
|
minDelta,
|
||||||
|
maxDelta,
|
||||||
|
boundedDelta,
|
||||||
|
newValue ) );
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected PropertyChangeListener createPropertyChangeListener() {
|
||||||
|
return new BasicScrollPaneUI.PropertyChangeHandler() {
|
||||||
|
@Override
|
||||||
|
public void propertyChange( PropertyChangeEvent e ) {
|
||||||
|
super.propertyChange( e );
|
||||||
|
|
||||||
|
switch( e.getPropertyName() ) {
|
||||||
|
case FlatClientProperties.SCROLL_BAR_SHOW_BUTTONS:
|
||||||
|
JScrollBar vsb = scrollpane.getVerticalScrollBar();
|
||||||
|
JScrollBar hsb = scrollpane.getHorizontalScrollBar();
|
||||||
|
if( vsb != null ) {
|
||||||
|
vsb.revalidate();
|
||||||
|
vsb.repaint();
|
||||||
|
}
|
||||||
|
if( hsb != null ) {
|
||||||
|
hsb.revalidate();
|
||||||
|
hsb.repaint();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ScrollPaneConstants.LOWER_LEFT_CORNER:
|
||||||
|
case ScrollPaneConstants.LOWER_RIGHT_CORNER:
|
||||||
|
case ScrollPaneConstants.UPPER_LEFT_CORNER:
|
||||||
|
case ScrollPaneConstants.UPPER_RIGHT_CORNER:
|
||||||
|
// remove border from buttons added to corners
|
||||||
|
Object corner = e.getNewValue();
|
||||||
|
if( corner instanceof JButton &&
|
||||||
|
((JButton)corner).getBorder() instanceof FlatButtonBorder &&
|
||||||
|
scrollpane.getViewport() != null &&
|
||||||
|
scrollpane.getViewport().getView() instanceof JTable )
|
||||||
|
{
|
||||||
|
((JButton)corner).setBorder( BorderFactory.createEmptyBorder() );
|
||||||
|
((JButton)corner).setFocusable( false );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private Handler getHandler() {
|
||||||
if( handler == null )
|
if( handler == null )
|
||||||
handler = new Handler();
|
handler = new Handler();
|
||||||
return handler;
|
return handler;
|
||||||
|
|||||||
@@ -30,8 +30,13 @@ import javax.swing.plaf.basic.BasicSeparatorUI;
|
|||||||
/**
|
/**
|
||||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JSeparator}.
|
* Provides the Flat LaF UI delegate for {@link javax.swing.JSeparator}.
|
||||||
*
|
*
|
||||||
|
* <!-- BasicSeparatorUI -->
|
||||||
|
*
|
||||||
* @uiDefault Separator.background Color unused
|
* @uiDefault Separator.background Color unused
|
||||||
* @uiDefault Separator.foreground Color
|
* @uiDefault Separator.foreground Color
|
||||||
|
*
|
||||||
|
* <!-- FlatSeparatorUI -->
|
||||||
|
*
|
||||||
* @uiDefault Separator.height int height (or width) of the component; may be larger than stripe
|
* @uiDefault Separator.height int height (or width) of the component; may be larger than stripe
|
||||||
* @uiDefault Separator.stripeWidth int width of the stripe
|
* @uiDefault Separator.stripeWidth int width of the stripe
|
||||||
* @uiDefault Separator.stripeIndent int indent of stripe from top (or left); allows positioning of stripe within component
|
* @uiDefault Separator.stripeIndent int indent of stripe from top (or left); allows positioning of stripe within component
|
||||||
|
|||||||
@@ -34,21 +34,27 @@ import com.formdev.flatlaf.util.UIScale;
|
|||||||
/**
|
/**
|
||||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JSlider}.
|
* Provides the Flat LaF UI delegate for {@link javax.swing.JSlider}.
|
||||||
*
|
*
|
||||||
|
* <!-- BasicSliderUI -->
|
||||||
|
*
|
||||||
* @uiDefault Slider.font Font
|
* @uiDefault Slider.font Font
|
||||||
* @uiDefault Slider.background Color
|
* @uiDefault Slider.background Color
|
||||||
* @uiDefault Slider.foreground Color unused
|
* @uiDefault Slider.foreground Color unused
|
||||||
* @uiDefault Slider.disabledForeground Color used for track and thumb if disabled
|
|
||||||
* @uiDefault Slider.trackColor Color
|
|
||||||
* @uiDefault Slider.thumbColor Color
|
|
||||||
* @uiDefault Slider.tickColor Color
|
* @uiDefault Slider.tickColor Color
|
||||||
* @uiDefault Slider.focusedColor Color
|
|
||||||
* @uiDefault Slider.hoverColor Color optional; defaults to Slider.focusedColor
|
|
||||||
* @uiDefault Slider.trackWidth int
|
|
||||||
* @uiDefault Slider.thumbWidth int
|
|
||||||
* @uiDefault Slider.horizontalSize Dimension preferred horizontal size; height is ignored; computed slider height is used
|
* @uiDefault Slider.horizontalSize Dimension preferred horizontal size; height is ignored; computed slider height is used
|
||||||
* @uiDefault Slider.verticalSize Dimension preferred vertical size; width is ignored; computed slider width is used
|
* @uiDefault Slider.verticalSize Dimension preferred vertical size; width is ignored; computed slider width is used
|
||||||
* @uiDefault Slider.minimumHorizontalSize Dimension height is ignored; computed slider height is used
|
* @uiDefault Slider.minimumHorizontalSize Dimension height is ignored; computed slider height is used
|
||||||
* @uiDefault Slider.minimumVerticalSize Dimension width is ignored; computed slider width is used
|
* @uiDefault Slider.minimumVerticalSize Dimension width is ignored; computed slider width is used
|
||||||
|
* @uiDefault Slider.border Border
|
||||||
|
*
|
||||||
|
* <!-- FlatSliderUI -->
|
||||||
|
*
|
||||||
|
* @uiDefault Slider.trackWidth int
|
||||||
|
* @uiDefault Slider.thumbWidth int
|
||||||
|
* @uiDefault Slider.trackColor Color
|
||||||
|
* @uiDefault Slider.thumbColor Color
|
||||||
|
* @uiDefault Slider.focusedColor Color optional; defaults to Component.focusColor
|
||||||
|
* @uiDefault Slider.hoverColor Color optional; defaults to Slider.focusedColor
|
||||||
|
* @uiDefault Slider.disabledForeground Color used for track and thumb is disabled
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
@@ -104,7 +110,7 @@ public class FlatSliderUI
|
|||||||
|
|
||||||
trackColor = UIManager.getColor( "Slider.trackColor" );
|
trackColor = UIManager.getColor( "Slider.trackColor" );
|
||||||
thumbColor = UIManager.getColor( "Slider.thumbColor" );
|
thumbColor = UIManager.getColor( "Slider.thumbColor" );
|
||||||
focusColor = UIManager.getColor( "Slider.focusedColor" );
|
focusColor = FlatUIUtils.getUIColor( "Slider.focusedColor", "Component.focusColor" );
|
||||||
hoverColor = FlatUIUtils.getUIColor( "Slider.hoverColor", focusColor );
|
hoverColor = FlatUIUtils.getUIColor( "Slider.hoverColor", focusColor );
|
||||||
disabledForeground = UIManager.getColor( "Slider.disabledForeground" );
|
disabledForeground = UIManager.getColor( "Slider.disabledForeground" );
|
||||||
}
|
}
|
||||||
@@ -195,7 +201,7 @@ public class FlatSliderUI
|
|||||||
}
|
}
|
||||||
|
|
||||||
if( coloredTrack != null ) {
|
if( coloredTrack != null ) {
|
||||||
g.setColor( slider.hasFocus() ? focusColor : (hover ? hoverColor : thumbColor) );
|
FlatUIUtils.setColor( g, slider.hasFocus() ? focusColor : (hover ? hoverColor : thumbColor), thumbColor );
|
||||||
((Graphics2D)g).fill( coloredTrack );
|
((Graphics2D)g).fill( coloredTrack );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,9 +211,10 @@ public class FlatSliderUI
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void paintThumb( Graphics g ) {
|
public void paintThumb( Graphics g ) {
|
||||||
g.setColor( slider.isEnabled()
|
FlatUIUtils.setColor( g, slider.isEnabled()
|
||||||
? (slider.hasFocus() ? focusColor : (hover ? hoverColor : thumbColor))
|
? (slider.hasFocus() ? focusColor : (hover ? hoverColor : thumbColor))
|
||||||
: disabledForeground );
|
: disabledForeground,
|
||||||
|
thumbColor );
|
||||||
|
|
||||||
if( isRoundThumb() )
|
if( isRoundThumb() )
|
||||||
g.fillOval( thumbRect.x, thumbRect.y, thumbRect.width, thumbRect.height );
|
g.fillOval( thumbRect.x, thumbRect.y, thumbRect.width, thumbRect.height );
|
||||||
|
|||||||
@@ -44,12 +44,23 @@ import javax.swing.plaf.basic.BasicSpinnerUI;
|
|||||||
/**
|
/**
|
||||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JSpinner}.
|
* Provides the Flat LaF UI delegate for {@link javax.swing.JSpinner}.
|
||||||
*
|
*
|
||||||
* TODO document used UI defaults of superclass
|
* <!-- BasicSpinnerUI -->
|
||||||
|
*
|
||||||
|
* @uiDefault Spinner.font Font
|
||||||
|
* @uiDefault Spinner.background Color
|
||||||
|
* @uiDefault Spinner.foreground Color
|
||||||
|
* @uiDefault Spinner.border Border
|
||||||
|
* @uiDefault Spinner.disableOnBoundaryValues boolean default is false
|
||||||
|
* @uiDefault Spinner.editorAlignment int 0=center, 2=left, 4=right, 10=leading, 11=trailing
|
||||||
|
* @uiDefault Spinner.editorBorderPainted boolean paint inner editor border; defaults to false
|
||||||
|
*
|
||||||
|
* <!-- FlatSpinnerUI -->
|
||||||
*
|
*
|
||||||
* @uiDefault Component.focusWidth int
|
* @uiDefault Component.focusWidth int
|
||||||
* @uiDefault Component.arc int
|
* @uiDefault Component.arc int
|
||||||
* @uiDefault Component.minimumWidth int
|
* @uiDefault Component.minimumWidth int
|
||||||
* @uiDefault Component.arrowType String triangle (default) or chevron
|
* @uiDefault Component.arrowType String triangle (default) or chevron
|
||||||
|
* @uiDefault Component.isIntelliJTheme boolean
|
||||||
* @uiDefault Component.borderColor Color
|
* @uiDefault Component.borderColor Color
|
||||||
* @uiDefault Component.disabledBorderColor Color
|
* @uiDefault Component.disabledBorderColor Color
|
||||||
* @uiDefault Spinner.disabledBackground Color
|
* @uiDefault Spinner.disabledBackground Color
|
||||||
@@ -71,6 +82,7 @@ public class FlatSpinnerUI
|
|||||||
protected int arc;
|
protected int arc;
|
||||||
protected int minimumWidth;
|
protected int minimumWidth;
|
||||||
protected String arrowType;
|
protected String arrowType;
|
||||||
|
protected boolean isIntelliJTheme;
|
||||||
protected Color borderColor;
|
protected Color borderColor;
|
||||||
protected Color disabledBorderColor;
|
protected Color disabledBorderColor;
|
||||||
protected Color disabledBackground;
|
protected Color disabledBackground;
|
||||||
@@ -95,6 +107,7 @@ public class FlatSpinnerUI
|
|||||||
arc = UIManager.getInt( "Component.arc" );
|
arc = UIManager.getInt( "Component.arc" );
|
||||||
minimumWidth = UIManager.getInt( "Component.minimumWidth" );
|
minimumWidth = UIManager.getInt( "Component.minimumWidth" );
|
||||||
arrowType = UIManager.getString( "Component.arrowType" );
|
arrowType = UIManager.getString( "Component.arrowType" );
|
||||||
|
isIntelliJTheme = UIManager.getBoolean( "Component.isIntelliJTheme" );
|
||||||
borderColor = UIManager.getColor( "Component.borderColor" );
|
borderColor = UIManager.getColor( "Component.borderColor" );
|
||||||
disabledBorderColor = UIManager.getColor( "Component.disabledBorderColor" );
|
disabledBorderColor = UIManager.getColor( "Component.disabledBorderColor" );
|
||||||
disabledBackground = UIManager.getColor( "Spinner.disabledBackground" );
|
disabledBackground = UIManager.getColor( "Spinner.disabledBackground" );
|
||||||
@@ -146,7 +159,7 @@ public class FlatSpinnerUI
|
|||||||
handler = null;
|
handler = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Handler getHandler() {
|
private Handler getHandler() {
|
||||||
if( handler == null )
|
if( handler == null )
|
||||||
handler = new Handler();
|
handler = new Handler();
|
||||||
return handler;
|
return handler;
|
||||||
@@ -251,8 +264,10 @@ public class FlatSpinnerUI
|
|||||||
boolean isLeftToRight = spinner.getComponentOrientation().isLeftToRight();
|
boolean isLeftToRight = spinner.getComponentOrientation().isLeftToRight();
|
||||||
|
|
||||||
// paint background
|
// paint background
|
||||||
g2.setColor( enabled ? c.getBackground() : disabledBackground );
|
g2.setColor( enabled
|
||||||
FlatUIUtils.fillRoundRectangle( g2, 0, 0, width, height, focusWidth, arc );
|
? c.getBackground()
|
||||||
|
: (isIntelliJTheme ? FlatUIUtils.getParentBackground( c ) : disabledBackground) );
|
||||||
|
FlatUIUtils.paintComponentBackground( g2, 0, 0, width, height, focusWidth, arc );
|
||||||
|
|
||||||
// paint arrow buttons background
|
// paint arrow buttons background
|
||||||
if( enabled ) {
|
if( enabled ) {
|
||||||
@@ -262,7 +277,7 @@ public class FlatSpinnerUI
|
|||||||
g2.clipRect( arrowX, 0, width - arrowX, height );
|
g2.clipRect( arrowX, 0, width - arrowX, height );
|
||||||
else
|
else
|
||||||
g2.clipRect( 0, 0, arrowX + arrowWidth, height );
|
g2.clipRect( 0, 0, arrowX + arrowWidth, height );
|
||||||
FlatUIUtils.fillRoundRectangle( g2, 0, 0, width, height, focusWidth, arc );
|
FlatUIUtils.paintComponentBackground( g2, 0, 0, width, height, focusWidth, arc );
|
||||||
g2.setClip( oldClip );
|
g2.setClip( oldClip );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -270,7 +285,7 @@ public class FlatSpinnerUI
|
|||||||
g2.setColor( enabled ? borderColor : disabledBorderColor );
|
g2.setColor( enabled ? borderColor : disabledBorderColor );
|
||||||
float lw = scale( 1f );
|
float lw = scale( 1f );
|
||||||
float lx = isLeftToRight ? arrowX : arrowX + arrowWidth - lw;
|
float lx = isLeftToRight ? arrowX : arrowX + arrowWidth - lw;
|
||||||
g2.fill( new Rectangle2D.Float( lx, focusWidth, lw, height - (focusWidth * 2) ) );
|
g2.fill( new Rectangle2D.Float( lx, focusWidth, lw, height - 1 - (focusWidth * 2) ) );
|
||||||
|
|
||||||
paint( g, c );
|
paint( g, c );
|
||||||
}
|
}
|
||||||
@@ -311,6 +326,7 @@ public class FlatSpinnerUI
|
|||||||
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 arrows width is the same as the inner height so that the arrows area is square
|
||||||
|
int minimumWidth = FlatUIUtils.minimumWidth( spinner, FlatSpinnerUI.this.minimumWidth );
|
||||||
int innerHeight = editorSize.height + padding.top + padding.bottom;
|
int innerHeight = editorSize.height + padding.top + padding.bottom;
|
||||||
return new Dimension(
|
return new Dimension(
|
||||||
Math.max( insets.left + insets.right + editorSize.width + padding.left + padding.right + innerHeight, scale( minimumWidth + (focusWidth * 2) ) ),
|
Math.max( insets.left + insets.right + editorSize.width + padding.left + padding.right + innerHeight, scale( minimumWidth + (focusWidth * 2) ) ),
|
||||||
|
|||||||
@@ -31,14 +31,19 @@ import com.formdev.flatlaf.util.UIScale;
|
|||||||
/**
|
/**
|
||||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JSplitPane}.
|
* Provides the Flat LaF UI delegate for {@link javax.swing.JSplitPane}.
|
||||||
*
|
*
|
||||||
* @uiDefault Component.arrowType String triangle (default) or chevron
|
* <!-- BasicSplitPaneUI -->
|
||||||
|
*
|
||||||
* @uiDefault SplitPane.background Color
|
* @uiDefault SplitPane.background Color
|
||||||
* @uiDefault SplitPane.foreground Color unused
|
* @uiDefault SplitPane.foreground Color unused
|
||||||
* @uiDefault SplitPane.dividerSize int
|
* @uiDefault SplitPane.dividerSize int
|
||||||
* @uiDefault SplitPane.continuousLayout boolean
|
|
||||||
* @uiDefault SplitPane.border Border
|
* @uiDefault SplitPane.border Border
|
||||||
* @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
|
||||||
|
*
|
||||||
|
* <!-- FlatSplitPaneUI -->
|
||||||
|
*
|
||||||
|
* @uiDefault Component.arrowType String triangle (default) or chevron
|
||||||
|
* @uiDefault SplitPane.continuousLayout boolean
|
||||||
* @uiDefault SplitPaneDivider.oneTouchArrowColor Color
|
* @uiDefault SplitPaneDivider.oneTouchArrowColor Color
|
||||||
* @uiDefault SplitPaneDivider.oneTouchHoverArrowColor Color
|
* @uiDefault SplitPaneDivider.oneTouchHoverArrowColor Color
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -41,30 +41,47 @@ import javax.swing.plaf.UIResource;
|
|||||||
import javax.swing.plaf.basic.BasicTabbedPaneUI;
|
import javax.swing.plaf.basic.BasicTabbedPaneUI;
|
||||||
import javax.swing.text.View;
|
import javax.swing.text.View;
|
||||||
import com.formdev.flatlaf.FlatLaf;
|
import com.formdev.flatlaf.FlatLaf;
|
||||||
|
import com.formdev.flatlaf.util.UIScale;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JTabbedPane}.
|
* Provides the Flat LaF UI delegate for {@link javax.swing.JTabbedPane}.
|
||||||
*
|
*
|
||||||
|
* @clientProperty JTabbedPane.showTabSeparators boolean
|
||||||
* @clientProperty JTabbedPane.hasFullBorder boolean
|
* @clientProperty JTabbedPane.hasFullBorder boolean
|
||||||
*
|
*
|
||||||
* @uiDefault Component.arrowType String triangle (default) or chevron
|
* <!-- BasicTabbedPaneUI -->
|
||||||
|
*
|
||||||
* @uiDefault TabbedPane.font Font
|
* @uiDefault TabbedPane.font Font
|
||||||
* @uiDefault TabbedPane.background Color
|
* @uiDefault TabbedPane.background Color
|
||||||
* @uiDefault TabbedPane.foreground Color
|
* @uiDefault TabbedPane.foreground Color
|
||||||
* @uiDefault TabbedPane.shadow Color used for scroll arrows and cropped line
|
* @uiDefault TabbedPane.shadow Color used for scroll arrows and cropped line
|
||||||
|
* @uiDefault TabbedPane.textIconGap int
|
||||||
|
* @uiDefault TabbedPane.tabInsets Insets
|
||||||
|
* @uiDefault TabbedPane.selectedTabPadInsets Insets
|
||||||
|
* @uiDefault TabbedPane.tabAreaInsets Insets
|
||||||
|
* @uiDefault TabbedPane.tabsOverlapBorder boolean
|
||||||
|
* @uiDefault TabbedPane.tabRunOverlay int
|
||||||
|
* @uiDefault TabbedPane.tabsOpaque boolean
|
||||||
|
* @uiDefault TabbedPane.contentOpaque boolean unused
|
||||||
|
* @uiDefault TabbedPane.opaque boolean
|
||||||
|
* @uiDefault TabbedPane.selectionFollowsFocus boolean default is true
|
||||||
|
*
|
||||||
|
* <!-- FlatTabbedPaneUI -->
|
||||||
|
*
|
||||||
|
* @uiDefault Component.arrowType String triangle (default) or chevron
|
||||||
* @uiDefault TabbedPane.disabledForeground Color
|
* @uiDefault TabbedPane.disabledForeground Color
|
||||||
|
* @uiDefault TabbedPane.selectedBackground Color optional
|
||||||
* @uiDefault TabbedPane.selectedForeground Color
|
* @uiDefault TabbedPane.selectedForeground Color
|
||||||
* @uiDefault TabbedPane.underlineColor Color
|
* @uiDefault TabbedPane.underlineColor 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
|
||||||
|
* @uiDefault TabbedPane.tabSeparatorColor Color optional; defaults to TabbedPane.contentAreaColor
|
||||||
* @uiDefault TabbedPane.contentAreaColor Color
|
* @uiDefault TabbedPane.contentAreaColor Color
|
||||||
* @uiDefault TabbedPane.textIconGap int
|
|
||||||
* @uiDefault TabbedPane.tabInsets Insets
|
|
||||||
* @uiDefault TabbedPane.tabAreaInsets Insets
|
|
||||||
* @uiDefault TabbedPane.tabHeight int
|
* @uiDefault TabbedPane.tabHeight int
|
||||||
* @uiDefault TabbedPane.tabSelectionHeight int
|
* @uiDefault TabbedPane.tabSelectionHeight int
|
||||||
* @uiDefault TabbedPane.contentSeparatorHeight int
|
* @uiDefault TabbedPane.contentSeparatorHeight int
|
||||||
|
* @uiDefault TabbedPane.showTabSeparators boolean
|
||||||
* @uiDefault TabbedPane.hasFullBorder boolean
|
* @uiDefault TabbedPane.hasFullBorder boolean
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
@@ -73,16 +90,19 @@ public class FlatTabbedPaneUI
|
|||||||
extends BasicTabbedPaneUI
|
extends BasicTabbedPaneUI
|
||||||
{
|
{
|
||||||
protected Color disabledForeground;
|
protected Color disabledForeground;
|
||||||
|
protected Color selectedBackground;
|
||||||
protected Color selectedForeground;
|
protected Color selectedForeground;
|
||||||
protected Color underlineColor;
|
protected Color underlineColor;
|
||||||
protected Color disabledUnderlineColor;
|
protected Color disabledUnderlineColor;
|
||||||
protected Color hoverColor;
|
protected Color hoverColor;
|
||||||
protected Color focusColor;
|
protected Color focusColor;
|
||||||
|
protected Color tabSeparatorColor;
|
||||||
protected Color contentAreaColor;
|
protected Color contentAreaColor;
|
||||||
|
|
||||||
protected int tabHeight;
|
protected int tabHeight;
|
||||||
protected int tabSelectionHeight;
|
protected int tabSelectionHeight;
|
||||||
protected int contentSeparatorHeight;
|
protected int contentSeparatorHeight;
|
||||||
|
protected boolean showTabSeparators;
|
||||||
protected boolean hasFullBorder;
|
protected boolean hasFullBorder;
|
||||||
protected boolean tabsOverlapBorder;
|
protected boolean tabsOverlapBorder;
|
||||||
|
|
||||||
@@ -95,16 +115,19 @@ public class FlatTabbedPaneUI
|
|||||||
super.installDefaults();
|
super.installDefaults();
|
||||||
|
|
||||||
disabledForeground = UIManager.getColor( "TabbedPane.disabledForeground" );
|
disabledForeground = UIManager.getColor( "TabbedPane.disabledForeground" );
|
||||||
|
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" );
|
||||||
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" );
|
||||||
|
tabSeparatorColor = UIManager.getColor( "TabbedPane.tabSeparatorColor" );
|
||||||
contentAreaColor = UIManager.getColor( "TabbedPane.contentAreaColor" );
|
contentAreaColor = UIManager.getColor( "TabbedPane.contentAreaColor" );
|
||||||
|
|
||||||
tabHeight = UIManager.getInt( "TabbedPane.tabHeight" );
|
tabHeight = UIManager.getInt( "TabbedPane.tabHeight" );
|
||||||
tabSelectionHeight = UIManager.getInt( "TabbedPane.tabSelectionHeight" );
|
tabSelectionHeight = UIManager.getInt( "TabbedPane.tabSelectionHeight" );
|
||||||
contentSeparatorHeight = UIManager.getInt( "TabbedPane.contentSeparatorHeight" );
|
contentSeparatorHeight = UIManager.getInt( "TabbedPane.contentSeparatorHeight" );
|
||||||
|
showTabSeparators = UIManager.getBoolean( "TabbedPane.showTabSeparators" );
|
||||||
hasFullBorder = UIManager.getBoolean( "TabbedPane.hasFullBorder" );
|
hasFullBorder = UIManager.getBoolean( "TabbedPane.hasFullBorder" );
|
||||||
tabsOverlapBorder = UIManager.getBoolean( "TabbedPane.tabsOverlapBorder" );
|
tabsOverlapBorder = UIManager.getBoolean( "TabbedPane.tabsOverlapBorder" );
|
||||||
|
|
||||||
@@ -124,11 +147,13 @@ public class FlatTabbedPaneUI
|
|||||||
super.uninstallDefaults();
|
super.uninstallDefaults();
|
||||||
|
|
||||||
disabledForeground = null;
|
disabledForeground = null;
|
||||||
|
selectedBackground = null;
|
||||||
selectedForeground = null;
|
selectedForeground = null;
|
||||||
underlineColor = null;
|
underlineColor = null;
|
||||||
disabledUnderlineColor = null;
|
disabledUnderlineColor = null;
|
||||||
hoverColor = null;
|
hoverColor = null;
|
||||||
focusColor = null;
|
focusColor = null;
|
||||||
|
tabSeparatorColor = null;
|
||||||
contentAreaColor = null;
|
contentAreaColor = null;
|
||||||
|
|
||||||
MigLayoutVisualPadding.uninstall( tabPane );
|
MigLayoutVisualPadding.uninstall( tabPane );
|
||||||
@@ -141,9 +166,13 @@ public class FlatTabbedPaneUI
|
|||||||
public void propertyChange( PropertyChangeEvent e ) {
|
public void propertyChange( PropertyChangeEvent e ) {
|
||||||
super.propertyChange( e );
|
super.propertyChange( e );
|
||||||
|
|
||||||
if( TABBED_PANE_HAS_FULL_BORDER.equals( e.getPropertyName() ) ) {
|
switch( e.getPropertyName() ) {
|
||||||
|
case TABBED_PANE_SHOW_TAB_SEPARATORS:
|
||||||
|
case TABBED_PANE_HAS_FULL_BORDER:
|
||||||
|
case TABBED_PANE_TAB_HEIGHT:
|
||||||
tabPane.revalidate();
|
tabPane.revalidate();
|
||||||
tabPane.repaint();
|
tabPane.repaint();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -153,7 +182,7 @@ public class FlatTabbedPaneUI
|
|||||||
protected JButton createScrollButton( int direction ) {
|
protected JButton createScrollButton( int direction ) {
|
||||||
// this method is invoked before installDefaults(), so we can not use color fields here
|
// this method is invoked before installDefaults(), so we can not use color fields here
|
||||||
return new FlatArrowButton( direction, UIManager.getString( "Component.arrowType" ),
|
return new FlatArrowButton( direction, UIManager.getString( "Component.arrowType" ),
|
||||||
UIManager.getColor( "TabbedPane.shadow" ),
|
UIManager.getColor( "TabbedPane.foreground" ),
|
||||||
UIManager.getColor( "TabbedPane.disabledForeground" ), null,
|
UIManager.getColor( "TabbedPane.disabledForeground" ), null,
|
||||||
UIManager.getColor( "TabbedPane.hoverColor" ) );
|
UIManager.getColor( "TabbedPane.hoverColor" ) );
|
||||||
}
|
}
|
||||||
@@ -187,6 +216,7 @@ public class FlatTabbedPaneUI
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected int calculateTabHeight( int tabPlacement, int tabIndex, int fontHeight ) {
|
protected int calculateTabHeight( int tabPlacement, int tabIndex, int fontHeight ) {
|
||||||
|
int tabHeight = clientPropertyInt( tabPane, TABBED_PANE_TAB_HEIGHT, this.tabHeight );
|
||||||
return Math.max( tabHeight, super.calculateTabHeight( tabPlacement, tabIndex, fontHeight ) - 2 /* was added by superclass */ );
|
return Math.max( tabHeight, super.calculateTabHeight( tabPlacement, tabIndex, fontHeight ) - 2 /* was added by superclass */ );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,7 +227,7 @@ public class FlatTabbedPaneUI
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected Insets getContentBorderInsets( int tabPlacement ) {
|
protected Insets getContentBorderInsets( int tabPlacement ) {
|
||||||
boolean hasFullBorder = this.hasFullBorder || clientPropertyEquals( tabPane, TABBED_PANE_HAS_FULL_BORDER, true );
|
boolean hasFullBorder = clientPropertyBoolean( tabPane, TABBED_PANE_HAS_FULL_BORDER, this.hasFullBorder );
|
||||||
int sh = scale( contentSeparatorHeight );
|
int sh = scale( contentSeparatorHeight );
|
||||||
Insets insets = hasFullBorder ? new Insets( sh, sh, sh, sh ) : new Insets( sh, 0, 0, 0 );
|
Insets insets = hasFullBorder ? new Insets( sh, sh, sh, sh ) : new Insets( sh, 0, 0, 0 );
|
||||||
|
|
||||||
@@ -262,7 +292,9 @@ public class FlatTabbedPaneUI
|
|||||||
? hoverColor
|
? hoverColor
|
||||||
: (enabled && isSelected && tabPane.hasFocus()
|
: (enabled && isSelected && tabPane.hasFocus()
|
||||||
? focusColor
|
? focusColor
|
||||||
: tabPane.getBackgroundAt( tabIndex )) );
|
: (selectedBackground != null && enabled && isSelected
|
||||||
|
? selectedBackground
|
||||||
|
: tabPane.getBackgroundAt( tabIndex ))) );
|
||||||
g.fillRect( x, y, w, h );
|
g.fillRect( x, y, w, h );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -270,6 +302,26 @@ public class FlatTabbedPaneUI
|
|||||||
protected void paintTabBorder( Graphics g, int tabPlacement, int tabIndex,
|
protected void paintTabBorder( Graphics g, int tabPlacement, int tabIndex,
|
||||||
int x, int y, int w, int h, boolean isSelected )
|
int x, int y, int w, int h, boolean isSelected )
|
||||||
{
|
{
|
||||||
|
// paint tab separators
|
||||||
|
if( clientPropertyBoolean( tabPane, TABBED_PANE_SHOW_TAB_SEPARATORS, showTabSeparators ) &&
|
||||||
|
!isLastInRun( tabIndex ) )
|
||||||
|
{
|
||||||
|
float sepWidth = UIScale.scale( 1f );
|
||||||
|
float offset = UIScale.scale( 5f );
|
||||||
|
|
||||||
|
g.setColor( (tabSeparatorColor != null) ? tabSeparatorColor : contentAreaColor );
|
||||||
|
if( tabPlacement == LEFT || tabPlacement == RIGHT ) {
|
||||||
|
// paint tab separator at bottom side
|
||||||
|
((Graphics2D)g).fill( new Rectangle2D.Float( x + offset, y + h - sepWidth, w - (offset * 2), sepWidth ) );
|
||||||
|
} else if( tabPane.getComponentOrientation().isLeftToRight() ) {
|
||||||
|
// paint tab separator at right side
|
||||||
|
((Graphics2D)g).fill( new Rectangle2D.Float( x + w - sepWidth, y + offset, sepWidth, h - (offset * 2) ) );
|
||||||
|
} else {
|
||||||
|
// paint tab separator at left side
|
||||||
|
((Graphics2D)g).fill( new Rectangle2D.Float( x, y + offset, sepWidth, h - (offset * 2) ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if( isSelected )
|
if( isSelected )
|
||||||
paintTabSelection( g, tabPlacement, x, y, w, h );
|
paintTabSelection( g, tabPlacement, x, y, w, h );
|
||||||
}
|
}
|
||||||
@@ -334,7 +386,7 @@ public class FlatTabbedPaneUI
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Actually does the 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
|
||||||
* - not invoking paintContentBorder*Edge() methods
|
* - not invoking paintContentBorder*Edge() methods
|
||||||
* - repaint selection
|
* - repaint selection
|
||||||
@@ -379,7 +431,7 @@ public class FlatTabbedPaneUI
|
|||||||
}
|
}
|
||||||
|
|
||||||
// compute insets for separator or full border
|
// compute insets for separator or full border
|
||||||
boolean hasFullBorder = this.hasFullBorder || clientPropertyEquals( tabPane, TABBED_PANE_HAS_FULL_BORDER, true );
|
boolean hasFullBorder = clientPropertyBoolean( tabPane, TABBED_PANE_HAS_FULL_BORDER, this.hasFullBorder );
|
||||||
int sh = scale( contentSeparatorHeight * 100 ); // multiply by 100 because rotateInsets() does not use floats
|
int sh = scale( contentSeparatorHeight * 100 ); // multiply by 100 because rotateInsets() does not use floats
|
||||||
Insets ci = new Insets( 0, 0, 0, 0 );
|
Insets ci = new Insets( 0, 0, 0, 0 );
|
||||||
rotateInsets( hasFullBorder ? new Insets( sh, sh, sh, sh ) : new Insets( sh, 0, 0, 0 ), ci, tabPlacement );
|
rotateInsets( hasFullBorder ? new Insets( sh, sh, sh, sh ) : new Insets( sh, 0, 0, 0 ), ci, tabPlacement );
|
||||||
@@ -414,6 +466,11 @@ public class FlatTabbedPaneUI
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isLastInRun( int tabIndex ) {
|
||||||
|
int run = getRunForTab( tabPane.getTabCount(), tabIndex );
|
||||||
|
return lastTabInRun( tabPane.getTabCount(), run ) == tabIndex;
|
||||||
|
}
|
||||||
|
|
||||||
private boolean isScrollTabLayout() {
|
private boolean isScrollTabLayout() {
|
||||||
return tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT;
|
return tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,115 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 FormDev Software GmbH
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.formdev.flatlaf.ui;
|
||||||
|
|
||||||
|
import java.awt.Component;
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import javax.swing.JTable;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
|
import javax.swing.UIManager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cell border for {@link javax.swing.table.DefaultTableCellRenderer}
|
||||||
|
* (used by {@link javax.swing.JTable}).
|
||||||
|
* <p>
|
||||||
|
* Uses separate cell margins from UI defaults to allow easy customizing.
|
||||||
|
*
|
||||||
|
* @author Karl Tauber
|
||||||
|
*/
|
||||||
|
public class FlatTableCellBorder
|
||||||
|
extends FlatLineBorder
|
||||||
|
{
|
||||||
|
final boolean showCellFocusIndicator = UIManager.getBoolean( "Table.showCellFocusIndicator" );
|
||||||
|
|
||||||
|
protected FlatTableCellBorder() {
|
||||||
|
super( UIManager.getInsets( "Table.cellMargins" ), UIManager.getColor( "Table.cellFocusColor" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
//---- class Default ------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Border for unselected cell that uses margins, but does not paint focus indicator border.
|
||||||
|
*/
|
||||||
|
public static class Default
|
||||||
|
extends FlatTableCellBorder
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
|
||||||
|
// do not paint focus indicator border
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//---- class Focused ------------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Border for focused unselected cell that uses margins and paints focus indicator border.
|
||||||
|
*/
|
||||||
|
public static class Focused
|
||||||
|
extends FlatTableCellBorder
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
//---- class Selected -----------------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Border for selected cell that uses margins and paints focus indicator border
|
||||||
|
* if enabled (Table.showCellFocusIndicator=true) or at least one selected cell is editable.
|
||||||
|
*/
|
||||||
|
public static class Selected
|
||||||
|
extends FlatTableCellBorder
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
|
||||||
|
if( !showCellFocusIndicator ) {
|
||||||
|
JTable table = (JTable) SwingUtilities.getAncestorOfClass( JTable.class, c );
|
||||||
|
if( table != null && !isSelectionEditable( table ) )
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
super.paintBorder( c, g, x, y, width, height );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether at least one selected cell is editable.
|
||||||
|
*/
|
||||||
|
private boolean isSelectionEditable( JTable table ) {
|
||||||
|
if( table.getRowSelectionAllowed() ) {
|
||||||
|
int columnCount = table.getColumnCount();
|
||||||
|
int[] selectedRows = table.getSelectedRows();
|
||||||
|
for( int selectedRow : selectedRows ) {
|
||||||
|
for( int column = 0; column < columnCount; column++ ) {
|
||||||
|
if( table.isCellEditable( selectedRow, column ) )
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( table.getColumnSelectionAllowed() ) {
|
||||||
|
int rowCount = table.getRowCount();
|
||||||
|
int[] selectedColumns = table.getSelectedColumns();
|
||||||
|
for( int selectedColumn : selectedColumns ) {
|
||||||
|
for( int row = 0; row < rowCount; row++ ) {
|
||||||
|
if( table.isCellEditable( row, selectedColumn ) )
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,6 +17,7 @@
|
|||||||
package com.formdev.flatlaf.ui;
|
package com.formdev.flatlaf.ui;
|
||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
|
import java.awt.Component;
|
||||||
import java.awt.Container;
|
import java.awt.Container;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
@@ -29,6 +30,7 @@ import javax.swing.JTable;
|
|||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
import javax.swing.plaf.basic.BasicTableHeaderUI;
|
import javax.swing.plaf.basic.BasicTableHeaderUI;
|
||||||
|
import javax.swing.table.TableCellRenderer;
|
||||||
import javax.swing.table.TableColumn;
|
import javax.swing.table.TableColumn;
|
||||||
import javax.swing.table.TableColumnModel;
|
import javax.swing.table.TableColumnModel;
|
||||||
import com.formdev.flatlaf.util.UIScale;
|
import com.formdev.flatlaf.util.UIScale;
|
||||||
@@ -36,7 +38,13 @@ import com.formdev.flatlaf.util.UIScale;
|
|||||||
/**
|
/**
|
||||||
* Provides the Flat LaF UI delegate for {@link javax.swing.table.JTableHeader}.
|
* Provides the Flat LaF UI delegate for {@link javax.swing.table.JTableHeader}.
|
||||||
*
|
*
|
||||||
* TODO document used UI defaults of superclass
|
* <!-- BasicTableHeaderUI -->
|
||||||
|
*
|
||||||
|
* @uiDefault TableHeader.font Font
|
||||||
|
* @uiDefault TableHeader.background Color
|
||||||
|
* @uiDefault TableHeader.foreground Color
|
||||||
|
*
|
||||||
|
* <!-- FlatTableHeaderUI -->
|
||||||
*
|
*
|
||||||
* @uiDefault TableHeader.separatorColor Color
|
* @uiDefault TableHeader.separatorColor Color
|
||||||
* @uiDefault TableHeader.bottomSeparatorColor Color
|
* @uiDefault TableHeader.bottomSeparatorColor Color
|
||||||
@@ -75,8 +83,14 @@ public class FlatTableHeaderUI
|
|||||||
@Override
|
@Override
|
||||||
public void paint( Graphics g, JComponent c ) {
|
public void paint( Graphics g, JComponent c ) {
|
||||||
// do not paint borders if JTableHeader.setDefaultRenderer() was used
|
// do not paint borders if JTableHeader.setDefaultRenderer() was used
|
||||||
boolean paintBorders = header.getDefaultRenderer().getClass().getName().equals(
|
TableCellRenderer defaultRenderer = header.getDefaultRenderer();
|
||||||
"sun.swing.table.DefaultTableCellHeaderRenderer" );
|
boolean paintBorders = isSystemDefaultRenderer( defaultRenderer );
|
||||||
|
if( !paintBorders && header.getColumnModel().getColumnCount() > 0 ) {
|
||||||
|
// check whether the renderer delegates to the system default renderer
|
||||||
|
Component rendererComponent = defaultRenderer.getTableCellRendererComponent(
|
||||||
|
header.getTable(), "", false, false, -1, 0 );
|
||||||
|
paintBorders = isSystemDefaultRenderer( rendererComponent );
|
||||||
|
}
|
||||||
|
|
||||||
if( paintBorders )
|
if( paintBorders )
|
||||||
paintColumnBorders( g, c );
|
paintColumnBorders( g, c );
|
||||||
@@ -87,6 +101,12 @@ public class FlatTableHeaderUI
|
|||||||
paintDraggedColumnBorders( g, c );
|
paintDraggedColumnBorders( g, c );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isSystemDefaultRenderer( Object headerRenderer ) {
|
||||||
|
String rendererClassName = headerRenderer.getClass().getName();
|
||||||
|
return rendererClassName.equals( "sun.swing.table.DefaultTableCellHeaderRenderer" ) ||
|
||||||
|
rendererClassName.equals( "sun.swing.FilePane$AlignableTableHeaderRenderer" );
|
||||||
|
}
|
||||||
|
|
||||||
private void paintColumnBorders( Graphics g, JComponent c ) {
|
private void paintColumnBorders( Graphics g, JComponent c ) {
|
||||||
int width = c.getWidth();
|
int width = c.getWidth();
|
||||||
int height = c.getHeight();
|
int height = c.getHeight();
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
package com.formdev.flatlaf.ui;
|
package com.formdev.flatlaf.ui;
|
||||||
|
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
|
import java.awt.Dimension;
|
||||||
import java.awt.event.FocusEvent;
|
import java.awt.event.FocusEvent;
|
||||||
import java.awt.event.FocusListener;
|
import java.awt.event.FocusListener;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
@@ -29,30 +30,84 @@ import com.formdev.flatlaf.util.UIScale;
|
|||||||
/**
|
/**
|
||||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JTable}.
|
* Provides the Flat LaF UI delegate for {@link javax.swing.JTable}.
|
||||||
*
|
*
|
||||||
* TODO document used UI defaults of superclass
|
* <!-- BasicTableUI -->
|
||||||
|
*
|
||||||
|
* @uiDefault Table.font Font
|
||||||
|
* @uiDefault Table.background Color
|
||||||
|
* @uiDefault Table.foreground Color
|
||||||
|
* @uiDefault Table.selectionBackground Color
|
||||||
|
* @uiDefault Table.selectionForeground Color
|
||||||
|
* @uiDefault Table.gridColor Color
|
||||||
|
* @uiDefault Table.scrollPaneBorder Border
|
||||||
|
* @uiDefault Table.dropLineColor Color
|
||||||
|
* @uiDefault Table.dropLineShortColor Color
|
||||||
|
*
|
||||||
|
* <!-- DefaultTableCellRenderer -->
|
||||||
|
*
|
||||||
|
* @uiDefault Table.cellNoFocusBorder Border
|
||||||
|
* @uiDefault Table.focusCellHighlightBorder Border
|
||||||
|
* @uiDefault Table.focusSelectedCellHighlightBorder Border
|
||||||
|
* @uiDefault Table.dropCellBackground Color
|
||||||
|
* @uiDefault Table.dropCellForeground Color
|
||||||
|
* @uiDefault Table.alternateRowColor Color
|
||||||
|
* @uiDefault Table.focusCellBackground Color
|
||||||
|
* @uiDefault Table.focusCellForeground Color
|
||||||
|
*
|
||||||
|
* <!-- FlatTableUI -->
|
||||||
*
|
*
|
||||||
* @uiDefault Table.rowHeight int
|
* @uiDefault Table.rowHeight int
|
||||||
|
* @uiDefault Table.showHorizontalLines boolean
|
||||||
|
* @uiDefault Table.showVerticalLines boolean
|
||||||
|
* @uiDefault Table.intercellSpacing Dimension
|
||||||
* @uiDefault Table.selectionInactiveBackground Color
|
* @uiDefault Table.selectionInactiveBackground Color
|
||||||
* @uiDefault Table.selectionInactiveForeground Color
|
* @uiDefault Table.selectionInactiveForeground Color
|
||||||
*
|
*
|
||||||
|
* <!-- FlatTableCellBorder -->
|
||||||
|
*
|
||||||
|
* @uiDefault Table.cellMargins Insets
|
||||||
|
* @uiDefault Table.cellFocusColor Color
|
||||||
|
* @uiDefault Table.showCellFocusIndicator boolean
|
||||||
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
public class FlatTableUI
|
public class FlatTableUI
|
||||||
extends BasicTableUI
|
extends BasicTableUI
|
||||||
{
|
{
|
||||||
|
protected boolean showHorizontalLines;
|
||||||
|
protected boolean showVerticalLines;
|
||||||
|
protected Dimension intercellSpacing;
|
||||||
|
|
||||||
protected Color selectionBackground;
|
protected Color selectionBackground;
|
||||||
protected Color selectionForeground;
|
protected Color selectionForeground;
|
||||||
protected Color selectionInactiveBackground;
|
protected Color selectionInactiveBackground;
|
||||||
protected Color selectionInactiveForeground;
|
protected Color selectionInactiveForeground;
|
||||||
|
|
||||||
|
private boolean oldShowHorizontalLines;
|
||||||
|
private boolean oldShowVerticalLines;
|
||||||
|
private Dimension oldIntercellSpacing;
|
||||||
|
|
||||||
public static ComponentUI createUI( JComponent c ) {
|
public static ComponentUI createUI( JComponent c ) {
|
||||||
return new FlatTableUI();
|
return new FlatTableUI();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void installUI( JComponent c ) {
|
||||||
|
super.installUI( c );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void uninstallUI( JComponent c ) {
|
||||||
|
super.uninstallUI( c );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void installDefaults() {
|
protected void installDefaults() {
|
||||||
super.installDefaults();
|
super.installDefaults();
|
||||||
|
|
||||||
|
showHorizontalLines = UIManager.getBoolean( "Table.showHorizontalLines" );
|
||||||
|
showVerticalLines = UIManager.getBoolean( "Table.showVerticalLines" );
|
||||||
|
intercellSpacing = UIManager.getDimension( "Table.intercellSpacing" );
|
||||||
|
|
||||||
selectionBackground = UIManager.getColor( "Table.selectionBackground" );
|
selectionBackground = UIManager.getColor( "Table.selectionBackground" );
|
||||||
selectionForeground = UIManager.getColor( "Table.selectionForeground" );
|
selectionForeground = UIManager.getColor( "Table.selectionForeground" );
|
||||||
selectionInactiveBackground = UIManager.getColor( "Table.selectionInactiveBackground" );
|
selectionInactiveBackground = UIManager.getColor( "Table.selectionInactiveBackground" );
|
||||||
@@ -63,6 +118,20 @@ public class FlatTableUI
|
|||||||
int rowHeight = FlatUIUtils.getUIInt( "Table.rowHeight", 16 );
|
int rowHeight = FlatUIUtils.getUIInt( "Table.rowHeight", 16 );
|
||||||
if( rowHeight > 0 )
|
if( rowHeight > 0 )
|
||||||
LookAndFeel.installProperty( table, "rowHeight", UIScale.scale( rowHeight ) );
|
LookAndFeel.installProperty( table, "rowHeight", UIScale.scale( rowHeight ) );
|
||||||
|
|
||||||
|
if( !showHorizontalLines ) {
|
||||||
|
oldShowHorizontalLines = table.getShowHorizontalLines();
|
||||||
|
table.setShowHorizontalLines( false );
|
||||||
|
}
|
||||||
|
if( !showVerticalLines ) {
|
||||||
|
oldShowVerticalLines = table.getShowVerticalLines();
|
||||||
|
table.setShowVerticalLines( false );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( intercellSpacing != null ) {
|
||||||
|
oldIntercellSpacing = table.getIntercellSpacing();
|
||||||
|
table.setIntercellSpacing( intercellSpacing );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -73,6 +142,16 @@ public class FlatTableUI
|
|||||||
selectionForeground = null;
|
selectionForeground = null;
|
||||||
selectionInactiveBackground = null;
|
selectionInactiveBackground = null;
|
||||||
selectionInactiveForeground = null;
|
selectionInactiveForeground = null;
|
||||||
|
|
||||||
|
// restore old show horizontal/vertical lines (if not modified)
|
||||||
|
if( !showHorizontalLines && oldShowHorizontalLines && !table.getShowHorizontalLines() )
|
||||||
|
table.setShowHorizontalLines( true );
|
||||||
|
if( !showVerticalLines && oldShowVerticalLines && !table.getShowVerticalLines() )
|
||||||
|
table.setShowVerticalLines( true );
|
||||||
|
|
||||||
|
// restore old intercell spacing (if not modified)
|
||||||
|
if( intercellSpacing != null && table.getIntercellSpacing().equals( intercellSpacing ) )
|
||||||
|
table.setIntercellSpacing( oldIntercellSpacing );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -31,11 +31,25 @@ import javax.swing.text.JTextComponent;
|
|||||||
/**
|
/**
|
||||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JTextArea}.
|
* Provides the Flat LaF UI delegate for {@link javax.swing.JTextArea}.
|
||||||
*
|
*
|
||||||
* TODO document used UI defaults of superclass
|
* <!-- BasicTextAreaUI -->
|
||||||
|
*
|
||||||
|
* @uiDefault TextArea.font Font
|
||||||
|
* @uiDefault TextArea.background Color
|
||||||
|
* @uiDefault TextArea.foreground Color also used if not editable
|
||||||
|
* @uiDefault TextArea.caretForeground Color
|
||||||
|
* @uiDefault TextArea.selectionBackground Color
|
||||||
|
* @uiDefault TextArea.selectionForeground Color
|
||||||
|
* @uiDefault TextArea.inactiveForeground Color used if not enabled (yes, this is confusing; this should be named disabledForeground)
|
||||||
|
* @uiDefault TextArea.border Border
|
||||||
|
* @uiDefault TextArea.margin Insets
|
||||||
|
* @uiDefault TextArea.caretBlinkRate int default is 500 milliseconds
|
||||||
|
*
|
||||||
|
* <!-- FlatTextAreaUI -->
|
||||||
*
|
*
|
||||||
* @uiDefault Component.minimumWidth int
|
* @uiDefault Component.minimumWidth int
|
||||||
* @uiDefault TextArea.disabledBackground Color
|
* @uiDefault Component.isIntelliJTheme boolean
|
||||||
* @uiDefault TextArea.inactiveBackground Color
|
* @uiDefault TextArea.disabledBackground Color used if not enabled
|
||||||
|
* @uiDefault TextArea.inactiveBackground Color used if not editable
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
@@ -43,6 +57,7 @@ public class FlatTextAreaUI
|
|||||||
extends BasicTextAreaUI
|
extends BasicTextAreaUI
|
||||||
{
|
{
|
||||||
protected int minimumWidth;
|
protected int minimumWidth;
|
||||||
|
protected boolean isIntelliJTheme;
|
||||||
protected Color disabledBackground;
|
protected Color disabledBackground;
|
||||||
protected Color inactiveBackground;
|
protected Color inactiveBackground;
|
||||||
|
|
||||||
@@ -55,6 +70,7 @@ public class FlatTextAreaUI
|
|||||||
super.installDefaults();
|
super.installDefaults();
|
||||||
|
|
||||||
minimumWidth = UIManager.getInt( "Component.minimumWidth" );
|
minimumWidth = UIManager.getInt( "Component.minimumWidth" );
|
||||||
|
isIntelliJTheme = UIManager.getBoolean( "Component.isIntelliJTheme" );
|
||||||
disabledBackground = UIManager.getColor( "TextArea.disabledBackground" );
|
disabledBackground = UIManager.getColor( "TextArea.disabledBackground" );
|
||||||
inactiveBackground = UIManager.getColor( "TextArea.inactiveBackground" );
|
inactiveBackground = UIManager.getColor( "TextArea.inactiveBackground" );
|
||||||
}
|
}
|
||||||
@@ -74,9 +90,11 @@ public class FlatTextAreaUI
|
|||||||
Color background = c.getBackground();
|
Color background = c.getBackground();
|
||||||
g.setColor( !(background instanceof UIResource)
|
g.setColor( !(background instanceof UIResource)
|
||||||
? background
|
? background
|
||||||
|
: (isIntelliJTheme && (!c.isEnabled() || !c.isEditable())
|
||||||
|
? FlatUIUtils.getParentBackground( c )
|
||||||
: (!c.isEnabled()
|
: (!c.isEnabled()
|
||||||
? disabledBackground
|
? disabledBackground
|
||||||
: (!c.isEditable() ? inactiveBackground : background)) );
|
: (!c.isEditable() ? inactiveBackground : background))) );
|
||||||
g.fillRect( 0, 0, c.getWidth(), c.getHeight() );
|
g.fillRect( 0, 0, c.getWidth(), c.getHeight() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,6 +117,7 @@ public class FlatTextAreaUI
|
|||||||
// and subtract 1px border line width.
|
// and subtract 1px border line width.
|
||||||
// Using "(scale( 1 ) * 2)" instead of "scale( 2 )" to deal with rounding
|
// Using "(scale( 1 ) * 2)" instead of "scale( 2 )" to deal with rounding
|
||||||
// issues. E.g. at scale factor 1.5 the first returns 4, but the second 3.
|
// issues. E.g. at scale factor 1.5 the first returns 4, but the second 3.
|
||||||
|
int minimumWidth = FlatUIUtils.minimumWidth( getComponent(), this.minimumWidth );
|
||||||
size.width = Math.max( size.width, scale( minimumWidth ) - (scale( 1 ) * 2) );
|
size.width = Math.max( size.width, scale( minimumWidth ) - (scale( 1 ) * 2) );
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,11 +17,15 @@
|
|||||||
package com.formdev.flatlaf.ui;
|
package com.formdev.flatlaf.ui;
|
||||||
|
|
||||||
import static com.formdev.flatlaf.util.UIScale.scale;
|
import static com.formdev.flatlaf.util.UIScale.scale;
|
||||||
|
import java.awt.Color;
|
||||||
import java.awt.Container;
|
import java.awt.Container;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
|
import java.awt.FontMetrics;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.Insets;
|
||||||
import java.awt.event.FocusListener;
|
import java.awt.event.FocusListener;
|
||||||
|
import java.beans.PropertyChangeEvent;
|
||||||
import javax.swing.JComboBox;
|
import javax.swing.JComboBox;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
import javax.swing.JSpinner;
|
import javax.swing.JSpinner;
|
||||||
@@ -29,16 +33,35 @@ import javax.swing.JTextField;
|
|||||||
import javax.swing.LookAndFeel;
|
import javax.swing.LookAndFeel;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
|
import javax.swing.plaf.UIResource;
|
||||||
import javax.swing.plaf.basic.BasicTextFieldUI;
|
import javax.swing.plaf.basic.BasicTextFieldUI;
|
||||||
import javax.swing.text.JTextComponent;
|
import javax.swing.text.JTextComponent;
|
||||||
|
import com.formdev.flatlaf.FlatClientProperties;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JTextField}.
|
* Provides the Flat LaF UI delegate for {@link javax.swing.JTextField}.
|
||||||
*
|
*
|
||||||
* TODO document used UI defaults of superclass
|
* <!-- BasicTextFieldUI -->
|
||||||
|
*
|
||||||
|
* @uiDefault TextField.font Font
|
||||||
|
* @uiDefault TextField.background Color
|
||||||
|
* @uiDefault TextField.foreground Color also used if not editable
|
||||||
|
* @uiDefault TextField.caretForeground Color
|
||||||
|
* @uiDefault TextField.selectionBackground Color
|
||||||
|
* @uiDefault TextField.selectionForeground Color
|
||||||
|
* @uiDefault TextField.disabledBackground Color used if not enabled
|
||||||
|
* @uiDefault TextField.inactiveBackground Color used if not editable
|
||||||
|
* @uiDefault TextField.inactiveForeground Color used if not enabled (yes, this is confusing; this should be named disabledForeground)
|
||||||
|
* @uiDefault TextField.border Border
|
||||||
|
* @uiDefault TextField.margin Insets
|
||||||
|
* @uiDefault TextField.caretBlinkRate int default is 500 milliseconds
|
||||||
|
*
|
||||||
|
* <!-- FlatTextFieldUI -->
|
||||||
*
|
*
|
||||||
* @uiDefault Component.focusWidth int
|
* @uiDefault Component.focusWidth int
|
||||||
* @uiDefault Component.minimumWidth int
|
* @uiDefault Component.minimumWidth int
|
||||||
|
* @uiDefault Component.isIntelliJTheme boolean
|
||||||
|
* @uiDefault TextField.placeholderForeground Color
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
@@ -47,6 +70,8 @@ public class FlatTextFieldUI
|
|||||||
{
|
{
|
||||||
protected int focusWidth;
|
protected int focusWidth;
|
||||||
protected int minimumWidth;
|
protected int minimumWidth;
|
||||||
|
protected boolean isIntelliJTheme;
|
||||||
|
protected Color placeholderForeground;
|
||||||
|
|
||||||
private FocusListener focusListener;
|
private FocusListener focusListener;
|
||||||
|
|
||||||
@@ -58,8 +83,11 @@ public class FlatTextFieldUI
|
|||||||
protected void installDefaults() {
|
protected void installDefaults() {
|
||||||
super.installDefaults();
|
super.installDefaults();
|
||||||
|
|
||||||
|
String prefix = getPropertyPrefix();
|
||||||
focusWidth = UIManager.getInt( "Component.focusWidth" );
|
focusWidth = UIManager.getInt( "Component.focusWidth" );
|
||||||
minimumWidth = UIManager.getInt( "Component.minimumWidth" );
|
minimumWidth = UIManager.getInt( "Component.minimumWidth" );
|
||||||
|
isIntelliJTheme = UIManager.getBoolean( "Component.isIntelliJTheme" );
|
||||||
|
placeholderForeground = UIManager.getColor( prefix + ".placeholderForeground" );
|
||||||
|
|
||||||
LookAndFeel.installProperty( getComponent(), "opaque", focusWidth == 0 );
|
LookAndFeel.installProperty( getComponent(), "opaque", focusWidth == 0 );
|
||||||
|
|
||||||
@@ -70,6 +98,8 @@ public class FlatTextFieldUI
|
|||||||
protected void uninstallDefaults() {
|
protected void uninstallDefaults() {
|
||||||
super.uninstallDefaults();
|
super.uninstallDefaults();
|
||||||
|
|
||||||
|
placeholderForeground = null;
|
||||||
|
|
||||||
MigLayoutVisualPadding.uninstall( getComponent() );
|
MigLayoutVisualPadding.uninstall( getComponent() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,9 +119,18 @@ public class FlatTextFieldUI
|
|||||||
focusListener = null;
|
focusListener = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void propertyChange( PropertyChangeEvent e ) {
|
||||||
|
super.propertyChange( e );
|
||||||
|
|
||||||
|
if( FlatClientProperties.PLACEHOLDER_TEXT.equals( e.getPropertyName() ) )
|
||||||
|
getComponent().repaint();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void paintSafely( Graphics g ) {
|
protected void paintSafely( Graphics g ) {
|
||||||
paintBackground( g, getComponent(), focusWidth );
|
paintBackground( g, getComponent(), focusWidth, isIntelliJTheme );
|
||||||
|
paintPlaceholder( g, getComponent(), placeholderForeground );
|
||||||
super.paintSafely( g );
|
super.paintSafely( g );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,7 +139,7 @@ public class FlatTextFieldUI
|
|||||||
// background is painted elsewhere
|
// background is painted elsewhere
|
||||||
}
|
}
|
||||||
|
|
||||||
static void paintBackground( Graphics g, JTextComponent c, int focusWidth ) {
|
static void paintBackground( Graphics g, JTextComponent c, int focusWidth, boolean isIntelliJTheme ) {
|
||||||
// do not paint background if:
|
// do not paint background if:
|
||||||
// - not opaque and
|
// - not opaque and
|
||||||
// - border is not a flat border and
|
// - border is not a flat border and
|
||||||
@@ -120,13 +159,43 @@ public class FlatTextFieldUI
|
|||||||
|
|
||||||
float fFocusWidth = (c.getBorder() instanceof FlatBorder) ? scale( (float) focusWidth ) : 0;
|
float fFocusWidth = (c.getBorder() instanceof FlatBorder) ? scale( (float) focusWidth ) : 0;
|
||||||
|
|
||||||
g2.setColor( c.getBackground() );
|
Color background = c.getBackground();
|
||||||
FlatUIUtils.fillRoundRectangle( g2, 0, 0, c.getWidth(), c.getHeight(), fFocusWidth, 0 );
|
g2.setColor( !(background instanceof UIResource)
|
||||||
|
? background
|
||||||
|
: (isIntelliJTheme && (!c.isEnabled() || !c.isEditable())
|
||||||
|
? FlatUIUtils.getParentBackground( c )
|
||||||
|
: background) );
|
||||||
|
FlatUIUtils.paintComponentBackground( g2, 0, 0, c.getWidth(), c.getHeight(), fFocusWidth, 0 );
|
||||||
} finally {
|
} finally {
|
||||||
g2.dispose();
|
g2.dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void paintPlaceholder( Graphics g, JTextComponent c, Color placeholderForeground ) {
|
||||||
|
// check whether text component is empty
|
||||||
|
if( c.getDocument().getLength() > 0 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// check for JComboBox
|
||||||
|
Container parent = c.getParent();
|
||||||
|
JComponent jc = (parent instanceof JComboBox) ? (JComboBox<?>) parent : c;
|
||||||
|
|
||||||
|
// get placeholder text
|
||||||
|
Object placeholder = jc.getClientProperty( FlatClientProperties.PLACEHOLDER_TEXT );
|
||||||
|
if( !(placeholder instanceof String) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
// compute placeholder location
|
||||||
|
Insets insets = c.getInsets();
|
||||||
|
FontMetrics fm = c.getFontMetrics( c.getFont() );
|
||||||
|
int x = insets.left;
|
||||||
|
int y = insets.top + fm.getAscent() + ((c.getHeight() - insets.top - insets.bottom - fm.getHeight()) / 2);
|
||||||
|
|
||||||
|
// paint placeholder
|
||||||
|
g.setColor( placeholderForeground );
|
||||||
|
FlatUIUtils.drawString( c, g, (String) placeholder, x, y );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Dimension getPreferredSize( JComponent c ) {
|
public Dimension getPreferredSize( JComponent c ) {
|
||||||
return applyMinimumWidth( super.getPreferredSize( c ), c );
|
return applyMinimumWidth( super.getPreferredSize( c ), c );
|
||||||
@@ -148,6 +217,7 @@ public class FlatTextFieldUI
|
|||||||
(parent != null && parent.getParent() instanceof JSpinner) )
|
(parent != null && parent.getParent() instanceof JSpinner) )
|
||||||
return size;
|
return size;
|
||||||
|
|
||||||
|
int minimumWidth = FlatUIUtils.minimumWidth( getComponent(), this.minimumWidth );
|
||||||
int focusWidth = (c.getBorder() instanceof FlatBorder) ? this.focusWidth : 0;
|
int focusWidth = (c.getBorder() instanceof FlatBorder) ? this.focusWidth : 0;
|
||||||
size.width = Math.max( size.width, scale( minimumWidth + (focusWidth * 2) ) );
|
size.width = Math.max( size.width, scale( minimumWidth + (focusWidth * 2) ) );
|
||||||
return size;
|
return size;
|
||||||
|
|||||||
@@ -18,18 +18,37 @@ package com.formdev.flatlaf.ui;
|
|||||||
|
|
||||||
import static com.formdev.flatlaf.util.UIScale.scale;
|
import static com.formdev.flatlaf.util.UIScale.scale;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
|
import java.awt.Graphics;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
import javax.swing.JEditorPane;
|
import javax.swing.JEditorPane;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
|
import javax.swing.plaf.UIResource;
|
||||||
import javax.swing.plaf.basic.BasicTextPaneUI;
|
import javax.swing.plaf.basic.BasicTextPaneUI;
|
||||||
|
import javax.swing.text.JTextComponent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JTextPane}.
|
* Provides the Flat LaF UI delegate for {@link javax.swing.JTextPane}.
|
||||||
*
|
*
|
||||||
* TODO document used UI defaults of superclass
|
* <!-- BasicTextPaneUI -->
|
||||||
|
*
|
||||||
|
* @uiDefault TextPane.font Font
|
||||||
|
* @uiDefault TextPane.background Color
|
||||||
|
* @uiDefault TextPane.foreground Color also used if not editable
|
||||||
|
* @uiDefault TextPane.caretForeground Color
|
||||||
|
* @uiDefault TextPane.selectionBackground Color
|
||||||
|
* @uiDefault TextPane.selectionForeground Color
|
||||||
|
* @uiDefault TextPane.disabledBackground Color used if not enabled
|
||||||
|
* @uiDefault TextPane.inactiveBackground Color used if not editable
|
||||||
|
* @uiDefault TextPane.inactiveForeground Color used if not enabled (yes, this is confusing; this should be named disabledForeground)
|
||||||
|
* @uiDefault TextPane.border Border
|
||||||
|
* @uiDefault TextPane.margin Insets
|
||||||
|
* @uiDefault TextPane.caretBlinkRate int default is 500 milliseconds
|
||||||
|
*
|
||||||
|
* <!-- FlatTextPaneUI -->
|
||||||
*
|
*
|
||||||
* @uiDefault Component.minimumWidth int
|
* @uiDefault Component.minimumWidth int
|
||||||
|
* @uiDefault Component.isIntelliJTheme boolean
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
@@ -37,6 +56,7 @@ public class FlatTextPaneUI
|
|||||||
extends BasicTextPaneUI
|
extends BasicTextPaneUI
|
||||||
{
|
{
|
||||||
protected int minimumWidth;
|
protected int minimumWidth;
|
||||||
|
protected boolean isIntelliJTheme;
|
||||||
|
|
||||||
private Object oldHonorDisplayProperties;
|
private Object oldHonorDisplayProperties;
|
||||||
|
|
||||||
@@ -49,6 +69,7 @@ public class FlatTextPaneUI
|
|||||||
super.installDefaults();
|
super.installDefaults();
|
||||||
|
|
||||||
minimumWidth = UIManager.getInt( "Component.minimumWidth" );
|
minimumWidth = UIManager.getInt( "Component.minimumWidth" );
|
||||||
|
isIntelliJTheme = UIManager.getBoolean( "Component.isIntelliJTheme" );
|
||||||
|
|
||||||
// use component font and foreground for HTML text
|
// use component font and foreground for HTML text
|
||||||
oldHonorDisplayProperties = getComponent().getClientProperty( JEditorPane.HONOR_DISPLAY_PROPERTIES );
|
oldHonorDisplayProperties = getComponent().getClientProperty( JEditorPane.HONOR_DISPLAY_PROPERTIES );
|
||||||
@@ -77,7 +98,21 @@ public class FlatTextPaneUI
|
|||||||
// and subtract 1px border line width.
|
// and subtract 1px border line width.
|
||||||
// Using "(scale( 1 ) * 2)" instead of "scale( 2 )" to deal with rounding
|
// Using "(scale( 1 ) * 2)" instead of "scale( 2 )" to deal with rounding
|
||||||
// issues. E.g. at scale factor 1.5 the first returns 4, but the second 3.
|
// issues. E.g. at scale factor 1.5 the first returns 4, but the second 3.
|
||||||
|
int minimumWidth = FlatUIUtils.minimumWidth( getComponent(), this.minimumWidth );
|
||||||
size.width = Math.max( size.width, scale( minimumWidth ) - (scale( 1 ) * 2) );
|
size.width = Math.max( size.width, scale( minimumWidth ) - (scale( 1 ) * 2) );
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void paintBackground( Graphics g ) {
|
||||||
|
JTextComponent c = getComponent();
|
||||||
|
|
||||||
|
// for compatibility with IntelliJ themes
|
||||||
|
if( isIntelliJTheme && (!c.isEnabled() || !c.isEditable()) && (c.getBackground() instanceof UIResource) ) {
|
||||||
|
FlatUIUtils.paintParentBackground( g, c );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
super.paintBackground( g );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,29 +16,58 @@
|
|||||||
|
|
||||||
package com.formdev.flatlaf.ui;
|
package com.formdev.flatlaf.ui;
|
||||||
|
|
||||||
|
import static com.formdev.flatlaf.FlatClientProperties.*;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
|
import java.awt.Component;
|
||||||
|
import java.awt.Graphics;
|
||||||
|
import java.beans.PropertyChangeEvent;
|
||||||
import javax.swing.AbstractButton;
|
import javax.swing.AbstractButton;
|
||||||
import javax.swing.ButtonModel;
|
import javax.swing.ButtonModel;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
|
import javax.swing.JToggleButton;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
|
import com.formdev.flatlaf.util.UIScale;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JToggleButton}.
|
* Provides the Flat LaF UI delegate for {@link javax.swing.JToggleButton}.
|
||||||
*
|
*
|
||||||
* TODO document used UI defaults of superclass
|
* <!-- BasicButtonUI -->
|
||||||
|
*
|
||||||
|
* @uiDefault ToggleButton.font Font
|
||||||
|
* @uiDefault ToggleButton.background Color
|
||||||
|
* @uiDefault ToggleButton.foreground Color
|
||||||
|
* @uiDefault ToggleButton.border Border
|
||||||
|
* @uiDefault ToggleButton.margin Insets
|
||||||
|
* @uiDefault ToggleButton.rollover boolean
|
||||||
|
*
|
||||||
|
* <!-- FlatButtonUI -->
|
||||||
*
|
*
|
||||||
* @uiDefault Component.focusWidth int
|
* @uiDefault Component.focusWidth int
|
||||||
* @uiDefault ToggleButton.arc int
|
* @uiDefault Button.arc int
|
||||||
|
* @uiDefault ToggleButton.minimumWidth int
|
||||||
|
* @uiDefault ToggleButton.iconTextGap int
|
||||||
|
* @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.pressedBackground Color
|
* @uiDefault ToggleButton.pressedBackground Color
|
||||||
* @uiDefault ToggleButton.disabledText Color
|
* @uiDefault ToggleButton.disabledText Color
|
||||||
|
* @uiDefault ToggleButton.toolbar.hoverBackground Color
|
||||||
|
* @uiDefault ToggleButton.toolbar.pressedBackground Color
|
||||||
|
*
|
||||||
|
* <!-- FlatToggleButtonUI -->
|
||||||
|
*
|
||||||
* @uiDefault ToggleButton.selectedBackground Color
|
* @uiDefault ToggleButton.selectedBackground Color
|
||||||
* @uiDefault ToggleButton.selectedForeground Color
|
* @uiDefault ToggleButton.selectedForeground Color
|
||||||
* @uiDefault ToggleButton.disabledSelectedBackground Color
|
* @uiDefault ToggleButton.disabledSelectedBackground Color
|
||||||
* @uiDefault ToggleButton.toolbar.hoverBackground Color
|
|
||||||
* @uiDefault ToggleButton.toolbar.pressedBackground Color
|
|
||||||
* @uiDefault ToggleButton.toolbar.selectedBackground Color
|
* @uiDefault ToggleButton.toolbar.selectedBackground Color
|
||||||
*
|
*
|
||||||
|
* @uiDefault ToggleButton.tab.underlineHeight int
|
||||||
|
* @uiDefault ToggleButton.tab.underlineColor Color
|
||||||
|
* @uiDefault ToggleButton.tab.disabledUnderlineColor Color
|
||||||
|
* @uiDefault ToggleButton.tab.selectedBackground Color optional
|
||||||
|
* @uiDefault ToggleButton.tab.hoverBackground Color
|
||||||
|
* @uiDefault ToggleButton.tab.focusBackground Color
|
||||||
|
*
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
@@ -51,6 +80,13 @@ public class FlatToggleButtonUI
|
|||||||
|
|
||||||
protected Color toolbarSelectedBackground;
|
protected Color toolbarSelectedBackground;
|
||||||
|
|
||||||
|
protected int tabUnderlineHeight;
|
||||||
|
protected Color tabUnderlineColor;
|
||||||
|
protected Color tabDisabledUnderlineColor;
|
||||||
|
protected Color tabSelectedBackground;
|
||||||
|
protected Color tabHoverBackground;
|
||||||
|
protected Color tabFocusBackground;
|
||||||
|
|
||||||
private boolean defaults_initialized = false;
|
private boolean defaults_initialized = false;
|
||||||
|
|
||||||
private static ComponentUI instance;
|
private static ComponentUI instance;
|
||||||
@@ -77,6 +113,13 @@ public class FlatToggleButtonUI
|
|||||||
|
|
||||||
toolbarSelectedBackground = UIManager.getColor( "ToggleButton.toolbar.selectedBackground" );
|
toolbarSelectedBackground = UIManager.getColor( "ToggleButton.toolbar.selectedBackground" );
|
||||||
|
|
||||||
|
tabUnderlineHeight = UIManager.getInt( "ToggleButton.tab.underlineHeight" );
|
||||||
|
tabUnderlineColor = UIManager.getColor( "ToggleButton.tab.underlineColor" );
|
||||||
|
tabDisabledUnderlineColor = UIManager.getColor( "ToggleButton.tab.disabledUnderlineColor" );
|
||||||
|
tabSelectedBackground = UIManager.getColor( "ToggleButton.tab.selectedBackground" );
|
||||||
|
tabHoverBackground = UIManager.getColor( "ToggleButton.tab.hoverBackground" );
|
||||||
|
tabFocusBackground = UIManager.getColor( "ToggleButton.tab.focusBackground" );
|
||||||
|
|
||||||
defaults_initialized = true;
|
defaults_initialized = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -87,6 +130,61 @@ public class FlatToggleButtonUI
|
|||||||
defaults_initialized = false;
|
defaults_initialized = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void propertyChange( AbstractButton b, PropertyChangeEvent e ) {
|
||||||
|
super.propertyChange( b, e );
|
||||||
|
|
||||||
|
switch( e.getPropertyName() ) {
|
||||||
|
case BUTTON_TYPE:
|
||||||
|
if( BUTTON_TYPE_TAB.equals( e.getOldValue() ) || BUTTON_TYPE_TAB.equals( e.getNewValue() ) ) {
|
||||||
|
MigLayoutVisualPadding.uninstall( b );
|
||||||
|
MigLayoutVisualPadding.install( b, getFocusWidth( b ) );
|
||||||
|
b.revalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
b.repaint();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TAB_BUTTON_UNDERLINE_HEIGHT:
|
||||||
|
case TAB_BUTTON_UNDERLINE_COLOR:
|
||||||
|
case TAB_BUTTON_SELECTED_BACKGROUND:
|
||||||
|
b.repaint();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static boolean isTabButton( Component c ) {
|
||||||
|
return c instanceof JToggleButton && clientPropertyEquals( (JToggleButton) c, BUTTON_TYPE, BUTTON_TYPE_TAB );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void paintBackground( Graphics g, JComponent c ) {
|
||||||
|
if( isTabButton( c ) ) {
|
||||||
|
int height = c.getHeight();
|
||||||
|
int width = c.getWidth();
|
||||||
|
boolean selected = ((AbstractButton)c).isSelected();
|
||||||
|
|
||||||
|
// paint background
|
||||||
|
Color background = buttonStateColor( c,
|
||||||
|
selected ? clientPropertyColor( c, TAB_BUTTON_SELECTED_BACKGROUND, tabSelectedBackground ) : null,
|
||||||
|
null, tabFocusBackground, tabHoverBackground, null );
|
||||||
|
if( background != null ) {
|
||||||
|
g.setColor( background );
|
||||||
|
g.fillRect( 0, 0, width, height );
|
||||||
|
}
|
||||||
|
|
||||||
|
// paint underline if selected
|
||||||
|
if( selected ) {
|
||||||
|
int underlineHeight = UIScale.scale( clientPropertyInt( c, TAB_BUTTON_UNDERLINE_HEIGHT, tabUnderlineHeight ) );
|
||||||
|
g.setColor( c.isEnabled()
|
||||||
|
? clientPropertyColor( c, TAB_BUTTON_UNDERLINE_COLOR, tabUnderlineColor )
|
||||||
|
: tabDisabledUnderlineColor );
|
||||||
|
g.fillRect( 0, height - underlineHeight, width, underlineHeight );
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
super.paintBackground( g, c );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Color getBackground( JComponent c ) {
|
protected Color getBackground( JComponent c ) {
|
||||||
ButtonModel model = ((AbstractButton)c).getModel();
|
ButtonModel model = ((AbstractButton)c).getModel();
|
||||||
@@ -114,4 +212,9 @@ public class FlatToggleButtonUI
|
|||||||
|
|
||||||
return super.getForeground( c );
|
return super.getForeground( c );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected int getFocusWidth( JComponent c ) {
|
||||||
|
return isTabButton( c ) ? 0 : super.getFocusWidth( c );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ import javax.swing.plaf.basic.BasicToolBarSeparatorUI;
|
|||||||
/**
|
/**
|
||||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JToolBar.Separator}.
|
* Provides the Flat LaF UI delegate for {@link javax.swing.JToolBar.Separator}.
|
||||||
*
|
*
|
||||||
|
* <!-- FlatToolBarSeparatorUI -->
|
||||||
|
*
|
||||||
* @uiDefault ToolBar.separatorWidth int
|
* @uiDefault ToolBar.separatorWidth int
|
||||||
* @uiDefault ToolBar.separatorColor Color
|
* @uiDefault ToolBar.separatorColor Color
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -33,7 +33,19 @@ import javax.swing.plaf.basic.BasicToolBarUI;
|
|||||||
/**
|
/**
|
||||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JToolBar}.
|
* Provides the Flat LaF UI delegate for {@link javax.swing.JToolBar}.
|
||||||
*
|
*
|
||||||
* TODO document used UI defaults of superclass
|
* <!-- BasicToolBarUI -->
|
||||||
|
*
|
||||||
|
* @uiDefault ToolBar.font Font
|
||||||
|
* @uiDefault ToolBar.background Color
|
||||||
|
* @uiDefault ToolBar.foreground Color
|
||||||
|
* @uiDefault ToolBar.border Border
|
||||||
|
* @uiDefault ToolBar.dockingBackground Color
|
||||||
|
* @uiDefault ToolBar.dockingForeground Color
|
||||||
|
* @uiDefault ToolBar.floatingBackground Color
|
||||||
|
* @uiDefault ToolBar.floatingForeground Color
|
||||||
|
* @uiDefault ToolBar.isRollover boolean
|
||||||
|
*
|
||||||
|
* <!-- FlatToolBarUI -->
|
||||||
*
|
*
|
||||||
* @uiDefault ToolBar.buttonMargins Insets
|
* @uiDefault ToolBar.buttonMargins Insets
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -21,22 +21,35 @@ import java.awt.FontMetrics;
|
|||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.awt.Insets;
|
import java.awt.Insets;
|
||||||
|
import java.beans.PropertyChangeListener;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
import javax.swing.JToolTip;
|
import javax.swing.JToolTip;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
import javax.swing.plaf.basic.BasicToolTipUI;
|
import javax.swing.plaf.basic.BasicToolTipUI;
|
||||||
import com.formdev.flatlaf.FlatLaf;
|
import com.formdev.flatlaf.util.StringUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JToolTip}.
|
* Provides the Flat LaF UI delegate for {@link javax.swing.JToolTip}.
|
||||||
*
|
*
|
||||||
|
* <!-- BasicToolTipUI -->
|
||||||
|
*
|
||||||
|
* @uiDefault ToolTip.font Font
|
||||||
|
* @uiDefault ToolTip.background Color
|
||||||
|
* @uiDefault ToolTip.foreground Color
|
||||||
|
* @uiDefault ToolTip.backgroundInactive Color
|
||||||
|
* @uiDefault ToolTip.foregroundInactive Color
|
||||||
|
* @uiDefault ToolTip.border Border
|
||||||
|
* @uiDefault ToolTip.borderInactive Border
|
||||||
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
public class FlatToolTipUI
|
public class FlatToolTipUI
|
||||||
extends BasicToolTipUI
|
extends BasicToolTipUI
|
||||||
{
|
{
|
||||||
|
private static PropertyChangeListener sharedPropertyChangedListener;
|
||||||
|
|
||||||
private static ComponentUI instance;
|
private static ComponentUI instance;
|
||||||
|
|
||||||
public static ComponentUI createUI( JComponent c ) {
|
public static ComponentUI createUI( JComponent c ) {
|
||||||
@@ -45,13 +58,45 @@ public class FlatToolTipUI
|
|||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void installUI( JComponent c ) {
|
||||||
|
super.installUI( c );
|
||||||
|
|
||||||
|
// update HTML renderer if necessary
|
||||||
|
FlatLabelUI.updateHTMLRenderer( c, ((JToolTip)c).getTipText(), false );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void installListeners( JComponent c ) {
|
||||||
|
super.installListeners( c );
|
||||||
|
|
||||||
|
if( sharedPropertyChangedListener == null ) {
|
||||||
|
sharedPropertyChangedListener = e -> {
|
||||||
|
String name = e.getPropertyName();
|
||||||
|
if( name == "text" || name == "font" || name == "foreground" ) {
|
||||||
|
JToolTip toolTip = (JToolTip) e.getSource();
|
||||||
|
FlatLabelUI.updateHTMLRenderer( toolTip, toolTip.getTipText(), false );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
c.addPropertyChangeListener( sharedPropertyChangedListener );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void uninstallListeners( JComponent c ) {
|
||||||
|
super.uninstallListeners( c );
|
||||||
|
|
||||||
|
c.removePropertyChangeListener( sharedPropertyChangedListener );
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Dimension getPreferredSize( JComponent c ) {
|
public Dimension getPreferredSize( JComponent c ) {
|
||||||
if( isMultiLine( c ) ) {
|
if( isMultiLine( c ) ) {
|
||||||
FontMetrics fm = c.getFontMetrics( c.getFont() );
|
FontMetrics fm = c.getFontMetrics( c.getFont() );
|
||||||
Insets insets = c.getInsets();
|
Insets insets = c.getInsets();
|
||||||
|
|
||||||
List<String> lines = FlatLaf.split( ((JToolTip)c).getTipText(), '\n' );
|
List<String> lines = StringUtils.split( ((JToolTip)c).getTipText(), '\n' );
|
||||||
int width = 0;
|
int width = 0;
|
||||||
int height = fm.getHeight() * Math.max( lines.size(), 1 );
|
int height = fm.getHeight() * Math.max( lines.size(), 1 );
|
||||||
for( String line : lines )
|
for( String line : lines )
|
||||||
@@ -71,7 +116,7 @@ public class FlatToolTipUI
|
|||||||
FlatUIUtils.setRenderingHints( (Graphics2D) g );
|
FlatUIUtils.setRenderingHints( (Graphics2D) g );
|
||||||
g.setColor( c.getForeground() );
|
g.setColor( c.getForeground() );
|
||||||
|
|
||||||
List<String> lines = FlatLaf.split( ((JToolTip)c).getTipText(), '\n' );
|
List<String> lines = StringUtils.split( ((JToolTip)c).getTipText(), '\n' );
|
||||||
|
|
||||||
int x = insets.left;
|
int x = insets.left;
|
||||||
int x2 = c.getWidth() - insets.right;
|
int x2 = c.getWidth() - insets.right;
|
||||||
|
|||||||
@@ -21,9 +21,16 @@ import java.awt.Component;
|
|||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.awt.Insets;
|
import java.awt.Insets;
|
||||||
import java.awt.Rectangle;
|
import java.awt.Rectangle;
|
||||||
|
import java.awt.event.MouseEvent;
|
||||||
|
import java.awt.event.MouseListener;
|
||||||
|
import java.beans.PropertyChangeEvent;
|
||||||
|
import java.beans.PropertyChangeListener;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
|
import javax.swing.JTree;
|
||||||
import javax.swing.LookAndFeel;
|
import javax.swing.LookAndFeel;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
|
import javax.swing.JTree.DropLocation;
|
||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
import javax.swing.plaf.basic.BasicTreeUI;
|
import javax.swing.plaf.basic.BasicTreeUI;
|
||||||
import javax.swing.tree.DefaultTreeCellRenderer;
|
import javax.swing.tree.DefaultTreeCellRenderer;
|
||||||
@@ -33,13 +40,50 @@ import com.formdev.flatlaf.util.UIScale;
|
|||||||
/**
|
/**
|
||||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JTree}.
|
* Provides the Flat LaF UI delegate for {@link javax.swing.JTree}.
|
||||||
*
|
*
|
||||||
* TODO document used UI defaults of superclass
|
* <!-- BasicTreeUI -->
|
||||||
|
*
|
||||||
|
* @uiDefault Tree.font Font
|
||||||
|
* @uiDefault Tree.background Color
|
||||||
|
* @uiDefault Tree.hash Color
|
||||||
|
* @uiDefault Tree.dropLineColor Color
|
||||||
|
* @uiDefault Tree.expandedIcon Icon
|
||||||
|
* @uiDefault Tree.collapsedIcon Icon
|
||||||
|
* @uiDefault Tree.leftChildIndent int
|
||||||
|
* @uiDefault Tree.rightChildIndent int
|
||||||
|
* @uiDefault Tree.rowHeight int
|
||||||
|
* @uiDefault Tree.scrollsOnExpand boolean
|
||||||
|
* @uiDefault Tree.scrollsHorizontallyAndVertically boolean
|
||||||
|
* @uiDefault Tree.paintLines boolean
|
||||||
|
* @uiDefault Tree.lineTypeDashed boolean
|
||||||
|
* @uiDefault Tree.showsRootHandles boolean
|
||||||
|
* @uiDefault Tree.repaintWholeRow boolean
|
||||||
|
*
|
||||||
|
* <!-- DefaultTreeCellRenderer -->
|
||||||
|
*
|
||||||
|
* @uiDefault Tree.leafIcon Icon
|
||||||
|
* @uiDefault Tree.closedIcon Icon
|
||||||
|
* @uiDefault Tree.openIcon Icon
|
||||||
|
* @uiDefault Tree.textBackground Color
|
||||||
|
* @uiDefault Tree.textForeground Color
|
||||||
|
* @uiDefault Tree.selectionBackground Color
|
||||||
|
* @uiDefault Tree.selectionForeground Color
|
||||||
|
* @uiDefault Tree.selectionBorderColor Color focus indicator border color
|
||||||
|
* @uiDefault Tree.drawsFocusBorderAroundIcon boolean
|
||||||
|
* @uiDefault Tree.drawDashedFocusIndicator boolean
|
||||||
|
* @uiDefault Tree.rendererFillBackground boolean default is true
|
||||||
|
* @uiDefault Tree.rendererMargins Insets
|
||||||
|
* @uiDefault Tree.dropCellBackground Color
|
||||||
|
* @uiDefault Tree.dropCellForeground Color
|
||||||
|
*
|
||||||
|
* <!-- FlatTreeUI -->
|
||||||
*
|
*
|
||||||
* @uiDefault Tree.border Border
|
* @uiDefault Tree.border Border
|
||||||
* @uiDefault Tree.selectionBackground Color
|
* @uiDefault Tree.selectionBackground Color
|
||||||
* @uiDefault Tree.selectionForeground Color
|
* @uiDefault Tree.selectionForeground Color
|
||||||
* @uiDefault Tree.selectionInactiveBackground Color
|
* @uiDefault Tree.selectionInactiveBackground Color
|
||||||
* @uiDefault Tree.selectionInactiveForeground Color
|
* @uiDefault Tree.selectionInactiveForeground Color
|
||||||
|
* @uiDefault Tree.wideSelection boolean
|
||||||
|
* @uiDefault Tree.showCellFocusIndicator boolean
|
||||||
*
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
@@ -50,6 +94,9 @@ public class FlatTreeUI
|
|||||||
protected Color selectionForeground;
|
protected Color selectionForeground;
|
||||||
protected Color selectionInactiveBackground;
|
protected Color selectionInactiveBackground;
|
||||||
protected Color selectionInactiveForeground;
|
protected Color selectionInactiveForeground;
|
||||||
|
protected Color selectionBorderColor;
|
||||||
|
protected boolean wideSelection;
|
||||||
|
protected boolean showCellFocusIndicator;
|
||||||
|
|
||||||
public static ComponentUI createUI( JComponent c ) {
|
public static ComponentUI createUI( JComponent c ) {
|
||||||
return new FlatTreeUI();
|
return new FlatTreeUI();
|
||||||
@@ -65,6 +112,9 @@ public class FlatTreeUI
|
|||||||
selectionForeground = UIManager.getColor( "Tree.selectionForeground" );
|
selectionForeground = UIManager.getColor( "Tree.selectionForeground" );
|
||||||
selectionInactiveBackground = UIManager.getColor( "Tree.selectionInactiveBackground" );
|
selectionInactiveBackground = UIManager.getColor( "Tree.selectionInactiveBackground" );
|
||||||
selectionInactiveForeground = UIManager.getColor( "Tree.selectionInactiveForeground" );
|
selectionInactiveForeground = UIManager.getColor( "Tree.selectionInactiveForeground" );
|
||||||
|
selectionBorderColor = UIManager.getColor( "Tree.selectionBorderColor" );
|
||||||
|
wideSelection = UIManager.getBoolean( "Tree.wideSelection" );
|
||||||
|
showCellFocusIndicator = UIManager.getBoolean( "Tree.showCellFocusIndicator" );
|
||||||
|
|
||||||
// scale
|
// scale
|
||||||
int rowHeight = FlatUIUtils.getUIInt( "Tree.rowHeight", 16 );
|
int rowHeight = FlatUIUtils.getUIInt( "Tree.rowHeight", 16 );
|
||||||
@@ -84,21 +134,115 @@ public class FlatTreeUI
|
|||||||
selectionForeground = null;
|
selectionForeground = null;
|
||||||
selectionInactiveBackground = null;
|
selectionInactiveBackground = null;
|
||||||
selectionInactiveForeground = null;
|
selectionInactiveForeground = null;
|
||||||
|
selectionBorderColor = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected MouseListener createMouseListener() {
|
||||||
|
if( !wideSelection )
|
||||||
|
return super.createMouseListener();
|
||||||
|
|
||||||
|
return new BasicTreeUI.MouseHandler() {
|
||||||
|
@Override
|
||||||
|
public void mousePressed( MouseEvent e ) {
|
||||||
|
super.mousePressed( handleWideMouseEvent( e ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseReleased( MouseEvent e ) {
|
||||||
|
super.mouseReleased( handleWideMouseEvent( e ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void mouseDragged( MouseEvent e ) {
|
||||||
|
super.mouseDragged( handleWideMouseEvent( e ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
private MouseEvent handleWideMouseEvent( MouseEvent e ) {
|
||||||
|
if( !tree.isEnabled() || !SwingUtilities.isLeftMouseButton( e ) || e.isConsumed() )
|
||||||
|
return e;
|
||||||
|
|
||||||
|
int x = e.getX();
|
||||||
|
int y = e.getY();
|
||||||
|
TreePath path = getClosestPathForLocation( tree, x, y );
|
||||||
|
if( path == null || isLocationInExpandControl( path, x, y ) )
|
||||||
|
return e;
|
||||||
|
|
||||||
|
Rectangle bounds = getPathBounds( tree, path );
|
||||||
|
if( bounds == null || y < bounds.y || y >= (bounds.y + bounds.height) )
|
||||||
|
return e;
|
||||||
|
|
||||||
|
int newX = Math.max( bounds.x, Math.min( x, bounds.x + bounds.width - 1 ) );
|
||||||
|
if( newX == x )
|
||||||
|
return e;
|
||||||
|
|
||||||
|
// clone mouse event, but with new X coordinate
|
||||||
|
return new MouseEvent( e.getComponent(), e.getID(), e.getWhen(),
|
||||||
|
e.getModifiers() | e.getModifiersEx(), newX, e.getY(),
|
||||||
|
e.getClickCount(), e.isPopupTrigger(), e.getButton() );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected PropertyChangeListener createPropertyChangeListener() {
|
||||||
|
if( !wideSelection )
|
||||||
|
return super.createPropertyChangeListener();
|
||||||
|
|
||||||
|
return new BasicTreeUI.PropertyChangeHandler() {
|
||||||
|
@Override
|
||||||
|
public void propertyChange( PropertyChangeEvent e ) {
|
||||||
|
super.propertyChange( e );
|
||||||
|
|
||||||
|
if( e.getSource() == tree && e.getPropertyName() == "dropLocation" ) {
|
||||||
|
JTree.DropLocation oldValue = (JTree.DropLocation) e.getOldValue();
|
||||||
|
repaintWideDropLocation( oldValue );
|
||||||
|
repaintWideDropLocation( tree.getDropLocation() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void repaintWideDropLocation(JTree.DropLocation loc) {
|
||||||
|
if( loc == null || isDropLine( loc ) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
Rectangle r = tree.getPathBounds( loc.getPath() );
|
||||||
|
if( r != null )
|
||||||
|
tree.repaint( 0, r.y, tree.getWidth(), r.height );
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Same as super.paintRow(), but uses inactive selection background/foreground if tree is not focused.
|
* Same as super.paintRow(), but supports wide selection and uses
|
||||||
|
* inactive selection background/foreground if tree is not focused.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void paintRow( Graphics g, Rectangle clipBounds, Insets insets, Rectangle bounds, TreePath path, int row,
|
protected void paintRow( Graphics g, Rectangle clipBounds, Insets insets, Rectangle bounds,
|
||||||
boolean isExpanded, boolean hasBeenExpanded, boolean isLeaf )
|
TreePath path, int row, boolean isExpanded, boolean hasBeenExpanded, boolean isLeaf )
|
||||||
{
|
{
|
||||||
if( editingComponent != null && editingRow == row )
|
boolean isEditing = (editingComponent != null && editingRow == row);
|
||||||
return;
|
|
||||||
|
|
||||||
boolean hasFocus = tree.hasFocus();
|
boolean hasFocus = tree.hasFocus();
|
||||||
boolean cellHasFocus = hasFocus && (row == getLeadSelectionRow());
|
boolean cellHasFocus = hasFocus && (row == getLeadSelectionRow());
|
||||||
boolean isSelected = tree.isRowSelected( row );
|
boolean isSelected = tree.isRowSelected( row );
|
||||||
|
boolean isDropRow = isDropRow( row );
|
||||||
|
|
||||||
|
// wide selection background
|
||||||
|
if( wideSelection && (isSelected || isDropRow) ) {
|
||||||
|
// fill background
|
||||||
|
g.setColor( isDropRow
|
||||||
|
? UIManager.getColor( "Tree.dropCellBackground" )
|
||||||
|
: (hasFocus ? selectionBackground : selectionInactiveBackground) );
|
||||||
|
g.fillRect( 0, bounds.y, tree.getWidth(), bounds.height );
|
||||||
|
|
||||||
|
// paint expand/collapse icon
|
||||||
|
if( shouldPaintExpandControl( path, row, isExpanded, hasBeenExpanded, isLeaf ) ) {
|
||||||
|
paintExpandControl( g, clipBounds, insets, bounds,
|
||||||
|
path, row, isExpanded, hasBeenExpanded, isLeaf );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( isEditing )
|
||||||
|
return;
|
||||||
|
|
||||||
// get renderer component
|
// get renderer component
|
||||||
Component rendererComponent = currentCellRenderer.getTreeCellRendererComponent( tree,
|
Component rendererComponent = currentCellRenderer.getTreeCellRendererComponent( tree,
|
||||||
@@ -106,7 +250,7 @@ public class FlatTreeUI
|
|||||||
|
|
||||||
// apply inactive selection background/foreground if tree is not focused
|
// apply inactive selection background/foreground if tree is not focused
|
||||||
Color oldBackgroundSelectionColor = null;
|
Color oldBackgroundSelectionColor = null;
|
||||||
if( isSelected && !hasFocus ) {
|
if( isSelected && !hasFocus && !isDropRow ) {
|
||||||
if( rendererComponent instanceof DefaultTreeCellRenderer ) {
|
if( rendererComponent instanceof DefaultTreeCellRenderer ) {
|
||||||
DefaultTreeCellRenderer renderer = (DefaultTreeCellRenderer) rendererComponent;
|
DefaultTreeCellRenderer renderer = (DefaultTreeCellRenderer) rendererComponent;
|
||||||
if( renderer.getBackgroundSelectionColor() == selectionBackground ) {
|
if( renderer.getBackgroundSelectionColor() == selectionBackground ) {
|
||||||
@@ -122,11 +266,43 @@ public class FlatTreeUI
|
|||||||
rendererComponent.setForeground( selectionInactiveForeground );
|
rendererComponent.setForeground( selectionInactiveForeground );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// remove focus selection border if exactly one item is selected
|
||||||
|
Color oldBorderSelectionColor = null;
|
||||||
|
if( isSelected && hasFocus &&
|
||||||
|
(!showCellFocusIndicator || tree.getMinSelectionRow() == tree.getMaxSelectionRow()) &&
|
||||||
|
rendererComponent instanceof DefaultTreeCellRenderer )
|
||||||
|
{
|
||||||
|
DefaultTreeCellRenderer renderer = (DefaultTreeCellRenderer) rendererComponent;
|
||||||
|
if( renderer.getBorderSelectionColor() == selectionBorderColor ) {
|
||||||
|
oldBorderSelectionColor = renderer.getBorderSelectionColor();
|
||||||
|
renderer.setBorderSelectionColor( null );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// paint renderer
|
// paint renderer
|
||||||
rendererPane.paintComponent( g, rendererComponent, tree, bounds.x, bounds.y, bounds.width, bounds.height, true );
|
rendererPane.paintComponent( g, rendererComponent, tree, bounds.x, bounds.y, bounds.width, bounds.height, true );
|
||||||
|
|
||||||
// restore background selection color
|
// restore background selection color and border selection color
|
||||||
if( oldBackgroundSelectionColor != null )
|
if( oldBackgroundSelectionColor != null )
|
||||||
((DefaultTreeCellRenderer)rendererComponent).setBackgroundSelectionColor( oldBackgroundSelectionColor );
|
((DefaultTreeCellRenderer)rendererComponent).setBackgroundSelectionColor( oldBackgroundSelectionColor );
|
||||||
|
if( oldBorderSelectionColor != null )
|
||||||
|
((DefaultTreeCellRenderer)rendererComponent).setBorderSelectionColor( oldBorderSelectionColor );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether dropping on a row.
|
||||||
|
* See DefaultTreeCellRenderer.getTreeCellRendererComponent().
|
||||||
|
*/
|
||||||
|
private boolean isDropRow( int row ) {
|
||||||
|
JTree.DropLocation dropLocation = tree.getDropLocation();
|
||||||
|
return dropLocation != null &&
|
||||||
|
dropLocation.getChildIndex() == -1 &&
|
||||||
|
tree.getRowForPath( dropLocation.getPath() ) == row;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Rectangle getDropLineRect( DropLocation loc ) {
|
||||||
|
Rectangle r = super.getDropLineRect( loc );
|
||||||
|
return wideSelection ? new Rectangle( 0, r.y, tree.getWidth(), r.height ) : r;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,9 @@ import javax.swing.JComponent;
|
|||||||
import javax.swing.LookAndFeel;
|
import javax.swing.LookAndFeel;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import javax.swing.plaf.ColorUIResource;
|
import javax.swing.plaf.ColorUIResource;
|
||||||
|
import com.formdev.flatlaf.FlatClientProperties;
|
||||||
import com.formdev.flatlaf.util.DerivedColor;
|
import com.formdev.flatlaf.util.DerivedColor;
|
||||||
|
import com.formdev.flatlaf.util.HiDPIUtils;
|
||||||
import com.formdev.flatlaf.util.JavaCompatibility;
|
import com.formdev.flatlaf.util.JavaCompatibility;
|
||||||
import com.formdev.flatlaf.util.UIScale;
|
import com.formdev.flatlaf.util.UIScale;
|
||||||
|
|
||||||
@@ -91,15 +93,33 @@ public class FlatUIUtils
|
|||||||
return (color != null) ? color : defaultColor;
|
return (color != null) ? color : defaultColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Color getUIColor( String key, String defaultKey ) {
|
||||||
|
Color color = UIManager.getColor( key );
|
||||||
|
return (color != null) ? color : UIManager.getColor( defaultKey );
|
||||||
|
}
|
||||||
|
|
||||||
public static int getUIInt( String key, int defaultValue ) {
|
public static int getUIInt( String key, int defaultValue ) {
|
||||||
Object value = UIManager.get( key );
|
Object value = UIManager.get( key );
|
||||||
return (value instanceof Integer) ? (Integer) value : defaultValue;
|
return (value instanceof Integer) ? (Integer) value : defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static float getUIFloat( String key, float defaultValue ) {
|
||||||
|
Object value = UIManager.get( key );
|
||||||
|
return (value instanceof Number) ? ((Number)value).floatValue() : defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
public static Color nonUIResource( Color c ) {
|
public static Color nonUIResource( Color c ) {
|
||||||
return (c instanceof ColorUIResource) ? new Color( c.getRGB(), true ) : c;
|
return (c instanceof ColorUIResource) ? new Color( c.getRGB(), true ) : c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static int minimumWidth( JComponent c, int minimumWidth ) {
|
||||||
|
return FlatClientProperties.clientPropertyInt( c, FlatClientProperties.MINIMUM_WIDTH, minimumWidth );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int minimumHeight( JComponent c, int minimumHeight ) {
|
||||||
|
return FlatClientProperties.clientPropertyInt( c, FlatClientProperties.MINIMUM_HEIGHT, minimumHeight );
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean isTableCellEditor( Component c ) {
|
public static boolean isTableCellEditor( Component c ) {
|
||||||
return c instanceof JComponent && Boolean.TRUE.equals( ((JComponent)c).getClientProperty( "JComboBox.isTableCellEditor" ) );
|
return c instanceof JComponent && Boolean.TRUE.equals( ((JComponent)c).getClientProperty( "JComboBox.isTableCellEditor" ) );
|
||||||
}
|
}
|
||||||
@@ -120,9 +140,73 @@ public class FlatUIUtils
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draws a round rectangle.
|
* Paints an outer border, which is usually a focus border.
|
||||||
|
* <p>
|
||||||
|
* The outside bounds of the painted border are {@code x,y,width,height}.
|
||||||
|
* The line width of the painted border is {@code focusWidth + lineWidth}.
|
||||||
|
* The given arc diameter refers to the inner rectangle ({@code x,y,width,height} minus {@code focusWidth}).
|
||||||
|
*
|
||||||
|
* @see #paintComponentBorder
|
||||||
|
* @see #paintComponentBackground
|
||||||
*/
|
*/
|
||||||
public static void drawRoundRectangle( Graphics2D g, int x, int y, int width, int height,
|
public static void paintComponentOuterBorder( Graphics2D g, int x, int y, int width, int height,
|
||||||
|
float focusWidth, float lineWidth, float arc )
|
||||||
|
{
|
||||||
|
double systemScaleFactor = UIScale.getSystemScaleFactor( g );
|
||||||
|
if( systemScaleFactor != 1 && systemScaleFactor != 2 ) {
|
||||||
|
// paint at scale 1x to avoid clipping on right and bottom edges at 125%, 150% or 175%
|
||||||
|
HiDPIUtils.paintAtScale1x( g, x, y, width, height, systemScaleFactor,
|
||||||
|
(g2d, x2, y2, width2, height2, scaleFactor) -> {
|
||||||
|
paintComponentOuterBorderImpl( g2d, x2, y2, width2, height2,
|
||||||
|
(float) (focusWidth * scaleFactor), (float) (lineWidth * scaleFactor), (float) (arc * scaleFactor) );
|
||||||
|
} );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
paintComponentOuterBorderImpl( g, x, y, width, height, focusWidth, lineWidth, arc );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void paintComponentOuterBorderImpl( Graphics2D g, int x, int y, int width, int height,
|
||||||
|
float focusWidth, float lineWidth, float arc )
|
||||||
|
{
|
||||||
|
float outerRadius = (arc > 0) ? arc + focusWidth - UIScale.scale( 2f ) : focusWidth;
|
||||||
|
float ow = focusWidth + lineWidth;
|
||||||
|
float innerRadius = outerRadius - ow;
|
||||||
|
|
||||||
|
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD );
|
||||||
|
path.append( createRoundRectanglePath( x, y, width, height, outerRadius, outerRadius, outerRadius, outerRadius ), false );
|
||||||
|
path.append( createRoundRectanglePath( x + ow, y + ow, width - (ow * 2), height - (ow * 2), innerRadius, innerRadius, innerRadius, innerRadius ), false );
|
||||||
|
g.fill( path );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draws the border of a component as round rectangle.
|
||||||
|
* <p>
|
||||||
|
* The outside bounds of the painted border are
|
||||||
|
* {@code x + focusWidth, y + focusWidth, width - (focusWidth * 2), height - (focusWidth * 2)}.
|
||||||
|
* The given arc diameter refers to the painted rectangle (and not to {@code x,y,width,height}).
|
||||||
|
*
|
||||||
|
* @see #paintComponentOuterBorder
|
||||||
|
* @see #paintComponentBackground
|
||||||
|
*/
|
||||||
|
public static void paintComponentBorder( Graphics2D g, int x, int y, int width, int height,
|
||||||
|
float focusWidth, float lineWidth, float arc )
|
||||||
|
{
|
||||||
|
double systemScaleFactor = UIScale.getSystemScaleFactor( g );
|
||||||
|
if( systemScaleFactor != 1 && systemScaleFactor != 2 ) {
|
||||||
|
// paint at scale 1x to avoid clipping on right and bottom edges at 125%, 150% or 175%
|
||||||
|
HiDPIUtils.paintAtScale1x( g, x, y, width, height, systemScaleFactor,
|
||||||
|
(g2d, x2, y2, width2, height2, scaleFactor) -> {
|
||||||
|
paintComponentBorderImpl( g2d, x2, y2, width2, height2,
|
||||||
|
(float) (focusWidth * scaleFactor), (float) (lineWidth * scaleFactor), (float) (arc * scaleFactor) );
|
||||||
|
} );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
paintComponentBorderImpl( g, x, y, width, height, focusWidth, lineWidth, arc );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void paintComponentBorderImpl( Graphics2D g, int x, int y, int width, int height,
|
||||||
float focusWidth, float lineWidth, float arc )
|
float focusWidth, float lineWidth, float arc )
|
||||||
{
|
{
|
||||||
float arc2 = arc > lineWidth ? arc - lineWidth : 0f;
|
float arc2 = arc > lineWidth ? arc - lineWidth : 0f;
|
||||||
@@ -141,9 +225,33 @@ public class FlatUIUtils
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fills a round rectangle.
|
* Fills the background of a component with a round rectangle.
|
||||||
|
* <p>
|
||||||
|
* The bounds of the painted round rectangle are
|
||||||
|
* {@code x + focusWidth, y + focusWidth, width - (focusWidth * 2), height - (focusWidth * 2)}.
|
||||||
|
* The given arc diameter refers to the painted rectangle (and not to {@code x,y,width,height}).
|
||||||
|
*
|
||||||
|
* @see #paintComponentOuterBorder
|
||||||
|
* @see #paintComponentBorder
|
||||||
*/
|
*/
|
||||||
public static void fillRoundRectangle( Graphics2D g, int x, int y, int width, int height,
|
public static void paintComponentBackground( Graphics2D g, int x, int y, int width, int height,
|
||||||
|
float focusWidth, float arc )
|
||||||
|
{
|
||||||
|
double systemScaleFactor = UIScale.getSystemScaleFactor( g );
|
||||||
|
if( systemScaleFactor != 1 && systemScaleFactor != 2 ) {
|
||||||
|
// paint at scale 1x to avoid clipping on right and bottom edges at 125%, 150% or 175%
|
||||||
|
HiDPIUtils.paintAtScale1x( g, x, y, width, height, systemScaleFactor,
|
||||||
|
(g2d, x2, y2, width2, height2, scaleFactor) -> {
|
||||||
|
paintComponentBackgroundImpl( g2d, x2, y2, width2, height2,
|
||||||
|
(float) (focusWidth * scaleFactor), (float) (arc * scaleFactor) );
|
||||||
|
} );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
paintComponentBackgroundImpl( g, x, y, width, height, focusWidth, arc );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void paintComponentBackgroundImpl( Graphics2D g, int x, int y, int width, int height,
|
||||||
float focusWidth, float arc )
|
float focusWidth, float arc )
|
||||||
{
|
{
|
||||||
g.fill( new RoundRectangle2D.Float(
|
g.fill( new RoundRectangle2D.Float(
|
||||||
@@ -163,6 +271,16 @@ public class FlatUIUtils
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the background color of the first opaque parent.
|
||||||
|
*/
|
||||||
|
public static Color getParentBackground( JComponent c ) {
|
||||||
|
Container parent = findOpaqueParent( c );
|
||||||
|
return (parent != null)
|
||||||
|
? parent.getBackground()
|
||||||
|
: UIManager.getColor( "Panel.background" ); // fallback, probably never used
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find the first parent that is opaque.
|
* Find the first parent that is opaque.
|
||||||
*/
|
*/
|
||||||
@@ -175,22 +293,14 @@ public class FlatUIUtils
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Paints an outline border.
|
* Creates a not-filled rectangle shape with the given line width.
|
||||||
*/
|
*/
|
||||||
public static void paintOutlineBorder( Graphics2D g, int x, int y, int width, int height,
|
public static Path2D createRectangle( float x, float y, float width, float height, float lineWidth ) {
|
||||||
float focusWidth, float lineWidth, float arc )
|
|
||||||
{
|
|
||||||
float outerArc = (arc > 0) ? arc + focusWidth - UIScale.scale( 2f ) : focusWidth;
|
|
||||||
float ow = focusWidth + lineWidth;
|
|
||||||
|
|
||||||
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD );
|
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD );
|
||||||
path.append( createOutlinePath( x, y, width, height, outerArc ), false );
|
path.append( new Rectangle2D.Float( x, y, width, height ), false );
|
||||||
path.append( createOutlinePath( x + ow, y + ow, width - (ow * 2), height - (ow * 2), outerArc - ow ), false );
|
path.append( new Rectangle2D.Float( x + lineWidth, y + lineWidth,
|
||||||
g.fill( path );
|
width - (lineWidth * 2), height - (lineWidth * 2) ), false );
|
||||||
}
|
return path;
|
||||||
|
|
||||||
private static Shape createOutlinePath( float x, float y, float width, float height, float arc ) {
|
|
||||||
return createRoundRectanglePath( x, y, width, height, arc, arc, arc, arc );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -207,7 +317,7 @@ public class FlatUIUtils
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a filled rounded rectangle shape and allows specifying the radius or each corner.
|
* Creates a filled rounded rectangle shape and allows specifying the radius of each corner.
|
||||||
*/
|
*/
|
||||||
public static Shape createRoundRectanglePath( float x, float y, float width, float height,
|
public static Shape createRoundRectanglePath( float x, float y, float width, float height,
|
||||||
float arcTopLeft, float arcTopRight, float arcBottomLeft, float arcBottomRight )
|
float arcTopLeft, float arcTopRight, float arcBottomLeft, float arcBottomRight )
|
||||||
@@ -241,10 +351,16 @@ public class FlatUIUtils
|
|||||||
return rect;
|
return rect;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a closed path for the given points.
|
||||||
|
*/
|
||||||
public static Path2D createPath( double... points ) {
|
public static Path2D createPath( double... points ) {
|
||||||
return createPath( true, points );
|
return createPath( true, points );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a 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();
|
||||||
path.moveTo( points[0], points[1] );
|
path.moveTo( points[0], points[1] );
|
||||||
|
|||||||
@@ -27,6 +27,12 @@ import javax.swing.plaf.basic.BasicViewportUI;
|
|||||||
/**
|
/**
|
||||||
* Provides the Flat LaF UI delegate for {@link javax.swing.JViewport}.
|
* Provides the Flat LaF UI delegate for {@link javax.swing.JViewport}.
|
||||||
*
|
*
|
||||||
|
* <!-- BasicViewportUI -->
|
||||||
|
*
|
||||||
|
* @uiDefault Viewport.font Font unused
|
||||||
|
* @uiDefault Viewport.background Color
|
||||||
|
* @uiDefault Viewport.foreground Color unused
|
||||||
|
*
|
||||||
* @author Karl Tauber
|
* @author Karl Tauber
|
||||||
*/
|
*/
|
||||||
public class FlatViewportUI
|
public class FlatViewportUI
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ import java.awt.Color;
|
|||||||
*/
|
*/
|
||||||
public class ColorFunctions
|
public class ColorFunctions
|
||||||
{
|
{
|
||||||
public static Color applyFunctions( Color color, ColorFunction[] functions ) {
|
public static Color applyFunctions( Color color, ColorFunction... functions ) {
|
||||||
float[] hsl = HSLColor.fromRGB( color );
|
float[] hsl = HSLColor.fromRGB( color );
|
||||||
float alpha = color.getAlpha() / 255f;
|
float alpha = color.getAlpha() / 255f;
|
||||||
|
|
||||||
|
|||||||
@@ -312,7 +312,7 @@ public class HSLColor
|
|||||||
*
|
*
|
||||||
* @param hsl an array containing the 3 HSL values
|
* @param hsl an array containing the 3 HSL values
|
||||||
*
|
*
|
||||||
* @returns the RGB Color object
|
* @return the RGB Color object
|
||||||
*/
|
*/
|
||||||
public static Color toRGB(float[] hsl)
|
public static Color toRGB(float[] hsl)
|
||||||
{
|
{
|
||||||
@@ -328,7 +328,7 @@ public class HSLColor
|
|||||||
* @param hsl an array containing the 3 HSL values
|
* @param hsl an array containing the 3 HSL values
|
||||||
* @param alpha the alpha value between 0 - 1
|
* @param alpha the alpha value between 0 - 1
|
||||||
*
|
*
|
||||||
* @returns the RGB Color object
|
* @return the RGB Color object
|
||||||
*/
|
*/
|
||||||
public static Color toRGB(float[] hsl, float alpha)
|
public static Color toRGB(float[] hsl, float alpha)
|
||||||
{
|
{
|
||||||
@@ -342,7 +342,7 @@ public class HSLColor
|
|||||||
* @param s Saturation is specified as a percentage in the range 1 - 100.
|
* @param s Saturation is specified as a percentage in the range 1 - 100.
|
||||||
* @param l Lumanance is specified as a percentage in the range 1 - 100.
|
* @param l Lumanance is specified as a percentage in the range 1 - 100.
|
||||||
*
|
*
|
||||||
* @returns the RGB Color object
|
* @return the RGB Color object
|
||||||
*/
|
*/
|
||||||
public static Color toRGB(float h, float s, float l)
|
public static Color toRGB(float h, float s, float l)
|
||||||
{
|
{
|
||||||
@@ -357,7 +357,7 @@ public class HSLColor
|
|||||||
* @param l Lumanance is specified as a percentage in the range 1 - 100.
|
* @param l Lumanance is specified as a percentage in the range 1 - 100.
|
||||||
* @param alpha the alpha value between 0 - 1
|
* @param alpha the alpha value between 0 - 1
|
||||||
*
|
*
|
||||||
* @returns the RGB Color object
|
* @return the RGB Color object
|
||||||
*/
|
*/
|
||||||
public static Color toRGB(float h, float s, float l, float alpha)
|
public static Color toRGB(float h, float s, float l, float alpha)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,111 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 FormDev Software GmbH
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.formdev.flatlaf.util;
|
||||||
|
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.geom.AffineTransform;
|
||||||
|
import java.awt.geom.Rectangle2D;
|
||||||
|
import javax.swing.JComponent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Karl Tauber
|
||||||
|
*/
|
||||||
|
public class HiDPIUtils
|
||||||
|
{
|
||||||
|
public interface Painter {
|
||||||
|
public void paint( Graphics2D g, int x, int y, int width, int height, double scaleFactor );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void paintAtScale1x( Graphics2D g, JComponent c, Painter painter ) {
|
||||||
|
paintAtScale1x( g, 0, 0, c.getWidth(), c.getHeight(), painter );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void paintAtScale1x( Graphics2D g, int x, int y, int width, int height, Painter painter ) {
|
||||||
|
paintAtScale1x( g, x, y, width, height, UIScale.getSystemScaleFactor( g ), painter );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Paint at system scale factor 1x to avoid rounding issues at 125%, 150% and 175% scaling.
|
||||||
|
* <p>
|
||||||
|
* Scales the given Graphics2D down to 100% and invokes the
|
||||||
|
* given painter passing scaled x, y, width and height.
|
||||||
|
* <p>
|
||||||
|
* Uses the same scaling calculation as the JRE uses.
|
||||||
|
*/
|
||||||
|
public static void paintAtScale1x( Graphics2D g, int x, int y, int width, int height,
|
||||||
|
double scaleFactor, Painter painter )
|
||||||
|
{
|
||||||
|
if( scaleFactor == 1 ) {
|
||||||
|
painter.paint( g, x, y, width, height, 1 );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// save original transform
|
||||||
|
AffineTransform transform = g.getTransform();
|
||||||
|
|
||||||
|
// scale rectangle
|
||||||
|
Rectangle2D.Double scaledRect = scale( transform, x, y, width, height );
|
||||||
|
|
||||||
|
try {
|
||||||
|
// unscale to factor 1.0
|
||||||
|
double scale = 1.0 / scaleFactor;
|
||||||
|
g.scale( scale, scale );
|
||||||
|
|
||||||
|
// compute origin delta x/y
|
||||||
|
double dx = Math.floor( scaledRect.x ) - transform.getTranslateX();
|
||||||
|
double dy = Math.floor( scaledRect.y ) - transform.getTranslateY();
|
||||||
|
|
||||||
|
// move origin to make sure that origin x/y are at whole numbers
|
||||||
|
if( dx != 0 || dy != 0 )
|
||||||
|
g.translate( dx, dy );
|
||||||
|
|
||||||
|
int swidth = (int) scaledRect.width;
|
||||||
|
int sheight = (int) scaledRect.height;
|
||||||
|
|
||||||
|
// paint
|
||||||
|
painter.paint( g, 0, 0, swidth, sheight, scaleFactor );
|
||||||
|
} finally {
|
||||||
|
// restore original transform
|
||||||
|
g.setTransform( transform );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scales a rectangle in the same way as the JRE does in
|
||||||
|
* sun.java2d.pipe.PixelToParallelogramConverter.fillRectangle(),
|
||||||
|
* which is used by Graphics.fillRect().
|
||||||
|
*/
|
||||||
|
private static Rectangle2D.Double scale( AffineTransform transform, int x, int y, int width, int height ) {
|
||||||
|
double dx1 = transform.getScaleX();
|
||||||
|
double dy2 = transform.getScaleY();
|
||||||
|
double px = x * dx1 + transform.getTranslateX();
|
||||||
|
double py = y * dy2 + transform.getTranslateY();
|
||||||
|
dx1 *= width;
|
||||||
|
dy2 *= height;
|
||||||
|
|
||||||
|
double newx = normalize( px );
|
||||||
|
double newy = normalize( py );
|
||||||
|
dx1 = normalize( px + dx1 ) - newx;
|
||||||
|
dy2 = normalize( py + dy2 ) - newy;
|
||||||
|
|
||||||
|
return new Rectangle2D.Double( newx, newy, dx1, dy2 );
|
||||||
|
}
|
||||||
|
|
||||||
|
private static double normalize( double value ) {
|
||||||
|
return Math.floor( value + 0.25 ) + 0.25;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -20,7 +20,10 @@ import java.awt.Graphics;
|
|||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import java.util.logging.Logger;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
|
import com.formdev.flatlaf.FlatLaf;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides Java version compatibility methods.
|
* Provides Java version compatibility methods.
|
||||||
@@ -52,7 +55,7 @@ public class JavaCompatibility
|
|||||||
? new Class[] { JComponent.class, Graphics2D.class, String.class, int.class, float.class, float.class }
|
? new Class[] { JComponent.class, Graphics2D.class, String.class, int.class, float.class, float.class }
|
||||||
: new Class[] { JComponent.class, Graphics.class, String.class, int.class, int.class, int.class } );
|
: new Class[] { JComponent.class, Graphics.class, String.class, int.class, int.class, int.class } );
|
||||||
} catch( Exception ex ) {
|
} catch( Exception ex ) {
|
||||||
ex.printStackTrace();
|
Logger.getLogger( FlatLaf.class.getName() ).log( Level.SEVERE, null, ex );
|
||||||
throw new RuntimeException( ex );
|
throw new RuntimeException( ex );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -64,7 +67,7 @@ public class JavaCompatibility
|
|||||||
else
|
else
|
||||||
drawStringUnderlineCharAtMethod.invoke( null, c, g, text, underlinedIndex, x, y );
|
drawStringUnderlineCharAtMethod.invoke( null, c, g, text, underlinedIndex, x, y );
|
||||||
} catch( IllegalAccessException | IllegalArgumentException | InvocationTargetException ex ) {
|
} catch( IllegalAccessException | IllegalArgumentException | InvocationTargetException ex ) {
|
||||||
ex.printStackTrace();
|
Logger.getLogger( FlatLaf.class.getName() ).log( Level.SEVERE, null, ex );
|
||||||
throw new RuntimeException( ex );
|
throw new RuntimeException( ex );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,77 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2019 FormDev Software GmbH
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.formdev.flatlaf.util;
|
|
||||||
|
|
||||||
import static com.formdev.flatlaf.util.UIScale.scale;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A number that scales its value.
|
|
||||||
*
|
|
||||||
* NOTE:
|
|
||||||
* Using ScaledNumber in UI defaults works only if the value is get with
|
|
||||||
* sun.swing.DefaultLookup.getInt(), which is used by some basic UI delegates,
|
|
||||||
* because this method uses "instanceof Number".
|
|
||||||
* UIManager.getInt() on the other hand uses "instanceof Integer" and does not work.
|
|
||||||
*
|
|
||||||
* @author Karl Tauber
|
|
||||||
*/
|
|
||||||
public class ScaledNumber
|
|
||||||
extends Number
|
|
||||||
{
|
|
||||||
private final int value;
|
|
||||||
|
|
||||||
public ScaledNumber( int value ) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int intValue() {
|
|
||||||
return scale( value );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public long longValue() {
|
|
||||||
return scale( value );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public float floatValue() {
|
|
||||||
return scale( (float) value );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public double doubleValue() {
|
|
||||||
return scale( (float) value );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
return Integer.hashCode( value );
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals( Object obj ) {
|
|
||||||
return (obj instanceof ScaledNumber)
|
|
||||||
? (value == ((ScaledNumber)obj).value)
|
|
||||||
: false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String toString() {
|
|
||||||
return Integer.toString( value );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019 FormDev Software GmbH
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.formdev.flatlaf.util;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility methods for strings.
|
||||||
|
*
|
||||||
|
* @author Karl Tauber
|
||||||
|
*/
|
||||||
|
public class StringUtils
|
||||||
|
{
|
||||||
|
public static String removeLeading( String string, String leading ) {
|
||||||
|
return string.startsWith( leading )
|
||||||
|
? string.substring( leading.length() )
|
||||||
|
: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String removeTrailing( String string, String trailing ) {
|
||||||
|
return string.endsWith( trailing )
|
||||||
|
? string.substring( 0, string.length() - trailing.length() )
|
||||||
|
: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<String> split( String str, char delim ) {
|
||||||
|
ArrayList<String> strs = new ArrayList<>();
|
||||||
|
int delimIndex = str.indexOf( delim );
|
||||||
|
int index = 0;
|
||||||
|
while( delimIndex >= 0 ) {
|
||||||
|
strs.add( str.substring( index, delimIndex ) );
|
||||||
|
index = delimIndex + 1;
|
||||||
|
delimIndex = str.indexOf( delim, index );
|
||||||
|
}
|
||||||
|
strs.add( str.substring( index ) );
|
||||||
|
|
||||||
|
return strs;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -197,6 +197,14 @@ public class UIScale
|
|||||||
return new FontUIResource( font.getFamily(), font.getStyle(), newFontSize );
|
return new FontUIResource( font.getFamily(), font.getStyle(), newFontSize );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Scales the given font.
|
||||||
|
*/
|
||||||
|
public static FontUIResource scaleFont( FontUIResource font, float scaleFactor ) {
|
||||||
|
int newFontSize = Math.round( font.getSize() * scaleFactor );
|
||||||
|
return new FontUIResource( font.getFamily(), font.getStyle(), newFontSize );
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Similar to sun.java2d.SunGraphicsEnvironment.getScaleFactor(String)
|
* Similar to sun.java2d.SunGraphicsEnvironment.getScaleFactor(String)
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
*/
|
*/
|
||||||
module com.formdev.flatlaf {
|
module com.formdev.flatlaf {
|
||||||
requires java.desktop;
|
requires java.desktop;
|
||||||
|
requires java.logging;
|
||||||
|
|
||||||
exports com.formdev.flatlaf;
|
exports com.formdev.flatlaf;
|
||||||
exports com.formdev.flatlaf.icons;
|
exports com.formdev.flatlaf.icons;
|
||||||
|
|||||||
@@ -30,6 +30,12 @@ Component.innerFocusWidth=0
|
|||||||
Component.arrowType=triangle
|
Component.arrowType=triangle
|
||||||
|
|
||||||
|
|
||||||
|
#---- ProgressBar ----
|
||||||
|
|
||||||
|
ProgressBar.foreground=#a0a0a0
|
||||||
|
ProgressBar.selectionForeground=@background
|
||||||
|
|
||||||
|
|
||||||
#---- RadioButton ----
|
#---- RadioButton ----
|
||||||
|
|
||||||
RadioButton.icon.centerDiameter=5
|
RadioButton.icon.centerDiameter=5
|
||||||
|
|||||||
@@ -20,21 +20,27 @@
|
|||||||
|
|
||||||
#---- variables ----
|
#---- variables ----
|
||||||
|
|
||||||
@background=3c3f41
|
@background=#3c3f41
|
||||||
@foreground=bbbbbb
|
@foreground=#bbbbbb
|
||||||
@selectionBackground=4B6EAF
|
@selectionBackground=#4B6EAF
|
||||||
@selectionForeground=@foreground
|
@selectionForeground=@foreground
|
||||||
@selectionInactiveBackground=0D293E
|
@selectionInactiveBackground=#0D293E
|
||||||
@selectionInactiveForeground=@foreground
|
@selectionInactiveForeground=@foreground
|
||||||
@disabledText=777777
|
@disabledText=#777777
|
||||||
@textComponentBackground=45494A
|
@textComponentBackground=#45494A
|
||||||
@cellFocusColor=000000
|
@cellFocusColor=#000000
|
||||||
@icon=adadad
|
@icon=#adadad
|
||||||
|
|
||||||
# Button
|
# Button
|
||||||
@buttonHoverBackground=lighten(3%,autoInverse)
|
@buttonHoverBackground=lighten(3%,autoInverse)
|
||||||
@buttonPressedBackground=lighten(6%,autoInverse)
|
@buttonPressedBackground=lighten(6%,autoInverse)
|
||||||
|
|
||||||
|
# Drop (use lazy colors for IntelliJ platform themes, which usually do not specify these colors)
|
||||||
|
@dropCellBackground=darken(List.selectionBackground,10%,lazy)
|
||||||
|
@dropCellForeground=lazy(List.selectionForeground)
|
||||||
|
@dropLineColor=lighten(List.selectionBackground,10%,lazy)
|
||||||
|
@dropLineShortColor=lighten(List.selectionBackground,30%,lazy)
|
||||||
|
|
||||||
|
|
||||||
#---- globals ----
|
#---- globals ----
|
||||||
|
|
||||||
@@ -50,78 +56,78 @@
|
|||||||
*.disabledBackground=@background
|
*.disabledBackground=@background
|
||||||
*.disabledForeground=@disabledText
|
*.disabledForeground=@disabledText
|
||||||
*.disabledText=@disabledText
|
*.disabledText=@disabledText
|
||||||
*.acceleratorForeground=bbbbbb
|
*.acceleratorForeground=#bbbbbb
|
||||||
*.acceleratorSelectionForeground=@selectionForeground
|
*.acceleratorSelectionForeground=@selectionForeground
|
||||||
|
|
||||||
|
|
||||||
#---- system ----
|
#---- system colors ----
|
||||||
|
|
||||||
control=@background
|
activeCaption=#434E60
|
||||||
controlText=@foreground
|
inactiveCaption=#393C3D
|
||||||
infoText=@foreground
|
controlHighlight=darken($controlShadow,20%)
|
||||||
text=@foreground
|
controlLtHighlight=darken($controlShadow,25%)
|
||||||
textText=@foreground
|
controlDkShadow=lighten($controlShadow,10%)
|
||||||
window=@background
|
|
||||||
|
|
||||||
|
|
||||||
#---- Button ----
|
#---- Button ----
|
||||||
|
|
||||||
Button.background=4c5052
|
Button.background=#4c5052
|
||||||
Button.hoverBackground=@buttonHoverBackground
|
Button.hoverBackground=@buttonHoverBackground
|
||||||
Button.pressedBackground=@buttonPressedBackground
|
Button.pressedBackground=@buttonPressedBackground
|
||||||
|
|
||||||
Button.borderColor=5e6060
|
Button.borderColor=#5e6060
|
||||||
Button.disabledBorderColor=5e6060
|
Button.disabledBorderColor=#5e6060
|
||||||
Button.focusedBorderColor=466d94
|
Button.focusedBorderColor=#466d94
|
||||||
Button.hoverBorderColor=@@Button.focusedBorderColor
|
Button.hoverBorderColor=$Button.focusedBorderColor
|
||||||
|
|
||||||
Button.default.background=365880
|
Button.default.background=#365880
|
||||||
Button.default.foreground=bbbbbb
|
Button.default.foreground=#bbbbbb
|
||||||
Button.default.hoverBackground=@buttonHoverBackground
|
Button.default.hoverBackground=@buttonHoverBackground
|
||||||
Button.default.pressedBackground=@buttonPressedBackground
|
Button.default.pressedBackground=@buttonPressedBackground
|
||||||
Button.default.borderColor=4c708c
|
Button.default.borderColor=#4c708c
|
||||||
Button.default.hoverBorderColor=537699
|
Button.default.hoverBorderColor=#537699
|
||||||
Button.default.focusedBorderColor=537699
|
Button.default.focusedBorderColor=#537699
|
||||||
Button.default.focusColor=43688c
|
Button.default.focusColor=#43688c
|
||||||
Button.default.boldText=true
|
Button.default.boldText=true
|
||||||
|
|
||||||
Button.toolbar.hoverBackground=4c5052
|
Button.toolbar.hoverBackground=#4c5052
|
||||||
Button.toolbar.pressedBackground=555a5d
|
Button.toolbar.pressedBackground=#555a5d
|
||||||
|
|
||||||
|
|
||||||
#---- CheckBox ----
|
#---- CheckBox ----
|
||||||
|
|
||||||
CheckBox.icon.borderColor=6B6B6B
|
CheckBox.icon.borderColor=#6B6B6B
|
||||||
CheckBox.icon.disabledBorderColor=545556
|
CheckBox.icon.disabledBorderColor=#545556
|
||||||
CheckBox.icon.selectedBorderColor=6B6B6B
|
CheckBox.icon.selectedBorderColor=#6B6B6B
|
||||||
CheckBox.icon.focusedBorderColor=466D94
|
CheckBox.icon.focusedBorderColor=#466D94
|
||||||
CheckBox.icon.hoverBorderColor=@@CheckBox.icon.focusedBorderColor
|
CheckBox.icon.hoverBorderColor=$CheckBox.icon.focusedBorderColor
|
||||||
CheckBox.icon.selectedFocusedBorderColor=466D94
|
CheckBox.icon.selectedFocusedBorderColor=#466D94
|
||||||
CheckBox.icon.background=43494A
|
CheckBox.icon.background=#43494A
|
||||||
CheckBox.icon.disabledBackground=@background
|
CheckBox.icon.disabledBackground=@background
|
||||||
CheckBox.icon.hoverBackground=@buttonHoverBackground
|
CheckBox.icon.hoverBackground=@buttonHoverBackground
|
||||||
CheckBox.icon.pressedBackground=@buttonPressedBackground
|
CheckBox.icon.pressedBackground=@buttonPressedBackground
|
||||||
CheckBox.icon.selectedBackground=43494A
|
CheckBox.icon.selectedBackground=#43494A
|
||||||
CheckBox.icon.checkmarkColor=A7A7A7
|
CheckBox.icon.checkmarkColor=#A7A7A7
|
||||||
CheckBox.icon.disabledCheckmarkColor=606060
|
CheckBox.icon.disabledCheckmarkColor=#606060
|
||||||
|
|
||||||
|
|
||||||
#---- ComboBox ----
|
#---- ComboBox ----
|
||||||
|
|
||||||
ComboBox.background=@textComponentBackground
|
ComboBox.background=@textComponentBackground
|
||||||
ComboBox.buttonBackground=@textComponentBackground
|
ComboBox.buttonBackground=@textComponentBackground
|
||||||
ComboBox.buttonEditableBackground=404445
|
ComboBox.buttonEditableBackground=#404445
|
||||||
ComboBox.buttonArrowColor=9A9DA1
|
ComboBox.buttonArrowColor=#9A9DA1
|
||||||
ComboBox.buttonDisabledArrowColor=585858
|
ComboBox.buttonDisabledArrowColor=#585858
|
||||||
ComboBox.buttonHoverArrowColor=bbbbbb
|
ComboBox.buttonHoverArrowColor=#bbbbbb
|
||||||
|
|
||||||
|
|
||||||
#---- Component ----
|
#---- Component ----
|
||||||
|
|
||||||
Component.borderColor=646464
|
Component.borderColor=#646464
|
||||||
Component.disabledBorderColor=646464
|
Component.disabledBorderColor=#646464
|
||||||
Component.focusedBorderColor=466d94
|
Component.focusedBorderColor=#466d94
|
||||||
Component.focusColor=3d6185
|
Component.focusColor=#3d6185
|
||||||
|
Component.linkColor=#589df6
|
||||||
|
|
||||||
|
|
||||||
#---- List ----
|
#---- List ----
|
||||||
@@ -131,111 +137,101 @@ List.background=@textComponentBackground
|
|||||||
|
|
||||||
#---- Menu ----
|
#---- Menu ----
|
||||||
|
|
||||||
Menu.icon.arrowColor=A7A7A7
|
Menu.icon.arrowColor=#A7A7A7
|
||||||
Menu.icon.disabledArrowColor=606060
|
Menu.icon.disabledArrowColor=#606060
|
||||||
|
|
||||||
|
|
||||||
#---- MenuBar ----
|
#---- MenuBar ----
|
||||||
|
|
||||||
MenuBar.borderColor=515151
|
MenuBar.borderColor=#515151
|
||||||
|
|
||||||
|
|
||||||
#---- MenuItemCheckBox ----
|
#---- MenuItemCheckBox ----
|
||||||
|
|
||||||
MenuItemCheckBox.icon.checkmarkColor=A7A7A7
|
MenuItemCheckBox.icon.checkmarkColor=#A7A7A7
|
||||||
MenuItemCheckBox.icon.disabledCheckmarkColor=606060
|
MenuItemCheckBox.icon.disabledCheckmarkColor=#606060
|
||||||
|
|
||||||
|
|
||||||
#---- OptionPane ----
|
|
||||||
|
|
||||||
OptionPane.icon.errorColor=C75450
|
|
||||||
OptionPane.icon.informationColor=3592C4
|
|
||||||
OptionPane.icon.questionColor=3592C4
|
|
||||||
OptionPane.icon.warningColor=F0A732
|
|
||||||
OptionPane.icon.foreground=null
|
|
||||||
|
|
||||||
|
|
||||||
#---- PopupMenu ----
|
#---- PopupMenu ----
|
||||||
|
|
||||||
PopupMenu.borderColor=515151
|
PopupMenu.borderColor=#5e5e5e
|
||||||
|
|
||||||
|
|
||||||
#---- ProgressBar ----
|
#---- ProgressBar ----
|
||||||
|
|
||||||
ProgressBar.background=555555
|
ProgressBar.background=#555555
|
||||||
ProgressBar.foreground=a0a0a0
|
ProgressBar.foreground=#4A88C7
|
||||||
ProgressBar.selectionForeground=@background
|
ProgressBar.selectionForeground=@foreground
|
||||||
ProgressBar.selectionBackground=@foreground
|
ProgressBar.selectionBackground=@foreground
|
||||||
|
|
||||||
|
|
||||||
#---- ScrollBar ----
|
#---- ScrollBar ----
|
||||||
|
|
||||||
ScrollBar.track=3F4244
|
ScrollBar.track=#3F4244
|
||||||
ScrollBar.thumb=5B5E5F
|
ScrollBar.thumb=#5B5E5F
|
||||||
ScrollBar.hoverTrackColor=434647
|
ScrollBar.hoverTrackColor=#434647
|
||||||
ScrollBar.hoverThumbColor=666868
|
ScrollBar.hoverThumbColor=#666868
|
||||||
|
|
||||||
|
|
||||||
#---- Separator ----
|
#---- Separator ----
|
||||||
|
|
||||||
Separator.foreground=515151
|
Separator.foreground=#515151
|
||||||
|
|
||||||
|
|
||||||
#---- Slider ----
|
#---- Slider ----
|
||||||
|
|
||||||
Slider.trackColor=646464
|
Slider.trackColor=#646464
|
||||||
Slider.thumbColor=A6A6A6
|
Slider.thumbColor=#A6A6A6
|
||||||
Slider.tickColor=888888
|
Slider.tickColor=#888888
|
||||||
Slider.focusedColor=@@Component.focusColor
|
Slider.hoverColor=darken(15%,autoInverse)
|
||||||
Slider.hoverColor=888888
|
Slider.disabledForeground=#4c5052
|
||||||
Slider.disabledForeground=4c5052
|
|
||||||
|
|
||||||
|
|
||||||
#---- SplitPane ----
|
#---- SplitPane ----
|
||||||
|
|
||||||
SplitPaneDivider.draggingColor=646464
|
SplitPaneDivider.draggingColor=#646464
|
||||||
SplitPaneDivider.oneTouchHoverArrowColor=7A7D81
|
SplitPaneDivider.oneTouchHoverArrowColor=#7A7D81
|
||||||
|
|
||||||
|
|
||||||
#---- TabbedPane ----
|
#---- TabbedPane ----
|
||||||
|
|
||||||
TabbedPane.disabledForeground=777777
|
TabbedPane.disabledForeground=@disabledText
|
||||||
TabbedPane.underlineColor=4A88C7
|
TabbedPane.underlineColor=#4A88C7
|
||||||
TabbedPane.disabledUnderlineColor=7a7a7a
|
TabbedPane.disabledUnderlineColor=#7a7a7a
|
||||||
TabbedPane.hoverColor=2e3133
|
TabbedPane.hoverColor=#2e3133
|
||||||
TabbedPane.focusColor=3d4b5c
|
TabbedPane.focusColor=#3d4b5c
|
||||||
TabbedPane.contentAreaColor=323232
|
TabbedPane.contentAreaColor=#323232
|
||||||
|
|
||||||
|
|
||||||
#---- Table ----
|
#---- Table ----
|
||||||
|
|
||||||
Table.background=@textComponentBackground
|
Table.background=@textComponentBackground
|
||||||
Table.gridColor=4F5152
|
Table.gridColor=#4F5152
|
||||||
|
|
||||||
|
|
||||||
#---- TableHeader ----
|
#---- TableHeader ----
|
||||||
|
|
||||||
TableHeader.background=45494A
|
TableHeader.background=#45494A
|
||||||
TableHeader.separatorColor=585858
|
TableHeader.separatorColor=#585858
|
||||||
TableHeader.bottomSeparatorColor=585858
|
TableHeader.bottomSeparatorColor=#585858
|
||||||
|
|
||||||
|
|
||||||
#---- ToggleButton ----
|
#---- ToggleButton ----
|
||||||
|
|
||||||
ToggleButton.selectedBackground=64696C
|
ToggleButton.selectedBackground=#64696C
|
||||||
ToggleButton.selectedForeground=@foreground
|
ToggleButton.selectedForeground=@foreground
|
||||||
ToggleButton.disabledSelectedBackground=525658
|
ToggleButton.disabledSelectedBackground=#525658
|
||||||
|
|
||||||
ToggleButton.toolbar.selectedBackground=5c6164
|
ToggleButton.toolbar.selectedBackground=#5c6164
|
||||||
|
|
||||||
|
|
||||||
#---- ToolTip ----
|
#---- ToolTip ----
|
||||||
|
|
||||||
ToolTip.border=4,6,4,6
|
ToolTip.border=4,6,4,6
|
||||||
ToolTip.background=1e2123
|
ToolTip.background=#1e2123
|
||||||
|
|
||||||
|
|
||||||
#---- Tree ----
|
#---- Tree ----
|
||||||
|
|
||||||
Tree.background=@textComponentBackground
|
Tree.background=@textComponentBackground
|
||||||
Tree.hash=505355
|
Tree.hash=#505355
|
||||||
|
|||||||
@@ -22,27 +22,26 @@
|
|||||||
|
|
||||||
Button.focusedBackground=null
|
Button.focusedBackground=null
|
||||||
|
|
||||||
Button.default.background=4A86C7
|
Button.default.background=#4D8AC9
|
||||||
Button.default.foreground=f0f0f0
|
Button.default.foreground=#FFFFFF
|
||||||
Button.default.focusedBackground=null
|
Button.default.focusedBackground=null
|
||||||
Button.default.hoverBackground=5B91CC
|
Button.default.borderColor=#3D75B2
|
||||||
Button.default.pressedBackground=6E9ED2
|
Button.default.hoverBorderColor=#A9C9F5
|
||||||
Button.default.borderColor=3167ad
|
Button.default.focusedBorderColor=#A9C9F5
|
||||||
Button.default.hoverBorderColor=a8cef6
|
Button.default.focusColor=#97c3f3
|
||||||
Button.default.focusedBorderColor=a8cef6
|
|
||||||
Button.default.focusColor=97c3f3
|
|
||||||
Button.default.boldText=true
|
Button.default.boldText=true
|
||||||
|
Button.default.borderWidth=1
|
||||||
|
|
||||||
|
|
||||||
#---- CheckBox ----
|
#---- CheckBox ----
|
||||||
|
|
||||||
CheckBox.icon.selectedBorderColor=4982CC
|
CheckBox.icon.selectedBorderColor=#4B97D9
|
||||||
CheckBox.icon.selectedFocusedBorderColor=ACCFF7
|
CheckBox.icon.selectedFocusedBorderColor=#ACCFF7
|
||||||
CheckBox.icon.selectedBackground=4D89C9
|
CheckBox.icon.selectedBackground=#4F9EE3
|
||||||
CheckBox.icon.checkmarkColor=FFFFFF
|
CheckBox.icon.checkmarkColor=#FFFFFF
|
||||||
|
|
||||||
CheckBox.icon.selectedHoverBackground=5E94CE
|
CheckBox.icon.selectedHoverBackground=#5E94CE
|
||||||
CheckBox.icon.selectedPressedBackground=72A1D4
|
CheckBox.icon.selectedPressedBackground=#72A1D4
|
||||||
|
|
||||||
|
|
||||||
#---- Component ----
|
#---- Component ----
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ CheckBoxMenuItemUI=com.formdev.flatlaf.ui.FlatCheckBoxMenuItemUI
|
|||||||
ColorChooserUI=com.formdev.flatlaf.ui.FlatColorChooserUI
|
ColorChooserUI=com.formdev.flatlaf.ui.FlatColorChooserUI
|
||||||
ComboBoxUI=com.formdev.flatlaf.ui.FlatComboBoxUI
|
ComboBoxUI=com.formdev.flatlaf.ui.FlatComboBoxUI
|
||||||
EditorPaneUI=com.formdev.flatlaf.ui.FlatEditorPaneUI
|
EditorPaneUI=com.formdev.flatlaf.ui.FlatEditorPaneUI
|
||||||
|
FileChooserUI=com.formdev.flatlaf.ui.FlatFileChooserUI
|
||||||
FormattedTextFieldUI=com.formdev.flatlaf.ui.FlatFormattedTextFieldUI
|
FormattedTextFieldUI=com.formdev.flatlaf.ui.FlatFormattedTextFieldUI
|
||||||
LabelUI=com.formdev.flatlaf.ui.FlatLabelUI
|
LabelUI=com.formdev.flatlaf.ui.FlatLabelUI
|
||||||
ListUI=com.formdev.flatlaf.ui.FlatListUI
|
ListUI=com.formdev.flatlaf.ui.FlatListUI
|
||||||
@@ -60,6 +61,31 @@ ViewportUI=com.formdev.flatlaf.ui.FlatViewportUI
|
|||||||
@textComponentMargin=2,6,2,6
|
@textComponentMargin=2,6,2,6
|
||||||
|
|
||||||
|
|
||||||
|
#---- system colors ----
|
||||||
|
|
||||||
|
desktop=@textComponentBackground
|
||||||
|
activeCaptionText=@foreground
|
||||||
|
activeCaptionBorder=$activeCaption
|
||||||
|
inactiveCaptionText=@foreground
|
||||||
|
inactiveCaptionBorder=$inactiveCaption
|
||||||
|
window=@background
|
||||||
|
windowBorder=@foreground
|
||||||
|
windowText=@foreground
|
||||||
|
menu=@background
|
||||||
|
menuText=@foreground
|
||||||
|
text=@textComponentBackground
|
||||||
|
textText=@foreground
|
||||||
|
textHighlight=@selectionBackground
|
||||||
|
textHighlightText=@selectionForeground
|
||||||
|
textInactiveText=@disabledText
|
||||||
|
control=@background
|
||||||
|
controlText=@foreground
|
||||||
|
controlShadow=$Component.borderColor
|
||||||
|
scrollbar=$ScrollBar.track
|
||||||
|
info=$ToolTip.background
|
||||||
|
infoText=@foreground
|
||||||
|
|
||||||
|
|
||||||
#---- Button ----
|
#---- Button ----
|
||||||
|
|
||||||
Button.border=com.formdev.flatlaf.ui.FlatButtonBorder
|
Button.border=com.formdev.flatlaf.ui.FlatButtonBorder
|
||||||
@@ -69,15 +95,21 @@ Button.margin=2,14,2,14
|
|||||||
Button.iconTextGap=4
|
Button.iconTextGap=4
|
||||||
Button.rollover=true
|
Button.rollover=true
|
||||||
Button.defaultButtonFollowsFocus=false
|
Button.defaultButtonFollowsFocus=false
|
||||||
|
[win]Button.defaultButtonFollowsFocus=true
|
||||||
|
|
||||||
Button.default.borderWidth=1
|
Button.default.borderWidth=1
|
||||||
|
|
||||||
|
|
||||||
|
#---- Caret ----
|
||||||
|
|
||||||
|
Caret.width={scaledInteger}1
|
||||||
|
|
||||||
|
|
||||||
#---- CheckBox ----
|
#---- CheckBox ----
|
||||||
|
|
||||||
CheckBox.border=com.formdev.flatlaf.ui.FlatMarginBorder
|
CheckBox.border=com.formdev.flatlaf.ui.FlatMarginBorder
|
||||||
CheckBox.icon=com.formdev.flatlaf.icons.FlatCheckBoxIcon
|
CheckBox.icon=com.formdev.flatlaf.icons.FlatCheckBoxIcon
|
||||||
CheckBox.arc=2
|
CheckBox.arc=4
|
||||||
CheckBox.margin=2,2,2,2
|
CheckBox.margin=2,2,2,2
|
||||||
CheckBox.iconTextGap=4
|
CheckBox.iconTextGap=4
|
||||||
CheckBox.rollover=true
|
CheckBox.rollover=true
|
||||||
@@ -106,7 +138,7 @@ ComboBox.padding=2,6,2,6
|
|||||||
#---- Component ----
|
#---- Component ----
|
||||||
|
|
||||||
Component.focusWidth=0
|
Component.focusWidth=0
|
||||||
Component.innerFocusWidth=0
|
Component.innerFocusWidth={float}0.5
|
||||||
Component.arc=5
|
Component.arc=5
|
||||||
Component.minimumWidth=64
|
Component.minimumWidth=64
|
||||||
Component.arrowType=chevron
|
Component.arrowType=chevron
|
||||||
@@ -116,8 +148,8 @@ Component.hideMnemonics=true
|
|||||||
#---- EditorPane ----
|
#---- EditorPane ----
|
||||||
|
|
||||||
EditorPane.border=com.formdev.flatlaf.ui.FlatMarginBorder
|
EditorPane.border=com.formdev.flatlaf.ui.FlatMarginBorder
|
||||||
EditorPane.background=@textComponentBackground
|
|
||||||
EditorPane.margin=@textComponentMargin
|
EditorPane.margin=@textComponentMargin
|
||||||
|
EditorPane.background=@textComponentBackground
|
||||||
|
|
||||||
|
|
||||||
#---- FileChooser ----
|
#---- FileChooser ----
|
||||||
@@ -128,12 +160,6 @@ FileChooser.homeFolderIcon=com.formdev.flatlaf.icons.FlatFileChooserHomeFolderIc
|
|||||||
FileChooser.detailsViewIcon=com.formdev.flatlaf.icons.FlatFileChooserDetailsViewIcon
|
FileChooser.detailsViewIcon=com.formdev.flatlaf.icons.FlatFileChooserDetailsViewIcon
|
||||||
FileChooser.listViewIcon=com.formdev.flatlaf.icons.FlatFileChooserListViewIcon
|
FileChooser.listViewIcon=com.formdev.flatlaf.icons.FlatFileChooserListViewIcon
|
||||||
|
|
||||||
FileChooser.icon.newFolderColor=@icon
|
|
||||||
FileChooser.icon.upFolderColor=@icon
|
|
||||||
FileChooser.icon.homeFolderColor=@icon
|
|
||||||
FileChooser.icon.detailsViewColor=@icon
|
|
||||||
FileChooser.icon.listViewColor=@icon
|
|
||||||
|
|
||||||
|
|
||||||
#---- FileView ----
|
#---- FileView ----
|
||||||
|
|
||||||
@@ -143,44 +169,45 @@ 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.icon.directoryColor=@icon
|
|
||||||
FileView.icon.fileColor=@icon
|
|
||||||
FileView.icon.computerColor=@icon
|
|
||||||
FileView.icon.hardDriveColor=@icon
|
|
||||||
FileView.icon.floppyDriveColor=@icon
|
|
||||||
|
|
||||||
|
|
||||||
#---- FormattedTextField ----
|
#---- FormattedTextField ----
|
||||||
|
|
||||||
FormattedTextField.border=com.formdev.flatlaf.ui.FlatBorder
|
FormattedTextField.border=com.formdev.flatlaf.ui.FlatBorder
|
||||||
FormattedTextField.background=@textComponentBackground
|
|
||||||
FormattedTextField.margin=@textComponentMargin
|
FormattedTextField.margin=@textComponentMargin
|
||||||
|
FormattedTextField.background=@textComponentBackground
|
||||||
|
FormattedTextField.placeholderForeground=@disabledText
|
||||||
|
|
||||||
|
|
||||||
#---- HelpButton ----
|
#---- HelpButton ----
|
||||||
|
|
||||||
HelpButton.icon=com.formdev.flatlaf.icons.FlatHelpButtonIcon
|
HelpButton.icon=com.formdev.flatlaf.icons.FlatHelpButtonIcon
|
||||||
HelpButton.borderColor=@@CheckBox.icon.borderColor
|
HelpButton.borderColor=$CheckBox.icon.borderColor
|
||||||
HelpButton.disabledBorderColor=@@CheckBox.icon.disabledBorderColor
|
HelpButton.disabledBorderColor=$CheckBox.icon.disabledBorderColor
|
||||||
HelpButton.focusedBorderColor=@@CheckBox.icon.focusedBorderColor
|
HelpButton.focusedBorderColor=$CheckBox.icon.focusedBorderColor
|
||||||
HelpButton.hoverBorderColor=@@?CheckBox.icon.hoverBorderColor
|
HelpButton.hoverBorderColor=$?CheckBox.icon.hoverBorderColor
|
||||||
HelpButton.background=@@CheckBox.icon.background
|
HelpButton.background=$CheckBox.icon.background
|
||||||
HelpButton.disabledBackground=@@CheckBox.icon.disabledBackground
|
HelpButton.disabledBackground=$CheckBox.icon.disabledBackground
|
||||||
HelpButton.focusedBackground=@@?CheckBox.icon.focusedBackground
|
HelpButton.focusedBackground=$?CheckBox.icon.focusedBackground
|
||||||
HelpButton.hoverBackground=@@?CheckBox.icon.hoverBackground
|
HelpButton.hoverBackground=$?CheckBox.icon.hoverBackground
|
||||||
HelpButton.pressedBackground=@@?CheckBox.icon.pressedBackground
|
HelpButton.pressedBackground=$?CheckBox.icon.pressedBackground
|
||||||
HelpButton.questionMarkColor=@@CheckBox.icon.checkmarkColor
|
HelpButton.questionMarkColor=$CheckBox.icon.checkmarkColor
|
||||||
HelpButton.disabledQuestionMarkColor=@@CheckBox.icon.disabledCheckmarkColor
|
HelpButton.disabledQuestionMarkColor=$CheckBox.icon.disabledCheckmarkColor
|
||||||
|
|
||||||
|
|
||||||
#---- List ----
|
#---- List ----
|
||||||
|
|
||||||
List.border=1,0,1,0
|
List.border=1,0,1,0
|
||||||
List.cellNoFocusBorder=1,6,1,6
|
List.border=0,0,0,0
|
||||||
List.focusCellHighlightBorder=1,6,1,6,@cellFocusColor
|
List.cellMargins=1,6,1,6
|
||||||
List.focusSelectedCellHighlightBorder=1,6,1,6,@cellFocusColor
|
List.cellFocusColor=@cellFocusColor
|
||||||
|
List.cellNoFocusBorder=com.formdev.flatlaf.ui.FlatListCellBorder$Default
|
||||||
|
List.focusCellHighlightBorder=com.formdev.flatlaf.ui.FlatListCellBorder$Focused
|
||||||
|
List.focusSelectedCellHighlightBorder=com.formdev.flatlaf.ui.FlatListCellBorder$Selected
|
||||||
List.selectionInactiveBackground=@selectionInactiveBackground
|
List.selectionInactiveBackground=@selectionInactiveBackground
|
||||||
List.selectionInactiveForeground=@selectionInactiveForeground
|
List.selectionInactiveForeground=@selectionInactiveForeground
|
||||||
|
List.dropCellBackground=@dropCellBackground
|
||||||
|
List.dropCellForeground=@dropCellForeground
|
||||||
|
List.dropLineColor=@dropLineColor
|
||||||
|
|
||||||
|
|
||||||
#---- Menu ----
|
#---- Menu ----
|
||||||
@@ -188,6 +215,8 @@ List.selectionInactiveForeground=@selectionInactiveForeground
|
|||||||
Menu.border=com.formdev.flatlaf.ui.FlatMarginBorder
|
Menu.border=com.formdev.flatlaf.ui.FlatMarginBorder
|
||||||
Menu.arrowIcon=com.formdev.flatlaf.icons.FlatMenuArrowIcon
|
Menu.arrowIcon=com.formdev.flatlaf.icons.FlatMenuArrowIcon
|
||||||
Menu.margin=2,2,2,2
|
Menu.margin=2,2,2,2
|
||||||
|
Menu.submenuPopupOffsetX={scaledInteger}-4
|
||||||
|
Menu.submenuPopupOffsetY={scaledInteger}-1
|
||||||
|
|
||||||
|
|
||||||
#---- MenuBar ----
|
#---- MenuBar ----
|
||||||
@@ -213,10 +242,11 @@ OptionPane.maxCharactersPerLine=80
|
|||||||
OptionPane.iconMessageGap=16
|
OptionPane.iconMessageGap=16
|
||||||
OptionPane.messagePadding=3
|
OptionPane.messagePadding=3
|
||||||
OptionPane.buttonPadding=8
|
OptionPane.buttonPadding=8
|
||||||
OptionPane.buttonMinimumWidth={scaledNumber}72
|
OptionPane.buttonMinimumWidth={scaledInteger}72
|
||||||
OptionPane.sameSizeButtons=true
|
OptionPane.sameSizeButtons=true
|
||||||
OptionPane.setButtonMargin=false
|
OptionPane.setButtonMargin=false
|
||||||
OptionPane.buttonOrientation=4
|
OptionPane.buttonOrientation=4
|
||||||
|
[mac]OptionPane.isYesLast=true
|
||||||
|
|
||||||
OptionPane.errorIcon=com.formdev.flatlaf.icons.FlatOptionPaneErrorIcon
|
OptionPane.errorIcon=com.formdev.flatlaf.icons.FlatOptionPaneErrorIcon
|
||||||
OptionPane.informationIcon=com.formdev.flatlaf.icons.FlatOptionPaneInformationIcon
|
OptionPane.informationIcon=com.formdev.flatlaf.icons.FlatOptionPaneInformationIcon
|
||||||
@@ -227,8 +257,9 @@ OptionPane.warningIcon=com.formdev.flatlaf.icons.FlatOptionPaneWarningIcon
|
|||||||
#---- PasswordField ----
|
#---- PasswordField ----
|
||||||
|
|
||||||
PasswordField.border=com.formdev.flatlaf.ui.FlatBorder
|
PasswordField.border=com.formdev.flatlaf.ui.FlatBorder
|
||||||
PasswordField.background=@textComponentBackground
|
|
||||||
PasswordField.margin=@textComponentMargin
|
PasswordField.margin=@textComponentMargin
|
||||||
|
PasswordField.background=@textComponentBackground
|
||||||
|
PasswordField.placeholderForeground=@disabledText
|
||||||
|
|
||||||
|
|
||||||
#---- PopupMenu ----
|
#---- PopupMenu ----
|
||||||
@@ -247,8 +278,9 @@ PopupMenuSeparator.stripeIndent=4
|
|||||||
#---- ProgressBar ----
|
#---- ProgressBar ----
|
||||||
|
|
||||||
ProgressBar.border=com.formdev.flatlaf.ui.FlatEmptyBorder
|
ProgressBar.border=com.formdev.flatlaf.ui.FlatEmptyBorder
|
||||||
ProgressBar.horizontalSize=146,6
|
ProgressBar.arc=4
|
||||||
ProgressBar.verticalSize=6,146
|
ProgressBar.horizontalSize=146,4
|
||||||
|
ProgressBar.verticalSize=4,146
|
||||||
|
|
||||||
|
|
||||||
#---- RadioButton ----
|
#---- RadioButton ----
|
||||||
@@ -272,13 +304,18 @@ RadioButtonMenuItem.margin=2,2,2,2
|
|||||||
#---- ScrollBar ----
|
#---- ScrollBar ----
|
||||||
|
|
||||||
ScrollBar.width=10
|
ScrollBar.width=10
|
||||||
|
ScrollBar.showButtons=false
|
||||||
|
ScrollBar.squareButtons=false
|
||||||
|
ScrollBar.buttonArrowColor=$ComboBox.buttonArrowColor
|
||||||
|
ScrollBar.buttonDisabledArrowColor=$ComboBox.buttonDisabledArrowColor
|
||||||
|
|
||||||
|
|
||||||
#---- ScrollPane ----
|
#---- ScrollPane ----
|
||||||
|
|
||||||
ScrollPane.border=com.formdev.flatlaf.ui.FlatBorder
|
ScrollPane.border=com.formdev.flatlaf.ui.FlatBorder
|
||||||
ScrollPane.background=@@ScrollBar.track
|
ScrollPane.background=$ScrollBar.track
|
||||||
ScrollPane.fillUpperCorner=true
|
ScrollPane.fillUpperCorner=true
|
||||||
|
ScrollPane.smoothScrolling=true
|
||||||
|
|
||||||
|
|
||||||
#---- Separator ----
|
#---- Separator ----
|
||||||
@@ -299,10 +336,10 @@ Slider.thumbWidth=11
|
|||||||
|
|
||||||
Spinner.border=com.formdev.flatlaf.ui.FlatRoundBorder
|
Spinner.border=com.formdev.flatlaf.ui.FlatRoundBorder
|
||||||
Spinner.background=@textComponentBackground
|
Spinner.background=@textComponentBackground
|
||||||
Spinner.buttonBackground=@@ComboBox.buttonEditableBackground
|
Spinner.buttonBackground=$ComboBox.buttonEditableBackground
|
||||||
Spinner.buttonArrowColor=@@ComboBox.buttonArrowColor
|
Spinner.buttonArrowColor=$ComboBox.buttonArrowColor
|
||||||
Spinner.buttonDisabledArrowColor=@@ComboBox.buttonDisabledArrowColor
|
Spinner.buttonDisabledArrowColor=$ComboBox.buttonDisabledArrowColor
|
||||||
Spinner.buttonHoverArrowColor=@@ComboBox.buttonHoverArrowColor
|
Spinner.buttonHoverArrowColor=$ComboBox.buttonHoverArrowColor
|
||||||
Spinner.padding=@textComponentMargin
|
Spinner.padding=@textComponentMargin
|
||||||
Spinner.editorBorderPainted=false
|
Spinner.editorBorderPainted=false
|
||||||
|
|
||||||
@@ -313,11 +350,11 @@ SplitPane.dividerSize={integer}5
|
|||||||
SplitPane.continuousLayout=true
|
SplitPane.continuousLayout=true
|
||||||
SplitPane.border=null
|
SplitPane.border=null
|
||||||
SplitPane.centerOneTouchButtons=true
|
SplitPane.centerOneTouchButtons=true
|
||||||
SplitPane.oneTouchButtonSize={scaledNumber}6
|
SplitPane.oneTouchButtonSize={scaledInteger}6
|
||||||
SplitPane.oneTouchButtonOffset={scaledNumber}2
|
SplitPane.oneTouchButtonOffset={scaledInteger}2
|
||||||
|
|
||||||
SplitPaneDivider.border=null
|
SplitPaneDivider.border=null
|
||||||
SplitPaneDivider.oneTouchArrowColor=@@ComboBox.buttonArrowColor
|
SplitPaneDivider.oneTouchArrowColor=$ComboBox.buttonArrowColor
|
||||||
|
|
||||||
|
|
||||||
#---- TabbedPane ----
|
#---- TabbedPane ----
|
||||||
@@ -331,68 +368,86 @@ TabbedPane.tabAreaInsets=0,0,0,0
|
|||||||
TabbedPane.selectedTabPadInsets=0,0,0,0
|
TabbedPane.selectedTabPadInsets=0,0,0,0
|
||||||
TabbedPane.tabRunOverlay=0
|
TabbedPane.tabRunOverlay=0
|
||||||
TabbedPane.tabsOverlapBorder=true
|
TabbedPane.tabsOverlapBorder=true
|
||||||
TabbedPane.shadow=@@ComboBox.buttonArrowColor
|
TabbedPane.shadow=@background
|
||||||
|
|
||||||
|
|
||||||
#---- Table ----
|
#---- Table ----
|
||||||
|
|
||||||
Table.rowHeight=20
|
Table.rowHeight=20
|
||||||
|
Table.showHorizontalLines=false
|
||||||
|
Table.showVerticalLines=false
|
||||||
|
Table.intercellSpacing={dimension}0,0
|
||||||
Table.scrollPaneBorder=com.formdev.flatlaf.ui.FlatBorder
|
Table.scrollPaneBorder=com.formdev.flatlaf.ui.FlatBorder
|
||||||
Table.ascendingSortIcon=com.formdev.flatlaf.icons.FlatAscendingSortIcon
|
Table.ascendingSortIcon=com.formdev.flatlaf.icons.FlatAscendingSortIcon
|
||||||
Table.descendingSortIcon=com.formdev.flatlaf.icons.FlatDescendingSortIcon
|
Table.descendingSortIcon=com.formdev.flatlaf.icons.FlatDescendingSortIcon
|
||||||
Table.sortIconColor=@icon
|
Table.sortIconColor=@icon
|
||||||
Table.cellNoFocusBorder=2,3,2,3
|
Table.cellMargins=2,3,2,3
|
||||||
Table.focusSelectedCellHighlightBorder=2,3,2,3,@cellFocusColor
|
Table.cellFocusColor=@cellFocusColor
|
||||||
|
Table.cellNoFocusBorder=com.formdev.flatlaf.ui.FlatTableCellBorder$Default
|
||||||
|
Table.focusCellHighlightBorder=com.formdev.flatlaf.ui.FlatTableCellBorder$Focused
|
||||||
|
Table.focusSelectedCellHighlightBorder=com.formdev.flatlaf.ui.FlatTableCellBorder$Selected
|
||||||
Table.selectionInactiveBackground=@selectionInactiveBackground
|
Table.selectionInactiveBackground=@selectionInactiveBackground
|
||||||
Table.selectionInactiveForeground=@selectionInactiveForeground
|
Table.selectionInactiveForeground=@selectionInactiveForeground
|
||||||
|
Table.dropCellBackground=@dropCellBackground
|
||||||
|
Table.dropCellForeground=@dropCellForeground
|
||||||
|
Table.dropLineColor=@dropLineColor
|
||||||
|
Table.dropLineShortColor=@dropLineShortColor
|
||||||
|
|
||||||
|
|
||||||
#---- TableHeader ----
|
#---- TableHeader ----
|
||||||
|
|
||||||
TableHeader.height=25
|
TableHeader.height=25
|
||||||
TableHeader.cellBorder=2,2,2,2
|
TableHeader.cellBorder=2,3,2,3
|
||||||
|
|
||||||
|
|
||||||
#---- TextArea ----
|
#---- TextArea ----
|
||||||
|
|
||||||
TextArea.border=com.formdev.flatlaf.ui.FlatMarginBorder
|
TextArea.border=com.formdev.flatlaf.ui.FlatMarginBorder
|
||||||
TextArea.background=@textComponentBackground
|
|
||||||
TextArea.margin=@textComponentMargin
|
TextArea.margin=@textComponentMargin
|
||||||
|
TextArea.background=@textComponentBackground
|
||||||
|
|
||||||
|
|
||||||
#---- TextField ----
|
#---- TextField ----
|
||||||
|
|
||||||
TextField.border=com.formdev.flatlaf.ui.FlatBorder
|
TextField.border=com.formdev.flatlaf.ui.FlatBorder
|
||||||
TextField.background=@textComponentBackground
|
|
||||||
TextField.margin=@textComponentMargin
|
TextField.margin=@textComponentMargin
|
||||||
|
TextField.background=@textComponentBackground
|
||||||
|
TextField.placeholderForeground=@disabledText
|
||||||
|
|
||||||
|
|
||||||
#---- TextPane ----
|
#---- TextPane ----
|
||||||
|
|
||||||
TextPane.border=com.formdev.flatlaf.ui.FlatMarginBorder
|
TextPane.border=com.formdev.flatlaf.ui.FlatMarginBorder
|
||||||
TextPane.background=@textComponentBackground
|
|
||||||
TextPane.margin=@textComponentMargin
|
TextPane.margin=@textComponentMargin
|
||||||
|
TextPane.background=@textComponentBackground
|
||||||
|
|
||||||
|
|
||||||
#---- TitledBorder ----
|
#---- TitledBorder ----
|
||||||
|
|
||||||
TitledBorder.titleColor=@foreground
|
TitledBorder.titleColor=@foreground
|
||||||
TitledBorder.border=1,1,1,1,@@Separator.foreground
|
TitledBorder.border=1,1,1,1,$Separator.foreground
|
||||||
|
|
||||||
|
|
||||||
#---- ToggleButton ----
|
#---- ToggleButton ----
|
||||||
|
|
||||||
ToggleButton.border=com.formdev.flatlaf.ui.FlatButtonBorder
|
ToggleButton.border=com.formdev.flatlaf.ui.FlatButtonBorder
|
||||||
ToggleButton.arc=6
|
|
||||||
ToggleButton.margin=2,14,2,14
|
ToggleButton.margin=2,14,2,14
|
||||||
ToggleButton.iconTextGap=4
|
ToggleButton.iconTextGap=4
|
||||||
ToggleButton.rollover=true
|
ToggleButton.rollover=true
|
||||||
|
|
||||||
ToggleButton.background=@@Button.background
|
ToggleButton.background=$Button.background
|
||||||
ToggleButton.pressedBackground=@@Button.pressedBackground
|
ToggleButton.pressedBackground=$Button.pressedBackground
|
||||||
|
|
||||||
ToggleButton.toolbar.hoverBackground=@@Button.toolbar.hoverBackground
|
ToggleButton.toolbar.hoverBackground=$Button.toolbar.hoverBackground
|
||||||
ToggleButton.toolbar.pressedBackground=@@Button.toolbar.pressedBackground
|
ToggleButton.toolbar.pressedBackground=$Button.toolbar.pressedBackground
|
||||||
|
|
||||||
|
# button type "tab"
|
||||||
|
ToggleButton.tab.underlineHeight=2
|
||||||
|
ToggleButton.tab.underlineColor=$TabbedPane.underlineColor
|
||||||
|
ToggleButton.tab.disabledUnderlineColor=$TabbedPane.disabledUnderlineColor
|
||||||
|
ToggleButton.tab.selectedBackground=$?TabbedPane.selectedBackground
|
||||||
|
ToggleButton.tab.hoverBackground=$TabbedPane.hoverColor
|
||||||
|
ToggleButton.tab.focusBackground=$TabbedPane.focusColor
|
||||||
|
|
||||||
|
|
||||||
#---- ToolBar ----
|
#---- ToolBar ----
|
||||||
@@ -406,14 +461,14 @@ ToolBar.floatingBackground=@background
|
|||||||
|
|
||||||
ToolBar.separatorSize=null
|
ToolBar.separatorSize=null
|
||||||
ToolBar.separatorWidth=7
|
ToolBar.separatorWidth=7
|
||||||
ToolBar.separatorColor=@@Separator.foreground
|
ToolBar.separatorColor=$Separator.foreground
|
||||||
|
|
||||||
|
|
||||||
#---- ToolTip ----
|
#---- ToolTip ----
|
||||||
|
|
||||||
ToolTip.border=4,6,4,6,@@Component.borderColor
|
ToolTip.border=4,6,4,6,$Component.borderColor
|
||||||
ToolTip.borderInactive=null
|
ToolTip.borderInactive=null
|
||||||
ToolTip.backgroundInactive=@@ToolTip.background
|
ToolTip.backgroundInactive=$ToolTip.background
|
||||||
ToolTip.foregroundInactive=@disabledText
|
ToolTip.foregroundInactive=@disabledText
|
||||||
|
|
||||||
|
|
||||||
@@ -422,9 +477,14 @@ ToolTip.foregroundInactive=@disabledText
|
|||||||
Tree.border=1,1,1,1
|
Tree.border=1,1,1,1
|
||||||
Tree.selectionInactiveBackground=@selectionInactiveBackground
|
Tree.selectionInactiveBackground=@selectionInactiveBackground
|
||||||
Tree.selectionInactiveForeground=@selectionInactiveForeground
|
Tree.selectionInactiveForeground=@selectionInactiveForeground
|
||||||
Tree.textBackground=@@Tree.background
|
Tree.textBackground=$Tree.background
|
||||||
Tree.selectionBorderColor=@cellFocusColor
|
Tree.selectionBorderColor=@cellFocusColor
|
||||||
|
Tree.dropCellBackground=@dropCellBackground
|
||||||
|
Tree.dropCellForeground=@dropCellForeground
|
||||||
|
Tree.dropLineColor=@dropLineColor
|
||||||
|
Tree.rendererFillBackground=false
|
||||||
Tree.rendererMargins=1,2,1,2
|
Tree.rendererMargins=1,2,1,2
|
||||||
|
Tree.wideSelection=true
|
||||||
Tree.paintLines=false
|
Tree.paintLines=false
|
||||||
Tree.leftChildIndent=7
|
Tree.leftChildIndent=7
|
||||||
Tree.rightChildIndent=11
|
Tree.rightChildIndent=11
|
||||||
|
|||||||
@@ -20,115 +20,121 @@
|
|||||||
|
|
||||||
#---- variables ----
|
#---- variables ----
|
||||||
|
|
||||||
@background=f2f2f2
|
@background=#f2f2f2
|
||||||
@foreground=000000
|
@foreground=#000000
|
||||||
@selectionBackground=4A6EB7
|
@selectionBackground=#2675BF
|
||||||
@selectionForeground=ffffff
|
@selectionForeground=#ffffff
|
||||||
@selectionInactiveBackground=d4d4d4
|
@selectionInactiveBackground=#d4d4d4
|
||||||
@selectionInactiveForeground=@foreground
|
@selectionInactiveForeground=@foreground
|
||||||
@disabledText=999999
|
@disabledText=#8C8C8C
|
||||||
@textComponentBackground=ffffff
|
@textComponentBackground=#ffffff
|
||||||
@cellFocusColor=000000
|
@cellFocusColor=#000000
|
||||||
@icon=afafaf
|
@icon=#afafaf
|
||||||
|
|
||||||
# Button
|
# Button
|
||||||
@buttonHoverBackground=darken(3%,autoInverse)
|
@buttonHoverBackground=darken(3%,autoInverse)
|
||||||
@buttonPressedBackground=darken(10%,autoInverse)
|
@buttonPressedBackground=darken(10%,autoInverse)
|
||||||
|
|
||||||
|
# Drop (use lazy colors for IntelliJ platform themes, which usually do not specify these colors)
|
||||||
|
@dropCellBackground=lighten(List.selectionBackground,10%,lazy)
|
||||||
|
@dropCellForeground=lazy(List.selectionForeground)
|
||||||
|
@dropLineColor=lighten(List.selectionBackground,20%,lazy)
|
||||||
|
@dropLineShortColor=darken(List.selectionBackground,20%,lazy)
|
||||||
|
|
||||||
|
|
||||||
#---- globals ----
|
#---- globals ----
|
||||||
|
|
||||||
*.background=@background
|
*.background=@background
|
||||||
*.foreground=@foreground
|
*.foreground=@foreground
|
||||||
*.textBackground=cccccc
|
*.textBackground=#cccccc
|
||||||
*.textForeground=@foreground
|
*.textForeground=@foreground
|
||||||
*.caretForeground=@foreground
|
*.caretForeground=@foreground
|
||||||
*.inactiveBackground=@background
|
*.inactiveBackground=@background
|
||||||
*.inactiveForeground=777777
|
*.inactiveForeground=@disabledText
|
||||||
*.selectionBackground=@selectionBackground
|
*.selectionBackground=@selectionBackground
|
||||||
*.selectionForeground=@selectionForeground
|
*.selectionForeground=@selectionForeground
|
||||||
*.disabledBackground=@background
|
*.disabledBackground=@background
|
||||||
*.disabledForeground=@disabledText
|
*.disabledForeground=@disabledText
|
||||||
*.disabledText=@disabledText
|
*.disabledText=@disabledText
|
||||||
*.acceleratorForeground=505050
|
*.acceleratorForeground=#505050
|
||||||
*.acceleratorSelectionForeground=@selectionForeground
|
*.acceleratorSelectionForeground=@selectionForeground
|
||||||
|
|
||||||
|
|
||||||
#---- system ----
|
#---- system colors ----
|
||||||
|
|
||||||
control=e0e0e0
|
activeCaption=#99b4d1
|
||||||
controlText=@foreground
|
inactiveCaption=#bfcddb
|
||||||
infoText=@foreground
|
controlHighlight=#e3e3e3
|
||||||
text=@foreground
|
controlLtHighlight=#fff
|
||||||
textText=@foreground
|
controlDkShadow=darken($controlShadow,15%)
|
||||||
window=@background
|
|
||||||
|
|
||||||
|
|
||||||
#---- Button ----
|
#---- Button ----
|
||||||
|
|
||||||
Button.background=ffffff
|
Button.background=#ffffff
|
||||||
Button.focusedBackground=e3f1fa
|
Button.focusedBackground=#e3f1fa
|
||||||
Button.hoverBackground=@buttonHoverBackground
|
Button.hoverBackground=@buttonHoverBackground
|
||||||
Button.pressedBackground=@buttonPressedBackground
|
Button.pressedBackground=@buttonPressedBackground
|
||||||
|
|
||||||
Button.borderColor=bfbfbf
|
Button.borderColor=$Component.borderColor
|
||||||
Button.disabledBorderColor=cfcfcf
|
Button.disabledBorderColor=$Component.disabledBorderColor
|
||||||
Button.focusedBorderColor=87afda
|
Button.focusedBorderColor=$Component.focusedBorderColor
|
||||||
Button.hoverBorderColor=@@Button.focusedBorderColor
|
Button.hoverBorderColor=$Button.focusedBorderColor
|
||||||
|
|
||||||
Button.default.background=@@Button.background
|
Button.default.background=$Button.background
|
||||||
Button.default.foreground=@foreground
|
Button.default.foreground=@foreground
|
||||||
Button.default.focusedBackground=@@Button.focusedBackground
|
Button.default.focusedBackground=$Button.focusedBackground
|
||||||
Button.default.hoverBackground=@buttonHoverBackground
|
Button.default.hoverBackground=@buttonHoverBackground
|
||||||
Button.default.pressedBackground=@buttonPressedBackground
|
Button.default.pressedBackground=@buttonPressedBackground
|
||||||
Button.default.borderColor=4D89C9
|
Button.default.borderColor=#4F9EE3
|
||||||
Button.default.hoverBorderColor=@@Button.hoverBorderColor
|
Button.default.hoverBorderColor=$Button.hoverBorderColor
|
||||||
Button.default.focusedBorderColor=@@Button.focusedBorderColor
|
Button.default.focusedBorderColor=$Button.focusedBorderColor
|
||||||
Button.default.focusColor=@@Component.focusColor
|
Button.default.focusColor=$Component.focusColor
|
||||||
Button.default.borderWidth=2
|
Button.default.borderWidth=2
|
||||||
|
|
||||||
Button.toolbar.hoverBackground=dfdfdf
|
Button.toolbar.hoverBackground=#dfdfdf
|
||||||
Button.toolbar.pressedBackground=d8d8d8
|
Button.toolbar.pressedBackground=#d8d8d8
|
||||||
|
|
||||||
|
|
||||||
#---- CheckBox ----
|
#---- CheckBox ----
|
||||||
|
|
||||||
CheckBox.icon.borderColor=878787
|
CheckBox.icon.borderColor=#b0b0b0
|
||||||
CheckBox.icon.disabledBorderColor=BDBDBD
|
CheckBox.icon.disabledBorderColor=#BDBDBD
|
||||||
CheckBox.icon.selectedBorderColor=878787
|
CheckBox.icon.selectedBorderColor=$CheckBox.icon.borderColor
|
||||||
CheckBox.icon.focusedBorderColor=7B9FC7
|
CheckBox.icon.focusedBorderColor=#7B9FC7
|
||||||
CheckBox.icon.hoverBorderColor=@@CheckBox.icon.focusedBorderColor
|
CheckBox.icon.hoverBorderColor=$CheckBox.icon.focusedBorderColor
|
||||||
CheckBox.icon.background=FFFFFF
|
CheckBox.icon.background=#FFFFFF
|
||||||
CheckBox.icon.disabledBackground=@background
|
CheckBox.icon.disabledBackground=@background
|
||||||
CheckBox.icon.focusedBackground=@@Button.focusedBackground
|
CheckBox.icon.focusedBackground=$Button.focusedBackground
|
||||||
CheckBox.icon.hoverBackground=@buttonHoverBackground
|
CheckBox.icon.hoverBackground=@buttonHoverBackground
|
||||||
CheckBox.icon.pressedBackground=@buttonPressedBackground
|
CheckBox.icon.pressedBackground=@buttonPressedBackground
|
||||||
CheckBox.icon.selectedBackground=FFFFFF
|
CheckBox.icon.selectedBackground=#FFFFFF
|
||||||
CheckBox.icon.checkmarkColor=4D89C9
|
CheckBox.icon.checkmarkColor=#4F9EE3
|
||||||
CheckBox.icon.disabledCheckmarkColor=ABABAB
|
CheckBox.icon.disabledCheckmarkColor=#ABABAB
|
||||||
|
|
||||||
|
|
||||||
#---- ComboBox ----
|
#---- ComboBox ----
|
||||||
|
|
||||||
ComboBox.background=@textComponentBackground
|
ComboBox.background=@textComponentBackground
|
||||||
ComboBox.buttonBackground=@textComponentBackground
|
ComboBox.buttonBackground=@textComponentBackground
|
||||||
ComboBox.buttonEditableBackground=fafafa
|
ComboBox.buttonEditableBackground=#fafafa
|
||||||
ComboBox.buttonArrowColor=666666
|
ComboBox.buttonArrowColor=#666666
|
||||||
ComboBox.buttonDisabledArrowColor=ABABAB
|
ComboBox.buttonDisabledArrowColor=#ABABAB
|
||||||
ComboBox.buttonHoverArrowColor=999999
|
ComboBox.buttonHoverArrowColor=#999999
|
||||||
|
|
||||||
|
|
||||||
#---- Component ----
|
#---- Component ----
|
||||||
|
|
||||||
Component.borderColor=c4c4c4
|
Component.borderColor=#c4c4c4
|
||||||
Component.disabledBorderColor=cfcfcf
|
Component.disabledBorderColor=#cfcfcf
|
||||||
Component.focusedBorderColor=87afda
|
Component.focusedBorderColor=#87afda
|
||||||
Component.focusColor=97c3f3
|
Component.focusColor=#97c3f3
|
||||||
|
Component.linkColor=#2470B3
|
||||||
|
|
||||||
|
|
||||||
#---- HelpButton ----
|
#---- HelpButton ----
|
||||||
|
|
||||||
HelpButton.questionMarkColor=4D89C9
|
HelpButton.questionMarkColor=#4F9EE3
|
||||||
|
|
||||||
|
|
||||||
#---- List ----
|
#---- List ----
|
||||||
@@ -138,110 +144,100 @@ List.background=@textComponentBackground
|
|||||||
|
|
||||||
#---- Menu ----
|
#---- Menu ----
|
||||||
|
|
||||||
Menu.icon.arrowColor=666666
|
Menu.icon.arrowColor=#666666
|
||||||
Menu.icon.disabledArrowColor=ABABAB
|
Menu.icon.disabledArrowColor=#ABABAB
|
||||||
|
|
||||||
|
|
||||||
#---- MenuBar ----
|
#---- MenuBar ----
|
||||||
|
|
||||||
MenuBar.borderColor=cdcdcd
|
MenuBar.borderColor=#cdcdcd
|
||||||
|
|
||||||
|
|
||||||
#---- MenuItemCheckBox ----
|
#---- MenuItemCheckBox ----
|
||||||
|
|
||||||
MenuItemCheckBox.icon.checkmarkColor=4D89C9
|
MenuItemCheckBox.icon.checkmarkColor=#4F9EE3
|
||||||
MenuItemCheckBox.icon.disabledCheckmarkColor=ABABAB
|
MenuItemCheckBox.icon.disabledCheckmarkColor=#ABABAB
|
||||||
|
|
||||||
|
|
||||||
#---- OptionPane ----
|
|
||||||
|
|
||||||
OptionPane.icon.errorColor=DB5860
|
|
||||||
OptionPane.icon.informationColor=389FD6
|
|
||||||
OptionPane.icon.questionColor=389FD6
|
|
||||||
OptionPane.icon.warningColor=EDA200
|
|
||||||
OptionPane.icon.foreground=null
|
|
||||||
|
|
||||||
|
|
||||||
#---- PopupMenu ----
|
#---- PopupMenu ----
|
||||||
|
|
||||||
PopupMenu.borderColor=cdcdcd
|
PopupMenu.borderColor=#adadad
|
||||||
|
|
||||||
|
|
||||||
#---- ProgressBar ----
|
#---- ProgressBar ----
|
||||||
|
|
||||||
ProgressBar.background=c4c4c4
|
ProgressBar.background=#D1D1D1
|
||||||
ProgressBar.foreground=808080
|
ProgressBar.foreground=#1E82E6
|
||||||
ProgressBar.selectionForeground=@textComponentBackground
|
ProgressBar.selectionForeground=@textComponentBackground
|
||||||
ProgressBar.selectionBackground=@foreground
|
ProgressBar.selectionBackground=@foreground
|
||||||
|
|
||||||
|
|
||||||
#---- ScrollBar ----
|
#---- ScrollBar ----
|
||||||
|
|
||||||
ScrollBar.track=F5F5F5
|
ScrollBar.track=#F5F5F5
|
||||||
ScrollBar.thumb=DBDBDB
|
ScrollBar.thumb=#DBDBDB
|
||||||
ScrollBar.hoverTrackColor=e6e6e6
|
ScrollBar.hoverTrackColor=#e6e6e6
|
||||||
ScrollBar.hoverThumbColor=c6c6c6
|
ScrollBar.hoverThumbColor=#c6c6c6
|
||||||
|
|
||||||
|
|
||||||
#---- Separator ----
|
#---- Separator ----
|
||||||
|
|
||||||
Separator.foreground=cdcdcd
|
Separator.foreground=#d1d1d1
|
||||||
|
|
||||||
|
|
||||||
#---- Slider ----
|
#---- Slider ----
|
||||||
|
|
||||||
Slider.trackColor=c4c4c4
|
Slider.trackColor=#c4c4c4
|
||||||
Slider.thumbColor=6e6e6e
|
Slider.thumbColor=#6e6e6e
|
||||||
Slider.tickColor=888888
|
Slider.tickColor=#888888
|
||||||
Slider.focusedColor=@@Component.focusColor
|
Slider.hoverColor=lighten(15%,autoInverse)
|
||||||
Slider.hoverColor=999999
|
Slider.disabledForeground=#c0c0c0
|
||||||
Slider.disabledForeground=c0c0c0
|
|
||||||
|
|
||||||
|
|
||||||
#---- SplitPane ----
|
#---- SplitPane ----
|
||||||
|
|
||||||
SplitPaneDivider.draggingColor=c4c4c4
|
SplitPaneDivider.draggingColor=#c4c4c4
|
||||||
SplitPaneDivider.oneTouchHoverArrowColor=333333
|
SplitPaneDivider.oneTouchHoverArrowColor=#333333
|
||||||
|
|
||||||
|
|
||||||
#---- TabbedPane ----
|
#---- TabbedPane ----
|
||||||
|
|
||||||
TabbedPane.disabledForeground=999999
|
TabbedPane.disabledForeground=@disabledText
|
||||||
TabbedPane.underlineColor=4083C9
|
TabbedPane.underlineColor=#4083C9
|
||||||
TabbedPane.disabledUnderlineColor=ababab
|
TabbedPane.disabledUnderlineColor=#ababab
|
||||||
TabbedPane.hoverColor=d9d9d9
|
TabbedPane.hoverColor=#d9d9d9
|
||||||
TabbedPane.focusColor=dae4ed
|
TabbedPane.focusColor=#dae4ed
|
||||||
TabbedPane.contentAreaColor=bfbfbf
|
TabbedPane.contentAreaColor=#bfbfbf
|
||||||
|
|
||||||
|
|
||||||
#---- Table ----
|
#---- Table ----
|
||||||
|
|
||||||
Table.background=@textComponentBackground
|
Table.background=@textComponentBackground
|
||||||
Table.gridColor=F7F7F7
|
Table.gridColor=#F7F7F7
|
||||||
|
|
||||||
|
|
||||||
#---- TableHeader ----
|
#---- TableHeader ----
|
||||||
|
|
||||||
TableHeader.background=ffffff
|
TableHeader.background=#ffffff
|
||||||
TableHeader.separatorColor=e5e5e5
|
TableHeader.separatorColor=#e5e5e5
|
||||||
TableHeader.bottomSeparatorColor=e5e5e5
|
TableHeader.bottomSeparatorColor=#e5e5e5
|
||||||
|
|
||||||
|
|
||||||
#---- ToggleButton ----
|
#---- ToggleButton ----
|
||||||
|
|
||||||
ToggleButton.selectedBackground=cfcfcf
|
ToggleButton.selectedBackground=#cfcfcf
|
||||||
ToggleButton.selectedForeground=@foreground
|
ToggleButton.selectedForeground=@foreground
|
||||||
ToggleButton.disabledSelectedBackground=dfdfdf
|
ToggleButton.disabledSelectedBackground=#dfdfdf
|
||||||
|
|
||||||
ToggleButton.toolbar.selectedBackground=cfcfcf
|
ToggleButton.toolbar.selectedBackground=#cfcfcf
|
||||||
|
|
||||||
|
|
||||||
#---- ToolTip ----
|
#---- ToolTip ----
|
||||||
|
|
||||||
ToolTip.background=fafafa
|
ToolTip.background=#fafafa
|
||||||
|
|
||||||
|
|
||||||
#---- Tree ----
|
#---- Tree ----
|
||||||
|
|
||||||
Tree.background=@textComponentBackground
|
Tree.background=@textComponentBackground
|
||||||
Tree.hash=E6E6E6
|
Tree.hash=#E6E6E6
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
#
|
||||||
|
# Copyright 2019 FormDev Software GmbH
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
|
||||||
|
#---- Button ----
|
||||||
|
|
||||||
|
Button.hoverBorderColor=null
|
||||||
|
Button.default.hoverBorderColor=null
|
||||||
|
|
||||||
|
|
||||||
|
#---- HelpButton ----
|
||||||
|
|
||||||
|
HelpButton.hoverBorderColor=null
|
||||||
4
flatlaf-demo/README.md
Normal file
4
flatlaf-demo/README.md
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
FlatLaf Demo
|
||||||
|
============
|
||||||
|
|
||||||
|
This sub-project contains the FlatLaf Demo source code.
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user