Compare commits

..

2 Commits

259 changed files with 28244 additions and 37500 deletions

View File

@@ -19,26 +19,39 @@ jobs:
strategy:
matrix:
# test against
# - Java 8 (minimum requirement)
# - Java 1.8 (minimum requirement)
# - Java 9 (first version with JPMS)
# - Java LTS versions (11, 17, ...)
# - lastest Java version(s)
java:
- 8
- 1.8
- 9
- 11 # LTS
- 17 # LTS
- 14
- 15
steps:
- uses: actions/checkout@v2
- uses: gradle/wrapper-validation-action@v1
if: matrix.java == '8'
- name: Setup Java ${{ matrix.java }}
uses: actions/setup-java@v2
uses: actions/setup-java@v1
with:
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
run: ./gradlew build
@@ -59,18 +72,29 @@ jobs:
needs: build
if: |
github.event_name == 'push' &&
(github.ref == 'refs/heads/main' || startsWith( github.ref, 'refs/heads/develop-' )) &&
github.ref == 'refs/heads/main' &&
github.repository == 'JFormDesigner/FlatLaf'
steps:
- uses: actions/checkout@v2
- name: Setup Java 11
uses: actions/setup-java@v2
uses: actions/setup-java@v1
with:
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
run: ./gradlew publish :flatlaf-theme-editor:build -Dorg.gradle.internal.publish.checksums.insecure=true
@@ -102,11 +126,22 @@ jobs:
- uses: actions/checkout@v2
- name: Setup Java 11
uses: actions/setup-java@v2
uses: actions/setup-java@v1
with:
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
run: ./gradlew publish :flatlaf-demo:build :flatlaf-theme-editor:build -Drelease=true

View File

@@ -11,14 +11,12 @@ on:
paths:
- 'flatlaf-natives/flatlaf-natives-windows/**'
- '.github/workflows/natives.yml'
- 'gradle/wrapper/gradle-wrapper.properties'
pull_request:
branches:
- '*'
paths:
- 'flatlaf-natives/flatlaf-natives-windows/**'
- '.github/workflows/natives.yml'
- 'gradle/wrapper/gradle-wrapper.properties'
jobs:
Windows:
@@ -29,17 +27,28 @@ jobs:
- uses: gradle/wrapper-validation-action@v1
- name: Setup Java 11
uses: actions/setup-java@v2
- name: Setup Java 1.8
uses: actions/setup-java@v1
with:
java-version: 11
distribution: adopt
cache: gradle
java-version: 1.8
- 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
# --no-daemon is necessary on Windows otherwise caching Gradle would fail with:
# tar.exe: Couldn't open ~/.gradle/caches/modules-2/modules-2.lock: Permission denied
run: ./gradlew :flatlaf-natives-windows:build --no-daemon
run: ./gradlew :flatlaf-natives-windows:build
- name: Upload artifacts
uses: actions/upload-artifact@v2

View File

