Compare commits

..

11 Commits

Author SHA1 Message Date
Karl Tauber
4d7a6ff331 AnimatedPainter:
- renamed `getValues()` to `getAnimatableValues()`
- renamed `getClientPropertyKey()` to `getAnimationClientPropertyKey()`
- AnimatedPainterSupport improvements
2025-03-13 11:46:14 +01:00
Karl Tauber
23fc3674c9 LineChartPanel:
- support "synchron" charts
- reworked to make code easier to understand/maintain
- added some JavaBean properties to make it configurable in JFormDesigner
- fixes some bugs

removed `FlatAnimatorTest.LineChartPanel` and replaced it with `LineChartPanel`
2025-03-12 18:35:56 +01:00
Karl Tauber
34a7214dd8 LineChartPanel copied from branch smooth-scrolling, commit 44a04cca2c 2025-03-11 19:33:36 +01:00
Karl Tauber
26d7008c04 AnimatedPainter: support individual animation duration, resolution and interpolator depending on value(s) 2021-11-22 22:07:45 +01:00
Karl Tauber
3b489e8e1a AnimatedPainter: support independent animation of multiple values 2021-11-22 22:07:20 +01:00
Karl Tauber
ccbf577f46 AnimatedBorder: demo for labeled material border 2021-11-21 23:20:47 +01:00
Karl Tauber
b903f18130 FlatAnimatorTest:
- support synchronized line chart
- LineChartPanel: added slider to change horizontal scaling
- FlatAnimatedIconTest: added line chart panel
- FlatAnimatedBorderTest: added line chart panel
2021-11-21 12:27:31 +01:00
Karl Tauber
9523c89c51 FlatAnimatorTest: added standard-easing and line chart
(line chart copied from `FlatSmoothScrollingTest.LineChartPanel` in branch `smooth-scrolling` commit 331ab06b0087d3a70f7c131368b88e5e7c92102f)
2021-11-20 15:14:03 +01:00
Karl Tauber
aa6fb2fcce AnimatedPainter added (refactored from AnimatedBorder and AnimatedIcon)
(checked API compatibility of AnimatedIcon with gradle task sigtestCheck)
2021-11-20 11:13:06 +01:00
Karl Tauber
e4fa2e28ea AnimatedBorder:
- support repainting only necessary region while animating
- use AbstractBorder in test app and fixed insets
2021-11-19 18:02:54 +01:00
Karl Tauber
b2245e2246 AnimatedBorder added (for future animations) (issue #66) 2021-11-19 18:02:54 +01:00
214 changed files with 29801 additions and 31258 deletions

View File

@@ -19,26 +19,40 @@ jobs:
strategy: strategy:
matrix: matrix:
# test against # test against
# - Java 8 (minimum requirement) # - Java 1.8 (minimum requirement)
# - Java 9 (first version with JPMS)
# - Java LTS versions (11, 17, ...) # - Java LTS versions (11, 17, ...)
# - lastest Java version(s) # - lastest Java version(s)
java: java:
- 8 - 1.8
- 9
- 11 # LTS - 11 # LTS
- 17 # LTS - 14
- 15
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- uses: gradle/wrapper-validation-action@v1 - uses: gradle/wrapper-validation-action@v1
if: matrix.java == '8' if: matrix.java == '1.8'
- name: Setup Java ${{ matrix.java }} - name: Setup Java ${{ matrix.java }}
uses: actions/setup-java@v2 uses: actions/setup-java@v1
with: with:
java-version: ${{ matrix.java }} java-version: ${{ matrix.java }}
distribution: adopt # Java 8 and 11 are pre-installed on ubuntu-latest
cache: gradle - name: Cache Gradle wrapper
uses: actions/cache@v1
with:
path: ~/.gradle/wrapper
key: ${{ runner.os }}-gradle-wrapper-${{ hashFiles('gradle/wrapper/gradle-wrapper.properties') }}
- name: Cache Gradle cache
uses: actions/cache@v2
with:
path: ~/.gradle/caches
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle.kts') }}
restore-keys: ${{ runner.os }}-gradle
- name: Build with Gradle - name: Build with Gradle
run: ./gradlew build run: ./gradlew build
@@ -59,18 +73,29 @@ jobs:
needs: build needs: build
if: | if: |
github.event_name == 'push' && github.event_name == 'push' &&
(github.ref == 'refs/heads/main' || startsWith( github.ref, 'refs/heads/develop-' )) && github.ref == 'refs/heads/main' &&
github.repository == 'JFormDesigner/FlatLaf' github.repository == 'JFormDesigner/FlatLaf'
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: Setup Java 11 - name: Setup Java 11
uses: actions/setup-java@v2 uses: actions/setup-java@v1
with: with:
java-version: 11 java-version: 11
distribution: adopt # pre-installed on ubuntu-latest
cache: gradle - name: Cache Gradle wrapper
uses: actions/cache@v1
with:
path: ~/.gradle/wrapper
key: ${{ runner.os }}-gradle-wrapper-${{ hashFiles('gradle/wrapper/gradle-wrapper.properties') }}
- name: Cache Gradle cache
uses: actions/cache@v2
with:
path: ~/.gradle/caches
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle.kts') }}
restore-keys: ${{ runner.os }}-gradle
- name: Publish snapshot to oss.sonatype.org - name: Publish snapshot to oss.sonatype.org
run: ./gradlew publish :flatlaf-theme-editor:build -Dorg.gradle.internal.publish.checksums.insecure=true run: ./gradlew publish :flatlaf-theme-editor:build -Dorg.gradle.internal.publish.checksums.insecure=true
@@ -102,11 +127,22 @@ jobs:
- uses: actions/checkout@v2 - uses: actions/checkout@v2
- name: Setup Java 11 - name: Setup Java 11
uses: actions/setup-java@v2 uses: actions/setup-java@v1
with: with:
java-version: 11 java-version: 11
distribution: adopt # pre-installed on ubuntu-latest
cache: gradle - name: Cache Gradle wrapper
uses: actions/cache@v1
with:
path: ~/.gradle/wrapper
key: ${{ runner.os }}-gradle-wrapper-${{ hashFiles('gradle/wrapper/gradle-wrapper.properties') }}
- name: Cache Gradle cache
uses: actions/cache@v2
with:
path: ~/.gradle/caches
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle.kts') }}
restore-keys: ${{ runner.os }}-gradle
- name: Release a new stable version to Maven Central - name: Release a new stable version to Maven Central
run: ./gradlew publish :flatlaf-demo:build :flatlaf-theme-editor:build -Drelease=true run: ./gradlew publish :flatlaf-demo:build :flatlaf-theme-editor:build -Drelease=true

View File

@@ -11,14 +11,12 @@ on:
paths: paths:
- 'flatlaf-natives/flatlaf-natives-windows/**' - 'flatlaf-natives/flatlaf-natives-windows/**'
- '.github/workflows/natives.yml' - '.github/workflows/natives.yml'
- 'gradle/wrapper/gradle-wrapper.properties'
pull_request: pull_request:
branches: branches:
- '*' - '*'
paths: paths:
- 'flatlaf-natives/flatlaf-natives-windows/**' - 'flatlaf-natives/flatlaf-natives-windows/**'
- '.github/workflows/natives.yml' - '.github/workflows/natives.yml'
- 'gradle/wrapper/gradle-wrapper.properties'
jobs: jobs:
Windows: Windows:
@@ -29,17 +27,28 @@ jobs:
- uses: gradle/wrapper-validation-action@v1 - uses: gradle/wrapper-validation-action@v1
- name: Setup Java 11 - name: Setup Java 1.8
uses: actions/setup-java@v2 uses: actions/setup-java@v1
with: with:
java-version: 11 java-version: 1.8
distribution: adopt
cache: gradle - name: Cache Gradle wrapper
uses: actions/cache@v1
with:
path: ~/.gradle/wrapper
key: ${{ runner.os }}-gradle-wrapper-${{ hashFiles('gradle/wrapper/gradle-wrapper.properties') }}
- name: Cache Gradle cache
uses: actions/cache@v2
with:
path: |
~/.gradle/caches
!~/.gradle/caches/modules-2/modules-2.lock
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle.kts') }}
restore-keys: ${{ runner.os }}-gradle
- name: Build with Gradle - name: Build with Gradle
# --no-daemon is necessary on Windows otherwise caching Gradle would fail with: run: ./gradlew :flatlaf-natives-windows:build
# tar.exe: Couldn't open ~/.gradle/caches/modules-2/modules-2.lock: Permission denied
run: ./gradlew :flatlaf-natives-windows:build --no-daemon
- name: Upload artifacts - name: Upload artifacts
uses: actions/upload-artifact@v2 uses: actions/upload-artifact@v2

View File

@@ -1,41 +1,7 @@
FlatLaf Change Log FlatLaf Change Log
================== ==================
## 2.0 ## 2.0-SNAPSHOT
- Added system property `flatlaf.nativeLibraryPath` to load native libraries
from a directory. (PR #453)
- Fixed "endless recursion in font" exception in
`FlatLaf$ActiveFont.createValue()` if `UIManager.getFont()` is invoked from
multiple threads. (issue #456)
- PasswordField: Preserve reveal button state when switching theme. (PR #442;
issue #173)
- PasswordField: Reveal button did not show password if
`JPasswordField.setEchoChar()` was invoked from application. (PR #442; issue
#173)
- Slider: Fixed/improved focused indicator color when changing accent color. (PR
#375)
- TextField:
- Improved hover/pressed/selected colors of leading/trailing buttons (e.g.
"reveal" button in password field). (issue #452)
- Clear button no longer paints over round border. (issue #451)
- Extras: Fixed concurrent loading of SVG icons on multiple threads. (issue
#459)
- Use FlatLaf native window decorations by default when running in
[JetBrains Runtime](https://github.com/JetBrains/JetBrainsRuntime/wiki)
(instead of using JetBrains custom decorations). System variable
`flatlaf.useJetBrainsCustomDecorations` is now `false` by default (was `true`
in FlatLaf 1.x). (issue #454)
- Native window decorations:
- Fixed blurry iconify/maximize/close button hover rectangles at 125%, 150% or
175% scaling. (issue #431)
- Updated maximize and restore icons for Windows 11 style. (requires Java
8u321, 11.0.14, 17.0.2 or 18+)
- Updated hover and pressed colors of iconify/maximize/close buttons for
Windows 11 style.
## 2.0-rc1
#### New features and improvements #### New features and improvements
@@ -62,18 +28,9 @@ FlatLaf Change Log
setting UI default `OptionPane.showIcon` to `true`. (issue #416) setting UI default `OptionPane.showIcon` to `true`. (issue #416)
- No longer show the Java "duke/cup" icon if no window icon image is set. - No longer show the Java "duke/cup" icon if no window icon image is set.
(issue #416) (issue #416)
- TextField, FormattedTextField and PasswordField: - TextField, FormattedTextField and PasswordField: Support leading and trailing
- Support leading and trailing icons (set client property icons (set client property `JTextField.leadingIcon` or
`JTextField.leadingIcon` or `JTextField.trailingIcon` to a `JTextField.trailingIcon` to an `Icon`). (PR #378; issue #368)
`javax.swing.Icon`). (PR #378; issue #368)
- Support leading and trailing components (set client property
`JTextField.leadingComponent` or `JTextField.trailingComponent` to a
`java.awt.Component`). (PR #386)
- Support "clear" (or "cancel") button to empty text field. Only shown if text
field is not empty, editable and enabled. (set client property
`JTextField.showClearButton` to `true`). (PR #442)
- PasswordField: Support reveal (or "eye") button to show password. (see UI
value `PasswordField.showRevealButton`) (PR #442; issue #173)
- TextComponents: Double/triple-click-and-drag now extends selection by whole - TextComponents: Double/triple-click-and-drag now extends selection by whole
words/lines. words/lines.
- Theming improvements: Reworks core themes to make it easier to create new - Theming improvements: Reworks core themes to make it easier to create new
@@ -104,10 +61,6 @@ FlatLaf Change Log
- Slider: Support specifying width of thumb border (see UI value - Slider: Support specifying width of thumb border (see UI value
`Slider.thumbBorderWidth`). `Slider.thumbBorderWidth`).
- TabbedPane: Optionally paint selected tab as card. (PR #343) - TabbedPane: Optionally paint selected tab as card. (PR #343)
- MenuItem:
- Paint the selected icon when the item is selected. (PR #415)
- Vertically align text if icons have different widths. (issue #437)
- Panel: Support painting background with rounded corners. (issue #367)
- Added more color functions to class `ColorFunctions` for easy use in - Added more color functions to class `ColorFunctions` for easy use in
applications: `lighten()`, `darken()`, `saturate()`, `desaturate()`, `spin()`, applications: `lighten()`, `darken()`, `saturate()`, `desaturate()`, `spin()`,
`tint()`, `shade()` and `luma()`. `tint()`, `shade()` and `luma()`.
@@ -120,40 +73,6 @@ FlatLaf Change Log
- `FlatSVGIcon`: Support loading SVG from `URL` (for JPMS), `URI`, `File` or - `FlatSVGIcon`: Support loading SVG from `URL` (for JPMS), `URI`, `File` or
`InputStream`. (issues #419 and #325) `InputStream`. (issues #419 and #325)
- `FlatSVGUtils`: Support loading SVG from `URL` (for JPMS). (issue #325) - `FlatSVGUtils`: Support loading SVG from `URL` (for JPMS). (issue #325)
- SwingX:
- New "column control" icon for `JXTable` that scales and uses antialiasing.
(issue #434)
#### Fixed bugs
- Native window decorations: Fixed `UnsatisfiedLinkError` on Windows 11 for ARM
processors. (issue #443)
- MenuBar: Do not fill background if non-opaque and having custom background
color. (issue #409)
- InternalFrame: Fill background to avoid that parent may shine through internal
frame if it contains non-opaque components. (better fix for issue #274)
- SwingX: Fixed `NullPointerException` in `FlatCaret` when using
`org.jdesktop.swingx.prompt.PromptSupport.setPrompt()` on a text field and
then switching theme.
## 1.6.5
#### Fixed bugs
- Linux: Fixed font problems when running on Oracle Java (OpenJDK is not
affected):
- oversized text if system font is "Inter" (issue #427)
- missing text if system font is "Cantarell" (on Fedora)
- MenuItem: Changed accelerator delimiter from `-` to `+`. (Windows and Linux).
- ComboBox: Fixed occasional `StackOverflowError` when modifying combo box not
on AWT thread. (issue #432)
- macOS: Fixed `NullPointerException` when using AWT component
`java.awt.Choice`. (issue #439)
- Native window decorations: Do not exit application with `UnsatisfiedLinkError`
in case that FlatLaf DLL cannot be executed because of restrictions on
temporary directory. Instead, continue with default window decorations. (issue
#436)
## 1.6.4 ## 1.6.4

View File

@@ -99,8 +99,6 @@ For more information and documentation visit
- [Customizing](https://www.formdev.com/flatlaf/customizing/) - [Customizing](https://www.formdev.com/flatlaf/customizing/)
- [How to Customize](https://www.formdev.com/flatlaf/how-to-customize/) - [How to Customize](https://www.formdev.com/flatlaf/how-to-customize/)
- [Properties Files](https://www.formdev.com/flatlaf/properties-files/) - [Properties Files](https://www.formdev.com/flatlaf/properties-files/)
- [Components UI Properties](https://www.formdev.com/flatlaf/components/)
- [Typography](https://www.formdev.com/flatlaf/typography/)
- [Client Properties](https://www.formdev.com/flatlaf/client-properties/) - [Client Properties](https://www.formdev.com/flatlaf/client-properties/)
- [System Properties](https://www.formdev.com/flatlaf/system-properties/) - [System Properties](https://www.formdev.com/flatlaf/system-properties/)
@@ -116,11 +114,6 @@ Buzz
Applications using FlatLaf Applications using FlatLaf
-------------------------- --------------------------
- ![New](images/new.svg) [MooInfo](https://github.com/rememberber/MooInfo) -
visual implementation of OSHI, to view information about the system and
hardware
- ![New](images/new.svg) [Jailer](https://github.com/Wisser/Jailer) 11.2 -
database subsetting and relational data browsing tool
- [Apache NetBeans](https://netbeans.apache.org/) 11.3 - IDE for Java, PHP, HTML - [Apache NetBeans](https://netbeans.apache.org/) 11.3 - IDE for Java, PHP, HTML
and much more and much more
- [jclasslib bytecode viewer](https://github.com/ingokegel/jclasslib) 5.5 - [jclasslib bytecode viewer](https://github.com/ingokegel/jclasslib) 5.5
@@ -148,8 +141,6 @@ Applications using FlatLaf
[OpenStreetMap](https://www.openstreetmap.org/) (requires FlatLaf JOSM plugin) [OpenStreetMap](https://www.openstreetmap.org/) (requires FlatLaf JOSM plugin)
- [jAlbum](https://jalbum.net/) 21 (**commercial**) - creates photo album - [jAlbum](https://jalbum.net/) 21 (**commercial**) - creates photo album
websites websites
- ![New](images/new.svg) [PDF Studio](https://www.qoppa.com/pdfstudio/) 2021
(**commercial**) - create, review and edit PDF documents
- [XMLmind XML Editor](https://www.xmlmind.com/xmleditor/) 9.3 (**commercial**) - [XMLmind XML Editor](https://www.xmlmind.com/xmleditor/) 9.3 (**commercial**)
- [Total Validator](https://www.totalvalidator.com/) 15 (**commercial**) - - [Total Validator](https://www.totalvalidator.com/) 15 (**commercial**) -
checks your website checks your website
@@ -182,7 +173,7 @@ Applications using FlatLaf
systems development platform systems development platform
- [JPass](https://github.com/gaborbata/jpass) - password manager with strong - [JPass](https://github.com/gaborbata/jpass) - password manager with strong
encryption encryption
- [Jes - Die Java-EÜR](https://www.jes-eur.de) - [Jes - Die Java-EÜR](https://www.jes-eur.de)
- [Mapton](https://mapton.org/) 2.0 - [Mapton](https://mapton.org/) 2.0
([source code](https://github.com/trixon/mapton)) - some kind of map ([source code](https://github.com/trixon/mapton)) - some kind of map
application (based on NetBeans platform) application (based on NetBeans platform)

View File

@@ -14,8 +14,8 @@
* limitations under the License. * limitations under the License.
*/ */
val releaseVersion = "2.0" val releaseVersion = "1.6.4"
val developmentVersion = "2.1-SNAPSHOT" val developmentVersion = "2.0-SNAPSHOT"
version = if( java.lang.Boolean.getBoolean( "release" ) ) releaseVersion else developmentVersion version = if( java.lang.Boolean.getBoolean( "release" ) ) releaseVersion else developmentVersion

View File

@@ -28,7 +28,7 @@ if( JavaVersion.current() >= JavaVersion.VERSION_1_9 ) {
} }
dependencies { dependencies {
add( "java9Implementation", sourceSets.main.get().output ) add( "java9Compile", sourceSets.main.get().output )
} }
tasks { tasks {

2151
compare1.txt Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -763,9 +763,9 @@ public interface FlatClientProperties
/** /**
* Specifies a component that will be placed at the leading edge of the tabs area. * Specifies a component that will be placed at the leading edge of the tabs area.
* <p> * <p>
* For top and bottom tab placement, the laid out component size will be * For top and bottom tab placement, the layed out component size will be
* the preferred component width and the tab area height.<br> * the preferred component width and the tab area height.<br>
* For left and right tab placement, the laid out component size will be * For left and right tab placement, the layed out component size will be
* the tab area width and the preferred component height. * the tab area width and the preferred component height.
* <p> * <p>
* <strong>Component</strong> {@link javax.swing.JTabbedPane}<br> * <strong>Component</strong> {@link javax.swing.JTabbedPane}<br>
@@ -776,9 +776,9 @@ public interface FlatClientProperties
/** /**
* Specifies a component that will be placed at the trailing edge of the tabs area. * Specifies a component that will be placed at the trailing edge of the tabs area.
* <p> * <p>
* For top and bottom tab placement, the laid out component size will be * For top and bottom tab placement, the layed out component size will be
* the available horizontal space (minimum is preferred component width) and the tab area height.<br> * the available horizontal space (minimum is preferred component width) and the tab area height.<br>
* For left and right tab placement, the laid out component size will be * For left and right tab placement, the layed out component size will be
* the tab area width and the available vertical space (minimum is preferred component height). * the tab area width and the available vertical space (minimum is preferred component height).
* <p> * <p>
* <strong>Component</strong> {@link javax.swing.JTabbedPane}<br> * <strong>Component</strong> {@link javax.swing.JTabbedPane}<br>
@@ -863,98 +863,6 @@ public interface FlatClientProperties
*/ */
String TEXT_FIELD_TRAILING_ICON = "JTextField.trailingIcon"; String TEXT_FIELD_TRAILING_ICON = "JTextField.trailingIcon";
/**
* Specifies a component that will be placed at the leading edge of the text field.
* <p>
* The component will be positioned inside and aligned to the visible text field border.
* There is no gap between the visible border and the component.
* The laid out component size will be the preferred component width
* and the inner text field height.
* <p>
* The component should be not opaque because the text field border is painted
* slightly inside the usually visible border in some cases.
* E.g. when focused (in some themes) or when an outline color is specified
* (see {@link #OUTLINE}).
* <p>
* The component is prepared in the following way:
* <ul>
* <li>Component client property {@link #STYLE_CLASS} is set to {@code inTextField}.
* <li>If component is a button or toggle button, client property {@link #BUTTON_TYPE}
* is set to {@link #BUTTON_TYPE_TOOLBAR_BUTTON}
* and button cursor is set to default cursor (if not set).
* <li>If component is a toolbar, client property {@link #STYLE_CLASS}
* is set to {@code inTextField} on all toolbar children
* and toolbar cursor is set to default cursor (if not set).
* </ul>
* Because text fields use the text cursor by default and the cursor is inherited by child components,
* it may be necessary to explicitly set component cursor if you e.g. need the default arrow cursor.
* E.g. {@code comp.setCursor( Cursor.getDefaultCursor() )}.
* <p>
* Styling is used to modify insets/margins and appearance of buttons and toolbars
* so that they fit nicely into the text field and do not increase text field height.
* See styles {@code [style]Button.inTextField} and {@code [style]ToolBar.inTextField}
* in {@code Flat[Light|Dark]Laf.properties}.
* <p>
* <strong>Component</strong> {@link javax.swing.JTextField} (and subclasses)<br>
* <strong>Value type</strong> {@link javax.swing.JComponent}
*
* @since 2
*/
String TEXT_FIELD_LEADING_COMPONENT = "JTextField.leadingComponent";
/**
* Specifies a component that will be placed at the trailing edge of the text field.
* <p>
* See {@link #TEXT_FIELD_LEADING_COMPONENT} for details.
* <p>
* <strong>Component</strong> {@link javax.swing.JTextField} (and subclasses)<br>
* <strong>Value type</strong> {@link javax.swing.JComponent}
*
* @since 2
*/
String TEXT_FIELD_TRAILING_COMPONENT = "JTextField.trailingComponent";
/**
* Specifies whether a "clear" (or "cancel") button is shown on the trailing side
* if the text field is not empty, editable and enabled. Default is {@code false}.
* <p>
* <strong>Component</strong> {@link javax.swing.JTextField} (and subclasses)<br>
* <strong>Value type</strong> {@link java.lang.Boolean}
*
* @since 2
*/
String TEXT_FIELD_SHOW_CLEAR_BUTTON = "JTextField.showClearButton";
/**
* Specifies the callback that is invoked when a "clear" (or "cancel") button is clicked.
* If a callback is specified than it is responsible for clearing the text field.
* Without callback, the text field clears itself.
* <p>
* Either use a {@link java.lang.Runnable}:
* <pre>{@code
* myTextField.putClientProperty( "JTextField.clearCallback",
* (Runnable) () -> {
* // clear field here or cancel search
* } );
* }</pre>
* Or use a {@link java.util.function.Consumer}&lt;javax.swing.text.JTextComponent&gt;
* that receives the text field as parameter:
* <pre>{@code
* myTextField.putClientProperty( "JTextField.clearCallback",
* (Consumer<JTextComponent>) textField -> {
* // clear field here or cancel search
* } );
* }</pre>
* <p>
* <strong>Component</strong> {@link javax.swing.JTextField} (and subclasses)<br>
* <strong>Value type</strong> {@link java.lang.Runnable}
* or {@link java.util.function.Consumer}&lt;javax.swing.text.JTextComponent&gt;
*
* @see #TEXT_FIELD_SHOW_CLEAR_BUTTON
* @since 2
*/
String TEXT_FIELD_CLEAR_CALLBACK = "JTextField.clearCallback";
//---- JToggleButton ------------------------------------------------------ //---- JToggleButton ------------------------------------------------------
/** /**

View File

@@ -52,7 +52,6 @@ import javax.swing.ImageIcon;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.JDialog; import javax.swing.JDialog;
import javax.swing.JFrame; import javax.swing.JFrame;
import javax.swing.JMenuBar;
import javax.swing.LookAndFeel; import javax.swing.LookAndFeel;
import javax.swing.PopupFactory; import javax.swing.PopupFactory;
import javax.swing.RootPaneContainer; import javax.swing.RootPaneContainer;
@@ -1037,23 +1036,12 @@ public abstract class FlatLaf
/** /**
* Revalidate and repaint all displayable frames and dialogs. * Revalidate and repaint all displayable frames and dialogs.
* <p>
* Useful to update UI after changing {@code TitlePane.menuBarEmbedded}.
* *
* @since 1.1.2 * @since 1.1.2
*/ */
public static void revalidateAndRepaintAllFramesAndDialogs() { public static void revalidateAndRepaintAllFramesAndDialogs() {
for( Window w : Window.getWindows() ) { for( Window w : Window.getWindows() ) {
if( isDisplayableFrameOrDialog( w ) ) { if( isDisplayableFrameOrDialog( w ) ) {
// revalidate menu bar
JMenuBar menuBar = (w instanceof JFrame)
? ((JFrame)w).getJMenuBar()
: (w instanceof JDialog
? ((JDialog)w).getJMenuBar()
: null);
if( menuBar != null )
menuBar.revalidate();
w.revalidate(); w.revalidate();
w.repaint(); w.repaint();
} }
@@ -1062,9 +1050,6 @@ public abstract class FlatLaf
/** /**
* Repaint all displayable frames and dialogs. * Repaint all displayable frames and dialogs.
* <p>
* Useful to update UI after changing {@code TitlePane.unifiedBackground},
* {@code MenuItem.selectionType} or {@code Component.hideMnemonics}.
* *
* @since 1.1.2 * @since 1.1.2
*/ */
@@ -1223,9 +1208,6 @@ public abstract class FlatLaf
} }
private Object getValue( Object key ) { private Object getValue( Object key ) {
// use local variable for getters to avoid potential multi-threading issues
List<Function<Object, Object>> uiDefaultsGetters = FlatLaf.this.uiDefaultsGetters;
if( uiDefaultsGetters == null ) if( uiDefaultsGetters == null )
return null; return null;
@@ -1279,9 +1261,8 @@ public abstract class FlatLaf
this.scaleSize = scaleSize; this.scaleSize = scaleSize;
} }
// using synchronized to avoid exception if invoked at the same time on multiple threads
@Override @Override
public synchronized Object createValue( UIDefaults table ) { public Object createValue( UIDefaults table ) {
if( inCreateValue ) if( inCreateValue )
throw new IllegalStateException( "FlatLaf: endless recursion in font" ); throw new IllegalStateException( "FlatLaf: endless recursion in font" );
@@ -1343,19 +1324,9 @@ public abstract class FlatLaf
} }
// derive font // derive font
if( newStyle != baseStyle || newSize != baseSize ) { if( newStyle != baseStyle || newSize != baseSize )
// hack for font "Ubuntu Medium" on Linux, which curiously belongs
// to family "Ubuntu Light" and using deriveFont() would create a light font
if( "Ubuntu Medium".equalsIgnoreCase( baseFont.getName() ) &&
"Ubuntu Light".equalsIgnoreCase( baseFont.getFamily() ) )
{
Font font = createCompositeFont( "Ubuntu Medium", newStyle, newSize );
if( !isFallbackFont( font ) )
return toUIResource( font );
}
return toUIResource( baseFont.deriveFont( newStyle, newSize ) ); return toUIResource( baseFont.deriveFont( newStyle, newSize ) );
} else else
return toUIResource( baseFont ); return toUIResource( baseFont );
} }

View File

@@ -81,7 +81,7 @@ public interface FlatSystemProperties
* {@link FlatClientProperties#USE_WINDOW_DECORATIONS} and * {@link FlatClientProperties#USE_WINDOW_DECORATIONS} and
* UI default {@code TitlePane.useWindowDecorations}. * UI default {@code TitlePane.useWindowDecorations}.
* <p> * <p>
* (requires Window 10/11) * (requires Window 10)
* <p> * <p>
* <strong>Allowed Values</strong> {@code false} and {@code true}<br> * <strong>Allowed Values</strong> {@code false} and {@code true}<br>
* <strong>Default</strong> none * <strong>Default</strong> none
@@ -92,16 +92,16 @@ public interface FlatSystemProperties
* Specifies whether JetBrains Runtime custom window decorations should be used * Specifies whether JetBrains Runtime custom window decorations should be used
* when creating {@code JFrame} or {@code JDialog}. * when creating {@code JFrame} or {@code JDialog}.
* Requires that the application runs in a * Requires that the application runs in a
* <a href="https://github.com/JetBrains/JetBrainsRuntime/wiki">JetBrains Runtime</a> * <a href="https://confluence.jetbrains.com/display/JBR/JetBrains+Runtime">JetBrains Runtime</a>
* (based on OpenJDK). * (based on OpenJDK).
* <p> * <p>
* Setting this to {@code false} disables using JetBrains Runtime custom window decorations. * Setting this to {@code false} disables using JetBrains Runtime custom window decorations.
* Then FlatLaf native window decorations are used. * Then FlatLaf native window decorations are used.
* <p> * <p>
* (requires Window 10/11) * (requires Window 10)
* <p> * <p>
* <strong>Allowed Values</strong> {@code false} and {@code true}<br> * <strong>Allowed Values</strong> {@code false} and {@code true}<br>
* <strong>Default</strong> {@code false} (since v2; was {@code true} in v1) * <strong>Default</strong> {@code true}
*/ */
String USE_JETBRAINS_CUSTOM_DECORATIONS = "flatlaf.useJetBrainsCustomDecorations"; String USE_JETBRAINS_CUSTOM_DECORATIONS = "flatlaf.useJetBrainsCustomDecorations";
@@ -116,7 +116,7 @@ public interface FlatSystemProperties
* {@link FlatClientProperties#MENU_BAR_EMBEDDED} and * {@link FlatClientProperties#MENU_BAR_EMBEDDED} and
* UI default {@code TitlePane.menuBarEmbedded}. * UI default {@code TitlePane.menuBarEmbedded}.
* <p> * <p>
* (requires Window 10/11) * (requires Window 10)
* <p> * <p>
* <strong>Allowed Values</strong> {@code false} and {@code true}<br> * <strong>Allowed Values</strong> {@code false} and {@code true}<br>
* <strong>Default</strong> none * <strong>Default</strong> none
@@ -139,15 +139,6 @@ public interface FlatSystemProperties
*/ */
String USE_TEXT_Y_CORRECTION = "flatlaf.useTextYCorrection"; String USE_TEXT_Y_CORRECTION = "flatlaf.useTextYCorrection";
/**
* Specifies a directory in which the native FlatLaf library have been extracted.
* The path can be absolute or relative to current application working directory.
* This can be used to avoid extraction of the native libraries to the temporary directory at runtime.
*
* @since 2
*/
String NATIVE_LIBRARY_PATH = "flatlaf.nativeLibraryPath";
/** /**
* Checks whether a system property is set and returns {@code true} if its value * Checks whether a system property is set and returns {@code true} if its value
* is {@code "true"} (case-insensitive), otherwise it returns {@code false}. * is {@code "true"} (case-insensitive), otherwise it returns {@code false}.

View File

@@ -17,7 +17,6 @@
package com.formdev.flatlaf; package com.formdev.flatlaf;
import java.awt.Font; import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.GraphicsConfiguration; import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment; import java.awt.GraphicsEnvironment;
import java.awt.Toolkit; import java.awt.Toolkit;
@@ -29,7 +28,7 @@ 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 javax.swing.text.StyleContext;
import com.formdev.flatlaf.util.LoggingFacade; import com.formdev.flatlaf.util.LoggingFacade;
import com.formdev.flatlaf.util.StringUtils; import com.formdev.flatlaf.util.StringUtils;
import com.formdev.flatlaf.util.SystemInfo; import com.formdev.flatlaf.util.SystemInfo;
@@ -122,25 +121,14 @@ class LinuxFontPolicy
for(;;) { for(;;) {
Font font = createFont( family, style, size, dsize ); Font font = createFont( family, style, size, dsize );
if( Font.DIALOG.equals( family ) )
return font;
// if the font family does not match any font on the system, "Dialog" family is returned // if the font family does not match any font on the system, "Dialog" family is returned
if( !Font.DIALOG.equals( font.getFamily() ) ) { if( !"Dialog".equals( font.getFamily() ) || "Dialog".equals( family ) )
// check for font problems
// - font height much larger than expected (e.g. font Inter; Oracle Java 8)
// - character width is zero (e.g. font Cantarell; Fedora; Oracle Java 8)
FontMetrics fm = StyleContext.getDefaultStyleContext().getFontMetrics( font );
if( fm.getHeight() > size * 2 || fm.stringWidth( "a" ) == 0 )
return createFont( Font.DIALOG, style, size, dsize );
return font; return font;
}
// find last word in family // find last word in family
int index = family.lastIndexOf( ' ' ); int index = family.lastIndexOf( ' ' );
if( index < 0 ) if( index < 0 )
return createFont( Font.DIALOG, style, size, dsize ); return createFont( "Dialog", style, size, dsize );
// check whether last work contains some font weight (e.g. Ultra-Bold or Heavy) // check whether last work contains some font weight (e.g. Ultra-Bold or Heavy)
String lastWord = family.substring( index + 1 ).toLowerCase(); String lastWord = family.substring( index + 1 ).toLowerCase();

View File

@@ -80,7 +80,7 @@ class UIDefaultsLoader
private static final String OPTIONAL_PREFIX = "?"; private static final String OPTIONAL_PREFIX = "?";
private static final String WILDCARD_PREFIX = "*."; private static final String WILDCARD_PREFIX = "*.";
static final String KEY_VARIABLES = "FlatLaf.internal.variables"; private static final String KEY_VARIABLES = "FlatLaf.internal.variables";
private static int parseColorDepth; private static int parseColorDepth;
@@ -364,12 +364,6 @@ class UIDefaultsLoader
if( resultValueType == null ) if( resultValueType == null )
resultValueType = tempResultValueType; resultValueType = tempResultValueType;
// do not parse styles here
if( key.startsWith( "[style]" ) ) {
resultValueType[0] = ValueType.STRING;
return value;
}
value = value.trim(); value = value.trim();
// null // null
@@ -588,18 +582,17 @@ class UIDefaultsLoader
private static Object parseBorder( String value, Function<String, String> resolver, List<ClassLoader> addonClassLoaders ) { 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[,lineThickness[,arc]]] // top,left,bottom,right[,lineColor[,lineThickness]]
List<String> parts = splitFunctionParams( value, ',' ); List<String> parts = splitFunctionParams( value, ',' );
Insets insets = parseInsets( value ); Insets insets = parseInsets( value );
ColorUIResource lineColor = (parts.size() >= 5) ColorUIResource lineColor = (parts.size() >= 5)
? (ColorUIResource) parseColorOrFunction( resolver.apply( parts.get( 4 ) ), resolver, true ) ? (ColorUIResource) parseColorOrFunction( resolver.apply( parts.get( 4 ) ), resolver, true )
: null; : null;
float lineThickness = (parts.size() >= 6 && !parts.get( 5 ).isEmpty()) ? parseFloat( parts.get( 5 ), true ) : 1f; float lineThickness = (parts.size() >= 6) ? parseFloat( parts.get( 5 ), true ) : 1f;
int arc = (parts.size() >= 7) ? parseInteger( parts.get( 6 ), true ) : 0;
return (LazyValue) t -> { return (LazyValue) t -> {
return (lineColor != null) return (lineColor != null)
? new FlatLineBorder( insets, lineColor, lineThickness, arc ) ? new FlatLineBorder( insets, lineColor, lineThickness )
: new FlatEmptyBorder( insets ); : new FlatEmptyBorder( insets );
}; };
} else } else
@@ -902,32 +895,21 @@ class UIDefaultsLoader
* Syntax: fade(color,amount[,options]) * Syntax: fade(color,amount[,options])
* - color: a color (e.g. #f00) or a color function * - color: a color (e.g. #f00) or a color function
* - amount: percentage 0-100% * - amount: percentage 0-100%
* - options: [derived] [lazy] * - options: [derived]
*/ */
private static Object parseColorFade( List<String> params, Function<String, String> resolver, boolean reportError ) { private static Object parseColorFade( List<String> params, Function<String, String> resolver, boolean reportError ) {
String colorStr = params.get( 0 ); String colorStr = params.get( 0 );
int amount = parsePercentage( params.get( 1 ) ); int amount = parsePercentage( params.get( 1 ) );
boolean derived = false; boolean derived = false;
boolean lazy = false;
if( params.size() > 2 ) { if( params.size() > 2 ) {
String options = params.get( 2 ); String options = params.get( 2 );
derived = options.contains( "derived" ); derived = options.contains( "derived" );
lazy = options.contains( "lazy" );
} }
// create function // create function
ColorFunction function = new ColorFunctions.Fade( amount ); ColorFunction function = new ColorFunctions.Fade( amount );
if( lazy ) {
return (LazyValue) t -> {
Object color = lazyUIManagerGet( colorStr );
return (color instanceof Color)
? new ColorUIResource( ColorFunctions.applyFunctions( (Color) color, function ) )
: null;
};
}
// parse base color, apply function and create derived color // parse base color, apply function and create derived color
return parseFunctionBaseColor( colorStr, function, derived, resolver, reportError ); return parseFunctionBaseColor( colorStr, function, derived, resolver, reportError );
} }

View File

@@ -69,7 +69,13 @@ public abstract class FlatAbstractIcon
} }
} }
protected abstract void paintIcon( Component c, Graphics2D g2 ); /**
* Paint the icon at {@code [0,0]} location.
* <p>
* The given graphics context is scaled.
* Use unscaled coordinates, width and height for painting.
*/
protected abstract void paintIcon( Component c, Graphics2D g );
@Override @Override
public int getIconWidth() { public int getIconWidth() {

View File

@@ -21,6 +21,7 @@ import java.awt.Component;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import com.formdev.flatlaf.util.AnimatedIcon; import com.formdev.flatlaf.util.AnimatedIcon;
import com.formdev.flatlaf.util.AnimatedPainter;
/** /**
* Base class for animated icons that scales width and height, creates and initializes * Base class for animated icons that scales width and height, creates and initializes
@@ -30,7 +31,7 @@ import com.formdev.flatlaf.util.AnimatedIcon;
* <p> * <p>
* This class does not store any state information (needed for animation) in its instance. * This class does not store any state information (needed for animation) in its instance.
* Instead a client property is set on the painted component. * Instead a client property is set on the painted component.
* This makes it possible to use a share icon instance for multiple components. * This makes it possible to use a shared icon instance for multiple components.
* *
* @author Karl Tauber * @author Karl Tauber
*/ */
@@ -45,11 +46,34 @@ public abstract class FlatAnimatedIcon
@Override @Override
public void paintIcon( Component c, Graphics g, int x, int y ) { public void paintIcon( Component c, Graphics g, int x, int y ) {
super.paintIcon( c, g, x, y ); super.paintIcon( c, g, x, y );
AnimatedIcon.AnimationSupport.saveIconLocation( this, c, x, y ); AnimatedPainter.saveRepaintLocation( this, c, x, y );
} }
@Override @Override
protected void paintIcon( Component c, Graphics2D g ) { protected void paintIcon( Component c, Graphics2D g ) {
AnimatedIcon.AnimationSupport.paintIcon( this, c, g, 0, 0 ); paintWithAnimation( c, g, 0, 0, getIconWidth(), getIconHeight() );
} }
/**
* Delegates painting to {@link #paintIconAnimated(Component, Graphics2D, float[])}.
* Ignores the given bounds because {@code [x,y]} are always {@code [0,0]} and
* {@code [width,height]} are scaled, but painting code should use unscaled width
* and height because given graphics context is scaled.
*
* @since 2
*/
@Override
public void paintAnimated( Component c, Graphics2D g, int x, int y, int width, int height, float[] animatedValues ) {
paintIconAnimated( c, g, animatedValues );
}
/**
* Paint the icon at {@code 0,0} location.
* <p>
* The given graphics context is scaled.
* Use unscaled coordinates, width and height for painting.
*
* @since 2
*/
protected abstract void paintIconAnimated( Component c, Graphics2D g, float[] animatedValues );
} }

View File

@@ -47,16 +47,8 @@ public class FlatClearIcon
@Styleable protected Color clearIconHoverColor = UIManager.getColor( "SearchField.clearIconHoverColor" ); @Styleable protected Color clearIconHoverColor = UIManager.getColor( "SearchField.clearIconHoverColor" );
@Styleable protected Color clearIconPressedColor = UIManager.getColor( "SearchField.clearIconPressedColor" ); @Styleable protected Color clearIconPressedColor = UIManager.getColor( "SearchField.clearIconPressedColor" );
private final boolean ignoreButtonState;
public FlatClearIcon() { public FlatClearIcon() {
this( false );
}
/** @since 2 */
public FlatClearIcon( boolean ignoreButtonState ) {
super( 16, 16, null ); super( 16, 16, null );
this.ignoreButtonState = ignoreButtonState;
} }
/** @since 2 */ /** @since 2 */
@@ -71,7 +63,7 @@ public class FlatClearIcon
@Override @Override
protected void paintIcon( Component c, Graphics2D g ) { protected void paintIcon( Component c, Graphics2D g ) {
if( !ignoreButtonState && c instanceof AbstractButton ) { if( c instanceof AbstractButton ) {
ButtonModel model = ((AbstractButton)c).getModel(); ButtonModel model = ((AbstractButton)c).getModel();
if( model.isPressed() || model.isRollover() ) { if( model.isPressed() || model.isRollover() ) {
/* /*

View File

@@ -21,16 +21,14 @@ import java.awt.Graphics;
import java.awt.Graphics2D; import java.awt.Graphics2D;
/** /**
* "arrow" icon for {@link javax.swing.JMenuItem}, {@link javax.swing.JCheckBoxMenuItem} * "arrow" icon for {@link javax.swing.JMenuItem}.
* and {@link javax.swing.JRadioButtonMenuItem}.
* *
* @author Karl Tauber * @author Karl Tauber
*/ */
public class FlatMenuItemArrowIcon public class FlatMenuItemArrowIcon
extends FlatAbstractIcon extends FlatMenuArrowIcon
{ {
public FlatMenuItemArrowIcon() { public FlatMenuItemArrowIcon() {
super( 6, 10, null );
} }
@Override @Override

View File

@@ -1,56 +0,0 @@
/*
* Copyright 2021 FormDev Software GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.formdev.flatlaf.icons;
import java.awt.Component;
import java.awt.Graphics2D;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Path2D;
import java.awt.geom.Rectangle2D;
import javax.swing.UIManager;
/**
* "eye" icon for {@link javax.swing.JPasswordField}.
*
* @uiDefault PasswordField.revealIconColor Color
*
* @author Karl Tauber
* @since 2
*/
public class FlatRevealIcon
extends FlatAbstractIcon
{
public FlatRevealIcon() {
super( 16, 16, UIManager.getColor( "PasswordField.revealIconColor" ) );
}
@Override
protected void paintIcon( Component c, Graphics2D g ) {
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD );
path.append( new Ellipse2D.Float( 5.15f, 6.15f, 5.7f, 5.7f ), false );
path.append( new Ellipse2D.Float( 6, 7, 4, 4 ), false );
g.fill( path );
Path2D path2 = new Path2D.Float( Path2D.WIND_EVEN_ODD );
path2.append( new Ellipse2D.Float( 2.15f, 4.15f, 11.7f, 11.7f ), false );
path2.append( new Ellipse2D.Float( 3, 5, 10, 10 ), false );
Area area = new Area( path2 );
area.subtract( new Area( new Rectangle2D.Float( 0, 9.5f, 16, 16 ) ) );
g.fill( area );
}
}

View File

@@ -45,16 +45,8 @@ public class FlatSearchIcon
@Styleable protected Color searchIconHoverColor = UIManager.getColor( "SearchField.searchIconHoverColor" ); @Styleable protected Color searchIconHoverColor = UIManager.getColor( "SearchField.searchIconHoverColor" );
@Styleable protected Color searchIconPressedColor = UIManager.getColor( "SearchField.searchIconPressedColor" ); @Styleable protected Color searchIconPressedColor = UIManager.getColor( "SearchField.searchIconPressedColor" );
private final boolean ignoreButtonState;
public FlatSearchIcon() { public FlatSearchIcon() {
this( false );
}
/** @since 2 */
public FlatSearchIcon( boolean ignoreButtonState ) {
super( 16, 16, null ); super( 16, 16, null );
this.ignoreButtonState = ignoreButtonState;
} }
/** @since 2 */ /** @since 2 */
@@ -78,10 +70,8 @@ public class FlatSearchIcon
</svg> </svg>
*/ */
g.setColor( ignoreButtonState g.setColor( FlatButtonUI.buttonStateColor( c, searchIconColor, searchIconColor,
? searchIconColor null, searchIconHoverColor, searchIconPressedColor ) );
: FlatButtonUI.buttonStateColor( c, searchIconColor, searchIconColor,
null, searchIconHoverColor, searchIconPressedColor ) );
// paint magnifier // paint magnifier
Area area = new Area( new Ellipse2D.Float( 2, 2, 10, 10 ) ); Area area = new Area( new Ellipse2D.Float( 2, 2, 10, 10 ) );

View File

@@ -30,12 +30,6 @@ public class FlatSearchWithHistoryIcon
extends FlatSearchIcon extends FlatSearchIcon
{ {
public FlatSearchWithHistoryIcon() { public FlatSearchWithHistoryIcon() {
this( false );
}
/** @since 2 */
public FlatSearchWithHistoryIcon( boolean ignoreButtonState ) {
super( ignoreButtonState );
} }
@Override @Override

View File

@@ -20,7 +20,6 @@ import java.awt.Color;
import java.awt.Component; import java.awt.Component;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.UIManager; import javax.swing.UIManager;
import com.formdev.flatlaf.ui.FlatButtonUI; import com.formdev.flatlaf.ui.FlatButtonUI;
import com.formdev.flatlaf.ui.FlatUIUtils; import com.formdev.flatlaf.ui.FlatUIUtils;
@@ -66,14 +65,8 @@ public abstract class FlatWindowAbstractIcon
protected void paintBackground( Component c, Graphics2D g ) { protected void paintBackground( Component c, Graphics2D g ) {
Color background = FlatButtonUI.buttonStateColor( c, null, null, null, hoverBackground, pressedBackground ); Color background = FlatButtonUI.buttonStateColor( c, null, null, null, hoverBackground, pressedBackground );
if( background != null ) { if( background != null ) {
// disable antialiasing for background rectangle painting to avoid blury edges when scaled (e.g. at 125% or 175%)
Object oldHint = g.getRenderingHint( RenderingHints.KEY_ANTIALIASING );
g.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF );
g.setColor( FlatUIUtils.deriveColor( background, c.getBackground() ) ); g.setColor( FlatUIUtils.deriveColor( background, c.getBackground() ) );
g.fillRect( 0, 0, width, height ); g.fillRect( 0, 0, width, height );
g.setRenderingHint( RenderingHints.KEY_ANTIALIASING, oldHint );
} }
} }

View File

@@ -24,7 +24,6 @@ import java.awt.geom.Line2D;
import java.awt.geom.Path2D; import java.awt.geom.Path2D;
import javax.swing.UIManager; import javax.swing.UIManager;
import com.formdev.flatlaf.ui.FlatButtonUI; import com.formdev.flatlaf.ui.FlatButtonUI;
import com.formdev.flatlaf.util.SystemInfo;
/** /**
* "close" icon for windows (frames and dialogs). * "close" icon for windows (frames and dialogs).
@@ -55,7 +54,7 @@ public class FlatWindowCloseIcon
int iy = y + ((height - iwh) / 2); int iy = y + ((height - iwh) / 2);
int ix2 = ix + iwh - 1; int ix2 = ix + iwh - 1;
int iy2 = iy + iwh - 1; int iy2 = iy + iwh - 1;
float thickness = SystemInfo.isWindows_11_orLater ? (float) scaleFactor : (int) scaleFactor; int thickness = (int) scaleFactor;
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD ); Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD );
path.append( new Line2D.Float( ix, iy, ix2, iy2 ), false ); path.append( new Line2D.Float( ix, iy, ix2, iy2 ), false );

View File

@@ -18,7 +18,6 @@ package com.formdev.flatlaf.icons;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import com.formdev.flatlaf.ui.FlatUIUtils; import com.formdev.flatlaf.ui.FlatUIUtils;
import com.formdev.flatlaf.util.SystemInfo;
/** /**
* "maximize" icon for windows (frames and dialogs). * "maximize" icon for windows (frames and dialogs).
@@ -36,11 +35,8 @@ public class FlatWindowMaximizeIcon
int iwh = (int) (10 * scaleFactor); int iwh = (int) (10 * scaleFactor);
int ix = x + ((width - iwh) / 2); int ix = x + ((width - iwh) / 2);
int iy = y + ((height - iwh) / 2); int iy = y + ((height - iwh) / 2);
float thickness = SystemInfo.isWindows_11_orLater ? (float) scaleFactor : (int) scaleFactor; int thickness = (int) scaleFactor;
int arc = Math.max( (int) (1.5 * scaleFactor), 2 );
g.fill( SystemInfo.isWindows_11_orLater g.fill( FlatUIUtils.createRectangle( ix, iy, iwh, iwh, thickness ) );
? FlatUIUtils.createRoundRectangle( ix, iy, iwh, iwh, thickness, arc, arc, arc, arc )
: FlatUIUtils.createRectangle( ix, iy, iwh, iwh, thickness ) );
} }
} }

View File

@@ -21,7 +21,6 @@ import java.awt.geom.Area;
import java.awt.geom.Path2D; import java.awt.geom.Path2D;
import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D;
import com.formdev.flatlaf.ui.FlatUIUtils; import com.formdev.flatlaf.ui.FlatUIUtils;
import com.formdev.flatlaf.util.SystemInfo;
/** /**
* "restore" icon for windows (frames and dialogs). * "restore" icon for windows (frames and dialogs).
@@ -39,33 +38,18 @@ public class FlatWindowRestoreIcon
int iwh = (int) (10 * scaleFactor); int iwh = (int) (10 * scaleFactor);
int ix = x + ((width - iwh) / 2); int ix = x + ((width - iwh) / 2);
int iy = y + ((height - iwh) / 2); int iy = y + ((height - iwh) / 2);
float thickness = SystemInfo.isWindows_11_orLater ? (float) scaleFactor : (int) scaleFactor; int thickness = (int) scaleFactor;
int arc = Math.max( (int) (1.5 * scaleFactor), 2 );
int arcOuter = (int) (arc + (1.5 * scaleFactor));
int rwh = (int) (8 * scaleFactor); int rwh = (int) (8 * scaleFactor);
int ro2 = iwh - rwh; int ro2 = iwh - rwh;
// upper-right rectangle Path2D r1 = FlatUIUtils.createRectangle( ix + ro2, iy, rwh, rwh, thickness );
Path2D r1 = SystemInfo.isWindows_11_orLater Path2D r2 = FlatUIUtils.createRectangle( ix, iy + ro2, rwh, rwh, thickness );
? FlatUIUtils.createRoundRectangle( ix + ro2, iy, rwh, rwh, thickness, arc, arcOuter, arc, arc )
: FlatUIUtils.createRectangle( ix + ro2, iy, rwh, rwh, thickness );
// lower-left rectangle
Path2D r2 = SystemInfo.isWindows_11_orLater
? FlatUIUtils.createRoundRectangle( ix, iy + ro2, rwh, rwh, thickness, arc, arc, arc, arc )
: FlatUIUtils.createRectangle( ix, iy + ro2, rwh, rwh, thickness );
// paint upper-right rectangle
Area area = new Area( r1 ); Area area = new Area( r1 );
if( SystemInfo.isWindows_11_orLater ) { area.subtract( new Area( new Rectangle2D.Float( ix, iy + ro2, rwh, rwh ) ) );
area.subtract( new Area( new Rectangle2D.Float( ix, (float) (iy + scaleFactor), rwh, rwh ) ) );
area.subtract( new Area( new Rectangle2D.Float( (float) (ix + scaleFactor), iy + ro2, rwh, rwh ) ) );
} else
area.subtract( new Area( new Rectangle2D.Float( ix, iy + ro2, rwh, rwh ) ) );
g.fill( area ); g.fill( area );
// paint lower-left rectangle
g.fill( r2 ); g.fill( r2 );
} }
} }

View File

@@ -38,18 +38,15 @@ import javax.swing.ButtonModel;
import javax.swing.Icon; import javax.swing.Icon;
import javax.swing.JButton; import javax.swing.JButton;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.JTextField;
import javax.swing.JToggleButton; import javax.swing.JToggleButton;
import javax.swing.JToolBar; import javax.swing.JToolBar;
import javax.swing.LookAndFeel; import javax.swing.LookAndFeel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager; import javax.swing.UIManager;
import javax.swing.plaf.ButtonUI; import javax.swing.plaf.ButtonUI;
import javax.swing.plaf.ComponentUI; import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.UIResource; import javax.swing.plaf.UIResource;
import javax.swing.plaf.basic.BasicButtonListener; import javax.swing.plaf.basic.BasicButtonListener;
import javax.swing.plaf.basic.BasicButtonUI; import javax.swing.plaf.basic.BasicButtonUI;
import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.FlatLaf; import com.formdev.flatlaf.FlatLaf;
import com.formdev.flatlaf.icons.FlatHelpButtonIcon; import com.formdev.flatlaf.icons.FlatHelpButtonIcon;
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable; import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
@@ -266,7 +263,7 @@ public class FlatButtonUI
case STYLE_CLASS: case STYLE_CLASS:
if( shared && FlatStylingSupport.hasStyleProperty( b ) ) { if( shared && FlatStylingSupport.hasStyleProperty( b ) ) {
// unshare component UI if necessary // unshare component UI if necessary
// updateUI() invokes installStyle() from installUI() // updateUI() invokes applyStyle() from installUI()
b.updateUI(); b.updateUI();
} else } else
installStyle( b ); installStyle( b );
@@ -423,21 +420,11 @@ public class FlatButtonUI
try { try {
FlatUIUtils.setRenderingHints( g2 ); FlatUIUtils.setRenderingHints( g2 );
boolean def = isDefaultButton( c );
boolean isToolBarButton = isToolBarButton( c ); boolean isToolBarButton = isToolBarButton( c );
float focusWidth = isToolBarButton ? 0 : FlatUIUtils.getBorderFocusWidth( c ); float focusWidth = isToolBarButton ? 0 : FlatUIUtils.getBorderFocusWidth( c );
float arc = FlatUIUtils.getBorderArc( c ); float arc = FlatUIUtils.getBorderArc( c );
float textFieldArc = 0;
// if toolbar button is in leading/trailing component of a text field, boolean def = isDefaultButton( c );
// increase toolbar button arc to match text field arc (if necessary)
if( isToolBarButton &&
FlatClientProperties.clientProperty( c, STYLE_CLASS, "", String.class ).contains( "inTextField" ) )
{
JTextField textField = (JTextField) SwingUtilities.getAncestorOfClass( JTextField.class, c );
if( textField != null )
textFieldArc = FlatUIUtils.getBorderArc( textField );
}
int x = 0; int x = 0;
int y = 0; int y = 0;
@@ -450,15 +437,8 @@ public class FlatButtonUI
y += spacing.top; y += spacing.top;
width -= spacing.left + spacing.right; width -= spacing.left + spacing.right;
height -= spacing.top + spacing.bottom; height -= spacing.top + spacing.bottom;
// reduce text field arc
textFieldArc -= spacing.top + spacing.bottom;
} }
// increase toolbar button arc to match text field arc (if necessary)
if( arc < textFieldArc )
arc = textFieldArc;
// paint shadow // paint shadow
Color shadowColor = def ? defaultShadowColor : this.shadowColor; Color shadowColor = def ? defaultShadowColor : this.shadowColor;
if( paintShadow && if( paintShadow &&

View File

@@ -101,9 +101,6 @@ public class FlatCaret
// adds selection highlights to the text component highlighter // adds selection highlights to the text component highlighter
if( isSelectionVisible() ) { if( isSelectionVisible() ) {
EventQueue.invokeLater( () -> { EventQueue.invokeLater( () -> {
if( getComponent() == null )
return; // was deinstalled
if( isSelectionVisible() ) { if( isSelectionVisible() ) {
setSelectionVisible( false ); setSelectionVisible( false );
setSelectionVisible( true ); setSelectionVisible( true );
@@ -256,9 +253,6 @@ public class FlatCaret
// select all // select all
if( c instanceof JFormattedTextField ) { if( c instanceof JFormattedTextField ) {
EventQueue.invokeLater( () -> { EventQueue.invokeLater( () -> {
if( getComponent() == null )
return; // was deinstalled
select( 0, doc.getLength() ); select( 0, doc.getLength() );
} ); } );
} else { } else {

View File

@@ -89,7 +89,6 @@ public class FlatCheckBoxMenuItemUI
protected void uninstallDefaults() { protected void uninstallDefaults() {
super.uninstallDefaults(); super.uninstallDefaults();
FlatMenuItemRenderer.clearClientProperties( menuItem.getParent() );
renderer = null; renderer = null;
oldStyleValues = null; oldStyleValues = null;
} }

View File

@@ -98,8 +98,8 @@ import com.formdev.flatlaf.util.SystemInfo;
* @uiDefault ComboBox.focusedBackground Color optional * @uiDefault ComboBox.focusedBackground Color optional
* @uiDefault ComboBox.disabledBackground Color * @uiDefault ComboBox.disabledBackground Color
* @uiDefault ComboBox.disabledForeground Color * @uiDefault ComboBox.disabledForeground Color
* @uiDefault ComboBox.buttonBackground Color optional * @uiDefault ComboBox.buttonBackground Color
* @uiDefault ComboBox.buttonEditableBackground Color optional * @uiDefault ComboBox.buttonEditableBackground Color
* @uiDefault ComboBox.buttonFocusedBackground Color optional; defaults to ComboBox.focusedBackground * @uiDefault ComboBox.buttonFocusedBackground Color optional; defaults to ComboBox.focusedBackground
* @uiDefault ComboBox.buttonSeparatorWidth int or float optional; defaults to Component.borderWidth * @uiDefault ComboBox.buttonSeparatorWidth int or float optional; defaults to Component.borderWidth
* @uiDefault ComboBox.buttonSeparatorColor Color optional * @uiDefault ComboBox.buttonSeparatorColor Color optional
@@ -281,10 +281,7 @@ public class FlatComboBoxUI
public void layoutContainer( Container parent ) { public void layoutContainer( Container parent ) {
super.layoutContainer( parent ); super.layoutContainer( parent );
// on macOS, a Swing combo box is used for AWT component java.awt.Choice if( arrowButton != null ) {
// and the font may be (temporary) null
if( arrowButton != null && comboBox.getFont() != null ) {
// limit button width to height of a raw combobox (without insets) // limit button width to height of a raw combobox (without insets)
FontMetrics fm = comboBox.getFontMetrics( comboBox.getFont() ); FontMetrics fm = comboBox.getFontMetrics( comboBox.getFont() );
int maxButtonWidth = fm.getHeight() + scale( padding.top ) + scale( padding.bottom ); int maxButtonWidth = fm.getHeight() + scale( padding.top ) + scale( padding.bottom );
@@ -543,27 +540,24 @@ public class FlatComboBoxUI
// paint arrow button background // paint arrow button background
if( enabled && !isCellRenderer ) { if( enabled && !isCellRenderer ) {
Color buttonColor = paintButton g2.setColor( paintButton
? buttonEditableBackground ? buttonEditableBackground
: (buttonFocusedBackground != null || focusedBackground != null) && isPermanentFocusOwner( comboBox ) : (buttonFocusedBackground != null || focusedBackground != null) && isPermanentFocusOwner( comboBox )
? (buttonFocusedBackground != null ? buttonFocusedBackground : focusedBackground) ? (buttonFocusedBackground != null ? buttonFocusedBackground : focusedBackground)
: buttonBackground; : buttonBackground );
if( buttonColor != null ) { Shape oldClip = g2.getClip();
g2.setColor( buttonColor ); if( isLeftToRight )
Shape oldClip = g2.getClip(); g2.clipRect( arrowX, 0, width - arrowX, height );
if( isLeftToRight ) else
g2.clipRect( arrowX, 0, width - arrowX, height ); g2.clipRect( 0, 0, arrowX + arrowWidth, height );
else FlatUIUtils.paintComponentBackground( g2, 0, 0, width, height, focusWidth, arc );
g2.clipRect( 0, 0, arrowX + arrowWidth, height ); g2.setClip( oldClip );
FlatUIUtils.paintComponentBackground( g2, 0, 0, width, height, focusWidth, arc );
g2.setClip( oldClip );
}
} }
// paint vertical line between value and arrow button // paint vertical line between value and arrow button
if( paintButton ) { if( paintButton ) {
Color separatorColor = enabled ? buttonSeparatorColor : buttonDisabledSeparatorColor; Color separatorColor = enabled ? buttonSeparatorColor : buttonDisabledSeparatorColor;
if( separatorColor != null && buttonSeparatorWidth > 0 ) { if( separatorColor != null ) {
g2.setColor( separatorColor ); g2.setColor( separatorColor );
float lw = scale( buttonSeparatorWidth ); float lw = scale( buttonSeparatorWidth );
float lx = isLeftToRight ? arrowX : arrowX + arrowWidth - lw; float lx = isLeftToRight ? arrowX : arrowX + arrowWidth - lw;
@@ -812,12 +806,9 @@ public class FlatComboBoxUI
// make opaque to avoid that background shines thru border (e.g. at 150% scaling) // make opaque to avoid that background shines thru border (e.g. at 150% scaling)
setOpaque( true ); setOpaque( true );
// set popup border
// use non-UIResource to avoid that it is overwritten when making
// popup visible (see JPopupMenu.setInvoker()) in theme editor preview
Border border = UIManager.getBorder( "PopupMenu.border" ); Border border = UIManager.getBorder( "PopupMenu.border" );
if( border != null ) if( border != null )
setBorder( FlatUIUtils.nonUIResource( border ) ); setBorder( border );
} }
@Override @Override
@@ -831,11 +822,6 @@ public class FlatComboBoxUI
void updateStyle() { void updateStyle() {
if( popupBackground != null ) if( popupBackground != null )
list.setBackground( popupBackground ); list.setBackground( popupBackground );
// set popup background because it may shine thru when scaled (e.g. at 150%)
// use non-UIResource to avoid that it is overwritten when making
// popup visible (see JPopupMenu.setInvoker()) in theme editor preview
setBackground( FlatUIUtils.nonUIResource( list.getBackground() ) );
} }
@Override @Override
@@ -922,9 +908,7 @@ public class FlatComboBoxUI
this.padding = padding; this.padding = padding;
} }
// using synchronized to avoid problems with code that modifies combo box void install( Component c ) {
// (model, selection, etc) not on AWT thread (which should be not done)
synchronized void install( Component c ) {
if( !(c instanceof JComponent) ) if( !(c instanceof JComponent) )
return; return;
@@ -956,7 +940,7 @@ public class FlatComboBoxUI
* there is no single place to uninstall it. * there is no single place to uninstall it.
* This is the reason why this method is called from various places. * This is the reason why this method is called from various places.
*/ */
synchronized void uninstall() { void uninstall() {
if( rendererComponent == null ) if( rendererComponent == null )
return; return;
@@ -967,9 +951,9 @@ public class FlatComboBoxUI
} }
@Override @Override
synchronized public Insets getBorderInsets( Component c, Insets insets ) { public Insets getBorderInsets( Component c, Insets insets ) {
Insets padding = scale( this.padding ); Insets padding = scale( this.padding );
if( rendererBorder != null && !(rendererBorder instanceof CellPaddingBorder) ) { if( rendererBorder != null ) {
Insets insideInsets = rendererBorder.getBorderInsets( c ); Insets insideInsets = rendererBorder.getBorderInsets( c );
insets.top = Math.max( padding.top, insideInsets.top ); insets.top = Math.max( padding.top, insideInsets.top );
insets.left = Math.max( padding.left, insideInsets.left ); insets.left = Math.max( padding.left, insideInsets.left );

View File

@@ -44,8 +44,8 @@ import com.formdev.flatlaf.util.LoggingFacade;
* <!-- BasicEditorPaneUI --> * <!-- BasicEditorPaneUI -->
* *
* @uiDefault EditorPane.font Font * @uiDefault EditorPane.font Font
* @uiDefault EditorPane.background Color * @uiDefault EditorPane.background Color also used if not editable
* @uiDefault EditorPane.foreground Color also used if not editable * @uiDefault EditorPane.foreground Color
* @uiDefault EditorPane.caretForeground Color * @uiDefault EditorPane.caretForeground Color
* @uiDefault EditorPane.selectionBackground Color * @uiDefault EditorPane.selectionBackground Color
* @uiDefault EditorPane.selectionForeground Color * @uiDefault EditorPane.selectionForeground Color

View File

@@ -275,10 +275,7 @@ public class FlatFileChooserUI
private boolean doNotUseSystemIcons() { private boolean doNotUseSystemIcons() {
// Java 17 32bit craches on Windows when using system icons // Java 17 32bit craches on Windows when using system icons
// fixed in Java 18+ (see https://bugs.openjdk.java.net/browse/JDK-8277299) return SystemInfo.isWindows && SystemInfo.isJava_17_orLater && !SystemInfo.isX86_64;
return SystemInfo.isWindows &&
SystemInfo.isX86 &&
(SystemInfo.isJava_17_orLater && !SystemInfo.isJava_18_orLater);
} }
//---- class FlatFileView ------------------------------------------------- //---- class FlatFileView -------------------------------------------------

View File

@@ -213,13 +213,6 @@ public class FlatInternalFrameTitlePane
case "componentOrientation": case "componentOrientation":
applyComponentOrientation( frame.getComponentOrientation() ); applyComponentOrientation( frame.getComponentOrientation() );
break; break;
case "opaque":
// Do not invoke super.propertyChange() here because it always
// invokes repaint(), which would cause endless repainting.
// The opaque flag is temporary changed in FlatUIUtils.hasOpaqueBeenExplicitlySet(),
// invoked from FlatInternalFrameUI.update().
return;
} }
super.propertyChange( e ); super.propertyChange( e );

View File

@@ -179,26 +179,6 @@ public class FlatInternalFrameUI
return FlatStylingSupport.getAnnotatedStyleableInfos( this, frame.getBorder() ); return FlatStylingSupport.getAnnotatedStyleableInfos( this, frame.getBorder() );
} }
@Override
public void update( Graphics g, JComponent c ) {
// The internal frame actually should be opaque and fill its background,
// but it must be non-opaque to allow translucent resize handles (outside of visual bounds).
// To avoid that parent may shine through internal frame (e.g. if menu bar is non-opaque),
// fill background excluding insets (translucent resize handles),
// but only if opaque was not set explicitly by application to false.
// If applications has set internal frame opacity to false, do not fill background (for compatibility).
if( !c.isOpaque() && !FlatUIUtils.hasOpaqueBeenExplicitlySet( c ) ) {
Insets insets = c.getInsets();
g.setColor( c.getBackground() );
g.fillRect( insets.left, insets.top,
c.getWidth() - insets.left - insets.right,
c.getHeight() - insets.top - insets.bottom );
}
super.update( g, c );
}
//---- class FlatInternalFrameBorder -------------------------------------- //---- class FlatInternalFrameBorder --------------------------------------
public static class FlatInternalFrameBorder public static class FlatInternalFrameBorder

View File

@@ -122,7 +122,7 @@ public class FlatLabelUI
JLabel label = (JLabel) e.getSource(); JLabel label = (JLabel) e.getSource();
if( shared && FlatStylingSupport.hasStyleProperty( label ) ) { if( shared && FlatStylingSupport.hasStyleProperty( label ) ) {
// unshare component UI if necessary // unshare component UI if necessary
// updateUI() invokes installStyle() from installUI() // updateUI() invokes applyStyle() from installUI()
label.updateUI(); label.updateUI();
} else } else
installStyle( label ); installStyle( label );

View File

@@ -37,18 +37,15 @@ public class FlatLineBorder
{ {
private final Color lineColor; private final Color lineColor;
private final float lineThickness; private final float lineThickness;
/** @since 2 */ private final int arc;
public FlatLineBorder( Insets insets, Color lineColor ) { public FlatLineBorder( Insets insets, Color lineColor ) {
this( insets, lineColor, 1f, 0 ); this( insets, lineColor, 1f );
} }
/** @since 2 */ public FlatLineBorder( Insets insets, Color lineColor, float lineThickness ) {
public FlatLineBorder( Insets insets, Color lineColor, float lineThickness, int arc ) {
super( insets ); super( insets );
this.lineColor = lineColor; this.lineColor = lineColor;
this.lineThickness = lineThickness; this.lineThickness = lineThickness;
this.arc = arc;
} }
public Color getLineColor() { public Color getLineColor() {
@@ -59,18 +56,13 @@ public class FlatLineBorder
return lineThickness; return lineThickness;
} }
/** @since 2 */
public int getArc() {
return arc;
}
@Override @Override
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) { public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
Graphics2D g2 = (Graphics2D) g.create(); Graphics2D g2 = (Graphics2D) g.create();
try { try {
FlatUIUtils.setRenderingHints( g2 ); FlatUIUtils.setRenderingHints( g2 );
FlatUIUtils.paintOutlinedComponent( g2, x, y, width, height, FlatUIUtils.paintOutlinedComponent( g2, x, y, width, height,
0, 0, 0, scale( getLineThickness() ), scale( getArc() ), null, getLineColor(), null ); 0, 0, 0, scale( getLineThickness() ), 0, null, getLineColor(), null );
} finally { } finally {
g2.dispose(); g2.dispose();
} }

View File

@@ -37,7 +37,7 @@ import javax.swing.plaf.ListUI;
public class FlatListCellBorder public class FlatListCellBorder
extends FlatLineBorder extends FlatLineBorder
{ {
/** @since 2 */ protected boolean showCellFocusIndicator = UIManager.getBoolean( "List.showCellFocusIndicator" ); protected boolean showCellFocusIndicator = UIManager.getBoolean( "List.showCellFocusIndicator" );
private Component c; private Component c;
@@ -113,7 +113,7 @@ public class FlatListCellBorder
/** /**
* Border for selected cell that uses margins and paints focus indicator border * Border for selected cell that uses margins and paints focus indicator border
* if enabled (List.showCellFocusIndicator=true) and multiple items are selected. * if enabled (List.showCellFocusIndicator=true) and exactly one item is selected.
*/ */
public static class Selected public static class Selected
extends FlatListCellBorder extends FlatListCellBorder
@@ -125,7 +125,7 @@ public class FlatListCellBorder
if( !showCellFocusIndicator ) if( !showCellFocusIndicator )
return; return;
// paint focus indicator border only if multiple items are selected // paint focus indicator border only if exactly one item is selected
JList<?> list = (JList<?>) SwingUtilities.getAncestorOfClass( JList.class, c ); JList<?> list = (JList<?>) SwingUtilities.getAncestorOfClass( JList.class, c );
if( list != null && list.getMinSelectionIndex() == list.getMaxSelectionIndex() ) if( list != null && list.getMinSelectionIndex() == list.getMaxSelectionIndex() )
return; return;

View File

@@ -78,9 +78,9 @@ public class FlatListUI
@Styleable protected Color selectionInactiveForeground; @Styleable protected Color selectionInactiveForeground;
// for FlatListCellBorder // for FlatListCellBorder
/** @since 2 */ @Styleable protected Insets cellMargins; @Styleable protected Insets cellMargins;
/** @since 2 */ @Styleable protected Color cellFocusColor; @Styleable protected Color cellFocusColor;
/** @since 2 */ @Styleable protected Boolean showCellFocusIndicator; @Styleable protected boolean showCellFocusIndicator;
private Map<String, Object> oldStyleValues; private Map<String, Object> oldStyleValues;

View File

@@ -180,15 +180,11 @@ public class FlatMenuBarUI
protected Color getBackground( JComponent c ) { protected Color getBackground( JComponent c ) {
Color background = c.getBackground(); Color background = c.getBackground();
// paint background if opaque // paint background if opaque or if having custom background color
if( c.isOpaque() ) if( c.isOpaque() || !(background instanceof UIResource) )
return background; return background;
// do not paint background if non-opaque and having custom background color // paint background if menu bar is not the "main" menu bar
if( !(background instanceof UIResource) )
return null;
// paint background if menu bar is not the "main" menu bar (e.g. in internal frame)
JRootPane rootPane = SwingUtilities.getRootPane( c ); JRootPane rootPane = SwingUtilities.getRootPane( c );
if( rootPane == null || !(rootPane.getParent() instanceof Window) || rootPane.getJMenuBar() != c ) if( rootPane == null || !(rootPane.getParent() instanceof Window) || rootPane.getJMenuBar() != c )
return background; return background;

View File

@@ -19,7 +19,6 @@ 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.Container;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.Font; import java.awt.Font;
import java.awt.FontMetrics; import java.awt.FontMetrics;
@@ -33,7 +32,6 @@ import java.awt.event.KeyEvent;
import java.text.AttributedCharacterIterator; import java.text.AttributedCharacterIterator;
import java.util.Map; import java.util.Map;
import javax.swing.Icon; import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JMenu; import javax.swing.JMenu;
import javax.swing.JMenuItem; import javax.swing.JMenuItem;
import javax.swing.KeyStroke; import javax.swing.KeyStroke;
@@ -41,7 +39,6 @@ import javax.swing.SwingUtilities;
import javax.swing.UIManager; import javax.swing.UIManager;
import javax.swing.plaf.basic.BasicHTML; import javax.swing.plaf.basic.BasicHTML;
import javax.swing.text.View; import javax.swing.text.View;
import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.FlatLaf; import com.formdev.flatlaf.FlatLaf;
import com.formdev.flatlaf.icons.FlatCheckBoxMenuItemIcon; import com.formdev.flatlaf.icons.FlatCheckBoxMenuItemIcon;
import com.formdev.flatlaf.icons.FlatMenuArrowIcon; import com.formdev.flatlaf.icons.FlatMenuArrowIcon;
@@ -55,15 +52,12 @@ import com.formdev.flatlaf.util.SystemInfo;
/** /**
* Renderer for menu items. * Renderer for menu items.
* *
* @uiDefault MenuItem.verticallyAlignText boolean
* @uiDefault MenuItem.minimumWidth int * @uiDefault MenuItem.minimumWidth int
* @uiDefault MenuItem.minimumIconSize Dimension * @uiDefault MenuItem.minimumIconSize Dimension
* @uiDefault MenuItem.textAcceleratorGap int * @uiDefault MenuItem.textAcceleratorGap int
* @uiDefault MenuItem.textNoAcceleratorGap int * @uiDefault MenuItem.textNoAcceleratorGap int
* @uiDefault MenuItem.acceleratorArrowGap int * @uiDefault MenuItem.acceleratorArrowGap int
* @uiDefault MenuItem.checkBackground Color * @uiDefault MenuItem.checkBackground Color
* @uiDefault MenuItem.checkMargins Insets
* @uiDefault MenuItem.selectionType String null (default) or underline
* @uiDefault MenuItem.underlineSelectionBackground Color * @uiDefault MenuItem.underlineSelectionBackground Color
* @uiDefault MenuItem.underlineSelectionCheckBackground Color * @uiDefault MenuItem.underlineSelectionCheckBackground Color
* @uiDefault MenuItem.underlineSelectionColor Color * @uiDefault MenuItem.underlineSelectionColor Color
@@ -73,15 +67,12 @@ import com.formdev.flatlaf.util.SystemInfo;
*/ */
public class FlatMenuItemRenderer public class FlatMenuItemRenderer
{ {
private static final String KEY_MAX_ICONS_WIDTH = "FlatLaf.internal.FlatMenuItemRenderer.maxIconWidth";
protected final JMenuItem menuItem; protected final JMenuItem menuItem;
protected Icon checkIcon; protected Icon checkIcon;
protected Icon arrowIcon; protected Icon arrowIcon;
@Styleable protected Font acceleratorFont; protected final Font acceleratorFont;
protected final String acceleratorDelimiter; protected final String acceleratorDelimiter;
/** @since 2 */ @Styleable protected boolean verticallyAlignText = FlatUIUtils.getUIBoolean( "MenuItem.verticallyAlignText", true );
@Styleable protected int minimumWidth = UIManager.getInt( "MenuItem.minimumWidth" ); @Styleable protected int minimumWidth = UIManager.getInt( "MenuItem.minimumWidth" );
@Styleable protected Dimension minimumIconSize; @Styleable protected Dimension minimumIconSize;
@Styleable protected int textAcceleratorGap = FlatUIUtils.getUIInt( "MenuItem.textAcceleratorGap", 28 ); @Styleable protected int textAcceleratorGap = FlatUIUtils.getUIInt( "MenuItem.textAcceleratorGap", 28 );
@@ -414,10 +405,11 @@ debug*/
return; return;
// center because the real icon may be smaller than dimension in iconRect // center because the real icon may be smaller than dimension in iconRect
int x = iconRect.x + centerOffset( iconRect.width, icon.getIconWidth() );
int y = iconRect.y + centerOffset( iconRect.height, icon.getIconHeight() ); int y = iconRect.y + centerOffset( iconRect.height, icon.getIconHeight() );
// paint // paint
icon.paintIcon( menuItem, g, iconRect.x, y ); icon.paintIcon( menuItem, g, x, y );
} }
protected static void paintText( Graphics g, JMenuItem menuItem, protected static void paintText( Graphics g, JMenuItem menuItem,
@@ -452,10 +444,6 @@ debug*/
htmlView.paint( HiDPIUtils.createGraphicsTextYCorrection( (Graphics2D) g ), textRect ); htmlView.paint( HiDPIUtils.createGraphicsTextYCorrection( (Graphics2D) g ), textRect );
} }
/**
* Returns {@code true} if either the menu item is armed (mouse over item)
* or it is a {@code JMenu} and selected (shows submenu).
*/
protected static boolean isArmedOrSelected( JMenuItem menuItem ) { protected static boolean isArmedOrSelected( JMenuItem menuItem ) {
return menuItem.isArmed() || (menuItem instanceof JMenu && menuItem.isSelected()); return menuItem.isArmed() || (menuItem instanceof JMenu && menuItem.isSelected());
} }
@@ -486,12 +474,6 @@ debug*/
return pressedIcon; return pressedIcon;
} }
if( isArmedOrSelected( menuItem ) ) {
Icon selectedIcon = menuItem.getSelectedIcon();
if( selectedIcon != null )
return selectedIcon;
}
return icon; return icon;
} }
@@ -578,44 +560,6 @@ debug*/
shiftGlyph = 0x21E7, shiftGlyph = 0x21E7,
commandGlyph = 0x2318; commandGlyph = 0x2318;
/**
* Calculates the maximum width of all menu item icons in the popup.
*/
private int getMaxIconsWidth() {
if( !verticallyAlignText )
return 0;
Container parent = menuItem.getParent();
if( !(parent instanceof JComponent) )
return 0;
int maxWidth = FlatClientProperties.clientPropertyInt( (JComponent) parent, KEY_MAX_ICONS_WIDTH, -1 );
if( maxWidth >= 0 )
return maxWidth;
maxWidth = 0;
for( Component c : parent.getComponents() ) {
if( !(c instanceof JMenuItem) )
continue;
Icon icon = ((JMenuItem)c).getIcon();
if( icon != null )
maxWidth = Math.max( maxWidth, icon.getIconWidth() );
}
((JComponent)parent).putClientProperty( KEY_MAX_ICONS_WIDTH, maxWidth );
return maxWidth;
}
static void clearClientProperties( Component c ) {
if( !(c instanceof JComponent) )
return;
JComponent jc = (JComponent) c;
jc.putClientProperty( FlatMenuItemRenderer.KEY_MAX_ICONS_WIDTH, null );
}
//---- class MinSizeIcon -------------------------------------------------- //---- class MinSizeIcon --------------------------------------------------
private class MinSizeIcon private class MinSizeIcon
@@ -630,7 +574,6 @@ debug*/
@Override @Override
public int getIconWidth() { public int getIconWidth() {
int iconWidth = (delegate != null) ? delegate.getIconWidth() : 0; int iconWidth = (delegate != null) ? delegate.getIconWidth() : 0;
iconWidth = Math.max( iconWidth, getMaxIconsWidth() );
return Math.max( iconWidth, scale( minimumIconSize.width ) ); return Math.max( iconWidth, scale( minimumIconSize.width ) );
} }

View File

@@ -89,7 +89,6 @@ public class FlatMenuItemUI
protected void uninstallDefaults() { protected void uninstallDefaults() {
super.uninstallDefaults(); super.uninstallDefaults();
FlatMenuItemRenderer.clearClientProperties( menuItem.getParent() );
renderer = null; renderer = null;
oldStyleValues = null; oldStyleValues = null;
} }

View File

@@ -111,7 +111,6 @@ public class FlatMenuUI
protected void uninstallDefaults() { protected void uninstallDefaults() {
super.uninstallDefaults(); super.uninstallDefaults();
FlatMenuItemRenderer.clearClientProperties( menuItem.getParent() );
renderer = null; renderer = null;
oldStyleValues = null; oldStyleValues = null;
} }

View File

@@ -56,7 +56,7 @@ public class FlatNativeWindowBorder
private static final boolean canUseJBRCustomDecorations = private static final boolean canUseJBRCustomDecorations =
canUseWindowDecorations && canUseWindowDecorations &&
SystemInfo.isJetBrainsJVM_11_orLater && SystemInfo.isJetBrainsJVM_11_orLater &&
FlatSystemProperties.getBoolean( FlatSystemProperties.USE_JETBRAINS_CUSTOM_DECORATIONS, false ); FlatSystemProperties.getBoolean( FlatSystemProperties.USE_JETBRAINS_CUSTOM_DECORATIONS, true );
private static Boolean supported; private static Boolean supported;
private static Provider nativeProvider; private static Provider nativeProvider;
@@ -313,10 +313,6 @@ public class FlatNativeWindowBorder
//---- class WindowTopBorder ------------------------------------------- //---- class WindowTopBorder -------------------------------------------
/**
* Window top border used on Windows 10.
* No longer needed since Windows 11.
*/
static class WindowTopBorder static class WindowTopBorder
extends JBRCustomDecorations.JBRWindowTopBorder extends JBRCustomDecorations.JBRWindowTopBorder
{ {

View File

@@ -19,7 +19,9 @@ 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 java.beans.PropertyChangeListener; import java.beans.PropertyChangeListener;
import javax.swing.Box; import javax.swing.Box;
import javax.swing.BoxLayout; import javax.swing.BoxLayout;
@@ -36,7 +38,6 @@ import javax.swing.plaf.UIResource;
import javax.swing.plaf.basic.BasicHTML; import javax.swing.plaf.basic.BasicHTML;
import javax.swing.plaf.basic.BasicOptionPaneUI; import javax.swing.plaf.basic.BasicOptionPaneUI;
import com.formdev.flatlaf.FlatClientProperties; import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.util.SwingUtils;
import com.formdev.flatlaf.util.UIScale; import com.formdev.flatlaf.util.UIScale;
/** /**
@@ -157,7 +158,7 @@ public class FlatOptionPaneUI
// set icon-message gap // set icon-message gap
if( iconMessageGap > 0 ) { if( iconMessageGap > 0 ) {
Component iconMessageSeparator = SwingUtils.getComponentByName( messageArea, "OptionPane.separator" ); Component iconMessageSeparator = findByName( messageArea, "OptionPane.separator" );
if( iconMessageSeparator != null ) if( iconMessageSeparator != null )
iconMessageSeparator.setPreferredSize( new Dimension( UIScale.scale( iconMessageGap ), 1 ) ); iconMessageSeparator.setPreferredSize( new Dimension( UIScale.scale( iconMessageGap ), 1 ) );
} }
@@ -229,7 +230,7 @@ public class FlatOptionPaneUI
// use non-UIResource borders to avoid that they are replaced when switching LaF // use non-UIResource borders to avoid that they are replaced when switching LaF
Border border = panel.getBorder(); Border border = panel.getBorder();
if( border instanceof UIResource ) if( border instanceof UIResource )
panel.setBorder( FlatUIUtils.nonUIResource( border ) ); panel.setBorder( new NonUIResourceBorder( border ) );
} }
if( child instanceof Container ) if( child instanceof Container )
@@ -237,8 +238,49 @@ public class FlatOptionPaneUI
} }
} }
private Component findByName( Container c, String name ) {
for( Component child : c.getComponents() ) {
if( name.equals( child.getName() ) )
return child;
if( child instanceof Container ) {
Component c2 = findByName( (Container) child, name );
if( c2 != null )
return c2;
}
}
return null;
}
@Override @Override
protected boolean getSizeButtonsToSameWidth() { protected boolean getSizeButtonsToSameWidth() {
return sameSizeButtons; return sameSizeButtons;
} }
//---- 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();
}
}
} }

View File

@@ -16,18 +16,9 @@
package com.formdev.flatlaf.ui; package com.formdev.flatlaf.ui;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.beans.PropertyChangeListener;
import java.util.Map;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.plaf.ComponentUI; import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicPanelUI; import javax.swing.plaf.basic.BasicPanelUI;
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
import com.formdev.flatlaf.util.LoggingFacade;
import com.formdev.flatlaf.util.UIScale;
/** /**
* Provides the Flat LaF UI delegate for {@link javax.swing.JPanel}. * Provides the Flat LaF UI delegate for {@link javax.swing.JPanel}.
@@ -36,118 +27,15 @@ import com.formdev.flatlaf.util.UIScale;
* *
* @uiDefault Panel.font Font unused * @uiDefault Panel.font Font unused
* @uiDefault Panel.background Color only used if opaque * @uiDefault Panel.background Color only used if opaque
* @uiDefault Panel.foreground Color unused * @uiDefault Panel.foreground Color
* @uiDefault Panel.border Border * @uiDefault Panel.border Border
* *
* @author Karl Tauber * @author Karl Tauber
*/ */
public class FlatPanelUI public class FlatPanelUI
extends BasicPanelUI extends BasicPanelUI
implements StyleableUI
{ {
// only used via styling (not in UI defaults)
/** @since 2 */ @Styleable protected int arc = -1;
private final boolean shared;
private PropertyChangeListener propertyChangeListener;
private Map<String, Object> oldStyleValues;
public static ComponentUI createUI( JComponent c ) { public static ComponentUI createUI( JComponent c ) {
return FlatUIUtils.canUseSharedUI( c ) return FlatUIUtils.createSharedUI( FlatPanelUI.class, FlatPanelUI::new );
? FlatUIUtils.createSharedUI( FlatPanelUI.class, () -> new FlatPanelUI( true ) )
: new FlatPanelUI( false );
}
/** @since 2 */
protected FlatPanelUI( boolean shared ) {
this.shared = shared;
}
@Override
public void installUI( JComponent c ) {
super.installUI( c );
propertyChangeListener = FlatStylingSupport.createPropertyChangeListener(
c, () -> stylePropertyChange( (JPanel) c ), null );
c.addPropertyChangeListener( propertyChangeListener );
installStyle( (JPanel) c );
}
@Override
public void uninstallUI( JComponent c ) {
super.uninstallUI( c );
c.removePropertyChangeListener( propertyChangeListener );
propertyChangeListener = null;
oldStyleValues = null;
}
private void stylePropertyChange( JPanel c ) {
if( shared && FlatStylingSupport.hasStyleProperty( c ) ) {
// unshare component UI if necessary
// updateUI() invokes installStyle() from installUI()
c.updateUI();
} else
installStyle( c );
c.revalidate();
c.repaint();
}
/** @since 2 */
protected void installStyle( JPanel c ) {
try {
applyStyle( c, FlatStylingSupport.getResolvedStyle( c, "Panel" ) );
} catch( RuntimeException ex ) {
LoggingFacade.INSTANCE.logSevere( null, ex );
}
}
/** @since 2 */
protected void applyStyle( JPanel c, Object style ) {
oldStyleValues = FlatStylingSupport.parseAndApply( oldStyleValues, style,
(key, value) -> applyStyleProperty( c, key, value ) );
}
/** @since 2 */
protected Object applyStyleProperty( JPanel c, String key, Object value ) {
return FlatStylingSupport.applyToAnnotatedObjectOrComponent( this, c, key, value );
}
/** @since 2 */
@Override
public Map<String, Class<?>> getStyleableInfos( JComponent c ) {
return FlatStylingSupport.getAnnotatedStyleableInfos( this );
}
@Override
public void update( Graphics g, JComponent c ) {
// fill background
if( c.isOpaque() ) {
int width = c.getWidth();
int height = c.getHeight();
int arc = (this.arc >= 0)
? this.arc
: ((c.getBorder() instanceof FlatLineBorder)
? ((FlatLineBorder)c.getBorder()).getArc()
: 0);
// fill background with parent color to avoid garbage in rounded corners
if( arc > 0 )
FlatUIUtils.paintParentBackground( g, c );
g.setColor( c.getBackground() );
if( arc > 0 ) {
// fill rounded rectangle if having rounded corners
Object[] oldRenderingHints = FlatUIUtils.setRenderingHints( g );
FlatUIUtils.paintComponentBackground( (Graphics2D) g, 0, 0, width, height,
0, UIScale.scale( arc ) );
FlatUIUtils.resetRenderingHints( g, oldRenderingHints );
} else
g.fillRect( 0, 0, width, height );
}
paint( g, c );
} }
} }

View File

@@ -28,8 +28,6 @@ import javax.swing.Action;
import javax.swing.ActionMap; import javax.swing.ActionMap;
import javax.swing.Icon; import javax.swing.Icon;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.JPasswordField;
import javax.swing.JToggleButton;
import javax.swing.LookAndFeel; import javax.swing.LookAndFeel;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import javax.swing.UIManager; import javax.swing.UIManager;
@@ -39,7 +37,6 @@ import javax.swing.text.Element;
import javax.swing.text.JTextComponent; import javax.swing.text.JTextComponent;
import javax.swing.text.PasswordView; import javax.swing.text.PasswordView;
import javax.swing.text.View; import javax.swing.text.View;
import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.icons.FlatCapsLockIcon; import com.formdev.flatlaf.icons.FlatCapsLockIcon;
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable; import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
import com.formdev.flatlaf.util.UIScale; import com.formdev.flatlaf.util.UIScale;
@@ -76,29 +73,18 @@ import com.formdev.flatlaf.util.UIScale;
* *
* @uiDefault PasswordField.echoChar character * @uiDefault PasswordField.echoChar character
* @uiDefault PasswordField.showCapsLock boolean * @uiDefault PasswordField.showCapsLock boolean
* @uiDefault PasswordField.showRevealButton boolean
* @uiDefault PasswordField.capsLockIcon Icon * @uiDefault PasswordField.capsLockIcon Icon
* @uiDefault PasswordField.revealIcon Icon
* *
* @author Karl Tauber * @author Karl Tauber
*/ */
public class FlatPasswordFieldUI public class FlatPasswordFieldUI
extends FlatTextFieldUI extends FlatTextFieldUI
{ {
// used to preserve reveal button state when switching theme
private static final String KEY_REVEAL_SELECTED = "FlatLaf.internal.FlatPasswordFieldUI.revealSelected";
private Character echoChar;
@Styleable protected boolean showCapsLock; @Styleable protected boolean showCapsLock;
/** @since 2 */ @Styleable protected boolean showRevealButton;
protected Icon capsLockIcon; protected Icon capsLockIcon;
/** @since 2 */ protected Icon revealIcon;
private KeyListener capsLockListener; private KeyListener capsLockListener;
private boolean capsLockIconShared = true; private boolean capsLockIconShared = true;
private JToggleButton revealButton;
private boolean uninstallEchoChar;
public static ComponentUI createUI( JComponent c ) { public static ComponentUI createUI( JComponent c ) {
return new FlatPasswordFieldUI(); return new FlatPasswordFieldUI();
@@ -109,33 +95,17 @@ public class FlatPasswordFieldUI
return "PasswordField"; return "PasswordField";
} }
@Override
public void installUI( JComponent c ) {
super.installUI( c );
installRevealButton();
}
@Override
public void uninstallUI( JComponent c ) {
uninstallRevealButton();
super.uninstallUI( c );
}
@Override @Override
protected void installDefaults() { protected void installDefaults() {
super.installDefaults(); super.installDefaults();
String prefix = getPropertyPrefix(); String prefix = getPropertyPrefix();
echoChar = (Character) UIManager.get( prefix + ".echoChar" ); Character echoChar = (Character) UIManager.get( prefix + ".echoChar" );
if( echoChar != null ) if( echoChar != null )
LookAndFeel.installProperty( getComponent(), "echoChar", echoChar ); LookAndFeel.installProperty( getComponent(), "echoChar", echoChar );
showCapsLock = UIManager.getBoolean( "PasswordField.showCapsLock" ); showCapsLock = UIManager.getBoolean( "PasswordField.showCapsLock" );
showRevealButton = UIManager.getBoolean( "PasswordField.showRevealButton" );
capsLockIcon = UIManager.getIcon( "PasswordField.capsLockIcon" ); capsLockIcon = UIManager.getIcon( "PasswordField.capsLockIcon" );
revealIcon = UIManager.getIcon( "PasswordField.revealIcon" );
capsLockIconShared = true; capsLockIconShared = true;
} }
@@ -144,7 +114,6 @@ public class FlatPasswordFieldUI
super.uninstallDefaults(); super.uninstallDefaults();
capsLockIcon = null; capsLockIcon = null;
revealIcon = null;
} }
@Override @Override
@@ -199,18 +168,6 @@ public class FlatPasswordFieldUI
return "PasswordField"; return "PasswordField";
} }
@Override
protected void applyStyle( Object style ) {
boolean oldShowRevealButton = showRevealButton;
super.applyStyle( style );
if( showRevealButton != oldShowRevealButton ) {
uninstallRevealButton();
installRevealButton();
}
}
/** @since 2 */ /** @since 2 */
@Override @Override
protected Object applyStyleProperty( String key, Object value ) { protected Object applyStyleProperty( String key, Object value ) {
@@ -275,72 +232,8 @@ public class FlatPasswordFieldUI
if( !showCapsLock ) if( !showCapsLock )
return false; return false;
return FlatUIUtils.isPermanentFocusOwner( getComponent() ) && JTextComponent c = getComponent();
return FlatUIUtils.isPermanentFocusOwner( c ) &&
Toolkit.getDefaultToolkit().getLockingKeyState( KeyEvent.VK_CAPS_LOCK ); Toolkit.getDefaultToolkit().getLockingKeyState( KeyEvent.VK_CAPS_LOCK );
} }
/** @since 2 */
protected void installRevealButton() {
if( showRevealButton ) {
revealButton = createRevealButton();
installLayout();
getComponent().add( revealButton );
}
}
/** @since 2 */
protected JToggleButton createRevealButton() {
JToggleButton button = new JToggleButton( revealIcon );
button.setName( "PasswordField.revealButton" );
prepareLeadingOrTrailingComponent( button );
button.putClientProperty( FlatClientProperties.STYLE_CLASS, "inTextField revealButton" );
if( FlatClientProperties.clientPropertyBoolean( getComponent(), KEY_REVEAL_SELECTED, false ) ) {
button.setSelected( true );
updateEchoChar( true );
}
button.addActionListener( e -> {
boolean selected = button.isSelected();
updateEchoChar( selected );
getComponent().putClientProperty( KEY_REVEAL_SELECTED, selected );
} );
return button;
}
private void updateEchoChar( boolean selected ) {
char newEchoChar = selected
? 0
: (echoChar != null ? echoChar : '*');
JPasswordField c = (JPasswordField) getComponent();
LookAndFeel.installProperty( c, "echoChar", newEchoChar );
// check whether was able to set echo char via LookAndFeel.installProperty()
// if not, then echo char was explicitly changed via JPasswordField.setEchoChar()
char actualEchoChar = c.getEchoChar();
if( actualEchoChar != newEchoChar ) {
if( selected && actualEchoChar != 0 ) {
// use explicitly set echo char
echoChar = actualEchoChar;
uninstallEchoChar = true;
}
c.setEchoChar( newEchoChar );
}
}
/** @since 2 */
protected void uninstallRevealButton() {
if( revealButton != null ) {
if( uninstallEchoChar && revealButton.isSelected() )
((JPasswordField)getComponent()).setEchoChar( echoChar );
getComponent().remove( revealButton );
revealButton = null;
}
}
@Override
protected JComponent[] getTrailingComponents() {
return new JComponent[] { trailingComponent, revealButton, clearButton };
}
} }

View File

@@ -121,10 +121,6 @@ public class FlatPopupFactory
popupWindow.getGraphicsConfiguration() == owner.getGraphicsConfiguration() ) popupWindow.getGraphicsConfiguration() == owner.getGraphicsConfiguration() )
return popup; return popup;
// avoid endless loop (should newer happen; PopupFactory cache size is 5)
if( ++count > 10 )
return popup;
// remove contents component from popup window // remove contents component from popup window
if( popupWindow instanceof JWindow ) if( popupWindow instanceof JWindow )
((JWindow)popupWindow).getContentPane().removeAll(); ((JWindow)popupWindow).getContentPane().removeAll();
@@ -132,6 +128,10 @@ public class FlatPopupFactory
// dispose unused popup // dispose unused popup
// (do not invoke popup.hide() because this would cache the popup window) // (do not invoke popup.hide() because this would cache the popup window)
popupWindow.dispose(); popupWindow.dispose();
// avoid endless loop (should newer happen; PopupFactory cache size is 5)
if( ++count > 10 )
return popup;
} }
} }

View File

@@ -16,18 +16,12 @@
package com.formdev.flatlaf.ui; package com.formdev.flatlaf.ui;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.LayoutManager;
import java.beans.PropertyChangeListener; import java.beans.PropertyChangeListener;
import java.util.Map; import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import javax.swing.BoxLayout;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.plaf.ComponentUI; import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.UIResource;
import javax.swing.plaf.basic.BasicPopupMenuUI; import javax.swing.plaf.basic.BasicPopupMenuUI;
import javax.swing.plaf.basic.DefaultMenuLayout;
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI; import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
import com.formdev.flatlaf.util.LoggingFacade; import com.formdev.flatlaf.util.LoggingFacade;
@@ -70,15 +64,6 @@ public class FlatPopupMenuUI
borderShared = null; borderShared = null;
} }
@Override
public void installDefaults() {
super.installDefaults();
LayoutManager layout = popupMenu.getLayout();
if( layout == null || layout instanceof UIResource )
popupMenu.setLayout( new FlatMenuLayout( popupMenu, BoxLayout.Y_AXIS ) );
}
@Override @Override
protected void installListeners() { protected void installListeners() {
super.installListeners(); super.installListeners();
@@ -121,21 +106,4 @@ public class FlatPopupMenuUI
public Map<String, Class<?>> getStyleableInfos( JComponent c ) { public Map<String, Class<?>> getStyleableInfos( JComponent c ) {
return FlatStylingSupport.getAnnotatedStyleableInfos( this, popupMenu.getBorder() ); return FlatStylingSupport.getAnnotatedStyleableInfos( this, popupMenu.getBorder() );
} }
//---- class FlatMenuLayout -----------------------------------------------
protected static class FlatMenuLayout
extends DefaultMenuLayout
{
public FlatMenuLayout( Container target, int axis ) {
super( target, axis );
}
@Override
public Dimension preferredLayoutSize( Container target ) {
FlatMenuItemRenderer.clearClientProperties( target );
return super.preferredLayoutSize( target );
}
}
} }

View File

@@ -89,7 +89,6 @@ public class FlatRadioButtonMenuItemUI
protected void uninstallDefaults() { protected void uninstallDefaults() {
super.uninstallDefaults(); super.uninstallDefaults();
FlatMenuItemRenderer.clearClientProperties( menuItem.getParent() );
renderer = null; renderer = null;
oldStyleValues = null; oldStyleValues = null;
} }

View File

@@ -139,7 +139,7 @@ public class FlatRadioButtonUI
case FlatClientProperties.STYLE_CLASS: case FlatClientProperties.STYLE_CLASS:
if( shared && FlatStylingSupport.hasStyleProperty( b ) ) { if( shared && FlatStylingSupport.hasStyleProperty( b ) ) {
// unshare component UI if necessary // unshare component UI if necessary
// updateUI() invokes installStyle() from installUI() // updateUI() invokes applyStyle() from installUI()
b.updateUI(); b.updateUI();
} else } else
installStyle( b ); installStyle( b );

View File

@@ -161,19 +161,6 @@ public class FlatRootPaneUI
c.putClientProperty( "jetbrains.awt.windowDarkAppearance", FlatLaf.isLafDark() ); c.putClientProperty( "jetbrains.awt.windowDarkAppearance", FlatLaf.isLafDark() );
} }
@Override
protected void uninstallDefaults( JRootPane c ) {
super.uninstallDefaults( c );
// uninstall background, foreground and font because not all Lafs set them
if( c.isBackgroundSet() && c.getBackground() instanceof UIResource )
c.setBackground( null );
if( c.isForegroundSet() && c.getForeground() instanceof UIResource )
c.setForeground( null );
if( c.isFontSet() && c.getFont() instanceof UIResource )
c.setFont( null );
}
@Override @Override
protected void installListeners( JRootPane root ) { protected void installListeners( JRootPane root ) {
super.installListeners( root ); super.installListeners( root );

View File

@@ -47,7 +47,7 @@ import com.formdev.flatlaf.util.UIScale;
* <!-- BasicScrollBarUI --> * <!-- BasicScrollBarUI -->
* *
* @uiDefault ScrollBar.background Color * @uiDefault ScrollBar.background Color
* @uiDefault ScrollBar.foreground Color unused * @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.width int

View File

@@ -125,7 +125,7 @@ public class FlatSeparatorUI
private void stylePropertyChange( JSeparator s ) { private void stylePropertyChange( JSeparator s ) {
if( shared && FlatStylingSupport.hasStyleProperty( s ) ) { if( shared && FlatStylingSupport.hasStyleProperty( s ) ) {
// unshare component UI if necessary // unshare component UI if necessary
// updateUI() invokes installStyle() from installUI() // updateUI() invokes applyStyle() from installUI()
s.updateUI(); s.updateUI();
} else } else
installStyle( s ); installStyle( s );

View File

@@ -71,7 +71,7 @@ import com.formdev.flatlaf.util.LoggingFacade;
* @uiDefault Spinner.disabledBackground Color * @uiDefault Spinner.disabledBackground Color
* @uiDefault Spinner.disabledForeground Color * @uiDefault Spinner.disabledForeground Color
* @uiDefault Spinner.focusedBackground Color optional * @uiDefault Spinner.focusedBackground Color optional
* @uiDefault Spinner.buttonBackground Color optional * @uiDefault Spinner.buttonBackground Color
* @uiDefault Spinner.buttonSeparatorWidth int or float optional; defaults to Component.borderWidth * @uiDefault Spinner.buttonSeparatorWidth int or float optional; defaults to Component.borderWidth
* @uiDefault Spinner.buttonSeparatorColor Color optional * @uiDefault Spinner.buttonSeparatorColor Color optional
* @uiDefault Spinner.buttonDisabledSeparatorColor Color optional * @uiDefault Spinner.buttonDisabledSeparatorColor Color optional
@@ -385,7 +385,7 @@ public class FlatSpinnerUI
boolean isLeftToRight = spinner.getComponentOrientation().isLeftToRight(); boolean isLeftToRight = spinner.getComponentOrientation().isLeftToRight();
// paint arrow buttons background // paint arrow buttons background
if( enabled && buttonBackground != null ) { if( enabled ) {
g2.setColor( buttonBackground ); g2.setColor( buttonBackground );
Shape oldClip = g2.getClip(); Shape oldClip = g2.getClip();
if( isLeftToRight ) if( isLeftToRight )
@@ -398,7 +398,7 @@ public class FlatSpinnerUI
// paint vertical line between value and arrow buttons // paint vertical line between value and arrow buttons
Color separatorColor = enabled ? buttonSeparatorColor : buttonDisabledSeparatorColor; Color separatorColor = enabled ? buttonSeparatorColor : buttonDisabledSeparatorColor;
if( separatorColor != null && buttonSeparatorWidth > 0 ) { if( separatorColor != null ) {
g2.setColor( separatorColor ); g2.setColor( separatorColor );
float lw = scale( buttonSeparatorWidth ); float lw = scale( buttonSeparatorWidth );
float lx = isLeftToRight ? arrowX : arrowX + arrowWidth - lw; float lx = isLeftToRight ? arrowX : arrowX + arrowWidth - lw;

View File

@@ -37,7 +37,7 @@ import javax.swing.plaf.TableUI;
public class FlatTableCellBorder public class FlatTableCellBorder
extends FlatLineBorder extends FlatLineBorder
{ {
/** @since 2 */ protected boolean showCellFocusIndicator = UIManager.getBoolean( "Table.showCellFocusIndicator" ); protected boolean showCellFocusIndicator = UIManager.getBoolean( "Table.showCellFocusIndicator" );
private Component c; private Component c;

View File

@@ -141,8 +141,8 @@ public class FlatTableHeaderBorder
protected boolean hideTrailingVerticalLine( JTableHeader header ) { protected boolean hideTrailingVerticalLine( JTableHeader header ) {
if( header.getUI() instanceof FlatTableHeaderUI ) { if( header.getUI() instanceof FlatTableHeaderUI ) {
FlatTableHeaderUI ui = (FlatTableHeaderUI) header.getUI(); FlatTableHeaderUI ui = (FlatTableHeaderUI) header.getUI();
if( ui.showTrailingVerticalLine != null ) if( ui.showTrailingVerticalLine )
return !ui.showTrailingVerticalLine; return false;
} }
if( showTrailingVerticalLine ) if( showTrailingVerticalLine )

View File

@@ -84,14 +84,14 @@ public class FlatTableHeaderUI
@Styleable(type=String.class) protected int sortIconPosition; @Styleable(type=String.class) protected int sortIconPosition;
// for FlatTableHeaderBorder // for FlatTableHeaderBorder
/** @since 2 */ @Styleable protected Insets cellMargins; @Styleable protected Insets cellMargins;
/** @since 2 */ @Styleable protected Color separatorColor; @Styleable protected Color separatorColor;
/** @since 2 */ @Styleable protected Boolean showTrailingVerticalLine; /** @since 2 */ @Styleable protected boolean showTrailingVerticalLine;
// for FlatAscendingSortIcon and FlatDescendingSortIcon // for FlatAscendingSortIcon and FlatDescendingSortIcon
// (needs to be public because icon classes are in another package) // (needs to be public because icon classes are in another package)
/** @since 2 */ @Styleable public String arrowType; @Styleable public String arrowType;
/** @since 2 */ @Styleable public Color sortIconColor; @Styleable public Color sortIconColor;
private PropertyChangeListener propertyChangeListener; private PropertyChangeListener propertyChangeListener;
private Map<String, Object> oldStyleValues; private Map<String, Object> oldStyleValues;

View File

@@ -108,9 +108,9 @@ public class FlatTableUI
@Styleable protected Color selectionInactiveForeground; @Styleable protected Color selectionInactiveForeground;
// for FlatTableCellBorder // for FlatTableCellBorder
/** @since 2 */ @Styleable protected Insets cellMargins; @Styleable protected Insets cellMargins;
/** @since 2 */ @Styleable protected Color cellFocusColor; @Styleable protected Color cellFocusColor;
/** @since 2 */ @Styleable protected Boolean showCellFocusIndicator; @Styleable protected boolean showCellFocusIndicator;
private boolean oldShowHorizontalLines; private boolean oldShowHorizontalLines;
private boolean oldShowVerticalLines; private boolean oldShowVerticalLines;

View File

@@ -19,40 +19,29 @@ package com.formdev.flatlaf.ui;
import static com.formdev.flatlaf.FlatClientProperties.*; import static com.formdev.flatlaf.FlatClientProperties.*;
import static com.formdev.flatlaf.util.UIScale.scale; import static com.formdev.flatlaf.util.UIScale.scale;
import java.awt.Color; import java.awt.Color;
import java.awt.Component;
import java.awt.Container; import java.awt.Container;
import java.awt.Cursor;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.FontMetrics; import java.awt.FontMetrics;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.awt.Insets; import java.awt.Insets;
import java.awt.LayoutManager;
import java.awt.LayoutManager2;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.awt.event.FocusListener; import java.awt.event.FocusListener;
import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeEvent;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;
import javax.swing.Icon; import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JComboBox; import javax.swing.JComboBox;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.JSpinner; import javax.swing.JSpinner;
import javax.swing.JTextField; import javax.swing.JTextField;
import javax.swing.JToggleButton;
import javax.swing.JToolBar;
import javax.swing.LookAndFeel; import javax.swing.LookAndFeel;
import javax.swing.UIManager; import javax.swing.UIManager;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
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.BasicTextFieldUI; import javax.swing.plaf.basic.BasicTextFieldUI;
import javax.swing.text.Caret; import javax.swing.text.Caret;
import javax.swing.text.Document;
import javax.swing.text.JTextComponent; import javax.swing.text.JTextComponent;
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable; import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI; import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
@@ -105,12 +94,6 @@ public class FlatTextFieldUI
/** @since 2 */ @Styleable protected Icon leadingIcon; /** @since 2 */ @Styleable protected Icon leadingIcon;
/** @since 2 */ @Styleable protected Icon trailingIcon; /** @since 2 */ @Styleable protected Icon trailingIcon;
/** @since 2 */ protected JComponent leadingComponent;
/** @since 2 */ protected JComponent trailingComponent;
/** @since 2 */ protected JComponent clearButton;
// only used via styling (not in UI defaults, but has likewise client properties)
/** @since 2 */ @Styleable protected boolean showClearButton;
private Color oldDisabledBackground; private Color oldDisabledBackground;
private Color oldInactiveBackground; private Color oldInactiveBackground;
@@ -118,7 +101,6 @@ public class FlatTextFieldUI
private Insets defaultMargin; private Insets defaultMargin;
private FocusListener focusListener; private FocusListener focusListener;
private DocumentListener documentListener;
private Map<String, Object> oldStyleValues; private Map<String, Object> oldStyleValues;
private AtomicBoolean borderShared; private AtomicBoolean borderShared;
@@ -133,19 +115,11 @@ public class FlatTextFieldUI
leadingIcon = clientProperty( c, TEXT_FIELD_LEADING_ICON, null, Icon.class ); leadingIcon = clientProperty( c, TEXT_FIELD_LEADING_ICON, null, Icon.class );
trailingIcon = clientProperty( c, TEXT_FIELD_TRAILING_ICON, null, Icon.class ); trailingIcon = clientProperty( c, TEXT_FIELD_TRAILING_ICON, null, Icon.class );
installLeadingComponent();
installTrailingComponent();
installClearButton();
installStyle(); installStyle();
} }
@Override @Override
public void uninstallUI( JComponent c ) { public void uninstallUI( JComponent c ) {
uninstallLeadingComponent();
uninstallTrailingComponent();
uninstallClearButton();
super.uninstallUI( c ); super.uninstallUI( c );
leadingIcon = null; leadingIcon = null;
@@ -207,11 +181,6 @@ public class FlatTextFieldUI
getComponent().removeFocusListener( focusListener ); getComponent().removeFocusListener( focusListener );
focusListener = null; focusListener = null;
if( documentListener != null ) {
getComponent().getDocument().removeDocumentListener( documentListener );
documentListener = null;
}
} }
@Override @Override
@@ -256,61 +225,9 @@ public class FlatTextFieldUI
trailingIcon = (e.getNewValue() instanceof Icon) ? (Icon) e.getNewValue() : null; trailingIcon = (e.getNewValue() instanceof Icon) ? (Icon) e.getNewValue() : null;
c.repaint(); c.repaint();
break; break;
case TEXT_FIELD_LEADING_COMPONENT:
uninstallLeadingComponent();
installLeadingComponent();
c.revalidate();
c.repaint();
break;
case TEXT_FIELD_TRAILING_COMPONENT:
uninstallTrailingComponent();
installTrailingComponent();
c.revalidate();
c.repaint();
break;
case TEXT_FIELD_SHOW_CLEAR_BUTTON:
uninstallClearButton();
installClearButton();
c.revalidate();
c.repaint();
break;
case "enabled":
case "editable":
updateClearButton();
break;
case "document":
if( documentListener != null ) {
if( e.getOldValue() instanceof Document )
((Document)e.getOldValue()).removeDocumentListener( documentListener );
if( e.getNewValue() instanceof Document )
((Document)e.getNewValue()).addDocumentListener( documentListener );
updateClearButton();
}
break;
} }
} }
/** @since 2 */
protected void installDocumentListener() {
if( documentListener != null )
return;
documentListener = new FlatDocumentListener();
getComponent().getDocument().addDocumentListener( documentListener );
}
/** @since 2 */
protected void documentChanged( DocumentEvent e ) {
if( clearButton != null )
updateClearButton();
}
/** @since 2 */ /** @since 2 */
protected void installStyle() { protected void installStyle() {
try { try {
@@ -329,15 +246,10 @@ public class FlatTextFieldUI
protected void applyStyle( Object style ) { protected void applyStyle( Object style ) {
oldDisabledBackground = disabledBackground; oldDisabledBackground = disabledBackground;
oldInactiveBackground = inactiveBackground; oldInactiveBackground = inactiveBackground;
boolean oldShowClearButton = showClearButton;
oldStyleValues = FlatStylingSupport.parseAndApply( oldStyleValues, style, this::applyStyleProperty ); oldStyleValues = FlatStylingSupport.parseAndApply( oldStyleValues, style, this::applyStyleProperty );
updateBackground(); updateBackground();
if( showClearButton != oldShowClearButton ) {
uninstallClearButton();
installClearButton();
}
} }
/** @since 2 */ /** @since 2 */
@@ -532,16 +444,6 @@ debug*/
// add width of leading and trailing icons // add width of leading and trailing icons
size.width += getLeadingIconWidth() + getTrailingIconWidth(); size.width += getLeadingIconWidth() + getTrailingIconWidth();
// add width of leading and trailing components
for( JComponent comp : getLeadingComponents() ) {
if( comp != null && comp.isVisible() )
size.width += comp.getPreferredSize().width;
}
for( JComponent comp : getTrailingComponents() ) {
if( comp != null && comp.isVisible() )
size.width += comp.getPreferredSize().width;
}
return size; return size;
} }
@@ -608,8 +510,7 @@ debug*/
/** /**
* Returns the rectangle used to paint leading and trailing icons. * Returns the rectangle used to paint leading and trailing icons.
* It invokes {@code super.getVisibleEditorRect()} and reduces left and/or * It invokes {@code super.getVisibleEditorRect()} and reduces left and/or
* right margin if the text field has leading or trailing icons or components. * right margin if the text field has leading or trailing icons.
* Also the preferred widths of leading and trailing components are removed.
* *
* @since 2 * @since 2
*/ */
@@ -618,31 +519,10 @@ debug*/
if( r == null ) if( r == null )
return null; return null;
boolean ltr = isLeftToRight(); // if a leading/trailing icon is shown, then the left/right margin is reduced
// remove width of leading/trailing components
JComponent[] leftComponents = ltr ? getLeadingComponents() : getTrailingComponents();
JComponent[] rightComponents = ltr ? getTrailingComponents() : getLeadingComponents();
boolean leftVisible = false;
boolean rightVisible = false;
for( JComponent leftComponent : leftComponents ) {
if( leftComponent != null && leftComponent.isVisible() ) {
int w = leftComponent.getPreferredSize().width;
r.x += w;
r.width -= w;
leftVisible = true;
}
}
for( JComponent rightComponent : rightComponents ) {
if( rightComponent != null && rightComponent.isVisible() ) {
r.width -= rightComponent.getPreferredSize().width;
rightVisible = true;
}
}
// if a leading/trailing icons (or components) are shown, then the left/right margins are reduced
// to the top margin, which places the icon nicely centered on left/right side // to the top margin, which places the icon nicely centered on left/right side
if( leftVisible || (ltr ? hasLeadingIcon() : hasTrailingIcon()) ) { boolean ltr = isLeftToRight();
if( ltr ? hasLeadingIcon() : hasTrailingIcon() ) {
// reduce left margin // reduce left margin
Insets margin = getComponent().getMargin(); Insets margin = getComponent().getMargin();
int newLeftMargin = Math.min( margin.left, margin.top ); int newLeftMargin = Math.min( margin.left, margin.top );
@@ -652,7 +532,7 @@ debug*/
r.width += diff; r.width += diff;
} }
} }
if( rightVisible || (ltr ? hasTrailingIcon() : hasLeadingIcon()) ) { if( ltr ? hasTrailingIcon() : hasLeadingIcon() ) {
// reduce right margin // reduce right margin
Insets margin = getComponent().getMargin(); Insets margin = getComponent().getMargin();
int newRightMargin = Math.min( margin.right, margin.top ); int newRightMargin = Math.min( margin.right, margin.top );
@@ -660,10 +540,6 @@ debug*/
r.width += scale( margin.right - newRightMargin ); r.width += scale( margin.right - newRightMargin );
} }
// make sure that width and height are not negative
r.width = Math.max( r.width, 0 );
r.height = Math.max( r.height, 0 );
return r; return r;
} }
@@ -702,266 +578,4 @@ debug*/
if( caret instanceof FlatCaret ) if( caret instanceof FlatCaret )
((FlatCaret)caret).scrollCaretToVisible(); ((FlatCaret)caret).scrollCaretToVisible();
} }
/** @since 2 */
protected void installLeadingComponent() {
JTextComponent c = getComponent();
leadingComponent = clientProperty( c, TEXT_FIELD_LEADING_COMPONENT, null, JComponent.class );
if( leadingComponent != null ) {
prepareLeadingOrTrailingComponent( leadingComponent );
installLayout();
c.add( leadingComponent );
}
}
/** @since 2 */
protected void installTrailingComponent() {
JTextComponent c = getComponent();
trailingComponent = clientProperty( c, TEXT_FIELD_TRAILING_COMPONENT, null, JComponent.class );
if( trailingComponent != null ) {
prepareLeadingOrTrailingComponent( trailingComponent );
installLayout();
c.add( trailingComponent );
}
}
/** @since 2 */
protected void uninstallLeadingComponent() {
if( leadingComponent != null ) {
getComponent().remove( leadingComponent );
leadingComponent = null;
}
}
/** @since 2 */
protected void uninstallTrailingComponent() {
if( trailingComponent != null ) {
getComponent().remove( trailingComponent );
trailingComponent = null;
}
}
/** @since 2 */
protected void installClearButton() {
JTextComponent c = getComponent();
if( clientPropertyBoolean( c, TEXT_FIELD_SHOW_CLEAR_BUTTON, showClearButton ) ) {
clearButton = createClearButton();
updateClearButton();
installDocumentListener();
installLayout();
c.add( clearButton );
}
}
/** @since 2 */
protected void uninstallClearButton() {
if( clearButton != null ) {
getComponent().remove( clearButton );
clearButton = null;
}
}
/** @since 2 */
protected JComponent createClearButton() {
JButton button = new JButton();
button.setName( "TextField.clearButton" );
button.putClientProperty( STYLE_CLASS, "clearButton" );
button.putClientProperty( BUTTON_TYPE, BUTTON_TYPE_TOOLBAR_BUTTON );
button.setCursor( Cursor.getDefaultCursor() );
button.addActionListener( e -> clearButtonClicked() );
return button;
}
/** @since 2 */
@SuppressWarnings( "unchecked" )
protected void clearButtonClicked() {
JTextComponent c = getComponent();
Object callback = c.getClientProperty( TEXT_FIELD_CLEAR_CALLBACK );
if( callback instanceof Runnable )
((Runnable)callback).run();
else if( callback instanceof Consumer )
((Consumer<JTextComponent>)callback).accept( c );
else
c.setText( "" );
}
/** @since 2 */
protected void updateClearButton() {
if( clearButton == null )
return;
JTextComponent c = getComponent();
boolean visible = c.isEnabled() && c.isEditable() && c.getDocument().getLength() > 0;
if( visible != clearButton.isVisible() ) {
clearButton.setVisible( visible );
c.revalidate();
c.repaint();
}
}
/**
* Returns components placed at the leading side of the text field.
* The returned array may contain {@code null}.
* The default implementation returns {@link #leadingComponent}.
*
* @since 2
*/
protected JComponent[] getLeadingComponents() {
return new JComponent[] { leadingComponent };
}
/**
* Returns components placed at the trailing side of the text field.
* The returned array may contain {@code null}.
* The default implementation returns {@link #trailingComponent} and {@link #clearButton}.
* <p>
* <strong>Note</strong>: The components in the array must be in reverse (visual) order.
*
* @since 2
*/
protected JComponent[] getTrailingComponents() {
return new JComponent[] { trailingComponent, clearButton };
}
/** @since 2 */
protected void prepareLeadingOrTrailingComponent( JComponent c ) {
c.putClientProperty( STYLE_CLASS, "inTextField" );
if( c instanceof JButton || c instanceof JToggleButton ) {
c.putClientProperty( BUTTON_TYPE, BUTTON_TYPE_TOOLBAR_BUTTON );
if( !c.isCursorSet() )
c.setCursor( Cursor.getDefaultCursor() );
} else if( c instanceof JToolBar ) {
for( Component child : c.getComponents() ) {
if( child instanceof JComponent )
((JComponent)child).putClientProperty( STYLE_CLASS, "inTextField" );
}
if( !c.isCursorSet() )
c.setCursor( Cursor.getDefaultCursor() );
}
}
/** @since 2 */
protected void installLayout() {
JTextComponent c = getComponent();
LayoutManager oldLayout = c.getLayout();
if( !(oldLayout instanceof FlatTextFieldLayout) )
c.setLayout( new FlatTextFieldLayout( oldLayout ) );
}
//---- class FlatTextFieldLayout ------------------------------------------
private class FlatTextFieldLayout
implements LayoutManager2, UIResource
{
private final LayoutManager delegate;
FlatTextFieldLayout( LayoutManager delegate ) {
this.delegate = delegate;
}
@Override
public void addLayoutComponent( String name, Component comp ) {
if( delegate != null )
delegate.addLayoutComponent( name, comp );
}
@Override
public void removeLayoutComponent( Component comp ) {
if( delegate != null )
delegate.removeLayoutComponent( comp );
}
@Override
public Dimension preferredLayoutSize( Container parent ) {
return (delegate != null) ? delegate.preferredLayoutSize( parent ) : null;
}
@Override
public Dimension minimumLayoutSize( Container parent ) {
return (delegate != null) ? delegate.minimumLayoutSize( parent ) : null;
}
@Override
public void layoutContainer( Container parent ) {
if( delegate != null )
delegate.layoutContainer( parent );
int ow = FlatUIUtils.getBorderFocusAndLineWidth( getComponent() );
int h = parent.getHeight() - ow - ow;
boolean ltr = isLeftToRight();
JComponent[] leftComponents = ltr ? getLeadingComponents() : getTrailingComponents();
JComponent[] rightComponents = ltr ? getTrailingComponents() : getLeadingComponents();
// layout left components
int x = ow;
for( JComponent leftComponent : leftComponents ) {
if( leftComponent != null && leftComponent.isVisible() ) {
int cw = leftComponent.getPreferredSize().width;
leftComponent.setBounds( x, ow, cw, h );
x += cw;
}
}
// layout right components
x = parent.getWidth() - ow;
for( JComponent rightComponent : rightComponents ) {
if( rightComponent != null && rightComponent.isVisible() ) {
int cw = rightComponent.getPreferredSize().width;
x -= cw;
rightComponent.setBounds( x, ow, cw, h );
}
}
}
@Override
public void addLayoutComponent( Component comp, Object constraints ) {
if( delegate instanceof LayoutManager2 )
((LayoutManager2)delegate).addLayoutComponent( comp, constraints );
}
@Override
public Dimension maximumLayoutSize( Container target ) {
return (delegate instanceof LayoutManager2) ? ((LayoutManager2)delegate).maximumLayoutSize( target ) : null;
}
@Override
public float getLayoutAlignmentX( Container target ) {
return (delegate instanceof LayoutManager2) ? ((LayoutManager2)delegate).getLayoutAlignmentX( target ) : 0.5f;
}
@Override
public float getLayoutAlignmentY( Container target ) {
return (delegate instanceof LayoutManager2) ? ((LayoutManager2)delegate).getLayoutAlignmentY( target ) : 0.5f;
}
@Override
public void invalidateLayout( Container target ) {
if( delegate instanceof LayoutManager2 )
((LayoutManager2)delegate).invalidateLayout( target );
}
}
//---- class FlatDocumentListener -----------------------------------------
private class FlatDocumentListener
implements DocumentListener
{
@Override
public void insertUpdate( DocumentEvent e ) {
documentChanged( e );
}
@Override
public void removeUpdate( DocumentEvent e ) {
documentChanged( e );
}
@Override
public void changedUpdate( DocumentEvent e ) {
documentChanged( e );
}
}
} }

View File

@@ -360,7 +360,7 @@ public class FlatTitlePane
// show/hide icon // show/hide icon
iconLabel.setVisible( hasIcon ); iconLabel.setVisible( hasIcon );
leftPanel.setBorder( hasIcon ? null : FlatUIUtils.nonUIResource( new FlatEmptyBorder( 0, noIconLeftGap, 0, 0 ) ) ); leftPanel.setBorder( hasIcon ? null : new FlatEmptyBorder( 0, noIconLeftGap, 0, 0 ) );
updateNativeTitleBarHeightAndHitTestSpotsLater(); updateNativeTitleBarHeightAndHitTestSpotsLater();
} }
@@ -854,7 +854,7 @@ debug*/
} else if( borderColor != null && (rootPane.getJMenuBar() == null || !rootPane.getJMenuBar().isVisible()) ) } else if( borderColor != null && (rootPane.getJMenuBar() == null || !rootPane.getJMenuBar().isVisible()) )
insets.bottom += UIScale.scale( 1 ); insets.bottom += UIScale.scale( 1 );
if( !SystemInfo.isWindows_11_orLater && hasNativeCustomDecoration() && !isWindowMaximized( c ) ) if( hasNativeCustomDecoration() && !isWindowMaximized( c ) )
insets = FlatUIUtils.addInsets( insets, WindowTopBorder.getInstance().getBorderInsets() ); insets = FlatUIUtils.addInsets( insets, WindowTopBorder.getInstance().getBorderInsets() );
return insets; return insets;
@@ -873,7 +873,7 @@ debug*/
FlatUIUtils.paintFilledRectangle( g, borderColor, x, y + height - lineHeight, width, lineHeight ); FlatUIUtils.paintFilledRectangle( g, borderColor, x, y + height - lineHeight, width, lineHeight );
} }
if( !SystemInfo.isWindows_11_orLater && hasNativeCustomDecoration() && !isWindowMaximized( c ) ) if( hasNativeCustomDecoration() && !isWindowMaximized( c ) )
WindowTopBorder.getInstance().paintBorder( c, g, x, y, width, height ); WindowTopBorder.getInstance().paintBorder( c, g, x, y, width, height );
} }
@@ -966,7 +966,7 @@ debug*/
activeChanged( true ); activeChanged( true );
updateNativeTitleBarHeightAndHitTestSpots(); updateNativeTitleBarHeightAndHitTestSpots();
if( !SystemInfo.isWindows_11_orLater && hasNativeCustomDecoration() ) if( hasNativeCustomDecoration() )
WindowTopBorder.getInstance().repaintBorder( FlatTitlePane.this ); WindowTopBorder.getInstance().repaintBorder( FlatTitlePane.this );
repaintWindowBorder(); repaintWindowBorder();
@@ -977,7 +977,7 @@ debug*/
activeChanged( false ); activeChanged( false );
updateNativeTitleBarHeightAndHitTestSpots(); updateNativeTitleBarHeightAndHitTestSpots();
if( !SystemInfo.isWindows_11_orLater && hasNativeCustomDecoration() ) if( hasNativeCustomDecoration() )
WindowTopBorder.getInstance().repaintBorder( FlatTitlePane.this ); WindowTopBorder.getInstance().repaintBorder( FlatTitlePane.this );
repaintWindowBorder(); repaintWindowBorder();

View File

@@ -121,7 +121,7 @@ public class FlatToolBarSeparatorUI
private void stylePropertyChange( JSeparator s ) { private void stylePropertyChange( JSeparator s ) {
if( shared && FlatStylingSupport.hasStyleProperty( s ) ) { if( shared && FlatStylingSupport.hasStyleProperty( s ) ) {
// unshare component UI if necessary // unshare component UI if necessary
// updateUI() invokes installStyle() from installUI() // updateUI() invokes applyStyle() from installUI()
s.updateUI(); s.updateUI();
} else } else
installStyle( s ); installStyle( s );

View File

@@ -52,7 +52,6 @@ import com.formdev.flatlaf.util.UIScale;
* *
* @uiDefault Tree.font Font * @uiDefault Tree.font Font
* @uiDefault Tree.background Color * @uiDefault Tree.background Color
* @uiDefault Tree.foreground Color unused
* @uiDefault Tree.hash Color * @uiDefault Tree.hash Color
* @uiDefault Tree.dropLineColor Color * @uiDefault Tree.dropLineColor Color
* @uiDefault Tree.expandedIcon Icon * @uiDefault Tree.expandedIcon Icon
@@ -137,12 +136,12 @@ public class FlatTreeUI
// for icons // for icons
// (needs to be public because icon classes are in another package) // (needs to be public because icon classes are in another package)
/** @since 2 */ @Styleable(dot=true) public String iconArrowType; @Styleable(dot=true) public String iconArrowType;
/** @since 2 */ @Styleable(dot=true) public Color iconExpandedColor; @Styleable(dot=true) public Color iconExpandedColor;
/** @since 2 */ @Styleable(dot=true) public Color iconCollapsedColor; @Styleable(dot=true) public Color iconCollapsedColor;
/** @since 2 */ @Styleable(dot=true) public Color iconLeafColor; @Styleable(dot=true) public Color iconLeafColor;
/** @since 2 */ @Styleable(dot=true) public Color iconClosedColor; @Styleable(dot=true) public Color iconClosedColor;
/** @since 2 */ @Styleable(dot=true) public Color iconOpenColor; @Styleable(dot=true) public Color iconOpenColor;
// only used via styling (not in UI defaults, but has likewise client properties) // only used via styling (not in UI defaults, but has likewise client properties)
/** @since 2 */ @Styleable protected boolean paintSelection = true; /** @since 2 */ @Styleable protected boolean paintSelection = true;

View File

@@ -188,11 +188,6 @@ public class FlatUIUtils
return (font instanceof UIResource) ? font.deriveFont( font.getStyle() ) : font; return (font instanceof UIResource) ? font.deriveFont( font.getStyle() ) : font;
} }
/** @since 2 */
public static Border nonUIResource( Border border ) {
return (border instanceof UIResource) ? new NonUIResourceBorder( border ) : border;
}
public static int minimumWidth( JComponent c, int minimumWidth ) { public static int minimumWidth( JComponent c, int minimumWidth ) {
return FlatClientProperties.clientPropertyInt( c, FlatClientProperties.MINIMUM_WIDTH, minimumWidth ); return FlatClientProperties.clientPropertyInt( c, FlatClientProperties.MINIMUM_WIDTH, minimumWidth );
} }
@@ -278,32 +273,6 @@ public class FlatUIUtils
: 0; : 0;
} }
/**
* Returns the scaled line thickness used to compute the border insets.
*
* @since 2
*/
public static float getBorderLineWidth( JComponent c ) {
FlatBorder border = getOutsideFlatBorder( c );
return (border != null)
? UIScale.scale( (float) border.getLineWidth( c ) )
: 0;
}
/**
* Returns the scaled thickness of the border.
* This includes the outer focus border and the actual component border.
*
* @since 2
*/
public static int getBorderFocusAndLineWidth( JComponent c ) {
FlatBorder border = getOutsideFlatBorder( c );
return (border != null)
? Math.round( UIScale.scale( (float) border.getFocusWidth( c ) )
+ UIScale.scale( (float) border.getLineWidth( c ) ) )
: 0;
}
/** /**
* Returns the scaled arc diameter of the border for the given component. * Returns the scaled arc diameter of the border for the given component.
*/ */
@@ -1013,31 +982,4 @@ debug*/
repaintComponent.repaint(); repaintComponent.repaint();
} }
} }
//---- 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();
}
}
} }

View File

@@ -27,7 +27,6 @@ import java.awt.Window;
import java.awt.geom.AffineTransform; import java.awt.geom.AffineTransform;
import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener; import java.beans.PropertyChangeListener;
import java.io.File;
import java.util.Collections; import java.util.Collections;
import java.util.IdentityHashMap; import java.util.IdentityHashMap;
import java.util.List; import java.util.List;
@@ -38,7 +37,6 @@ import javax.swing.Timer;
import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener; import javax.swing.event.ChangeListener;
import javax.swing.event.EventListenerList; import javax.swing.event.EventListenerList;
import com.formdev.flatlaf.FlatSystemProperties;
import com.formdev.flatlaf.util.LoggingFacade; import com.formdev.flatlaf.util.LoggingFacade;
import com.formdev.flatlaf.util.NativeLibrary; import com.formdev.flatlaf.util.NativeLibrary;
import com.formdev.flatlaf.util.SystemInfo; import com.formdev.flatlaf.util.SystemInfo;
@@ -92,10 +90,6 @@ class FlatWindowsNativeWindowBorder
if( !SystemInfo.isWindows_10_orLater ) if( !SystemInfo.isWindows_10_orLater )
return null; return null;
// requires x86 architecture
if( !SystemInfo.isX86 && !SystemInfo.isX86_64 )
return null;
// load native library // load native library
if( nativeLibrary == null ) { if( nativeLibrary == null ) {
if( !SystemInfo.isJava_9_orLater ) { if( !SystemInfo.isJava_9_orLater ) {
@@ -116,7 +110,11 @@ class FlatWindowsNativeWindowBorder
} }
} }
nativeLibrary = createNativeLibrary(); String libraryName = "com/formdev/flatlaf/natives/flatlaf-windows-x86";
if( SystemInfo.isX86_64 )
libraryName += "_64";
nativeLibrary = new NativeLibrary( libraryName, null, true );
} }
// check whether native library was successfully loaded // check whether native library was successfully loaded
@@ -129,23 +127,6 @@ class FlatWindowsNativeWindowBorder
return instance; return instance;
} }
private static NativeLibrary createNativeLibrary() {
String libraryName = "flatlaf-windows-x86";
if( SystemInfo.isX86_64 )
libraryName += "_64";
String libraryPath = System.getProperty( FlatSystemProperties.NATIVE_LIBRARY_PATH );
if( libraryPath != null ) {
File libraryFile = new File( libraryPath, libraryName + ".dll" );
if( libraryFile.exists() )
return new NativeLibrary( libraryFile, true );
else
LoggingFacade.INSTANCE.logSevere( "Did not find external library " + libraryFile + ", using extracted library instead", null );
}
return new NativeLibrary( "com/formdev/flatlaf/natives/" + libraryName, null, true );
}
private FlatWindowsNativeWindowBorder() { private FlatWindowsNativeWindowBorder() {
} }
@@ -186,18 +167,11 @@ class FlatWindowsNativeWindowBorder
return; return;
// install // install
try { WndProc wndProc = new WndProc( window );
WndProc wndProc = new WndProc( window ); if( wndProc.hwnd == 0 )
if( wndProc.hwnd == 0 ) return;
return;
windowsMap.put( window, wndProc ); windowsMap.put( window, wndProc );
} catch( UnsatisfiedLinkError ex ) {
// catch for the case that the operating system prevents execution of DLL
// (e.g. if DLLs in temp folder are restricted)
// --> continue application without custom decorations
LoggingFacade.INSTANCE.logSevere( null, ex );
}
} }
private void uninstall( Window window ) { private void uninstall( Window window ) {

View File

@@ -298,7 +298,7 @@ public class JBRCustomDecorations
} }
private void paintImpl( Graphics2D g, int x, int y, int width, int height, double scaleFactor ) { private void paintImpl( Graphics2D g, int x, int y, int width, int height, double scaleFactor ) {
g.fillRect( x, y, width, 1 ); g.drawRect( x, y, width - 1, 0 );
} }
void repaintBorder( Component c ) { void repaintBorder( Component c ) {

View File

@@ -0,0 +1,83 @@
/*
* Copyright 2021 FormDev Software GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.formdev.flatlaf.util;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JComponent;
import javax.swing.border.Border;
/**
* Border that automatically animates painting on component value changes.
* <p>
* {@link #getAnimatableValues(Component)} returns the animatable value(s) of the component.
* If the value(s) have changed, then {@link #paintAnimated(Component, Graphics2D, int, int, int, int, float[])}
* is invoked multiple times with animated value(s) (from old value(s) to new value(s)).
* If {@link #getAnimatableValues(Component)} returns multiple values, then each value
* gets its own independent animation, which may start/end at different points in time,
* may have different duration, resolution and interpolator.
* <p>
* Example for an animated border:
* <pre>
* private class MyAnimatedBorder
* implements AnimatedBorder
* {
* &#64;Override
* public float[] getAnimatableValues( Component c ) {
* return new float[] { c.isFocusOwner() ? 1 : 0 };
* }
*
* &#64;Override
* public void paintAnimated( Component c, Graphics2D g, int x, int y, int width, int height, float[] animatedValues ) {
* int lh = UIScale.scale( 2 );
*
* g.setColor( Color.blue );
* g.fillRect( x, y + height - lh, Math.round( width * animatedValues[0] ), lh );
* }
*
* &#64;Override
* public Insets getBorderInsets( Component c ) {
* return UIScale.scale( new Insets( 4, 4, 4, 4 ) );
* }
*
* &#64;Override public boolean isBorderOpaque() { return false; }
* }
*
* // sample usage
* JTextField textField = new JTextField();
* textField.setBorder( new MyAnimatedBorder() );
* </pre>
*
* Animation works only if the component passed to {@link #paintBorder(Component, Graphics, int, int, int, int)}
* is a instance of {@link JComponent}.
* A client property is set on the component to store the animation state.
*
* @author Karl Tauber
* @since 2
*/
public interface AnimatedBorder
extends Border, AnimatedPainter
{
/**
* Invokes {@link #paintWithAnimation(Component, Graphics, int, int, int, int)}.
*/
@Override
default void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
paintWithAnimation( c, g, x, y, width, height );
}
}

View File

@@ -18,62 +18,87 @@ package com.formdev.flatlaf.util;
import java.awt.Component; import java.awt.Component;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.Icon; import javax.swing.Icon;
import javax.swing.JComponent; import javax.swing.JComponent;
import com.formdev.flatlaf.util.Animator.Interpolator;
/** /**
* Icon that automatically animates painting on component value changes. * Icon that automatically animates painting on component value changes.
* <p> * <p>
* {@link #getValue(Component)} returns the value of the component. * {@link #getAnimatableValues(Component)} returns the animatable value(s) of the component.
* If the value changes, then {@link #paintIconAnimated(Component, Graphics, int, int, float)} * If the value(s) have changed, then {@link #paintAnimated(Component, Graphics2D, int, int, int, int, float[])}
* is invoked multiple times with animated value (from old value to new value). * is invoked multiple times with animated value(s) (from old value(s) to new value(s)).
* If {@link #getAnimatableValues(Component)} returns multiple values, then each value
* gets its own independent animation, which may start/end at different points in time,
* may have different duration, resolution and interpolator.
* <p> * <p>
* Example for an animated icon: * Example for an animated icon:
* <pre> * <pre>
* private class AnimatedMinimalTestIcon * private class MyAnimatedIcon
* implements AnimatedIcon * implements AnimatedIcon
* { * {
* &#64;Override
* public float[] getAnimatableValues( Component c ) {
* return new float[] { ((AbstractButton)c).isSelected() ? 1 : 0 };
* }
*
* &#64;Override public int getIconWidth() { return 100; } * &#64;Override public int getIconWidth() { return 100; }
* &#64;Override public int getIconHeight() { return 20; } * &#64;Override public int getIconHeight() { return 20; }
* *
* &#64;Override * &#64;Override
* public void paintIconAnimated( Component c, Graphics g, int x, int y, float animatedValue ) { * public void paintAnimated( Component c, Graphics2D g, int x, int y, int width, int height, float[] animatedValues ) {
* int w = getIconWidth();
* int h = getIconHeight();
*
* g.setColor( Color.red ); * g.setColor( Color.red );
* g.drawRect( x, y, w - 1, h - 1 ); * g.drawRect( x, y, width - 1, height - 1 );
* g.fillRect( x, y, Math.round( w * animatedValue ), h ); * g.fillRect( x, y, Math.round( width * animatedValues[0] ), height );
* }
*
* &#64;Override
* public float getValue( Component c ) {
* return ((AbstractButton)c).isSelected() ? 1 : 0;
* } * }
* } * }
* *
* // sample usage * // sample usage
* JCheckBox checkBox = new JCheckBox( "test" ); * JCheckBox checkBox = new JCheckBox( "test" );
* checkBox.setIcon( new AnimatedMinimalTestIcon() ); * checkBox.setIcon( new MyAnimatedIcon() );
* </pre> * </pre>
* *
* Animation works only if the component passed to {@link #paintIcon(Component, Graphics, int, int)} * Animation works only if the component passed to {@link #paintIcon(Component, Graphics, int, int)}
* is a instance of {@link JComponent}. * is an instance of {@link JComponent}.
* A client property is set on the component to store the animation state. * A client property is set on the component to store the animation state.
* *
* @author Karl Tauber * @author Karl Tauber
*/ */
public interface AnimatedIcon public interface AnimatedIcon
extends Icon extends Icon, AnimatedPainter
{ {
/**
* {@inheritDoc}
*
* @since 2
*/
@Override @Override
public default void paintIcon( Component c, Graphics g, int x, int y ) { default float[] getAnimatableValues( Component c ) {
AnimationSupport.paintIcon( this, c, g, x, y ); // for compatibility
return new float[] { getValue( c ) };
} }
/** /**
* Paints the icon for the given animated value. * Invokes {@link #paintWithAnimation(Component, Graphics, int, int, int, int)}.
*/
@Override
default void paintIcon( Component c, Graphics g, int x, int y ) {
paintWithAnimation( c, g, x, y, getIconWidth(), getIconHeight() );
}
/**
* {@inheritDoc}
*
* @since 2
*/
@Override
default void paintAnimated( Component c, Graphics2D g, int x, int y, int width, int height, float[] animatedValues ) {
// for compatibility
paintIconAnimated( c, g, x, y, animatedValues[0] );
}
/**
* Paints the icon for the given (animated) value.
* *
* @param c the component that this icon belongs to * @param c the component that this icon belongs to
* @param g the graphics context * @param g the graphics context
@@ -82,52 +107,45 @@ public interface AnimatedIcon
* @param animatedValue the animated value, which is either equal to what {@link #getValue(Component)} * @param animatedValue the animated value, which is either equal to what {@link #getValue(Component)}
* returned, or somewhere between the previous value and the latest value * returned, or somewhere between the previous value and the latest value
* that {@link #getValue(Component)} returned * that {@link #getValue(Component)} returned
*
* @deprecated override {@link #paintAnimated(Component, Graphics2D, int, int, int, int, float[])} instead
*/ */
void paintIconAnimated( Component c, Graphics g, int x, int y, float animatedValue ); @Deprecated
default void paintIconAnimated( Component c, Graphics g, int x, int y, float animatedValue ) {
}
/** /**
* Gets the value of the component. * Gets the animatable value of the component.
* <p> * <p>
* This can be any value and depends on the component. * This can be any value and depends on the component.
* If the value changes, then this class animates from the old value to the new one. * If the value changes, then this class animates from the old value to the new one.
* <p> * <p>
* For a toggle button this could be {@code 0} for off and {@code 1} for on. * For a toggle button this could be {@code 0} for off and {@code 1} for on.
*
* @deprecated override {@link #getAnimatableValues(Component)} instead
*/ */
float getValue( Component c ); @Deprecated
default float getValue( Component c ) {
/** return 0;
* Returns whether animation is enabled for this icon (default is {@code true}).
*/
default boolean isAnimationEnabled() {
return true;
} }
/** /**
* Returns the duration of the animation in milliseconds (default is 150). * {@inheritDoc}
*
* @since TODO
*/ */
default int getAnimationDuration() { @Override
return 150; default Object getAnimationClientPropertyKey() {
} // for compatibility
return getClientPropertyKey();
/**
* Returns the resolution of the animation in milliseconds (default is 10).
* Resolution is the amount of time between timing events.
*/
default int getAnimationResolution() {
return 10;
}
/**
* Returns the interpolator for the animation.
* Default is {@link CubicBezierEasing#STANDARD_EASING}.
*/
default Interpolator getAnimationInterpolator() {
return CubicBezierEasing.STANDARD_EASING;
} }
/** /**
* Returns the client property key used to store the animation support. * Returns the client property key used to store the animation support.
*
* @deprecated override {@link #getAnimationClientPropertyKey()} instead
*/ */
@Deprecated
default Object getClientPropertyKey() { default Object getClientPropertyKey() {
return getClass(); return getClass();
} }
@@ -135,115 +153,25 @@ public interface AnimatedIcon
//---- class AnimationSupport --------------------------------------------- //---- class AnimationSupport ---------------------------------------------
/** /**
* Animation support class that stores the animation state and implements the animation. * Animation support.
*/ */
@Deprecated
class AnimationSupport class AnimationSupport
{ {
private float startValue; /**
private float targetValue; * @deprecated use {@link AnimatedPainter#paintWithAnimation(Component, Graphics, int, int, int, int)} instead
private float animatedValue; */
private float fraction; @Deprecated
private Animator animator;
// last x,y coordinates of the icon needed to repaint while animating
private int x;
private int y;
public static void paintIcon( AnimatedIcon icon, Component c, Graphics g, int x, int y ) { public static void paintIcon( AnimatedIcon icon, Component c, Graphics g, int x, int y ) {
if( !isAnimationEnabled( icon, c ) ) { AnimatedPainterSupport.paint( icon, c, (Graphics2D) g, x, y, icon.getIconWidth(), icon.getIconHeight() );
// paint without animation if animation is disabled or
// component is not a JComponent and therefore does not support
// client properties, which are required to keep animation state
paintIconImpl( icon, c, g, x, y, null );
return;
}
JComponent jc = (JComponent) c;
Object key = icon.getClientPropertyKey();
AnimationSupport as = (AnimationSupport) jc.getClientProperty( key );
if( as == null ) {
// painted first time --> do not animate, but remember current component value
as = new AnimationSupport();
as.startValue = as.targetValue = as.animatedValue = icon.getValue( c );
as.x = x;
as.y = y;
jc.putClientProperty( key, as );
} else {
// get component value
float value = icon.getValue( c );
if( value != as.targetValue ) {
// value changed --> (re)start animation
if( as.animator == null ) {
// create animator
AnimationSupport as2 = as;
as.animator = new Animator( icon.getAnimationDuration(), fraction -> {
// check whether component was removed while animation is running
if( !c.isDisplayable() ) {
as2.animator.stop();
return;
}
// compute animated value
as2.animatedValue = as2.startValue + ((as2.targetValue - as2.startValue) * fraction);
as2.fraction = fraction;
// repaint icon
c.repaint( as2.x, as2.y, icon.getIconWidth(), icon.getIconHeight() );
}, () -> {
as2.startValue = as2.animatedValue = as2.targetValue;
as2.animator = null;
} );
}
if( as.animator.isRunning() ) {
// if animation is still running, restart it from the current
// animated value to the new target value with reduced duration
as.animator.cancel();
int duration2 = (int) (icon.getAnimationDuration() * as.fraction);
if( duration2 > 0 )
as.animator.setDuration( duration2 );
as.startValue = as.animatedValue;
} else {
// new animation
as.animator.setDuration( icon.getAnimationDuration() );
as.animator.setResolution( icon.getAnimationResolution() );
as.animator.setInterpolator( icon.getAnimationInterpolator() );
as.animatedValue = as.startValue;
}
as.targetValue = value;
as.animator.start();
}
as.x = x;
as.y = y;
}
paintIconImpl( icon, c, g, x, y, as );
}
private static void paintIconImpl( AnimatedIcon icon, Component c, Graphics g, int x, int y, AnimationSupport as ) {
float value = (as != null) ? as.animatedValue : icon.getValue( c );
icon.paintIconAnimated( c, g, x, y, value );
}
private static boolean isAnimationEnabled( AnimatedIcon icon, Component c ) {
return Animator.useAnimation() && icon.isAnimationEnabled() && c instanceof JComponent;
} }
/**
* @deprecated use {@link AnimatedPainter#saveRepaintLocation(AnimatedPainter, Component, int, int)} instead
*/
@Deprecated
public static void saveIconLocation( AnimatedIcon icon, Component c, int x, int y ) { public static void saveIconLocation( AnimatedIcon icon, Component c, int x, int y ) {
if( !isAnimationEnabled( icon, c ) ) AnimatedPainterSupport.saveRepaintLocation( icon, c, x, y );
return;
AnimationSupport as = (AnimationSupport) ((JComponent)c).getClientProperty( icon.getClientPropertyKey() );
if( as != null ) {
as.x = x;
as.y = y;
}
} }
} }
} }

View File

@@ -0,0 +1,181 @@
/*
* Copyright 2021 FormDev Software GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.formdev.flatlaf.util;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JComponent;
import com.formdev.flatlaf.util.Animator.Interpolator;
/**
* Painter that automatically animates painting on component value(s) changes.
* <p>
* {@link #getAnimatableValues(Component)} returns the animatable value(s) of the component.
* If the value(s) have changed, then {@link #paintAnimated(Component, Graphics2D, int, int, int, int, float[])}
* is invoked multiple times with animated value(s) (from old value(s) to new value(s)).
* If {@link #getAnimatableValues(Component)} returns multiple values, then each value
* gets its own independent animation, which may start/end at different points in time,
* may have different duration, resolution and interpolator.
* <p>
* See {@link AnimatedBorder} or {@link AnimatedIcon} for examples.
* <p>
* Animation works only if the component passed to {@link #paintWithAnimation(Component, Graphics, int, int, int, int)}
* is an instance of {@link JComponent}.
* A client property is set on the component to store the animation state.
*
* @author Karl Tauber
* @since 2
*/
public interface AnimatedPainter
{
/**
* Gets the animatable value(s) of the component.
* <p>
* This can be any value(s) and depends on the component.
* If the value(s) changes, then this class animates from the old value(s) to the new ones.
* If multiple values are returned, then each value gets its own independent animation.
* <p>
* For a toggle button this could be {@code 0} for off and {@code 1} for on.
* A complex check box could return values for selected, hover, pressed and focused states.
* The painter then can show independent animations for those states.
*/
float[] getAnimatableValues( Component c );
/**
* Starts painting.
* Either invokes {@link #paintAnimated(Component, Graphics2D, int, int, int, int, float[])}
* once to paint current value(s) (see {@link #getAnimatableValues(Component)}. Or if value(s) has
* changed, compared to last painting, then it starts an animation and invokes
* {@link #paintAnimated(Component, Graphics2D, int, int, int, int, float[])}
* multiple times with animated value(s) (from old value(s) to new value(s)).
*
* @param c the component that this painter belongs to
* @param g the graphics context
* @param x the x coordinate of the paint area
* @param y the y coordinate of the paint area
* @param width the width of the paint area
* @param height the height of the paint area
*/
default void paintWithAnimation( Component c, Graphics g, int x, int y, int width, int height ) {
AnimatedPainterSupport.paint( this, c, (Graphics2D) g, x, y, width, height );
}
/**
* Paints the given (animated) value(s).
* <p>
* Invoked from {@link #paintWithAnimation(Component, Graphics, int, int, int, int)}.
*
* @param c the component that this painter belongs to
* @param g the graphics context
* @param x the x coordinate of the paint area
* @param y the y coordinate of the paint area
* @param width the width of the paint area
* @param height the height of the paint area
* @param animatedValues the animated values, which are either equal to what {@link #getAnimatableValues(Component)}
* returned, or somewhere between the previous values and the latest values
* that {@link #getAnimatableValues(Component)} returned
*/
void paintAnimated( Component c, Graphics2D g, int x, int y, int width, int height, float[] animatedValues );
/**
* Invoked from animator to repaint an area.
* <p>
* Useful to limit the repaint region. E.g. if only the bottom border is animated.
* If more than one border side is animated (e.g. bottom and right side), then it
* makes no sense to do separate repaints because the Swing repaint manager unions
* the regions and the whole component is repainted.
* <p>
* The default implementation repaints the whole given area.
*/
default void repaintDuringAnimation( Component c, int x, int y, int width, int height ) {
c.repaint( x, y, width, height );
}
/**
* Returns whether animation is enabled for this painter (default is {@code true}).
*/
default boolean isAnimationEnabled() {
return true;
}
/**
* Returns the duration of the animation in milliseconds (default is 150).
*/
default int getAnimationDuration() {
return 150;
}
/**
* Returns the resolution of the animation in milliseconds (default is 10).
* Resolution is the amount of time between timing events.
*/
default int getAnimationResolution() {
return 10;
}
/**
* Returns the interpolator for the animation.
* Default is {@link CubicBezierEasing#STANDARD_EASING}.
*/
default Interpolator getAnimationInterpolator() {
return CubicBezierEasing.STANDARD_EASING;
}
/**
* Returns the duration of the animation in milliseconds (default is 150)
* for the given value index and value.
*/
default int getAnimationDuration( int valueIndex, float value ) {
return getAnimationDuration();
}
/**
* Returns the resolution of the animation in milliseconds (default is 10)
* for the given value index and value.
* Resolution is the amount of time between timing events.
*/
default int getAnimationResolution( int valueIndex, float value ) {
return getAnimationResolution();
}
/**
* Returns the interpolator for the animation
* for the given value index and value.
* Default is {@link CubicBezierEasing#STANDARD_EASING}.
*/
default Interpolator getAnimationInterpolator( int valueIndex, float value ) {
return getAnimationInterpolator();
}
/**
* Returns the client property key used to store the animation support.
*/
default Object getAnimationClientPropertyKey() {
return getClass();
}
/**
* Saves location for repainting animated area with
* {@link AnimatedPainter#repaintDuringAnimation(Component, int, int, int, int)}.
* Only needed when graphics context passed to {@link #paintWithAnimation(Component, Graphics, int, int, int, int)}
* uses transformed location.
*/
static void saveRepaintLocation( AnimatedPainter painter, Component c, int x, int y ) {
AnimatedPainterSupport.saveRepaintLocation( painter, c, x, y );
}
}

View File

@@ -0,0 +1,185 @@
/*
* Copyright 2021 FormDev Software GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.formdev.flatlaf.util;
import java.awt.Component;
import java.awt.Graphics2D;
import javax.swing.JComponent;
/**
* Animation support class that stores the animation state and implements the animation.
*
* @author Karl Tauber
* @since 2
*/
class AnimatedPainterSupport
{
private final int valueIndex;
private float startValue;
private float targetValue;
private float animatedValue;
private float fraction;
private Animator animator;
// last bounds of the paint area needed to repaint while animating
private int x;
private int y;
private int width;
private int height;
private AnimatedPainterSupport( int valueIndex ) {
this.valueIndex = valueIndex;
}
static void paint( AnimatedPainter painter, Component c, Graphics2D g,
int x, int y, int width, int height )
{
// get animatable component values
float[] values = painter.getAnimatableValues( c );
if( !isAnimationEnabled( painter, c ) ) {
// paint without animation if animation is disabled or
// component is not a JComponent and therefore does not support
// client properties, which are required to keep animation state
painter.paintAnimated( c, g, x, y, width, height, values );
return;
}
JComponent jc = (JComponent) c;
Object key = painter.getAnimationClientPropertyKey();
AnimatedPainterSupport[] ass = (AnimatedPainterSupport[]) jc.getClientProperty( key );
// check whether length of values array has changed
if( ass != null && ass.length != values.length ) {
// cancel all running animations
for( int i = 0; i < ass.length; i++ ) {
AnimatedPainterSupport as = ass[i];
if( as.animator != null )
as.animator.cancel();
}
ass = null;
}
if( ass == null ) {
ass = new AnimatedPainterSupport[values.length];
jc.putClientProperty( key, ass );
}
for( int i = 0; i < ass.length; i++ ) {
AnimatedPainterSupport as = ass[i];
float value = values[i];
if( as == null ) {
// painted first time --> do not animate, but remember current component value
as = new AnimatedPainterSupport( i );
as.startValue = as.targetValue = as.animatedValue = value;
ass[i] = as;
} else if( value != as.targetValue ) {
// value changed --> (re)start animation
int animationDuration = painter.getAnimationDuration( as.valueIndex, value );
// do not animate if animation duration (for current value) is zero
if( animationDuration <= 0 ) {
if( as.animator != null ) {
as.animator.cancel();
as.animator = null;
}
as.startValue = as.targetValue = as.animatedValue = value;
as.fraction = 0;
continue;
}
if( as.animator == null ) {
// create animator
AnimatedPainterSupport as2 = as;
as.animator = new Animator( 1, fraction -> {
// check whether component was removed while animation is running
if( !c.isDisplayable() ) {
as2.animator.stop();
return;
}
// compute animated value
as2.animatedValue = as2.startValue + ((as2.targetValue - as2.startValue) * fraction);
as2.fraction = fraction;
// repaint
painter.repaintDuringAnimation( c, as2.x, as2.y, as2.width, as2.height );
}, () -> {
as2.startValue = as2.animatedValue = as2.targetValue;
as2.animator = null;
} );
}
if( as.animator.isRunning() ) {
// if animation is still running, restart it from the current
// animated value to the new target value with reduced duration
as.animator.cancel();
int duration2 = (int) (animationDuration * as.fraction);
if( duration2 > 0 )
as.animator.setDuration( duration2 );
as.startValue = as.animatedValue;
} else {
// new animation
as.animator.setDuration( animationDuration );
as.animatedValue = as.startValue;
}
// update animator for new value
as.animator.setResolution( painter.getAnimationResolution( as.valueIndex, value ) );
as.animator.setInterpolator( painter.getAnimationInterpolator( as.valueIndex, value ) );
// start animation
as.targetValue = value;
as.animator.start();
}
as.x = x;
as.y = y;
as.width = width;
as.height = height;
}
float[] animatedValues = new float[ass.length];
for( int i = 0; i < ass.length; i++ )
animatedValues[i] = ass[i].animatedValue;
painter.paintAnimated( c, g, x, y, width, height, animatedValues );
}
private static boolean isAnimationEnabled( AnimatedPainter painter, Component c ) {
return Animator.useAnimation() && painter.isAnimationEnabled() && c instanceof JComponent;
}
static void saveRepaintLocation( AnimatedPainter painter, Component c, int x, int y ) {
if( !isAnimationEnabled( painter, c ) )
return;
AnimatedPainterSupport[] ass = (AnimatedPainterSupport[]) ((JComponent)c).getClientProperty( painter.getAnimationClientPropertyKey() );
if( ass != null ) {
for( int i = 0; i < ass.length; i++ ) {
AnimatedPainterSupport as = ass[i];
as.x = x;
as.y = y;
}
}
}
}

View File

@@ -122,8 +122,6 @@ public class ColorFunctions
return color1; return color1;
if( weight <= 0 ) if( weight <= 0 )
return color2; return color2;
if( color1.equals( color2 ) )
return color1;
int r1 = color1.getRed(); int r1 = color1.getRed();
int g1 = color1.getGreen(); int g1 = color1.getGreen();
@@ -198,9 +196,6 @@ public class ColorFunctions
: (float) Math.pow( (value + 0.055) / 1.055, 2.4 ); : (float) Math.pow( (value + 0.055) / 1.055, 2.4 );
} }
/**
* Applies the given color functions to the given color and returns the new color.
*/
public static Color applyFunctions( Color color, ColorFunction... functions ) { public static Color applyFunctions( Color color, ColorFunction... functions ) {
// if having only a single function of type Mix, then avoid four unnecessary conversions: // if having only a single function of type Mix, then avoid four unnecessary conversions:
// 1. RGB to HSL in this method // 1. RGB to HSL in this method
@@ -226,9 +221,6 @@ public class ColorFunctions
return HSLColor.toRGB( hsla[0], hsla[1], hsla[2], hsla[3] / 100 ); return HSLColor.toRGB( hsla[0], hsla[1], hsla[2], hsla[3] / 100 );
} }
/**
* Clamps the given value between 0 and 100.
*/
public static float clamp( float value ) { public static float clamp( float value ) {
return (value < 0) return (value < 0)
? 0 ? 0

View File

@@ -60,19 +60,6 @@ public class NativeLibrary
: false; : false;
} }
/**
* Load native library from given file.
*
* @param libraryFile the file of the native library
* @param supported whether the native library is supported on the current platform
* @since 2
*/
public NativeLibrary( File libraryFile, boolean supported ) {
this.loaded = supported
? loadLibraryFromFile( libraryFile )
: false;
}
/** /**
* Returns whether the native library is loaded. * Returns whether the native library is loaded.
* <p> * <p>
@@ -133,16 +120,6 @@ public class NativeLibrary
} }
} }
private boolean loadLibraryFromFile( File libraryFile ) {
try {
System.load( libraryFile.getAbsolutePath() );
return true;
} catch( Throwable ex ) {
log( null, ex );
return false;
}
}
private static String decorateLibraryName( String libraryName ) { private static String decorateLibraryName( String libraryName ) {
if( SystemInfo.isWindows ) if( SystemInfo.isWindows )
return libraryName.concat( ".dll" ); return libraryName.concat( ".dll" );

View File

@@ -1,50 +0,0 @@
/*
* Copyright 2022 FormDev Software GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.formdev.flatlaf.util;
import java.awt.Component;
import java.awt.Container;
/**
* Utility methods for Swing.
*
* @author Karl Tauber
* @since 2
*/
public class SwingUtils
{
/**
* Search for a (grand) child component with the given name.
*
* @return a component; or {@code null}
*/
@SuppressWarnings( "unchecked" )
public static <T extends Component> T getComponentByName( Container parent, String name ) {
for( Component child : parent.getComponents() ) {
if( name.equals( child.getName() ) )
return (T) child;
if( child instanceof Container ) {
T c = getComponentByName( (Container) child, name );
if( c != null )
return c;
}
}
return null;
}
}

View File

@@ -34,17 +34,12 @@ public class SystemInfo
// OS versions // OS versions
public static final long osVersion; public static final long osVersion;
public static final boolean isWindows_10_orLater; public static final boolean isWindows_10_orLater;
/** <strong>Note</strong>: This requires Java 8u321, 11.0.14, 17.0.2 or 18 (or later).
* (see https://bugs.openjdk.java.net/browse/JDK-8274840)
* @since 2 */ public static final boolean isWindows_11_orLater;
public static final boolean isMacOS_10_11_ElCapitan_orLater; public static final boolean isMacOS_10_11_ElCapitan_orLater;
public static final boolean isMacOS_10_14_Mojave_orLater; public static final boolean isMacOS_10_14_Mojave_orLater;
public static final boolean isMacOS_10_15_Catalina_orLater; public static final boolean isMacOS_10_15_Catalina_orLater;
// OS architecture // OS architecture
/** @since 2 */ public static final boolean isX86;
/** @since 1.1 */ public static final boolean isX86_64; /** @since 1.1 */ public static final boolean isX86_64;
/** @since 2 */ public static final boolean isAARCH64;
// Java versions // Java versions
public static final long javaVersion; public static final long javaVersion;
@@ -52,7 +47,6 @@ public class SystemInfo
public static final boolean isJava_11_orLater; public static final boolean isJava_11_orLater;
public static final boolean isJava_15_orLater; public static final boolean isJava_15_orLater;
/** @since 2 */ public static final boolean isJava_17_orLater; /** @since 2 */ public static final boolean isJava_17_orLater;
/** @since 2 */ public static final boolean isJava_18_orLater;
// Java VMs // Java VMs
public static final boolean isJetBrainsJVM; public static final boolean isJetBrainsJVM;
@@ -76,17 +70,13 @@ public class SystemInfo
// OS versions // OS versions
osVersion = scanVersion( System.getProperty( "os.version" ) ); osVersion = scanVersion( System.getProperty( "os.version" ) );
isWindows_10_orLater = (isWindows && osVersion >= toVersion( 10, 0, 0, 0 )); isWindows_10_orLater = (isWindows && osVersion >= toVersion( 10, 0, 0, 0 ));
isWindows_11_orLater = (isWindows_10_orLater && osName.length() > "windows ".length() &&
scanVersion( osName.substring( "windows ".length() ) ) >= toVersion( 11, 0, 0, 0 ));
isMacOS_10_11_ElCapitan_orLater = (isMacOS && osVersion >= toVersion( 10, 11, 0, 0 )); isMacOS_10_11_ElCapitan_orLater = (isMacOS && osVersion >= toVersion( 10, 11, 0, 0 ));
isMacOS_10_14_Mojave_orLater = (isMacOS && osVersion >= toVersion( 10, 14, 0, 0 )); isMacOS_10_14_Mojave_orLater = (isMacOS && osVersion >= toVersion( 10, 14, 0, 0 ));
isMacOS_10_15_Catalina_orLater = (isMacOS && osVersion >= toVersion( 10, 15, 0, 0 )); isMacOS_10_15_Catalina_orLater = (isMacOS && osVersion >= toVersion( 10, 15, 0, 0 ));
// OS architecture // OS architecture
String osArch = System.getProperty( "os.arch" ); String osArch = System.getProperty( "os.arch" );
isX86 = osArch.equals( "x86" );
isX86_64 = osArch.equals( "amd64" ) || osArch.equals( "x86_64" ); isX86_64 = osArch.equals( "amd64" ) || osArch.equals( "x86_64" );
isAARCH64 = osArch.equals( "aarch64" );
// Java versions // Java versions
javaVersion = scanVersion( System.getProperty( "java.version" ) ); javaVersion = scanVersion( System.getProperty( "java.version" ) );
@@ -94,7 +84,6 @@ public class SystemInfo
isJava_11_orLater = (javaVersion >= toVersion( 11, 0, 0, 0 )); isJava_11_orLater = (javaVersion >= toVersion( 11, 0, 0, 0 ));
isJava_15_orLater = (javaVersion >= toVersion( 15, 0, 0, 0 )); isJava_15_orLater = (javaVersion >= toVersion( 15, 0, 0, 0 ));
isJava_17_orLater = (javaVersion >= toVersion( 17, 0, 0, 0 )); isJava_17_orLater = (javaVersion >= toVersion( 17, 0, 0, 0 ));
isJava_18_orLater = (javaVersion >= toVersion( 18, 0, 0, 0 ));
// Java VMs // Java VMs
isJetBrainsJVM = System.getProperty( "java.vm.vendor", "Unknown" ) isJetBrainsJVM = System.getProperty( "java.vm.vendor", "Unknown" )

View File

@@ -289,7 +289,7 @@ Slider.trackValueColor = @accentSliderColor
Slider.trackColor = lighten(@background,15%) Slider.trackColor = lighten(@background,15%)
Slider.thumbColor = $Slider.trackValueColor Slider.thumbColor = $Slider.trackValueColor
Slider.tickColor = @disabledForeground Slider.tickColor = @disabledForeground
Slider.focusedColor = fade(changeLightness($Component.focusColor,60%,derived),30%,derived) Slider.focusedColor = fade($Component.focusColor,70%,derived)
Slider.hoverThumbColor = lighten($Slider.thumbColor,5%,derived) Slider.hoverThumbColor = lighten($Slider.thumbColor,5%,derived)
Slider.pressedThumbColor = lighten($Slider.thumbColor,8%,derived) Slider.pressedThumbColor = lighten($Slider.thumbColor,8%,derived)
Slider.disabledTrackColor = lighten(@background,10%) Slider.disabledTrackColor = lighten(@background,10%)
@@ -334,8 +334,8 @@ TableHeader.bottomSeparatorColor = $TableHeader.separatorColor
#---- TitlePane ---- #---- TitlePane ----
TitlePane.embeddedForeground = darken($TitlePane.foreground,15%) TitlePane.embeddedForeground = darken($TitlePane.foreground,15%)
TitlePane.buttonHoverBackground = lighten($TitlePane.background,15%,derived) TitlePane.buttonHoverBackground = lighten($TitlePane.background,10%,derived)
TitlePane.buttonPressedBackground = lighten($TitlePane.background,10%,derived) TitlePane.buttonPressedBackground = lighten($TitlePane.background,20%,derived)
#---- ToggleButton ---- #---- ToggleButton ----
@@ -355,18 +355,3 @@ ToolTip.background = shade(@background,50%)
#---- Tree ---- #---- Tree ----
Tree.hash = lighten($Tree.background,5%) Tree.hash = lighten($Tree.background,5%)
#---- Styles ------------------------------------------------------------------
#---- inTextField ----
# for leading/trailing components in text fields
[style]Button.inTextField = \
focusable: false; \
toolbar.margin: 1,1,1,1; \
toolbar.spacingInsets: 1,1,1,1; \
toolbar.hoverBackground: fade(Actions.GreyInline,30%,lazy); \
toolbar.pressedBackground: fade(Actions.GreyInline,40%,lazy); \
toolbar.selectedBackground: fade(Actions.GreyInline,50%,lazy)

View File

@@ -58,7 +58,7 @@ mini.font = -3
[mac]semibold.font = "HelveticaNeue-Medium" [mac]semibold.font = "HelveticaNeue-Medium"
# Linux # Linux
[linux]light.font = "Lato Light", "Ubuntu Light", "Cantarell Light" [linux]light.font = "Lato Light", "Ubuntu Light", "Cantarell Light"
[linux]semibold.font = "Lato Semibold", "Ubuntu Medium", "Montserrat SemiBold" [linux]semibold.font = "Lato Semibold", "Ubuntu Medium"
# fallback for unknown platform # fallback for unknown platform
light.font = +0 light.font = +0
semibold.font = +0 semibold.font = +0
@@ -227,7 +227,6 @@ Button.defaultButtonFollowsFocus = false
Button.borderWidth = 1 Button.borderWidth = 1
Button.default.borderWidth = 1 Button.default.borderWidth = 1
# for buttons in toolbars
Button.toolbar.margin = 3,3,3,3 Button.toolbar.margin = 3,3,3,3
Button.toolbar.spacingInsets = 1,2,1,2 Button.toolbar.spacingInsets = 1,2,1,2
@@ -431,7 +430,6 @@ MenuItem.checkIcon = null
MenuItem.margin = @menuItemMargin MenuItem.margin = @menuItemMargin
MenuItem.opaque = false MenuItem.opaque = false
MenuItem.borderPainted = true MenuItem.borderPainted = true
MenuItem.verticallyAlignText = true
MenuItem.background = @menuBackground MenuItem.background = @menuBackground
MenuItem.checkBackground = @menuCheckBackground MenuItem.checkBackground = @menuCheckBackground
MenuItem.checkMargins = 2,2,2,2 MenuItem.checkMargins = 2,2,2,2
@@ -441,7 +439,7 @@ MenuItem.iconTextGap = 6
MenuItem.textAcceleratorGap = 24 MenuItem.textAcceleratorGap = 24
MenuItem.textNoAcceleratorGap = 6 MenuItem.textNoAcceleratorGap = 6
MenuItem.acceleratorArrowGap = 2 MenuItem.acceleratorArrowGap = 2
MenuItem.acceleratorDelimiter = + MenuItem.acceleratorDelimiter = -
[mac]MenuItem.acceleratorDelimiter = [mac]MenuItem.acceleratorDelimiter =
# for MenuItem.selectionType = underline # for MenuItem.selectionType = underline
@@ -484,10 +482,7 @@ PasswordField.placeholderForeground = @disabledForeground
PasswordField.iconTextGap = 4 PasswordField.iconTextGap = 4
PasswordField.echoChar = \u2022 PasswordField.echoChar = \u2022
PasswordField.showCapsLock = true PasswordField.showCapsLock = true
PasswordField.showRevealButton = false
PasswordField.capsLockIcon = com.formdev.flatlaf.icons.FlatCapsLockIcon PasswordField.capsLockIcon = com.formdev.flatlaf.icons.FlatCapsLockIcon
PasswordField.revealIcon = com.formdev.flatlaf.icons.FlatRevealIcon
PasswordField.revealIconColor = lazy(Actions.Grey)
#---- Popup ---- #---- Popup ----
@@ -589,13 +584,13 @@ ScrollPane.smoothScrolling = true
#---- SearchField ---- #---- SearchField ----
SearchField.searchIconColor = fade(Actions.GreyInline,90%,lazy) SearchField.searchIconColor = fadeout(Actions.GreyInline,10%,lazy)
SearchField.searchIconHoverColor = fade(Actions.GreyInline,70%,lazy) SearchField.searchIconHoverColor = fadeout(Actions.GreyInline,30%,lazy)
SearchField.searchIconPressedColor = fade(Actions.GreyInline,50%,lazy) SearchField.searchIconPressedColor = fadeout(Actions.GreyInline,50%,lazy)
SearchField.clearIconColor = fade(Actions.GreyInline,50%,lazy) SearchField.clearIconColor = fadeout(Actions.GreyInline,50%,lazy)
SearchField.clearIconHoverColor = $SearchField.clearIconColor SearchField.clearIconHoverColor = $SearchField.clearIconColor
SearchField.clearIconPressedColor = fade(Actions.GreyInline,80%,lazy) SearchField.clearIconPressedColor = fadeout(Actions.GreyInline,20%,lazy)
#---- Separator ---- #---- Separator ----
@@ -802,8 +797,8 @@ TitlePane.inactiveBackground = $TitlePane.background
TitlePane.foreground = @foreground TitlePane.foreground = @foreground
TitlePane.inactiveForeground = @disabledForeground TitlePane.inactiveForeground = @disabledForeground
TitlePane.closeHoverBackground = #c42b1c TitlePane.closeHoverBackground = #e81123
TitlePane.closePressedBackground = fade($TitlePane.closeHoverBackground,90%) TitlePane.closePressedBackground = fade($TitlePane.closeHoverBackground,60%)
TitlePane.closeHoverForeground = #fff TitlePane.closeHoverForeground = #fff
TitlePane.closePressedForeground = #fff TitlePane.closePressedForeground = #fff
@@ -893,32 +888,3 @@ Tree.icon.collapsedColor = @icon
Tree.icon.leafColor = @icon Tree.icon.leafColor = @icon
Tree.icon.closedColor = @icon Tree.icon.closedColor = @icon
Tree.icon.openColor = @icon Tree.icon.openColor = @icon
#---- Styles ------------------------------------------------------------------
#---- inTextField ----
# for leading/trailing components in text fields
[style]ToggleButton.inTextField = $[style]Button.inTextField
[style]ToolBar.inTextField = \
floatable: false; \
opaque: false; \
borderMargins: 0,0,0,0
[style]ToolBarSeparator.inTextField = \
separatorWidth: 3
#---- clearButton ----
# for clear/cancel button in text fields
[style]Button.clearButton = \
icon: com.formdev.flatlaf.icons.FlatClearIcon; \
focusable: false; \
toolbar.margin: 1,1,1,1; \
toolbar.spacingInsets: 1,1,1,1; \
toolbar.hoverBackground: null; \
toolbar.pressedBackground: null

View File

@@ -296,7 +296,7 @@ Slider.trackValueColor = @accentSliderColor
Slider.trackColor = darken(@background,18%) Slider.trackColor = darken(@background,18%)
Slider.thumbColor = $Slider.trackValueColor Slider.thumbColor = $Slider.trackValueColor
Slider.tickColor = @disabledForeground Slider.tickColor = @disabledForeground
Slider.focusedColor = fade(changeLightness($Component.focusColor,75%,derived),50%,derived) Slider.focusedColor = fade($Component.focusColor,50%,derived)
Slider.hoverThumbColor = darken($Slider.thumbColor,5%,derived) Slider.hoverThumbColor = darken($Slider.thumbColor,5%,derived)
Slider.pressedThumbColor = darken($Slider.thumbColor,8%,derived) Slider.pressedThumbColor = darken($Slider.thumbColor,8%,derived)
Slider.disabledTrackColor = darken(@background,13%) Slider.disabledTrackColor = darken(@background,13%)
@@ -342,7 +342,7 @@ TableHeader.bottomSeparatorColor = $TableHeader.separatorColor
TitlePane.embeddedForeground = lighten($TitlePane.foreground,35%) TitlePane.embeddedForeground = lighten($TitlePane.foreground,35%)
TitlePane.buttonHoverBackground = darken($TitlePane.background,10%,derived) TitlePane.buttonHoverBackground = darken($TitlePane.background,10%,derived)
TitlePane.buttonPressedBackground = darken($TitlePane.background,8%,derived) TitlePane.buttonPressedBackground = darken($TitlePane.background,20%,derived)
#---- ToggleButton ---- #---- ToggleButton ----
@@ -362,18 +362,3 @@ ToolTip.background = lighten(@background,3%)
#---- Tree ---- #---- Tree ----
Tree.hash = darken($Tree.background,10%) Tree.hash = darken($Tree.background,10%)
#---- Styles ------------------------------------------------------------------
#---- inTextField ----
# for leading/trailing components in text fields
[style]Button.inTextField = \
focusable: false; \
toolbar.margin: 1,1,1,1; \
toolbar.spacingInsets: 1,1,1,1; \
toolbar.hoverBackground: fade(Actions.GreyInline,10%,lazy); \
toolbar.pressedBackground: fade(Actions.GreyInline,20%,lazy); \
toolbar.selectedBackground: fade(Actions.GreyInline,30%,lazy)

View File

@@ -150,7 +150,6 @@ ToggleButton.endBackground = $ToggleButton.background
[Gruvbox_Dark_Soft]ToggleButton.selectedBackground = $ToggleButton.selectedBackground [Gruvbox_Dark_Soft]ToggleButton.selectedBackground = $ToggleButton.selectedBackground
[Gruvbox_Dark_Soft]ToggleButton.toolbar.selectedBackground = $ToggleButton.toolbar.selectedBackground [Gruvbox_Dark_Soft]ToggleButton.toolbar.selectedBackground = $ToggleButton.toolbar.selectedBackground
[Hiberbee_Dark]TabbedPane.focusColor = #5A5A5A
[Hiberbee_Dark]ToggleButton.selectedBackground = $ToggleButton.selectedBackground [Hiberbee_Dark]ToggleButton.selectedBackground = $ToggleButton.selectedBackground
[Hiberbee_Dark]ToggleButton.selectedBackground = $ToggleButton.selectedBackground [Hiberbee_Dark]ToggleButton.selectedBackground = $ToggleButton.selectedBackground
[Hiberbee_Dark]ToggleButton.toolbar.selectedBackground = $ToggleButton.toolbar.selectedBackground [Hiberbee_Dark]ToggleButton.toolbar.selectedBackground = $ToggleButton.toolbar.selectedBackground
@@ -211,17 +210,11 @@ ToggleButton.endBackground = $ToggleButton.background
[GitHub_Contrast]ProgressBar.selectionBackground = #222 [GitHub_Contrast]ProgressBar.selectionBackground = #222
[GitHub_Contrast]ProgressBar.selectionForeground = #222 [GitHub_Contrast]ProgressBar.selectionForeground = #222
[Light_Owl]List.selectionInactiveForeground = lazy(List.foreground)
[Light_Owl]ProgressBar.selectionBackground = #111 [Light_Owl]ProgressBar.selectionBackground = #111
[Light_Owl]ProgressBar.selectionForeground = #fff [Light_Owl]ProgressBar.selectionForeground = #fff
[Light_Owl]TabbedPane.selectedForeground = lazy(TabbedPane.foreground)
[Light_Owl]Table.selectionForeground = lazy(Table.foreground)
[Light_Owl_Contrast]List.selectionInactiveForeground = lazy(List.foreground)
[Light_Owl_Contrast]ProgressBar.selectionBackground = #111 [Light_Owl_Contrast]ProgressBar.selectionBackground = #111
[Light_Owl_Contrast]ProgressBar.selectionForeground = #fff [Light_Owl_Contrast]ProgressBar.selectionForeground = #fff
[Light_Owl_Contrast]TabbedPane.selectedForeground = lazy(TabbedPane.foreground)
[Light_Owl_Contrast]Table.selectionForeground = lazy(Table.foreground)
[Material_Lighter]ProgressBar.selectionBackground = #222 [Material_Lighter]ProgressBar.selectionBackground = #222
[Material_Lighter]ProgressBar.selectionForeground = #fff [Material_Lighter]ProgressBar.selectionForeground = #fff

View File

@@ -22,12 +22,8 @@ import java.awt.Dimension;
import java.awt.Font; import java.awt.Font;
import java.awt.Insets; import java.awt.Insets;
import javax.swing.UIManager; import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.UIDefaults.ActiveValue; import javax.swing.UIDefaults.ActiveValue;
import javax.swing.UIDefaults.LazyValue;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import com.formdev.flatlaf.ui.FlatEmptyBorder;
import com.formdev.flatlaf.ui.FlatLineBorder;
/** /**
* @author Karl Tauber * @author Karl Tauber
@@ -50,8 +46,8 @@ public class TestUIDefaultsLoader
assertEquals( 1.23f, UIDefaultsLoader.parseValue( "dummy", "1.23", null ) ); assertEquals( 1.23f, UIDefaultsLoader.parseValue( "dummy", "1.23", null ) );
assertEquals( 1.23f, UIDefaultsLoader.parseValue( "dummyWidth", "1.23", null ) ); assertEquals( 1.23f, UIDefaultsLoader.parseValue( "dummyWidth", "1.23", null ) );
assertEquals( new Insets( 1,2,3,4 ), UIDefaultsLoader.parseValue( "dummyInsets", "1,2,3,4", null ) ); assertEquals( new Insets( 2,2,2,2 ), UIDefaultsLoader.parseValue( "dummyInsets", "2,2,2,2", null ) );
assertEquals( new Dimension( 1,2 ), UIDefaultsLoader.parseValue( "dummySize", "1,2", null ) ); assertEquals( new Dimension( 2,2 ), UIDefaultsLoader.parseValue( "dummySize", "2,2", null ) );
assertEquals( new Color( 0xff0000 ), UIDefaultsLoader.parseValue( "dummy", "#f00", null ) ); assertEquals( new Color( 0xff0000 ), UIDefaultsLoader.parseValue( "dummy", "#f00", null ) );
assertEquals( new Color( 0xff0000 ), UIDefaultsLoader.parseValue( "dummyColor", "#f00", null ) ); assertEquals( new Color( 0xff0000 ), UIDefaultsLoader.parseValue( "dummyColor", "#f00", null ) );
} }
@@ -74,35 +70,11 @@ public class TestUIDefaultsLoader
assertEquals( 1.23f, UIDefaultsLoader.parseValue( "dummy", "1.23", float.class ) ); assertEquals( 1.23f, UIDefaultsLoader.parseValue( "dummy", "1.23", float.class ) );
assertEquals( 1.23f, UIDefaultsLoader.parseValue( "dummy", "1.23", Float.class ) ); assertEquals( 1.23f, UIDefaultsLoader.parseValue( "dummy", "1.23", Float.class ) );
assertEquals( new Insets( 1,2,3,4 ), UIDefaultsLoader.parseValue( "dummy", "1,2,3,4", Insets.class ) ); assertEquals( new Insets( 2,2,2,2 ), UIDefaultsLoader.parseValue( "dummy", "2,2,2,2", Insets.class ) );
assertEquals( new Dimension( 1,2 ), UIDefaultsLoader.parseValue( "dummy", "1,2", Dimension.class ) ); assertEquals( new Dimension( 2,2 ), UIDefaultsLoader.parseValue( "dummy", "2,2", Dimension.class ) );
assertEquals( new Color( 0xff0000 ), UIDefaultsLoader.parseValue( "dummy", "#f00", Color.class ) ); assertEquals( new Color( 0xff0000 ), UIDefaultsLoader.parseValue( "dummy", "#f00", Color.class ) );
} }
@Test
void parseBorders() {
Insets insets = new Insets( 1,2,3,4 );
assertBorderEquals( new FlatEmptyBorder( insets ), "1,2,3,4" );
assertBorderEquals( new FlatLineBorder( insets, Color.red ), "1,2,3,4,#f00" );
assertBorderEquals( new FlatLineBorder( insets, Color.red, 2.5f, 0 ), "1,2,3,4,#f00,2.5" );
assertBorderEquals( new FlatLineBorder( insets, Color.red, 2.5f, 6 ), "1,2,3,4,#f00,2.5,6" );
assertBorderEquals( new FlatLineBorder( insets, Color.red, 1, 6 ), "1,2,3,4,#f00,,6" );
}
private void assertBorderEquals( Border expected, String actualStyle ) {
Border actual = (Border) ((LazyValue)UIDefaultsLoader.parseValue( "dummyBorder", actualStyle, null )).createValue( null );
assertEquals( expected.getClass(), actual.getClass() );
if( expected instanceof FlatEmptyBorder )
assertEquals( ((FlatEmptyBorder)actual).getBorderInsets(), ((FlatEmptyBorder)expected).getBorderInsets() );
if( expected instanceof FlatLineBorder ) {
FlatLineBorder a = (FlatLineBorder) actual;
FlatLineBorder e = (FlatLineBorder) expected;
assertEquals( a.getLineColor(), e.getLineColor() );
assertEquals( a.getLineThickness(), e.getLineThickness() );
assertEquals( a.getArc(), e.getArc() );
}
}
@Test @Test
void parseFonts() { void parseFonts() {
// style // style

View File

@@ -40,7 +40,7 @@ public class TestFlatStyleClasses
@BeforeAll @BeforeAll
static void setup() { static void setup() {
System.setProperty( FlatSystemProperties.UI_SCALE, "1x" ); System.setProperty( FlatSystemProperties.UI_SCALE_ENABLED, "false" );
TestUtils.setup( false ); TestUtils.setup( false );
UIManager.put( "[style]Button.primary", BUTTON_PRIMARY ); UIManager.put( "[style]Button.primary", BUTTON_PRIMARY );
@@ -61,7 +61,6 @@ public class TestFlatStyleClasses
UIManager.put( "[style]MenuItem.test", "foreground: #000011" ); UIManager.put( "[style]MenuItem.test", "foreground: #000011" );
UIManager.put( "[style]CheckBoxMenuItem.test", "foreground: #000012" ); UIManager.put( "[style]CheckBoxMenuItem.test", "foreground: #000012" );
UIManager.put( "[style]RadioButtonMenuItem.test", "foreground: #000013" ); UIManager.put( "[style]RadioButtonMenuItem.test", "foreground: #000013" );
UIManager.put( "[style]Panel.test", "foreground: #000034" );
UIManager.put( "[style]PasswordField.test", "foreground: #000014" ); UIManager.put( "[style]PasswordField.test", "foreground: #000014" );
UIManager.put( "[style]PopupMenu.test", "foreground: #000015" ); UIManager.put( "[style]PopupMenu.test", "foreground: #000015" );
UIManager.put( "[style]PopupMenuSeparator.test", "foreground: #000016" ); UIManager.put( "[style]PopupMenuSeparator.test", "foreground: #000016" );
@@ -100,7 +99,7 @@ public class TestFlatStyleClasses
@AfterAll @AfterAll
static void cleanup() { static void cleanup() {
TestUtils.cleanup(); TestUtils.cleanup();
System.clearProperty( FlatSystemProperties.UI_SCALE ); System.clearProperty( FlatSystemProperties.UI_SCALE_ENABLED );
} }
@Test @Test
@@ -279,14 +278,6 @@ public class TestFlatStyleClasses
assertEquals( new Color( 0x000013 ), c.getForeground() ); assertEquals( new Color( 0x000013 ), c.getForeground() );
} }
@Test
void panel() {
JPanel c = new JPanel();
c.putClientProperty( FlatClientProperties.STYLE_CLASS, "test" );
assertEquals( Color.magenta, c.getBackground() );
assertEquals( new Color( 0x000034 ), c.getForeground() );
}
@Test @Test
void passwordField() { void passwordField() {
JPasswordField c = new JPasswordField(); JPasswordField c = new JPasswordField();

View File

@@ -20,7 +20,6 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
import static com.formdev.flatlaf.ui.TestUtils.assertMapEquals; import static com.formdev.flatlaf.ui.TestUtils.assertMapEquals;
import java.awt.Color; import java.awt.Color;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.Font;
import java.awt.Insets; import java.awt.Insets;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.Map; import java.util.Map;
@@ -258,7 +257,7 @@ public class TestFlatStyleableInfo
// FlatListCellBorder // FlatListCellBorder
"cellMargins", Insets.class, "cellMargins", Insets.class,
"cellFocusColor", Color.class, "cellFocusColor", Color.class,
"showCellFocusIndicator", Boolean.class "showCellFocusIndicator", boolean.class
); );
assertMapEquals( expected, ui.getStyleableInfos( c ) ); assertMapEquals( expected, ui.getStyleableInfos( c ) );
@@ -302,6 +301,7 @@ public class TestFlatStyleableInfo
Map<String, Class<?>> expected = new LinkedHashMap<>(); Map<String, Class<?>> expected = new LinkedHashMap<>();
menuItem( expected ); menuItem( expected );
menuItem_arrowIcon( expected );
assertMapEquals( expected, ui.getStyleableInfos( c ) ); assertMapEquals( expected, ui.getStyleableInfos( c ) );
} }
@@ -314,6 +314,7 @@ public class TestFlatStyleableInfo
Map<String, Class<?>> expected = new LinkedHashMap<>(); Map<String, Class<?>> expected = new LinkedHashMap<>();
menuItem( expected ); menuItem( expected );
menuItem_checkIcon( expected ); menuItem_checkIcon( expected );
menuItem_arrowIcon( expected );
assertMapEquals( expected, ui.getStyleableInfos( c ) ); assertMapEquals( expected, ui.getStyleableInfos( c ) );
} }
@@ -326,6 +327,7 @@ public class TestFlatStyleableInfo
Map<String, Class<?>> expected = new LinkedHashMap<>(); Map<String, Class<?>> expected = new LinkedHashMap<>();
menuItem( expected ); menuItem( expected );
menuItem_checkIcon( expected ); menuItem_checkIcon( expected );
menuItem_arrowIcon( expected );
assertMapEquals( expected, ui.getStyleableInfos( c ) ); assertMapEquals( expected, ui.getStyleableInfos( c ) );
} }
@@ -336,8 +338,7 @@ public class TestFlatStyleableInfo
"selectionForeground", Color.class, "selectionForeground", Color.class,
"disabledForeground", Color.class, "disabledForeground", Color.class,
"acceleratorForeground", Color.class, "acceleratorForeground", Color.class,
"acceleratorSelectionForeground", Color.class, "acceleratorSelectionForeground", Color.class
"acceleratorFont", Font.class
); );
menuItemRenderer( expected ); menuItemRenderer( expected );
@@ -345,7 +346,6 @@ public class TestFlatStyleableInfo
private void menuItemRenderer( Map<String, Class<?>> expected ) { private void menuItemRenderer( Map<String, Class<?>> expected ) {
expectedMap( expected, expectedMap( expected,
"verticallyAlignText", boolean.class,
"minimumWidth", int.class, "minimumWidth", int.class,
"minimumIconSize", Dimension.class, "minimumIconSize", Dimension.class,
"textAcceleratorGap", int.class, "textAcceleratorGap", int.class,
@@ -379,18 +379,6 @@ public class TestFlatStyleableInfo
); );
} }
@Test
void panel() {
JPanel c = new JPanel();
FlatPanelUI ui = (FlatPanelUI) c.getUI();
Map<String, Class<?>> expected = expectedMap(
"arc", int.class
);
assertMapEquals( expected, ui.getStyleableInfos( c ) );
}
@Test @Test
void passwordField() { void passwordField() {
JPasswordField c = new JPasswordField(); JPasswordField c = new JPasswordField();
@@ -398,8 +386,7 @@ public class TestFlatStyleableInfo
Map<String, Class<?>> expected = new LinkedHashMap<>(); Map<String, Class<?>> expected = new LinkedHashMap<>();
expectedMap( expected, expectedMap( expected,
"showCapsLock", boolean.class, "showCapsLock", boolean.class
"showRevealButton", boolean.class
); );
// FlatPasswordFieldUI extends FlatTextFieldUI // FlatPasswordFieldUI extends FlatTextFieldUI
@@ -760,7 +747,7 @@ public class TestFlatStyleableInfo
// FlatTableCellBorder // FlatTableCellBorder
"cellMargins", Insets.class, "cellMargins", Insets.class,
"cellFocusColor", Color.class, "cellFocusColor", Color.class,
"showCellFocusIndicator", Boolean.class "showCellFocusIndicator", boolean.class
); );
assertMapEquals( expected, ui.getStyleableInfos( c ) ); assertMapEquals( expected, ui.getStyleableInfos( c ) );
@@ -779,7 +766,7 @@ public class TestFlatStyleableInfo
// FlatTableHeaderBorder // FlatTableHeaderBorder
"cellMargins", Insets.class, "cellMargins", Insets.class,
"separatorColor", Color.class, "separatorColor", Color.class,
"showTrailingVerticalLine", Boolean.class, "showTrailingVerticalLine", boolean.class,
// FlatAscendingSortIcon and FlatDescendingSortIcon // FlatAscendingSortIcon and FlatDescendingSortIcon
"arrowType", String.class, "arrowType", String.class,
@@ -824,8 +811,7 @@ public class TestFlatStyleableInfo
"focusedBackground", Color.class, "focusedBackground", Color.class,
"iconTextGap", int.class, "iconTextGap", int.class,
"leadingIcon", Icon.class, "leadingIcon", Icon.class,
"trailingIcon", Icon.class, "trailingIcon", Icon.class
"showClearButton", boolean.class
); );
// border // border
@@ -1148,6 +1134,17 @@ public class TestFlatStyleableInfo
assertMapEquals( expected, icon.getStyleableInfos() ); assertMapEquals( expected, icon.getStyleableInfos() );
} }
@Test
void flatMenuItemArrowIcon() {
FlatMenuItemArrowIcon icon = new FlatMenuItemArrowIcon();
// FlatMenuItemArrowIcon extends FlatMenuArrowIcon
Map<String, Class<?>> expected = new LinkedHashMap<>();
flatMenuArrowIcon( expected );
assertMapEquals( expected, icon.getStyleableInfos() );
}
private void flatMenuArrowIcon( Map<String, Class<?>> expected ) { private void flatMenuArrowIcon( Map<String, Class<?>> expected ) {
expectedMap( expected, expectedMap( expected,
"arrowType", String.class, "arrowType", String.class,

View File

@@ -261,7 +261,6 @@ public class TestFlatStyling
// AbstractButton properties // AbstractButton properties
ui.applyStyle( b, "margin: 2,2,2,2" ); ui.applyStyle( b, "margin: 2,2,2,2" );
ui.applyStyle( b, "iconTextGap: 4" );
} }
@Test @Test
@@ -313,9 +312,6 @@ public class TestFlatStyling
ui.applyStyle( "foreground: #fff" ); ui.applyStyle( "foreground: #fff" );
ui.applyStyle( "border: 2,2,2,2,#f00" ); ui.applyStyle( "border: 2,2,2,2,#f00" );
ui.applyStyle( "font: italic 12 monospaced" ); ui.applyStyle( "font: italic 12 monospaced" );
// JComboBox properties
ui.applyStyle( "maximumRowCount: 20" );
} }
@Test @Test
@@ -339,7 +335,6 @@ public class TestFlatStyling
ui.applyStyle( "selectionColor: #fff" ); ui.applyStyle( "selectionColor: #fff" );
ui.applyStyle( "selectedTextColor: #fff" ); ui.applyStyle( "selectedTextColor: #fff" );
ui.applyStyle( "disabledTextColor: #fff" ); ui.applyStyle( "disabledTextColor: #fff" );
ui.applyStyle( "margin: 2,2,2,2" );
} }
@Test @Test
@@ -455,6 +450,7 @@ public class TestFlatStyling
Consumer<String> applyStyle = style -> ui.applyStyle( style ); Consumer<String> applyStyle = style -> ui.applyStyle( style );
menuItem( applyStyle ); menuItem( applyStyle );
menuItem_arrowIcon( applyStyle );
} }
@Test @Test
@@ -465,6 +461,7 @@ public class TestFlatStyling
Consumer<String> applyStyle = style -> ui.applyStyle( style ); Consumer<String> applyStyle = style -> ui.applyStyle( style );
menuItem( applyStyle ); menuItem( applyStyle );
menuItem_checkIcon( applyStyle ); menuItem_checkIcon( applyStyle );
menuItem_arrowIcon( applyStyle );
} }
@Test @Test
@@ -475,6 +472,7 @@ public class TestFlatStyling
Consumer<String> applyStyle = style -> ui.applyStyle( style ); Consumer<String> applyStyle = style -> ui.applyStyle( style );
menuItem( applyStyle ); menuItem( applyStyle );
menuItem_checkIcon( applyStyle ); menuItem_checkIcon( applyStyle );
menuItem_arrowIcon( applyStyle );
} }
private void menuItem( Consumer<String> applyStyle ) { private void menuItem( Consumer<String> applyStyle ) {
@@ -483,7 +481,6 @@ public class TestFlatStyling
applyStyle.accept( "disabledForeground: #fff" ); applyStyle.accept( "disabledForeground: #fff" );
applyStyle.accept( "acceleratorForeground: #fff" ); applyStyle.accept( "acceleratorForeground: #fff" );
applyStyle.accept( "acceleratorSelectionForeground: #fff" ); applyStyle.accept( "acceleratorSelectionForeground: #fff" );
applyStyle.accept( "acceleratorFont: italic 12 monospaced" );
menuItemRenderer( applyStyle ); menuItemRenderer( applyStyle );
@@ -495,11 +492,9 @@ public class TestFlatStyling
// AbstractButton properties // AbstractButton properties
applyStyle.accept( "margin: 2,2,2,2" ); applyStyle.accept( "margin: 2,2,2,2" );
applyStyle.accept( "iconTextGap: 4" );
} }
private void menuItemRenderer( Consumer<String> applyStyle ) { private void menuItemRenderer( Consumer<String> applyStyle ) {
applyStyle.accept( "verticallyAlignText: false" );
applyStyle.accept( "minimumWidth: 10" ); applyStyle.accept( "minimumWidth: 10" );
applyStyle.accept( "minimumIconSize: 16,16" ); applyStyle.accept( "minimumIconSize: 16,16" );
applyStyle.accept( "textAcceleratorGap: 28" ); applyStyle.accept( "textAcceleratorGap: 28" );
@@ -528,20 +523,6 @@ public class TestFlatStyling
applyStyle.accept( "selectionForeground: #fff" ); applyStyle.accept( "selectionForeground: #fff" );
} }
@Test
void panel() {
JPanel c = new JPanel();
FlatPanelUI ui = (FlatPanelUI) c.getUI();
ui.applyStyle( c, "arc: 8" );
// JComponent properties
ui.applyStyle( c, "background: #fff" );
ui.applyStyle( c, "foreground: #fff" );
ui.applyStyle( c, "border: 2,2,2,2,#f00" );
ui.applyStyle( c, "font: italic 12 monospaced" );
}
@Test @Test
void passwordField() { void passwordField() {
JPasswordField c = new JPasswordField(); JPasswordField c = new JPasswordField();
@@ -551,7 +532,6 @@ public class TestFlatStyling
textField( ui ); textField( ui );
ui.applyStyle( "showCapsLock: true" ); ui.applyStyle( "showCapsLock: true" );
ui.applyStyle( "showRevealButton: true" );
// capsLockIcon // capsLockIcon
ui.applyStyle( "capsLockIconColor: #fff" ); ui.applyStyle( "capsLockIconColor: #fff" );
@@ -625,7 +605,6 @@ public class TestFlatStyling
// AbstractButton properties // AbstractButton properties
ui.applyStyle( b, "margin: 2,2,2,2" ); ui.applyStyle( b, "margin: 2,2,2,2" );
ui.applyStyle( b, "iconTextGap: 4" );
//---- icon ---- //---- icon ----
@@ -722,7 +701,6 @@ public class TestFlatStyling
ui.applyStyle( "background: #fff" ); ui.applyStyle( "background: #fff" );
ui.applyStyle( "foreground: #fff" ); ui.applyStyle( "foreground: #fff" );
ui.applyStyle( "border: 2,2,2,2,#f00" ); ui.applyStyle( "border: 2,2,2,2,#f00" );
ui.applyStyle( "viewportBorder: 2,2,2,2,#f00" );
} }
@Test @Test
@@ -772,8 +750,6 @@ public class TestFlatStyling
ui.applyStyle( "foreground: #fff" ); ui.applyStyle( "foreground: #fff" );
ui.applyStyle( "border: 2,2,2,2,#f00" ); ui.applyStyle( "border: 2,2,2,2,#f00" );
ui.applyStyle( "font: italic 12 monospaced" ); ui.applyStyle( "font: italic 12 monospaced" );
// JSlider properties
ui.applyStyle( "minimum: 0" ); ui.applyStyle( "minimum: 0" );
ui.applyStyle( "maximum: 50" ); ui.applyStyle( "maximum: 50" );
ui.applyStyle( "value: 20" ); ui.applyStyle( "value: 20" );
@@ -785,6 +761,12 @@ public class TestFlatStyling
ui.applyStyle( "paintTicks: true" ); ui.applyStyle( "paintTicks: true" );
ui.applyStyle( "paintTrack: true" ); ui.applyStyle( "paintTrack: true" );
ui.applyStyle( "snapToTicks: true" ); ui.applyStyle( "snapToTicks: true" );
// JSlider properties
ui.applyStyle( "paintLabels: true" );
ui.applyStyle( "paintTicks: true" );
ui.applyStyle( "paintTrack: true" );
ui.applyStyle( "snapToTicks: true" );
} }
@Test @Test
@@ -936,6 +918,7 @@ public class TestFlatStyling
// JComponent properties // JComponent properties
ui.applyStyle( "background: #fff" ); ui.applyStyle( "background: #fff" );
ui.applyStyle( "foreground: #fff" ); ui.applyStyle( "foreground: #fff" );
ui.applyStyle( "border: 2,2,2,2,#f00" );
ui.applyStyle( "font: italic 12 monospaced" ); ui.applyStyle( "font: italic 12 monospaced" );
// JTable properties // JTable properties
@@ -967,6 +950,7 @@ public class TestFlatStyling
// JComponent properties // JComponent properties
ui.applyStyle( "background: #fff" ); ui.applyStyle( "background: #fff" );
ui.applyStyle( "foreground: #fff" ); ui.applyStyle( "foreground: #fff" );
ui.applyStyle( "border: 2,2,2,2,#f00" );
ui.applyStyle( "font: italic 12 monospaced" ); ui.applyStyle( "font: italic 12 monospaced" );
} }
@@ -991,7 +975,6 @@ public class TestFlatStyling
ui.applyStyle( "selectionColor: #fff" ); ui.applyStyle( "selectionColor: #fff" );
ui.applyStyle( "selectedTextColor: #fff" ); ui.applyStyle( "selectedTextColor: #fff" );
ui.applyStyle( "disabledTextColor: #fff" ); ui.applyStyle( "disabledTextColor: #fff" );
ui.applyStyle( "margin: 2,2,2,2" );
} }
@Test @Test
@@ -1012,8 +995,6 @@ public class TestFlatStyling
ui.applyStyle( "leadingIcon: com.formdev.flatlaf.icons.FlatSearchIcon" ); ui.applyStyle( "leadingIcon: com.formdev.flatlaf.icons.FlatSearchIcon" );
ui.applyStyle( "trailingIcon: com.formdev.flatlaf.icons.FlatClearIcon" ); ui.applyStyle( "trailingIcon: com.formdev.flatlaf.icons.FlatClearIcon" );
ui.applyStyle( "showClearButton: true" );
// border // border
flatTextBorder( style -> ui.applyStyle( style ) ); flatTextBorder( style -> ui.applyStyle( style ) );
@@ -1028,7 +1009,6 @@ public class TestFlatStyling
ui.applyStyle( "selectionColor: #fff" ); ui.applyStyle( "selectionColor: #fff" );
ui.applyStyle( "selectedTextColor: #fff" ); ui.applyStyle( "selectedTextColor: #fff" );
ui.applyStyle( "disabledTextColor: #fff" ); ui.applyStyle( "disabledTextColor: #fff" );
ui.applyStyle( "margin: 2,2,2,2" );
} }
@Test @Test
@@ -1052,7 +1032,6 @@ public class TestFlatStyling
ui.applyStyle( "selectionColor: #fff" ); ui.applyStyle( "selectionColor: #fff" );
ui.applyStyle( "selectedTextColor: #fff" ); ui.applyStyle( "selectedTextColor: #fff" );
ui.applyStyle( "disabledTextColor: #fff" ); ui.applyStyle( "disabledTextColor: #fff" );
ui.applyStyle( "margin: 2,2,2,2" );
} }
@Test @Test
@@ -1363,6 +1342,18 @@ public class TestFlatStyling
void flatMenuArrowIcon() { void flatMenuArrowIcon() {
FlatMenuArrowIcon icon = new FlatMenuArrowIcon(); FlatMenuArrowIcon icon = new FlatMenuArrowIcon();
flatMenuArrowIcon( icon );
}
@Test
void flatMenuItemArrowIcon() {
FlatMenuItemArrowIcon icon = new FlatMenuItemArrowIcon();
// FlatMenuItemArrowIcon extends FlatMenuArrowIcon
flatMenuArrowIcon( icon );
}
private void flatMenuArrowIcon( FlatMenuArrowIcon icon ) {
icon.applyStyleProperty( "arrowType", "chevron" ); icon.applyStyleProperty( "arrowType", "chevron" );
icon.applyStyleProperty( "arrowColor", Color.WHITE ); icon.applyStyleProperty( "arrowColor", Color.WHITE );
icon.applyStyleProperty( "disabledArrowColor", Color.WHITE ); icon.applyStyleProperty( "disabledArrowColor", Color.WHITE );

View File

@@ -22,7 +22,6 @@ import javax.swing.text.DefaultEditorKit;
import com.formdev.flatlaf.FlatClientProperties; import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.extras.FlatSVGIcon; import com.formdev.flatlaf.extras.FlatSVGIcon;
import com.formdev.flatlaf.icons.FlatSearchIcon; import com.formdev.flatlaf.icons.FlatSearchIcon;
import com.formdev.flatlaf.icons.FlatSearchWithHistoryIcon;
import net.miginfocom.layout.AC; import net.miginfocom.layout.AC;
import net.miginfocom.layout.BoundSize; import net.miginfocom.layout.BoundSize;
import net.miginfocom.layout.ConstraintParser; import net.miginfocom.layout.ConstraintParser;
@@ -37,62 +36,6 @@ class BasicComponentsPanel
{ {
BasicComponentsPanel() { BasicComponentsPanel() {
initComponents(); initComponents();
// show reveal button for password field
// to enable this for all password fields use:
// UIManager.put( "PasswordField.showRevealButton", true );
passwordField1.putClientProperty( FlatClientProperties.STYLE, "showRevealButton: true" );
// add leading/trailing icons to text fields
leadingIconTextField.putClientProperty( FlatClientProperties.PLACEHOLDER_TEXT, "Search" );
leadingIconTextField.putClientProperty( FlatClientProperties.TEXT_FIELD_LEADING_ICON,
new FlatSearchIcon() );
trailingIconTextField.putClientProperty( FlatClientProperties.TEXT_FIELD_TRAILING_ICON,
new FlatSVGIcon( "com/formdev/flatlaf/demo/icons/DataTables.svg" ) );
iconsTextField.putClientProperty( FlatClientProperties.TEXT_FIELD_LEADING_ICON,
new FlatSVGIcon( "com/formdev/flatlaf/demo/icons/user.svg" ) );
iconsTextField.putClientProperty( FlatClientProperties.TEXT_FIELD_TRAILING_ICON,
new FlatSVGIcon( "com/formdev/flatlaf/demo/icons/bookmarkGroup.svg" ) );
// search history button
JButton searchHistoryButton = new JButton( new FlatSearchWithHistoryIcon( true ) );
searchHistoryButton.setToolTipText( "Search History" );
searchHistoryButton.addActionListener( e -> {
JPopupMenu popupMenu = new JPopupMenu();
popupMenu.add( "(empty)" );
popupMenu.show( searchHistoryButton, 0, searchHistoryButton.getHeight() );
} );
compsTextField.putClientProperty( FlatClientProperties.TEXT_FIELD_LEADING_COMPONENT, searchHistoryButton );
// match case button
JToggleButton matchCaseButton = new JToggleButton( new FlatSVGIcon( "com/formdev/flatlaf/demo/icons/matchCase.svg" ) );
matchCaseButton.setRolloverIcon( new FlatSVGIcon( "com/formdev/flatlaf/demo/icons/matchCaseHovered.svg" ) );
matchCaseButton.setSelectedIcon( new FlatSVGIcon( "com/formdev/flatlaf/demo/icons/matchCaseSelected.svg" ) );
matchCaseButton.setToolTipText( "Match Case" );
// whole words button
JToggleButton wordsButton = new JToggleButton( new FlatSVGIcon( "com/formdev/flatlaf/demo/icons/words.svg" ) );
wordsButton.setRolloverIcon( new FlatSVGIcon( "com/formdev/flatlaf/demo/icons/wordsHovered.svg" ) );
wordsButton.setSelectedIcon( new FlatSVGIcon( "com/formdev/flatlaf/demo/icons/wordsSelected.svg" ) );
wordsButton.setToolTipText( "Whole Words" );
// regex button
JToggleButton regexButton = new JToggleButton( new FlatSVGIcon( "com/formdev/flatlaf/demo/icons/regex.svg" ) );
regexButton.setRolloverIcon( new FlatSVGIcon( "com/formdev/flatlaf/demo/icons/regexHovered.svg" ) );
regexButton.setSelectedIcon( new FlatSVGIcon( "com/formdev/flatlaf/demo/icons/regexSelected.svg" ) );
regexButton.setToolTipText( "Regular Expression" );
// search toolbar
JToolBar searchToolbar = new JToolBar();
searchToolbar.add( matchCaseButton );
searchToolbar.add( wordsButton );
searchToolbar.addSeparator();
searchToolbar.add( regexButton );
compsTextField.putClientProperty( FlatClientProperties.TEXT_FIELD_TRAILING_COMPONENT, searchToolbar );
// show clear button (if text field is not empty)
compsTextField.putClientProperty( FlatClientProperties.TEXT_FIELD_SHOW_CLEAR_BUTTON, true );
clearTextField.putClientProperty( FlatClientProperties.TEXT_FIELD_SHOW_CLEAR_BUTTON, true );
} }
private void initComponents() { private void initComponents() {
@@ -144,7 +87,7 @@ class BasicComponentsPanel
JFormattedTextField formattedTextField4 = new JFormattedTextField(); JFormattedTextField formattedTextField4 = new JFormattedTextField();
JFormattedTextField formattedTextField5 = new JFormattedTextField(); JFormattedTextField formattedTextField5 = new JFormattedTextField();
JLabel passwordFieldLabel = new JLabel(); JLabel passwordFieldLabel = new JLabel();
passwordField1 = new JPasswordField(); JPasswordField passwordField1 = new JPasswordField();
JPasswordField passwordField2 = new JPasswordField(); JPasswordField passwordField2 = new JPasswordField();
JPasswordField passwordField3 = new JPasswordField(); JPasswordField passwordField3 = new JPasswordField();
JPasswordField passwordField4 = new JPasswordField(); JPasswordField passwordField4 = new JPasswordField();
@@ -188,12 +131,9 @@ class BasicComponentsPanel
JComboBox<String> warningHintsComboBox = new JComboBox<>(); JComboBox<String> warningHintsComboBox = new JComboBox<>();
JSpinner warningHintsSpinner = new JSpinner(); JSpinner warningHintsSpinner = new JSpinner();
JLabel iconsLabel = new JLabel(); JLabel iconsLabel = new JLabel();
leadingIconTextField = new JTextField(); JTextField leadingIconTextField = new JTextField();
trailingIconTextField = new JTextField(); JTextField trailingIconTextField = new JTextField();
iconsTextField = new JTextField(); JTextField iconsTextField = new JTextField();
JLabel compsLabel = new JLabel();
compsTextField = new JTextField();
clearTextField = new JTextField();
JLabel fontsLabel = new JLabel(); JLabel fontsLabel = new JLabel();
JLabel h00Label = new JLabel(); JLabel h00Label = new JLabel();
JLabel h0Label = new JLabel(); JLabel h0Label = new JLabel();
@@ -241,7 +181,6 @@ class BasicComponentsPanel
"[]" + "[]" +
"[]" + "[]" +
"[]" + "[]" +
"[]" +
"[]0" + "[]0" +
"[]")); "[]"));
@@ -750,93 +689,84 @@ class BasicComponentsPanel
iconsTextField.setText("text"); iconsTextField.setText("text");
add(iconsTextField, "cell 3 14,growx"); add(iconsTextField, "cell 3 14,growx");
//---- compsLabel ----
compsLabel.setText("Leading/trailing comp.:");
add(compsLabel, "cell 0 15");
add(compsTextField, "cell 1 15 2 1,growx");
//---- clearTextField ----
clearTextField.setText("clear me");
add(clearTextField, "cell 3 15,growx");
//---- fontsLabel ---- //---- fontsLabel ----
fontsLabel.setText("Typography / Fonts:"); fontsLabel.setText("Typography / Fonts:");
add(fontsLabel, "cell 0 16"); add(fontsLabel, "cell 0 15");
//---- h00Label ---- //---- h00Label ----
h00Label.setText("H00"); h00Label.setText("H00");
h00Label.putClientProperty("FlatLaf.styleClass", "h00"); h00Label.putClientProperty("FlatLaf.styleClass", "h00");
add(h00Label, "cell 1 16 5 1"); add(h00Label, "cell 1 15 5 1");
//---- h0Label ---- //---- h0Label ----
h0Label.setText("H0"); h0Label.setText("H0");
h0Label.putClientProperty("FlatLaf.styleClass", "h0"); h0Label.putClientProperty("FlatLaf.styleClass", "h0");
add(h0Label, "cell 1 16 5 1"); add(h0Label, "cell 1 15 5 1");
//---- h1Label ---- //---- h1Label ----
h1Label.setText("H1"); h1Label.setText("H1");
h1Label.putClientProperty("FlatLaf.styleClass", "h1"); h1Label.putClientProperty("FlatLaf.styleClass", "h1");
add(h1Label, "cell 1 16 5 1"); add(h1Label, "cell 1 15 5 1");
//---- h2Label ---- //---- h2Label ----
h2Label.setText("H2"); h2Label.setText("H2");
h2Label.putClientProperty("FlatLaf.styleClass", "h2"); h2Label.putClientProperty("FlatLaf.styleClass", "h2");
add(h2Label, "cell 1 16 5 1"); add(h2Label, "cell 1 15 5 1");
//---- h3Label ---- //---- h3Label ----
h3Label.setText("H3"); h3Label.setText("H3");
h3Label.putClientProperty("FlatLaf.styleClass", "h3"); h3Label.putClientProperty("FlatLaf.styleClass", "h3");
add(h3Label, "cell 1 16 5 1"); add(h3Label, "cell 1 15 5 1");
//---- h4Label ---- //---- h4Label ----
h4Label.setText("H4"); h4Label.setText("H4");
h4Label.putClientProperty("FlatLaf.styleClass", "h4"); h4Label.putClientProperty("FlatLaf.styleClass", "h4");
add(h4Label, "cell 1 16 5 1"); add(h4Label, "cell 1 15 5 1");
//---- lightLabel ---- //---- lightLabel ----
lightLabel.setText("light"); lightLabel.setText("light");
lightLabel.putClientProperty("FlatLaf.style", "font: 200% $light.font"); lightLabel.putClientProperty("FlatLaf.style", "font: 200% $light.font");
add(lightLabel, "cell 1 16 5 1,gapx 30"); add(lightLabel, "cell 1 15 5 1,gapx 30");
//---- semiboldLabel ---- //---- semiboldLabel ----
semiboldLabel.setText("semibold"); semiboldLabel.setText("semibold");
semiboldLabel.putClientProperty("FlatLaf.style", "font: 200% $semibold.font"); semiboldLabel.putClientProperty("FlatLaf.style", "font: 200% $semibold.font");
add(semiboldLabel, "cell 1 16 5 1"); add(semiboldLabel, "cell 1 15 5 1");
//---- fontZoomLabel ---- //---- fontZoomLabel ----
fontZoomLabel.setText("(200%)"); fontZoomLabel.setText("(200%)");
fontZoomLabel.putClientProperty("FlatLaf.styleClass", "small"); fontZoomLabel.putClientProperty("FlatLaf.styleClass", "small");
fontZoomLabel.setEnabled(false); fontZoomLabel.setEnabled(false);
add(fontZoomLabel, "cell 1 16 5 1"); add(fontZoomLabel, "cell 1 15 5 1");
//---- largeLabel ---- //---- largeLabel ----
largeLabel.setText("large"); largeLabel.setText("large");
largeLabel.putClientProperty("FlatLaf.styleClass", "large"); largeLabel.putClientProperty("FlatLaf.styleClass", "large");
add(largeLabel, "cell 1 17 5 1"); add(largeLabel, "cell 1 16 5 1");
//---- defaultLabel ---- //---- defaultLabel ----
defaultLabel.setText("default"); defaultLabel.setText("default");
add(defaultLabel, "cell 1 17 5 1"); add(defaultLabel, "cell 1 16 5 1");
//---- mediumLabel ---- //---- mediumLabel ----
mediumLabel.setText("medium"); mediumLabel.setText("medium");
mediumLabel.putClientProperty("FlatLaf.styleClass", "medium"); mediumLabel.putClientProperty("FlatLaf.styleClass", "medium");
add(mediumLabel, "cell 1 17 5 1"); add(mediumLabel, "cell 1 16 5 1");
//---- smallLabel ---- //---- smallLabel ----
smallLabel.setText("small"); smallLabel.setText("small");
smallLabel.putClientProperty("FlatLaf.styleClass", "small"); smallLabel.putClientProperty("FlatLaf.styleClass", "small");
add(smallLabel, "cell 1 17 5 1"); add(smallLabel, "cell 1 16 5 1");
//---- miniLabel ---- //---- miniLabel ----
miniLabel.setText("mini"); miniLabel.setText("mini");
miniLabel.putClientProperty("FlatLaf.styleClass", "mini"); miniLabel.putClientProperty("FlatLaf.styleClass", "mini");
add(miniLabel, "cell 1 17 5 1"); add(miniLabel, "cell 1 16 5 1");
//---- monospacedLabel ---- //---- monospacedLabel ----
monospacedLabel.setText("monospaced"); monospacedLabel.setText("monospaced");
monospacedLabel.putClientProperty("FlatLaf.styleClass", "monospaced"); monospacedLabel.putClientProperty("FlatLaf.styleClass", "monospaced");
add(monospacedLabel, "cell 1 17 5 1,gapx 30"); add(monospacedLabel, "cell 1 16 5 1,gapx 30");
//======== popupMenu1 ======== //======== popupMenu1 ========
{ {
@@ -862,6 +792,17 @@ class BasicComponentsPanel
copyMenuItem.addActionListener( new DefaultEditorKit.CopyAction() ); copyMenuItem.addActionListener( new DefaultEditorKit.CopyAction() );
pasteMenuItem.addActionListener( new DefaultEditorKit.PasteAction() ); pasteMenuItem.addActionListener( new DefaultEditorKit.PasteAction() );
// add leading/trailing icons to text fields
leadingIconTextField.putClientProperty( FlatClientProperties.PLACEHOLDER_TEXT, "Search" );
leadingIconTextField.putClientProperty( FlatClientProperties.TEXT_FIELD_LEADING_ICON,
new FlatSearchIcon() );
trailingIconTextField.putClientProperty( FlatClientProperties.TEXT_FIELD_TRAILING_ICON,
new FlatSVGIcon( "com/formdev/flatlaf/demo/icons/DataTables.svg" ) );
iconsTextField.putClientProperty( FlatClientProperties.TEXT_FIELD_LEADING_ICON,
new FlatSVGIcon( "com/formdev/flatlaf/demo/icons/user.svg" ) );
iconsTextField.putClientProperty( FlatClientProperties.TEXT_FIELD_TRAILING_ICON,
new FlatSVGIcon( "com/formdev/flatlaf/demo/icons/bookmarkGroup.svg" ) );
if( FlatLafDemo.screenshotsMode ) { if( FlatLafDemo.screenshotsMode ) {
// hide some components // hide some components
Component[] hiddenComponents = { Component[] hiddenComponents = {
@@ -900,7 +841,7 @@ class BasicComponentsPanel
rows[11].setGapAfter( zeroGap ); rows[11].setGapAfter( zeroGap );
rows[12].setGapBefore( zeroGap ); rows[12].setGapBefore( zeroGap );
rows[13].setGapBefore( zeroGap ); rows[13].setGapBefore( zeroGap );
rows[16].setGapBefore( zeroGap ); rows[15].setGapBefore( zeroGap );
layout.setRowConstraints( ac ); layout.setRowConstraints( ac );
// move two text field into same row as spinners // move two text field into same row as spinners
@@ -918,11 +859,5 @@ class BasicComponentsPanel
} }
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables // JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
private JPasswordField passwordField1;
private JTextField leadingIconTextField;
private JTextField trailingIconTextField;
private JTextField iconsTextField;
private JTextField compsTextField;
private JTextField clearTextField;
// JFormDesigner - End of variables declaration //GEN-END:variables // JFormDesigner - End of variables declaration //GEN-END:variables
} }

View File

@@ -1,4 +1,4 @@
JFDML JFormDesigner: "7.0.5.0.404" Java: "17" encoding: "UTF-8" JFDML JFormDesigner: "7.0.4.0.360" Java: "16" encoding: "UTF-8"
new FormModel { new FormModel {
contentType: "form/swing" contentType: "form/swing"
@@ -9,7 +9,7 @@ new FormModel {
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "insets dialog,hidemode 3" "$layoutConstraints": "insets dialog,hidemode 3"
"$columnConstraints": "[][sizegroup 1][sizegroup 1][sizegroup 1][][]" "$columnConstraints": "[][sizegroup 1][sizegroup 1][sizegroup 1][][]"
"$rowConstraints": "[][][][][][][][][][][][]para[][][][][]0[]" "$rowConstraints": "[][][][][][][][][][][][]para[][][][]0[]"
} ) { } ) {
name: "this" name: "this"
add( new FormComponent( "javax.swing.JLabel" ) { add( new FormComponent( "javax.swing.JLabel" ) {
@@ -375,9 +375,6 @@ new FormModel {
add( new FormComponent( "javax.swing.JPasswordField" ) { add( new FormComponent( "javax.swing.JPasswordField" ) {
name: "passwordField1" name: "passwordField1"
"text": "Editable" "text": "Editable"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 8,growx" "value": "cell 1 8,growx"
} ) } )
@@ -659,114 +656,82 @@ new FormModel {
} ) } )
add( new FormComponent( "javax.swing.JTextField" ) { add( new FormComponent( "javax.swing.JTextField" ) {
name: "leadingIconTextField" name: "leadingIconTextField"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 14,growx" "value": "cell 1 14,growx"
} ) } )
add( new FormComponent( "javax.swing.JTextField" ) { add( new FormComponent( "javax.swing.JTextField" ) {
name: "trailingIconTextField" name: "trailingIconTextField"
"text": "text" "text": "text"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 14,growx" "value": "cell 2 14,growx"
} ) } )
add( new FormComponent( "javax.swing.JTextField" ) { add( new FormComponent( "javax.swing.JTextField" ) {
name: "iconsTextField" name: "iconsTextField"
"text": "text" "text": "text"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 3 14,growx" "value": "cell 3 14,growx"
} ) } )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "compsLabel"
"text": "Leading/trailing comp.:"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 15"
} )
add( new FormComponent( "javax.swing.JTextField" ) {
name: "compsTextField"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 15 2 1,growx"
} )
add( new FormComponent( "javax.swing.JTextField" ) {
name: "clearTextField"
"text": "clear me"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 3 15,growx"
} )
add( new FormComponent( "javax.swing.JLabel" ) { add( new FormComponent( "javax.swing.JLabel" ) {
name: "fontsLabel" name: "fontsLabel"
"text": "Typography / Fonts:" "text": "Typography / Fonts:"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 16" "value": "cell 0 15"
} ) } )
add( new FormComponent( "javax.swing.JLabel" ) { add( new FormComponent( "javax.swing.JLabel" ) {
name: "h00Label" name: "h00Label"
"text": "H00" "text": "H00"
"$client.FlatLaf.styleClass": "h00" "$client.FlatLaf.styleClass": "h00"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 16 5 1" "value": "cell 1 15 5 1"
} ) } )
add( new FormComponent( "javax.swing.JLabel" ) { add( new FormComponent( "javax.swing.JLabel" ) {
name: "h0Label" name: "h0Label"
"text": "H0" "text": "H0"
"$client.FlatLaf.styleClass": "h0" "$client.FlatLaf.styleClass": "h0"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 16 5 1" "value": "cell 1 15 5 1"
} ) } )
add( new FormComponent( "javax.swing.JLabel" ) { add( new FormComponent( "javax.swing.JLabel" ) {
name: "h1Label" name: "h1Label"
"text": "H1" "text": "H1"
"$client.FlatLaf.styleClass": "h1" "$client.FlatLaf.styleClass": "h1"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 16 5 1" "value": "cell 1 15 5 1"
} ) } )
add( new FormComponent( "javax.swing.JLabel" ) { add( new FormComponent( "javax.swing.JLabel" ) {
name: "h2Label" name: "h2Label"
"text": "H2" "text": "H2"
"$client.FlatLaf.styleClass": "h2" "$client.FlatLaf.styleClass": "h2"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 16 5 1" "value": "cell 1 15 5 1"
} ) } )
add( new FormComponent( "javax.swing.JLabel" ) { add( new FormComponent( "javax.swing.JLabel" ) {
name: "h3Label" name: "h3Label"
"text": "H3" "text": "H3"
"$client.FlatLaf.styleClass": "h3" "$client.FlatLaf.styleClass": "h3"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 16 5 1" "value": "cell 1 15 5 1"
} ) } )
add( new FormComponent( "javax.swing.JLabel" ) { add( new FormComponent( "javax.swing.JLabel" ) {
name: "h4Label" name: "h4Label"
"text": "H4" "text": "H4"
"$client.FlatLaf.styleClass": "h4" "$client.FlatLaf.styleClass": "h4"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 16 5 1" "value": "cell 1 15 5 1"
} ) } )
add( new FormComponent( "javax.swing.JLabel" ) { add( new FormComponent( "javax.swing.JLabel" ) {
name: "lightLabel" name: "lightLabel"
"text": "light" "text": "light"
"$client.FlatLaf.style": "font: 200% $light.font" "$client.FlatLaf.style": "font: 200% $light.font"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 16 5 1,gapx 30" "value": "cell 1 15 5 1,gapx 30"
} ) } )
add( new FormComponent( "javax.swing.JLabel" ) { add( new FormComponent( "javax.swing.JLabel" ) {
name: "semiboldLabel" name: "semiboldLabel"
"text": "semibold" "text": "semibold"
"$client.FlatLaf.style": "font: 200% $semibold.font" "$client.FlatLaf.style": "font: 200% $semibold.font"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 16 5 1" "value": "cell 1 15 5 1"
} ) } )
add( new FormComponent( "javax.swing.JLabel" ) { add( new FormComponent( "javax.swing.JLabel" ) {
name: "fontZoomLabel" name: "fontZoomLabel"
@@ -774,48 +739,48 @@ new FormModel {
"$client.FlatLaf.styleClass": "small" "$client.FlatLaf.styleClass": "small"
"enabled": false "enabled": false
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 16 5 1" "value": "cell 1 15 5 1"
} ) } )
add( new FormComponent( "javax.swing.JLabel" ) { add( new FormComponent( "javax.swing.JLabel" ) {
name: "largeLabel" name: "largeLabel"
"text": "large" "text": "large"
"$client.FlatLaf.styleClass": "large" "$client.FlatLaf.styleClass": "large"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 17 5 1" "value": "cell 1 16 5 1"
} ) } )
add( new FormComponent( "javax.swing.JLabel" ) { add( new FormComponent( "javax.swing.JLabel" ) {
name: "defaultLabel" name: "defaultLabel"
"text": "default" "text": "default"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 17 5 1" "value": "cell 1 16 5 1"
} ) } )
add( new FormComponent( "javax.swing.JLabel" ) { add( new FormComponent( "javax.swing.JLabel" ) {
name: "mediumLabel" name: "mediumLabel"
"text": "medium" "text": "medium"
"$client.FlatLaf.styleClass": "medium" "$client.FlatLaf.styleClass": "medium"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 17 5 1" "value": "cell 1 16 5 1"
} ) } )
add( new FormComponent( "javax.swing.JLabel" ) { add( new FormComponent( "javax.swing.JLabel" ) {
name: "smallLabel" name: "smallLabel"
"text": "small" "text": "small"
"$client.FlatLaf.styleClass": "small" "$client.FlatLaf.styleClass": "small"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 17 5 1" "value": "cell 1 16 5 1"
} ) } )
add( new FormComponent( "javax.swing.JLabel" ) { add( new FormComponent( "javax.swing.JLabel" ) {
name: "miniLabel" name: "miniLabel"
"text": "mini" "text": "mini"
"$client.FlatLaf.styleClass": "mini" "$client.FlatLaf.styleClass": "mini"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 17 5 1" "value": "cell 1 16 5 1"
} ) } )
add( new FormComponent( "javax.swing.JLabel" ) { add( new FormComponent( "javax.swing.JLabel" ) {
name: "monospacedLabel" name: "monospacedLabel"
"text": "monospaced" "text": "monospaced"
"$client.FlatLaf.styleClass": "monospaced" "$client.FlatLaf.styleClass": "monospaced"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 17 5 1,gapx 30" "value": "cell 1 16 5 1,gapx 30"
} ) } )
}, new FormLayoutConstraints( null ) { }, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 0, 0 ) "location": new java.awt.Point( 0, 0 )

View File

@@ -62,10 +62,10 @@ class ControlBar
// initialize look and feels combo box // initialize look and feels combo box
DefaultComboBoxModel<LookAndFeelInfo> lafModel = new DefaultComboBoxModel<>(); DefaultComboBoxModel<LookAndFeelInfo> lafModel = new DefaultComboBoxModel<>();
lafModel.addElement( new LookAndFeelInfo( "FlatLaf Light (F1)", FlatLightLaf.class.getName() ) ); lafModel.addElement( new LookAndFeelInfo( "Flat Light (F1)", FlatLightLaf.class.getName() ) );
lafModel.addElement( new LookAndFeelInfo( "FlatLaf Dark (F2)", FlatDarkLaf.class.getName() ) ); lafModel.addElement( new LookAndFeelInfo( "Flat Dark (F2)", FlatDarkLaf.class.getName() ) );
lafModel.addElement( new LookAndFeelInfo( "FlatLaf IntelliJ (F3)", FlatIntelliJLaf.class.getName() ) ); lafModel.addElement( new LookAndFeelInfo( "Flat IntelliJ (F3)", FlatIntelliJLaf.class.getName() ) );
lafModel.addElement( new LookAndFeelInfo( "FlatLaf Darcula (F4)", FlatDarculaLaf.class.getName() ) ); lafModel.addElement( new LookAndFeelInfo( "Flat Darcula (F4)", FlatDarculaLaf.class.getName() ) );
UIManager.LookAndFeelInfo[] lookAndFeels = UIManager.getInstalledLookAndFeels(); UIManager.LookAndFeelInfo[] lookAndFeels = UIManager.getInstalledLookAndFeels();
for( UIManager.LookAndFeelInfo lookAndFeel : lookAndFeels ) { for( UIManager.LookAndFeelInfo lookAndFeel : lookAndFeels ) {

View File

@@ -71,11 +71,8 @@ public class FlatLafDemo
// create frame // create frame
DemoFrame frame = new DemoFrame(); DemoFrame frame = new DemoFrame();
if( FlatLafDemo.screenshotsMode ) { if( FlatLafDemo.screenshotsMode )
frame.setPreferredSize( SystemInfo.isJava_9_orLater frame.setPreferredSize( new Dimension( 1660, 840 ) );
? new Dimension( 830, 440 )
: new Dimension( 1660, 880 ) );
}
// show frame // show frame
frame.pack(); frame.pack();

View File

@@ -412,6 +412,7 @@ class TabsPanel
cardTabTypeButton = new JToggleButton(); cardTabTypeButton = new JToggleButton();
//======== this ======== //======== this ========
setName("this");
setLayout(new MigLayout( setLayout(new MigLayout(
"insets dialog,hidemode 3", "insets dialog,hidemode 3",
// columns // columns
@@ -425,6 +426,7 @@ class TabsPanel
//======== panel1 ======== //======== panel1 ========
{ {
panel1.setName("panel1");
panel1.setLayout(new MigLayout( panel1.setLayout(new MigLayout(
"insets 0,hidemode 3", "insets 0,hidemode 3",
// columns // columns
@@ -443,35 +445,41 @@ class TabsPanel
//---- tabPlacementLabel ---- //---- tabPlacementLabel ----
tabPlacementLabel.setText("Tab placement"); tabPlacementLabel.setText("Tab placement");
tabPlacementLabel.putClientProperty("FlatLaf.styleClass", "h3"); tabPlacementLabel.putClientProperty("FlatLaf.styleClass", "h3");
tabPlacementLabel.setName("tabPlacementLabel");
panel1.add(tabPlacementLabel, "cell 0 0"); panel1.add(tabPlacementLabel, "cell 0 0");
//======== tabPlacementToolBar ======== //======== tabPlacementToolBar ========
{ {
tabPlacementToolBar.setFloatable(false); tabPlacementToolBar.setFloatable(false);
tabPlacementToolBar.setBorder(BorderFactory.createEmptyBorder()); tabPlacementToolBar.setBorder(BorderFactory.createEmptyBorder());
tabPlacementToolBar.setName("tabPlacementToolBar");
//---- topPlacementButton ---- //---- topPlacementButton ----
topPlacementButton.setText("top"); topPlacementButton.setText("top");
topPlacementButton.setSelected(true); topPlacementButton.setSelected(true);
topPlacementButton.putClientProperty("FlatLaf.styleClass", "small"); topPlacementButton.putClientProperty("FlatLaf.styleClass", "small");
topPlacementButton.setName("topPlacementButton");
topPlacementButton.addActionListener(e -> tabPlacementChanged()); topPlacementButton.addActionListener(e -> tabPlacementChanged());
tabPlacementToolBar.add(topPlacementButton); tabPlacementToolBar.add(topPlacementButton);
//---- bottomPlacementButton ---- //---- bottomPlacementButton ----
bottomPlacementButton.setText("bottom"); bottomPlacementButton.setText("bottom");
bottomPlacementButton.putClientProperty("FlatLaf.styleClass", "small"); bottomPlacementButton.putClientProperty("FlatLaf.styleClass", "small");
bottomPlacementButton.setName("bottomPlacementButton");
bottomPlacementButton.addActionListener(e -> tabPlacementChanged()); bottomPlacementButton.addActionListener(e -> tabPlacementChanged());
tabPlacementToolBar.add(bottomPlacementButton); tabPlacementToolBar.add(bottomPlacementButton);
//---- leftPlacementButton ---- //---- leftPlacementButton ----
leftPlacementButton.setText("left"); leftPlacementButton.setText("left");
leftPlacementButton.putClientProperty("FlatLaf.styleClass", "small"); leftPlacementButton.putClientProperty("FlatLaf.styleClass", "small");
leftPlacementButton.setName("leftPlacementButton");
leftPlacementButton.addActionListener(e -> tabPlacementChanged()); leftPlacementButton.addActionListener(e -> tabPlacementChanged());
tabPlacementToolBar.add(leftPlacementButton); tabPlacementToolBar.add(leftPlacementButton);
//---- rightPlacementButton ---- //---- rightPlacementButton ----
rightPlacementButton.setText("right"); rightPlacementButton.setText("right");
rightPlacementButton.putClientProperty("FlatLaf.styleClass", "small"); rightPlacementButton.putClientProperty("FlatLaf.styleClass", "small");
rightPlacementButton.setName("rightPlacementButton");
rightPlacementButton.addActionListener(e -> tabPlacementChanged()); rightPlacementButton.addActionListener(e -> tabPlacementChanged());
tabPlacementToolBar.add(rightPlacementButton); tabPlacementToolBar.add(rightPlacementButton);
tabPlacementToolBar.addSeparator(); tabPlacementToolBar.addSeparator();
@@ -479,38 +487,49 @@ class TabsPanel
//---- scrollButton ---- //---- scrollButton ----
scrollButton.setText("scroll"); scrollButton.setText("scroll");
scrollButton.putClientProperty("FlatLaf.styleClass", "small"); scrollButton.putClientProperty("FlatLaf.styleClass", "small");
scrollButton.setName("scrollButton");
scrollButton.addActionListener(e -> scrollChanged()); scrollButton.addActionListener(e -> scrollChanged());
tabPlacementToolBar.add(scrollButton); tabPlacementToolBar.add(scrollButton);
//---- borderButton ---- //---- borderButton ----
borderButton.setText("border"); borderButton.setText("border");
borderButton.putClientProperty("FlatLaf.styleClass", "small"); borderButton.putClientProperty("FlatLaf.styleClass", "small");
borderButton.setName("borderButton");
borderButton.addActionListener(e -> borderChanged()); borderButton.addActionListener(e -> borderChanged());
tabPlacementToolBar.add(borderButton); tabPlacementToolBar.add(borderButton);
} }
panel1.add(tabPlacementToolBar, "cell 0 0,alignx right,growx 0"); panel1.add(tabPlacementToolBar, "cell 0 0,alignx right,growx 0");
//======== tabPlacementTabbedPane ========
{
tabPlacementTabbedPane.setName("tabPlacementTabbedPane");
}
panel1.add(tabPlacementTabbedPane, "cell 0 1,width 300:300,height 100:100"); panel1.add(tabPlacementTabbedPane, "cell 0 1,width 300:300,height 100:100");
//---- tabLayoutLabel ---- //---- tabLayoutLabel ----
tabLayoutLabel.setText("Tab layout"); tabLayoutLabel.setText("Tab layout");
tabLayoutLabel.putClientProperty("FlatLaf.styleClass", "h3"); tabLayoutLabel.putClientProperty("FlatLaf.styleClass", "h3");
tabLayoutLabel.setName("tabLayoutLabel");
panel1.add(tabLayoutLabel, "cell 0 2"); panel1.add(tabLayoutLabel, "cell 0 2");
//======== tabLayoutToolBar ======== //======== tabLayoutToolBar ========
{ {
tabLayoutToolBar.setFloatable(false); tabLayoutToolBar.setFloatable(false);
tabLayoutToolBar.setBorder(BorderFactory.createEmptyBorder()); tabLayoutToolBar.setBorder(BorderFactory.createEmptyBorder());
tabLayoutToolBar.setName("tabLayoutToolBar");
//---- scrollTabLayoutButton ---- //---- scrollTabLayoutButton ----
scrollTabLayoutButton.setText("scroll"); scrollTabLayoutButton.setText("scroll");
scrollTabLayoutButton.setSelected(true); scrollTabLayoutButton.setSelected(true);
scrollTabLayoutButton.putClientProperty("FlatLaf.styleClass", "small"); scrollTabLayoutButton.putClientProperty("FlatLaf.styleClass", "small");
scrollTabLayoutButton.setName("scrollTabLayoutButton");
scrollTabLayoutButton.addActionListener(e -> tabLayoutChanged()); scrollTabLayoutButton.addActionListener(e -> tabLayoutChanged());
tabLayoutToolBar.add(scrollTabLayoutButton); tabLayoutToolBar.add(scrollTabLayoutButton);
//---- wrapTabLayoutButton ---- //---- wrapTabLayoutButton ----
wrapTabLayoutButton.setText("wrap"); wrapTabLayoutButton.setText("wrap");
wrapTabLayoutButton.putClientProperty("FlatLaf.styleClass", "small"); wrapTabLayoutButton.putClientProperty("FlatLaf.styleClass", "small");
wrapTabLayoutButton.setName("wrapTabLayoutButton");
wrapTabLayoutButton.addActionListener(e -> tabLayoutChanged()); wrapTabLayoutButton.addActionListener(e -> tabLayoutChanged());
tabLayoutToolBar.add(wrapTabLayoutButton); tabLayoutToolBar.add(wrapTabLayoutButton);
} }
@@ -520,62 +539,87 @@ class TabsPanel
scrollLayoutNoteLabel.setText("(use mouse wheel to scroll; arrow button shows hidden tabs)"); scrollLayoutNoteLabel.setText("(use mouse wheel to scroll; arrow button shows hidden tabs)");
scrollLayoutNoteLabel.setEnabled(false); scrollLayoutNoteLabel.setEnabled(false);
scrollLayoutNoteLabel.putClientProperty("FlatLaf.styleClass", "small"); scrollLayoutNoteLabel.putClientProperty("FlatLaf.styleClass", "small");
scrollLayoutNoteLabel.setName("scrollLayoutNoteLabel");
panel1.add(scrollLayoutNoteLabel, "cell 0 3"); panel1.add(scrollLayoutNoteLabel, "cell 0 3");
//---- wrapLayoutNoteLabel ---- //---- wrapLayoutNoteLabel ----
wrapLayoutNoteLabel.setText("(probably better to use scroll layout?)"); wrapLayoutNoteLabel.setText("(probably better to use scroll layout?)");
wrapLayoutNoteLabel.setEnabled(false); wrapLayoutNoteLabel.setEnabled(false);
wrapLayoutNoteLabel.putClientProperty("FlatLaf.styleClass", "small"); wrapLayoutNoteLabel.putClientProperty("FlatLaf.styleClass", "small");
wrapLayoutNoteLabel.setName("wrapLayoutNoteLabel");
panel1.add(wrapLayoutNoteLabel, "cell 0 3"); panel1.add(wrapLayoutNoteLabel, "cell 0 3");
//======== scrollLayoutTabbedPane ========
{
scrollLayoutTabbedPane.setName("scrollLayoutTabbedPane");
}
panel1.add(scrollLayoutTabbedPane, "cell 0 4"); panel1.add(scrollLayoutTabbedPane, "cell 0 4");
//======== wrapLayoutTabbedPane ========
{
wrapLayoutTabbedPane.setName("wrapLayoutTabbedPane");
}
panel1.add(wrapLayoutTabbedPane, "cell 0 4,width 100:100,height pref*2px"); panel1.add(wrapLayoutTabbedPane, "cell 0 4,width 100:100,height pref*2px");
//---- closableTabsLabel ---- //---- closableTabsLabel ----
closableTabsLabel.setText("Closable tabs"); closableTabsLabel.setText("Closable tabs");
closableTabsLabel.putClientProperty("FlatLaf.styleClass", "h3"); closableTabsLabel.putClientProperty("FlatLaf.styleClass", "h3");
closableTabsLabel.setName("closableTabsLabel");
panel1.add(closableTabsLabel, "cell 0 5"); panel1.add(closableTabsLabel, "cell 0 5");
//======== closableTabsToolBar ======== //======== closableTabsToolBar ========
{ {
closableTabsToolBar.setFloatable(false); closableTabsToolBar.setFloatable(false);
closableTabsToolBar.setBorder(BorderFactory.createEmptyBorder()); closableTabsToolBar.setBorder(BorderFactory.createEmptyBorder());
closableTabsToolBar.setName("closableTabsToolBar");
//---- squareCloseButton ---- //---- squareCloseButton ----
squareCloseButton.setText("square"); squareCloseButton.setText("square");
squareCloseButton.setSelected(true); squareCloseButton.setSelected(true);
squareCloseButton.putClientProperty("FlatLaf.styleClass", "small"); squareCloseButton.putClientProperty("FlatLaf.styleClass", "small");
squareCloseButton.setName("squareCloseButton");
squareCloseButton.addActionListener(e -> closeButtonStyleChanged()); squareCloseButton.addActionListener(e -> closeButtonStyleChanged());
closableTabsToolBar.add(squareCloseButton); closableTabsToolBar.add(squareCloseButton);
//---- circleCloseButton ---- //---- circleCloseButton ----
circleCloseButton.setText("circle"); circleCloseButton.setText("circle");
circleCloseButton.putClientProperty("FlatLaf.styleClass", "small"); circleCloseButton.putClientProperty("FlatLaf.styleClass", "small");
circleCloseButton.setName("circleCloseButton");
circleCloseButton.addActionListener(e -> closeButtonStyleChanged()); circleCloseButton.addActionListener(e -> closeButtonStyleChanged());
closableTabsToolBar.add(circleCloseButton); closableTabsToolBar.add(circleCloseButton);
//---- redCrossCloseButton ---- //---- redCrossCloseButton ----
redCrossCloseButton.setText("red cross"); redCrossCloseButton.setText("red cross");
redCrossCloseButton.putClientProperty("FlatLaf.styleClass", "small"); redCrossCloseButton.putClientProperty("FlatLaf.styleClass", "small");
redCrossCloseButton.setName("redCrossCloseButton");
redCrossCloseButton.addActionListener(e -> closeButtonStyleChanged()); redCrossCloseButton.addActionListener(e -> closeButtonStyleChanged());
closableTabsToolBar.add(redCrossCloseButton); closableTabsToolBar.add(redCrossCloseButton);
} }
panel1.add(closableTabsToolBar, "cell 0 5,alignx right,growx 0"); panel1.add(closableTabsToolBar, "cell 0 5,alignx right,growx 0");
//======== closableTabsTabbedPane ========
{
closableTabsTabbedPane.setName("closableTabsTabbedPane");
}
panel1.add(closableTabsTabbedPane, "cell 0 6"); panel1.add(closableTabsTabbedPane, "cell 0 6");
//---- tabAreaComponentsLabel ---- //---- tabAreaComponentsLabel ----
tabAreaComponentsLabel.setText("Custom tab area components"); tabAreaComponentsLabel.setText("Custom tab area components");
tabAreaComponentsLabel.putClientProperty("FlatLaf.styleClass", "h3"); tabAreaComponentsLabel.putClientProperty("FlatLaf.styleClass", "h3");
tabAreaComponentsLabel.setName("tabAreaComponentsLabel");
panel1.add(tabAreaComponentsLabel, "cell 0 7"); panel1.add(tabAreaComponentsLabel, "cell 0 7");
//======== tabAreaComponentsToolBar ======== //======== tabAreaComponentsToolBar ========
{ {
tabAreaComponentsToolBar.setFloatable(false); tabAreaComponentsToolBar.setFloatable(false);
tabAreaComponentsToolBar.setBorder(BorderFactory.createEmptyBorder()); tabAreaComponentsToolBar.setBorder(BorderFactory.createEmptyBorder());
tabAreaComponentsToolBar.setName("tabAreaComponentsToolBar");
//---- leadingComponentButton ---- //---- leadingComponentButton ----
leadingComponentButton.setText("leading"); leadingComponentButton.setText("leading");
leadingComponentButton.setSelected(true); leadingComponentButton.setSelected(true);
leadingComponentButton.putClientProperty("FlatLaf.styleClass", "small"); leadingComponentButton.putClientProperty("FlatLaf.styleClass", "small");
leadingComponentButton.setName("leadingComponentButton");
leadingComponentButton.addActionListener(e -> customComponentsChanged()); leadingComponentButton.addActionListener(e -> customComponentsChanged());
tabAreaComponentsToolBar.add(leadingComponentButton); tabAreaComponentsToolBar.add(leadingComponentButton);
@@ -583,16 +627,23 @@ class TabsPanel
trailingComponentButton.setText("trailing"); trailingComponentButton.setText("trailing");
trailingComponentButton.setSelected(true); trailingComponentButton.setSelected(true);
trailingComponentButton.putClientProperty("FlatLaf.styleClass", "small"); trailingComponentButton.putClientProperty("FlatLaf.styleClass", "small");
trailingComponentButton.setName("trailingComponentButton");
trailingComponentButton.addActionListener(e -> customComponentsChanged()); trailingComponentButton.addActionListener(e -> customComponentsChanged());
tabAreaComponentsToolBar.add(trailingComponentButton); tabAreaComponentsToolBar.add(trailingComponentButton);
} }
panel1.add(tabAreaComponentsToolBar, "cell 0 7,alignx right,growx 0"); panel1.add(tabAreaComponentsToolBar, "cell 0 7,alignx right,growx 0");
//======== customComponentsTabbedPane ========
{
customComponentsTabbedPane.setName("customComponentsTabbedPane");
}
panel1.add(customComponentsTabbedPane, "cell 0 8"); panel1.add(customComponentsTabbedPane, "cell 0 8");
} }
add(panel1, "cell 0 0"); add(panel1, "cell 0 0");
//======== panel2 ======== //======== panel2 ========
{ {
panel2.setName("panel2");
panel2.setLayout(new MigLayout( panel2.setLayout(new MigLayout(
"insets 0,hidemode 3", "insets 0,hidemode 3",
// columns // columns
@@ -614,37 +665,82 @@ class TabsPanel
//---- tabIconPlacementLabel ---- //---- tabIconPlacementLabel ----
tabIconPlacementLabel.setText("Tab icon placement"); tabIconPlacementLabel.setText("Tab icon placement");
tabIconPlacementLabel.putClientProperty("FlatLaf.styleClass", "h3"); tabIconPlacementLabel.putClientProperty("FlatLaf.styleClass", "h3");
tabIconPlacementLabel.setName("tabIconPlacementLabel");
panel2.add(tabIconPlacementLabel, "cell 0 0"); panel2.add(tabIconPlacementLabel, "cell 0 0");
//---- tabIconPlacementNodeLabel ---- //---- tabIconPlacementNodeLabel ----
tabIconPlacementNodeLabel.setText("(top/bottom/leading/trailing)"); tabIconPlacementNodeLabel.setText("(top/bottom/leading/trailing)");
tabIconPlacementNodeLabel.setEnabled(false); tabIconPlacementNodeLabel.setEnabled(false);
tabIconPlacementNodeLabel.putClientProperty("FlatLaf.styleClass", "small"); tabIconPlacementNodeLabel.putClientProperty("FlatLaf.styleClass", "small");
tabIconPlacementNodeLabel.setName("tabIconPlacementNodeLabel");
panel2.add(tabIconPlacementNodeLabel, "cell 0 1"); panel2.add(tabIconPlacementNodeLabel, "cell 0 1");
//======== iconTopTabbedPane ========
{
iconTopTabbedPane.setName("iconTopTabbedPane");
}
panel2.add(iconTopTabbedPane, "cell 0 2"); panel2.add(iconTopTabbedPane, "cell 0 2");
//======== iconBottomTabbedPane ========
{
iconBottomTabbedPane.setName("iconBottomTabbedPane");
}
panel2.add(iconBottomTabbedPane, "cell 0 3"); panel2.add(iconBottomTabbedPane, "cell 0 3");
//======== iconLeadingTabbedPane ========
{
iconLeadingTabbedPane.setName("iconLeadingTabbedPane");
}
panel2.add(iconLeadingTabbedPane, "cell 0 4"); panel2.add(iconLeadingTabbedPane, "cell 0 4");
//======== iconTrailingTabbedPane ========
{
iconTrailingTabbedPane.setName("iconTrailingTabbedPane");
}
panel2.add(iconTrailingTabbedPane, "cell 0 5"); panel2.add(iconTrailingTabbedPane, "cell 0 5");
//---- tabAreaAlignmentLabel ---- //---- tabAreaAlignmentLabel ----
tabAreaAlignmentLabel.setText("Tab area alignment"); tabAreaAlignmentLabel.setText("Tab area alignment");
tabAreaAlignmentLabel.putClientProperty("FlatLaf.styleClass", "h3"); tabAreaAlignmentLabel.putClientProperty("FlatLaf.styleClass", "h3");
tabAreaAlignmentLabel.setName("tabAreaAlignmentLabel");
panel2.add(tabAreaAlignmentLabel, "cell 0 6"); panel2.add(tabAreaAlignmentLabel, "cell 0 6");
//---- tabAreaAlignmentNoteLabel ---- //---- tabAreaAlignmentNoteLabel ----
tabAreaAlignmentNoteLabel.setText("(leading/center/trailing/fill)"); tabAreaAlignmentNoteLabel.setText("(leading/center/trailing/fill)");
tabAreaAlignmentNoteLabel.setEnabled(false); tabAreaAlignmentNoteLabel.setEnabled(false);
tabAreaAlignmentNoteLabel.putClientProperty("FlatLaf.styleClass", "small"); tabAreaAlignmentNoteLabel.putClientProperty("FlatLaf.styleClass", "small");
tabAreaAlignmentNoteLabel.setName("tabAreaAlignmentNoteLabel");
panel2.add(tabAreaAlignmentNoteLabel, "cell 0 7"); panel2.add(tabAreaAlignmentNoteLabel, "cell 0 7");
//======== alignLeadingTabbedPane ========
{
alignLeadingTabbedPane.setName("alignLeadingTabbedPane");
}
panel2.add(alignLeadingTabbedPane, "cell 0 8"); panel2.add(alignLeadingTabbedPane, "cell 0 8");
//======== alignCenterTabbedPane ========
{
alignCenterTabbedPane.setName("alignCenterTabbedPane");
}
panel2.add(alignCenterTabbedPane, "cell 0 9"); panel2.add(alignCenterTabbedPane, "cell 0 9");
//======== alignTrailingTabbedPane ========
{
alignTrailingTabbedPane.setName("alignTrailingTabbedPane");
}
panel2.add(alignTrailingTabbedPane, "cell 0 10"); panel2.add(alignTrailingTabbedPane, "cell 0 10");
//======== alignFillTabbedPane ========
{
alignFillTabbedPane.setName("alignFillTabbedPane");
}
panel2.add(alignFillTabbedPane, "cell 0 11"); panel2.add(alignFillTabbedPane, "cell 0 11");
} }
add(panel2, "cell 1 0,growy"); add(panel2, "cell 1 0,growy");
//======== panel3 ======== //======== panel3 ========
{ {
panel3.setName("panel3");
panel3.setLayout(new MigLayout( panel3.setLayout(new MigLayout(
"insets 0,hidemode 3", "insets 0,hidemode 3",
// columns // columns
@@ -664,31 +760,61 @@ class TabsPanel
//---- tabWidthModeLabel ---- //---- tabWidthModeLabel ----
tabWidthModeLabel.setText("Tab width mode"); tabWidthModeLabel.setText("Tab width mode");
tabWidthModeLabel.putClientProperty("FlatLaf.styleClass", "h3"); tabWidthModeLabel.putClientProperty("FlatLaf.styleClass", "h3");
tabWidthModeLabel.setName("tabWidthModeLabel");
panel3.add(tabWidthModeLabel, "cell 0 0"); panel3.add(tabWidthModeLabel, "cell 0 0");
//---- tabWidthModeNoteLabel ---- //---- tabWidthModeNoteLabel ----
tabWidthModeNoteLabel.setText("(preferred/equal/compact)"); tabWidthModeNoteLabel.setText("(preferred/equal/compact)");
tabWidthModeNoteLabel.setEnabled(false); tabWidthModeNoteLabel.setEnabled(false);
tabWidthModeNoteLabel.putClientProperty("FlatLaf.styleClass", "small"); tabWidthModeNoteLabel.putClientProperty("FlatLaf.styleClass", "small");
tabWidthModeNoteLabel.setName("tabWidthModeNoteLabel");
panel3.add(tabWidthModeNoteLabel, "cell 0 1"); panel3.add(tabWidthModeNoteLabel, "cell 0 1");
//======== widthPreferredTabbedPane ========
{
widthPreferredTabbedPane.setName("widthPreferredTabbedPane");
}
panel3.add(widthPreferredTabbedPane, "cell 0 2"); panel3.add(widthPreferredTabbedPane, "cell 0 2");
//======== widthEqualTabbedPane ========
{
widthEqualTabbedPane.setName("widthEqualTabbedPane");
}
panel3.add(widthEqualTabbedPane, "cell 0 3"); panel3.add(widthEqualTabbedPane, "cell 0 3");
//======== widthCompactTabbedPane ========
{
widthCompactTabbedPane.setName("widthCompactTabbedPane");
}
panel3.add(widthCompactTabbedPane, "cell 0 4"); panel3.add(widthCompactTabbedPane, "cell 0 4");
//---- minMaxTabWidthLabel ---- //---- minMaxTabWidthLabel ----
minMaxTabWidthLabel.setText("Minimum/maximum tab width"); minMaxTabWidthLabel.setText("Minimum/maximum tab width");
minMaxTabWidthLabel.putClientProperty("FlatLaf.styleClass", "h3"); minMaxTabWidthLabel.putClientProperty("FlatLaf.styleClass", "h3");
minMaxTabWidthLabel.setName("minMaxTabWidthLabel");
panel3.add(minMaxTabWidthLabel, "cell 0 5"); panel3.add(minMaxTabWidthLabel, "cell 0 5");
//======== minimumTabWidthTabbedPane ========
{
minimumTabWidthTabbedPane.setName("minimumTabWidthTabbedPane");
}
panel3.add(minimumTabWidthTabbedPane, "cell 0 6"); panel3.add(minimumTabWidthTabbedPane, "cell 0 6");
//======== maximumTabWidthTabbedPane ========
{
maximumTabWidthTabbedPane.setName("maximumTabWidthTabbedPane");
}
panel3.add(maximumTabWidthTabbedPane, "cell 0 7"); panel3.add(maximumTabWidthTabbedPane, "cell 0 7");
//---- tabAlignmentLabel ---- //---- tabAlignmentLabel ----
tabAlignmentLabel.setText("Tab title alignment"); tabAlignmentLabel.setText("Tab title alignment");
tabAlignmentLabel.putClientProperty("FlatLaf.styleClass", "h3"); tabAlignmentLabel.putClientProperty("FlatLaf.styleClass", "h3");
tabAlignmentLabel.setName("tabAlignmentLabel");
panel3.add(tabAlignmentLabel, "cell 0 8"); panel3.add(tabAlignmentLabel, "cell 0 8");
//======== panel5 ======== //======== panel5 ========
{ {
panel5.setName("panel5");
panel5.setLayout(new MigLayout( panel5.setLayout(new MigLayout(
"insets 0,hidemode 3", "insets 0,hidemode 3",
// columns // columns
@@ -704,30 +830,52 @@ class TabsPanel
tabAlignmentNoteLabel.setText("(leading/center/trailing)"); tabAlignmentNoteLabel.setText("(leading/center/trailing)");
tabAlignmentNoteLabel.setEnabled(false); tabAlignmentNoteLabel.setEnabled(false);
tabAlignmentNoteLabel.putClientProperty("FlatLaf.styleClass", "small"); tabAlignmentNoteLabel.putClientProperty("FlatLaf.styleClass", "small");
tabAlignmentNoteLabel.setName("tabAlignmentNoteLabel");
panel5.add(tabAlignmentNoteLabel, "cell 0 0"); panel5.add(tabAlignmentNoteLabel, "cell 0 0");
//---- tabAlignmentNoteLabel2 ---- //---- tabAlignmentNoteLabel2 ----
tabAlignmentNoteLabel2.setText("(trailing)"); tabAlignmentNoteLabel2.setText("(trailing)");
tabAlignmentNoteLabel2.setEnabled(false); tabAlignmentNoteLabel2.setEnabled(false);
tabAlignmentNoteLabel2.putClientProperty("FlatLaf.styleClass", "small"); tabAlignmentNoteLabel2.putClientProperty("FlatLaf.styleClass", "small");
tabAlignmentNoteLabel2.setName("tabAlignmentNoteLabel2");
panel5.add(tabAlignmentNoteLabel2, "cell 1 0,alignx right,growx 0"); panel5.add(tabAlignmentNoteLabel2, "cell 1 0,alignx right,growx 0");
//======== tabAlignLeadingTabbedPane ========
{
tabAlignLeadingTabbedPane.setName("tabAlignLeadingTabbedPane");
}
panel5.add(tabAlignLeadingTabbedPane, "cell 0 1"); panel5.add(tabAlignLeadingTabbedPane, "cell 0 1");
//======== tabAlignVerticalTabbedPane ======== //======== tabAlignVerticalTabbedPane ========
{ {
tabAlignVerticalTabbedPane.setTabPlacement(SwingConstants.LEFT); tabAlignVerticalTabbedPane.setTabPlacement(SwingConstants.LEFT);
tabAlignVerticalTabbedPane.setName("tabAlignVerticalTabbedPane");
} }
panel5.add(tabAlignVerticalTabbedPane, "cell 1 1 1 3,growy"); panel5.add(tabAlignVerticalTabbedPane, "cell 1 1 1 3,growy");
//======== tabAlignCenterTabbedPane ========
{
tabAlignCenterTabbedPane.setName("tabAlignCenterTabbedPane");
}
panel5.add(tabAlignCenterTabbedPane, "cell 0 2"); panel5.add(tabAlignCenterTabbedPane, "cell 0 2");
//======== tabAlignTrailingTabbedPane ========
{
tabAlignTrailingTabbedPane.setName("tabAlignTrailingTabbedPane");
}
panel5.add(tabAlignTrailingTabbedPane, "cell 0 3"); panel5.add(tabAlignTrailingTabbedPane, "cell 0 3");
} }
panel3.add(panel5, "cell 0 9"); panel3.add(panel5, "cell 0 9");
} }
add(panel3, "cell 2 0"); add(panel3, "cell 2 0");
//---- separator2 ----
separator2.setName("separator2");
add(separator2, "cell 0 1 3 1"); add(separator2, "cell 0 1 3 1");
//======== panel4 ======== //======== panel4 ========
{ {
panel4.setName("panel4");
panel4.setLayout(new MigLayout( panel4.setLayout(new MigLayout(
"insets 0,hidemode 3", "insets 0,hidemode 3",
// columns // columns
@@ -742,29 +890,34 @@ class TabsPanel
//---- scrollButtonsPolicyLabel ---- //---- scrollButtonsPolicyLabel ----
scrollButtonsPolicyLabel.setText("Scroll buttons policy:"); scrollButtonsPolicyLabel.setText("Scroll buttons policy:");
scrollButtonsPolicyLabel.setName("scrollButtonsPolicyLabel");
panel4.add(scrollButtonsPolicyLabel, "cell 0 0"); panel4.add(scrollButtonsPolicyLabel, "cell 0 0");
//======== scrollButtonsPolicyToolBar ======== //======== scrollButtonsPolicyToolBar ========
{ {
scrollButtonsPolicyToolBar.setFloatable(false); scrollButtonsPolicyToolBar.setFloatable(false);
scrollButtonsPolicyToolBar.setBorder(BorderFactory.createEmptyBorder()); scrollButtonsPolicyToolBar.setBorder(BorderFactory.createEmptyBorder());
scrollButtonsPolicyToolBar.setName("scrollButtonsPolicyToolBar");
//---- scrollAsNeededSingleButton ---- //---- scrollAsNeededSingleButton ----
scrollAsNeededSingleButton.setText("asNeededSingle"); scrollAsNeededSingleButton.setText("asNeededSingle");
scrollAsNeededSingleButton.setSelected(true); scrollAsNeededSingleButton.setSelected(true);
scrollAsNeededSingleButton.putClientProperty("FlatLaf.styleClass", "small"); scrollAsNeededSingleButton.putClientProperty("FlatLaf.styleClass", "small");
scrollAsNeededSingleButton.setName("scrollAsNeededSingleButton");
scrollAsNeededSingleButton.addActionListener(e -> scrollButtonsPolicyChanged()); scrollAsNeededSingleButton.addActionListener(e -> scrollButtonsPolicyChanged());
scrollButtonsPolicyToolBar.add(scrollAsNeededSingleButton); scrollButtonsPolicyToolBar.add(scrollAsNeededSingleButton);
//---- scrollAsNeededButton ---- //---- scrollAsNeededButton ----
scrollAsNeededButton.setText("asNeeded"); scrollAsNeededButton.setText("asNeeded");
scrollAsNeededButton.putClientProperty("FlatLaf.styleClass", "small"); scrollAsNeededButton.putClientProperty("FlatLaf.styleClass", "small");
scrollAsNeededButton.setName("scrollAsNeededButton");
scrollAsNeededButton.addActionListener(e -> scrollButtonsPolicyChanged()); scrollAsNeededButton.addActionListener(e -> scrollButtonsPolicyChanged());
scrollButtonsPolicyToolBar.add(scrollAsNeededButton); scrollButtonsPolicyToolBar.add(scrollAsNeededButton);
//---- scrollNeverButton ---- //---- scrollNeverButton ----
scrollNeverButton.setText("never"); scrollNeverButton.setText("never");
scrollNeverButton.putClientProperty("FlatLaf.styleClass", "small"); scrollNeverButton.putClientProperty("FlatLaf.styleClass", "small");
scrollNeverButton.setName("scrollNeverButton");
scrollNeverButton.addActionListener(e -> scrollButtonsPolicyChanged()); scrollNeverButton.addActionListener(e -> scrollButtonsPolicyChanged());
scrollButtonsPolicyToolBar.add(scrollNeverButton); scrollButtonsPolicyToolBar.add(scrollNeverButton);
} }
@@ -772,23 +925,27 @@ class TabsPanel
//---- scrollButtonsPlacementLabel ---- //---- scrollButtonsPlacementLabel ----
scrollButtonsPlacementLabel.setText("Scroll buttons placement:"); scrollButtonsPlacementLabel.setText("Scroll buttons placement:");
scrollButtonsPlacementLabel.setName("scrollButtonsPlacementLabel");
panel4.add(scrollButtonsPlacementLabel, "cell 2 0"); panel4.add(scrollButtonsPlacementLabel, "cell 2 0");
//======== scrollButtonsPlacementToolBar ======== //======== scrollButtonsPlacementToolBar ========
{ {
scrollButtonsPlacementToolBar.setFloatable(false); scrollButtonsPlacementToolBar.setFloatable(false);
scrollButtonsPlacementToolBar.setBorder(BorderFactory.createEmptyBorder()); scrollButtonsPlacementToolBar.setBorder(BorderFactory.createEmptyBorder());
scrollButtonsPlacementToolBar.setName("scrollButtonsPlacementToolBar");
//---- scrollBothButton ---- //---- scrollBothButton ----
scrollBothButton.setText("both"); scrollBothButton.setText("both");
scrollBothButton.setSelected(true); scrollBothButton.setSelected(true);
scrollBothButton.putClientProperty("FlatLaf.styleClass", "small"); scrollBothButton.putClientProperty("FlatLaf.styleClass", "small");
scrollBothButton.setName("scrollBothButton");
scrollBothButton.addActionListener(e -> scrollButtonsPlacementChanged()); scrollBothButton.addActionListener(e -> scrollButtonsPlacementChanged());
scrollButtonsPlacementToolBar.add(scrollBothButton); scrollButtonsPlacementToolBar.add(scrollBothButton);
//---- scrollTrailingButton ---- //---- scrollTrailingButton ----
scrollTrailingButton.setText("trailing"); scrollTrailingButton.setText("trailing");
scrollTrailingButton.putClientProperty("FlatLaf.styleClass", "small"); scrollTrailingButton.putClientProperty("FlatLaf.styleClass", "small");
scrollTrailingButton.setName("scrollTrailingButton");
scrollTrailingButton.addActionListener(e -> scrollButtonsPlacementChanged()); scrollTrailingButton.addActionListener(e -> scrollButtonsPlacementChanged());
scrollButtonsPlacementToolBar.add(scrollTrailingButton); scrollButtonsPlacementToolBar.add(scrollTrailingButton);
} }
@@ -796,28 +953,33 @@ class TabsPanel
//---- showTabSeparatorsCheckBox ---- //---- showTabSeparatorsCheckBox ----
showTabSeparatorsCheckBox.setText("Show tab separators"); showTabSeparatorsCheckBox.setText("Show tab separators");
showTabSeparatorsCheckBox.setName("showTabSeparatorsCheckBox");
showTabSeparatorsCheckBox.addActionListener(e -> showTabSeparatorsChanged()); showTabSeparatorsCheckBox.addActionListener(e -> showTabSeparatorsChanged());
panel4.add(showTabSeparatorsCheckBox, "cell 4 0"); panel4.add(showTabSeparatorsCheckBox, "cell 4 0");
//---- tabsPopupPolicyLabel ---- //---- tabsPopupPolicyLabel ----
tabsPopupPolicyLabel.setText("Tabs popup policy:"); tabsPopupPolicyLabel.setText("Tabs popup policy:");
tabsPopupPolicyLabel.setName("tabsPopupPolicyLabel");
panel4.add(tabsPopupPolicyLabel, "cell 0 1"); panel4.add(tabsPopupPolicyLabel, "cell 0 1");
//======== tabsPopupPolicyToolBar ======== //======== tabsPopupPolicyToolBar ========
{ {
tabsPopupPolicyToolBar.setFloatable(false); tabsPopupPolicyToolBar.setFloatable(false);
tabsPopupPolicyToolBar.setBorder(BorderFactory.createEmptyBorder()); tabsPopupPolicyToolBar.setBorder(BorderFactory.createEmptyBorder());
tabsPopupPolicyToolBar.setName("tabsPopupPolicyToolBar");
//---- popupAsNeededButton ---- //---- popupAsNeededButton ----
popupAsNeededButton.setText("asNeeded"); popupAsNeededButton.setText("asNeeded");
popupAsNeededButton.setSelected(true); popupAsNeededButton.setSelected(true);
popupAsNeededButton.putClientProperty("FlatLaf.styleClass", "small"); popupAsNeededButton.putClientProperty("FlatLaf.styleClass", "small");
popupAsNeededButton.setName("popupAsNeededButton");
popupAsNeededButton.addActionListener(e -> tabsPopupPolicyChanged()); popupAsNeededButton.addActionListener(e -> tabsPopupPolicyChanged());
tabsPopupPolicyToolBar.add(popupAsNeededButton); tabsPopupPolicyToolBar.add(popupAsNeededButton);
//---- popupNeverButton ---- //---- popupNeverButton ----
popupNeverButton.setText("never"); popupNeverButton.setText("never");
popupNeverButton.putClientProperty("FlatLaf.styleClass", "small"); popupNeverButton.putClientProperty("FlatLaf.styleClass", "small");
popupNeverButton.setName("popupNeverButton");
popupNeverButton.addActionListener(e -> tabsPopupPolicyChanged()); popupNeverButton.addActionListener(e -> tabsPopupPolicyChanged());
tabsPopupPolicyToolBar.add(popupNeverButton); tabsPopupPolicyToolBar.add(popupNeverButton);
} }
@@ -825,22 +987,26 @@ class TabsPanel
//---- tabTypeLabel ---- //---- tabTypeLabel ----
tabTypeLabel.setText("Tab type:"); tabTypeLabel.setText("Tab type:");
tabTypeLabel.setName("tabTypeLabel");
panel4.add(tabTypeLabel, "cell 2 1"); panel4.add(tabTypeLabel, "cell 2 1");
//======== tabTypeToolBar ======== //======== tabTypeToolBar ========
{ {
tabTypeToolBar.setFloatable(false); tabTypeToolBar.setFloatable(false);
tabTypeToolBar.setName("tabTypeToolBar");
//---- underlinedTabTypeButton ---- //---- underlinedTabTypeButton ----
underlinedTabTypeButton.setText("underlined"); underlinedTabTypeButton.setText("underlined");
underlinedTabTypeButton.setSelected(true); underlinedTabTypeButton.setSelected(true);
underlinedTabTypeButton.putClientProperty("FlatLaf.styleClass", "small"); underlinedTabTypeButton.putClientProperty("FlatLaf.styleClass", "small");
underlinedTabTypeButton.setName("underlinedTabTypeButton");
underlinedTabTypeButton.addActionListener(e -> tabTypeChanged()); underlinedTabTypeButton.addActionListener(e -> tabTypeChanged());
tabTypeToolBar.add(underlinedTabTypeButton); tabTypeToolBar.add(underlinedTabTypeButton);
//---- cardTabTypeButton ---- //---- cardTabTypeButton ----
cardTabTypeButton.setText("card"); cardTabTypeButton.setText("card");
cardTabTypeButton.putClientProperty("FlatLaf.styleClass", "small"); cardTabTypeButton.putClientProperty("FlatLaf.styleClass", "small");
cardTabTypeButton.setName("cardTabTypeButton");
cardTabTypeButton.addActionListener(e -> tabTypeChanged()); cardTabTypeButton.addActionListener(e -> tabTypeChanged());
tabTypeToolBar.add(cardTabTypeButton); tabTypeToolBar.add(cardTabTypeButton);
} }

View File

@@ -1,8 +1,9 @@
JFDML JFormDesigner: "7.0.5.0.404" Java: "17" encoding: "UTF-8" JFDML JFormDesigner: "7.0.5.0.382" Java: "16" encoding: "UTF-8"
new FormModel { new FormModel {
contentType: "form/swing" contentType: "form/swing"
root: new FormRoot { root: new FormRoot {
"$setComponentNames": true
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "insets dialog,hidemode 3" "$layoutConstraints": "insets dialog,hidemode 3"
"$columnConstraints": "[grow,fill]para[fill]para[fill]" "$columnConstraints": "[grow,fill]para[fill]para[fill]"

View File

@@ -144,13 +144,13 @@ public class IJThemesPanel
// add core themes at beginning // add core themes at beginning
categories.put( themes.size(), "Core Themes" ); categories.put( themes.size(), "Core Themes" );
if( showLight ) if( showLight )
themes.add( new IJThemeInfo( "FlatLaf Light", null, false, null, null, null, null, null, FlatLightLaf.class.getName() ) ); themes.add( new IJThemeInfo( "Flat Light", null, false, null, null, null, null, null, FlatLightLaf.class.getName() ) );
if( showDark ) if( showDark )
themes.add( new IJThemeInfo( "FlatLaf Dark", null, true, null, null, null, null, null, FlatDarkLaf.class.getName() ) ); themes.add( new IJThemeInfo( "Flat Dark", null, true, null, null, null, null, null, FlatDarkLaf.class.getName() ) );
if( showLight ) if( showLight )
themes.add( new IJThemeInfo( "FlatLaf IntelliJ", null, false, null, null, null, null, null, FlatIntelliJLaf.class.getName() ) ); themes.add( new IJThemeInfo( "Flat IntelliJ", null, false, null, null, null, null, null, FlatIntelliJLaf.class.getName() ) );
if( showDark ) if( showDark )
themes.add( new IJThemeInfo( "FlatLaf Darcula", null, true, null, null, null, null, null, FlatDarculaLaf.class.getName() ) ); themes.add( new IJThemeInfo( "Flat Darcula", null, true, null, null, null, null, null, FlatDarculaLaf.class.getName() ) );
// add themes from directory // add themes from directory
categories.put( themes.size(), "Current Directory" ); categories.put( themes.size(), "Current Directory" );

View File

@@ -1,9 +0,0 @@
<!-- Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -->
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="matchCase">
<g id="Cc">
<path d="M8.77476 11.8297C8.32279 12.2816 7.83717 12.623 7.31789 12.8538C6.80823 13.075 6.19279 13.1856 5.47157 13.1856C4.17337 13.1856 3.10116 12.7144 2.25492 11.772C1.41831 10.8296 1 9.5939 1 8.06491V7.93509C1 6.4061 1.42792 5.17041 2.28377 4.22802C3.13962 3.27601 4.23588 2.8 5.57254 2.8C6.81304 2.8 7.8564 3.18465 8.70263 3.95395L7.72178 5.64161C7.01979 5.0454 6.3178 4.7473 5.61581 4.7473C4.89459 4.7473 4.30319 5.03098 3.84161 5.59834C3.38964 6.1657 3.16366 6.935 3.16366 7.90624V8.05049C3.16366 9.04096 3.38964 9.81988 3.84161 10.3872C4.29357 10.9546 4.88978 11.2383 5.63024 11.2383C6.35146 11.2383 7.06787 10.9306 7.77947 10.3151L8.77476 11.8297Z" fill="#7F8B91" fill-opacity="0.5"/>
<path d="M15.6304 12.1182C15.2842 12.474 14.914 12.7432 14.5197 12.9259C14.135 13.1086 13.6542 13.2 13.0773 13.2C12.0483 13.2 11.2021 12.8346 10.5386 12.1037C9.87504 11.3633 9.54327 10.4209 9.54327 9.27656V9.11789C9.54327 7.97356 9.87984 7.03116 10.553 6.29071C11.2261 5.55025 12.0772 5.18003 13.1061 5.18003C14.135 5.18003 14.962 5.50217 15.5871 6.14646L14.6639 7.67545C14.1927 7.22349 13.6927 6.9975 13.1638 6.9975C12.7022 6.9975 12.3224 7.18983 12.0243 7.57448C11.7262 7.95913 11.5771 8.46398 11.5771 9.08904V9.26214C11.5771 9.90643 11.7262 10.4209 12.0243 10.8055C12.332 11.1902 12.7359 11.3825 13.2359 11.3825C13.736 11.3825 14.236 11.1565 14.7361 10.7046L15.6304 12.1182Z" fill="#7F8B91" fill-opacity="0.5"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -1,9 +0,0 @@
<!-- Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -->
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="matchCaseHovered">
<g id="Cc">
<path d="M8.77476 11.8297C8.32279 12.2816 7.83717 12.623 7.31789 12.8538C6.80823 13.075 6.19279 13.1856 5.47157 13.1856C4.17337 13.1856 3.10116 12.7144 2.25492 11.772C1.41831 10.8296 1 9.5939 1 8.06491V7.93509C1 6.4061 1.42792 5.17041 2.28377 4.22802C3.13962 3.27601 4.23588 2.8 5.57254 2.8C6.81304 2.8 7.8564 3.18465 8.70263 3.95395L7.72178 5.64161C7.01979 5.0454 6.3178 4.7473 5.61581 4.7473C4.89459 4.7473 4.30319 5.03098 3.84161 5.59834C3.38964 6.1657 3.16366 6.935 3.16366 7.90624V8.05049C3.16366 9.04096 3.38964 9.81988 3.84161 10.3872C4.29357 10.9546 4.88978 11.2383 5.63024 11.2383C6.35146 11.2383 7.06787 10.9306 7.77947 10.3151L8.77476 11.8297Z" fill="#7F8B91" fill-opacity="0.9"/>
<path d="M15.6304 12.1182C15.2842 12.474 14.914 12.7432 14.5197 12.9259C14.135 13.1086 13.6542 13.2 13.0773 13.2C12.0483 13.2 11.2021 12.8346 10.5386 12.1037C9.87504 11.3633 9.54327 10.4209 9.54327 9.27656V9.11789C9.54327 7.97356 9.87984 7.03116 10.553 6.29071C11.2261 5.55025 12.0772 5.18003 13.1061 5.18003C14.135 5.18003 14.962 5.50217 15.5871 6.14646L14.6639 7.67545C14.1927 7.22349 13.6927 6.9975 13.1638 6.9975C12.7022 6.9975 12.3224 7.18983 12.0243 7.57448C11.7262 7.95913 11.5771 8.46398 11.5771 9.08904V9.26214C11.5771 9.90643 11.7262 10.4209 12.0243 10.8055C12.332 11.1902 12.7359 11.3825 13.2359 11.3825C13.736 11.3825 14.236 11.1565 14.7361 10.7046L15.6304 12.1182Z" fill="#7F8B91" fill-opacity="0.9"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -1,9 +0,0 @@
<!-- Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -->
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="matchCaseSelected">
<g id="Cc">
<path d="M8.77476 11.8297C8.32279 12.2816 7.83717 12.623 7.31789 12.8538C6.80823 13.075 6.19279 13.1856 5.47157 13.1856C4.17337 13.1856 3.10116 12.7144 2.25492 11.772C1.41831 10.8296 1 9.5939 1 8.06491V7.93509C1 6.4061 1.42792 5.17041 2.28377 4.22802C3.13962 3.276 4.23588 2.8 5.57254 2.8C6.81304 2.8 7.8564 3.18465 8.70263 3.95395L7.72178 5.64161C7.01979 5.0454 6.3178 4.74729 5.61581 4.74729C4.89459 4.74729 4.30319 5.03097 3.84161 5.59833C3.38964 6.16569 3.16366 6.935 3.16366 7.90624V8.05048C3.16366 9.04096 3.38964 9.81988 3.84161 10.3872C4.29357 10.9546 4.88978 11.2383 5.63024 11.2383C6.35146 11.2383 7.06787 10.9306 7.77947 10.3151L8.77476 11.8297Z" fill="#40B6E0"/>
<path d="M15.6304 12.1182C15.2842 12.474 14.914 12.7432 14.5197 12.9259C14.135 13.1086 13.6542 13.2 13.0773 13.2C12.0483 13.2 11.2021 12.8346 10.5386 12.1037C9.87504 11.3633 9.54327 10.4209 9.54327 9.27656V9.11789C9.54327 7.97355 9.87984 7.03116 10.553 6.29071C11.2261 5.55025 12.0772 5.18003 13.1061 5.18003C14.135 5.18003 14.962 5.50217 15.5871 6.14646L14.6639 7.67545C14.1927 7.22348 13.6927 6.9975 13.1638 6.9975C12.7022 6.9975 12.3224 7.18983 12.0243 7.57448C11.7262 7.95913 11.5771 8.46398 11.5771 9.08904V9.26213C11.5771 9.90643 11.7262 10.4209 12.0243 10.8055C12.332 11.1902 12.7359 11.3825 13.2359 11.3825C13.736 11.3825 14.236 11.1565 14.7361 10.7046L15.6304 12.1182Z" fill="#40B6E0"/>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -1,7 +0,0 @@
<!-- Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -->
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<g fill="none" fill-opacity=".5" fill-rule="evenodd">
<rect width="2" height="2" x="3" y="11" fill="#7F8B91"/>
<path fill="#7F8B91" d="M9.8339746,5.61435935 L12.0980762,4.30717968 L12.8980762,5.69282032 L10.6339746,7 L12.8980762,8.30717968 L12.0980762,9.69282032 L9.8339746,8.38564065 L9.8339746,11 L8.2339746,11 L8.2339746,8.38564065 L5.96987298,9.69282032 L5.16987298,8.30717968 L7.4339746,7 L5.16987298,5.69282032 L5.96987298,4.30717968 L8.2339746,5.61435935 L8.2339746,3 L9.8339746,3 L9.8339746,5.61435935 Z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 770 B

View File

@@ -1,7 +0,0 @@
<!-- Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -->
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<g fill="none" fill-opacity=".9" fill-rule="evenodd">
<rect width="2" height="2" x="3" y="11" fill="#7F8B91"/>
<path fill="#7F8B91" d="M9.8339746,5.61435935 L12.0980762,4.30717968 L12.8980762,5.69282032 L10.6339746,7 L12.8980762,8.30717968 L12.0980762,9.69282032 L9.8339746,8.38564065 L9.8339746,11 L8.2339746,11 L8.2339746,8.38564065 L5.96987298,9.69282032 L5.16987298,8.30717968 L7.4339746,7 L5.16987298,5.69282032 L5.96987298,4.30717968 L8.2339746,5.61435935 L8.2339746,3 L9.8339746,3 L9.8339746,5.61435935 Z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 770 B

View File

@@ -1,7 +0,0 @@
<!-- Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -->
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<g fill="none" fill-rule="evenodd">
<rect width="2" height="2" x="3" y="11" fill="#40B6E0"/>
<path fill="#40B6E0" d="M9.8339746,5.61435935 L12.0980762,4.30717968 L12.8980762,5.69282032 L10.6339746,7 L12.8980762,8.30717968 L12.0980762,9.69282032 L9.8339746,8.38564065 L9.8339746,11 L8.2339746,11 L8.2339746,8.38564065 L5.96987298,9.69282032 L5.16987298,8.30717968 L7.4339746,7 L5.16987298,5.69282032 L5.96987298,4.30717968 L8.2339746,5.61435935 L8.2339746,3 L9.8339746,3 L9.8339746,5.61435935 Z"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 752 B

View File

@@ -1,6 +0,0 @@
<!-- Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -->
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="words">
<path id="W" d="M14.5213 3.01418L11.6986 13H9.82624L8.01064 6.68794L6.19504 13H4.3227L1.5 3.01418H3.67021L5.3156 9.53901L7.14539 3H8.93262L10.7482 9.53901L12.4078 3.01418H14.5213Z" fill="#7F8B91" fill-opacity="0.5"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 487 B

View File

@@ -1,6 +0,0 @@
<!-- Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -->
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="wordsHovered">
<path id="W" d="M14.5213 3.01418L11.6986 13H9.82624L8.01064 6.68794L6.19504 13H4.3227L1.5 3.01418H3.67021L5.3156 9.53901L7.14539 3H8.93262L10.7482 9.53901L12.4078 3.01418H14.5213Z" fill="#7F8B91" fill-opacity="0.9"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 494 B

View File

@@ -1,6 +0,0 @@
<!-- Copyright 2000-2021 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. -->
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<g id="wordsSelected">
<path id="W" d="M14.5213 3.01418L11.6986 13H9.82624L8.01064 6.68794L6.19504 13H4.3227L1.5 3.01418H3.67021L5.3156 9.53901L7.14539 3H8.93262L10.7482 9.53901L12.4078 3.01418H14.5213Z" fill="#40B6E0"/>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 476 B

View File

@@ -145,7 +145,7 @@
"license": "MIT", "license": "MIT",
"licenseFile": "Hiberbee.LICENSE.txt", "licenseFile": "Hiberbee.LICENSE.txt",
"sourceCodeUrl": "https://github.com/Hiberbee/code-highlight-themes", "sourceCodeUrl": "https://github.com/Hiberbee/code-highlight-themes",
"sourceCodePath": "blob/latest/src/main/resources/HiberbeeDark.theme.json" "sourceCodePath": "blob/master/src/main/resources/HiberbeeDark.theme.json"
}, },
"HighContrast.theme.json": { "HighContrast.theme.json": {
"name": "High contrast", "name": "High contrast",
@@ -184,7 +184,7 @@
"license": "MIT", "license": "MIT",
"licenseFile": "nord.LICENSE.txt", "licenseFile": "nord.LICENSE.txt",
"sourceCodeUrl": "https://github.com/arcticicestudio/nord-jetbrains", "sourceCodeUrl": "https://github.com/arcticicestudio/nord-jetbrains",
"sourceCodePath": "blob/main/src/nord.theme.json" "sourceCodePath": "blob/develop/src/nord.theme.json"
}, },
"one_dark.theme.json": { "one_dark.theme.json": {
"name": "One Dark", "name": "One Dark",

View File

@@ -22,7 +22,7 @@ plugins {
dependencies { dependencies {
implementation( project( ":flatlaf-core" ) ) implementation( project( ":flatlaf-core" ) )
implementation( "com.formdev:svgSalamander:1.1.3" ) implementation( "com.formdev:svgSalamander:1.1.2.4" )
} }
flatlafModuleInfo { flatlafModuleInfo {

View File

@@ -475,7 +475,7 @@ public class FlatInspector
appendRow( buf, "Border", toString( ((JComponent)c).getBorder(), classHierarchy ) ); appendRow( buf, "Border", toString( ((JComponent)c).getBorder(), classHierarchy ) );
appendRow( buf, "Background", toString( c.getBackground() ) + (c.isBackgroundSet() ? "" : " NOT SET") ); appendRow( buf, "Background", toString( c.getBackground() ) + (c.isBackgroundSet() ? "" : " NOT SET") );
appendRow( buf, "Foreground", toString( c.getForeground() ) + (c.isForegroundSet() ? "" : " NOT SET") ); appendRow( buf, "Foreground", toString( c.getForeground() ) + (c.isBackgroundSet() ? "" : " NOT SET") );
appendRow( buf, "Font", toString( c.getFont() ) + (c.isFontSet() ? "" : " NOT SET") ); appendRow( buf, "Font", toString( c.getFont() ) + (c.isFontSet() ? "" : " NOT SET") );
if( c instanceof JComponent ) { if( c instanceof JComponent ) {

View File

@@ -273,12 +273,10 @@ public class FlatSVGIcon
// since the input stream is already loaded and parsed, // since the input stream is already loaded and parsed,
// get diagram here and remove it from cache // get diagram here and remove it from cache
update(); update();
synchronized( FlatSVGIcon.class ) { svgCache.remove( uri );
svgCache.remove( uri );
}
} }
private static synchronized URI loadFromStream( InputStream in ) throws IOException { private static URI loadFromStream( InputStream in ) throws IOException {
try( InputStream in2 = in ) { try( InputStream in2 = in ) {
return svgUniverse.loadSVG( in2, "/flatlaf-stream-" + (streamNumber++) ); return svgUniverse.loadSVG( in2, "/flatlaf-stream-" + (streamNumber++) );
} }
@@ -477,7 +475,7 @@ public class FlatSVGIcon
loadFailed = (diagram == null); loadFailed = (diagram == null);
} }
static synchronized SVGDiagram loadSVG( URI uri ) { static SVGDiagram loadSVG( URI uri ) {
// get from our cache // get from our cache
SVGDiagram diagram = svgCache.get( uri ); SVGDiagram diagram = svgCache.get( uri );
if( diagram != null ) if( diagram != null )

View File

@@ -43,7 +43,6 @@ import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer; import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableColumnModel; import javax.swing.table.TableColumnModel;
import com.formdev.flatlaf.FlatLaf; import com.formdev.flatlaf.FlatLaf;
import com.formdev.flatlaf.extras.components.FlatTextField;
import com.formdev.flatlaf.icons.FlatAbstractIcon; import com.formdev.flatlaf.icons.FlatAbstractIcon;
import com.formdev.flatlaf.ui.FlatBorder; import com.formdev.flatlaf.ui.FlatBorder;
import com.formdev.flatlaf.ui.FlatEmptyBorder; import com.formdev.flatlaf.ui.FlatEmptyBorder;
@@ -558,7 +557,7 @@ public class FlatUIDefaultsInspector
panel = new JPanel(); panel = new JPanel();
filterPanel = new JPanel(); filterPanel = new JPanel();
flterLabel = new JLabel(); flterLabel = new JLabel();
filterField = new FlatTextField(); filterField = new JTextField();
valueTypeLabel = new JLabel(); valueTypeLabel = new JLabel();
valueTypeField = new JComboBox<>(); valueTypeField = new JComboBox<>();
scrollPane = new JScrollPane(); scrollPane = new JScrollPane();
@@ -589,8 +588,7 @@ public class FlatUIDefaultsInspector
new Insets(0, 0, 0, 10), 0, 0)); new Insets(0, 0, 0, 10), 0, 0));
//---- filterField ---- //---- filterField ----
filterField.setPlaceholderText("enter one or more filter strings, separated by space characters"); filterField.putClientProperty("JTextField.placeholderText", "enter one or more filter strings, separated by space characters");
filterField.setShowClearButton(true);
filterPanel.add(filterField, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0, filterPanel.add(filterField, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0,
GridBagConstraints.CENTER, GridBagConstraints.BOTH, GridBagConstraints.CENTER, GridBagConstraints.BOTH,
new Insets(0, 0, 0, 10), 0, 0)); new Insets(0, 0, 0, 10), 0, 0));
@@ -669,7 +667,7 @@ public class FlatUIDefaultsInspector
private JPanel panel; private JPanel panel;
private JPanel filterPanel; private JPanel filterPanel;
private JLabel flterLabel; private JLabel flterLabel;
private FlatTextField filterField; private JTextField filterField;
private JLabel valueTypeLabel; private JLabel valueTypeLabel;
private JComboBox<String> valueTypeField; private JComboBox<String> valueTypeField;
private JScrollPane scrollPane; private JScrollPane scrollPane;

View File

@@ -20,10 +20,9 @@ new FormModel {
"labelFor": new FormReference( "filterField" ) "labelFor": new FormReference( "filterField" )
"displayedMnemonic": 70 "displayedMnemonic": 70
}, new FormLayoutConstraints( class com.jformdesigner.runtime.GridBagConstraintsEx ) ) }, new FormLayoutConstraints( class com.jformdesigner.runtime.GridBagConstraintsEx ) )
add( new FormComponent( "com.formdev.flatlaf.extras.components.FlatTextField" ) { add( new FormComponent( "javax.swing.JTextField" ) {
name: "filterField" name: "filterField"
"placeholderText": "enter one or more filter strings, separated by space characters" "$client.JTextField.placeholderText": "enter one or more filter strings, separated by space characters"
"showClearButton": true
}, new FormLayoutConstraints( class com.jformdesigner.runtime.GridBagConstraintsEx ) { }, new FormLayoutConstraints( class com.jformdesigner.runtime.GridBagConstraintsEx ) {
"gridx": 1 "gridx": 1
} ) } )

Some files were not shown because too many files have changed in this diff Show More