@@ -1,63 +1,7 @@
FlatLaf Change Log
==================
## 2.0.2
- Native window decorations (Windows 10/11 only): Fixed rendering artifacts on
HiDPI screens when dragging window partly offscreen and back into screen
bounds. (issue #477)
- Repaint component when setting client property `JComponent.outline` (issue
#480).
- macOS: Fixed NPE when using some icons in main menu items. (issue #483)
## 2.0.1
- Fixed memory leak in Panel, Separator and ToolBarSeparator. (issue #471;
regression in FlatLaf 2.0)
- ToolTip: Fixed wrong tooltip location if component overrides
`JComponent.getToolTipLocation()` and wants place tooltip under mouse
location. (issue #468)
- Extras: Added copy constructor to `FlatSVGIcon`. (issue #465)
- Moved `module-info.class` from `META-INF\versions\9\` to root folder of JARs.
(issue #466)
## 2.0
- 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
## 2.0-SNAPSHOT
#### New features and improvements
@@ -68,34 +12,9 @@ FlatLaf Change Log
- Style classes allow defining style rules at a single place (in UI defaults)
and use them in any component. (PR #388)\
E.g.: `mySlider.putClientProperty( "FlatLaf.styleClass", "myclass" );`
- Typography defines several font styles for headers and various text sizes,
which makes it easy to use consistent font styles across the application. (PR
#396)
- Native window decorations (Windows 10/11 only):
- Unified backgrounds for window title bar is now enabled by default (window
title bar has now same background color as window content). Bottom separator
for menu bars is no longer painted (if unified background is enabled).
- Show Windows 11 snap layouts menu when hovering the mouse over the maximize
button. (issues #397 and #407)
- Possibility to hide window title bar icon (for single window set client
property `JRootPane.titleBarShowIcon` to `false`; for all windows set UI
value `TitlePane.showIcon` to `false`).
- OptionPane: Hide window title bar icon by default. Can be be made visibly by
setting UI default `OptionPane.showIcon` to `true`. (issue #416)
- No longer show the Java "duke/cup" icon if no window icon image is set.
(issue #416)
- TextField, FormattedTextField and PasswordField:
- Support leading and trailing icons (set client property
`JTextField.leadingIcon` or `JTextField.trailingIcon` to a
`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)
- TextField, FormattedTextField and PasswordField: Support leading and trailing
icons (set client property `JTextField.leadingIcon` or
`JTextField.trailingIcon` to an `Icon`). (PR #378; issue #368)
- TextComponents: Double/triple-click-and-drag now extends selection by whole
words/lines.
- Theming improvements: Reworks core themes to make it easier to create new
@@ -125,96 +44,25 @@ FlatLaf Change Log
incompatible changes in FlatLaf properties files.
- Slider: Support specifying width of thumb border (see UI value
`Slider.thumbBorderWidth`).
- 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
applications: `lighten()`, `darken()`, `saturate()`, `desaturate()`, `spin()`,
`tint()`, `shade()` and `luma()`.
- Support defining fonts in FlatLaf properties files. (issue #384)
- Added method `FlatLaf.registerCustomDefaultsSource(URL packageUrl)` for JPMS.
(issue #325)
- Extras:
- Added class `FlatDesktop` for easy integration into macOS screen menu
(About, Preferences and Quit) when using Java 8.
- `FlatSVGIcon`: Support loading SVG from `URL` (for JPMS), `URI`, `File` or
`InputStream`. (issues #419 and #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
#### Fixed bugs
- ComboBox: Fixed regression in FlatLaf 1.6.3 that makes selected item invisible
in popup list if `DefaultListCellRenderer` is used as renderer. If using
default renderer, it works. (issue #426)
## 1.6.3
#### Fixed bugs
- ComboBox (not editable): Fixed regression in FlatLaf 1.6.2 that may display
text in non-editable combo boxes in bold. (issue #423)
- Tree: Fixed editing cell issue with custom cell renderer and cell editor that
use same component for rendering and editing. (issue #385)
## 1.6.2
- Extras: Added class `FlatDesktop` for easy integration into macOS screen menu
(About, Preferences and Quit) when using Java 8.
#### Fixed bugs
- ComboBox (not editable): Fixed background painted outside of border if round
edges are enabled (client property `JComponent.roundRect` is `true`). (similar
to issue #382; regression since fixing #330 in FlatLaf 1.4)
- ComboBox: Fixed `NullPointerException`, which may occur under special
circumstances. (issue #408)
- Tree: Fixed editing cell issue with custom cell renderer and cell editor that
use same component for rendering and editing. (issue #385)
- Table: Do not select text in cell editor when it gets focus (when
`JTable.surrendersFocusOnKeystroke` is `true`) and
`TextComponent.selectAllOnFocusPolicy` is `once` (the default) or `always`.
(issue #395)
- Linux: Fixed NPE when using `java.awt.TrayIcon`. (issue #405)
- FileChooser: Workaround for crash on Windows with Java 17 32-bit (disabled
Windows icons). Java 17 64-bit is not affected. (issue #403)
- Native window decorations: Fixed layout loop, which may occur under special
circumstances and slows down the application. (issue #420)
## 1.6.1

View File

@@ -11,9 +11,9 @@ scales on **HiDPI** displays and runs on Java 8 or newer.
The look is heavily inspired by **Darcula** and **IntelliJ** themes from
IntelliJ IDEA 2019.2+ and uses almost the same colors and icons.
![FlatLaf Light](images/flat_light.png)
![Flat Light](images/flat_light.png)
![FlatLaf Dark](images/flat_dark.png)
![Flat Dark](images/flat_dark.png)
IntelliJ Platform Themes
@@ -99,22 +99,10 @@ For more information and documentation visit
- [Customizing](https://www.formdev.com/flatlaf/customizing/)
- [How to Customize](https://www.formdev.com/flatlaf/how-to-customize/)
- [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/)
- [System Properties](https://www.formdev.com/flatlaf/system-properties/)
Theme Editor
------------
The Theme Editor that supports editing FlatLaf theme properties files. See
[Theme Editor documentation](https://www.formdev.com/flatlaf/theme-editor/) for
details and downloads.
![Theme Editor](images/theme-editor@1.5x.png)
Buzz
----
@@ -126,13 +114,6 @@ Buzz
Applications using FlatLaf
--------------------------
- ![New](images/new.svg) [Ultorg](https://www.ultorg.com/) (**commercial**) - a
visual query system for relational databases
- ![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
and much more
- [jclasslib bytecode viewer](https://github.com/ingokegel/jclasslib) 5.5
@@ -160,16 +141,13 @@ Applications using FlatLaf
[OpenStreetMap](https://www.openstreetmap.org/) (requires FlatLaf JOSM plugin)
- [jAlbum](https://jalbum.net/) 21 (**commercial**) - creates photo album
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**)
- [Total Validator](https://www.totalvalidator.com/) 15 (**commercial**) -
checks your website
- [j-lawyer](https://github.com/jlawyerorg/j-lawyer-org) - Kanzleisoftware
- [MegaMek](https://github.com/MegaMek/megamek),
[MegaMekLab](https://github.com/MegaMek/megameklab) and
[MekHQ](https://github.com/MegaMek/mekhq) v0.47.5+ - a sci-fi tabletop
BattleTech simulator suite handling battles, unit building, and campaigns
- [MegaMek](https://github.com/MegaMek/megamek) v0.47.4 and
[MekHQ](https://github.com/MegaMek/mekhq) v0.47.5 - a turn-based sci-fi board
game
- [GUIslice Builder](https://github.com/ImpulseAdventure/GUIslice-Builder)
0.13.b024 - GUI builder for
[GUIslice](https://github.com/ImpulseAdventure/GUIslice), a lightweight GUI
@@ -195,7 +173,7 @@ Applications using FlatLaf
systems development platform
- [JPass](https://github.com/gaborbata/jpass) - password manager with strong
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
([source code](https://github.com/trixon/mapton)) - some kind of map
application (based on NetBeans platform)

View File

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

View File

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

View File

@@ -63,8 +63,10 @@ if( JavaVersion.current() >= JavaVersion.VERSION_1_9 ) {
jar {
manifest.attributes( "Multi-Release" to "true" )
from( sourceSets["module-info"].output ) {
include( "module-info.class" )
into( "META-INF/versions/9" ) {
from( sourceSets["module-info"].output ) {
include( "module-info.class" )
}
}
}
}

2151
compare1.txt Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
#Signature file v4.1
#Version 2.0
#Version 1.6
CLSS public abstract interface com.formdev.flatlaf.FlatClientProperties
fld public final static java.lang.String BUTTON_TYPE = "JButton.buttonType"
@@ -31,8 +31,6 @@ fld public final static java.lang.String SELECT_ALL_ON_FOCUS_POLICY_ALWAYS = "al
fld public final static java.lang.String SELECT_ALL_ON_FOCUS_POLICY_NEVER = "never"
fld public final static java.lang.String SELECT_ALL_ON_FOCUS_POLICY_ONCE = "once"
fld public final static java.lang.String SQUARE_SIZE = "JButton.squareSize"
fld public final static java.lang.String STYLE = "FlatLaf.style"
fld public final static java.lang.String STYLE_CLASS = "FlatLaf.styleClass"
fld public final static java.lang.String TABBED_PANE_ALIGN_CENTER = "center"
fld public final static java.lang.String TABBED_PANE_ALIGN_FILL = "fill"
fld public final static java.lang.String TABBED_PANE_ALIGN_LEADING = "leading"
@@ -61,9 +59,6 @@ fld public final static java.lang.String TABBED_PANE_TAB_CLOSE_TOOLTIPTEXT = "JT
fld public final static java.lang.String TABBED_PANE_TAB_HEIGHT = "JTabbedPane.tabHeight"
fld public final static java.lang.String TABBED_PANE_TAB_ICON_PLACEMENT = "JTabbedPane.tabIconPlacement"
fld public final static java.lang.String TABBED_PANE_TAB_INSETS = "JTabbedPane.tabInsets"
fld public final static java.lang.String TABBED_PANE_TAB_TYPE = "JTabbedPane.tabType"
fld public final static java.lang.String TABBED_PANE_TAB_TYPE_CARD = "card"
fld public final static java.lang.String TABBED_PANE_TAB_TYPE_UNDERLINED = "underlined"
fld public final static java.lang.String TABBED_PANE_TAB_WIDTH_MODE = "JTabbedPane.tabWidthMode"
fld public final static java.lang.String TABBED_PANE_TAB_WIDTH_MODE_COMPACT = "compact"
fld public final static java.lang.String TABBED_PANE_TAB_WIDTH_MODE_EQUAL = "equal"
@@ -72,20 +67,12 @@ fld public final static java.lang.String TABBED_PANE_TRAILING_COMPONENT = "JTabb
fld public final static java.lang.String TAB_BUTTON_SELECTED_BACKGROUND = "JToggleButton.tab.selectedBackground"
fld public final static java.lang.String TAB_BUTTON_UNDERLINE_COLOR = "JToggleButton.tab.underlineColor"
fld public final static java.lang.String TAB_BUTTON_UNDERLINE_HEIGHT = "JToggleButton.tab.underlineHeight"
fld public final static java.lang.String TEXT_FIELD_CLEAR_CALLBACK = "JTextField.clearCallback"
fld public final static java.lang.String TEXT_FIELD_LEADING_COMPONENT = "JTextField.leadingComponent"
fld public final static java.lang.String TEXT_FIELD_LEADING_ICON = "JTextField.leadingIcon"
fld public final static java.lang.String TEXT_FIELD_PADDING = "JTextField.padding"
fld public final static java.lang.String TEXT_FIELD_SHOW_CLEAR_BUTTON = "JTextField.showClearButton"
fld public final static java.lang.String TEXT_FIELD_TRAILING_COMPONENT = "JTextField.trailingComponent"
fld public final static java.lang.String TEXT_FIELD_TRAILING_ICON = "JTextField.trailingIcon"
fld public final static java.lang.String TITLE_BAR_BACKGROUND = "JRootPane.titleBarBackground"
fld public final static java.lang.String TITLE_BAR_FOREGROUND = "JRootPane.titleBarForeground"
fld public final static java.lang.String TITLE_BAR_SHOW_ICON = "JRootPane.titleBarShowIcon"
fld public final static java.lang.String TREE_PAINT_SELECTION = "JTree.paintSelection"
fld public final static java.lang.String TREE_WIDE_SELECTION = "JTree.wideSelection"
fld public final static java.lang.String USE_WINDOW_DECORATIONS = "JRootPane.useWindowDecorations"
meth public static <%0 extends java.lang.Object> {%%0} clientProperty(javax.swing.JComponent,java.lang.String,{%%0},java.lang.Class<{%%0}>)
meth public static boolean clientPropertyBoolean(javax.swing.JComponent,java.lang.String,boolean)
meth public static boolean clientPropertyEquals(javax.swing.JComponent,java.lang.String,java.lang.Object)
meth public static int clientPropertyInt(javax.swing.JComponent,java.lang.String,int)
@@ -178,7 +165,6 @@ meth public boolean isSupportedLookAndFeel()
meth public final boolean equals(java.lang.Object)
meth public final int hashCode()
meth public java.lang.String getID()
meth public java.util.Map<java.lang.String,java.lang.String> getExtraDefaults()
meth public javax.swing.Icon getDisabledIcon(javax.swing.JComponent,javax.swing.Icon)
meth public javax.swing.UIDefaults getDefaults()
meth public static boolean install(javax.swing.LookAndFeel)
@@ -188,8 +174,6 @@ meth public static boolean isShowMnemonics()
meth public static boolean isUseNativeWindowDecorations()
meth public static boolean setup(javax.swing.LookAndFeel)
meth public static boolean supportsNativeWindowDecorations()
meth public static java.lang.Object parseDefaultsValue(java.lang.String,java.lang.String,java.lang.Class<?>)
meth public static java.util.Map<java.lang.String,java.lang.String> getGlobalExtraDefaults()
meth public static javax.swing.UIDefaults$ActiveValue createActiveFontValue(float)
meth public static void hideMnemonics()
meth public static void initIconColors(javax.swing.UIDefaults,boolean)
@@ -197,26 +181,22 @@ meth public static void installLafInfo(java.lang.String,java.lang.Class<? extend
meth public static void registerCustomDefaultsSource(java.io.File)
meth public static void registerCustomDefaultsSource(java.lang.String)
meth public static void registerCustomDefaultsSource(java.lang.String,java.lang.ClassLoader)
meth public static void registerCustomDefaultsSource(java.net.URL)
meth public static void repaintAllFramesAndDialogs()
meth public static void revalidateAndRepaintAllFramesAndDialogs()
meth public static void runWithUIDefaultsGetter(java.util.function.Function<java.lang.Object,java.lang.Object>,java.lang.Runnable)
meth public static void setGlobalExtraDefaults(java.util.Map<java.lang.String,java.lang.String>)
meth public static void setUseNativeWindowDecorations(boolean)
meth public static void showMnemonics(java.awt.Component)
meth public static void unregisterCustomDefaultsSource(java.io.File)
meth public static void unregisterCustomDefaultsSource(java.lang.String)
meth public static void unregisterCustomDefaultsSource(java.lang.String,java.lang.ClassLoader)
meth public static void unregisterCustomDefaultsSource(java.net.URL)
meth public static void updateUI()
meth public static void updateUILater()
meth public void initialize()
meth public void registerUIDefaultsGetter(java.util.function.Function<java.lang.Object,java.lang.Object>)
meth public void setExtraDefaults(java.util.Map<java.lang.String,java.lang.String>)
meth public void uninitialize()
meth public void unregisterUIDefaultsGetter(java.util.function.Function<java.lang.Object,java.lang.Object>)
supr javax.swing.plaf.basic.BasicLookAndFeel
hfds DESKTOPFONTHINTS,aquaLoaded,customDefaultsSources,desktopPropertyListener,desktopPropertyName,desktopPropertyName2,extraDefaults,globalExtraDefaults,mnemonicHandler,oldPopupFactory,postInitialization,uiDefaultsGetters,updateUIPending
hfds DESKTOPFONTHINTS,aquaLoaded,customDefaultsSources,desktopPropertyListener,desktopPropertyName,desktopPropertyName2,mnemonicHandler,oldPopupFactory,postInitialization,uiDefaultsGetters,updateUIPending
hcls ActiveFont,FlatUIDefaults,ImageIconUIResource
CLSS public abstract interface static com.formdev.flatlaf.FlatLaf$DisabledIconProvider
@@ -251,7 +231,6 @@ hfds baseTheme,dark,name,properties
CLSS public abstract interface com.formdev.flatlaf.FlatSystemProperties
fld public final static java.lang.String ANIMATION = "flatlaf.animation"
fld public final static java.lang.String MENUBAR_EMBEDDED = "flatlaf.menuBarEmbedded"
fld public final static java.lang.String NATIVE_LIBRARY_PATH = "flatlaf.nativeLibraryPath"
fld public final static java.lang.String UI_SCALE = "flatlaf.uiScale"
fld public final static java.lang.String UI_SCALE_ALLOW_SCALE_DOWN = "flatlaf.uiScale.allowScaleDown"
fld public final static java.lang.String UI_SCALE_ENABLED = "flatlaf.uiScale.enabled"
@@ -351,15 +330,7 @@ innr public static HSLIncreaseDecrease
innr public static Mix
meth public !varargs static java.awt.Color applyFunctions(java.awt.Color,com.formdev.flatlaf.util.ColorFunctions$ColorFunction[])
meth public static float clamp(float)
meth public static float luma(java.awt.Color)
meth public static java.awt.Color darken(java.awt.Color,float)
meth public static java.awt.Color desaturate(java.awt.Color,float)
meth public static java.awt.Color lighten(java.awt.Color,float)
meth public static java.awt.Color mix(java.awt.Color,java.awt.Color,float)
meth public static java.awt.Color saturate(java.awt.Color,float)
meth public static java.awt.Color shade(java.awt.Color,float)
meth public static java.awt.Color spin(java.awt.Color,float)
meth public static java.awt.Color tint(java.awt.Color,float)
supr java.lang.Object
CLSS public abstract interface static com.formdev.flatlaf.util.ColorFunctions$ColorFunction
@@ -595,7 +566,6 @@ meth public static java.util.List<java.awt.Image> getResolutionVariants(java.awt
supr java.lang.Object
CLSS public com.formdev.flatlaf.util.NativeLibrary
cons public init(java.io.File,boolean)
cons public init(java.lang.String,java.lang.ClassLoader,boolean)
meth public boolean isLoaded()
supr java.lang.Object
@@ -619,52 +589,18 @@ meth public void paintIcon(java.awt.Component,java.awt.Graphics,int,int)
supr java.lang.Object
hfds iconHeight,iconWidth,imageIcon,lastImage,lastSystemScaleFactor,lastUserScaleFactor
CLSS public com.formdev.flatlaf.util.SoftCache<%0 extends java.lang.Object, %1 extends java.lang.Object>
cons public init()
cons public init(int)
intf java.util.Map<{com.formdev.flatlaf.util.SoftCache%0},{com.formdev.flatlaf.util.SoftCache%1}>
meth public boolean containsKey(java.lang.Object)
meth public boolean containsValue(java.lang.Object)
meth public boolean isEmpty()
meth public int size()
meth public java.util.Collection<{com.formdev.flatlaf.util.SoftCache%1}> values()
meth public java.util.Set<java.util.Map$Entry<{com.formdev.flatlaf.util.SoftCache%0},{com.formdev.flatlaf.util.SoftCache%1}>> entrySet()
meth public java.util.Set<{com.formdev.flatlaf.util.SoftCache%0}> keySet()
meth public void clear()
meth public void forEach(java.util.function.BiConsumer<? super {com.formdev.flatlaf.util.SoftCache%0},? super {com.formdev.flatlaf.util.SoftCache%1}>)
meth public void putAll(java.util.Map<? extends {com.formdev.flatlaf.util.SoftCache%0},? extends {com.formdev.flatlaf.util.SoftCache%1}>)
meth public void replaceAll(java.util.function.BiFunction<? super {com.formdev.flatlaf.util.SoftCache%0},? super {com.formdev.flatlaf.util.SoftCache%1},? extends {com.formdev.flatlaf.util.SoftCache%1}>)
meth public {com.formdev.flatlaf.util.SoftCache%1} get(java.lang.Object)
meth public {com.formdev.flatlaf.util.SoftCache%1} put({com.formdev.flatlaf.util.SoftCache%0},{com.formdev.flatlaf.util.SoftCache%1})
meth public {com.formdev.flatlaf.util.SoftCache%1} remove(java.lang.Object)
supr java.lang.Object
hfds map,queue
hcls CacheReference
CLSS public com.formdev.flatlaf.util.StringUtils
cons public init()
meth public static boolean isEmpty(java.lang.String)
meth public static boolean isTrimmedEmpty(java.lang.String)
meth public static java.lang.String removeLeading(java.lang.String,java.lang.String)
meth public static java.lang.String removeTrailing(java.lang.String,java.lang.String)
meth public static java.lang.String substringTrimmed(java.lang.String,int)
meth public static java.lang.String substringTrimmed(java.lang.String,int,int)
meth public static java.util.List<java.lang.String> split(java.lang.String,char)
meth public static java.util.List<java.lang.String> split(java.lang.String,char,boolean,boolean)
supr java.lang.Object
CLSS public com.formdev.flatlaf.util.SwingUtils
cons public init()
meth public static <%0 extends java.awt.Component> {%%0} getComponentByName(java.awt.Container,java.lang.String)
supr java.lang.Object
CLSS public com.formdev.flatlaf.util.SystemInfo
cons public init()
fld public final static boolean isAARCH64
fld public final static boolean isJava_11_orLater
fld public final static boolean isJava_15_orLater
fld public final static boolean isJava_17_orLater
fld public final static boolean isJava_18_orLater
fld public final static boolean isJava_9_orLater
fld public final static boolean isJetBrainsJVM
fld public final static boolean isJetBrainsJVM_11_orLater
@@ -679,8 +615,6 @@ fld public final static boolean isWebswing
fld public final static boolean isWinPE
fld public final static boolean isWindows
fld public final static boolean isWindows_10_orLater
fld public final static boolean isWindows_11_orLater
fld public final static boolean isX86
fld public final static boolean isX86_64
fld public final static long javaVersion
fld public final static long osVersion
@@ -693,7 +627,6 @@ cons public init()
meth public static boolean isSystemScalingEnabled()
meth public static double getSystemScaleFactor(java.awt.Graphics2D)
meth public static double getSystemScaleFactor(java.awt.GraphicsConfiguration)
meth public static float computeFontScaleFactor(java.awt.Font)
meth public static float getUserScaleFactor()
meth public static float scale(float)
meth public static float unscale(float)
@@ -1000,34 +933,6 @@ CLSS public abstract interface !annotation java.lang.annotation.Target
intf java.lang.annotation.Annotation
meth public abstract java.lang.annotation.ElementType[] value()
CLSS public abstract interface java.util.Map<%0 extends java.lang.Object, %1 extends java.lang.Object>
innr public abstract interface static Entry
meth public abstract boolean containsKey(java.lang.Object)
meth public abstract boolean containsValue(java.lang.Object)
meth public abstract boolean equals(java.lang.Object)
meth public abstract boolean isEmpty()
meth public abstract int hashCode()
meth public abstract int size()
meth public abstract java.util.Collection<{java.util.Map%1}> values()
meth public abstract java.util.Set<java.util.Map$Entry<{java.util.Map%0},{java.util.Map%1}>> entrySet()
meth public abstract java.util.Set<{java.util.Map%0}> keySet()
meth public abstract void clear()
meth public abstract void putAll(java.util.Map<? extends {java.util.Map%0},? extends {java.util.Map%1}>)
meth public abstract {java.util.Map%1} get(java.lang.Object)
meth public abstract {java.util.Map%1} put({java.util.Map%0},{java.util.Map%1})
meth public abstract {java.util.Map%1} remove(java.lang.Object)
meth public boolean remove(java.lang.Object,java.lang.Object)
meth public boolean replace({java.util.Map%0},{java.util.Map%1},{java.util.Map%1})
meth public void forEach(java.util.function.BiConsumer<? super {java.util.Map%0},? super {java.util.Map%1}>)
meth public void replaceAll(java.util.function.BiFunction<? super {java.util.Map%0},? super {java.util.Map%1},? extends {java.util.Map%1}>)
meth public {java.util.Map%1} compute({java.util.Map%0},java.util.function.BiFunction<? super {java.util.Map%0},? super {java.util.Map%1},? extends {java.util.Map%1}>)
meth public {java.util.Map%1} computeIfAbsent({java.util.Map%0},java.util.function.Function<? super {java.util.Map%0},? extends {java.util.Map%1}>)
meth public {java.util.Map%1} computeIfPresent({java.util.Map%0},java.util.function.BiFunction<? super {java.util.Map%0},? super {java.util.Map%1},? extends {java.util.Map%1}>)
meth public {java.util.Map%1} getOrDefault(java.lang.Object,{java.util.Map%1})
meth public {java.util.Map%1} merge({java.util.Map%0},{java.util.Map%1},java.util.function.BiFunction<? super {java.util.Map%1},? super {java.util.Map%1},? extends {java.util.Map%1}>)
meth public {java.util.Map%1} putIfAbsent({java.util.Map%0},{java.util.Map%1})
meth public {java.util.Map%1} replace({java.util.Map%0},{java.util.Map%1})
CLSS public abstract interface javax.swing.Icon
meth public abstract int getIconHeight()
meth public abstract int getIconWidth()

View File

@@ -331,24 +331,6 @@ public interface FlatClientProperties
*/
String MENU_BAR_EMBEDDED = "JRootPane.menuBarEmbedded";
/**
* Specifies whether the window icon should be shown in the window title bar
* (requires enabled window decorations).
* <p>
* Setting this shows/hides the windows icon
* for the {@code JFrame} or {@code JDialog} that contains the root pane.
* <p>
* This client property has higher priority than UI default {@code TitlePane.showIcon}.
* <p>
* (requires Window 10)
* <p>
* <strong>Component</strong> {@link javax.swing.JRootPane}<br>
* <strong>Value type</strong> {@link java.lang.Boolean}
*
* @since 2
*/
String TITLE_BAR_SHOW_ICON = "JRootPane.titleBarShowIcon";
/**
* Background color of window title bar (requires enabled window decorations).
* <p>
@@ -393,35 +375,6 @@ public interface FlatClientProperties
//---- JTabbedPane --------------------------------------------------------
/**
* Specifies type of the selected tab.
* <p>
* <strong>Component</strong> {@link javax.swing.JTabbedPane}<br>
* <strong>Value type</strong> {@link java.lang.String}<br>
* <strong>Allowed Values</strong>
* {@link #TABBED_PANE_TAB_TYPE_UNDERLINED} or
* {@link #TABBED_PANE_TAB_TYPE_CARD}
*
* @since 2
*/
String TABBED_PANE_TAB_TYPE = "JTabbedPane.tabType";
/**
* Paint the selected tab underlined.
*
* @see #TABBED_PANE_TAB_TYPE
* @since 2
*/
String TABBED_PANE_TAB_TYPE_UNDERLINED = "underlined";
/**
* Paint the selected tab as card.
*
* @see #TABBED_PANE_TAB_TYPE
* @since 2
*/
String TABBED_PANE_TAB_TYPE_CARD = "card";
/**
* Specifies whether separators are shown between tabs.
* <p>
@@ -763,9 +716,9 @@ public interface FlatClientProperties
/**
* Specifies a component that will be placed at the leading edge of the tabs area.
* <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>
* 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.
* <p>
* <strong>Component</strong> {@link javax.swing.JTabbedPane}<br>
@@ -776,9 +729,9 @@ public interface FlatClientProperties
/**
* Specifies a component that will be placed at the trailing edge of the tabs area.
* <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>
* 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).
* <p>
* <strong>Component</strong> {@link javax.swing.JTabbedPane}<br>
@@ -863,98 +816,6 @@ public interface FlatClientProperties
*/
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 ------------------------------------------------------
/**

View File

@@ -31,7 +31,6 @@ import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
@@ -52,7 +51,6 @@ import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JMenuBar;
import javax.swing.LookAndFeel;
import javax.swing.PopupFactory;
import javax.swing.RootPaneContainer;
@@ -394,7 +392,6 @@ public abstract class FlatLaf
"EditorPane.inactiveBackground",
"FormattedTextField.disabledBackground",
"PasswordField.disabledBackground",
"RootPane.background",
"Spinner.disabledBackground",
"TextArea.disabledBackground",
"TextArea.inactiveBackground",
@@ -413,8 +410,7 @@ public abstract class FlatLaf
"Spinner.disabledForeground",
"ToggleButton.disabledText" );
putDefaults( defaults, defaults.getColor( "textText" ),
"DesktopIcon.foreground",
"RootPane.foreground" );
"DesktopIcon.foreground" );
initFonts( defaults );
initIconColors( defaults, isDark() );
@@ -424,7 +420,7 @@ public abstract class FlatLaf
// (using defaults.remove() to avoid that lazy value is resolved and icon loaded here)
Object icon = defaults.remove( "InternalFrame.icon" );
defaults.put( "InternalFrame.icon", icon );
defaults.put( "TitlePane.icon", icon ); // no longer used, but keep for compatibility
defaults.put( "TitlePane.icon", icon );
// get addons and sort them by priority
ServiceLoader<FlatDefaultsAddon> addonLoader = ServiceLoader.load( FlatDefaultsAddon.class );
@@ -537,16 +533,13 @@ public abstract class FlatLaf
// use active value for all fonts to allow changing fonts in all components with:
// UIManager.put( "defaultFont", myFont );
// (this is similar as in Nimbus L&F)
Object activeFont = new ActiveFont( null, null, -1, 0, 0, 0, 0 );
Object activeFont = new ActiveFont( null, -1, 0, 0, 0, 0 );
// override fonts
for( Object key : defaults.keySet() ) {
if( key instanceof String && (((String)key).endsWith( ".font" ) || ((String)key).endsWith( "Font" )) )
defaults.put( key, activeFont );
}
// add fonts that are not set in BasicLookAndFeel
defaults.put( "RootPane.font", activeFont );
}
private void initDefaultFont( UIDefaults defaults ) {
@@ -624,7 +617,7 @@ public abstract class FlatLaf
/** @since 1.1 */
public static ActiveValue createActiveFontValue( float scaleFactor ) {
return new ActiveFont( null, null, -1, 0, 0, 0, scaleFactor );
return new ActiveFont( null, -1, 0, 0, 0, scaleFactor );
}
/**
@@ -758,9 +751,6 @@ public abstract class FlatLaf
* and can therefore override all UI defaults.
* <p>
* Invoke this method before setting the look and feel.
* <p>
* If using Java modules, the package must be opened in {@code module-info.java}.
* Otherwise use {@link #registerCustomDefaultsSource(URL)}.
*
* @param packageName a package name (e.g. "com.myapp.resources")
*/
@@ -802,32 +792,6 @@ public abstract class FlatLaf
}
}
/**
* Registers a package where FlatLaf searches for properties files with custom UI defaults.
* <p>
* See {@link #registerCustomDefaultsSource(String)} for details.
* <p>
* This method is useful if using Java modules and the package containing the properties files
* is not opened in {@code module-info.java}.
* E.g. {@code FlatLaf.registerCustomDefaultsSource( MyApp.class.getResource( "/com/myapp/themes/" ) )}.
*
* @param packageUrl a package URL
* @since 2
*/
public static void registerCustomDefaultsSource( URL packageUrl ) {
if( customDefaultsSources == null )
customDefaultsSources = new ArrayList<>();
customDefaultsSources.add( packageUrl );
}
/** @since 2 */
public static void unregisterCustomDefaultsSource( URL packageUrl ) {
if( customDefaultsSources == null )
return;
customDefaultsSources.remove( packageUrl );
}
/**
* Registers a folder where FlatLaf searches for properties files with custom UI defaults.
* <p>
@@ -1037,23 +1001,12 @@ public abstract class FlatLaf
/**
* Revalidate and repaint all displayable frames and dialogs.
* <p>
* Useful to update UI after changing {@code TitlePane.menuBarEmbedded}.
*
* @since 1.1.2
*/
public static void revalidateAndRepaintAllFramesAndDialogs() {
for( Window w : Window.getWindows() ) {
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.repaint();
}
@@ -1062,9 +1015,6 @@ public abstract class FlatLaf
/**
* 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
*/
@@ -1223,9 +1173,6 @@ public abstract class FlatLaf
}
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 )
return null;
@@ -1244,7 +1191,6 @@ public abstract class FlatLaf
static class ActiveFont
implements ActiveValue
{
private final String baseFontKey;
private final List<String> families;
private final int style;
private final int styleChange;
@@ -1254,9 +1200,7 @@ public abstract class FlatLaf
// cache (scaled/derived) font
private FontUIResource font;
private Font lastBaseFont;
private boolean inCreateValue;
private Font lastDefaultFont;
/**
* @param families list of font families, or {@code null}
@@ -1267,10 +1211,9 @@ public abstract class FlatLaf
* @param relativeSize added to size of base font, or {@code 0}
* @param scaleSize multiply size of base font, or {@code 0}
*/
ActiveFont( String baseFontKey, List<String> families, int style, int styleChange,
ActiveFont( List<String> families, int style, int styleChange,
int absoluteSize, int relativeSize, float scaleSize )
{
this.baseFontKey = baseFontKey;
this.families = families;
this.style = style;
this.styleChange = styleChange;
@@ -1279,33 +1222,18 @@ public abstract class FlatLaf
this.scaleSize = scaleSize;
}
// using synchronized to avoid exception if invoked at the same time on multiple threads
@Override
public synchronized Object createValue( UIDefaults table ) {
if( inCreateValue )
throw new IllegalStateException( "FlatLaf: endless recursion in font" );
public Object createValue( UIDefaults table ) {
Font defaultFont = UIManager.getFont( "defaultFont" );
Font baseFont = null;
// fallback (to avoid NPE in case that this is used in another Laf)
if( defaultFont == null )
defaultFont = UIManager.getFont( "Label.font" );
inCreateValue = true;
try {
if( baseFontKey != null )
baseFont = (Font) UIDefaultsLoader.lazyUIManagerGet( baseFontKey );
if( lastDefaultFont != defaultFont ) {
lastDefaultFont = defaultFont;
if( baseFont == null )
baseFont = UIManager.getFont( "defaultFont" );
// fallback (to avoid NPE in case that this is used in another Laf)
if( baseFont == null )
baseFont = UIManager.getFont( "Label.font" );
} finally {
inCreateValue = false;
}
if( lastBaseFont != baseFont ) {
lastBaseFont = baseFont;
font = derive( baseFont, fontSize -> UIScale.scale( fontSize ) );
font = derive( defaultFont, fontSize -> UIScale.scale( fontSize ) );
}
return font;
@@ -1343,19 +1271,9 @@ public abstract class FlatLaf
}
// derive font
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 );
}
if( newStyle != baseStyle || newSize != baseSize )
return toUIResource( baseFont.deriveFont( newStyle, newSize ) );
} else
else
return toUIResource( baseFont );
}

View File

@@ -81,7 +81,7 @@ public interface FlatSystemProperties
* {@link FlatClientProperties#USE_WINDOW_DECORATIONS} and
* UI default {@code TitlePane.useWindowDecorations}.
* <p>
* (requires Window 10/11)
* (requires Window 10)
* <p>
* <strong>Allowed Values</strong> {@code false} and {@code true}<br>
* <strong>Default</strong> none
@@ -92,16 +92,16 @@ public interface FlatSystemProperties
* Specifies whether JetBrains Runtime custom window decorations should be used
* when creating {@code JFrame} or {@code JDialog}.
* 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).
* <p>
* Setting this to {@code false} disables using JetBrains Runtime custom window decorations.
* Then FlatLaf native window decorations are used.
* <p>
* (requires Window 10/11)
* (requires Window 10)
* <p>
* <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";
@@ -116,7 +116,7 @@ public interface FlatSystemProperties
* {@link FlatClientProperties#MENU_BAR_EMBEDDED} and
* UI default {@code TitlePane.menuBarEmbedded}.
* <p>
* (requires Window 10/11)
* (requires Window 10)
* <p>
* <strong>Allowed Values</strong> {@code false} and {@code true}<br>
* <strong>Default</strong> none
@@ -139,15 +139,6 @@ public interface FlatSystemProperties
*/
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
* is {@code "true"} (case-insensitive), otherwise it returns {@code false}.

View File

@@ -17,7 +17,6 @@
package com.formdev.flatlaf;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.Toolkit;
@@ -29,7 +28,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.StringTokenizer;
import javax.swing.text.StyleContext;
import com.formdev.flatlaf.util.LoggingFacade;
import com.formdev.flatlaf.util.StringUtils;
import com.formdev.flatlaf.util.SystemInfo;
@@ -122,25 +121,14 @@ class LinuxFontPolicy
for(;;) {
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( !Font.DIALOG.equals( font.getFamily() ) ) {
// 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 );
if( !"Dialog".equals( font.getFamily() ) || "Dialog".equals( family ) )
return font;
}
// find last word in family
int index = family.lastIndexOf( ' ' );
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)
String lastWord = family.substring( index + 1 ).toLowerCase();

View File

@@ -22,12 +22,13 @@ import java.awt.Font;
import java.awt.Insets;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.StreamTokenizer;
import java.io.StringReader;
import java.net.URL;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -55,7 +56,6 @@ import com.formdev.flatlaf.util.DerivedColor;
import com.formdev.flatlaf.util.GrayFilter;
import com.formdev.flatlaf.util.HSLColor;
import com.formdev.flatlaf.util.LoggingFacade;
import com.formdev.flatlaf.util.SoftCache;
import com.formdev.flatlaf.util.StringUtils;
import com.formdev.flatlaf.util.SystemInfo;
import com.formdev.flatlaf.util.UIScale;
@@ -80,11 +80,11 @@ class UIDefaultsLoader
private static final String OPTIONAL_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 final SoftCache<String, Object> fontCache = new SoftCache<>();
private static final Cache<String, Object> fontCache = new Cache<>();
static void loadDefaultsFromProperties( Class<?> lookAndFeelClass, List<FlatDefaultsAddon> addons,
Properties additionalDefaults, boolean dark, UIDefaults defaults )
@@ -158,18 +158,6 @@ class UIDefaultsLoader
properties.load( in );
}
}
} else if( source instanceof URL ) {
// load from package URL
URL packageUrl = (URL) source;
for( Class<?> lafClass : lafClasses ) {
URL propertiesUrl = new URL( packageUrl + lafClass.getSimpleName() + ".properties" );
try( InputStream in = propertiesUrl.openStream() ) {
properties.load( in );
} catch( FileNotFoundException ex ) {
// ignore
}
}
} else if( source instanceof File ) {
// load from folder
File folder = (File) source;
@@ -364,12 +352,6 @@ class UIDefaultsLoader
if( resultValueType == null )
resultValueType = tempResultValueType;
// do not parse styles here
if( key.startsWith( "[style]" ) ) {
resultValueType[0] = ValueType.STRING;
return value;
}
value = value.trim();
// null
@@ -447,7 +429,10 @@ class UIDefaultsLoader
// check whether value type is specified in the value
if( value.startsWith( "#" ) )
valueType = ValueType.COLOR;
else if( value.startsWith( TYPE_PREFIX ) ) {
else if( value.startsWith( "\"" ) && value.indexOf( '"', 1 ) == value.length() - 1 ) {
valueType = ValueType.STRING;
value = value.substring( 1, value.length() - 1 );
} else if( value.startsWith( TYPE_PREFIX ) ) {
int end = value.indexOf( TYPE_PREFIX_END );
if( end != -1 ) {
try {
@@ -539,12 +524,6 @@ class UIDefaultsLoader
case GRAYFILTER: return parseGrayFilter( value );
case UNKNOWN:
default:
// string
if( value.startsWith( "\"" ) && value.endsWith( "\"" ) ) {
resultValueType[0] = ValueType.STRING;
return value.substring( 1, value.length() - 1 );
}
// colors
Object color = parseColorOrFunction( value, resolver, false );
if( color != null ) {
@@ -588,18 +567,17 @@ class UIDefaultsLoader
private static Object parseBorder( String value, Function<String, String> resolver, List<ClassLoader> addonClassLoaders ) {
if( value.indexOf( ',' ) >= 0 ) {
// top,left,bottom,right[,lineColor[,lineThickness[,arc]]]
// top,left,bottom,right[,lineColor[,lineThickness]]
List<String> parts = splitFunctionParams( value, ',' );
Insets insets = parseInsets( value );
ColorUIResource lineColor = (parts.size() >= 5)
? (ColorUIResource) parseColorOrFunction( resolver.apply( parts.get( 4 ) ), resolver, true )
: null;
float lineThickness = (parts.size() >= 6 && !parts.get( 5 ).isEmpty()) ? parseFloat( parts.get( 5 ), true ) : 1f;
int arc = (parts.size() >= 7) ? parseInteger( parts.get( 6 ), true ) : 0;
float lineThickness = (parts.size() >= 6) ? parseFloat( parts.get( 5 ), true ) : 1f;
return (LazyValue) t -> {
return (lineColor != null)
? new FlatLineBorder( insets, lineColor, lineThickness, arc )
? new FlatLineBorder( insets, lineColor, lineThickness )
: new FlatEmptyBorder( insets );
};
} else
@@ -902,32 +880,21 @@ class UIDefaultsLoader
* Syntax: fade(color,amount[,options])
* - color: a color (e.g. #f00) or a color function
* - amount: percentage 0-100%
* - options: [derived] [lazy]
* - options: [derived]
*/
private static Object parseColorFade( List<String> params, Function<String, String> resolver, boolean reportError ) {
String colorStr = params.get( 0 );
int amount = parsePercentage( params.get( 1 ) );
boolean derived = false;
boolean lazy = false;
if( params.size() > 2 ) {
String options = params.get( 2 );
derived = options.contains( "derived" );
lazy = options.contains( "lazy" );
}
// create function
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
return parseFunctionBaseColor( colorStr, function, derived, resolver, reportError );
}
@@ -1072,7 +1039,7 @@ class UIDefaultsLoader
}
/**
* Syntax: [normal] [bold|+bold|-bold] [italic|+italic|-italic] [<size>|+<incr>|-<decr>|<percent>%] [family[, family]] [$baseFontKey]
* Syntax: [normal] [bold|+bold|-bold] [italic|+italic|-italic] [<size>|+<incr>|-<decr>|<percent>%] [family[, family]]
*/
private static Object parseFont( String value ) {
Object font = fontCache.get( value );
@@ -1085,7 +1052,6 @@ class UIDefaultsLoader
int relativeSize = 0;
float scaleSize = 0;
List<String> families = null;
String baseFontKey = null;
// use StreamTokenizer to split string because it supports quoted strings
StreamTokenizer st = new StreamTokenizer( new StringReader( value ) );
@@ -1135,12 +1101,6 @@ class UIDefaultsLoader
scaleSize = parseInteger( param.substring( 0, param.length() - 1 ), true ) / 100f;
else
absoluteSize = parseInteger( param, true );
} else if( firstChar == '$' ) {
// reference to base font
if( baseFontKey != null )
throw new IllegalArgumentException( "baseFontKey specified more than once in '" + value + "'" );
baseFontKey = param.substring( 1 );
} else {
// font family
if( families == null )
@@ -1167,7 +1127,7 @@ class UIDefaultsLoader
throw new IllegalArgumentException( "can not use '+italic' and '-italic' in '" + value + "'" );
}
font = new FlatLaf.ActiveFont( baseFontKey, families, style, styleChange, absoluteSize, relativeSize, scaleSize );
font = new FlatLaf.ActiveFont( families, style, styleChange, absoluteSize, relativeSize, scaleSize );
fontCache.put( value, font );
return font;
}
@@ -1320,7 +1280,7 @@ class UIDefaultsLoader
* For use in LazyValue to get value for given key from UIManager and report error
* if not found. If key is prefixed by '?', then no error is reported.
*/
static Object lazyUIManagerGet( String uiKey ) {
private static Object lazyUIManagerGet( String uiKey ) {
boolean optional = false;
if( uiKey.startsWith( OPTIONAL_PREFIX ) ) {
uiKey = uiKey.substring( OPTIONAL_PREFIX.length() );
@@ -1336,4 +1296,43 @@ class UIDefaultsLoader
private static void throwMissingParametersException( String value ) {
throw new IllegalArgumentException( "missing parameters in function '" + value + "'" );
}
//---- class Cache --------------------------------------------------------
private static class Cache<K,V>
{
private final Map<K, CacheReference<K,V>> map = new HashMap<>();
private final ReferenceQueue<V> queue = new ReferenceQueue<>();
V get( K key ) {
expungeStaleEntries();
CacheReference<K,V> ref = map.get( key );
return (ref != null) ? ref.get() : null;
}
void put( K key, V value ) {
expungeStaleEntries();
map.put( key, new CacheReference<>( key, value, queue ) );
}
@SuppressWarnings( "unchecked" )
void expungeStaleEntries() {
Reference<? extends V> reference;
while( (reference = queue.poll()) != null )
map.remove( ((CacheReference<K,V>)reference).key );
}
//---- class CacheReference ----
private static class CacheReference<K,V>
extends SoftReference<V>
{
final K key;
public CacheReference( K key, V value, ReferenceQueue<? super V> queue ) {
super( value, queue );
this.key = key;
}
}
}
}

View File

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

View File

@@ -96,8 +96,8 @@ public class FlatHelpButtonIcon
</svg>
*/
boolean enabled = c == null || c.isEnabled();
boolean focused = c != null && FlatUIUtils.isPermanentFocusOwner( c );
boolean enabled = c.isEnabled();
boolean focused = FlatUIUtils.isPermanentFocusOwner( c );
float xy = 0.5f;
float wh = iconSize() - 1;

View File

@@ -63,7 +63,7 @@ public class FlatMenuArrowIcon
@Override
protected void paintIcon( Component c, Graphics2D g ) {
if( c != null && !c.getComponentOrientation().isLeftToRight() )
if( !c.getComponentOrientation().isLeftToRight() )
g.rotate( Math.toRadians( 180 ), width / 2., height / 2. );
g.setColor( getArrowColor( c ) );
@@ -82,7 +82,7 @@ public class FlatMenuArrowIcon
if( c instanceof JMenu && ((JMenu)c).isSelected() && !isUnderlineSelection() )
return selectionForeground;
return c == null || c.isEnabled() ? arrowColor : disabledArrowColor;
return c.isEnabled() ? arrowColor : disabledArrowColor;
}
protected boolean isUnderlineSelection() {

View File

@@ -21,16 +21,14 @@ import java.awt.Graphics;
import java.awt.Graphics2D;
/**
* "arrow" icon for {@link javax.swing.JMenuItem}, {@link javax.swing.JCheckBoxMenuItem}
* and {@link javax.swing.JRadioButtonMenuItem}.
* "arrow" icon for {@link javax.swing.JMenuItem}.
*
* @author Karl Tauber
*/
public class FlatMenuItemArrowIcon
extends FlatAbstractIcon
extends FlatMenuArrowIcon
{
public FlatMenuItemArrowIcon() {
super( 6, 10, null );
}
@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 searchIconPressedColor = UIManager.getColor( "SearchField.searchIconPressedColor" );
private final boolean ignoreButtonState;
public FlatSearchIcon() {
this( false );
}
/** @since 2 */
public FlatSearchIcon( boolean ignoreButtonState ) {
super( 16, 16, null );
this.ignoreButtonState = ignoreButtonState;
}
/** @since 2 */
@@ -78,10 +70,8 @@ public class FlatSearchIcon
</svg>
*/
g.setColor( ignoreButtonState
? searchIconColor
: FlatButtonUI.buttonStateColor( c, searchIconColor, searchIconColor,
null, searchIconHoverColor, searchIconPressedColor ) );
g.setColor( FlatButtonUI.buttonStateColor( c, searchIconColor, searchIconColor,
null, searchIconHoverColor, searchIconPressedColor ) );
// paint magnifier
Area area = new Area( new Ellipse2D.Float( 2, 2, 10, 10 ) );

View File

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

View File

@@ -20,7 +20,6 @@ import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.UIManager;
import com.formdev.flatlaf.ui.FlatButtonUI;
import com.formdev.flatlaf.ui.FlatUIUtils;
@@ -66,14 +65,8 @@ public abstract class FlatWindowAbstractIcon
protected void paintBackground( Component c, Graphics2D g ) {
Color background = FlatButtonUI.buttonStateColor( c, null, null, null, hoverBackground, pressedBackground );
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.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 javax.swing.UIManager;
import com.formdev.flatlaf.ui.FlatButtonUI;
import com.formdev.flatlaf.util.SystemInfo;
/**
* "close" icon for windows (frames and dialogs).
@@ -55,7 +54,7 @@ public class FlatWindowCloseIcon
int iy = y + ((height - iwh) / 2);
int ix2 = ix + 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 );
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 com.formdev.flatlaf.ui.FlatUIUtils;
import com.formdev.flatlaf.util.SystemInfo;
/**
* "maximize" icon for windows (frames and dialogs).
@@ -36,11 +35,8 @@ public class FlatWindowMaximizeIcon
int iwh = (int) (10 * scaleFactor);
int ix = x + ((width - iwh) / 2);
int iy = y + ((height - iwh) / 2);
float thickness = SystemInfo.isWindows_11_orLater ? (float) scaleFactor : (int) scaleFactor;
int arc = Math.max( (int) (1.5 * scaleFactor), 2 );
int thickness = (int) scaleFactor;
g.fill( SystemInfo.isWindows_11_orLater
? FlatUIUtils.createRoundRectangle( ix, iy, iwh, iwh, thickness, arc, arc, arc, arc )
: FlatUIUtils.createRectangle( ix, iy, iwh, iwh, thickness ) );
g.fill( 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.Rectangle2D;
import com.formdev.flatlaf.ui.FlatUIUtils;
import com.formdev.flatlaf.util.SystemInfo;
/**
* "restore" icon for windows (frames and dialogs).
@@ -39,33 +38,18 @@ public class FlatWindowRestoreIcon
int iwh = (int) (10 * scaleFactor);
int ix = x + ((width - iwh) / 2);
int iy = y + ((height - iwh) / 2);
float thickness = SystemInfo.isWindows_11_orLater ? (float) scaleFactor : (int) scaleFactor;
int arc = Math.max( (int) (1.5 * scaleFactor), 2 );
int arcOuter = (int) (arc + (1.5 * scaleFactor));
int thickness = (int) scaleFactor;
int rwh = (int) (8 * scaleFactor);
int ro2 = iwh - rwh;
// upper-right rectangle
Path2D r1 = SystemInfo.isWindows_11_orLater
? FlatUIUtils.createRoundRectangle( ix + ro2, iy, rwh, rwh, thickness, arc, arcOuter, arc, arc )
: FlatUIUtils.createRectangle( ix + ro2, iy, rwh, rwh, thickness );
Path2D r1 = FlatUIUtils.createRectangle( ix + ro2, iy, rwh, rwh, thickness );
Path2D r2 = FlatUIUtils.createRectangle( ix, iy + ro2, 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 );
if( SystemInfo.isWindows_11_orLater ) {
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 ) ) );
area.subtract( new Area( new Rectangle2D.Float( ix, iy + ro2, rwh, rwh ) ) );
g.fill( area );
// paint lower-left rectangle
g.fill( r2 );
}
}

View File

@@ -38,18 +38,15 @@ import javax.swing.ButtonModel;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JTextField;
import javax.swing.JToggleButton;
import javax.swing.JToolBar;
import javax.swing.LookAndFeel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.plaf.ButtonUI;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.UIResource;
import javax.swing.plaf.basic.BasicButtonListener;
import javax.swing.plaf.basic.BasicButtonUI;
import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.FlatLaf;
import com.formdev.flatlaf.icons.FlatHelpButtonIcon;
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
@@ -262,15 +259,11 @@ public class FlatButtonUI
b.repaint();
break;
case OUTLINE:
b.repaint();
break;
case STYLE:
case STYLE_CLASS:
if( shared && FlatStylingSupport.hasStyleProperty( b ) ) {
// unshare component UI if necessary
// updateUI() invokes installStyle() from installUI()
// updateUI() invokes applyStyle() from installUI()
b.updateUI();
} else
installStyle( b );
@@ -427,21 +420,11 @@ public class FlatButtonUI
try {
FlatUIUtils.setRenderingHints( g2 );
boolean def = isDefaultButton( c );
boolean isToolBarButton = isToolBarButton( c );
float focusWidth = isToolBarButton ? 0 : FlatUIUtils.getBorderFocusWidth( c );
float arc = FlatUIUtils.getBorderArc( c );
float textFieldArc = 0;
// if toolbar button is in leading/trailing component of a text field,
// 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 );
}
boolean def = isDefaultButton( c );
int x = 0;
int y = 0;
@@ -454,15 +437,8 @@ public class FlatButtonUI
y += spacing.top;
width -= spacing.left + spacing.right;
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
Color shadowColor = def ? defaultShadowColor : this.shadowColor;
if( paintShadow &&
@@ -573,9 +549,6 @@ public class FlatButtonUI
public static Color buttonStateColor( Component c, Color enabledColor, Color disabledColor,
Color focusedColor, Color hoverColor, Color pressedColor )
{
if( c == null )
return enabledColor;
if( !c.isEnabled() )
return disabledColor;

View File

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

View File

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

View File

@@ -98,8 +98,8 @@ import com.formdev.flatlaf.util.SystemInfo;
* @uiDefault ComboBox.focusedBackground Color optional
* @uiDefault ComboBox.disabledBackground Color
* @uiDefault ComboBox.disabledForeground Color
* @uiDefault ComboBox.buttonBackground Color optional
* @uiDefault ComboBox.buttonEditableBackground Color optional
* @uiDefault ComboBox.buttonBackground Color
* @uiDefault ComboBox.buttonEditableBackground Color
* @uiDefault ComboBox.buttonFocusedBackground Color optional; defaults to ComboBox.focusedBackground
* @uiDefault ComboBox.buttonSeparatorWidth int or float optional; defaults to Component.borderWidth
* @uiDefault ComboBox.buttonSeparatorColor Color optional
@@ -281,10 +281,7 @@ public class FlatComboBoxUI
public void layoutContainer( Container parent ) {
super.layoutContainer( parent );
// on macOS, a Swing combo box is used for AWT component java.awt.Choice
// and the font may be (temporary) null
if( arrowButton != null && comboBox.getFont() != null ) {
if( arrowButton != null ) {
// limit button width to height of a raw combobox (without insets)
FontMetrics fm = comboBox.getFontMetrics( comboBox.getFont() );
int maxButtonWidth = fm.getHeight() + scale( padding.top ) + scale( padding.bottom );
@@ -354,7 +351,6 @@ public class FlatComboBoxUI
break;
case COMPONENT_ROUND_RECT:
case OUTLINE:
comboBox.repaint();
break;
@@ -544,27 +540,24 @@ public class FlatComboBoxUI
// paint arrow button background
if( enabled && !isCellRenderer ) {
Color buttonColor = paintButton
g2.setColor( paintButton
? buttonEditableBackground
: (buttonFocusedBackground != null || focusedBackground != null) && isPermanentFocusOwner( comboBox )
? (buttonFocusedBackground != null ? buttonFocusedBackground : focusedBackground)
: buttonBackground;
if( buttonColor != null ) {
g2.setColor( buttonColor );
Shape oldClip = g2.getClip();
if( isLeftToRight )
g2.clipRect( arrowX, 0, width - arrowX, height );
else
g2.clipRect( 0, 0, arrowX + arrowWidth, height );
FlatUIUtils.paintComponentBackground( g2, 0, 0, width, height, focusWidth, arc );
g2.setClip( oldClip );
}
: buttonBackground );
Shape oldClip = g2.getClip();
if( isLeftToRight )
g2.clipRect( arrowX, 0, width - arrowX, height );
else
g2.clipRect( 0, 0, arrowX + arrowWidth, height );
FlatUIUtils.paintComponentBackground( g2, 0, 0, width, height, focusWidth, arc );
g2.setClip( oldClip );
}
// paint vertical line between value and arrow button
if( paintButton ) {
Color separatorColor = enabled ? buttonSeparatorColor : buttonDisabledSeparatorColor;
if( separatorColor != null && buttonSeparatorWidth > 0 ) {
if( separatorColor != null ) {
g2.setColor( separatorColor );
float lw = scale( buttonSeparatorWidth );
float lx = isLeftToRight ? arrowX : arrowX + arrowWidth - lw;
@@ -582,6 +575,22 @@ public class FlatComboBoxUI
@Override
@SuppressWarnings( "unchecked" )
public void paintCurrentValue( Graphics g, Rectangle bounds, boolean hasFocus ) {
// apply clipping using rounded rectangle to avoid that renderer paints
// outside of border if combobox uses larger arc for edges
// (e.g. FlatClientProperties.COMPONENT_ROUND_RECT is true)
FlatBorder border = FlatUIUtils.getOutsideFlatBorder( comboBox );
if( border != null ) {
int clipArc = border.getArc( comboBox ) - (border.getLineWidth( comboBox ) * 2);
if( clipArc > 0 ) {
int x = bounds.x;
int width = bounds.width + bounds.height;
if( !comboBox.getComponentOrientation().isLeftToRight() )
x -= bounds.height;
((Graphics2D)g).clip( FlatUIUtils.createComponentRectangle(
x, bounds.y, width, bounds.height, scale( (float) clipArc ) ) );
}
}
paddingBorder.uninstall();
ListCellRenderer<Object> renderer = comboBox.getRenderer();
@@ -595,20 +604,11 @@ public class FlatComboBoxUI
c.setBackground( getBackground( enabled ) );
c.setForeground( getForeground( enabled ) );
// make renderer component temporary non-opaque to avoid that renderer paints
// background outside of border if combobox uses larger arc for edges
// (e.g. FlatClientProperties.COMPONENT_ROUND_RECT is true)
if( c instanceof JComponent )
((JComponent)c).setOpaque( false );
boolean shouldValidate = (c instanceof JPanel);
paddingBorder.install( c );
currentValuePane.paintComponent( g, c, comboBox, bounds.x, bounds.y, bounds.width, bounds.height, shouldValidate );
paddingBorder.uninstall();
if( c instanceof JComponent )
((JComponent)c).setOpaque( true );
}
@Override
@@ -813,12 +813,9 @@ public class FlatComboBoxUI
// make opaque to avoid that background shines thru border (e.g. at 150% scaling)
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" );
if( border != null )
setBorder( FlatUIUtils.nonUIResource( border ) );
setBorder( border );
}
@Override
@@ -832,11 +829,6 @@ public class FlatComboBoxUI
void updateStyle() {
if( popupBackground != null )
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
@@ -923,9 +915,7 @@ public class FlatComboBoxUI
this.padding = padding;
}
// using synchronized to avoid problems with code that modifies combo box
// (model, selection, etc) not on AWT thread (which should be not done)
synchronized void install( Component c ) {
void install( Component c ) {
if( !(c instanceof JComponent) )
return;
@@ -957,7 +947,7 @@ public class FlatComboBoxUI
* there is no single place to uninstall it.
* This is the reason why this method is called from various places.
*/
synchronized void uninstall() {
void uninstall() {
if( rendererComponent == null )
return;
@@ -968,9 +958,9 @@ public class FlatComboBoxUI
}
@Override
synchronized public Insets getBorderInsets( Component c, Insets insets ) {
public Insets getBorderInsets( Component c, Insets insets ) {
Insets padding = scale( this.padding );
if( rendererBorder != null && !(rendererBorder instanceof CellPaddingBorder) ) {
if( rendererBorder != null ) {
Insets insideInsets = rendererBorder.getBorderInsets( c );
insets.top = Math.max( padding.top, insideInsets.top );
insets.left = Math.max( padding.left, insideInsets.left );

View File

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

View File

@@ -262,23 +262,12 @@ public class FlatFileChooserUI
@Override
public FileView getFileView( JFileChooser fc ) {
return doNotUseSystemIcons() ? super.getFileView( fc ) : fileView;
return fileView;
}
@Override
public void clearIconCache() {
if( doNotUseSystemIcons() )
super.clearIconCache();
else
fileView.clearIconCache();
}
private boolean doNotUseSystemIcons() {
// 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.isX86 &&
(SystemInfo.isJava_17_orLater && !SystemInfo.isJava_18_orLater);
fileView.clearIconCache();
}
//---- class FlatFileView -------------------------------------------------

View File

@@ -213,13 +213,6 @@ public class FlatInternalFrameTitlePane
case "componentOrientation":
applyComponentOrientation( frame.getComponentOrientation() );
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 );

View File

@@ -179,26 +179,6 @@ public class FlatInternalFrameUI
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 --------------------------------------
public static class FlatInternalFrameBorder

View File

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

View File

@@ -37,18 +37,15 @@ public class FlatLineBorder
{
private final Color lineColor;
private final float lineThickness;
/** @since 2 */ private final int arc;
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, int arc ) {
public FlatLineBorder( Insets insets, Color lineColor, float lineThickness ) {
super( insets );
this.lineColor = lineColor;
this.lineThickness = lineThickness;
this.arc = arc;
}
public Color getLineColor() {
@@ -59,18 +56,13 @@ public class FlatLineBorder
return lineThickness;
}
/** @since 2 */
public int getArc() {
return arc;
}
@Override
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
Graphics2D g2 = (Graphics2D) g.create();
try {
FlatUIUtils.setRenderingHints( g2 );
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 {
g2.dispose();
}

View File

@@ -37,7 +37,7 @@ import javax.swing.plaf.ListUI;
public class FlatListCellBorder
extends FlatLineBorder
{
/** @since 2 */ protected boolean showCellFocusIndicator = UIManager.getBoolean( "List.showCellFocusIndicator" );
protected boolean showCellFocusIndicator = UIManager.getBoolean( "List.showCellFocusIndicator" );
private Component c;
@@ -113,7 +113,7 @@ public class FlatListCellBorder
/**
* 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
extends FlatListCellBorder
@@ -125,7 +125,7 @@ public class FlatListCellBorder
if( !showCellFocusIndicator )
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 );
if( list != null && list.getMinSelectionIndex() == list.getMaxSelectionIndex() )
return;

View File

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

View File

@@ -53,9 +53,6 @@ public class FlatMenuBarBorder
@Override
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
if( !showBottomSeparator( c ) )
return;
float lineHeight = scale( (float) 1 );
FlatUIUtils.paintFilledRectangle( g, borderColor, x, y + height - lineHeight, width, lineHeight );
}
@@ -71,9 +68,4 @@ public class FlatMenuBarBorder
insets.right = scale( margin.right );
return insets;
}
/** @since 2 */
protected boolean showBottomSeparator( Component c ) {
return !FlatMenuBarUI.useUnifiedBackground( c );
}
}

View File

@@ -17,7 +17,6 @@
package com.formdev.flatlaf.ui;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.Window;
@@ -180,22 +179,20 @@ public class FlatMenuBarUI
protected Color getBackground( JComponent c ) {
Color background = c.getBackground();
// paint background if opaque
if( c.isOpaque() )
// paint background if opaque or if having custom background color
if( c.isOpaque() || !(background instanceof UIResource) )
return background;
// do not paint background if non-opaque and having custom background color
if( !(background instanceof UIResource) )
return null;
// paint background if menu bar is not the "main" menu bar (e.g. in internal frame)
// paint background if menu bar is not the "main" menu bar
JRootPane rootPane = SwingUtilities.getRootPane( c );
if( rootPane == null || !(rootPane.getParent() instanceof Window) || rootPane.getJMenuBar() != c )
return background;
// use parent background for unified title pane
if( useUnifiedBackground( c ) )
background = FlatUIUtils.getParentBackground( c );
// (not storing value of "TitlePane.unifiedBackground" in class to allow changing at runtime)
if( UIManager.getBoolean( "TitlePane.unifiedBackground" ) &&
FlatNativeWindowBorder.hasCustomDecoration( (Window) rootPane.getParent() ) )
background = FlatUIUtils.getParentBackground( c );
// paint background in full screen mode
if( FlatUIUtils.isFullScreen( rootPane ) )
@@ -205,22 +202,6 @@ public class FlatMenuBarUI
return FlatRootPaneUI.isMenuBarEmbedded( rootPane ) ? null : background;
}
/**@since 2 */
static boolean useUnifiedBackground( Component c ) {
// check whether:
// - TitlePane.unifiedBackground is true and
// - menu bar is the "main" menu bar and
// - window has custom decorations enabled
JRootPane rootPane;
// (not storing value of "TitlePane.unifiedBackground" in class to allow changing at runtime)
return UIManager.getBoolean( "TitlePane.unifiedBackground" ) &&
(rootPane = SwingUtilities.getRootPane( c )) != null &&
rootPane.getParent() instanceof Window &&
rootPane.getJMenuBar() == c &&
FlatNativeWindowBorder.hasCustomDecoration( (Window) rootPane.getParent() );
}
//---- class TakeFocus ----------------------------------------------------
/**

View File

@@ -19,7 +19,6 @@ package com.formdev.flatlaf.ui;
import static com.formdev.flatlaf.util.UIScale.scale;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
@@ -33,7 +32,6 @@ import java.awt.event.KeyEvent;
import java.text.AttributedCharacterIterator;
import java.util.Map;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.KeyStroke;
@@ -41,7 +39,6 @@ import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.plaf.basic.BasicHTML;
import javax.swing.text.View;
import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.FlatLaf;
import com.formdev.flatlaf.icons.FlatCheckBoxMenuItemIcon;
import com.formdev.flatlaf.icons.FlatMenuArrowIcon;
@@ -55,15 +52,12 @@ import com.formdev.flatlaf.util.SystemInfo;
/**
* Renderer for menu items.
*
* @uiDefault MenuItem.verticallyAlignText boolean
* @uiDefault MenuItem.minimumWidth int
* @uiDefault MenuItem.minimumIconSize Dimension
* @uiDefault MenuItem.textAcceleratorGap int
* @uiDefault MenuItem.textNoAcceleratorGap int
* @uiDefault MenuItem.acceleratorArrowGap int
* @uiDefault MenuItem.checkBackground Color
* @uiDefault MenuItem.checkMargins Insets
* @uiDefault MenuItem.selectionType String null (default) or underline
* @uiDefault MenuItem.underlineSelectionBackground Color
* @uiDefault MenuItem.underlineSelectionCheckBackground Color
* @uiDefault MenuItem.underlineSelectionColor Color
@@ -73,15 +67,12 @@ import com.formdev.flatlaf.util.SystemInfo;
*/
public class FlatMenuItemRenderer
{
private static final String KEY_MAX_ICONS_WIDTH = "FlatLaf.internal.FlatMenuItemRenderer.maxIconWidth";
protected final JMenuItem menuItem;
protected Icon checkIcon;
protected Icon arrowIcon;
@Styleable protected Font acceleratorFont;
protected final Font acceleratorFont;
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 Dimension minimumIconSize;
@Styleable protected int textAcceleratorGap = FlatUIUtils.getUIInt( "MenuItem.textAcceleratorGap", 28 );
@@ -414,10 +405,11 @@ debug*/
return;
// 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() );
// paint
icon.paintIcon( menuItem, g, iconRect.x, y );
icon.paintIcon( menuItem, g, x, y );
}
protected static void paintText( Graphics g, JMenuItem menuItem,
@@ -452,10 +444,6 @@ debug*/
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 ) {
return menuItem.isArmed() || (menuItem instanceof JMenu && menuItem.isSelected());
}
@@ -486,12 +474,6 @@ debug*/
return pressedIcon;
}
if( isArmedOrSelected( menuItem ) ) {
Icon selectedIcon = menuItem.getSelectedIcon();
if( selectedIcon != null )
return selectedIcon;
}
return icon;
}
@@ -578,44 +560,6 @@ debug*/
shiftGlyph = 0x21E7,
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 --------------------------------------------------
private class MinSizeIcon
@@ -630,7 +574,6 @@ debug*/
@Override
public int getIconWidth() {
int iconWidth = (delegate != null) ? delegate.getIconWidth() : 0;
iconWidth = Math.max( iconWidth, getMaxIconsWidth() );
return Math.max( iconWidth, scale( minimumIconSize.width ) );
}

View File

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

View File

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

View File

@@ -56,7 +56,7 @@ public class FlatNativeWindowBorder
private static final boolean canUseJBRCustomDecorations =
canUseWindowDecorations &&
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 Provider nativeProvider;
@@ -235,8 +235,7 @@ public class FlatNativeWindowBorder
}
static void setTitleBarHeightAndHitTestSpots( Window window, int titleBarHeight,
List<Rectangle> hitTestSpots, Rectangle appIconBounds, Rectangle minimizeButtonBounds,
Rectangle maximizeButtonBounds, Rectangle closeButtonBounds )
List<Rectangle> hitTestSpots, Rectangle appIconBounds )
{
if( canUseJBRCustomDecorations ) {
JBRCustomDecorations.setTitleBarHeightAndHitTestSpots( window, titleBarHeight, hitTestSpots );
@@ -246,8 +245,9 @@ public class FlatNativeWindowBorder
if( !isSupported() )
return;
nativeProvider.updateTitleBarInfo( window, titleBarHeight, hitTestSpots,
appIconBounds, minimizeButtonBounds, maximizeButtonBounds, closeButtonBounds );
nativeProvider.setTitleBarHeight( window, titleBarHeight );
nativeProvider.setTitleBarHitTestSpots( window, hitTestSpots );
nativeProvider.setTitleBarAppIconBounds( window, appIconBounds );
}
static boolean showWindow( Window window, int cmd ) {
@@ -268,7 +268,7 @@ public class FlatNativeWindowBorder
try {
/*
Class<?> cls = Class.forName( "com.formdev.flatlaf.natives.jna.windows.FlatWindowsNativeWindowBorder" );
java.lang.reflect.Method m = cls.getMethod( "getInstance" );
Method m = cls.getMethod( "getInstance" );
setNativeProvider( (Provider) m.invoke( null ) );
*/
setNativeProvider( FlatWindowsNativeWindowBorder.getInstance() );
@@ -292,9 +292,9 @@ public class FlatNativeWindowBorder
{
boolean hasCustomDecoration( Window window );
void setHasCustomDecoration( Window window, boolean hasCustomDecoration );
void updateTitleBarInfo( Window window, int titleBarHeight, List<Rectangle> hitTestSpots,
Rectangle appIconBounds, Rectangle minimizeButtonBounds, Rectangle maximizeButtonBounds,
Rectangle closeButtonBounds );
void setTitleBarHeight( Window window, int titleBarHeight );
void setTitleBarHitTestSpots( Window window, List<Rectangle> hitTestSpots );
void setTitleBarAppIconBounds( Window window, Rectangle appIconBounds );
// commands for showWindow(); values must match Win32 API
// https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-showwindow
@@ -313,10 +313,6 @@ public class FlatNativeWindowBorder
//---- class WindowTopBorder -------------------------------------------
/**
* Window top border used on Windows 10.
* No longer needed since Windows 11.
*/
static class WindowTopBorder
extends JBRCustomDecorations.JBRWindowTopBorder
{

View File

@@ -19,24 +19,21 @@ package com.formdev.flatlaf.ui;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridBagConstraints;
import java.beans.PropertyChangeListener;
import java.awt.Insets;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JRootPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.UIResource;
import javax.swing.plaf.basic.BasicHTML;
import javax.swing.plaf.basic.BasicOptionPaneUI;
import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.util.SwingUtils;
import com.formdev.flatlaf.util.UIScale;
/**
@@ -82,7 +79,6 @@ import com.formdev.flatlaf.util.UIScale;
*
* <!-- FlatOptionPaneUI -->
*
* @uiDefault OptionPane.showIcon boolean
* @uiDefault OptionPane.iconMessageGap int
* @uiDefault OptionPane.messagePadding int
* @uiDefault OptionPane.maxCharactersPerLine int
@@ -92,7 +88,6 @@ import com.formdev.flatlaf.util.UIScale;
public class FlatOptionPaneUI
extends BasicOptionPaneUI
{
/** @since 2 */ protected boolean showIcon;
protected int iconMessageGap;
protected int messagePadding;
protected int maxCharactersPerLine;
@@ -107,7 +102,6 @@ public class FlatOptionPaneUI
protected void installDefaults() {
super.installDefaults();
showIcon = UIManager.getBoolean( "OptionPane.showIcon" );
iconMessageGap = UIManager.getInt( "OptionPane.iconMessageGap" );
messagePadding = UIManager.getInt( "OptionPane.messagePadding" );
maxCharactersPerLine = UIManager.getInt( "OptionPane.maxCharactersPerLine" );
@@ -122,24 +116,6 @@ public class FlatOptionPaneUI
updateChildPanels( optionPane );
}
@Override
protected PropertyChangeListener createPropertyChangeListener() {
PropertyChangeListener superListener = super.createPropertyChangeListener();
return e -> {
superListener.propertyChange( e );
// hide window title bar icon
// (only if showIcon is false, otherwise the default behavior is used)
if( !showIcon && "ancestor".equals( e.getPropertyName() ) && e.getNewValue() != null ) {
JRootPane rootPane = SwingUtilities.getRootPane( optionPane );
if( rootPane != null &&
rootPane.getContentPane().getComponentCount() > 0 &&
rootPane.getContentPane().getComponent( 0 ) == optionPane )
rootPane.putClientProperty( FlatClientProperties.TITLE_BAR_SHOW_ICON, false );
}
};
}
@Override
public Dimension getMinimumOptionPaneSize() {
return UIScale.scale( super.getMinimumOptionPaneSize() );
@@ -157,7 +133,7 @@ public class FlatOptionPaneUI
// set icon-message gap
if( iconMessageGap > 0 ) {
Component iconMessageSeparator = SwingUtils.getComponentByName( messageArea, "OptionPane.separator" );
Component iconMessageSeparator = findByName( messageArea, "OptionPane.separator" );
if( iconMessageSeparator != null )
iconMessageSeparator.setPreferredSize( new Dimension( UIScale.scale( iconMessageGap ), 1 ) );
}
@@ -229,7 +205,7 @@ public class FlatOptionPaneUI
// use non-UIResource borders to avoid that they are replaced when switching LaF
Border border = panel.getBorder();
if( border instanceof UIResource )
panel.setBorder( FlatUIUtils.nonUIResource( border ) );
panel.setBorder( new NonUIResourceBorder( border ) );
}
if( child instanceof Container )
@@ -237,8 +213,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
protected boolean getSizeButtonsToSameWidth() {
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,20 +16,9 @@
package com.formdev.flatlaf.ui;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Map;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicPanelUI;
import com.formdev.flatlaf.FlatClientProperties;
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}.
@@ -38,122 +27,15 @@ import com.formdev.flatlaf.util.UIScale;
*
* @uiDefault Panel.font Font unused
* @uiDefault Panel.background Color only used if opaque
* @uiDefault Panel.foreground Color unused
* @uiDefault Panel.foreground Color
* @uiDefault Panel.border Border
*
* @author Karl Tauber
*/
public class FlatPanelUI
extends BasicPanelUI
implements StyleableUI, PropertyChangeListener
{
// only used via styling (not in UI defaults)
/** @since 2 */ @Styleable protected int arc = -1;
private final boolean shared;
private Map<String, Object> oldStyleValues;
public static ComponentUI createUI( JComponent c ) {
return FlatUIUtils.canUseSharedUI( c )
? 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 );
c.addPropertyChangeListener( this );
installStyle( (JPanel) c );
}
@Override
public void uninstallUI( JComponent c ) {
super.uninstallUI( c );
c.removePropertyChangeListener( this );
oldStyleValues = null;
}
/** @since 2.0.1 */
@Override
public void propertyChange( PropertyChangeEvent e ) {
switch( e.getPropertyName() ) {
case FlatClientProperties.STYLE:
case FlatClientProperties.STYLE_CLASS:
JPanel c = (JPanel) e.getSource();
if( shared && FlatStylingSupport.hasStyleProperty( c ) ) {
// unshare component UI if necessary
// updateUI() invokes installStyle() from installUI()
c.updateUI();
} else
installStyle( c );
c.revalidate();
c.repaint();
break;
}
}
/** @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 );
return FlatUIUtils.createSharedUI( FlatPanelUI.class, FlatPanelUI::new );
}
}

View File

@@ -28,8 +28,6 @@ import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JPasswordField;
import javax.swing.JToggleButton;
import javax.swing.LookAndFeel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
@@ -39,7 +37,6 @@ import javax.swing.text.Element;
import javax.swing.text.JTextComponent;
import javax.swing.text.PasswordView;
import javax.swing.text.View;
import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.icons.FlatCapsLockIcon;
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
import com.formdev.flatlaf.util.UIScale;
@@ -76,29 +73,18 @@ import com.formdev.flatlaf.util.UIScale;
*
* @uiDefault PasswordField.echoChar character
* @uiDefault PasswordField.showCapsLock boolean
* @uiDefault PasswordField.showRevealButton boolean
* @uiDefault PasswordField.capsLockIcon Icon
* @uiDefault PasswordField.revealIcon Icon
*
* @author Karl Tauber
*/
public class FlatPasswordFieldUI
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;
/** @since 2 */ @Styleable protected boolean showRevealButton;
protected Icon capsLockIcon;
/** @since 2 */ protected Icon revealIcon;
private KeyListener capsLockListener;
private boolean capsLockIconShared = true;
private JToggleButton revealButton;
private boolean uninstallEchoChar;
public static ComponentUI createUI( JComponent c ) {
return new FlatPasswordFieldUI();
@@ -109,33 +95,17 @@ public class FlatPasswordFieldUI
return "PasswordField";
}
@Override
public void installUI( JComponent c ) {
super.installUI( c );
installRevealButton();
}
@Override
public void uninstallUI( JComponent c ) {
uninstallRevealButton();
super.uninstallUI( c );
}
@Override
protected void installDefaults() {
super.installDefaults();
String prefix = getPropertyPrefix();
echoChar = (Character) UIManager.get( prefix + ".echoChar" );
Character echoChar = (Character) UIManager.get( prefix + ".echoChar" );
if( echoChar != null )
LookAndFeel.installProperty( getComponent(), "echoChar", echoChar );
showCapsLock = UIManager.getBoolean( "PasswordField.showCapsLock" );
showRevealButton = UIManager.getBoolean( "PasswordField.showRevealButton" );
capsLockIcon = UIManager.getIcon( "PasswordField.capsLockIcon" );
revealIcon = UIManager.getIcon( "PasswordField.revealIcon" );
capsLockIconShared = true;
}
@@ -144,7 +114,6 @@ public class FlatPasswordFieldUI
super.uninstallDefaults();
capsLockIcon = null;
revealIcon = null;
}
@Override
@@ -199,18 +168,6 @@ public class FlatPasswordFieldUI
return "PasswordField";
}
@Override
protected void applyStyle( Object style ) {
boolean oldShowRevealButton = showRevealButton;
super.applyStyle( style );
if( showRevealButton != oldShowRevealButton ) {
uninstallRevealButton();
installRevealButton();
}
}
/** @since 2 */
@Override
protected Object applyStyleProperty( String key, Object value ) {
@@ -275,72 +232,8 @@ public class FlatPasswordFieldUI
if( !showCapsLock )
return false;
return FlatUIUtils.isPermanentFocusOwner( getComponent() ) &&
JTextComponent c = getComponent();
return FlatUIUtils.isPermanentFocusOwner( c ) &&
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

@@ -16,12 +16,10 @@
package com.formdev.flatlaf.ui;
import java.awt.AWTEvent;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
@@ -35,7 +33,6 @@ import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.MouseEvent;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import javax.swing.JComponent;
@@ -124,10 +121,6 @@ public class FlatPopupFactory
popupWindow.getGraphicsConfiguration() == owner.getGraphicsConfiguration() )
return popup;
// avoid endless loop (should newer happen; PopupFactory cache size is 5)
if( ++count > 10 )
return popup;
// remove contents component from popup window
if( popupWindow instanceof JWindow )
((JWindow)popupWindow).getContentPane().removeAll();
@@ -135,6 +128,10 @@ public class FlatPopupFactory
// dispose unused popup
// (do not invoke popup.hide() because this would cache the popup window)
popupWindow.dispose();
// avoid endless loop (should newer happen; PopupFactory cache size is 5)
if( ++count > 10 )
return popup;
}
}
@@ -222,7 +219,7 @@ public class FlatPopupFactory
* and corrects the y-location so that the tooltip is placed above the mouse location.
*/
private Point fixToolTipLocation( Component owner, Component contents, int x, int y ) {
if( !(contents instanceof JToolTip) || !wasInvokedFromToolTipManager() || hasTipLocation( owner ) )
if( !(contents instanceof JToolTip) || !wasInvokedFromToolTipManager() )
return null;
PointerInfo pointerInfo = MouseInfo.getPointerInfo();
@@ -267,35 +264,6 @@ public class FlatPopupFactory
return StackUtils.wasInvokedFrom( ToolTipManager.class.getName(), "showTipWindow", 8 );
}
/**
* Checks whether the owner component returns a tooltip location in
* JComponent.getToolTipLocation(MouseEvent).
*/
private boolean hasTipLocation( Component owner ) {
if( !(owner instanceof JComponent) )
return false;
AWTEvent e = EventQueue.getCurrentEvent();
MouseEvent me;
if( e instanceof MouseEvent )
me = (MouseEvent) e;
else {
// no mouse event available because a timer is used to show the tooltip
// --> create mouse event from current mouse location
PointerInfo pointerInfo = MouseInfo.getPointerInfo();
if( pointerInfo == null )
return false;
Point location = new Point( pointerInfo.getLocation());
SwingUtilities.convertPointFromScreen( location, owner );
me = new MouseEvent( owner, MouseEvent.MOUSE_MOVED, System.currentTimeMillis(),
0, location.x, location.y, 0, false );
}
return me.getSource() == owner &&
((JComponent)owner).getToolTipLocation( me ) != null;
}
//---- class NonFlashingPopup ---------------------------------------------
private class NonFlashingPopup

View File

@@ -16,18 +16,12 @@
package com.formdev.flatlaf.ui;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.LayoutManager;
import java.beans.PropertyChangeListener;
import java.util.Map;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.swing.BoxLayout;
import javax.swing.JComponent;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.UIResource;
import javax.swing.plaf.basic.BasicPopupMenuUI;
import javax.swing.plaf.basic.DefaultMenuLayout;
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
import com.formdev.flatlaf.util.LoggingFacade;
@@ -70,15 +64,6 @@ public class FlatPopupMenuUI
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
protected void installListeners() {
super.installListeners();
@@ -121,21 +106,4 @@ public class FlatPopupMenuUI
public Map<String, Class<?>> getStyleableInfos( JComponent c ) {
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() {
super.uninstallDefaults();
FlatMenuItemRenderer.clearClientProperties( menuItem.getParent() );
renderer = null;
oldStyleValues = null;
}

View File

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

View File

@@ -66,9 +66,6 @@ import com.formdev.flatlaf.util.UIScale;
*
* <!-- FlatWindowResizer -->
*
* @uiDefault RootPane.font Font unused
* @uiDefault RootPane.background Color
* @uiDefault RootPane.foreground Color unused
* @uiDefault RootPane.borderDragThickness int
* @uiDefault RootPane.cornerDragWidth int
* @uiDefault RootPane.honorFrameMinimumSizeOnResize boolean
@@ -129,23 +126,8 @@ public class FlatRootPaneUI
protected void installDefaults( JRootPane c ) {
super.installDefaults( c );
// Give the root pane useful background, foreground and font.
// Background is used for title bar and menu bar if native window decorations
// and unified background are enabled.
// Foreground and font are usually not used, but set for completeness.
// Not using LookAndFeel.installColorsAndFont() here because it will not work
// because the properties are null by default but inherit non-null values from parent.
if( !c.isBackgroundSet() || c.getBackground() instanceof UIResource )
c.setBackground( UIManager.getColor( "RootPane.background" ) );
if( !c.isForegroundSet() || c.getForeground() instanceof UIResource )
c.setForeground( UIManager.getColor( "RootPane.foreground" ) );
if( !c.isFontSet() || c.getFont() instanceof UIResource )
c.setFont( UIManager.getFont( "RootPane.font" ) );
// Update background color of JFrame or JDialog parent to avoid bad border
// on HiDPI screens when switching from light to dark Laf.
// Window background color is also used in native window decorations
// to fill background when window is initially shown or when resizing window.
// The background of JFrame is initialized in JFrame.frameInit() and
// the background of JDialog in JDialog.dialogInit(),
// but it was not updated when switching Laf.
@@ -161,19 +143,6 @@ public class FlatRootPaneUI
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
protected void installListeners( JRootPane root ) {
super.installListeners( root );
@@ -344,11 +313,6 @@ public class FlatRootPaneUI
}
break;
case FlatClientProperties.TITLE_BAR_SHOW_ICON:
if( titlePane != null )
titlePane.updateIcon();
break;
case FlatClientProperties.TITLE_BAR_BACKGROUND:
case FlatClientProperties.TITLE_BAR_FOREGROUND:
if( titlePane != null )

View File

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

View File

@@ -291,10 +291,6 @@ public class FlatScrollPaneUI
}
break;
case FlatClientProperties.OUTLINE:
scrollpane.repaint();
break;
case FlatClientProperties.STYLE:
case FlatClientProperties.STYLE_CLASS:
installStyle();

View File

@@ -21,7 +21,6 @@ import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Map;
import javax.swing.JComponent;
@@ -29,7 +28,6 @@ import javax.swing.JSeparator;
import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicSeparatorUI;
import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
import com.formdev.flatlaf.util.LoggingFacade;
@@ -52,7 +50,7 @@ import com.formdev.flatlaf.util.LoggingFacade;
*/
public class FlatSeparatorUI
extends BasicSeparatorUI
implements StyleableUI, PropertyChangeListener
implements StyleableUI
{
@Styleable protected int height;
@Styleable protected int stripeWidth;
@@ -60,6 +58,7 @@ public class FlatSeparatorUI
private final boolean shared;
private boolean defaults_initialized = false;
private PropertyChangeListener propertyChangeListener;
private Map<String, Object> oldStyleValues;
public static ComponentUI createUI( JComponent c ) {
@@ -110,33 +109,28 @@ public class FlatSeparatorUI
protected void installListeners( JSeparator s ) {
super.installListeners( s );
s.addPropertyChangeListener( this );
propertyChangeListener = FlatStylingSupport.createPropertyChangeListener(
s, () -> stylePropertyChange( s ), null );
s.addPropertyChangeListener( propertyChangeListener );
}
@Override
protected void uninstallListeners( JSeparator s ) {
super.uninstallListeners( s );
s.removePropertyChangeListener( this );
s.removePropertyChangeListener( propertyChangeListener );
propertyChangeListener = null;
}
/** @since 2.0.1 */
@Override
public void propertyChange( PropertyChangeEvent e ) {
switch( e.getPropertyName() ) {
case FlatClientProperties.STYLE:
case FlatClientProperties.STYLE_CLASS:
JSeparator s = (JSeparator) e.getSource();
if( shared && FlatStylingSupport.hasStyleProperty( s ) ) {
// unshare component UI if necessary
// updateUI() invokes installStyle() from installUI()
s.updateUI();
} else
installStyle( s );
s.revalidate();
s.repaint();
break;
}
private void stylePropertyChange( JSeparator s ) {
if( shared && FlatStylingSupport.hasStyleProperty( s ) ) {
// unshare component UI if necessary
// updateUI() invokes applyStyle() from installUI()
s.updateUI();
} else
installStyle( s );
s.revalidate();
s.repaint();
}
/** @since 2 */

View File

@@ -71,7 +71,7 @@ import com.formdev.flatlaf.util.LoggingFacade;
* @uiDefault Spinner.disabledBackground Color
* @uiDefault Spinner.disabledForeground Color
* @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.buttonSeparatorColor Color optional
* @uiDefault Spinner.buttonDisabledSeparatorColor Color optional
@@ -385,7 +385,7 @@ public class FlatSpinnerUI
boolean isLeftToRight = spinner.getComponentOrientation().isLeftToRight();
// paint arrow buttons background
if( enabled && buttonBackground != null ) {
if( enabled ) {
g2.setColor( buttonBackground );
Shape oldClip = g2.getClip();
if( isLeftToRight )
@@ -398,7 +398,7 @@ public class FlatSpinnerUI
// paint vertical line between value and arrow buttons
Color separatorColor = enabled ? buttonSeparatorColor : buttonDisabledSeparatorColor;
if( separatorColor != null && buttonSeparatorWidth > 0 ) {
if( separatorColor != null ) {
g2.setColor( separatorColor );
float lw = scale( buttonSeparatorWidth );
float lx = isLeftToRight ? arrowX : arrowX + arrowWidth - lw;
@@ -538,7 +538,6 @@ public class FlatSpinnerUI
break;
case FlatClientProperties.COMPONENT_ROUND_RECT:
case FlatClientProperties.OUTLINE:
spinner.repaint();
break;

View File

@@ -97,7 +97,8 @@ public class FlatStylingSupport
Object style = getStyle( c );
Object styleClass = getStyleClass( c );
Object styleForClasses = getStyleForClasses( styleClass, type );
return joinStyles( styleForClasses, style );
Object styleForType = getStyleForType( type );
return joinStyles( joinStyles( styleForType, styleForClasses ), style );
}
/**
@@ -162,6 +163,28 @@ public class FlatStylingSupport
UIManager.get( "[style]" + type + '.' + styleClass ) );
}
/**
* Returns the styles for the given type.
* <p>
* The style rules must be defined in UI defaults either as strings (in CSS syntax)
* or as {@link java.util.Map}&lt;String, Object&gt; (with binary values).
* The key must be in syntax: {@code [style]type}.
* E.g. in FlatLaf properties file:
* <pre>{@code
* [style]Button = borderColor: #08f; background: #08f; foreground: #fff
* }</pre>
* or in Java code:
* <pre>{@code
* UIManager.put( "[style]Button", "borderColor: #08f; background: #08f; foreground: #fff" );
* }</pre>
*
* @param type the type of the component
* @return the styles
*/
public static Object getStyleForType( String type ) {
return UIManager.get( "[style]" + type );
}
/**
* Joins two styles. They can be either strings (in CSS syntax)
* or {@link java.util.Map}&lt;String, Object&gt; (with binary values).
@@ -462,22 +485,34 @@ public class FlatStylingSupport
String getterName = buildMethodName( "get", name );
String setterName = buildMethodName( "set", name );
try {
Method getter;
for(;;) {
try {
getter = cls.getMethod( getterName );
Method getter;
try {
getter = cls.getMethod( getterName );
} catch( NoSuchMethodException ex ) {
getter = cls.getMethod( buildMethodName( "is", name ) );
}
Method setter = cls.getMethod( setterName, getter.getReturnType() );
Object oldValue = getter.invoke( obj );
setter.invoke( obj, convertToEnum( value, getter.getReturnType() ) );
return oldValue;
} catch( NoSuchMethodException ex ) {
getter = cls.getMethod( buildMethodName( "is", name ) );
throw new UnknownStyleException( name );
} catch( Exception ex ) {
if( ex instanceof IllegalAccessException ) {
// this may happen for private subclasses of public Swing classes
// that override public property getter/setter
// e.g. class JSlider.SmartHashtable.LabelUIResource.getForeground()
// --> try again with superclass
cls = cls.getSuperclass();
if( cls != null && cls != Object.class )
continue;
}
throw new IllegalArgumentException( "failed to invoke property methods '" + cls.getName() + "."
+ getterName + "()' or '" + setterName + "(...)'", ex );
}
Method setter = cls.getMethod( setterName, getter.getReturnType() );
Object oldValue = getter.invoke( obj );
setter.invoke( obj, convertToEnum( value, getter.getReturnType() ) );
return oldValue;
} catch( NoSuchMethodException ex ) {
throw new UnknownStyleException( name );
} catch( Exception ex ) {
throw new IllegalArgumentException( "failed to invoke property methods '" + cls.getName() + "."
+ getterName + "()' or '" + setterName + "(...)'", ex );
}
}

View File

@@ -40,8 +40,6 @@ import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.ContainerEvent;
import java.awt.event.ContainerListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
@@ -136,15 +134,12 @@ import com.formdev.flatlaf.util.UIScale;
* @uiDefault TabbedPane.maximumTabWidth int optional
* @uiDefault TabbedPane.tabHeight int
* @uiDefault TabbedPane.tabSelectionHeight int
* @uiDefault TabbedPane.cardTabSelectionHeight int
* @uiDefault TabbedPane.contentSeparatorHeight int
* @uiDefault TabbedPane.showTabSeparators boolean
* @uiDefault TabbedPane.tabSeparatorsFullHeight boolean
* @uiDefault TabbedPane.hasFullBorder boolean
* @uiDefault TabbedPane.activeTabBorder boolean
*
* @uiDefault TabbedPane.tabLayoutPolicy String wrap (default) or scroll
* @uiDefault TabbedPane.tabType String underlined (default) or card
* @uiDefault TabbedPane.tabsPopupPolicy String never or asNeeded (default)
* @uiDefault TabbedPane.scrollButtonsPolicy String never, asNeeded or asNeededSingle (default)
* @uiDefault TabbedPane.scrollButtonsPlacement String both (default) or trailing
@@ -170,10 +165,6 @@ public class FlatTabbedPaneUI
extends BasicTabbedPaneUI
implements StyleableUI
{
// tab type
/** @since 2 */ protected static final int TAB_TYPE_UNDERLINED = 0;
/** @since 2 */ protected static final int TAB_TYPE_CARD = 1;
// tabs popup policy / scroll arrows policy
protected static final int NEVER = 0;
// protected static final int ALWAYS = 1;
@@ -209,14 +200,12 @@ public class FlatTabbedPaneUI
@Styleable protected int maximumTabWidth;
@Styleable protected int tabHeight;
@Styleable protected int tabSelectionHeight;
/** @since 2 */ @Styleable protected int cardTabSelectionHeight;
@Styleable protected int contentSeparatorHeight;
@Styleable protected boolean showTabSeparators;
@Styleable protected boolean tabSeparatorsFullHeight;
@Styleable protected boolean hasFullBorder;
@Styleable protected boolean tabsOpaque = true;
@Styleable(type=String.class) private int tabType;
@Styleable(type=String.class) private int tabsPopupPolicy;
@Styleable(type=String.class) private int scrollButtonsPolicy;
@Styleable(type=String.class) private int scrollButtonsPlacement;
@@ -329,14 +318,12 @@ public class FlatTabbedPaneUI
maximumTabWidth = UIManager.getInt( "TabbedPane.maximumTabWidth" );
tabHeight = UIManager.getInt( "TabbedPane.tabHeight" );
tabSelectionHeight = UIManager.getInt( "TabbedPane.tabSelectionHeight" );
cardTabSelectionHeight = UIManager.getInt( "TabbedPane.cardTabSelectionHeight" );
contentSeparatorHeight = UIManager.getInt( "TabbedPane.contentSeparatorHeight" );
showTabSeparators = UIManager.getBoolean( "TabbedPane.showTabSeparators" );
tabSeparatorsFullHeight = UIManager.getBoolean( "TabbedPane.tabSeparatorsFullHeight" );
hasFullBorder = UIManager.getBoolean( "TabbedPane.hasFullBorder" );
tabsOpaque = UIManager.getBoolean( "TabbedPane.tabsOpaque" );
tabType = parseTabType( UIManager.getString( "TabbedPane.tabType" ) );
tabsPopupPolicy = parseTabsPopupPolicy( UIManager.getString( "TabbedPane.tabsPopupPolicy" ) );
scrollButtonsPolicy = parseScrollButtonsPolicy( UIManager.getString( "TabbedPane.scrollButtonsPolicy" ) );
scrollButtonsPlacement = parseScrollButtonsPlacement( UIManager.getString( "TabbedPane.scrollButtonsPlacement" ) );
@@ -573,13 +560,6 @@ public class FlatTabbedPaneUI
return handler;
}
@Override
protected FocusListener createFocusListener() {
Handler handler = getHandler();
handler.focusDelegate = super.createFocusListener();
return handler;
}
@Override
protected LayoutManager createLayoutManager() {
if( tabPane.getTabLayoutPolicy() == JTabbedPane.WRAP_TAB_LAYOUT )
@@ -638,7 +618,6 @@ public class FlatTabbedPaneUI
if( value instanceof String ) {
switch( key ) {
case "tabType": value = parseTabType( (String) value ); break;
case "tabsPopupPolicy": value = parseTabsPopupPolicy( (String) value ); break;
case "scrollButtonsPolicy": value = parseScrollButtonsPolicy( (String) value ); break;
case "scrollButtonsPlacement": value = parseScrollButtonsPlacement( (String) value ); break;
@@ -728,25 +707,8 @@ public class FlatTabbedPaneUI
return;
Rectangle r = getTabBounds( tabPane, tabIndex );
if( r == null )
return;
// increase size of repaint region to include part of content border
if( contentSeparatorHeight > 0 &&
getTabType() == TAB_TYPE_CARD &&
clientPropertyBoolean( tabPane, TABBED_PANE_SHOW_CONTENT_SEPARATOR, true ) )
{
int sh = scale( contentSeparatorHeight );
switch( tabPane.getTabPlacement() ) {
default:
case TOP: r.height += sh; break;
case BOTTOM: r.height += sh; r.y -= sh; break;
case LEFT: r.width += sh; break;
case RIGHT: r.width += sh; r.x -= sh; break;
}
}
tabPane.repaint( r );
if( r != null )
tabPane.repaint( r );
}
private boolean inCalculateEqual;
@@ -1083,21 +1045,16 @@ public class FlatTabbedPaneUI
int x, int y, int w, int h, boolean isSelected )
{
// paint tab background
Color background = getTabBackground( tabPlacement, tabIndex, isSelected );
g.setColor( FlatUIUtils.deriveColor( background, tabPane.getBackground() ) );
g.fillRect( x, y, w, h );
}
/** @since 2 */
protected Color getTabBackground( int tabPlacement, int tabIndex, boolean isSelected ) {
boolean enabled = tabPane.isEnabled();
return enabled && tabPane.isEnabledAt( tabIndex ) && getRolloverTab() == tabIndex
Color background = enabled && tabPane.isEnabledAt( tabIndex ) && getRolloverTab() == tabIndex
? hoverColor
: (enabled && isSelected && FlatUIUtils.isPermanentFocusOwner( tabPane )
? focusColor
: (selectedBackground != null && enabled && isSelected
? selectedBackground
: tabPane.getBackgroundAt( tabIndex )));
g.setColor( FlatUIUtils.deriveColor( background, tabPane.getBackground() ) );
g.fillRect( x, y, w, h );
}
@Override
@@ -1107,62 +1064,7 @@ public class FlatTabbedPaneUI
// paint tab separators
if( clientPropertyBoolean( tabPane, TABBED_PANE_SHOW_TAB_SEPARATORS, showTabSeparators ) &&
!isLastInRun( tabIndex ) )
{
if( getTabType() == TAB_TYPE_CARD ) {
// some separators need to be omitted if selected tab is painted as card
int selectedIndex = tabPane.getSelectedIndex();
if( tabIndex != selectedIndex - 1 && tabIndex != selectedIndex )
paintTabSeparator( g, tabPlacement, x, y, w, h );
} else
paintTabSeparator( g, tabPlacement, x, y, w, h );
}
// paint active tab border
if( isSelected && getTabType() == TAB_TYPE_CARD )
paintCardTabBorder( g, tabPlacement, tabIndex, x, y, w, h );
}
/** @since 2 */
protected void paintCardTabBorder( Graphics g, int tabPlacement, int tabIndex, int x, int y, int w, int h ) {
Graphics2D g2 = (Graphics2D) g;
float borderWidth = scale( (float) contentSeparatorHeight );
g.setColor( (tabSeparatorColor != null) ? tabSeparatorColor : contentAreaColor );
switch( tabPlacement ) {
default:
case TOP:
case BOTTOM:
// paint left and right tab border
g2.fill( new Rectangle2D.Float( x, y, borderWidth, h ) );
g2.fill( new Rectangle2D.Float( x + w - borderWidth, y, borderWidth, h ) );
break;
case LEFT:
case RIGHT:
// paint top and bottom tab border
g2.fill( new Rectangle2D.Float( x, y, w, borderWidth ) );
g2.fill( new Rectangle2D.Float( x, y + h - borderWidth, w, borderWidth ) );
break;
}
if( cardTabSelectionHeight <= 0 ) {
// if there is no tab selection indicator, paint a top border as well
switch( tabPlacement ) {
default:
case TOP:
g2.fill( new Rectangle2D.Float( x, y, w, borderWidth ) );
break;
case BOTTOM:
g2.fill( new Rectangle2D.Float( x, y + h - borderWidth, w, borderWidth ) );
break;
case LEFT:
g2.fill( new Rectangle2D.Float( x, y, borderWidth, h ) );
break;
case RIGHT:
g2.fill( new Rectangle2D.Float( x + w - borderWidth, y, borderWidth, h ) );
break;
}
}
paintTabSeparator( g, tabPlacement, x, y, w, h );
}
protected void paintTabCloseButton( Graphics g, int tabIndex, int x, int y, int w, int h ) {
@@ -1208,30 +1110,26 @@ public class FlatTabbedPaneUI
g.setColor( tabPane.isEnabled() ? underlineColor : disabledUnderlineColor );
// paint underline selection
boolean atBottom = (getTabType() != TAB_TYPE_CARD);
Insets contentInsets = getContentBorderInsets( tabPlacement );
int tabSelectionHeight = scale( atBottom ? this.tabSelectionHeight : cardTabSelectionHeight );
int sx, sy;
int tabSelectionHeight = scale( this.tabSelectionHeight );
switch( tabPlacement ) {
case TOP:
default:
sy = atBottom ? (y + h + contentInsets.top - tabSelectionHeight) : y;
int sy = y + h + contentInsets.top - tabSelectionHeight;
g.fillRect( x, sy, w, tabSelectionHeight );
break;
case BOTTOM:
sy = atBottom ? (y - contentInsets.bottom) : (y + h - tabSelectionHeight);
g.fillRect( x, sy, w, tabSelectionHeight );
g.fillRect( x, y - contentInsets.bottom, w, tabSelectionHeight );
break;
case LEFT:
sx = atBottom ? (x + w + contentInsets.left - tabSelectionHeight) : x;
int sx = x + w + contentInsets.left - tabSelectionHeight;
g.fillRect( sx, y, tabSelectionHeight, h );
break;
case RIGHT:
sx = atBottom ? (x - contentInsets.right) : (x + w - tabSelectionHeight);
g.fillRect( sx, y, tabSelectionHeight, h );
g.fillRect( x - contentInsets.right, y, tabSelectionHeight, h );
break;
}
}
@@ -1243,7 +1141,6 @@ public class FlatTabbedPaneUI
* - paint full border (if enabled)
* - not invoking paintContentBorder*Edge() methods
* - repaint selection
* - painting active tab border style
*/
@Override
protected void paintContentBorder( Graphics g, int tabPlacement, int selectedIndex ) {
@@ -1292,49 +1189,12 @@ public class FlatTabbedPaneUI
Insets ci = new Insets( 0, 0, 0, 0 );
rotateInsets( hasFullBorder ? new Insets( sh, sh, sh, sh ) : new Insets( sh, 0, 0, 0 ), ci, tabPlacement );
// create path for content separator or full border
// paint content separator or full border
g.setColor( contentAreaColor );
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD );
path.append( new Rectangle2D.Float( x, y, w, h ), false );
path.append( new Rectangle2D.Float( x + (ci.left / 100f), y + (ci.top / 100f),
w - (ci.left / 100f) - (ci.right / 100f), h - (ci.top / 100f) - (ci.bottom / 100f) ), false );
// add gap for selected tab to path
if( getTabType() == TAB_TYPE_CARD ) {
float csh = scale( (float) contentSeparatorHeight );
Rectangle tabRect = getTabBounds( tabPane, selectedIndex );
Rectangle2D.Float innerTabRect = new Rectangle2D.Float( tabRect.x + csh, tabRect.y + csh,
tabRect.width - (csh * 2), tabRect.height - (csh * 2) );
// Ensure that the separator outside the tabViewport is present (doesn't get cutoff by the active tab)
// If left unsolved the active tab is "visible" in the separator (the gap) even when outside the viewport
if( tabViewport != null )
Rectangle2D.intersect( tabViewport.getBounds(), innerTabRect, innerTabRect );
Rectangle2D.Float gap = null;
if( isHorizontalTabPlacement() ) {
if( innerTabRect.width > 0 ) {
float y2 = (tabPlacement == TOP) ? y : y + h - csh;
gap = new Rectangle2D.Float( innerTabRect.x, y2, innerTabRect.width, csh );
}
} else {
if( innerTabRect.height > 0 ) {
float x2 = (tabPlacement == LEFT) ? x : x + w - csh;
gap = new Rectangle2D.Float( x2, innerTabRect.y, csh, innerTabRect.height );
}
}
if( gap != null ) {
path.append( gap, false );
// fill gap in case that the tab is colored (e.g. focused or hover)
g.setColor( getTabBackground( tabPlacement, selectedIndex, true ) );
((Graphics2D)g).fill( gap );
}
}
// paint content separator or full border
g.setColor( contentAreaColor );
((Graphics2D)g).fill( path );
// repaint selection in scroll-tab-layout because it may be painted before
@@ -1539,15 +1399,6 @@ public class FlatTabbedPaneUI
clientPropertyBoolean( tabPane, TABBED_PANE_HIDE_TAB_AREA_WITH_ONE_TAB, hideTabAreaWithOneTab );
}
/** @since 2 */
protected int getTabType() {
Object value = tabPane.getClientProperty( TABBED_PANE_TAB_TYPE );
return (value instanceof String)
? parseTabType( (String) value )
: tabType;
}
protected int getTabsPopupPolicy() {
Object value = tabPane.getClientProperty( TABBED_PANE_TABS_POPUP_POLICY );
@@ -1600,18 +1451,6 @@ public class FlatTabbedPaneUI
: tabWidthMode;
}
/** @since 2 */
protected static int parseTabType( String str ) {
if( str == null )
return TAB_TYPE_UNDERLINED;
switch( str ) {
default:
case TABBED_PANE_TAB_TYPE_UNDERLINED: return TAB_TYPE_UNDERLINED;
case TABBED_PANE_TAB_TYPE_CARD: return TAB_TYPE_CARD;
}
}
protected static int parseTabsPopupPolicy( String str ) {
if( str == null )
return AS_NEEDED;
@@ -2425,12 +2264,11 @@ public class FlatTabbedPaneUI
private class Handler
implements MouseListener, MouseMotionListener, PropertyChangeListener,
ChangeListener, ComponentListener, ContainerListener, FocusListener
ChangeListener, ComponentListener, ContainerListener
{
MouseListener mouseDelegate;
PropertyChangeListener propertyChangeDelegate;
ChangeListener changeDelegate;
FocusListener focusDelegate;
private final PropertyChangeListener contentListener = this::contentPropertyChange;
@@ -2600,10 +2438,6 @@ public class FlatTabbedPaneUI
break;
case TABBED_PANE_SHOW_TAB_SEPARATORS:
case TABBED_PANE_TAB_TYPE:
tabPane.repaint();
break;
case TABBED_PANE_SHOW_CONTENT_SEPARATOR:
case TABBED_PANE_HAS_FULL_BORDER:
case TABBED_PANE_HIDE_TAB_AREA_WITH_ONE_TAB:
@@ -2702,20 +2536,6 @@ public class FlatTabbedPaneUI
if( !(c instanceof UIResource) )
c.removePropertyChangeListener( contentListener );
}
//---- interface FocusListener ----
@Override
public void focusGained( FocusEvent e ) {
focusDelegate.focusGained( e );
repaintTab( tabPane.getSelectedIndex() );
}
@Override
public void focusLost( FocusEvent e ) {
focusDelegate.focusLost( e );
repaintTab( tabPane.getSelectedIndex() );
}
}
//---- class FlatTabbedPaneLayout -----------------------------------------

View File

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

View File

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

View File

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

View File

@@ -108,9 +108,9 @@ public class FlatTableUI
@Styleable protected Color selectionInactiveForeground;
// for FlatTableCellBorder
/** @since 2 */ @Styleable protected Insets cellMargins;
/** @since 2 */ @Styleable protected Color cellFocusColor;
/** @since 2 */ @Styleable protected Boolean showCellFocusIndicator;
@Styleable protected Insets cellMargins;
@Styleable protected Color cellFocusColor;
@Styleable protected boolean showCellFocusIndicator;
private boolean oldShowHorizontalLines;
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.util.UIScale.scale;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.LayoutManager;
import java.awt.LayoutManager2;
import java.awt.Rectangle;
import java.awt.event.FocusListener;
import java.beans.PropertyChangeEvent;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Consumer;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.JToggleButton;
import javax.swing.JToolBar;
import javax.swing.LookAndFeel;
import javax.swing.UIManager;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.UIResource;
import javax.swing.plaf.basic.BasicTextFieldUI;
import javax.swing.text.Caret;
import javax.swing.text.Document;
import javax.swing.text.JTextComponent;
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
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 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 oldInactiveBackground;
@@ -118,7 +101,6 @@ public class FlatTextFieldUI
private Insets defaultMargin;
private FocusListener focusListener;
private DocumentListener documentListener;
private Map<String, Object> oldStyleValues;
private AtomicBoolean borderShared;
@@ -133,19 +115,11 @@ public class FlatTextFieldUI
leadingIcon = clientProperty( c, TEXT_FIELD_LEADING_ICON, null, Icon.class );
trailingIcon = clientProperty( c, TEXT_FIELD_TRAILING_ICON, null, Icon.class );
installLeadingComponent();
installTrailingComponent();
installClearButton();
installStyle();
}
@Override
public void uninstallUI( JComponent c ) {
uninstallLeadingComponent();
uninstallTrailingComponent();
uninstallClearButton();
super.uninstallUI( c );
leadingIcon = null;
@@ -207,11 +181,6 @@ public class FlatTextFieldUI
getComponent().removeFocusListener( focusListener );
focusListener = null;
if( documentListener != null ) {
getComponent().getDocument().removeDocumentListener( documentListener );
documentListener = null;
}
}
@Override
@@ -232,7 +201,6 @@ public class FlatTextFieldUI
switch( e.getPropertyName() ) {
case PLACEHOLDER_TEXT:
case COMPONENT_ROUND_RECT:
case OUTLINE:
case TEXT_FIELD_PADDING:
c.repaint();
break;
@@ -257,61 +225,9 @@ public class FlatTextFieldUI
trailingIcon = (e.getNewValue() instanceof Icon) ? (Icon) e.getNewValue() : null;
c.repaint();
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 */
protected void installStyle() {
try {
@@ -330,15 +246,10 @@ public class FlatTextFieldUI
protected void applyStyle( Object style ) {
oldDisabledBackground = disabledBackground;
oldInactiveBackground = inactiveBackground;
boolean oldShowClearButton = showClearButton;
oldStyleValues = FlatStylingSupport.parseAndApply( oldStyleValues, style, this::applyStyleProperty );
updateBackground();
if( showClearButton != oldShowClearButton ) {
uninstallClearButton();
installClearButton();
}
}
/** @since 2 */
@@ -533,16 +444,6 @@ debug*/
// add width of leading and trailing icons
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;
}
@@ -609,8 +510,7 @@ debug*/
/**
* Returns the rectangle used to paint leading and trailing icons.
* It invokes {@code super.getVisibleEditorRect()} and reduces left and/or
* right margin if the text field has leading or trailing icons or components.
* Also the preferred widths of leading and trailing components are removed.
* right margin if the text field has leading or trailing icons.
*
* @since 2
*/
@@ -619,31 +519,10 @@ debug*/
if( r == null )
return null;
boolean ltr = isLeftToRight();
// 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
// if a leading/trailing icon is shown, then the left/right margin is reduced
// 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
Insets margin = getComponent().getMargin();
int newLeftMargin = Math.min( margin.left, margin.top );
@@ -653,7 +532,7 @@ debug*/
r.width += diff;
}
}
if( rightVisible || (ltr ? hasTrailingIcon() : hasLeadingIcon()) ) {
if( ltr ? hasTrailingIcon() : hasLeadingIcon() ) {
// reduce right margin
Insets margin = getComponent().getMargin();
int newRightMargin = Math.min( margin.right, margin.top );
@@ -661,10 +540,6 @@ debug*/
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;
}
@@ -703,266 +578,4 @@ debug*/
if( caret instanceof FlatCaret )
((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

@@ -50,6 +50,8 @@ import javax.accessibility.AccessibleContext;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
@@ -64,6 +66,7 @@ import javax.swing.border.Border;
import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.FlatSystemProperties;
import com.formdev.flatlaf.ui.FlatNativeWindowBorder.WindowTopBorder;
import com.formdev.flatlaf.util.ScaledImageIcon;
import com.formdev.flatlaf.util.SystemInfo;
import com.formdev.flatlaf.util.UIScale;
@@ -77,8 +80,6 @@ import com.formdev.flatlaf.util.UIScale;
* @uiDefault TitlePane.embeddedForeground Color
* @uiDefault TitlePane.borderColor Color optional
* @uiDefault TitlePane.unifiedBackground boolean
* @uiDefault TitlePane.showIcon boolean
* @uiDefault TitlePane.noIconLeftGap int
* @uiDefault TitlePane.iconSize Dimension
* @uiDefault TitlePane.iconMargins Insets
* @uiDefault TitlePane.titleMargins Insets
@@ -87,6 +88,7 @@ import com.formdev.flatlaf.util.UIScale;
* @uiDefault TitlePane.centerTitle boolean
* @uiDefault TitlePane.centerTitleIfMenuBarEmbedded boolean
* @uiDefault TitlePane.menuBarTitleGap int
* @uiDefault TitlePane.icon Icon
* @uiDefault TitlePane.closeIcon Icon
* @uiDefault TitlePane.iconifyIcon Icon
* @uiDefault TitlePane.maximizeIcon Icon
@@ -104,8 +106,6 @@ public class FlatTitlePane
protected final Color embeddedForeground = UIManager.getColor( "TitlePane.embeddedForeground" );
protected final Color borderColor = UIManager.getColor( "TitlePane.borderColor" );
/** @since 2 */ protected final boolean showIcon = FlatUIUtils.getUIBoolean( "TitlePane.showIcon", true );
/** @since 2 */ protected final int noIconLeftGap = FlatUIUtils.getUIInt( "TitlePane.noIconLeftGap", 8 );
protected final Dimension iconSize = UIManager.getDimension( "TitlePane.iconSize" );
protected final int buttonMaximizedHeight = UIManager.getInt( "TitlePane.buttonMaximizedHeight" );
protected final boolean centerTitle = UIManager.getBoolean( "TitlePane.centerTitle" );
@@ -224,11 +224,6 @@ public class FlatTitlePane
restoreButton = createButton( "TitlePane.restoreIcon", "Restore", e -> restore() );
closeButton = createButton( "TitlePane.closeIcon", "Close", e -> close() );
// initially hide buttons that are only supported in frames
iconifyButton.setVisible( false );
maximizeButton.setVisible( false );
restoreButton.setVisible( false );
buttonPanel = new JPanel() {
@Override
public Dimension getPreferredSize() {
@@ -248,9 +243,11 @@ public class FlatTitlePane
if( rootPane.getWindowDecorationStyle() == JRootPane.FRAME ) {
// JRootPane.FRAME works only for frames (and not for dialogs)
// but at this time the owner window type is unknown (not yet added)
// so we add the iconify/maximize/restore buttons and they are shown
// so we add the iconify/maximize/restore buttons and they are hidden
// later in frameStateChanged(), which is invoked from addNotify()
restoreButton.setVisible( false );
buttonPanel.add( iconifyButton );
buttonPanel.add( maximizeButton );
buttonPanel.add( restoreButton );
@@ -340,27 +337,36 @@ public class FlatTitlePane
protected void updateIcon() {
// get window images
List<Image> images = null;
if( clientPropertyBoolean( rootPane, TITLE_BAR_SHOW_ICON, showIcon ) ) {
images = window.getIconImages();
if( images.isEmpty() ) {
// search in owners
for( Window owner = window.getOwner(); owner != null; owner = owner.getOwner() ) {
images = owner.getIconImages();
if( !images.isEmpty() )
break;
}
List<Image> images = window.getIconImages();
if( images.isEmpty() ) {
// search in owners
for( Window owner = window.getOwner(); owner != null; owner = owner.getOwner() ) {
images = owner.getIconImages();
if( !images.isEmpty() )
break;
}
}
boolean hasIcon = (images != null && !images.isEmpty());
boolean hasIcon = true;
// set icon
iconLabel.setIcon( hasIcon ? new FlatTitlePaneIcon( images, iconSize ) : null );
if( !images.isEmpty() )
iconLabel.setIcon( new FlatTitlePaneIcon( images, iconSize ) );
else {
// no icon set on window --> use default icon
Icon defaultIcon = UIManager.getIcon( "TitlePane.icon" );
if( defaultIcon != null && (defaultIcon.getIconWidth() == 0 || defaultIcon.getIconHeight() == 0) )
defaultIcon = null;
if( defaultIcon != null ) {
if( defaultIcon instanceof ImageIcon )
defaultIcon = new ScaledImageIcon( (ImageIcon) defaultIcon, iconSize.width, iconSize.height );
iconLabel.setIcon( defaultIcon );
} else
hasIcon = false;
}
// show/hide icon
iconLabel.setVisible( hasIcon );
leftPanel.setBorder( hasIcon ? null : FlatUIUtils.nonUIResource( new FlatEmptyBorder( 0, noIconLeftGap, 0, 0 ) ) );
updateNativeTitleBarHeightAndHitTestSpotsLater();
}
@@ -502,7 +508,7 @@ public class FlatTitlePane
protected void menuBarLayouted() {
updateNativeTitleBarHeightAndHitTestSpotsLater();
doLayout();
revalidate();
}
/*debug
@@ -515,23 +521,17 @@ public class FlatTitlePane
g.drawLine( 0, debugTitleBarHeight, getWidth(), debugTitleBarHeight );
}
if( debugHitTestSpots != null ) {
g.setColor( Color.red );
Point offset = SwingUtilities.convertPoint( this, 0, 0, window );
for( Rectangle r : debugHitTestSpots )
paintRect( g, Color.red, r );
g.drawRect( r.x - offset.x, r.y - offset.y, r.width - 1, r.height - 1 );
}
if( debugAppIconBounds != null ) {
g.setColor( Color.blue);
Point offset = SwingUtilities.convertPoint( this, 0, 0, window );
Rectangle r = debugAppIconBounds;
g.drawRect( r.x - offset.x, r.y - offset.y, r.width - 1, r.height - 1 );
}
paintRect( g, Color.cyan, debugCloseButtonBounds );
paintRect( g, Color.blue, debugAppIconBounds );
paintRect( g, Color.blue, debugMinimizeButtonBounds );
paintRect( g, Color.magenta, debugMaximizeButtonBounds );
paintRect( g, Color.cyan, debugCloseButtonBounds );
}
private void paintRect( Graphics g, Color color, Rectangle r ) {
if( r == null )
return;
g.setColor( color );
Point offset = SwingUtilities.convertPoint( this, 0, 0, window );
g.drawRect( r.x - offset.x, r.y - offset.y, r.width - 1, r.height - 1 );
}
debug*/
@@ -702,15 +702,9 @@ debug*/
return window != null && FlatNativeWindowBorder.hasCustomDecoration( window );
}
// used to invoke updateNativeTitleBarHeightAndHitTestSpots() only once from latest invokeLater()
private int laterCounter;
protected void updateNativeTitleBarHeightAndHitTestSpotsLater() {
laterCounter++;
EventQueue.invokeLater( () -> {
laterCounter--;
if( laterCounter == 0 )
updateNativeTitleBarHeightAndHitTestSpots();
updateNativeTitleBarHeightAndHitTestSpots();
} );
}
@@ -728,9 +722,8 @@ debug*/
List<Rectangle> hitTestSpots = new ArrayList<>();
Rectangle appIconBounds = null;
if( iconLabel.isVisible() ) {
// compute real icon size (without insets; 1px larger for easier hitting)
// compute real icon size (without insets; 1px wider for easier hitting)
Point location = SwingUtilities.convertPoint( iconLabel, 0, 0, window );
Insets iconInsets = iconLabel.getInsets();
Rectangle iconBounds = new Rectangle(
@@ -766,7 +759,7 @@ debug*/
JMenuBar menuBar = rootPane.getJMenuBar();
if( hasVisibleEmbeddedMenuBar( menuBar ) ) {
r = getNativeHitTestSpot( menuBar );
r = getNativeHitTestSpot( menuBarPlaceholder );
if( r != null ) {
Component horizontalGlue = findHorizontalGlue( menuBar );
if( horizontalGlue != null ) {
@@ -775,18 +768,18 @@ debug*/
// the glue component area can used to move the window.
Point glueLocation = SwingUtilities.convertPoint( horizontalGlue, 0, 0, window );
int x2 = glueLocation.x + horizontalGlue.getWidth();
Rectangle r2;
if( getComponentOrientation().isLeftToRight() ) {
r2 = new Rectangle( x2, r.y, (r.x + r.width) - x2, r.height );
r.width = glueLocation.x - r.x;
int trailingWidth = (r.x + r.width - HIT_TEST_SPOT_GROW) - glueLocation.x;
r.width -= trailingWidth;
r2 = new Rectangle( glueLocation.x + horizontalGlue.getWidth(), r.y, trailingWidth, r.height );
} else {
r2 = new Rectangle( r.x, r.y, glueLocation.x - r.x, r.height );
r.width = (r.x + r.width) - x2;
r.x = x2;
int leadingWidth = (glueLocation.x + horizontalGlue.getWidth()) - (r.x + HIT_TEST_SPOT_GROW);
r.x += leadingWidth;
r.width -= leadingWidth;
r2 = new Rectangle( glueLocation.x -leadingWidth, r.y, leadingWidth, r.height );
}
r2.grow( HIT_TEST_SPOT_GROW, HIT_TEST_SPOT_GROW );
hitTestSpots.add( r2 );
}
@@ -794,30 +787,16 @@ debug*/
}
}
Rectangle minimizeButtonBounds = boundsInWindow( iconifyButton );
Rectangle maximizeButtonBounds = boundsInWindow( maximizeButton.isVisible() ? maximizeButton : restoreButton );
Rectangle closeButtonBounds = boundsInWindow( closeButton );
FlatNativeWindowBorder.setTitleBarHeightAndHitTestSpots( window, titleBarHeight,
hitTestSpots, appIconBounds, minimizeButtonBounds, maximizeButtonBounds, closeButtonBounds );
FlatNativeWindowBorder.setTitleBarHeightAndHitTestSpots( window, titleBarHeight, hitTestSpots, appIconBounds );
/*debug
debugTitleBarHeight = titleBarHeight;
debugHitTestSpots = hitTestSpots;
debugAppIconBounds = appIconBounds;
debugMinimizeButtonBounds = minimizeButtonBounds;
debugMaximizeButtonBounds = maximizeButtonBounds;
debugCloseButtonBounds = closeButtonBounds;
repaint();
debug*/
}
private Rectangle boundsInWindow( JComponent c ) {
return c.isShowing()
? SwingUtilities.convertRectangle( c.getParent(), c.getBounds(), window )
: null;
}
protected Rectangle getNativeHitTestSpot( JComponent c ) {
Dimension size = c.getSize();
if( size.width <= 0 || size.height <= 0 )
@@ -825,16 +804,17 @@ debug*/
Point location = SwingUtilities.convertPoint( c, 0, 0, window );
Rectangle r = new Rectangle( location, size );
// slightly increase rectangle so that component receives mouseExit events
r.grow( HIT_TEST_SPOT_GROW, HIT_TEST_SPOT_GROW );
return r;
}
private static final int HIT_TEST_SPOT_GROW = 2;
/*debug
private int debugTitleBarHeight;
private List<Rectangle> debugHitTestSpots;
private Rectangle debugAppIconBounds;
private Rectangle debugMinimizeButtonBounds;
private Rectangle debugMaximizeButtonBounds;
private Rectangle debugCloseButtonBounds;
debug*/
//---- class FlatTitlePaneBorder ------------------------------------------
@@ -854,7 +834,7 @@ debug*/
} else if( borderColor != null && (rootPane.getJMenuBar() == null || !rootPane.getJMenuBar().isVisible()) )
insets.bottom += UIScale.scale( 1 );
if( !SystemInfo.isWindows_11_orLater && hasNativeCustomDecoration() && !isWindowMaximized( c ) )
if( hasNativeCustomDecoration() && !isWindowMaximized( c ) )
insets = FlatUIUtils.addInsets( insets, WindowTopBorder.getInstance().getBorderInsets() );
return insets;
@@ -866,14 +846,14 @@ debug*/
Border menuBarBorder = getMenuBarBorder();
if( menuBarBorder != null ) {
// if menu bar is embedded, paint menu bar border
menuBarBorder.paintBorder( rootPane.getJMenuBar(), g, x, y, width, height );
menuBarBorder.paintBorder( c, g, x, y, width, height );
} else if( borderColor != null && (rootPane.getJMenuBar() == null || !rootPane.getJMenuBar().isVisible()) ) {
// paint border between title pane and content if border color is specified
float lineHeight = UIScale.scale( (float) 1 );
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 );
}
@@ -966,7 +946,7 @@ debug*/
activeChanged( true );
updateNativeTitleBarHeightAndHitTestSpots();
if( !SystemInfo.isWindows_11_orLater && hasNativeCustomDecoration() )
if( hasNativeCustomDecoration() )
WindowTopBorder.getInstance().repaintBorder( FlatTitlePane.this );
repaintWindowBorder();
@@ -977,7 +957,7 @@ debug*/
activeChanged( false );
updateNativeTitleBarHeightAndHitTestSpots();
if( !SystemInfo.isWindows_11_orLater && hasNativeCustomDecoration() )
if( hasNativeCustomDecoration() )
WindowTopBorder.getInstance().repaintBorder( FlatTitlePane.this );
repaintWindowBorder();

View File

@@ -22,7 +22,6 @@ import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Map;
import javax.swing.JComponent;
@@ -32,7 +31,6 @@ import javax.swing.SwingConstants;
import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicToolBarSeparatorUI;
import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
import com.formdev.flatlaf.util.LoggingFacade;
@@ -49,7 +47,7 @@ import com.formdev.flatlaf.util.LoggingFacade;
*/
public class FlatToolBarSeparatorUI
extends BasicToolBarSeparatorUI
implements StyleableUI, PropertyChangeListener
implements StyleableUI
{
private static final int LINE_WIDTH = 1;
@@ -58,6 +56,7 @@ public class FlatToolBarSeparatorUI
private final boolean shared;
private boolean defaults_initialized = false;
private PropertyChangeListener propertyChangeListener;
private Map<String, Object> oldStyleValues;
public static ComponentUI createUI( JComponent c ) {
@@ -106,33 +105,28 @@ public class FlatToolBarSeparatorUI
protected void installListeners( JSeparator s ) {
super.installListeners( s );
s.addPropertyChangeListener( this );
propertyChangeListener = FlatStylingSupport.createPropertyChangeListener(
s, () -> stylePropertyChange( s ), null );
s.addPropertyChangeListener( propertyChangeListener );
}
@Override
protected void uninstallListeners( JSeparator s ) {
super.uninstallListeners( s );
s.removePropertyChangeListener( this );
s.removePropertyChangeListener( propertyChangeListener );
propertyChangeListener = null;
}
/** @since 2.0.1 */
@Override
public void propertyChange( PropertyChangeEvent e ) {
switch( e.getPropertyName() ) {
case FlatClientProperties.STYLE:
case FlatClientProperties.STYLE_CLASS:
JSeparator s = (JSeparator) e.getSource();
if( shared && FlatStylingSupport.hasStyleProperty( s ) ) {
// unshare component UI if necessary
// updateUI() invokes installStyle() from installUI()
s.updateUI();
} else
installStyle( s );
s.revalidate();
s.repaint();
break;
}
private void stylePropertyChange( JSeparator s ) {
if( shared && FlatStylingSupport.hasStyleProperty( s ) ) {
// unshare component UI if necessary
// updateUI() invokes applyStyle() from installUI()
s.updateUI();
} else
installStyle( s );
s.revalidate();
s.repaint();
}
/** @since 2 */

View File

@@ -21,7 +21,6 @@ import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.List;
import javax.swing.JComponent;
@@ -50,8 +49,9 @@ import com.formdev.flatlaf.util.StringUtils;
*/
public class FlatToolTipUI
extends BasicToolTipUI
implements PropertyChangeListener
{
private static PropertyChangeListener sharedPropertyChangedListener;
public static ComponentUI createUI( JComponent c ) {
return FlatUIUtils.createSharedUI( FlatToolTipUI.class, FlatToolTipUI::new );
}
@@ -68,24 +68,24 @@ public class FlatToolTipUI
protected void installListeners( JComponent c ) {
super.installListeners( c );
c.addPropertyChangeListener( this );
if( sharedPropertyChangedListener == null ) {
sharedPropertyChangedListener = e -> {
String name = e.getPropertyName();
if( name == "tiptext" || name == "font" || name == "foreground" ) {
JToolTip toolTip = (JToolTip) e.getSource();
FlatLabelUI.updateHTMLRenderer( toolTip, toolTip.getTipText(), false );
}
};
}
c.addPropertyChangeListener( sharedPropertyChangedListener );
}
@Override
protected void uninstallListeners( JComponent c ) {
super.uninstallListeners( c );
c.removePropertyChangeListener( this );
}
/** @since 2.0.1 */
@Override
public void propertyChange( PropertyChangeEvent e ) {
String name = e.getPropertyName();
if( name == "tiptext" || name == "font" || name == "foreground" ) {
JToolTip toolTip = (JToolTip) e.getSource();
FlatLabelUI.updateHTMLRenderer( toolTip, toolTip.getTipText(), false );
}
c.removePropertyChangeListener( sharedPropertyChangedListener );
}
@Override

View File

@@ -52,7 +52,6 @@ import com.formdev.flatlaf.util.UIScale;
*
* @uiDefault Tree.font Font
* @uiDefault Tree.background Color
* @uiDefault Tree.foreground Color unused
* @uiDefault Tree.hash Color
* @uiDefault Tree.dropLineColor Color
* @uiDefault Tree.expandedIcon Icon
@@ -137,12 +136,12 @@ public class FlatTreeUI
// for icons
// (needs to be public because icon classes are in another package)
/** @since 2 */ @Styleable(dot=true) public String iconArrowType;
/** @since 2 */ @Styleable(dot=true) public Color iconExpandedColor;
/** @since 2 */ @Styleable(dot=true) public Color iconCollapsedColor;
/** @since 2 */ @Styleable(dot=true) public Color iconLeafColor;
/** @since 2 */ @Styleable(dot=true) public Color iconClosedColor;
/** @since 2 */ @Styleable(dot=true) public Color iconOpenColor;
@Styleable(dot=true) public String iconArrowType;
@Styleable(dot=true) public Color iconExpandedColor;
@Styleable(dot=true) public Color iconCollapsedColor;
@Styleable(dot=true) public Color iconLeafColor;
@Styleable(dot=true) public Color iconClosedColor;
@Styleable(dot=true) public Color iconOpenColor;
// only used via styling (not in UI defaults, but has likewise client properties)
/** @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;
}
/** @since 2 */
public static Border nonUIResource( Border border ) {
return (border instanceof UIResource) ? new NonUIResourceBorder( border ) : border;
}
public static int minimumWidth( JComponent c, int minimumWidth ) {
return FlatClientProperties.clientPropertyInt( c, FlatClientProperties.MINIMUM_WIDTH, minimumWidth );
}
@@ -278,32 +273,6 @@ public class FlatUIUtils
: 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.
*/
@@ -1013,31 +982,4 @@ debug*/
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.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.util.Collections;
import java.util.IdentityHashMap;
import java.util.List;
@@ -38,7 +37,6 @@ import javax.swing.Timer;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.EventListenerList;
import com.formdev.flatlaf.FlatSystemProperties;
import com.formdev.flatlaf.util.LoggingFacade;
import com.formdev.flatlaf.util.NativeLibrary;
import com.formdev.flatlaf.util.SystemInfo;
@@ -56,10 +54,6 @@ import com.formdev.flatlaf.util.SystemInfo;
// https://github.com/oberth/custom-chrome
// https://github.com/rossy/borderless-window
//
// Windows 11
// https://docs.microsoft.com/en-us/windows/apps/desktop/modernize/apply-snap-layout-menu
// https://github.com/dotnet/wpf/issues/4825#issuecomment-930442736
//
/**
* Native window border support for Windows 10 when using custom decorations.
@@ -92,10 +86,6 @@ class FlatWindowsNativeWindowBorder
if( !SystemInfo.isWindows_10_orLater )
return null;
// requires x86 architecture
if( !SystemInfo.isX86 && !SystemInfo.isX86_64 )
return null;
// load native library
if( nativeLibrary == null ) {
if( !SystemInfo.isJava_9_orLater ) {
@@ -116,7 +106,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
@@ -129,23 +123,6 @@ class FlatWindowsNativeWindowBorder
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() {
}
@@ -186,18 +163,11 @@ class FlatWindowsNativeWindowBorder
return;
// install
try {
WndProc wndProc = new WndProc( window );
if( wndProc.hwnd == 0 )
return;
WndProc wndProc = new WndProc( window );
if( wndProc.hwnd == 0 )
return;
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 );
}
windowsMap.put( window, wndProc );
}
private void uninstall( Window window ) {
@@ -207,24 +177,30 @@ class FlatWindowsNativeWindowBorder
}
@Override
public void updateTitleBarInfo( Window window, int titleBarHeight, List<Rectangle> hitTestSpots,
Rectangle appIconBounds, Rectangle minimizeButtonBounds, Rectangle maximizeButtonBounds,
Rectangle closeButtonBounds )
{
public void setTitleBarHeight( Window window, int titleBarHeight ) {
WndProc wndProc = windowsMap.get( window );
if( wndProc == null )
return;
wndProc.titleBarHeight = titleBarHeight;
wndProc.hitTestSpots = hitTestSpots.toArray( new Rectangle[hitTestSpots.size()] );
wndProc.appIconBounds = cloneRectange( appIconBounds );
wndProc.minimizeButtonBounds = cloneRectange( minimizeButtonBounds );
wndProc.maximizeButtonBounds = cloneRectange( maximizeButtonBounds );
wndProc.closeButtonBounds = cloneRectange( closeButtonBounds );
}
private static Rectangle cloneRectange( Rectangle rect ) {
return (rect != null) ? new Rectangle( rect ) : null;
@Override
public void setTitleBarHitTestSpots( Window window, List<Rectangle> hitTestSpots ) {
WndProc wndProc = windowsMap.get( window );
if( wndProc == null )
return;
wndProc.hitTestSpots = hitTestSpots.toArray( new Rectangle[hitTestSpots.size()] );
}
@Override
public void setTitleBarAppIconBounds( Window window, Rectangle appIconBounds ) {
WndProc wndProc = windowsMap.get( window );
if( wndProc == null )
return;
wndProc.appIconBounds = (appIconBounds != null) ? new Rectangle( appIconBounds ) : null;
}
@Override
@@ -327,21 +303,14 @@ class FlatWindowsNativeWindowBorder
HTCLIENT = 1,
HTCAPTION = 2,
HTSYSMENU = 3,
HTMINBUTTON = 8,
HTMAXBUTTON = 9,
HTTOP = 12,
HTCLOSE = 20;
HTTOP = 12;
private Window window;
private final long hwnd;
// Swing coordinates/values may be scaled on a HiDPI screen
private int titleBarHeight;
private Rectangle[] hitTestSpots;
private Rectangle appIconBounds;
private Rectangle minimizeButtonBounds;
private Rectangle maximizeButtonBounds;
private Rectangle closeButtonBounds;
WndProc( Window window ) {
this.window = window;
@@ -386,7 +355,7 @@ class FlatWindowsNativeWindowBorder
// invoked from native code
private int onNcHitTest( int x, int y, boolean isOnResizeBorder ) {
// scale-down mouse x/y because Swing coordinates/values may be scaled on a HiDPI screen
// scale-down mouse x/y
Point pt = scaleDown( x, y );
int sx = pt.x;
int sy = pt.y;
@@ -394,26 +363,9 @@ class FlatWindowsNativeWindowBorder
// return HTSYSMENU if mouse is over application icon
// - left-click on HTSYSMENU area shows system menu
// - double-left-click sends WM_CLOSE
if( contains( appIconBounds, sx, sy ) )
if( appIconBounds != null && appIconBounds.contains( sx, sy ) )
return HTSYSMENU;
// return HTMINBUTTON if mouse is over minimize button
// - hovering mouse over HTMINBUTTON area shows tooltip on Windows 10/11
if( contains( minimizeButtonBounds, sx, sy ) )
return HTMINBUTTON;
// return HTMAXBUTTON if mouse is over maximize/restore button
// - hovering mouse over HTMAXBUTTON area shows tooltip on Windows 10
// - hovering mouse over HTMAXBUTTON area shows snap layouts menu on Windows 11
// https://docs.microsoft.com/en-us/windows/apps/desktop/modernize/apply-snap-layout-menu
if( contains( maximizeButtonBounds, sx, sy ) )
return HTMAXBUTTON;
// return HTCLOSE if mouse is over close button
// - hovering mouse over HTCLOSE area shows tooltip on Windows 10/11
if( contains( closeButtonBounds, sx, sy ) )
return HTCLOSE;
boolean isOnTitleBar = (sy < titleBarHeight);
if( isOnTitleBar ) {
@@ -430,10 +382,6 @@ class FlatWindowsNativeWindowBorder
return isOnResizeBorder ? HTTOP : HTCLIENT;
}
private boolean contains( Rectangle rect, int x, int y ) {
return (rect != null && rect.contains( x, y ) );
}
/**
* Scales down in the same way as AWT.
* See AwtWin32GraphicsDevice::ScaleDownX() and ::ScaleDownY()

View File

@@ -298,7 +298,7 @@ public class JBRCustomDecorations
}
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 ) {

View File

@@ -122,8 +122,6 @@ public class ColorFunctions
return color1;
if( weight <= 0 )
return color2;
if( color1.equals( color2 ) )
return color1;
int r1 = color1.getRed();
int g1 = color1.getGreen();
@@ -198,9 +196,6 @@ public class ColorFunctions
: (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 ) {
// if having only a single function of type Mix, then avoid four unnecessary conversions:
// 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 );
}
/**
* Clamps the given value between 0 and 100.
*/
public static float clamp( float value ) {
return (value < 0)
? 0

View File

@@ -60,19 +60,6 @@ public class NativeLibrary
: 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.
* <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 ) {
if( SystemInfo.isWindows )
return libraryName.concat( ".dll" );

View File

@@ -1,168 +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.util;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.BiFunction;
/**
* A simple cache (map) that uses soft references for the values.
*
* @author Karl Tauber
* @since 2
*/
public class SoftCache<K,V>
implements Map<K, V>
{
private final Map<K, CacheReference<K,V>> map;
private final ReferenceQueue<V> queue = new ReferenceQueue<>();
public SoftCache() {
map = new HashMap<>();
}
public SoftCache( int initialCapacity ) {
map = new HashMap<>( initialCapacity );
}
@Override
public int size() {
expungeStaleEntries();
return map.size();
}
@Override
public boolean isEmpty() {
expungeStaleEntries();
return map.isEmpty();
}
@Override
public boolean containsKey( Object key ) {
expungeStaleEntries();
return map.containsKey( key );
}
/**
* Not supported. Throws {@link UnsupportedOperationException}.
*/
@Override
public boolean containsValue( Object value ) {
throw new UnsupportedOperationException();
}
@Override
public V get( Object key ) {
expungeStaleEntries();
return getRef( map.get( key ) );
}
@Override
public V put( K key, V value ) {
expungeStaleEntries();
return getRef( map.put( key, new CacheReference<>( key, value, queue ) ) );
}
@Override
public V remove( Object key ) {
expungeStaleEntries();
return getRef( map.remove( key ) );
}
private V getRef( CacheReference<K,V> ref ) {
return (ref != null) ? ref.get() : null;
}
@Override
public void putAll( Map<? extends K, ? extends V> m ) {
expungeStaleEntries();
for( Entry<? extends K, ? extends V> e : m.entrySet() )
put( e.getKey(), e.getValue() );
}
@Override
public void clear() {
map.clear();
expungeStaleEntries();
}
@Override
public Set<K> keySet() {
expungeStaleEntries();
return map.keySet();
}
/**
* Not supported. Throws {@link UnsupportedOperationException}.
*/
@Override
public Collection<V> values() {
throw new UnsupportedOperationException();
}
/**
* Not supported. Throws {@link UnsupportedOperationException}.
*/
@Override
public Set<Entry<K, V>> entrySet() {
throw new UnsupportedOperationException();
}
/**
* Not supported. Throws {@link UnsupportedOperationException}.
*/
@Override
public void forEach( BiConsumer<? super K, ? super V> action ) {
throw new UnsupportedOperationException();
}
/**
* Not supported. Throws {@link UnsupportedOperationException}.
*/
@Override
public void replaceAll( BiFunction<? super K, ? super V, ? extends V> function ) {
throw new UnsupportedOperationException();
}
@SuppressWarnings( "unchecked" )
private void expungeStaleEntries() {
Reference<? extends V> reference;
while( (reference = queue.poll()) != null )
map.remove( ((CacheReference<K,V>)reference).key );
}
//---- class CacheReference ----
private static class CacheReference<K,V>
extends SoftReference<V>
{
// needed to remove reference from map in expungeStaleEntries()
final K key;
CacheReference( K key, V value, ReferenceQueue<? super V> queue ) {
super( value, queue );
this.key = key;
}
}
}

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,25 +34,18 @@ public class SystemInfo
// OS versions
public static final long osVersion;
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_14_Mojave_orLater;
public static final boolean isMacOS_10_15_Catalina_orLater;
// OS architecture
/** @since 2 */ public static final boolean isX86;
/** @since 1.1 */ public static final boolean isX86_64;
/** @since 2 */ public static final boolean isAARCH64;
// Java versions
public static final long javaVersion;
public static final boolean isJava_9_orLater;
public static final boolean isJava_11_orLater;
public static final boolean isJava_15_orLater;
/** @since 2 */ public static final boolean isJava_17_orLater;
/** @since 2 */ public static final boolean isJava_18_orLater;
// Java VMs
public static final boolean isJetBrainsJVM;
@@ -76,25 +69,19 @@ public class SystemInfo
// OS versions
osVersion = scanVersion( System.getProperty( "os.version" ) );
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_14_Mojave_orLater = (isMacOS && osVersion >= toVersion( 10, 14, 0, 0 ));
isMacOS_10_15_Catalina_orLater = (isMacOS && osVersion >= toVersion( 10, 15, 0, 0 ));
// OS architecture
String osArch = System.getProperty( "os.arch" );
isX86 = osArch.equals( "x86" );
isX86_64 = osArch.equals( "amd64" ) || osArch.equals( "x86_64" );
isAARCH64 = osArch.equals( "aarch64" );
// Java versions
javaVersion = scanVersion( System.getProperty( "java.version" ) );
isJava_9_orLater = (javaVersion >= toVersion( 9, 0, 0, 0 ));
isJava_11_orLater = (javaVersion >= toVersion( 11, 0, 0, 0 ));
isJava_15_orLater = (javaVersion >= toVersion( 15, 0, 0, 0 ));
isJava_17_orLater = (javaVersion >= toVersion( 17, 0, 0, 0 ));
isJava_18_orLater = (javaVersion >= toVersion( 18, 0, 0, 0 ));
// Java VMs
isJetBrainsJVM = System.getProperty( "java.vm.vendor", "Unknown" )

View File

@@ -289,7 +289,7 @@ Slider.trackValueColor = @accentSliderColor
Slider.trackColor = lighten(@background,15%)
Slider.thumbColor = $Slider.trackValueColor
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.pressedThumbColor = lighten($Slider.thumbColor,8%,derived)
Slider.disabledTrackColor = lighten(@background,10%)
@@ -334,8 +334,8 @@ TableHeader.bottomSeparatorColor = $TableHeader.separatorColor
#---- TitlePane ----
TitlePane.embeddedForeground = darken($TitlePane.foreground,15%)
TitlePane.buttonHoverBackground = lighten($TitlePane.background,15%,derived)
TitlePane.buttonPressedBackground = lighten($TitlePane.background,10%,derived)
TitlePane.buttonHoverBackground = lighten($TitlePane.background,10%,derived)
TitlePane.buttonPressedBackground = lighten($TitlePane.background,20%,derived)
#---- ToggleButton ----
@@ -355,18 +355,3 @@ ToolTip.background = shade(@background,50%)
#---- Tree ----
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

@@ -26,68 +26,6 @@
# Instead copy and modify only those properties that you need to alter.
#
#---- typography / fonts ----
# headings
h00.font = +24
h0.font = +18
h1.font = +12 $semibold.font
h2.font = +6 $semibold.font
h3.font = +3 $semibold.font
h4.font = bold
h1.regular.font = +12
h2.regular.font = +6
h3.regular.font = +3
# text
large.font = +2
medium.font = -1
small.font = -2
mini.font = -3
# default font
#defaultFont = ...
# font weights
# Windows
[win]light.font = "Segoe UI Light"
[win]semibold.font = "Segoe UI Semibold"
# macOS
[mac]light.font = "HelveticaNeue-Thin"
[mac]semibold.font = "HelveticaNeue-Medium"
# Linux
[linux]light.font = "Lato Light", "Ubuntu Light", "Cantarell Light"
[linux]semibold.font = "Lato Semibold", "Ubuntu Medium", "Montserrat SemiBold"
# fallback for unknown platform
light.font = +0
semibold.font = +0
# monospaced
[win]monospaced.font = Consolas, "Courier New", Monospaced
[mac]monospaced.font = Menlo, Monospaced
[linux]monospaced.font = "Liberation Mono", "Ubuntu Mono", Monospaced
monospaced.font = Monospaced
# styles
[style].h00 = font: $h00.font
[style].h0 = font: $h0.font
[style].h1 = font: $h1.font
[style].h2 = font: $h2.font
[style].h3 = font: $h3.font
[style].h4 = font: $h4.font
[style].h1.regular = font: $h1.regular.font
[style].h2.regular = font: $h2.regular.font
[style].h3.regular = font: $h3.regular.font
[style].large = font: $large.font
[style].medium = font: $medium.font
[style].small = font: $small.font
[style].mini = font: $mini.font
[style].light = font: $light.font
[style].semibold = font: $semibold.font
[style].monospaced = font: $monospaced.font
#---- UI delegates ----
ButtonUI = com.formdev.flatlaf.ui.FlatButtonUI
@@ -227,7 +165,6 @@ Button.defaultButtonFollowsFocus = false
Button.borderWidth = 1
Button.default.borderWidth = 1
# for buttons in toolbars
Button.toolbar.margin = 3,3,3,3
Button.toolbar.spacingInsets = 1,2,1,2
@@ -431,7 +368,6 @@ MenuItem.checkIcon = null
MenuItem.margin = @menuItemMargin
MenuItem.opaque = false
MenuItem.borderPainted = true
MenuItem.verticallyAlignText = true
MenuItem.background = @menuBackground
MenuItem.checkBackground = @menuCheckBackground
MenuItem.checkMargins = 2,2,2,2
@@ -441,7 +377,7 @@ MenuItem.iconTextGap = 6
MenuItem.textAcceleratorGap = 24
MenuItem.textNoAcceleratorGap = 6
MenuItem.acceleratorArrowGap = 2
MenuItem.acceleratorDelimiter = +
MenuItem.acceleratorDelimiter = -
[mac]MenuItem.acceleratorDelimiter =
# for MenuItem.selectionType = underline
@@ -458,7 +394,6 @@ OptionPane.messageAreaBorder = 0,0,0,0
OptionPane.buttonAreaBorder = 12,0,0,0
OptionPane.messageForeground = null
OptionPane.showIcon = false
OptionPane.maxCharactersPerLine = 80
OptionPane.iconMessageGap = 16
OptionPane.messagePadding = 3
@@ -484,10 +419,7 @@ PasswordField.placeholderForeground = @disabledForeground
PasswordField.iconTextGap = 4
PasswordField.echoChar = \u2022
PasswordField.showCapsLock = true
PasswordField.showRevealButton = false
PasswordField.capsLockIcon = com.formdev.flatlaf.icons.FlatCapsLockIcon
PasswordField.revealIcon = com.formdev.flatlaf.icons.FlatRevealIcon
PasswordField.revealIconColor = lazy(Actions.Grey)
#---- Popup ----
@@ -589,13 +521,13 @@ ScrollPane.smoothScrolling = true
#---- SearchField ----
SearchField.searchIconColor = fade(Actions.GreyInline,90%,lazy)
SearchField.searchIconHoverColor = fade(Actions.GreyInline,70%,lazy)
SearchField.searchIconPressedColor = fade(Actions.GreyInline,50%,lazy)
SearchField.searchIconColor = fadeout(Actions.GreyInline,10%,lazy)
SearchField.searchIconHoverColor = fadeout(Actions.GreyInline,30%,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.clearIconPressedColor = fade(Actions.GreyInline,80%,lazy)
SearchField.clearIconPressedColor = fadeout(Actions.GreyInline,20%,lazy)
#---- Separator ----
@@ -655,7 +587,6 @@ SplitPaneDivider.gripGap = 2
TabbedPane.tabHeight = 32
TabbedPane.tabSelectionHeight = 3
TabbedPane.cardTabSelectionHeight = 2
TabbedPane.contentSeparatorHeight = 1
TabbedPane.showTabSeparators = false
TabbedPane.tabSeparatorsFullHeight = false
@@ -677,9 +608,6 @@ TabbedPane.tabAlignment = center
# allowed values: preferred, equal or compact
TabbedPane.tabWidthMode = preferred
# allowed values: underlined or card
TabbedPane.tabType = underlined
# allowed values: chevron or triangle
TabbedPane.arrowType = chevron
TabbedPane.buttonInsets = 2,1,2,1
@@ -781,9 +709,7 @@ TitledBorder.border = 1,1,1,1,$Separator.foreground
TitlePane.useWindowDecorations = true
TitlePane.menuBarEmbedded = true
TitlePane.unifiedBackground = true
TitlePane.showIcon = true
TitlePane.noIconLeftGap = 8
TitlePane.unifiedBackground = false
TitlePane.iconSize = 16,16
TitlePane.iconMargins = 3,8,3,8
TitlePane.titleMargins = 3,0,3,0
@@ -802,8 +728,8 @@ TitlePane.inactiveBackground = $TitlePane.background
TitlePane.foreground = @foreground
TitlePane.inactiveForeground = @disabledForeground
TitlePane.closeHoverBackground = #c42b1c
TitlePane.closePressedBackground = fade($TitlePane.closeHoverBackground,90%)
TitlePane.closeHoverBackground = #e81123
TitlePane.closePressedBackground = fade($TitlePane.closeHoverBackground,60%)
TitlePane.closeHoverForeground = #fff
TitlePane.closePressedForeground = #fff
@@ -893,32 +819,3 @@ Tree.icon.collapsedColor = @icon
Tree.icon.leafColor = @icon
Tree.icon.closedColor = @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.thumbColor = $Slider.trackValueColor
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.pressedThumbColor = darken($Slider.thumbColor,8%,derived)
Slider.disabledTrackColor = darken(@background,13%)
@@ -342,7 +342,7 @@ TableHeader.bottomSeparatorColor = $TableHeader.separatorColor
TitlePane.embeddedForeground = lighten($TitlePane.foreground,35%)
TitlePane.buttonHoverBackground = darken($TitlePane.background,10%,derived)
TitlePane.buttonPressedBackground = darken($TitlePane.background,8%,derived)
TitlePane.buttonPressedBackground = darken($TitlePane.background,20%,derived)
#---- ToggleButton ----
@@ -362,18 +362,3 @@ ToolTip.background = lighten(@background,3%)
#---- Tree ----
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.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.toolbar.selectedBackground = $ToggleButton.toolbar.selectedBackground
@@ -211,17 +210,11 @@ ToggleButton.endBackground = $ToggleButton.background
[GitHub_Contrast]ProgressBar.selectionBackground = #222
[GitHub_Contrast]ProgressBar.selectionForeground = #222
[Light_Owl]List.selectionInactiveForeground = lazy(List.foreground)
[Light_Owl]ProgressBar.selectionBackground = #111
[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.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.selectionForeground = #fff

View File

@@ -22,12 +22,8 @@ import java.awt.Dimension;
import java.awt.Font;
import java.awt.Insets;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.UIDefaults.ActiveValue;
import javax.swing.UIDefaults.LazyValue;
import org.junit.jupiter.api.Test;
import com.formdev.flatlaf.ui.FlatEmptyBorder;
import com.formdev.flatlaf.ui.FlatLineBorder;
/**
* @author Karl Tauber
@@ -50,8 +46,8 @@ public class TestUIDefaultsLoader
assertEquals( 1.23f, UIDefaultsLoader.parseValue( "dummy", "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 Dimension( 1,2 ), UIDefaultsLoader.parseValue( "dummySize", "1,2", null ) );
assertEquals( new Insets( 2,2,2,2 ), UIDefaultsLoader.parseValue( "dummyInsets", "2,2,2,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( "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( new Insets( 1,2,3,4 ), UIDefaultsLoader.parseValue( "dummy", "1,2,3,4", Insets.class ) );
assertEquals( new Dimension( 1,2 ), UIDefaultsLoader.parseValue( "dummy", "1,2", Dimension.class ) );
assertEquals( new Insets( 2,2,2,2 ), UIDefaultsLoader.parseValue( "dummy", "2,2,2,2", Insets.class ) );
assertEquals( new Dimension( 2,2 ), UIDefaultsLoader.parseValue( "dummy", "2,2", Dimension.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
void parseFonts() {
// style

View File

@@ -1,65 +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.icons;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import javax.swing.Icon;
import com.formdev.flatlaf.ui.TestUtils;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
class TestFlatIconPaintingNullComponent
{
static Graphics graphics;
@BeforeAll
static void setup() {
TestUtils.setup( false );
graphics = new BufferedImage( 32, 32, BufferedImage.TYPE_INT_ARGB ).getGraphics();
graphics.setColor( Color.white );
}
@AfterAll
static void cleanup() {
TestUtils.cleanup();
graphics = null;
}
@Test
void flatHelpButtonIcon() {
paintWithoutException( new FlatHelpButtonIcon() );
}
@Test
void flatMenuArrowIcon() {
paintWithoutException( new FlatMenuArrowIcon() );
}
@Test
void flatSearchIcon() {
paintWithoutException( new FlatSearchIcon() );
}
private void paintWithoutException( Icon icon ) {
graphics.clearRect( 0, 0, 32, 32 );
assertDoesNotThrow( () -> icon.paintIcon( null, graphics, 0, 0 ) );
}
}

View File

@@ -40,7 +40,7 @@ public class TestFlatStyleClasses
@BeforeAll
static void setup() {
System.setProperty( FlatSystemProperties.UI_SCALE, "1x" );
System.setProperty( FlatSystemProperties.UI_SCALE_ENABLED, "false" );
TestUtils.setup( false );
UIManager.put( "[style]Button.primary", BUTTON_PRIMARY );
@@ -61,7 +61,6 @@ public class TestFlatStyleClasses
UIManager.put( "[style]MenuItem.test", "foreground: #000011" );
UIManager.put( "[style]CheckBoxMenuItem.test", "foreground: #000012" );
UIManager.put( "[style]RadioButtonMenuItem.test", "foreground: #000013" );
UIManager.put( "[style]Panel.test", "foreground: #000034" );
UIManager.put( "[style]PasswordField.test", "foreground: #000014" );
UIManager.put( "[style]PopupMenu.test", "foreground: #000015" );
UIManager.put( "[style]PopupMenuSeparator.test", "foreground: #000016" );
@@ -100,7 +99,7 @@ public class TestFlatStyleClasses
@AfterAll
static void cleanup() {
TestUtils.cleanup();
System.clearProperty( FlatSystemProperties.UI_SCALE );
System.clearProperty( FlatSystemProperties.UI_SCALE_ENABLED );
}
@Test
@@ -279,14 +278,6 @@ public class TestFlatStyleClasses
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
void passwordField() {
JPasswordField c = new JPasswordField();

View File

@@ -0,0 +1,306 @@
/*
* 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.ui;
import static org.junit.jupiter.api.Assertions.assertEquals;
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.*;
import javax.swing.table.JTableHeader;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import com.formdev.flatlaf.FlatSystemProperties;
/**
* @author Karl Tauber
*/
public class TestFlatStyleType
{
@BeforeAll
static void setup() {
System.setProperty( FlatSystemProperties.UI_SCALE_ENABLED, "false" );
TestUtils.setup( false );
UIManager.put( "[style]Button", "foreground: #000001" );
UIManager.put( "[style]CheckBox", "foreground: #000002" );
UIManager.put( "[style]ComboBox", "foreground: #000003" );
UIManager.put( "[style]EditorPane", "foreground: #000004" );
UIManager.put( "[style]FormattedTextField", "foreground: #000005" );
UIManager.put( "[style]InternalFrame", "foreground: #000006" );
UIManager.put( "[style]Label", "foreground: #000007" );
UIManager.put( "[style]List", "foreground: #000008" );
UIManager.put( "[style]MenuBar", "foreground: #000009" );
UIManager.put( "[style]Menu", "foreground: #000010" );
UIManager.put( "[style]MenuItem", "foreground: #000011" );
UIManager.put( "[style]CheckBoxMenuItem", "foreground: #000012" );
UIManager.put( "[style]RadioButtonMenuItem", "foreground: #000013" );
UIManager.put( "[style]PasswordField", "foreground: #000014" );
UIManager.put( "[style]PopupMenu", "foreground: #000015" );
UIManager.put( "[style]PopupMenuSeparator", "foreground: #000016" );
UIManager.put( "[style]ProgressBar", "foreground: #000017" );
UIManager.put( "[style]RadioButton", "foreground: #000018" );
UIManager.put( "[style]ScrollBar", "foreground: #000019" );
UIManager.put( "[style]ScrollPane", "foreground: #000020" );
UIManager.put( "[style]Separator", "foreground: #000021" );
UIManager.put( "[style]Slider", "foreground: #000022" );
UIManager.put( "[style]Spinner", "foreground: #000023" );
UIManager.put( "[style]SplitPane", "foreground: #000024" );
UIManager.put( "[style]TabbedPane", "foreground: #000025" );
UIManager.put( "[style]Table", "foreground: #000026" );
UIManager.put( "[style]TableHeader", "foreground: #000027" );
UIManager.put( "[style]TextArea", "foreground: #000028" );
UIManager.put( "[style]TextField", "foreground: #000029" );
UIManager.put( "[style]TextPane", "foreground: #000030" );
UIManager.put( "[style]ToggleButton", "foreground: #000031" );
UIManager.put( "[style]ToolBar", "foreground: #000032" );
UIManager.put( "[style]Tree", "foreground: #000033" );
// JToolBar.Separator
UIManager.put( "[style]ToolBarSeparator", "separatorWidth: 21" );
}
@AfterAll
static void cleanup() {
TestUtils.cleanup();
System.clearProperty( FlatSystemProperties.UI_SCALE_ENABLED );
}
@Test
void styleForType() {
assertEquals( "foreground: #000001", FlatStylingSupport.getStyleForType( "Button" ) );
}
//---- components ---------------------------------------------------------
@Test
void button() {
JButton c = new JButton();
assertEquals( new Color( 0x000001 ), c.getForeground() );
}
@Test
void checkBox() {
JCheckBox c = new JCheckBox();
assertEquals( new Color( 0x000002 ), c.getForeground() );
}
@Test
void comboBox() {
JComboBox<Object> c = new JComboBox<>();
assertEquals( new Color( 0x000003 ), c.getForeground() );
}
@Test
void editorPane() {
JEditorPane c = new JEditorPane();
assertEquals( new Color( 0x000004 ), c.getForeground() );
}
@Test
void formattedTextField() {
JFormattedTextField c = new JFormattedTextField();
assertEquals( new Color( 0x000005 ), c.getForeground() );
}
@Test
void internalFrame() {
JInternalFrame c = new JInternalFrame();
assertEquals( new Color( 0x000006 ), c.getForeground() );
}
@Test
void label() {
JLabel c = new JLabel();
assertEquals( new Color( 0x000007 ), c.getForeground() );
}
@Test
void list() {
JList<Object> c = new JList<>();
assertEquals( new Color( 0x000008 ), c.getForeground() );
}
@Test
void menuBar() {
JMenuBar c = new JMenuBar();
assertEquals( new Color( 0x000009 ), c.getForeground() );
}
@Test
void menu() {
JMenu c = new JMenu();
assertEquals( new Color( 0x000010 ), c.getForeground() );
}
@Test
void menuItem() {
JMenuItem c = new JMenuItem();
assertEquals( new Color( 0x000011 ), c.getForeground() );
}
@Test
void checkBoxMenuItem() {
JCheckBoxMenuItem c = new JCheckBoxMenuItem();
assertEquals( new Color( 0x000012 ), c.getForeground() );
}
@Test
void radioButtonMenuItem() {
JRadioButtonMenuItem c = new JRadioButtonMenuItem();
assertEquals( new Color( 0x000013 ), c.getForeground() );
}
@Test
void passwordField() {
JPasswordField c = new JPasswordField();
assertEquals( new Color( 0x000014 ), c.getForeground() );
}
@Test
void popupMenu() {
JPopupMenu c = new JPopupMenu();
assertEquals( new Color( 0x000015 ), c.getForeground() );
}
@Test
void popupMenuSeparator() {
JPopupMenu.Separator c = new JPopupMenu.Separator();
assertEquals( new Color( 0x000016 ), c.getForeground() );
}
@Test
void progressBar() {
JProgressBar c = new JProgressBar();
assertEquals( new Color( 0x000017 ), c.getForeground() );
}
@Test
void radioButton() {
JRadioButton c = new JRadioButton();
assertEquals( new Color( 0x000018 ), c.getForeground() );
}
@Test
void scrollBar() {
JScrollBar c = new JScrollBar();
assertEquals( new Color( 0x000019 ), c.getForeground() );
}
@Test
void scrollPane() {
JScrollPane c = new JScrollPane();
assertEquals( new Color( 0x000020 ), c.getForeground() );
}
@Test
void separator() {
JSeparator c = new JSeparator();
assertEquals( new Color( 0x000021 ), c.getForeground() );
}
@Test
void slider() {
JSlider c = new JSlider();
assertEquals( new Color( 0x000022 ), c.getForeground() );
}
@Test
void slider2() {
JSlider c = new JSlider();
// when slider labels are painted, then a Java private subclass of JLabel
// is used that overrides getForeground(), which is not accessible via reflection
// see class JSlider.SmartHashtable.LabelUIResource
c.setPaintLabels( true );
c.setMajorTickSpacing( 50 );
assertEquals( new Color( 0x000022 ), c.getForeground() );
}
@Test
void spinner() {
JSpinner c = new JSpinner();
assertEquals( new Color( 0x000023 ), c.getForeground() );
}
@Test
void splitPane() {
JSplitPane c = new JSplitPane();
assertEquals( new Color( 0x000024 ), c.getForeground() );
}
@Test
void tabbedPane() {
JTabbedPane c = new JTabbedPane();
assertEquals( new Color( 0x000025 ), c.getForeground() );
}
@Test
void table() {
JTable c = new JTable();
assertEquals( new Color( 0x000026 ), c.getForeground() );
}
@Test
void tableHeader() {
JTableHeader c = new JTableHeader();
assertEquals( new Color( 0x000027 ), c.getForeground() );
}
@Test
void textArea() {
JTextArea c = new JTextArea();
assertEquals( new Color( 0x000028 ), c.getForeground() );
}
@Test
void textField() {
JTextField c = new JTextField();
assertEquals( new Color( 0x000029 ), c.getForeground() );
}
@Test
void textPane() {
JTextPane c = new JTextPane();
assertEquals( new Color( 0x000030 ), c.getForeground() );
}
@Test
void toggleButton() {
JToggleButton c = new JToggleButton();
assertEquals( new Color( 0x000031 ), c.getForeground() );
}
@Test
void toolBar() {
JToolBar c = new JToolBar();
assertEquals( new Color( 0x000032 ), c.getForeground() );
}
@Test
void toolBarSeparator() {
JToolBar.Separator c = new JToolBar.Separator();
assertEquals( new Dimension( 0, 21 ), c.getPreferredSize() );
}
@Test
void tree() {
JTree c = new JTree();
assertEquals( new Color( 0x000033 ), c.getForeground() );
}
}

View File

@@ -20,7 +20,6 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
import static com.formdev.flatlaf.ui.TestUtils.assertMapEquals;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Insets;
import java.util.LinkedHashMap;
import java.util.Map;
@@ -258,7 +257,7 @@ public class TestFlatStyleableInfo
// FlatListCellBorder
"cellMargins", Insets.class,
"cellFocusColor", Color.class,
"showCellFocusIndicator", Boolean.class
"showCellFocusIndicator", boolean.class
);
assertMapEquals( expected, ui.getStyleableInfos( c ) );
@@ -302,6 +301,7 @@ public class TestFlatStyleableInfo
Map<String, Class<?>> expected = new LinkedHashMap<>();
menuItem( expected );
menuItem_arrowIcon( expected );
assertMapEquals( expected, ui.getStyleableInfos( c ) );
}
@@ -314,6 +314,7 @@ public class TestFlatStyleableInfo
Map<String, Class<?>> expected = new LinkedHashMap<>();
menuItem( expected );
menuItem_checkIcon( expected );
menuItem_arrowIcon( expected );
assertMapEquals( expected, ui.getStyleableInfos( c ) );
}
@@ -326,6 +327,7 @@ public class TestFlatStyleableInfo
Map<String, Class<?>> expected = new LinkedHashMap<>();
menuItem( expected );
menuItem_checkIcon( expected );
menuItem_arrowIcon( expected );
assertMapEquals( expected, ui.getStyleableInfos( c ) );
}
@@ -336,8 +338,7 @@ public class TestFlatStyleableInfo
"selectionForeground", Color.class,
"disabledForeground", Color.class,
"acceleratorForeground", Color.class,
"acceleratorSelectionForeground", Color.class,
"acceleratorFont", Font.class
"acceleratorSelectionForeground", Color.class
);
menuItemRenderer( expected );
@@ -345,7 +346,6 @@ public class TestFlatStyleableInfo
private void menuItemRenderer( Map<String, Class<?>> expected ) {
expectedMap( expected,
"verticallyAlignText", boolean.class,
"minimumWidth", int.class,
"minimumIconSize", Dimension.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
void passwordField() {
JPasswordField c = new JPasswordField();
@@ -398,8 +386,7 @@ public class TestFlatStyleableInfo
Map<String, Class<?>> expected = new LinkedHashMap<>();
expectedMap( expected,
"showCapsLock", boolean.class,
"showRevealButton", boolean.class
"showCapsLock", boolean.class
);
// FlatPasswordFieldUI extends FlatTextFieldUI
@@ -698,14 +685,12 @@ public class TestFlatStyleableInfo
"maximumTabWidth", int.class,
"tabHeight", int.class,
"tabSelectionHeight", int.class,
"cardTabSelectionHeight", int.class,
"contentSeparatorHeight", int.class,
"showTabSeparators", boolean.class,
"tabSeparatorsFullHeight", boolean.class,
"hasFullBorder", boolean.class,
"tabsOpaque", boolean.class,
"tabType", String.class,
"tabsPopupPolicy", String.class,
"scrollButtonsPolicy", String.class,
"scrollButtonsPlacement", String.class,
@@ -760,7 +745,7 @@ public class TestFlatStyleableInfo
// FlatTableCellBorder
"cellMargins", Insets.class,
"cellFocusColor", Color.class,
"showCellFocusIndicator", Boolean.class
"showCellFocusIndicator", boolean.class
);
assertMapEquals( expected, ui.getStyleableInfos( c ) );
@@ -779,7 +764,7 @@ public class TestFlatStyleableInfo
// FlatTableHeaderBorder
"cellMargins", Insets.class,
"separatorColor", Color.class,
"showTrailingVerticalLine", Boolean.class,
"showTrailingVerticalLine", boolean.class,
// FlatAscendingSortIcon and FlatDescendingSortIcon
"arrowType", String.class,
@@ -824,8 +809,7 @@ public class TestFlatStyleableInfo
"focusedBackground", Color.class,
"iconTextGap", int.class,
"leadingIcon", Icon.class,
"trailingIcon", Icon.class,
"showClearButton", boolean.class
"trailingIcon", Icon.class
);
// border
@@ -1148,6 +1132,17 @@ public class TestFlatStyleableInfo
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 ) {
expectedMap( expected,
"arrowType", String.class,

View File

@@ -261,7 +261,6 @@ public class TestFlatStyling
// AbstractButton properties
ui.applyStyle( b, "margin: 2,2,2,2" );
ui.applyStyle( b, "iconTextGap: 4" );
}
@Test
@@ -313,9 +312,6 @@ public class TestFlatStyling
ui.applyStyle( "foreground: #fff" );
ui.applyStyle( "border: 2,2,2,2,#f00" );
ui.applyStyle( "font: italic 12 monospaced" );
// JComboBox properties
ui.applyStyle( "maximumRowCount: 20" );
}
@Test
@@ -339,7 +335,6 @@ public class TestFlatStyling
ui.applyStyle( "selectionColor: #fff" );
ui.applyStyle( "selectedTextColor: #fff" );
ui.applyStyle( "disabledTextColor: #fff" );
ui.applyStyle( "margin: 2,2,2,2" );
}
@Test
@@ -455,6 +450,7 @@ public class TestFlatStyling
Consumer<String> applyStyle = style -> ui.applyStyle( style );
menuItem( applyStyle );
menuItem_arrowIcon( applyStyle );
}
@Test
@@ -465,6 +461,7 @@ public class TestFlatStyling
Consumer<String> applyStyle = style -> ui.applyStyle( style );
menuItem( applyStyle );
menuItem_checkIcon( applyStyle );
menuItem_arrowIcon( applyStyle );
}
@Test
@@ -475,6 +472,7 @@ public class TestFlatStyling
Consumer<String> applyStyle = style -> ui.applyStyle( style );
menuItem( applyStyle );
menuItem_checkIcon( applyStyle );
menuItem_arrowIcon( applyStyle );
}
private void menuItem( Consumer<String> applyStyle ) {
@@ -483,7 +481,6 @@ public class TestFlatStyling
applyStyle.accept( "disabledForeground: #fff" );
applyStyle.accept( "acceleratorForeground: #fff" );
applyStyle.accept( "acceleratorSelectionForeground: #fff" );
applyStyle.accept( "acceleratorFont: italic 12 monospaced" );
menuItemRenderer( applyStyle );
@@ -495,11 +492,9 @@ public class TestFlatStyling
// AbstractButton properties
applyStyle.accept( "margin: 2,2,2,2" );
applyStyle.accept( "iconTextGap: 4" );
}
private void menuItemRenderer( Consumer<String> applyStyle ) {
applyStyle.accept( "verticallyAlignText: false" );
applyStyle.accept( "minimumWidth: 10" );
applyStyle.accept( "minimumIconSize: 16,16" );
applyStyle.accept( "textAcceleratorGap: 28" );
@@ -528,20 +523,6 @@ public class TestFlatStyling
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
void passwordField() {
JPasswordField c = new JPasswordField();
@@ -551,7 +532,6 @@ public class TestFlatStyling
textField( ui );
ui.applyStyle( "showCapsLock: true" );
ui.applyStyle( "showRevealButton: true" );
// capsLockIcon
ui.applyStyle( "capsLockIconColor: #fff" );
@@ -625,7 +605,6 @@ public class TestFlatStyling
// AbstractButton properties
ui.applyStyle( b, "margin: 2,2,2,2" );
ui.applyStyle( b, "iconTextGap: 4" );
//---- icon ----
@@ -722,7 +701,6 @@ public class TestFlatStyling
ui.applyStyle( "background: #fff" );
ui.applyStyle( "foreground: #fff" );
ui.applyStyle( "border: 2,2,2,2,#f00" );
ui.applyStyle( "viewportBorder: 2,2,2,2,#f00" );
}
@Test
@@ -772,8 +750,6 @@ public class TestFlatStyling
ui.applyStyle( "foreground: #fff" );
ui.applyStyle( "border: 2,2,2,2,#f00" );
ui.applyStyle( "font: italic 12 monospaced" );
// JSlider properties
ui.applyStyle( "minimum: 0" );
ui.applyStyle( "maximum: 50" );
ui.applyStyle( "value: 20" );
@@ -785,6 +761,12 @@ public class TestFlatStyling
ui.applyStyle( "paintTicks: true" );
ui.applyStyle( "paintTrack: true" );
ui.applyStyle( "snapToTicks: true" );
// JSlider properties
ui.applyStyle( "paintLabels: true" );
ui.applyStyle( "paintTicks: true" );
ui.applyStyle( "paintTrack: true" );
ui.applyStyle( "snapToTicks: true" );
}
@Test
@@ -867,14 +849,12 @@ public class TestFlatStyling
ui.applyStyle( "maximumTabWidth: 100" );
ui.applyStyle( "tabHeight: 30" );
ui.applyStyle( "tabSelectionHeight: 3" );
ui.applyStyle( "cardTabSelectionHeight: 2" );
ui.applyStyle( "contentSeparatorHeight: 1" );
ui.applyStyle( "showTabSeparators: false" );
ui.applyStyle( "tabSeparatorsFullHeight: false" );
ui.applyStyle( "hasFullBorder: false" );
ui.applyStyle( "tabsOpaque: false" );
ui.applyStyle( "tabType: card" );
ui.applyStyle( "tabsPopupPolicy: asNeeded" );
ui.applyStyle( "scrollButtonsPolicy: asNeeded" );
ui.applyStyle( "scrollButtonsPlacement: both" );
@@ -936,6 +916,7 @@ public class TestFlatStyling
// JComponent properties
ui.applyStyle( "background: #fff" );
ui.applyStyle( "foreground: #fff" );
ui.applyStyle( "border: 2,2,2,2,#f00" );
ui.applyStyle( "font: italic 12 monospaced" );
// JTable properties
@@ -967,6 +948,7 @@ public class TestFlatStyling
// JComponent properties
ui.applyStyle( "background: #fff" );
ui.applyStyle( "foreground: #fff" );
ui.applyStyle( "border: 2,2,2,2,#f00" );
ui.applyStyle( "font: italic 12 monospaced" );
}
@@ -991,7 +973,6 @@ public class TestFlatStyling
ui.applyStyle( "selectionColor: #fff" );
ui.applyStyle( "selectedTextColor: #fff" );
ui.applyStyle( "disabledTextColor: #fff" );
ui.applyStyle( "margin: 2,2,2,2" );
}
@Test
@@ -1012,8 +993,6 @@ public class TestFlatStyling
ui.applyStyle( "leadingIcon: com.formdev.flatlaf.icons.FlatSearchIcon" );
ui.applyStyle( "trailingIcon: com.formdev.flatlaf.icons.FlatClearIcon" );
ui.applyStyle( "showClearButton: true" );
// border
flatTextBorder( style -> ui.applyStyle( style ) );
@@ -1028,7 +1007,6 @@ public class TestFlatStyling
ui.applyStyle( "selectionColor: #fff" );
ui.applyStyle( "selectedTextColor: #fff" );
ui.applyStyle( "disabledTextColor: #fff" );
ui.applyStyle( "margin: 2,2,2,2" );
}
@Test
@@ -1052,7 +1030,6 @@ public class TestFlatStyling
ui.applyStyle( "selectionColor: #fff" );
ui.applyStyle( "selectedTextColor: #fff" );
ui.applyStyle( "disabledTextColor: #fff" );
ui.applyStyle( "margin: 2,2,2,2" );
}
@Test
@@ -1363,6 +1340,18 @@ public class TestFlatStyling
void 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( "arrowColor", Color.WHITE );
icon.applyStyleProperty( "disabledArrowColor", Color.WHITE );

View File

@@ -17,6 +17,7 @@
package com.formdev.flatlaf.ui;
import java.awt.Font;
import java.util.Iterator;
import java.util.Map;
import java.util.Objects;
import javax.swing.UIManager;
@@ -42,7 +43,12 @@ public class TestUtils
}
public static void cleanup() {
UIManager.put( "defaultFont", null );
// remove all properties added by UIManager.put()
Iterator<Object> it = UIManager.getDefaults().keySet().iterator();
while( it.hasNext() ) {
it.next();
it.remove();
}
}
public static void scaleFont( float factor ) {

View File

@@ -22,11 +22,6 @@ import javax.swing.text.DefaultEditorKit;
import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.extras.FlatSVGIcon;
import com.formdev.flatlaf.icons.FlatSearchIcon;
import com.formdev.flatlaf.icons.FlatSearchWithHistoryIcon;
import net.miginfocom.layout.AC;
import net.miginfocom.layout.BoundSize;
import net.miginfocom.layout.ConstraintParser;
import net.miginfocom.layout.DimConstraint;
import net.miginfocom.swing.*;
/**
@@ -37,62 +32,6 @@ class BasicComponentsPanel
{
BasicComponentsPanel() {
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() {
@@ -144,7 +83,7 @@ class BasicComponentsPanel
JFormattedTextField formattedTextField4 = new JFormattedTextField();
JFormattedTextField formattedTextField5 = new JFormattedTextField();
JLabel passwordFieldLabel = new JLabel();
passwordField1 = new JPasswordField();
JPasswordField passwordField1 = new JPasswordField();
JPasswordField passwordField2 = new JPasswordField();
JPasswordField passwordField3 = new JPasswordField();
JPasswordField passwordField4 = new JPasswordField();
@@ -188,28 +127,9 @@ class BasicComponentsPanel
JComboBox<String> warningHintsComboBox = new JComboBox<>();
JSpinner warningHintsSpinner = new JSpinner();
JLabel iconsLabel = new JLabel();
leadingIconTextField = new JTextField();
trailingIconTextField = new JTextField();
iconsTextField = new JTextField();
JLabel compsLabel = new JLabel();
compsTextField = new JTextField();
clearTextField = new JTextField();
JLabel fontsLabel = new JLabel();
JLabel h00Label = new JLabel();
JLabel h0Label = new JLabel();
JLabel h1Label = new JLabel();
JLabel h2Label = new JLabel();
JLabel h3Label = new JLabel();
JLabel h4Label = new JLabel();
JLabel lightLabel = new JLabel();
JLabel semiboldLabel = new JLabel();
JLabel fontZoomLabel = new JLabel();
JLabel largeLabel = new JLabel();
JLabel defaultLabel = new JLabel();
JLabel mediumLabel = new JLabel();
JLabel smallLabel = new JLabel();
JLabel miniLabel = new JLabel();
JLabel monospacedLabel = new JLabel();
JTextField leadingIconTextField = new JTextField();
JTextField trailingIconTextField = new JTextField();
JTextField iconsTextField = new JTextField();
JPopupMenu popupMenu1 = new JPopupMenu();
JMenuItem cutMenuItem = new JMenuItem();
JMenuItem copyMenuItem = new JMenuItem();
@@ -240,9 +160,6 @@ class BasicComponentsPanel
"[]para" +
"[]" +
"[]" +
"[]" +
"[]" +
"[]0" +
"[]"));
//---- labelLabel ----
@@ -750,94 +667,6 @@ class BasicComponentsPanel
iconsTextField.setText("text");
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.setText("Typography / Fonts:");
add(fontsLabel, "cell 0 16");
//---- h00Label ----
h00Label.setText("H00");
h00Label.putClientProperty("FlatLaf.styleClass", "h00");
add(h00Label, "cell 1 16 5 1");
//---- h0Label ----
h0Label.setText("H0");
h0Label.putClientProperty("FlatLaf.styleClass", "h0");
add(h0Label, "cell 1 16 5 1");
//---- h1Label ----
h1Label.setText("H1");
h1Label.putClientProperty("FlatLaf.styleClass", "h1");
add(h1Label, "cell 1 16 5 1");
//---- h2Label ----
h2Label.setText("H2");
h2Label.putClientProperty("FlatLaf.styleClass", "h2");
add(h2Label, "cell 1 16 5 1");
//---- h3Label ----
h3Label.setText("H3");
h3Label.putClientProperty("FlatLaf.styleClass", "h3");
add(h3Label, "cell 1 16 5 1");
//---- h4Label ----
h4Label.setText("H4");
h4Label.putClientProperty("FlatLaf.styleClass", "h4");
add(h4Label, "cell 1 16 5 1");
//---- lightLabel ----
lightLabel.setText("light");
lightLabel.putClientProperty("FlatLaf.style", "font: 200% $light.font");
add(lightLabel, "cell 1 16 5 1,gapx 30");
//---- semiboldLabel ----
semiboldLabel.setText("semibold");
semiboldLabel.putClientProperty("FlatLaf.style", "font: 200% $semibold.font");
add(semiboldLabel, "cell 1 16 5 1");
//---- fontZoomLabel ----
fontZoomLabel.setText("(200%)");
fontZoomLabel.putClientProperty("FlatLaf.styleClass", "small");
fontZoomLabel.setEnabled(false);
add(fontZoomLabel, "cell 1 16 5 1");
//---- largeLabel ----
largeLabel.setText("large");
largeLabel.putClientProperty("FlatLaf.styleClass", "large");
add(largeLabel, "cell 1 17 5 1");
//---- defaultLabel ----
defaultLabel.setText("default");
add(defaultLabel, "cell 1 17 5 1");
//---- mediumLabel ----
mediumLabel.setText("medium");
mediumLabel.putClientProperty("FlatLaf.styleClass", "medium");
add(mediumLabel, "cell 1 17 5 1");
//---- smallLabel ----
smallLabel.setText("small");
smallLabel.putClientProperty("FlatLaf.styleClass", "small");
add(smallLabel, "cell 1 17 5 1");
//---- miniLabel ----
miniLabel.setText("mini");
miniLabel.putClientProperty("FlatLaf.styleClass", "mini");
add(miniLabel, "cell 1 17 5 1");
//---- monospacedLabel ----
monospacedLabel.setText("monospaced");
monospacedLabel.putClientProperty("FlatLaf.styleClass", "monospaced");
add(monospacedLabel, "cell 1 17 5 1,gapx 30");
//======== popupMenu1 ========
{
@@ -862,67 +691,54 @@ class BasicComponentsPanel
copyMenuItem.addActionListener( new DefaultEditorKit.CopyAction() );
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 ) {
// hide some components
Component[] hiddenComponents = {
labelLabel, label1, label2,
button13, button14, button15, button16, comboBox5, comboBox6,
textField6, passwordField5,
textFieldLabel, textField2, textField4, textField6,
formattedTextFieldLabel, formattedTextField1, formattedTextField2, formattedTextField3, formattedTextField4, formattedTextField5,
passwordFieldLabel, passwordField1, passwordField2, passwordField3, passwordField4, passwordField5,
textAreaLabel, scrollPane1, scrollPane2, scrollPane3, scrollPane4, textArea5,
editorPaneLabel, scrollPane5, scrollPane6, scrollPane7, scrollPane8, editorPane5,
textPaneLabel, scrollPane9, scrollPane10, scrollPane11, scrollPane12, textPane5,
errorHintsLabel, errorHintsTextField, errorHintsComboBox, errorHintsSpinner,
warningHintsLabel, warningHintsTextField, warningHintsComboBox, warningHintsSpinner,
fontZoomLabel,
};
for( Component c : hiddenComponents )
c.setVisible( false );
// update layout (change row gaps to zero)
// move leading/trailing icon fields and password fields some rows up
Component[] formattedTextFields = { formattedTextFieldLabel, formattedTextField1, formattedTextField2, formattedTextField3, formattedTextField4 };
Component[] passwordFields = { passwordFieldLabel, passwordField1, passwordField2, passwordField3, passwordField4 };
Component[] iconsFields = { iconsLabel, leadingIconTextField, trailingIconTextField, iconsTextField };
MigLayout layout = (MigLayout) getLayout();
Object rowCons = layout.getRowConstraints();
AC ac = (rowCons instanceof String)
? ConstraintParser.parseColumnConstraints( (String) rowCons )
: (AC) rowCons;
BoundSize zeroGap = ConstraintParser.parseBoundSize( "0", true, true );
DimConstraint[] rows = ac.getConstaints();
rows[6].setGapBefore( zeroGap );
rows[7].setGapBefore( zeroGap );
rows[8].setGapBefore( zeroGap );
rows[9].setGapBefore( zeroGap );
rows[10].setGapBefore( zeroGap );
rows[11].setGapBefore( zeroGap );
rows[11].setGapAfter( zeroGap );
rows[12].setGapBefore( zeroGap );
rows[13].setGapBefore( zeroGap );
rows[16].setGapBefore( zeroGap );
layout.setRowConstraints( ac );
// move two text field into same row as spinners
spinnerLabel.setText( "JSpinner / JTextField:" );
layout.setComponentConstraints( textField1, "cell 3 5,growx" );
layout.setComponentConstraints( textField3, "cell 4 5,growx" );
for( int i = 0; i < iconsFields.length; i++ ) {
Object cons = layout.getComponentConstraints( passwordFields[i] );
layout.setComponentConstraints( iconsFields[i], cons );
}
for( int i = 0; i < passwordFields.length; i++ ) {
Object cons = layout.getComponentConstraints( formattedTextFields[i] );
layout.setComponentConstraints( passwordFields[i], cons );
}
// make "Not editable disabled" combobox smaller
Object cons = layout.getComponentConstraints( comboBox4 );
layout.setComponentConstraints( comboBox4, cons + ",width 50:50" );
revalidate();
repaint();
}
}
// 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
}

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 {
contentType: "form/swing"
@@ -9,7 +9,7 @@ new FormModel {
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "insets dialog,hidemode 3"
"$columnConstraints": "[][sizegroup 1][sizegroup 1][sizegroup 1][][]"
"$rowConstraints": "[][][][][][][][][][][][]para[][][][][]0[]"
"$rowConstraints": "[][][][][][][][][][][][]para[][][]"
} ) {
name: "this"
add( new FormComponent( "javax.swing.JLabel" ) {
@@ -375,9 +375,6 @@ new FormModel {
add( new FormComponent( "javax.swing.JPasswordField" ) {
name: "passwordField1"
"text": "Editable"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 8,growx"
} )
@@ -659,167 +656,24 @@ new FormModel {
} )
add( new FormComponent( "javax.swing.JTextField" ) {
name: "leadingIconTextField"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 14,growx"
} )
add( new FormComponent( "javax.swing.JTextField" ) {
name: "trailingIconTextField"
"text": "text"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 14,growx"
} )
add( new FormComponent( "javax.swing.JTextField" ) {
name: "iconsTextField"
"text": "text"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"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" ) {
name: "fontsLabel"
"text": "Typography / Fonts:"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 16"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "h00Label"
"text": "H00"
"$client.FlatLaf.styleClass": "h00"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 16 5 1"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "h0Label"
"text": "H0"
"$client.FlatLaf.styleClass": "h0"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 16 5 1"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "h1Label"
"text": "H1"
"$client.FlatLaf.styleClass": "h1"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 16 5 1"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "h2Label"
"text": "H2"
"$client.FlatLaf.styleClass": "h2"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 16 5 1"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "h3Label"
"text": "H3"
"$client.FlatLaf.styleClass": "h3"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 16 5 1"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "h4Label"
"text": "H4"
"$client.FlatLaf.styleClass": "h4"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 16 5 1"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "lightLabel"
"text": "light"
"$client.FlatLaf.style": "font: 200% $light.font"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 16 5 1,gapx 30"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "semiboldLabel"
"text": "semibold"
"$client.FlatLaf.style": "font: 200% $semibold.font"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 16 5 1"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "fontZoomLabel"
"text": "(200%)"
"$client.FlatLaf.styleClass": "small"
"enabled": false
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 16 5 1"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "largeLabel"
"text": "large"
"$client.FlatLaf.styleClass": "large"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 17 5 1"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "defaultLabel"
"text": "default"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 17 5 1"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "mediumLabel"
"text": "medium"
"$client.FlatLaf.styleClass": "medium"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 17 5 1"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "smallLabel"
"text": "small"
"$client.FlatLaf.styleClass": "small"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 17 5 1"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "miniLabel"
"text": "mini"
"$client.FlatLaf.styleClass": "mini"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 17 5 1"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "monospacedLabel"
"text": "monospaced"
"$client.FlatLaf.styleClass": "monospaced"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 17 5 1,gapx 30"
} )
}, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 0, 0 )
"size": new java.awt.Dimension( 920, 550 )
"size": new java.awt.Dimension( 920, 480 )
} )
add( new FormContainer( "javax.swing.JPopupMenu", new FormLayoutManager( class javax.swing.JPopupMenu ) ) {
name: "popupMenu1"
@@ -839,7 +693,7 @@ new FormModel {
"mnemonic": 80
} )
}, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 0, 570 )
"location": new java.awt.Point( 0, 500 )
"size": new java.awt.Dimension( 91, 87 )
} )
}

View File

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

View File

@@ -29,7 +29,6 @@ import java.util.prefs.Preferences;
import javax.swing.*;
import javax.swing.text.DefaultEditorKit;
import javax.swing.text.StyleContext;
import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.FlatDarculaLaf;
import com.formdev.flatlaf.FlatDarkLaf;
import com.formdev.flatlaf.FlatIntelliJLaf;
@@ -51,6 +50,7 @@ import com.formdev.flatlaf.ui.JBRCustomDecorations;
import com.formdev.flatlaf.util.ColorFunctions;
import com.formdev.flatlaf.util.LoggingFacade;
import com.formdev.flatlaf.util.SystemInfo;
import com.formdev.flatlaf.util.UIScale;
import net.miginfocom.layout.ConstraintParser;
import net.miginfocom.layout.LC;
import net.miginfocom.layout.UnitValue;
@@ -160,7 +160,8 @@ class DemoFrame
private void aboutActionPerformed() {
JLabel titleLabel = new JLabel( "FlatLaf Demo" );
titleLabel.putClientProperty( FlatClientProperties.STYLE_CLASS, "h1" );
Font titleFont = titleLabel.getFont();
titleLabel.setFont( titleFont.deriveFont( (float) titleFont.getSize() + UIScale.scale( 6 ) ) );
String link = "https://www.formdev.com/flatlaf/";
JLabel linkLabel = new JLabel( "<html><a href=\"#\">" + link + "</a></html>" );
@@ -215,7 +216,6 @@ class DemoFrame
menuBarEmbeddedCheckBoxMenuItem.setEnabled( windowDecorations );
unifiedTitleBarMenuItem.setEnabled( windowDecorations );
showTitleBarIconMenuItem.setEnabled( windowDecorations );
}
private void menuBarEmbeddedChanged() {
@@ -228,16 +228,6 @@ class DemoFrame
FlatLaf.repaintAllFramesAndDialogs();
}
private void showTitleBarIcon() {
boolean showIcon = showTitleBarIconMenuItem.isSelected();
// for main frame (because already created)
getRootPane().putClientProperty( FlatClientProperties.TITLE_BAR_SHOW_ICON, showIcon );
// for other not yet created frames/dialogs
UIManager.put( "TitlePane.showIcon", showIcon );
}
private void underlineMenuSelection() {
UIManager.put( "MenuItem.selectionType", underlineMenuSelectionMenuItem.isSelected() ? "underline" : null );
}
@@ -477,7 +467,6 @@ class DemoFrame
windowDecorationsCheckBoxMenuItem = new JCheckBoxMenuItem();
menuBarEmbeddedCheckBoxMenuItem = new JCheckBoxMenuItem();
unifiedTitleBarMenuItem = new JCheckBoxMenuItem();
showTitleBarIconMenuItem = new JCheckBoxMenuItem();
underlineMenuSelectionMenuItem = new JCheckBoxMenuItem();
alwaysShowMnemonicsMenuItem = new JCheckBoxMenuItem();
animatedLafChangeMenuItem = new JCheckBoxMenuItem();
@@ -729,11 +718,13 @@ class DemoFrame
//---- windowDecorationsCheckBoxMenuItem ----
windowDecorationsCheckBoxMenuItem.setText("Window decorations");
windowDecorationsCheckBoxMenuItem.setSelected(true);
windowDecorationsCheckBoxMenuItem.addActionListener(e -> windowDecorationsChanged());
optionsMenu.add(windowDecorationsCheckBoxMenuItem);
//---- menuBarEmbeddedCheckBoxMenuItem ----
menuBarEmbeddedCheckBoxMenuItem.setText("Embedded menu bar");
menuBarEmbeddedCheckBoxMenuItem.setSelected(true);
menuBarEmbeddedCheckBoxMenuItem.addActionListener(e -> menuBarEmbeddedChanged());
optionsMenu.add(menuBarEmbeddedCheckBoxMenuItem);
@@ -742,11 +733,6 @@ class DemoFrame
unifiedTitleBarMenuItem.addActionListener(e -> unifiedTitleBar());
optionsMenu.add(unifiedTitleBarMenuItem);
//---- showTitleBarIconMenuItem ----
showTitleBarIconMenuItem.setText("Show window title bar icon");
showTitleBarIconMenuItem.addActionListener(e -> showTitleBarIcon());
optionsMenu.add(showTitleBarIconMenuItem);
//---- underlineMenuSelectionMenuItem ----
underlineMenuSelectionMenuItem.setText("Use underline menu selection");
underlineMenuSelectionMenuItem.addActionListener(e -> underlineMenuSelection());
@@ -890,11 +876,6 @@ class DemoFrame
pasteMenuItem.addActionListener( new DefaultEditorKit.PasteAction() );
if( FlatLaf.supportsNativeWindowDecorations() ) {
windowDecorationsCheckBoxMenuItem.setSelected( FlatLaf.isUseNativeWindowDecorations() );
menuBarEmbeddedCheckBoxMenuItem.setSelected( UIManager.getBoolean( "TitlePane.menuBarEmbedded" ) );
unifiedTitleBarMenuItem.setSelected( UIManager.getBoolean( "TitlePane.unifiedBackground" ) );
showTitleBarIconMenuItem.setSelected( UIManager.getBoolean( "TitlePane.showIcon" ) );
if( JBRCustomDecorations.isSupported() ) {
// If the JetBrains Runtime is used, it forces the use of it's own custom
// window decoration, which can not disabled.
@@ -904,7 +885,6 @@ class DemoFrame
unsupported( windowDecorationsCheckBoxMenuItem );
unsupported( menuBarEmbeddedCheckBoxMenuItem );
unsupported( unifiedTitleBarMenuItem );
unsupported( showTitleBarIconMenuItem );
}
if( SystemInfo.isMacOS )
@@ -937,7 +917,6 @@ class DemoFrame
private JCheckBoxMenuItem windowDecorationsCheckBoxMenuItem;
private JCheckBoxMenuItem menuBarEmbeddedCheckBoxMenuItem;
private JCheckBoxMenuItem unifiedTitleBarMenuItem;
private JCheckBoxMenuItem showTitleBarIconMenuItem;
private JCheckBoxMenuItem underlineMenuSelectionMenuItem;
private JCheckBoxMenuItem alwaysShowMnemonicsMenuItem;
private JCheckBoxMenuItem animatedLafChangeMenuItem;

View File

@@ -354,6 +354,7 @@ new FormModel {
add( new FormComponent( "javax.swing.JCheckBoxMenuItem" ) {
name: "windowDecorationsCheckBoxMenuItem"
"text": "Window decorations"
"selected": true
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
@@ -362,6 +363,7 @@ new FormModel {
add( new FormComponent( "javax.swing.JCheckBoxMenuItem" ) {
name: "menuBarEmbeddedCheckBoxMenuItem"
"text": "Embedded menu bar"
"selected": true
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
@@ -375,14 +377,6 @@ new FormModel {
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "unifiedTitleBar", false ) )
} )
add( new FormComponent( "javax.swing.JCheckBoxMenuItem" ) {
name: "showTitleBarIconMenuItem"
"text": "Show window title bar icon"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "showTitleBarIcon", false ) )
} )
add( new FormComponent( "javax.swing.JCheckBoxMenuItem" ) {
name: "underlineMenuSelectionMenuItem"
"text": "Use underline menu selection"

View File

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

View File

@@ -18,15 +18,11 @@ package com.formdev.flatlaf.demo;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.geom.Area;
import java.awt.geom.RoundRectangle2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
import javax.swing.border.Border;
import com.formdev.flatlaf.FlatLaf;
import com.formdev.flatlaf.ui.FlatDropShadowBorder;
import com.formdev.flatlaf.ui.FlatEmptyBorder;
import com.formdev.flatlaf.ui.FlatPopupMenuBorder;
import com.formdev.flatlaf.ui.FlatUIUtils;
import com.formdev.flatlaf.util.UIScale;
import net.miginfocom.swing.*;
@@ -91,9 +87,6 @@ class HintManager
initComponents();
setOpaque( false );
updateBalloonBorder();
hintLabel.setText( "<html>" + hint.message + "</html>" );
// grab all mouse events to avoid that components overlapped
@@ -105,28 +98,8 @@ class HintManager
public void updateUI() {
super.updateUI();
if( UIManager.getLookAndFeel() instanceof FlatLaf )
setBackground( UIManager.getColor( "HintPanel.backgroundColor" ) );
else {
// using nonUIResource() because otherwise Nimbus does not fill the background
setBackground( FlatUIUtils.nonUIResource( UIManager.getColor( "info" ) ) );
}
if( hint != null )
updateBalloonBorder();
}
private void updateBalloonBorder() {
int direction;
switch( hint.position ) {
case SwingConstants.LEFT: direction = SwingConstants.RIGHT; break;
case SwingConstants.TOP: direction = SwingConstants.BOTTOM; break;
case SwingConstants.RIGHT: direction = SwingConstants.LEFT; break;
case SwingConstants.BOTTOM: direction = SwingConstants.TOP; break;
default: throw new IllegalArgumentException();
}
setBorder( new BalloonBorder( direction, FlatUIUtils.getUIColor( "PopupMenu.borderColor", Color.gray ) ) );
setBackground( UIManager.getColor( "HintPanel.backgroundColor" ) );
setBorder( new FlatPopupMenuBorder() );
}
void showHint() {
@@ -142,6 +115,11 @@ class HintManager
public void updateUI() {
super.updateUI();
setBorder( new FlatDropShadowBorder(
UIManager.getColor( "Popup.dropShadowColor" ),
UIManager.getInsets( "Popup.dropShadowInsets" ),
FlatUIUtils.getUIFloat( "Popup.dropShadowOpacity", 0.5f ) ) );
// use invokeLater because at this time the UI delegates
// of child components are not yet updated
EventQueue.invokeLater( () -> {
@@ -238,127 +216,4 @@ class HintManager
private JButton gotItButton;
// JFormDesigner - End of variables declaration //GEN-END:variables
}
//---- class BalloonBorder ------------------------------------------------
private static class BalloonBorder
extends FlatEmptyBorder
{
private static int ARC = 8;
private static int ARROW_XY = 16;
private static int ARROW_SIZE = 8;
private static int SHADOW_SIZE = 6;
private static int SHADOW_TOP_SIZE = 3;
private static int SHADOW_SIZE2 = SHADOW_SIZE + 2;
private final int direction;
private final Color borderColor;
private final Border shadowBorder;
public BalloonBorder( int direction, Color borderColor ) {
super( 1 + SHADOW_TOP_SIZE, 1 + SHADOW_SIZE, 1 + SHADOW_SIZE, 1 + SHADOW_SIZE );
this.direction = direction;
this.borderColor = borderColor;
switch( direction ) {
case SwingConstants.LEFT: left += ARROW_SIZE; break;
case SwingConstants.TOP: top += ARROW_SIZE; break;
case SwingConstants.RIGHT: right += ARROW_SIZE; break;
case SwingConstants.BOTTOM: bottom += ARROW_SIZE; break;
}
shadowBorder = UIManager.getLookAndFeel() instanceof FlatLaf
? new FlatDropShadowBorder(
UIManager.getColor( "Popup.dropShadowColor" ),
new Insets( SHADOW_SIZE2, SHADOW_SIZE2, SHADOW_SIZE2, SHADOW_SIZE2 ),
FlatUIUtils.getUIFloat( "Popup.dropShadowOpacity", 0.5f ) )
: null;
}
@Override
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
Graphics2D g2 = (Graphics2D) g.create();
try {
FlatUIUtils.setRenderingHints( g2 );
g2.translate( x, y );
// shadow coordinates
int sx = 0;
int sy = 0;
int sw = width;
int sh = height;
int arrowSize = UIScale.scale( ARROW_SIZE );
switch( direction ) {
case SwingConstants.LEFT: sx += arrowSize; sw -= arrowSize; break;
case SwingConstants.TOP: sy += arrowSize; sh -= arrowSize; break;
case SwingConstants.RIGHT: sw -= arrowSize; break;
case SwingConstants.BOTTOM: sh -= arrowSize; break;
}
// paint shadow
if( shadowBorder != null )
shadowBorder.paintBorder( c, g2, sx, sy, sw, sh );
// create balloon shape
int bx = UIScale.scale( SHADOW_SIZE );
int by = UIScale.scale( SHADOW_TOP_SIZE );
int bw = width - UIScale.scale( SHADOW_SIZE + SHADOW_SIZE );
int bh = height - UIScale.scale( SHADOW_TOP_SIZE + SHADOW_SIZE );
g2.translate( bx, by );
Shape shape = createBalloonShape( bw, bh );
// fill balloon background
g2.setColor( c.getBackground() );
g2.fill( shape );
// paint balloon border
g2.setColor( borderColor );
g2.setStroke( new BasicStroke( UIScale.scale( 1f ) ) );
g2.draw( shape );
} finally {
g2.dispose();
}
}
private Shape createBalloonShape( int width, int height ) {
int arc = UIScale.scale( ARC );
int xy = UIScale.scale( ARROW_XY );
int awh = UIScale.scale( ARROW_SIZE );
Shape rect;
Shape arrow;
switch( direction ) {
case SwingConstants.LEFT:
rect = new RoundRectangle2D.Float( awh, 0, width - 1 - awh, height - 1, arc, arc );
arrow = FlatUIUtils.createPath( awh,xy, 0,xy+awh, awh,xy+awh+awh );
break;
case SwingConstants.TOP:
rect = new RoundRectangle2D.Float( 0, awh, width - 1, height - 1 - awh, arc, arc );
arrow = FlatUIUtils.createPath( xy,awh, xy+awh,0, xy+awh+awh,awh );
break;
case SwingConstants.RIGHT:
rect = new RoundRectangle2D.Float( 0, 0, width - 1 - awh, height - 1, arc, arc );
int x = width - 1 - awh;
arrow = FlatUIUtils.createPath( x,xy, x+awh,xy+awh, x,xy+awh+awh );
break;
case SwingConstants.BOTTOM:
rect = new RoundRectangle2D.Float( 0, 0, width - 1, height - 1 - awh, arc, arc );
int y = height - 1 - awh;
arrow = FlatUIUtils.createPath( xy,y, xy+awh,y+awh, xy+awh+awh,y );
break;
default:
throw new RuntimeException();
}
Area area = new Area( rect );
area.add( new Area( arrow ) );
return area;
}
}
}

View File

@@ -21,7 +21,6 @@ import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;
import javax.swing.border.*;
import com.formdev.flatlaf.FlatLaf;
import net.miginfocom.swing.*;
/**
@@ -45,29 +44,6 @@ class OptionPanePanel
"OK",
"Cancel",
} );
if( FlatLaf.supportsNativeWindowDecorations() ) {
updateShowTitleBarIcon();
UIManager.getDefaults().addPropertyChangeListener( e -> {
switch( e.getPropertyName() ) {
case "TitlePane.showIcon":
case "TitlePane.useWindowDecorations":
updateShowTitleBarIcon();
break;
}
} );
} else
showTitleBarIconCheckBox.setEnabled( false );
}
private void updateShowTitleBarIcon() {
showTitleBarIconCheckBox.setEnabled( UIManager.getBoolean( "TitlePane.showIcon" ) &&
FlatLaf.isUseNativeWindowDecorations() );
}
private void showTitleBarIcon() {
UIManager.put( "OptionPane.showIcon", showTitleBarIconCheckBox.isSelected() );
}
private void initComponents() {
@@ -78,7 +54,6 @@ class OptionPanePanel
JPanel panel1 = new JPanel();
JOptionPane plainOptionPane = new JOptionPane();
plainShowDialogLabel = new OptionPanePanel.ShowDialogLinkLabel();
showTitleBarIconCheckBox = new JCheckBox();
JLabel errorLabel = new JLabel();
JPanel panel2 = new JPanel();
JOptionPane errorOptionPane = new JOptionPane();
@@ -118,7 +93,7 @@ class OptionPanePanel
//======== panel9 ========
{
panel9.setLayout(new MigLayout(
"insets dialog,hidemode 3",
"flowy,insets dialog,hidemode 3",
// columns
"[]" +
"[]" +
@@ -151,12 +126,7 @@ class OptionPanePanel
//---- plainShowDialogLabel ----
plainShowDialogLabel.setOptionPane(plainOptionPane);
plainShowDialogLabel.setTitleLabel(plainLabel);
panel9.add(plainShowDialogLabel, "cell 1 0");
//---- showTitleBarIconCheckBox ----
showTitleBarIconCheckBox.setText("Show window title bar icon");
showTitleBarIconCheckBox.addActionListener(e -> showTitleBarIcon());
panel9.add(showTitleBarIconCheckBox, "cell 2 0");
panel9.add(plainShowDialogLabel, "cell 2 0");
//---- errorLabel ----
errorLabel.setText("Error");
@@ -178,7 +148,7 @@ class OptionPanePanel
//---- errorShowDialogLabel ----
errorShowDialogLabel.setTitleLabel(errorLabel);
errorShowDialogLabel.setOptionPane(errorOptionPane);
panel9.add(errorShowDialogLabel, "cell 1 1");
panel9.add(errorShowDialogLabel, "cell 2 1");
//---- informationLabel ----
informationLabel.setText("Information");
@@ -200,7 +170,7 @@ class OptionPanePanel
//---- informationShowDialogLabel ----
informationShowDialogLabel.setOptionPane(informationOptionPane);
informationShowDialogLabel.setTitleLabel(informationLabel);
panel9.add(informationShowDialogLabel, "cell 1 2");
panel9.add(informationShowDialogLabel, "cell 2 2");
//---- questionLabel ----
questionLabel.setText("Question");
@@ -244,7 +214,7 @@ class OptionPanePanel
//---- warningShowDialogLabel ----
warningShowDialogLabel.setOptionPane(warningOptionPane);
warningShowDialogLabel.setTitleLabel(warningLabel);
panel9.add(warningShowDialogLabel, "cell 1 4");
panel9.add(warningShowDialogLabel, "cell 2 4");
//---- inputLabel ----
inputLabel.setText("Input");
@@ -266,7 +236,7 @@ class OptionPanePanel
//---- inputShowDialogLabel ----
inputShowDialogLabel.setOptionPane(inputOptionPane);
inputShowDialogLabel.setTitleLabel(inputLabel);
panel9.add(inputShowDialogLabel, "cell 1 5");
panel9.add(inputShowDialogLabel, "cell 2 5");
//---- inputIconLabel ----
inputIconLabel.setText("Input + icon");
@@ -289,7 +259,7 @@ class OptionPanePanel
//---- inputIconShowDialogLabel ----
inputIconShowDialogLabel.setTitleLabel(inputIconLabel);
inputIconShowDialogLabel.setOptionPane(inputIconOptionPane);
panel9.add(inputIconShowDialogLabel, "cell 1 6");
panel9.add(inputIconShowDialogLabel, "cell 2 6");
//---- customLabel ----
customLabel.setText("Custom");
@@ -309,7 +279,7 @@ class OptionPanePanel
//---- customShowDialogLabel ----
customShowDialogLabel.setOptionPane(customOptionPane);
customShowDialogLabel.setTitleLabel(customLabel);
panel9.add(customShowDialogLabel, "cell 1 7");
panel9.add(customShowDialogLabel, "cell 2 7");
}
scrollPane1.setViewportView(panel9);
}
@@ -319,7 +289,6 @@ class OptionPanePanel
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
private OptionPanePanel.ShowDialogLinkLabel plainShowDialogLabel;
private JCheckBox showTitleBarIconCheckBox;
private OptionPanePanel.ShowDialogLinkLabel errorShowDialogLabel;
private OptionPanePanel.ShowDialogLinkLabel informationShowDialogLabel;
private JOptionPane customOptionPane;
@@ -335,7 +304,6 @@ class OptionPanePanel
ShowDialogLinkLabel() {
setText( "<html><a href=\"#\">Show dialog</a></html>" );
setCursor( Cursor.getPredefinedCursor( Cursor.HAND_CURSOR ) );
addMouseListener( new MouseAdapter() {
@Override

View File

@@ -12,7 +12,7 @@ new FormModel {
name: "scrollPane1"
"border": new javax.swing.border.EmptyBorder( 0, 0, 0, 0 )
add( new FormContainer( "com.formdev.flatlaf.demo.ScrollablePanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "insets dialog,hidemode 3"
"$layoutConstraints": "flowy,insets dialog,hidemode 3"
"$columnConstraints": "[][][fill]"
"$rowConstraints": "[top][top][top][top][top][top][top][top]"
} ) {
@@ -42,16 +42,6 @@ new FormModel {
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 0"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "showTitleBarIconCheckBox"
"text": "Show window title bar icon"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "showTitleBarIcon", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 0"
} )
@@ -83,7 +73,7 @@ new FormModel {
"JavaCodeGenerator.variableLocal": false
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 1"
"value": "cell 2 1"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "informationLabel"
@@ -113,7 +103,7 @@ new FormModel {
"JavaCodeGenerator.variableLocal": false
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 2"
"value": "cell 2 2"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "questionLabel"
@@ -167,7 +157,7 @@ new FormModel {
"optionPane": new FormReference( "warningOptionPane" )
"titleLabel": new FormReference( "warningLabel" )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 4"
"value": "cell 2 4"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "inputLabel"
@@ -194,7 +184,7 @@ new FormModel {
"optionPane": new FormReference( "inputOptionPane" )
"titleLabel": new FormReference( "inputLabel" )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 5"
"value": "cell 2 5"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "inputIconLabel"
@@ -222,7 +212,7 @@ new FormModel {
"titleLabel": new FormReference( "inputIconLabel" )
"optionPane": new FormReference( "inputIconOptionPane" )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 6"
"value": "cell 2 6"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "customLabel"
@@ -250,7 +240,7 @@ new FormModel {
"optionPane": new FormReference( "customOptionPane" )
"titleLabel": new FormReference( "customLabel" )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 7"
"value": "cell 2 7"
} )
} )
}, new FormLayoutConstraints( class java.lang.String ) {
@@ -258,7 +248,7 @@ new FormModel {
} )
}, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 0, 0 )
"size": new java.awt.Dimension( 955, 900 )
"size": new java.awt.Dimension( 840, 900 )
} )
}
}

View File

@@ -303,11 +303,6 @@ class TabsPanel
putTabbedPanesClientProperty( TABBED_PANE_SCROLL_BUTTONS_PLACEMENT, scrollButtonsPlacement );
}
private void tabTypeChanged() {
String tabType = cardTabTypeButton.isSelected() ? TABBED_PANE_TAB_TYPE_CARD : null;
putTabbedPanesClientProperty( TABBED_PANE_TAB_TYPE, tabType );
}
private void showTabSeparatorsChanged() {
Boolean showTabSeparators = showTabSeparatorsCheckBox.isSelected() ? true : null;
putTabbedPanesClientProperty( TABBED_PANE_SHOW_TAB_SEPARATORS, showTabSeparators );
@@ -401,17 +396,14 @@ class TabsPanel
scrollButtonsPlacementToolBar = new JToolBar();
scrollBothButton = new JToggleButton();
scrollTrailingButton = new JToggleButton();
showTabSeparatorsCheckBox = new JCheckBox();
tabsPopupPolicyLabel = new JLabel();
tabsPopupPolicyToolBar = new JToolBar();
popupAsNeededButton = new JToggleButton();
popupNeverButton = new JToggleButton();
tabTypeLabel = new JLabel();
tabTypeToolBar = new JToolBar();
underlinedTabTypeButton = new JToggleButton();
cardTabTypeButton = new JToggleButton();
showTabSeparatorsCheckBox = new JCheckBox();
//======== this ========
setName("this");
setLayout(new MigLayout(
"insets dialog,hidemode 3",
// columns
@@ -425,6 +417,7 @@ class TabsPanel
//======== panel1 ========
{
panel1.setName("panel1");
panel1.setLayout(new MigLayout(
"insets 0,hidemode 3",
// columns
@@ -442,75 +435,92 @@ class TabsPanel
//---- tabPlacementLabel ----
tabPlacementLabel.setText("Tab placement");
tabPlacementLabel.putClientProperty("FlatLaf.styleClass", "h3");
tabPlacementLabel.setFont(tabPlacementLabel.getFont().deriveFont(tabPlacementLabel.getFont().getSize() + 4f));
tabPlacementLabel.setName("tabPlacementLabel");
panel1.add(tabPlacementLabel, "cell 0 0");
//======== tabPlacementToolBar ========
{
tabPlacementToolBar.setFloatable(false);
tabPlacementToolBar.setBorder(BorderFactory.createEmptyBorder());
tabPlacementToolBar.setName("tabPlacementToolBar");
//---- topPlacementButton ----
topPlacementButton.setText("top");
topPlacementButton.setSelected(true);
topPlacementButton.putClientProperty("FlatLaf.styleClass", "small");
topPlacementButton.setFont(topPlacementButton.getFont().deriveFont(topPlacementButton.getFont().getSize() - 2f));
topPlacementButton.setName("topPlacementButton");
topPlacementButton.addActionListener(e -> tabPlacementChanged());
tabPlacementToolBar.add(topPlacementButton);
//---- bottomPlacementButton ----
bottomPlacementButton.setText("bottom");
bottomPlacementButton.putClientProperty("FlatLaf.styleClass", "small");
bottomPlacementButton.setFont(bottomPlacementButton.getFont().deriveFont(bottomPlacementButton.getFont().getSize() - 2f));
bottomPlacementButton.setName("bottomPlacementButton");
bottomPlacementButton.addActionListener(e -> tabPlacementChanged());
tabPlacementToolBar.add(bottomPlacementButton);
//---- leftPlacementButton ----
leftPlacementButton.setText("left");
leftPlacementButton.putClientProperty("FlatLaf.styleClass", "small");
leftPlacementButton.setFont(leftPlacementButton.getFont().deriveFont(leftPlacementButton.getFont().getSize() - 2f));
leftPlacementButton.setName("leftPlacementButton");
leftPlacementButton.addActionListener(e -> tabPlacementChanged());
tabPlacementToolBar.add(leftPlacementButton);
//---- rightPlacementButton ----
rightPlacementButton.setText("right");
rightPlacementButton.putClientProperty("FlatLaf.styleClass", "small");
rightPlacementButton.setFont(rightPlacementButton.getFont().deriveFont(rightPlacementButton.getFont().getSize() - 2f));
rightPlacementButton.setName("rightPlacementButton");
rightPlacementButton.addActionListener(e -> tabPlacementChanged());
tabPlacementToolBar.add(rightPlacementButton);
tabPlacementToolBar.addSeparator();
//---- scrollButton ----
scrollButton.setText("scroll");
scrollButton.putClientProperty("FlatLaf.styleClass", "small");
scrollButton.setFont(scrollButton.getFont().deriveFont(scrollButton.getFont().getSize() - 2f));
scrollButton.setName("scrollButton");
scrollButton.addActionListener(e -> scrollChanged());
tabPlacementToolBar.add(scrollButton);
//---- borderButton ----
borderButton.setText("border");
borderButton.putClientProperty("FlatLaf.styleClass", "small");
borderButton.setFont(borderButton.getFont().deriveFont(borderButton.getFont().getSize() - 2f));
borderButton.setName("borderButton");
borderButton.addActionListener(e -> borderChanged());
tabPlacementToolBar.add(borderButton);
}
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");
//---- tabLayoutLabel ----
tabLayoutLabel.setText("Tab layout");
tabLayoutLabel.putClientProperty("FlatLaf.styleClass", "h3");
tabLayoutLabel.setFont(tabLayoutLabel.getFont().deriveFont(tabLayoutLabel.getFont().getSize() + 4f));
tabLayoutLabel.setName("tabLayoutLabel");
panel1.add(tabLayoutLabel, "cell 0 2");
//======== tabLayoutToolBar ========
{
tabLayoutToolBar.setFloatable(false);
tabLayoutToolBar.setBorder(BorderFactory.createEmptyBorder());
tabLayoutToolBar.setName("tabLayoutToolBar");
//---- scrollTabLayoutButton ----
scrollTabLayoutButton.setText("scroll");
scrollTabLayoutButton.setFont(scrollTabLayoutButton.getFont().deriveFont(scrollTabLayoutButton.getFont().getSize() - 2f));
scrollTabLayoutButton.setSelected(true);
scrollTabLayoutButton.putClientProperty("FlatLaf.styleClass", "small");
scrollTabLayoutButton.setName("scrollTabLayoutButton");
scrollTabLayoutButton.addActionListener(e -> tabLayoutChanged());
tabLayoutToolBar.add(scrollTabLayoutButton);
//---- wrapTabLayoutButton ----
wrapTabLayoutButton.setText("wrap");
wrapTabLayoutButton.putClientProperty("FlatLaf.styleClass", "small");
wrapTabLayoutButton.setFont(wrapTabLayoutButton.getFont().deriveFont(wrapTabLayoutButton.getFont().getSize() - 2f));
wrapTabLayoutButton.setName("wrapTabLayoutButton");
wrapTabLayoutButton.addActionListener(e -> tabLayoutChanged());
tabLayoutToolBar.add(wrapTabLayoutButton);
}
@@ -519,80 +529,112 @@ class TabsPanel
//---- scrollLayoutNoteLabel ----
scrollLayoutNoteLabel.setText("(use mouse wheel to scroll; arrow button shows hidden tabs)");
scrollLayoutNoteLabel.setEnabled(false);
scrollLayoutNoteLabel.putClientProperty("FlatLaf.styleClass", "small");
scrollLayoutNoteLabel.setFont(scrollLayoutNoteLabel.getFont().deriveFont(scrollLayoutNoteLabel.getFont().getSize() - 2f));
scrollLayoutNoteLabel.setName("scrollLayoutNoteLabel");
panel1.add(scrollLayoutNoteLabel, "cell 0 3");
//---- wrapLayoutNoteLabel ----
wrapLayoutNoteLabel.setText("(probably better to use scroll layout?)");
wrapLayoutNoteLabel.setEnabled(false);
wrapLayoutNoteLabel.putClientProperty("FlatLaf.styleClass", "small");
wrapLayoutNoteLabel.setFont(wrapLayoutNoteLabel.getFont().deriveFont(wrapLayoutNoteLabel.getFont().getSize() - 2f));
wrapLayoutNoteLabel.setName("wrapLayoutNoteLabel");
panel1.add(wrapLayoutNoteLabel, "cell 0 3");
//======== scrollLayoutTabbedPane ========
{
scrollLayoutTabbedPane.setName("scrollLayoutTabbedPane");
}
panel1.add(scrollLayoutTabbedPane, "cell 0 4");
//======== wrapLayoutTabbedPane ========
{
wrapLayoutTabbedPane.setName("wrapLayoutTabbedPane");
}
panel1.add(wrapLayoutTabbedPane, "cell 0 4,width 100:100,height pref*2px");
//---- closableTabsLabel ----
closableTabsLabel.setText("Closable tabs");
closableTabsLabel.putClientProperty("FlatLaf.styleClass", "h3");
closableTabsLabel.setFont(closableTabsLabel.getFont().deriveFont(closableTabsLabel.getFont().getSize() + 4f));
closableTabsLabel.setName("closableTabsLabel");
panel1.add(closableTabsLabel, "cell 0 5");
//======== closableTabsToolBar ========
{
closableTabsToolBar.setFloatable(false);
closableTabsToolBar.setBorder(BorderFactory.createEmptyBorder());
closableTabsToolBar.setName("closableTabsToolBar");
//---- squareCloseButton ----
squareCloseButton.setText("square");
squareCloseButton.setFont(squareCloseButton.getFont().deriveFont(squareCloseButton.getFont().getSize() - 2f));
squareCloseButton.setSelected(true);
squareCloseButton.putClientProperty("FlatLaf.styleClass", "small");
squareCloseButton.setName("squareCloseButton");
squareCloseButton.addActionListener(e -> closeButtonStyleChanged());
closableTabsToolBar.add(squareCloseButton);
//---- circleCloseButton ----
circleCloseButton.setText("circle");
circleCloseButton.putClientProperty("FlatLaf.styleClass", "small");
circleCloseButton.setFont(circleCloseButton.getFont().deriveFont(circleCloseButton.getFont().getSize() - 2f));
circleCloseButton.setName("circleCloseButton");
circleCloseButton.addActionListener(e -> closeButtonStyleChanged());
closableTabsToolBar.add(circleCloseButton);
//---- redCrossCloseButton ----
redCrossCloseButton.setText("red cross");
redCrossCloseButton.putClientProperty("FlatLaf.styleClass", "small");
redCrossCloseButton.setFont(redCrossCloseButton.getFont().deriveFont(redCrossCloseButton.getFont().getSize() - 2f));
redCrossCloseButton.setName("redCrossCloseButton");
redCrossCloseButton.addActionListener(e -> closeButtonStyleChanged());
closableTabsToolBar.add(redCrossCloseButton);
}
panel1.add(closableTabsToolBar, "cell 0 5,alignx right,growx 0");
//======== closableTabsTabbedPane ========
{
closableTabsTabbedPane.setName("closableTabsTabbedPane");
}
panel1.add(closableTabsTabbedPane, "cell 0 6");
//---- tabAreaComponentsLabel ----
tabAreaComponentsLabel.setText("Custom tab area components");
tabAreaComponentsLabel.putClientProperty("FlatLaf.styleClass", "h3");
tabAreaComponentsLabel.setFont(tabAreaComponentsLabel.getFont().deriveFont(tabAreaComponentsLabel.getFont().getSize() + 4f));
tabAreaComponentsLabel.setName("tabAreaComponentsLabel");
panel1.add(tabAreaComponentsLabel, "cell 0 7");
//======== tabAreaComponentsToolBar ========
{
tabAreaComponentsToolBar.setFloatable(false);
tabAreaComponentsToolBar.setBorder(BorderFactory.createEmptyBorder());
tabAreaComponentsToolBar.setName("tabAreaComponentsToolBar");
//---- leadingComponentButton ----
leadingComponentButton.setText("leading");
leadingComponentButton.setFont(leadingComponentButton.getFont().deriveFont(leadingComponentButton.getFont().getSize() - 2f));
leadingComponentButton.setSelected(true);
leadingComponentButton.putClientProperty("FlatLaf.styleClass", "small");
leadingComponentButton.setName("leadingComponentButton");
leadingComponentButton.addActionListener(e -> customComponentsChanged());
tabAreaComponentsToolBar.add(leadingComponentButton);
//---- trailingComponentButton ----
trailingComponentButton.setText("trailing");
trailingComponentButton.setFont(trailingComponentButton.getFont().deriveFont(trailingComponentButton.getFont().getSize() - 2f));
trailingComponentButton.setSelected(true);
trailingComponentButton.putClientProperty("FlatLaf.styleClass", "small");
trailingComponentButton.setName("trailingComponentButton");
trailingComponentButton.addActionListener(e -> customComponentsChanged());
tabAreaComponentsToolBar.add(trailingComponentButton);
}
panel1.add(tabAreaComponentsToolBar, "cell 0 7,alignx right,growx 0");
//======== customComponentsTabbedPane ========
{
customComponentsTabbedPane.setName("customComponentsTabbedPane");
}
panel1.add(customComponentsTabbedPane, "cell 0 8");
}
add(panel1, "cell 0 0");
//======== panel2 ========
{
panel2.setName("panel2");
panel2.setLayout(new MigLayout(
"insets 0,hidemode 3",
// columns
@@ -613,38 +655,83 @@ class TabsPanel
//---- tabIconPlacementLabel ----
tabIconPlacementLabel.setText("Tab icon placement");
tabIconPlacementLabel.putClientProperty("FlatLaf.styleClass", "h3");
tabIconPlacementLabel.setFont(tabIconPlacementLabel.getFont().deriveFont(tabIconPlacementLabel.getFont().getSize() + 4f));
tabIconPlacementLabel.setName("tabIconPlacementLabel");
panel2.add(tabIconPlacementLabel, "cell 0 0");
//---- tabIconPlacementNodeLabel ----
tabIconPlacementNodeLabel.setText("(top/bottom/leading/trailing)");
tabIconPlacementNodeLabel.setEnabled(false);
tabIconPlacementNodeLabel.putClientProperty("FlatLaf.styleClass", "small");
tabIconPlacementNodeLabel.setFont(tabIconPlacementNodeLabel.getFont().deriveFont(tabIconPlacementNodeLabel.getFont().getSize() - 2f));
tabIconPlacementNodeLabel.setName("tabIconPlacementNodeLabel");
panel2.add(tabIconPlacementNodeLabel, "cell 0 1");
//======== iconTopTabbedPane ========
{
iconTopTabbedPane.setName("iconTopTabbedPane");
}
panel2.add(iconTopTabbedPane, "cell 0 2");
//======== iconBottomTabbedPane ========
{
iconBottomTabbedPane.setName("iconBottomTabbedPane");
}
panel2.add(iconBottomTabbedPane, "cell 0 3");
//======== iconLeadingTabbedPane ========
{
iconLeadingTabbedPane.setName("iconLeadingTabbedPane");
}
panel2.add(iconLeadingTabbedPane, "cell 0 4");
//======== iconTrailingTabbedPane ========
{
iconTrailingTabbedPane.setName("iconTrailingTabbedPane");
}
panel2.add(iconTrailingTabbedPane, "cell 0 5");
//---- tabAreaAlignmentLabel ----
tabAreaAlignmentLabel.setText("Tab area alignment");
tabAreaAlignmentLabel.putClientProperty("FlatLaf.styleClass", "h3");
tabAreaAlignmentLabel.setFont(tabAreaAlignmentLabel.getFont().deriveFont(tabAreaAlignmentLabel.getFont().getSize() + 4f));
tabAreaAlignmentLabel.setName("tabAreaAlignmentLabel");
panel2.add(tabAreaAlignmentLabel, "cell 0 6");
//---- tabAreaAlignmentNoteLabel ----
tabAreaAlignmentNoteLabel.setText("(leading/center/trailing/fill)");
tabAreaAlignmentNoteLabel.setEnabled(false);
tabAreaAlignmentNoteLabel.putClientProperty("FlatLaf.styleClass", "small");
tabAreaAlignmentNoteLabel.setFont(tabAreaAlignmentNoteLabel.getFont().deriveFont(tabAreaAlignmentNoteLabel.getFont().getSize() - 2f));
tabAreaAlignmentNoteLabel.setName("tabAreaAlignmentNoteLabel");
panel2.add(tabAreaAlignmentNoteLabel, "cell 0 7");
//======== alignLeadingTabbedPane ========
{
alignLeadingTabbedPane.setName("alignLeadingTabbedPane");
}
panel2.add(alignLeadingTabbedPane, "cell 0 8");
//======== alignCenterTabbedPane ========
{
alignCenterTabbedPane.setName("alignCenterTabbedPane");
}
panel2.add(alignCenterTabbedPane, "cell 0 9");
//======== alignTrailingTabbedPane ========
{
alignTrailingTabbedPane.setName("alignTrailingTabbedPane");
}
panel2.add(alignTrailingTabbedPane, "cell 0 10");
//======== alignFillTabbedPane ========
{
alignFillTabbedPane.setName("alignFillTabbedPane");
}
panel2.add(alignFillTabbedPane, "cell 0 11");
}
add(panel2, "cell 1 0,growy");
//======== panel3 ========
{
panel3.setName("panel3");
panel3.setLayout(new MigLayout(
"insets 0,hidemode 3",
// columns
@@ -663,32 +750,62 @@ class TabsPanel
//---- tabWidthModeLabel ----
tabWidthModeLabel.setText("Tab width mode");
tabWidthModeLabel.putClientProperty("FlatLaf.styleClass", "h3");
tabWidthModeLabel.setFont(tabWidthModeLabel.getFont().deriveFont(tabWidthModeLabel.getFont().getSize() + 4f));
tabWidthModeLabel.setName("tabWidthModeLabel");
panel3.add(tabWidthModeLabel, "cell 0 0");
//---- tabWidthModeNoteLabel ----
tabWidthModeNoteLabel.setText("(preferred/equal/compact)");
tabWidthModeNoteLabel.setFont(tabWidthModeNoteLabel.getFont().deriveFont(tabWidthModeNoteLabel.getFont().getSize() - 2f));
tabWidthModeNoteLabel.setEnabled(false);
tabWidthModeNoteLabel.putClientProperty("FlatLaf.styleClass", "small");
tabWidthModeNoteLabel.setName("tabWidthModeNoteLabel");
panel3.add(tabWidthModeNoteLabel, "cell 0 1");
//======== widthPreferredTabbedPane ========
{
widthPreferredTabbedPane.setName("widthPreferredTabbedPane");
}
panel3.add(widthPreferredTabbedPane, "cell 0 2");
//======== widthEqualTabbedPane ========
{
widthEqualTabbedPane.setName("widthEqualTabbedPane");
}
panel3.add(widthEqualTabbedPane, "cell 0 3");
//======== widthCompactTabbedPane ========
{
widthCompactTabbedPane.setName("widthCompactTabbedPane");
}
panel3.add(widthCompactTabbedPane, "cell 0 4");
//---- minMaxTabWidthLabel ----
minMaxTabWidthLabel.setText("Minimum/maximum tab width");
minMaxTabWidthLabel.putClientProperty("FlatLaf.styleClass", "h3");
minMaxTabWidthLabel.setFont(minMaxTabWidthLabel.getFont().deriveFont(minMaxTabWidthLabel.getFont().getSize() + 4f));
minMaxTabWidthLabel.setName("minMaxTabWidthLabel");
panel3.add(minMaxTabWidthLabel, "cell 0 5");
//======== minimumTabWidthTabbedPane ========
{
minimumTabWidthTabbedPane.setName("minimumTabWidthTabbedPane");
}
panel3.add(minimumTabWidthTabbedPane, "cell 0 6");
//======== maximumTabWidthTabbedPane ========
{
maximumTabWidthTabbedPane.setName("maximumTabWidthTabbedPane");
}
panel3.add(maximumTabWidthTabbedPane, "cell 0 7");
//---- tabAlignmentLabel ----
tabAlignmentLabel.setText("Tab title alignment");
tabAlignmentLabel.putClientProperty("FlatLaf.styleClass", "h3");
tabAlignmentLabel.setFont(tabAlignmentLabel.getFont().deriveFont(tabAlignmentLabel.getFont().getSize() + 4f));
tabAlignmentLabel.setName("tabAlignmentLabel");
panel3.add(tabAlignmentLabel, "cell 0 8");
//======== panel5 ========
{
panel5.setName("panel5");
panel5.setLayout(new MigLayout(
"insets 0,hidemode 3",
// columns
@@ -703,68 +820,94 @@ class TabsPanel
//---- tabAlignmentNoteLabel ----
tabAlignmentNoteLabel.setText("(leading/center/trailing)");
tabAlignmentNoteLabel.setEnabled(false);
tabAlignmentNoteLabel.putClientProperty("FlatLaf.styleClass", "small");
tabAlignmentNoteLabel.setFont(tabAlignmentNoteLabel.getFont().deriveFont(tabAlignmentNoteLabel.getFont().getSize() - 2f));
tabAlignmentNoteLabel.setName("tabAlignmentNoteLabel");
panel5.add(tabAlignmentNoteLabel, "cell 0 0");
//---- tabAlignmentNoteLabel2 ----
tabAlignmentNoteLabel2.setText("(trailing)");
tabAlignmentNoteLabel2.setEnabled(false);
tabAlignmentNoteLabel2.putClientProperty("FlatLaf.styleClass", "small");
tabAlignmentNoteLabel2.setFont(tabAlignmentNoteLabel2.getFont().deriveFont(tabAlignmentNoteLabel2.getFont().getSize() - 2f));
tabAlignmentNoteLabel2.setName("tabAlignmentNoteLabel2");
panel5.add(tabAlignmentNoteLabel2, "cell 1 0,alignx right,growx 0");
//======== tabAlignLeadingTabbedPane ========
{
tabAlignLeadingTabbedPane.setName("tabAlignLeadingTabbedPane");
}
panel5.add(tabAlignLeadingTabbedPane, "cell 0 1");
//======== tabAlignVerticalTabbedPane ========
{
tabAlignVerticalTabbedPane.setTabPlacement(SwingConstants.LEFT);
tabAlignVerticalTabbedPane.setName("tabAlignVerticalTabbedPane");
}
panel5.add(tabAlignVerticalTabbedPane, "cell 1 1 1 3,growy");
//======== tabAlignCenterTabbedPane ========
{
tabAlignCenterTabbedPane.setName("tabAlignCenterTabbedPane");
}
panel5.add(tabAlignCenterTabbedPane, "cell 0 2");
//======== tabAlignTrailingTabbedPane ========
{
tabAlignTrailingTabbedPane.setName("tabAlignTrailingTabbedPane");
}
panel5.add(tabAlignTrailingTabbedPane, "cell 0 3");
}
panel3.add(panel5, "cell 0 9");
}
add(panel3, "cell 2 0");
//---- separator2 ----
separator2.setName("separator2");
add(separator2, "cell 0 1 3 1");
//======== panel4 ========
{
panel4.setName("panel4");
panel4.setLayout(new MigLayout(
"insets 0,hidemode 3",
// columns
"[]" +
"[fill]para" +
"[fill]" +
"[fill]para" +
"[fill]",
"[fill]para",
// rows
"[]" +
"[center]"));
//---- scrollButtonsPolicyLabel ----
scrollButtonsPolicyLabel.setText("Scroll buttons policy:");
scrollButtonsPolicyLabel.setName("scrollButtonsPolicyLabel");
panel4.add(scrollButtonsPolicyLabel, "cell 0 0");
//======== scrollButtonsPolicyToolBar ========
{
scrollButtonsPolicyToolBar.setFloatable(false);
scrollButtonsPolicyToolBar.setBorder(BorderFactory.createEmptyBorder());
scrollButtonsPolicyToolBar.setName("scrollButtonsPolicyToolBar");
//---- scrollAsNeededSingleButton ----
scrollAsNeededSingleButton.setText("asNeededSingle");
scrollAsNeededSingleButton.setFont(scrollAsNeededSingleButton.getFont().deriveFont(scrollAsNeededSingleButton.getFont().getSize() - 2f));
scrollAsNeededSingleButton.setSelected(true);
scrollAsNeededSingleButton.putClientProperty("FlatLaf.styleClass", "small");
scrollAsNeededSingleButton.setName("scrollAsNeededSingleButton");
scrollAsNeededSingleButton.addActionListener(e -> scrollButtonsPolicyChanged());
scrollButtonsPolicyToolBar.add(scrollAsNeededSingleButton);
//---- scrollAsNeededButton ----
scrollAsNeededButton.setText("asNeeded");
scrollAsNeededButton.putClientProperty("FlatLaf.styleClass", "small");
scrollAsNeededButton.setFont(scrollAsNeededButton.getFont().deriveFont(scrollAsNeededButton.getFont().getSize() - 2f));
scrollAsNeededButton.setName("scrollAsNeededButton");
scrollAsNeededButton.addActionListener(e -> scrollButtonsPolicyChanged());
scrollButtonsPolicyToolBar.add(scrollAsNeededButton);
//---- scrollNeverButton ----
scrollNeverButton.setText("never");
scrollNeverButton.putClientProperty("FlatLaf.styleClass", "small");
scrollNeverButton.setFont(scrollNeverButton.getFont().deriveFont(scrollNeverButton.getFont().getSize() - 2f));
scrollNeverButton.setName("scrollNeverButton");
scrollNeverButton.addActionListener(e -> scrollButtonsPolicyChanged());
scrollButtonsPolicyToolBar.add(scrollNeverButton);
}
@@ -772,79 +915,65 @@ class TabsPanel
//---- scrollButtonsPlacementLabel ----
scrollButtonsPlacementLabel.setText("Scroll buttons placement:");
scrollButtonsPlacementLabel.setName("scrollButtonsPlacementLabel");
panel4.add(scrollButtonsPlacementLabel, "cell 2 0");
//======== scrollButtonsPlacementToolBar ========
{
scrollButtonsPlacementToolBar.setFloatable(false);
scrollButtonsPlacementToolBar.setBorder(BorderFactory.createEmptyBorder());
scrollButtonsPlacementToolBar.setName("scrollButtonsPlacementToolBar");
//---- scrollBothButton ----
scrollBothButton.setText("both");
scrollBothButton.setFont(scrollBothButton.getFont().deriveFont(scrollBothButton.getFont().getSize() - 2f));
scrollBothButton.setSelected(true);
scrollBothButton.putClientProperty("FlatLaf.styleClass", "small");
scrollBothButton.setName("scrollBothButton");
scrollBothButton.addActionListener(e -> scrollButtonsPlacementChanged());
scrollButtonsPlacementToolBar.add(scrollBothButton);
//---- scrollTrailingButton ----
scrollTrailingButton.setText("trailing");
scrollTrailingButton.putClientProperty("FlatLaf.styleClass", "small");
scrollTrailingButton.setFont(scrollTrailingButton.getFont().deriveFont(scrollTrailingButton.getFont().getSize() - 2f));
scrollTrailingButton.setName("scrollTrailingButton");
scrollTrailingButton.addActionListener(e -> scrollButtonsPlacementChanged());
scrollButtonsPlacementToolBar.add(scrollTrailingButton);
}
panel4.add(scrollButtonsPlacementToolBar, "cell 3 0");
//---- showTabSeparatorsCheckBox ----
showTabSeparatorsCheckBox.setText("Show tab separators");
showTabSeparatorsCheckBox.addActionListener(e -> showTabSeparatorsChanged());
panel4.add(showTabSeparatorsCheckBox, "cell 4 0");
//---- tabsPopupPolicyLabel ----
tabsPopupPolicyLabel.setText("Tabs popup policy:");
tabsPopupPolicyLabel.setName("tabsPopupPolicyLabel");
panel4.add(tabsPopupPolicyLabel, "cell 0 1");
//======== tabsPopupPolicyToolBar ========
{
tabsPopupPolicyToolBar.setFloatable(false);
tabsPopupPolicyToolBar.setBorder(BorderFactory.createEmptyBorder());
tabsPopupPolicyToolBar.setName("tabsPopupPolicyToolBar");
//---- popupAsNeededButton ----
popupAsNeededButton.setText("asNeeded");
popupAsNeededButton.setFont(popupAsNeededButton.getFont().deriveFont(popupAsNeededButton.getFont().getSize() - 2f));
popupAsNeededButton.setSelected(true);
popupAsNeededButton.putClientProperty("FlatLaf.styleClass", "small");
popupAsNeededButton.setName("popupAsNeededButton");
popupAsNeededButton.addActionListener(e -> tabsPopupPolicyChanged());
tabsPopupPolicyToolBar.add(popupAsNeededButton);
//---- popupNeverButton ----
popupNeverButton.setText("never");
popupNeverButton.putClientProperty("FlatLaf.styleClass", "small");
popupNeverButton.setFont(popupNeverButton.getFont().deriveFont(popupNeverButton.getFont().getSize() - 2f));
popupNeverButton.setName("popupNeverButton");
popupNeverButton.addActionListener(e -> tabsPopupPolicyChanged());
tabsPopupPolicyToolBar.add(popupNeverButton);
}
panel4.add(tabsPopupPolicyToolBar, "cell 1 1");
//---- tabTypeLabel ----
tabTypeLabel.setText("Tab type:");
panel4.add(tabTypeLabel, "cell 2 1");
//======== tabTypeToolBar ========
{
tabTypeToolBar.setFloatable(false);
//---- underlinedTabTypeButton ----
underlinedTabTypeButton.setText("underlined");
underlinedTabTypeButton.setSelected(true);
underlinedTabTypeButton.putClientProperty("FlatLaf.styleClass", "small");
underlinedTabTypeButton.addActionListener(e -> tabTypeChanged());
tabTypeToolBar.add(underlinedTabTypeButton);
//---- cardTabTypeButton ----
cardTabTypeButton.setText("card");
cardTabTypeButton.putClientProperty("FlatLaf.styleClass", "small");
cardTabTypeButton.addActionListener(e -> tabTypeChanged());
tabTypeToolBar.add(cardTabTypeButton);
}
panel4.add(tabTypeToolBar, "cell 3 1");
//---- showTabSeparatorsCheckBox ----
showTabSeparatorsCheckBox.setText("Show tab separators");
showTabSeparatorsCheckBox.setName("showTabSeparatorsCheckBox");
showTabSeparatorsCheckBox.addActionListener(e -> showTabSeparatorsChanged());
panel4.add(showTabSeparatorsCheckBox, "cell 2 1 2 1");
}
add(panel4, "cell 0 2 3 1");
@@ -881,11 +1010,6 @@ class TabsPanel
ButtonGroup tabsPopupPolicyButtonGroup = new ButtonGroup();
tabsPopupPolicyButtonGroup.add(popupAsNeededButton);
tabsPopupPolicyButtonGroup.add(popupNeverButton);
//---- tabTypeButtonGroup ----
ButtonGroup tabTypeButtonGroup = new ButtonGroup();
tabTypeButtonGroup.add(underlinedTabTypeButton);
tabTypeButtonGroup.add(cardTabTypeButton);
// JFormDesigner - End of component initialization //GEN-END:initComponents
if( FlatLafDemo.screenshotsMode ) {
@@ -965,14 +1089,10 @@ class TabsPanel
private JToolBar scrollButtonsPlacementToolBar;
private JToggleButton scrollBothButton;
private JToggleButton scrollTrailingButton;
private JCheckBox showTabSeparatorsCheckBox;
private JLabel tabsPopupPolicyLabel;
private JToolBar tabsPopupPolicyToolBar;
private JToggleButton popupAsNeededButton;
private JToggleButton popupNeverButton;
private JLabel tabTypeLabel;
private JToolBar tabTypeToolBar;
private JToggleButton underlinedTabTypeButton;
private JToggleButton cardTabTypeButton;
private JCheckBox showTabSeparatorsCheckBox;
// JFormDesigner - End of variables declaration //GEN-END:variables
}

View File

@@ -1,8 +1,9 @@
JFDML JFormDesigner: "7.0.5.0.404" Java: "17" encoding: "UTF-8"
JFDML JFormDesigner: "7.0.2.0.298" Java: "15" encoding: "UTF-8"
new FormModel {
contentType: "form/swing"
root: new FormRoot {
"$setComponentNames": true
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "insets dialog,hidemode 3"
"$columnConstraints": "[grow,fill]para[fill]para[fill]"
@@ -21,7 +22,7 @@ new FormModel {
add( new FormComponent( "javax.swing.JLabel" ) {
name: "tabPlacementLabel"
"text": "Tab placement"
"$client.FlatLaf.styleClass": "h3"
"font": new com.jformdesigner.model.SwingDerivedFont( null, 0, 4, false )
auxiliary() {
"JavaCodeGenerator.variableLocal": true
}
@@ -37,28 +38,28 @@ new FormModel {
"text": "top"
"selected": true
"$buttonGroup": new FormReference( "tabPlacementButtonGroup" )
"$client.FlatLaf.styleClass": "small"
"font": &SwingDerivedFont0 new com.jformdesigner.model.SwingDerivedFont( null, 0, -2, false )
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabPlacementChanged", false ) )
} )
add( new FormComponent( "javax.swing.JToggleButton" ) {
name: "bottomPlacementButton"
"text": "bottom"
"$buttonGroup": new FormReference( "tabPlacementButtonGroup" )
"$client.FlatLaf.styleClass": "small"
"font": #SwingDerivedFont0
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabPlacementChanged", false ) )
} )
add( new FormComponent( "javax.swing.JToggleButton" ) {
name: "leftPlacementButton"
"text": "left"
"$buttonGroup": new FormReference( "tabPlacementButtonGroup" )
"$client.FlatLaf.styleClass": "small"
"font": #SwingDerivedFont0
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabPlacementChanged", false ) )
} )
add( new FormComponent( "javax.swing.JToggleButton" ) {
name: "rightPlacementButton"
"text": "right"
"$buttonGroup": new FormReference( "tabPlacementButtonGroup" )
"$client.FlatLaf.styleClass": "small"
"font": #SwingDerivedFont0
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabPlacementChanged", false ) )
} )
add( new FormComponent( "javax.swing.JToolBar$Separator" ) {
@@ -67,13 +68,13 @@ new FormModel {
add( new FormComponent( "javax.swing.JToggleButton" ) {
name: "scrollButton"
"text": "scroll"
"$client.FlatLaf.styleClass": "small"
"font": new com.jformdesigner.model.SwingDerivedFont( null, 0, -2, false )
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "scrollChanged", false ) )
} )
add( new FormComponent( "javax.swing.JToggleButton" ) {
name: "borderButton"
"text": "border"
"$client.FlatLaf.styleClass": "small"
"font": new com.jformdesigner.model.SwingDerivedFont( null, 0, -2, false )
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "borderChanged", false ) )
} )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
@@ -87,7 +88,7 @@ new FormModel {
add( new FormComponent( "javax.swing.JLabel" ) {
name: "tabLayoutLabel"
"text": "Tab layout"
"$client.FlatLaf.styleClass": "h3"
"font": &SwingDerivedFont1 new com.jformdesigner.model.SwingDerivedFont( null, 0, 4, false )
auxiliary() {
"JavaCodeGenerator.variableLocal": true
}
@@ -102,15 +103,15 @@ new FormModel {
name: "scrollTabLayoutButton"
"text": "scroll"
"$buttonGroup": new FormReference( "tabLayoutButtonGroup" )
"font": &SwingDerivedFont2 new com.jformdesigner.model.SwingDerivedFont( null, 0, -2, false )
"selected": true
"$client.FlatLaf.styleClass": "small"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabLayoutChanged", false ) )
} )
add( new FormComponent( "javax.swing.JToggleButton" ) {
name: "wrapTabLayoutButton"
"text": "wrap"
"$buttonGroup": new FormReference( "tabLayoutButtonGroup" )
"$client.FlatLaf.styleClass": "small"
"font": #SwingDerivedFont2
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabLayoutChanged", false ) )
} )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
@@ -120,7 +121,7 @@ new FormModel {
name: "scrollLayoutNoteLabel"
"text": "(use mouse wheel to scroll; arrow button shows hidden tabs)"
"enabled": false
"$client.FlatLaf.styleClass": "small"
"font": &SwingDerivedFont3 new com.jformdesigner.model.SwingDerivedFont( null, 0, -2, false )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 3"
} )
@@ -128,7 +129,7 @@ new FormModel {
name: "wrapLayoutNoteLabel"
"text": "(probably better to use scroll layout?)"
"enabled": false
"$client.FlatLaf.styleClass": "small"
"font": #SwingDerivedFont3
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 3"
} )
@@ -145,7 +146,7 @@ new FormModel {
add( new FormComponent( "javax.swing.JLabel" ) {
name: "closableTabsLabel"
"text": "Closable tabs"
"$client.FlatLaf.styleClass": "h3"
"font": #SwingDerivedFont1
auxiliary() {
"JavaCodeGenerator.variableLocal": true
}
@@ -159,23 +160,23 @@ new FormModel {
add( new FormComponent( "javax.swing.JToggleButton" ) {
name: "squareCloseButton"
"text": "square"
"font": &SwingDerivedFont4 new com.jformdesigner.model.SwingDerivedFont( null, 0, -2, false )
"$buttonGroup": new FormReference( "closableTabsButtonGroup" )
"selected": true
"$client.FlatLaf.styleClass": "small"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "closeButtonStyleChanged", false ) )
} )
add( new FormComponent( "javax.swing.JToggleButton" ) {
name: "circleCloseButton"
"text": "circle"
"font": #SwingDerivedFont4
"$buttonGroup": new FormReference( "closableTabsButtonGroup" )
"$client.FlatLaf.styleClass": "small"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "closeButtonStyleChanged", false ) )
} )
add( new FormComponent( "javax.swing.JToggleButton" ) {
name: "redCrossCloseButton"
"text": "red cross"
"font": #SwingDerivedFont4
"$buttonGroup": new FormReference( "closableTabsButtonGroup" )
"$client.FlatLaf.styleClass": "small"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "closeButtonStyleChanged", false ) )
} )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
@@ -189,7 +190,7 @@ new FormModel {
add( new FormComponent( "javax.swing.JLabel" ) {
name: "tabAreaComponentsLabel"
"text": "Custom tab area components"
"$client.FlatLaf.styleClass": "h3"
"font": #SwingDerivedFont1
auxiliary() {
"JavaCodeGenerator.variableLocal": true
}
@@ -203,15 +204,15 @@ new FormModel {
add( new FormComponent( "javax.swing.JToggleButton" ) {
name: "leadingComponentButton"
"text": "leading"
"font": &SwingDerivedFont5 new com.jformdesigner.model.SwingDerivedFont( null, 0, -2, false )
"selected": true
"$client.FlatLaf.styleClass": "small"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "customComponentsChanged", false ) )
} )
add( new FormComponent( "javax.swing.JToggleButton" ) {
name: "trailingComponentButton"
"text": "trailing"
"font": #SwingDerivedFont5
"selected": true
"$client.FlatLaf.styleClass": "small"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "customComponentsChanged", false ) )
} )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
@@ -237,7 +238,7 @@ new FormModel {
add( new FormComponent( "javax.swing.JLabel" ) {
name: "tabIconPlacementLabel"
"text": "Tab icon placement"
"$client.FlatLaf.styleClass": "h3"
"font": new com.jformdesigner.model.SwingDerivedFont( null, 0, 4, false )
auxiliary() {
"JavaCodeGenerator.variableLocal": true
}
@@ -248,7 +249,7 @@ new FormModel {
name: "tabIconPlacementNodeLabel"
"text": "(top/bottom/leading/trailing)"
"enabled": false
"$client.FlatLaf.styleClass": "small"
"font": new com.jformdesigner.model.SwingDerivedFont( null, 0, -2, false )
auxiliary() {
"JavaCodeGenerator.variableLocal": true
}
@@ -278,7 +279,7 @@ new FormModel {
add( new FormComponent( "javax.swing.JLabel" ) {
name: "tabAreaAlignmentLabel"
"text": "Tab area alignment"
"$client.FlatLaf.styleClass": "h3"
"font": &SwingDerivedFont6 new com.jformdesigner.model.SwingDerivedFont( null, 0, 4, false )
auxiliary() {
"JavaCodeGenerator.variableLocal": true
}
@@ -289,7 +290,7 @@ new FormModel {
name: "tabAreaAlignmentNoteLabel"
"text": "(leading/center/trailing/fill)"
"enabled": false
"$client.FlatLaf.styleClass": "small"
"font": &SwingDerivedFont7 new com.jformdesigner.model.SwingDerivedFont( null, 0, -2, false )
auxiliary() {
"JavaCodeGenerator.variableLocal": true
}
@@ -331,7 +332,7 @@ new FormModel {
add( new FormComponent( "javax.swing.JLabel" ) {
name: "tabWidthModeLabel"
"text": "Tab width mode"
"$client.FlatLaf.styleClass": "h3"
"font": #SwingDerivedFont6
auxiliary() {
"JavaCodeGenerator.variableLocal": true
}
@@ -341,8 +342,8 @@ new FormModel {
add( new FormComponent( "javax.swing.JLabel" ) {
name: "tabWidthModeNoteLabel"
"text": "(preferred/equal/compact)"
"font": new com.jformdesigner.model.SwingDerivedFont( null, 0, -2, false )
"enabled": false
"$client.FlatLaf.styleClass": "small"
auxiliary() {
"JavaCodeGenerator.variableLocal": true
}
@@ -367,7 +368,7 @@ new FormModel {
add( new FormComponent( "javax.swing.JLabel" ) {
name: "minMaxTabWidthLabel"
"text": "Minimum/maximum tab width"
"$client.FlatLaf.styleClass": "h3"
"font": new com.jformdesigner.model.SwingDerivedFont( null, 0, 4, false )
auxiliary() {
"JavaCodeGenerator.variableLocal": true
}
@@ -387,7 +388,7 @@ new FormModel {
add( new FormComponent( "javax.swing.JLabel" ) {
name: "tabAlignmentLabel"
"text": "Tab title alignment"
"$client.FlatLaf.styleClass": "h3"
"font": #SwingDerivedFont6
auxiliary() {
"JavaCodeGenerator.variableLocal": true
}
@@ -404,7 +405,7 @@ new FormModel {
name: "tabAlignmentNoteLabel"
"text": "(leading/center/trailing)"
"enabled": false
"$client.FlatLaf.styleClass": "small"
"font": #SwingDerivedFont7
auxiliary() {
"JavaCodeGenerator.variableLocal": true
}
@@ -415,7 +416,7 @@ new FormModel {
name: "tabAlignmentNoteLabel2"
"text": "(trailing)"
"enabled": false
"$client.FlatLaf.styleClass": "small"
"font": #SwingDerivedFont7
auxiliary() {
"JavaCodeGenerator.variableLocal": true
}
@@ -456,7 +457,7 @@ new FormModel {
} )
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "insets 0,hidemode 3"
"$columnConstraints": "[][fill]para[fill][fill]para[fill]"
"$columnConstraints": "[][fill]para[fill][fill]para"
"$rowConstraints": "[][center]"
} ) {
name: "panel4"
@@ -476,23 +477,23 @@ new FormModel {
add( new FormComponent( "javax.swing.JToggleButton" ) {
name: "scrollAsNeededSingleButton"
"text": "asNeededSingle"
"font": #SwingDerivedFont2
"selected": true
"$buttonGroup": new FormReference( "scrollButtonsPolicyButtonGroup" )
"$client.FlatLaf.styleClass": "small"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "scrollButtonsPolicyChanged", false ) )
} )
add( new FormComponent( "javax.swing.JToggleButton" ) {
name: "scrollAsNeededButton"
"text": "asNeeded"
"font": #SwingDerivedFont2
"$buttonGroup": new FormReference( "scrollButtonsPolicyButtonGroup" )
"$client.FlatLaf.styleClass": "small"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "scrollButtonsPolicyChanged", false ) )
} )
add( new FormComponent( "javax.swing.JToggleButton" ) {
name: "scrollNeverButton"
"text": "never"
"font": #SwingDerivedFont2
"$buttonGroup": new FormReference( "scrollButtonsPolicyButtonGroup" )
"$client.FlatLaf.styleClass": "small"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "scrollButtonsPolicyChanged", false ) )
} )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
@@ -511,31 +512,21 @@ new FormModel {
add( new FormComponent( "javax.swing.JToggleButton" ) {
name: "scrollBothButton"
"text": "both"
"font": #SwingDerivedFont2
"selected": true
"$buttonGroup": new FormReference( "scrollButtonsPlacementButtonGroup" )
"$client.FlatLaf.styleClass": "small"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "scrollButtonsPlacementChanged", false ) )
} )
add( new FormComponent( "javax.swing.JToggleButton" ) {
name: "scrollTrailingButton"
"text": "trailing"
"font": #SwingDerivedFont2
"$buttonGroup": new FormReference( "scrollButtonsPlacementButtonGroup" )
"$client.FlatLaf.styleClass": "small"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "scrollButtonsPlacementChanged", false ) )
} )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 3 0"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "showTabSeparatorsCheckBox"
"text": "Show tab separators"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "showTabSeparatorsChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 4 0"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "tabsPopupPolicyLabel"
"text": "Tabs popup policy:"
@@ -549,54 +540,37 @@ new FormModel {
add( new FormComponent( "javax.swing.JToggleButton" ) {
name: "popupAsNeededButton"
"text": "asNeeded"
"font": #SwingDerivedFont2
"selected": true
"$buttonGroup": new FormReference( "tabsPopupPolicyButtonGroup" )
"$client.FlatLaf.styleClass": "small"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabsPopupPolicyChanged", false ) )
} )
add( new FormComponent( "javax.swing.JToggleButton" ) {
name: "popupNeverButton"
"text": "never"
"font": #SwingDerivedFont2
"$buttonGroup": new FormReference( "tabsPopupPolicyButtonGroup" )
"$client.FlatLaf.styleClass": "small"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabsPopupPolicyChanged", false ) )
} )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 1"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "tabTypeLabel"
"text": "Tab type:"
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "showTabSeparatorsCheckBox"
"text": "Show tab separators"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "showTabSeparatorsChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 1"
} )
add( new FormContainer( "javax.swing.JToolBar", new FormLayoutManager( class javax.swing.JToolBar ) ) {
name: "tabTypeToolBar"
"floatable": false
add( new FormComponent( "javax.swing.JToggleButton" ) {
name: "underlinedTabTypeButton"
"text": "underlined"
"selected": true
"$buttonGroup": new FormReference( "tabTypeButtonGroup" )
"$client.FlatLaf.styleClass": "small"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabTypeChanged", false ) )
} )
add( new FormComponent( "javax.swing.JToggleButton" ) {
name: "cardTabTypeButton"
"text": "card"
"$buttonGroup": new FormReference( "tabTypeButtonGroup" )
"$client.FlatLaf.styleClass": "small"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabTypeChanged", false ) )
} )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 3 1"
"value": "cell 2 1 2 1"
} )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 2 3 1"
} )
}, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 0, 0 )
"size": new java.awt.Dimension( 1145, 895 )
"size": new java.awt.Dimension( 1075, 895 )
} )
add( new FormNonVisual( "javax.swing.ButtonGroup" ) {
name: "tabPlacementButtonGroup"
@@ -628,10 +602,5 @@ new FormModel {
}, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 200, 1020 )
} )
add( new FormNonVisual( "javax.swing.ButtonGroup" ) {
name: "tabTypeButtonGroup"
}, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 0, 1072 )
} )
}
}

View File

@@ -144,13 +144,13 @@ public class IJThemesPanel
// add core themes at beginning
categories.put( themes.size(), "Core Themes" );
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 )
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 )
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 )
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
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

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