Compare commits

...

42 Commits
1.3 ... 1.5

Author SHA1 Message Date
Karl Tauber
6fcee03752 release 1.5 2021-08-04 15:13:58 +02:00
Karl Tauber
5782ceeb5d README.md: added descriptions to addons 2021-08-04 14:27:57 +02:00
Karl Tauber
f752db5892 FileChooser: fixed missing (localized) texts when FlatLaf is loaded in special classloader
(e.g. plugin system in Apache NetBeans)

https://issues.apache.org/jira/browse/NETBEANS-5865
2021-08-04 11:15:18 +02:00
Karl Tauber
bce58bc97b SwingX: added search and clear icons to JXSearchField (issue #359) 2021-08-03 17:52:49 +02:00
Karl Tauber
d373687bc4 Testing: added FlatSingleComponentTest to easier test/debug single components 2021-08-03 15:16:04 +02:00
Karl Tauber
e5e510c825 Demo: fixed inconsistent behavior when first changing font size and then font family, which did loose user scale factor on Windows in Java 9+ (issue #352) 2021-08-02 19:16:38 +02:00
Karl Tauber
29064ec72f Button and TextComponent: do not apply minimum width/height if margins are set (issue #364) 2021-08-02 18:36:10 +02:00
Karl Tauber
953eee1dc8 TableHeader: made getRolloverColumn() public to allow usage in custom renderers (issue #336) 2021-08-02 18:01:08 +02:00
Karl Tauber
75f76f4875 ComboBox and Spinner: limit arrow button width if component has large preferred height (issue #361) 2021-08-02 15:27:25 +02:00
Karl Tauber
ecfbe68c33 Native window decorations: updated DLLs (issues #357 and #339)
built by GitHub Actions:
https://github.com/JFormDesigner/FlatLaf/actions/runs/1085691279
2021-07-31 21:22:09 +02:00
Karl Tauber
7f02eb9cf0 Native window decorations: when window is initially shown, fill background with window background color (instead of white), which avoids flickering in dark themes (issue #339) 2021-07-31 21:05:01 +02:00
Karl Tauber
4ab90065dc Native window decorations: when resizing a window to the right or to the bottom, then first fill the new space with the window background color (instead of black) before the layout is updated (issue #339) 2021-07-31 18:02:10 +02:00
Karl Tauber
d3e39a1359 Native window decorations: fixed occasional application crash on Windows 10 in flatlaf-windows.dll (issue #357) 2021-07-30 23:06:09 +02:00
Karl Tauber
60e5861de4 InternalFrame: limit internal frame bounds to parent bounds on resize; honor maximum size of internal frame (issue #362) 2021-07-29 16:44:50 +02:00
Karl Tauber
ca7f5045ae Popup: fixed incorrectly placed drop shadow for medium-weight popups in maximized windows (issue #358) 2021-07-29 15:39:16 +02:00
Karl Tauber
b0997fb5d2 release 1.4 2021-07-13 11:02:10 +02:00
Karl Tauber
37dab9fb22 TabbedPane: fixed rendering of tab separators in scroll layout if scaled on HiDPI screens 2021-07-12 11:48:34 +02:00
Karl Tauber
fb44c8fbe4 TextField: fixed location of placeholder text if paddings are used (e.g. in ComboBox) (for commit a9dcf09d13) 2021-07-10 21:05:26 +02:00
Karl Tauber
94375b7d36 Extras: added support for client property JTextField.padding (for commit a9dcf09d13) 2021-07-10 20:59:34 +02:00
Karl Tauber
8b585deb78 ToolBar: support focusable buttons in toolbar (issue #346)
fixed focusable state when switching to/from other Laf
2021-07-10 13:32:30 +02:00
Karl Tauber
4d8b544aed UIDefaultsKeysDump: also use FlatTestLaf, which adds missing keys to FlatLafUIKeys.txt 2021-07-10 13:28:02 +02:00
Karl Tauber
548d651d29 PasswordField: move the lower bar of the caps lock icon up a half pixel 2021-07-10 11:03:13 +02:00
Karl Tauber
0b342acec9 PasswordField: paint caps lock icon on left side in right-to-left component orientation 2021-07-09 15:14:29 +02:00
Karl Tauber
cc6d3c1b1a PasswordField: Caps lock icon no longer painted over long text (issue #172) 2021-07-09 15:03:16 +02:00
Karl Tauber
74a748d92e use LoggingFacade instead of printStackTrace() in flatlaf-extras and flatlaf-demo 2021-07-09 13:22:37 +02:00
Karl Tauber
1de81d0af5 ComboBox: fixed StackOverflowError when using single renderer instance in multiple comboboxes (regression since commit 4507ce359d) 2021-07-09 11:39:35 +02:00
Karl Tauber
ff9ef21f67 OptionPane: align wrapped lines to the right if component orientation is right-to-left (issue #350) 2021-07-08 17:53:44 +02:00
Karl Tauber
266a546478 Window decorations: window title bar width is no longer considered when calculating preferred/minimum width of window (issue #351) 2021-07-08 16:54:34 +02:00
Karl Tauber
87407ca832 Table and PopupFactory: use StackWalker in Java 9+ for better performance (issue #334) 2021-07-08 14:02:50 +02:00
Karl Tauber
90282d4436 UI defaults dumps updated for issue #335 2021-07-08 00:02:33 +02:00
Karl Tauber
abbe6d6c1f ToolBar: paint focus indicator for focused button in toolbar (issue #346) 2021-07-07 18:17:45 +02:00
Karl Tauber
a28f701e6f OptionPane: do not make child components, which are derived from JPanel, non-opaque (issue #349) 2021-07-07 10:57:54 +02:00
Karl Tauber
4cdc995a7f ComboBox: simplified code in configureEditor() 2021-07-05 23:14:05 +02:00
Karl Tauber
c708205593 TestFlatComponentSizes: shortened combobox text because unit tests on GitHub Actions use font size 15 2021-07-05 20:06:07 +02:00
Karl Tauber
a22c6c8013 ComboBox (not editable):
- increased size of internal renderer pane to the component border so that it can paint within the whole component
- increase combo box size if a custom renderer uses a border with insets that are larger than the default combo box padding (`2,6,2,6`)
2021-07-05 18:41:17 +02:00
Karl Tauber
b576f473e5 fixed component heights at 1.25x, 1.75x and 2.25x scaling factors (Java 8 only) so that Button, ComboBox, Spinner and TextField components (including subclasses) have same heights 2021-07-05 15:15:37 +02:00
Karl Tauber
0b127caa83 ComboBox: fixed minimum width if focusWidth > 0 (to be equal with button minimum width)
added some unit tests to compare component sizes
2021-07-05 11:07:32 +02:00
Karl Tauber
4507ce359d ComboBox: reworked uninstall of CellPaddingBorder, which is temporary used for cell renderers, to make it easier to understand and reliable
(tested using FlatCustomBordersTest, FlatNetBeansTest, etc)
2021-07-03 10:43:55 +02:00
Karl Tauber
3e14f28dc2 ComboBox (editable) and Spinner: increased size of internal text field to the component border so that it behaves like plain text field (issue #330) 2021-07-02 18:43:37 +02:00
Karl Tauber
a9dcf09d13 TextField: support adding extra padding
(for #172, #173 and #330)
2021-07-02 15:38:45 +02:00
Karl Tauber
c8998c2bcf PasswordField: UI delegate FlatPasswordFieldUI now extends FlatTextFieldUI (instead of BasicPasswordFieldUI) to avoid duplicate code and for easier extensibility (e.g. for #173 and #341) 2021-07-02 14:03:54 +02:00
Karl Tauber
10bf1295bc CHANGELOG.md: fixed UI key ComboBox.popupFocusedBackground to ComboBox.popupBackground 2021-07-02 10:52:30 +02:00
88 changed files with 3368 additions and 378 deletions

View File

@@ -1,6 +1,80 @@
FlatLaf Change Log FlatLaf Change Log
================== ==================
## 1.5
#### New features and improvements
- SwingX: Added search and clear icons to `JXSearchField`. (issue #359)
#### Fixed bugs
- Button and TextComponent: Do not apply minimum width/height if margins are
set. (issue #364)
- ComboBox and Spinner: Limit arrow button width if component has large
preferred height. (issue #361)
- FileChooser: Fixed missing (localized) texts when FlatLaf is loaded in special
classloader (e.g. plugin system in Apache NetBeans).
- InternalFrame: Limit internal frame bounds to parent bounds on resize. Also
honor maximum size of internal frame. (issue #362)
- Popup: Fixed incorrectly placed drop shadow for medium-weight popups in
maximized windows. (issue #358)
- Native window decorations (Windows 10 only):
- Fixed occasional application crash in `flatlaf-windows.dll`. (issue #357)
- When window is initially shown, fill background with window background color
(instead of white), which avoids flickering in dark themes. (issue 339)
- When resizing a window at the right/bottom edge, then first fill the new
space with the window background color (instead of black) before the layout
is updated.
- When resizing a window at the left/top edge, then first fill the new space
with the window background color (instead of garbage) before the layout is
updated.
## 1.4
#### New features and improvements
- TextField, FormattedTextField and PasswordField: Support adding extra padding.
(set client property `JTextField.padding` to `Insets`).
- PasswordField: UI delegate `FlatPasswordFieldUI` now extends `FlatTextFieldUI`
(instead of `BasicPasswordFieldUI`) to avoid duplicate code and for easier
extensibility.
- Table and PopupFactory: Use `StackWalker` in Java 9+ for better performance.
(issue #334)
- ToolBar: Paint focus indicator for focused button in toolbar. (issue #346)
- ToolBar: Support focusable buttons in toolbar (set UI value
`ToolBar.focusableButtons` to `true`). (issue #346)
#### Fixed bugs
- ComboBox (editable) and Spinner: Increased size of internal text field to the
component border so that it behaves like plain text field (mouse click to left
of text now positions caret to first character instead of opening ComboBox
popup; mouse cursor is now of type "text" within the whole component, except
for arrow buttons). (issue #330)
- ComboBox (not editable): Increased size of internal renderer pane to the
component border so that it can paint within the whole component. Also
increase combo box size if a custom renderer uses a border with insets that
are larger than the default combo box padding (`2,6,2,6`).
- Fixed component heights at `1.25x`, `1.75x` and `2.25x` scaling factors (Java
8 only) so that Button, ComboBox, Spinner and TextField components (including
subclasses) have same heights. This increases heights of Button and TextField
components by:
- `2px` at `1.75x` in **Light** and **Dark** themes
- `2px` at `1.25x` and `2.25x` in **IntelliJ** and **Darcula** themes
- OptionPane: Do not make child components, which are derived from `JPanel`,
non-opaque. (issue #349)
- OptionPane: Align wrapped lines to the right if component orientation is
right-to-left. (issue #350)
- PasswordField: Caps lock icon no longer painted over long text. (issue #172)
- PasswordField: Paint caps lock icon on left side in right-to-left component
orientation.
- Window decorations: Window title bar width is no longer considered when
calculating preferred/minimum width of window. (issue #351)
## 1.3 ## 1.3
#### New features and improvements #### New features and improvements
@@ -10,7 +84,7 @@ FlatLaf Change Log
`PasswordField.focusedBackground`, `FormattedTextField.focusedBackground`, `PasswordField.focusedBackground`, `FormattedTextField.focusedBackground`,
`TextArea.focusedBackground`, `TextPane.focusedBackground`, `TextArea.focusedBackground`, `TextPane.focusedBackground`,
`EditorPane.focusedBackground`, `ComboBox.focusedBackground`, `EditorPane.focusedBackground`, `ComboBox.focusedBackground`,
`ComboBox.buttonFocusedBackground`, `ComboBox.popupFocusedBackground` and `ComboBox.buttonFocusedBackground`, `ComboBox.popupBackground` and
`Spinner.focusedBackground`). (issue #335) `Spinner.focusedBackground`). (issue #335)
#### Fixed bugs #### Fixed bugs

View File

@@ -67,10 +67,13 @@ docs).
Addons Addons
------ ------
- [IntelliJ Themes Pack](flatlaf-intellij-themes) - [IntelliJ Themes Pack](flatlaf-intellij-themes) - bundles many popular
- [Extras](flatlaf-extras) open-source 3rd party themes
- [SwingX](flatlaf-swingx) - [Extras](flatlaf-extras) - SVG icon, tri-state check box, UI inspectors, and
- [JIDE Common Layer](flatlaf-jide-oss) more
- [SwingX](flatlaf-swingx) - support for SwingX components
- [JIDE Common Layer](flatlaf-jide-oss) - support for JIDE Common Layer
components
Getting started Getting started

View File

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

View File

@@ -21,6 +21,12 @@ plugins {
`flatlaf-publish` `flatlaf-publish`
} }
dependencies {
testImplementation( "org.junit.jupiter:junit-jupiter-api:5.7.2" )
testImplementation( "org.junit.jupiter:junit-jupiter-params" )
testRuntimeOnly( "org.junit.jupiter:junit-jupiter-engine" )
}
java { java {
withSourcesJar() withSourcesJar()
withJavadocJar() withJavadocJar()
@@ -52,6 +58,11 @@ tasks {
named<Jar>( "javadocJar" ) { named<Jar>( "javadocJar" ) {
archiveBaseName.set( "flatlaf" ) archiveBaseName.set( "flatlaf" )
} }
test {
useJUnitPlatform()
testLogging.exceptionFormat = org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL
}
} }
flatlafPublish { flatlafPublish {

View File

@@ -733,6 +733,18 @@ public interface FlatClientProperties
*/ */
String PLACEHOLDER_TEXT = "JTextField.placeholderText"; String PLACEHOLDER_TEXT = "JTextField.placeholderText";
/**
* Specifies the padding of the text.
* This changes the location and size of the text view within the component bounds,
* but does not affect the size of the component.
* <p>
* <strong>Component</strong> {@link javax.swing.JTextField} (and subclasses)<br>
* <strong>Value type</strong> {@link java.awt.Insets}
*
* @since 1.4
*/
String TEXT_FIELD_PADDING = "JTextField.padding";
//---- JToggleButton ------------------------------------------------------ //---- JToggleButton ------------------------------------------------------
/** /**

View File

@@ -32,10 +32,13 @@ import java.beans.PropertyChangeListener;
import java.io.File; import java.io.File;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.MissingResourceException;
import java.util.Properties; import java.util.Properties;
import java.util.ResourceBundle;
import java.util.ServiceLoader; import java.util.ServiceLoader;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.Function; import java.util.function.Function;
@@ -66,6 +69,7 @@ import com.formdev.flatlaf.ui.FlatRootPaneUI;
import com.formdev.flatlaf.util.GrayFilter; import com.formdev.flatlaf.util.GrayFilter;
import com.formdev.flatlaf.util.LoggingFacade; import com.formdev.flatlaf.util.LoggingFacade;
import com.formdev.flatlaf.util.MultiResolutionImageSupport; import com.formdev.flatlaf.util.MultiResolutionImageSupport;
import com.formdev.flatlaf.util.StringUtils;
import com.formdev.flatlaf.util.SystemInfo; import com.formdev.flatlaf.util.SystemInfo;
import com.formdev.flatlaf.util.UIScale; import com.formdev.flatlaf.util.UIScale;
@@ -356,8 +360,8 @@ public abstract class FlatLaf
// (can be queried without using FlatLaf API) // (can be queried without using FlatLaf API)
defaults.put( "laf.dark", isDark() ); defaults.put( "laf.dark", isDark() );
// add resource bundle for localized texts // init resource bundle for localized texts
defaults.addResourceBundle( "com.formdev.flatlaf.resources.Bundle" ); initResourceBundle( defaults, "com.formdev.flatlaf.resources.Bundle" );
// initialize some defaults (for overriding) that are used in UI delegates, // initialize some defaults (for overriding) that are used in UI delegates,
// but are not set in BasicLookAndFeel // but are not set in BasicLookAndFeel
@@ -453,6 +457,45 @@ public abstract class FlatLaf
return null; return null;
} }
private void initResourceBundle( UIDefaults defaults, String bundleName ) {
// add resource bundle for localized texts
defaults.addResourceBundle( bundleName );
// Check whether Swing can not load the FlatLaf resource bundle,
// which can happen in applications that use some plugin system
// and load FlatLaf in a plugin that uses its own classloader.
// (e.g. Apache NetBeans)
if( defaults.get( "FileChooser.fileNameHeaderText" ) != null )
return;
// load FlatLaf resource bundle and add content to defaults
try {
ResourceBundle bundle = ResourceBundle.getBundle( bundleName, defaults.getDefaultLocale() );
Enumeration<String> keys = bundle.getKeys();
while( keys.hasMoreElements() ) {
String key = keys.nextElement();
String value = bundle.getString( key );
String baseKey = StringUtils.removeTrailing( key, ".textAndMnemonic" );
if( baseKey != key ) {
String text = value.replace( "&", "" );
String mnemonic = null;
int index = value.indexOf( '&' );
if( index >= 0 )
mnemonic = Integer.toString( Character.toUpperCase( value.charAt( index + 1 ) ) );
defaults.put( baseKey + "Text", text );
if( mnemonic != null )
defaults.put( baseKey + "Mnemonic", mnemonic );
} else
defaults.put( key, value );
}
} catch( MissingResourceException ex ) {
LoggingFacade.INSTANCE.logSevere( null, ex );
}
}
private void initFonts( UIDefaults defaults ) { private void initFonts( UIDefaults defaults ) {
FontUIResource uiFont = null; FontUIResource uiFont = null;

View File

@@ -309,6 +309,9 @@ class LinuxFontPolicy
* - running on JetBrains Runtime 11 or later and scaling is enabled in system Settings * - running on JetBrains Runtime 11 or later and scaling is enabled in system Settings
*/ */
private static boolean isSystemScaling() { private static boolean isSystemScaling() {
if( GraphicsEnvironment.isHeadless() )
return true;
GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment() GraphicsConfiguration gc = GraphicsEnvironment.getLocalGraphicsEnvironment()
.getDefaultScreenDevice().getDefaultConfiguration(); .getDefaultScreenDevice().getDefaultConfiguration();
return UIScale.getSystemScaleFactor( gc ) > 1; return UIScale.getSystemScaleFactor( gc ) > 1;

View File

@@ -44,7 +44,7 @@ public class FlatCapsLockIcon
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<g fill="none" fill-rule="evenodd"> <g fill="none" fill-rule="evenodd">
<rect width="16" height="16" fill="#6E6E6E" rx="3"/> <rect width="16" height="16" fill="#6E6E6E" rx="3"/>
<rect width="6" height="2" x="5" y="12" fill="#FFF"/> <rect width="6" height="2" x="5" y="11.5" fill="#FFF"/>
<path fill="#FFF" d="M2,8 L8,2 L14,8 L11,8 L11,10 L5,10 L5,8 L2,8 Z"/> <path fill="#FFF" d="M2,8 L8,2 L14,8 L11,8 L11,10 L5,10 L5,8 L2,8 Z"/>
</g> </g>
</svg> </svg>
@@ -52,7 +52,7 @@ public class FlatCapsLockIcon
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD ); Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD );
path.append( new RoundRectangle2D.Float( 0, 0, 16, 16, 6, 6 ), false ); path.append( new RoundRectangle2D.Float( 0, 0, 16, 16, 6, 6 ), false );
path.append( new Rectangle2D.Float( 5, 12, 6, 2 ), false ); path.append( new Rectangle2D.Float( 5, 11.5f, 6, 2 ), false );
path.append( FlatUIUtils.createPath( 2,8, 8,2, 14,8, 11,8, 11,10, 5,10, 5,8 ), false ); path.append( FlatUIUtils.createPath( 2,8, 8,2, 14,8, 11,8, 11,10, 5,10, 5,8 ), false );
g.fill( path ); g.fill( path );
} }

View File

@@ -0,0 +1,85 @@
/*
* 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.Color;
import java.awt.Component;
import java.awt.Graphics2D;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.geom.Path2D;
import javax.swing.AbstractButton;
import javax.swing.ButtonModel;
import javax.swing.UIManager;
import com.formdev.flatlaf.ui.FlatUIUtils;
/**
* "clear" icon for search fields.
*
* @uiDefault SearchField.clearIconColor Color
* @uiDefault SearchField.clearIconHoverColor Color
* @uiDefault SearchField.clearIconPressedColor Color
*
* @author Karl Tauber
* @since 1.5
*/
public class FlatClearIcon
extends FlatAbstractIcon
{
protected Color clearIconColor = UIManager.getColor( "SearchField.clearIconColor" );
protected Color clearIconHoverColor = UIManager.getColor( "SearchField.clearIconHoverColor" );
protected Color clearIconPressedColor = UIManager.getColor( "SearchField.clearIconPressedColor" );
public FlatClearIcon() {
super( 16, 16, null );
}
@Override
protected void paintIcon( Component c, Graphics2D g ) {
if( c instanceof AbstractButton ) {
ButtonModel model = ((AbstractButton)c).getModel();
if( model.isPressed() || model.isRollover() ) {
/*
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<path fill="#7F8B91" fill-opacity=".5" fill-rule="evenodd" d="M8,1.75 C11.4517797,1.75 14.25,4.54822031 14.25,8 C14.25,11.4517797 11.4517797,14.25 8,14.25 C4.54822031,14.25 1.75,11.4517797 1.75,8 C1.75,4.54822031 4.54822031,1.75 8,1.75 Z M10.5,4.5 L8,7 L5.5,4.5 L4.5,5.5 L7,8 L4.5,10.5 L5.5,11.5 L8,9 L10.5,11.5 L11.5,10.5 L9,8 L11.5,5.5 L10.5,4.5 Z"/>
</svg>
*/
// paint filled circle with cross
g.setColor( model.isPressed() ? clearIconPressedColor : clearIconHoverColor );
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD );
path.append( new Ellipse2D.Float( 1.75f, 1.75f, 12.5f, 12.5f ), false );
path.append( FlatUIUtils.createPath( 4.5,5.5, 5.5,4.5, 8,7, 10.5,4.5, 11.5,5.5, 9,8, 11.5,10.5, 10.5,11.5, 8,9, 5.5,11.5, 4.5,10.5, 7,8 ), false );
g.fill( path );
return;
}
}
/*
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<path fill="none" stroke="#7F8B91" stroke-linecap="square" stroke-opacity=".5" d="M5,5 L11,11 M5,11 L11,5"/>
</svg>
*/
// paint cross
g.setColor( clearIconColor );
Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD );
path.append( new Line2D.Float( 5,5, 11,11 ), false );
path.append( new Line2D.Float( 5,11, 11,5 ), false );
g.draw( path );
}
}

View File

@@ -0,0 +1,69 @@
/*
* 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.Color;
import java.awt.Component;
import java.awt.Graphics2D;
import java.awt.geom.Area;
import java.awt.geom.Ellipse2D;
import javax.swing.UIManager;
import com.formdev.flatlaf.ui.FlatButtonUI;
import com.formdev.flatlaf.ui.FlatUIUtils;
/**
* "search" icon for search fields.
*
* @uiDefault SearchField.searchIconColor Color
* @uiDefault SearchField.searchIconHoverColor Color
* @uiDefault SearchField.searchIconPressedColor Color
*
* @author Karl Tauber
* @since 1.5
*/
public class FlatSearchIcon
extends FlatAbstractIcon
{
protected Color searchIconColor = UIManager.getColor( "SearchField.searchIconColor" );
protected Color searchIconHoverColor = UIManager.getColor( "SearchField.searchIconHoverColor" );
protected Color searchIconPressedColor = UIManager.getColor( "SearchField.searchIconPressedColor" );
public FlatSearchIcon() {
super( 16, 16, null );
}
@Override
protected void paintIcon( Component c, Graphics2D g ) {
/*
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<g fill="none" fill-opacity=".9" fill-rule="evenodd">
<polygon fill="#7F8B91" points="10.813 9.75 14 12.938 12.938 14 9.75 10.813"/>
<path fill="#7F8B91" d="M7,2 C9.76142375,2 12,4.23857625 12,7 C12,9.76142375 9.76142375,12 7,12 C4.23857625,12 2,9.76142375 2,7 C2,4.23857625 4.23857625,2 7,2 Z M7,3 C4.790861,3 3,4.790861 3,7 C3,9.209139 4.790861,11 7,11 C9.209139,11 11,9.209139 11,7 C11,4.790861 9.209139,3 7,3 Z"/>
</g>
</svg>
*/
g.setColor( FlatButtonUI.buttonStateColor( c, searchIconColor, searchIconColor,
null, searchIconHoverColor, searchIconPressedColor ) );
// paint magnifier
Area area = new Area( new Ellipse2D.Float( 2, 2, 10, 10 ) );
area.subtract( new Area( new Ellipse2D.Float( 3, 3, 8, 8 ) ) );
area.add( new Area( FlatUIUtils.createPath( 10.813,9.75, 14,12.938, 12.938,14, 9.75,10.813 ) ) );
g.fill( area );
}
}

View File

@@ -0,0 +1,55 @@
/*
* 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 com.formdev.flatlaf.ui.FlatUIUtils;
/**
* "search with history" icon for search fields.
*
* @author Karl Tauber
* @since 1.5
*/
public class FlatSearchWithHistoryIcon
extends FlatSearchIcon
{
public FlatSearchWithHistoryIcon() {
}
@Override
protected void paintIcon( Component c, Graphics2D g ) {
/*
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<g fill="none" fill-opacity=".9" fill-rule="evenodd">
<polygon fill="#7F8B91" points="8.813 9.75 12 12.938 10.938 14 7.75 10.813"/>
<path fill="#7F8B91" d="M5,2 C7.76142375,2 10,4.23857625 10,7 C10,9.76142375 7.76142375,12 5,12 C2.23857625,12 0,9.76142375 0,7 C0,4.23857625 2.23857625,2 5,2 Z M5,3 C2.790861,3 1,4.790861 1,7 C1,9.209139 2.790861,11 5,11 C7.209139,11 9,9.209139 9,7 C9,4.790861 7.209139,3 5,3 Z"/>
<polygon fill="#7F8B91" points="11 7 16 7 13.5 10"/>
</g>
</svg>
*/
// paint magnifier
g.translate( -2, 0 );
super.paintIcon( c, g );
g.translate( 2, 0 );
// paint history arrow
g.fill( FlatUIUtils.createPath( 11,7, 16,7, 13.5,10 ) );
}
}

View File

@@ -176,13 +176,14 @@ public class FlatBorder
@Override @Override
public Insets getBorderInsets( Component c, Insets insets ) { public Insets getBorderInsets( Component c, Insets insets ) {
float focusWidth = scale( (float) getFocusWidth( c ) ); float focusWidth = scale( (float) getFocusWidth( c ) );
float ow = focusWidth + scale( (float) getLineWidth( c ) ); int ow = Math.round( focusWidth + scale( (float) getLineWidth( c ) ) );
insets = super.getBorderInsets( c, insets ); insets = super.getBorderInsets( c, insets );
insets.top = Math.round( scale( (float) insets.top ) + ow );
insets.left = Math.round( scale( (float) insets.left ) + ow ); insets.top = scale( insets.top ) + ow;
insets.bottom = Math.round( scale( (float) insets.bottom ) + ow ); insets.left = scale( insets.left ) + ow;
insets.right = Math.round( scale( (float) insets.right ) + ow ); insets.bottom = scale( insets.bottom ) + ow;
insets.right = scale( insets.right ) + ow;
if( isCellEditor( c ) ) { if( isCellEditor( c ) ) {
// remove top and bottom insets if used as cell editor // remove top and bottom insets if used as cell editor

View File

@@ -20,6 +20,7 @@ import java.awt.Color;
import java.awt.Component; import java.awt.Component;
import java.awt.GradientPaint; import java.awt.GradientPaint;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets; import java.awt.Insets;
import java.awt.Paint; import java.awt.Paint;
import javax.swing.AbstractButton; import javax.swing.AbstractButton;
@@ -42,11 +43,13 @@ import com.formdev.flatlaf.util.UIScale;
* @uiDefault Button.default.hoverBorderColor Color optional * @uiDefault Button.default.hoverBorderColor Color optional
* @uiDefault Button.default.focusedBorderColor Color * @uiDefault Button.default.focusedBorderColor Color
* @uiDefault Button.default.focusColor Color * @uiDefault Button.default.focusColor Color
* @uiDefault Button.toolbar.focusColor Color optional; defaults to Component.focusColor
* @uiDefault Button.borderWidth int * @uiDefault Button.borderWidth int
* @uiDefault Button.default.borderWidth int * @uiDefault Button.default.borderWidth int
* @uiDefault Button.innerFocusWidth int or float optional; defaults to Component.innerFocusWidth * @uiDefault Button.innerFocusWidth int or float optional; defaults to Component.innerFocusWidth
* @uiDefault Button.toolbar.margin Insets * @uiDefault Button.toolbar.margin Insets
* @uiDefault Button.toolbar.spacingInsets Insets * @uiDefault Button.toolbar.spacingInsets Insets
* @uiDefault Button.toolbar.focusWidth int or float optional; default is 1
* @uiDefault Button.arc int * @uiDefault Button.arc int
* *
* @author Karl Tauber * @author Karl Tauber
@@ -64,11 +67,15 @@ public class FlatButtonBorder
protected final Color defaultHoverBorderColor = UIManager.getColor( "Button.default.hoverBorderColor" ); protected final Color defaultHoverBorderColor = UIManager.getColor( "Button.default.hoverBorderColor" );
protected final Color defaultFocusedBorderColor = UIManager.getColor( "Button.default.focusedBorderColor" ); protected final Color defaultFocusedBorderColor = UIManager.getColor( "Button.default.focusedBorderColor" );
protected final Color defaultFocusColor = UIManager.getColor( "Button.default.focusColor" ); protected final Color defaultFocusColor = UIManager.getColor( "Button.default.focusColor" );
/** @since 1.4 */
protected final Color toolbarFocusColor = UIManager.getColor( "Button.toolbar.focusColor" );
protected final int borderWidth = UIManager.getInt( "Button.borderWidth" ); protected final int borderWidth = UIManager.getInt( "Button.borderWidth" );
protected final int defaultBorderWidth = UIManager.getInt( "Button.default.borderWidth" ); protected final int defaultBorderWidth = UIManager.getInt( "Button.default.borderWidth" );
protected final float buttonInnerFocusWidth = FlatUIUtils.getUIFloat( "Button.innerFocusWidth", innerFocusWidth ); protected final float buttonInnerFocusWidth = FlatUIUtils.getUIFloat( "Button.innerFocusWidth", innerFocusWidth );
protected final Insets toolbarMargin = UIManager.getInsets( "Button.toolbar.margin" ); protected final Insets toolbarMargin = UIManager.getInsets( "Button.toolbar.margin" );
protected final Insets toolbarSpacingInsets = UIManager.getInsets( "Button.toolbar.spacingInsets" ); protected final Insets toolbarSpacingInsets = UIManager.getInsets( "Button.toolbar.spacingInsets" );
/** @since 1.4 */
protected final float toolbarFocusWidth = FlatUIUtils.getUIFloat( "Button.toolbar.focusWidth", 1.5f );
protected final int arc = UIManager.getInt( "Button.arc" ); protected final int arc = UIManager.getInt( "Button.arc" );
@Override @Override
@@ -79,11 +86,41 @@ public class FlatButtonBorder
!FlatButtonUI.isHelpButton( c ) && !FlatButtonUI.isHelpButton( c ) &&
!FlatToggleButtonUI.isTabButton( c ) ) !FlatToggleButtonUI.isTabButton( c ) )
super.paintBorder( c, g, x, y, width, height ); super.paintBorder( c, g, x, y, width, height );
else if( FlatButtonUI.isToolBarButton( c ) && isFocused( c ) )
paintToolBarFocus( c, g, x, y, width, height );
}
/**
* @since 1.4
*/
protected void paintToolBarFocus( Component c, Graphics g, int x, int y, int width, int height ) {
Graphics2D g2 = (Graphics2D) g.create();
try {
FlatUIUtils.setRenderingHints( g2 );
float focusWidth = UIScale.scale( toolbarFocusWidth );
float arc = UIScale.scale( (float) getArc( c ) );
Color outlineColor = getOutlineColor( c );
Insets spacing = UIScale.scale( toolbarSpacingInsets );
x += spacing.left;
y += spacing.top;
width -= spacing.left + spacing.right;
height -= spacing.top + spacing.bottom;
g2.setColor( (outlineColor != null) ? outlineColor : getFocusColor( c ) );
// not using paintComponentOuterBorder() here because its round edges look too "thick"
FlatUIUtils.paintComponentBorder( g2, x, y, width, height, 0, focusWidth, arc );
} finally {
g2.dispose();
}
} }
@Override @Override
protected Color getFocusColor( Component c ) { protected Color getFocusColor( Component c ) {
return FlatButtonUI.isDefaultButton( c ) ? defaultFocusColor : super.getFocusColor( c ); return (toolbarFocusColor != null && FlatButtonUI.isToolBarButton( c ))
? toolbarFocusColor
: (FlatButtonUI.isDefaultButton( c ) ? defaultFocusColor : super.getFocusColor( c ));
} }
@Override @Override

View File

@@ -30,6 +30,7 @@ import java.awt.Insets;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.awt.geom.RoundRectangle2D; import java.awt.geom.RoundRectangle2D;
import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeEvent;
import java.util.Objects;
import javax.swing.AbstractButton; import javax.swing.AbstractButton;
import javax.swing.ButtonModel; import javax.swing.ButtonModel;
import javax.swing.Icon; import javax.swing.Icon;
@@ -129,6 +130,7 @@ public class FlatButtonUI
protected Color toolbarSelectedBackground; protected Color toolbarSelectedBackground;
private Icon helpButtonIcon; private Icon helpButtonIcon;
private Insets defaultMargin;
private boolean defaults_initialized = false; private boolean defaults_initialized = false;
@@ -184,6 +186,7 @@ public class FlatButtonUI
toolbarSelectedBackground = UIManager.getColor( prefix + "toolbar.selectedBackground" ); toolbarSelectedBackground = UIManager.getColor( prefix + "toolbar.selectedBackground" );
helpButtonIcon = UIManager.getIcon( "HelpButton.icon" ); helpButtonIcon = UIManager.getIcon( "HelpButton.icon" );
defaultMargin = UIManager.getInsets( prefix + "margin" );
defaults_initialized = true; defaults_initialized = true;
} }
@@ -499,16 +502,23 @@ public class FlatButtonUI
} else if( isIconOnlyOrSingleCharacter && ((AbstractButton)c).getIcon() == null ) { } else if( isIconOnlyOrSingleCharacter && ((AbstractButton)c).getIcon() == null ) {
// make single-character-no-icon button square (increase width) // make single-character-no-icon button square (increase width)
prefSize.width = Math.max( prefSize.width, prefSize.height ); prefSize.width = Math.max( prefSize.width, prefSize.height );
} else if( !isIconOnlyOrSingleCharacter && !isToolBarButton( c ) && c.getBorder() instanceof FlatButtonBorder ) { } else if( !isIconOnlyOrSingleCharacter && !isToolBarButton( c ) &&
c.getBorder() instanceof FlatButtonBorder && hasDefaultMargins( c ) )
{
// apply minimum width/height // apply minimum width/height
float focusWidth = FlatUIUtils.getBorderFocusWidth( c ); int fw = Math.round( FlatUIUtils.getBorderFocusWidth( c ) * 2 );
prefSize.width = Math.max( prefSize.width, scale( FlatUIUtils.minimumWidth( c, minimumWidth ) ) + Math.round( focusWidth * 2 ) ); prefSize.width = Math.max( prefSize.width, scale( FlatUIUtils.minimumWidth( c, minimumWidth ) ) + fw );
prefSize.height = Math.max( prefSize.height, scale( FlatUIUtils.minimumHeight( c, 0 ) ) + Math.round( focusWidth * 2 ) ); prefSize.height = Math.max( prefSize.height, scale( FlatUIUtils.minimumHeight( c, 0 ) ) + fw );
} }
return prefSize; return prefSize;
} }
private boolean hasDefaultMargins( JComponent c ) {
Insets margin = ((AbstractButton)c).getMargin();
return margin instanceof UIResource && Objects.equals( margin, defaultMargin );
}
//---- class FlatButtonListener ------------------------------------------- //---- class FlatButtonListener -------------------------------------------
protected class FlatButtonListener protected class FlatButtonListener

View File

@@ -18,10 +18,13 @@ package com.formdev.flatlaf.ui;
import static com.formdev.flatlaf.FlatClientProperties.*; import static com.formdev.flatlaf.FlatClientProperties.*;
import java.awt.EventQueue; import java.awt.EventQueue;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.event.FocusEvent; import java.awt.event.FocusEvent;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import javax.swing.JFormattedTextField; import javax.swing.JFormattedTextField;
import javax.swing.plaf.UIResource; import javax.swing.plaf.UIResource;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultCaret; import javax.swing.text.DefaultCaret;
import javax.swing.text.Document; import javax.swing.text.Document;
import javax.swing.text.JTextComponent; import javax.swing.text.JTextComponent;
@@ -61,6 +64,19 @@ public class FlatCaret
} }
} }
@Override
protected void adjustVisibility( Rectangle nloc ) {
JTextComponent c = getComponent();
if( c != null && c.getUI() instanceof FlatTextFieldUI ) {
Insets padding = ((FlatTextFieldUI)c.getUI()).getPadding();
if( padding != null ) {
nloc.x -= padding.left;
nloc.y -= padding.top;
}
}
super.adjustVisibility( nloc );
}
@Override @Override
public void focusGained( FocusEvent e ) { public void focusGained( FocusEvent e ) {
if( !wasTemporaryLost && (!isMousePressed || selectAllOnMouseClick) ) if( !wasTemporaryLost && (!isMousePressed || selectAllOnMouseClick) )
@@ -127,4 +143,23 @@ public class FlatCaret
moveDot( doc.getLength() ); moveDot( doc.getLength() );
} }
} }
/**
* @since 1.4
*/
public void scrollCaretToVisible() {
JTextComponent c = getComponent();
if( c == null || c.getUI() == null )
return;
try {
Rectangle loc = c.getUI().modelToView( c, getDot(), getDotBias() );
if( loc != null ) {
adjustVisibility( loc );
damage( loc );
}
} catch( BadLocationException ex ) {
// ignore
}
}
} }

View File

@@ -17,11 +17,13 @@
package com.formdev.flatlaf.ui; package com.formdev.flatlaf.ui;
import static com.formdev.flatlaf.util.UIScale.scale; import static com.formdev.flatlaf.util.UIScale.scale;
import static com.formdev.flatlaf.util.UIScale.unscale;
import java.awt.Color; import java.awt.Color;
import java.awt.Component; import java.awt.Component;
import java.awt.ComponentOrientation; import java.awt.ComponentOrientation;
import java.awt.Container; import java.awt.Container;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration; import java.awt.GraphicsConfiguration;
@@ -39,7 +41,6 @@ import java.awt.event.MouseEvent;
import java.awt.event.MouseListener; import java.awt.event.MouseListener;
import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D;
import java.beans.PropertyChangeListener; import java.beans.PropertyChangeListener;
import java.lang.ref.WeakReference;
import javax.swing.AbstractAction; import javax.swing.AbstractAction;
import javax.swing.BorderFactory; import javax.swing.BorderFactory;
import javax.swing.CellRendererPane; import javax.swing.CellRendererPane;
@@ -68,7 +69,6 @@ import javax.swing.plaf.basic.ComboPopup;
import javax.swing.text.JTextComponent; import javax.swing.text.JTextComponent;
import com.formdev.flatlaf.FlatClientProperties; import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.util.SystemInfo; import com.formdev.flatlaf.util.SystemInfo;
import com.formdev.flatlaf.util.UIScale;
/** /**
* Provides the Flat LaF UI delegate for {@link javax.swing.JComboBox}. * Provides the Flat LaF UI delegate for {@link javax.swing.JComboBox}.
@@ -137,7 +137,7 @@ public class FlatComboBoxUI
protected boolean hover; protected boolean hover;
protected boolean pressed; protected boolean pressed;
private WeakReference<Component> lastRendererComponent; private CellPaddingBorder paddingBorder;
public static ComponentUI createUI( JComponent c ) { public static ComponentUI createUI( JComponent c ) {
return new FlatComboBoxUI(); return new FlatComboBoxUI();
@@ -222,8 +222,7 @@ public class FlatComboBoxUI
if( maximumRowCount > 0 && maximumRowCount != 8 && comboBox.getMaximumRowCount() == 8 ) if( maximumRowCount > 0 && maximumRowCount != 8 && comboBox.getMaximumRowCount() == 8 )
comboBox.setMaximumRowCount( maximumRowCount ); comboBox.setMaximumRowCount( maximumRowCount );
// scale paddingBorder = new CellPaddingBorder( padding );
padding = UIScale.scale( padding );
MigLayoutVisualPadding.install( comboBox ); MigLayoutVisualPadding.install( comboBox );
} }
@@ -250,6 +249,8 @@ public class FlatComboBoxUI
popupBackground = null; popupBackground = null;
paddingBorder.uninstall();
MigLayoutVisualPadding.uninstall( comboBox ); MigLayoutVisualPadding.uninstall( comboBox );
} }
@@ -261,8 +262,12 @@ public class FlatComboBoxUI
super.layoutContainer( parent ); super.layoutContainer( parent );
if( arrowButton != 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 );
Insets insets = getInsets(); Insets insets = getInsets();
int buttonWidth = parent.getPreferredSize().height - insets.top - insets.bottom; int buttonWidth = Math.min( parent.getPreferredSize().height - insets.top - insets.bottom, maxButtonWidth );
if( buttonWidth != arrowButton.getWidth() ) { if( buttonWidth != arrowButton.getWidth() ) {
// set width of arrow button to preferred height of combobox // set width of arrow button to preferred height of combobox
int xOffset = comboBox.getComponentOrientation().isLeftToRight() int xOffset = comboBox.getComponentOrientation().isLeftToRight()
@@ -276,11 +281,6 @@ public class FlatComboBoxUI
editor.setBounds( rectangleForCurrentValue() ); editor.setBounds( rectangleForCurrentValue() );
} }
} }
if( editor != null && padding != null ) {
// fix editor bounds by subtracting padding
editor.setBounds( FlatUIUtils.subtractInsets( editor.getBounds(), padding ) );
}
} }
}; };
} }
@@ -371,6 +371,7 @@ public class FlatComboBoxUI
editor.applyComponentOrientation( comboBox.getComponentOrientation() ); editor.applyComponentOrientation( comboBox.getComponentOrientation() );
updateEditorPadding();
updateEditorColors(); updateEditorColors();
// macOS // macOS
@@ -387,6 +388,25 @@ public class FlatComboBoxUI
} }
} }
private void updateEditorPadding() {
if( !(editor instanceof JTextField) )
return;
JTextField textField = (JTextField) editor;
Insets insets = textField.getInsets();
Insets pad = padding;
if( insets.top != 0 || insets.left != 0 || insets.bottom != 0 || insets.right != 0 ) {
// if text field has custom border, subtract text field insets from padding
pad = new Insets(
unscale( Math.max( scale( padding.top ) - insets.top, 0 ) ),
unscale( Math.max( scale( padding.left ) - insets.left, 0 ) ),
unscale( Math.max( scale( padding.bottom ) - insets.bottom, 0 ) ),
unscale( Math.max( scale( padding.right ) - insets.right, 0 ) )
);
}
textField.putClientProperty( FlatClientProperties.TEXT_FIELD_PADDING, pad );
}
private void updateEditorColors() { private void updateEditorColors() {
// use non-UIResource colors because when SwingUtilities.updateComponentTreeUI() // use non-UIResource colors because when SwingUtilities.updateComponentTreeUI()
// is used, then the editor is updated after the combobox and the // is used, then the editor is updated after the combobox and the
@@ -471,30 +491,24 @@ public class FlatComboBoxUI
@Override @Override
@SuppressWarnings( "unchecked" ) @SuppressWarnings( "unchecked" )
public void paintCurrentValue( Graphics g, Rectangle bounds, boolean hasFocus ) { public void paintCurrentValue( Graphics g, Rectangle bounds, boolean hasFocus ) {
paddingBorder.uninstall();
ListCellRenderer<Object> renderer = comboBox.getRenderer(); ListCellRenderer<Object> renderer = comboBox.getRenderer();
uninstallCellPaddingBorder( renderer );
if( renderer == null ) if( renderer == null )
renderer = new DefaultListCellRenderer(); renderer = new DefaultListCellRenderer();
Component c = renderer.getListCellRendererComponent( listBox, comboBox.getSelectedItem(), -1, false, false ); Component c = renderer.getListCellRendererComponent( listBox, comboBox.getSelectedItem(), -1, false, false );
c.setFont( comboBox.getFont() ); c.setFont( comboBox.getFont() );
c.applyComponentOrientation( comboBox.getComponentOrientation() ); c.applyComponentOrientation( comboBox.getComponentOrientation() );
uninstallCellPaddingBorder( c );
boolean enabled = comboBox.isEnabled(); boolean enabled = comboBox.isEnabled();
c.setBackground( getBackground( enabled ) ); c.setBackground( getBackground( enabled ) );
c.setForeground( getForeground( enabled ) ); c.setForeground( getForeground( enabled ) );
boolean shouldValidate = (c instanceof JPanel); boolean shouldValidate = (c instanceof JPanel);
if( padding != null )
bounds = FlatUIUtils.subtractInsets( bounds, padding );
// increase the size of the rendering area to make sure that the text
// is vertically aligned with other component types (e.g. JTextField)
Insets rendererInsets = getRendererComponentInsets( c );
if( rendererInsets != null )
bounds = FlatUIUtils.addInsets( bounds, rendererInsets );
paddingBorder.install( c );
currentValuePane.paintComponent( g, c, comboBox, bounds.x, bounds.y, bounds.width, bounds.height, shouldValidate ); currentValuePane.paintComponent( g, c, comboBox, bounds.x, bounds.y, bounds.width, bounds.height, shouldValidate );
paddingBorder.uninstall();
} }
@Override @Override
@@ -526,77 +540,49 @@ public class FlatComboBoxUI
@Override @Override
public Dimension getMinimumSize( JComponent c ) { public Dimension getMinimumSize( JComponent c ) {
Dimension minimumSize = super.getMinimumSize( c ); Dimension minimumSize = super.getMinimumSize( c );
minimumSize.width = Math.max( minimumSize.width, scale( FlatUIUtils.minimumWidth( c, minimumWidth ) ) ); int fw = Math.round( FlatUIUtils.getBorderFocusWidth( c ) * 2 );
minimumSize.width = Math.max( minimumSize.width, scale( FlatUIUtils.minimumWidth( c, minimumWidth ) ) + fw );
return minimumSize; return minimumSize;
} }
@Override @Override
protected Dimension getDefaultSize() { protected Dimension getDefaultSize() {
@SuppressWarnings( "unchecked" ) paddingBorder.uninstall();
ListCellRenderer<Object> renderer = comboBox.getRenderer();
uninstallCellPaddingBorder( renderer );
Dimension size = super.getDefaultSize(); Dimension size = super.getDefaultSize();
paddingBorder.uninstall();
uninstallCellPaddingBorder( renderer );
return size; return size;
} }
@Override @Override
protected Dimension getDisplaySize() { protected Dimension getDisplaySize() {
@SuppressWarnings( "unchecked" ) paddingBorder.uninstall();
ListCellRenderer<Object> renderer = comboBox.getRenderer();
uninstallCellPaddingBorder( renderer );
Dimension displaySize = super.getDisplaySize(); Dimension displaySize = super.getDisplaySize();
paddingBorder.uninstall();
// remove padding added in super.getDisplaySize()
int displayWidth = displaySize.width - padding.left - padding.right;
int displayHeight = displaySize.height - padding.top - padding.bottom;
// recalculate width without hardcoded 100 under special conditions // recalculate width without hardcoded 100 under special conditions
if( displaySize.width == 100 + padding.left + padding.right && if( displayWidth == 100 &&
comboBox.isEditable() && comboBox.isEditable() &&
comboBox.getItemCount() == 0 && comboBox.getItemCount() == 0 &&
comboBox.getPrototypeDisplayValue() == null ) comboBox.getPrototypeDisplayValue() == null )
{ {
int width = getDefaultSize().width; displayWidth = Math.max( getDefaultSize().width, editor.getPreferredSize().width );
width = Math.max( width, editor.getPreferredSize().width );
width += padding.left + padding.right;
displaySize = new Dimension( width, displaySize.height );
} }
uninstallCellPaddingBorder( renderer ); return new Dimension( displayWidth, displayHeight );
return displaySize;
} }
@Override @Override
protected Dimension getSizeForComponent( Component comp ) { protected Dimension getSizeForComponent( Component comp ) {
paddingBorder.install( comp );
Dimension size = super.getSizeForComponent( comp ); Dimension size = super.getSizeForComponent( comp );
paddingBorder.uninstall();
// remove the renderer border top/bottom insets from the size to make sure that
// the combobox gets the same height as other component types (e.g. JTextField)
Insets rendererInsets = getRendererComponentInsets( comp );
if( rendererInsets != null )
size = new Dimension( size.width, size.height - rendererInsets.top - rendererInsets.bottom );
return size; return size;
} }
private Insets getRendererComponentInsets( Component rendererComponent ) {
if( rendererComponent instanceof JComponent ) {
Border rendererBorder = ((JComponent)rendererComponent).getBorder();
if( rendererBorder != null )
return rendererBorder.getBorderInsets( rendererComponent );
}
return null;
}
private void uninstallCellPaddingBorder( Object o ) {
CellPaddingBorder.uninstall( o );
if( lastRendererComponent != null ) {
CellPaddingBorder.uninstall( lastRendererComponent );
lastRendererComponent = null;
}
}
private boolean isCellRenderer() { private boolean isCellRenderer() {
return comboBox.getParent() instanceof CellRendererPane; return comboBox.getParent() instanceof CellRendererPane;
} }
@@ -660,13 +646,11 @@ public class FlatComboBoxUI
protected class FlatComboPopup protected class FlatComboPopup
extends BasicComboPopup extends BasicComboPopup
{ {
private CellPaddingBorder paddingBorder;
protected FlatComboPopup( JComboBox combo ) { protected FlatComboPopup( JComboBox combo ) {
super( combo ); super( combo );
// BasicComboPopup listens to JComboBox.componentOrientation and updates // BasicComboPopup listens to JComboBox.componentOrientation and updates
// the component orientation of the list, scroller and popup, but when // the component orientation of the list, scroll pane and popup, but when
// switching the LaF and a new combo popup is created, the component // switching the LaF and a new combo popup is created, the component
// orientation is not applied. // orientation is not applied.
ComponentOrientation o = comboBox.getComponentOrientation(); ComponentOrientation o = comboBox.getComponentOrientation();
@@ -745,6 +729,19 @@ public class FlatComboBoxUI
}; };
} }
@Override
protected int getPopupHeightForRowCount( int maxRowCount ) {
int height = super.getPopupHeightForRowCount( maxRowCount );
paddingBorder.uninstall();
return height;
}
@Override
protected void paintChildren( Graphics g ) {
super.paintChildren( g );
paddingBorder.uninstall();
}
//---- class PopupListCellRenderer ----- //---- class PopupListCellRenderer -----
private class PopupListCellRenderer private class PopupListCellRenderer
@@ -754,22 +751,15 @@ public class FlatComboBoxUI
public Component getListCellRendererComponent( JList list, Object value, public Component getListCellRendererComponent( JList list, Object value,
int index, boolean isSelected, boolean cellHasFocus ) int index, boolean isSelected, boolean cellHasFocus )
{ {
ListCellRenderer renderer = comboBox.getRenderer(); paddingBorder.uninstall();
CellPaddingBorder.uninstall( renderer );
CellPaddingBorder.uninstall( lastRendererComponent );
ListCellRenderer renderer = comboBox.getRenderer();
if( renderer == null ) if( renderer == null )
renderer = new DefaultListCellRenderer(); renderer = new DefaultListCellRenderer();
Component c = renderer.getListCellRendererComponent( list, value, index, isSelected, cellHasFocus ); Component c = renderer.getListCellRendererComponent( list, value, index, isSelected, cellHasFocus );
c.applyComponentOrientation( comboBox.getComponentOrientation() ); c.applyComponentOrientation( comboBox.getComponentOrientation() );
if( c instanceof JComponent ) { paddingBorder.install( c );
if( paddingBorder == null )
paddingBorder = new CellPaddingBorder( padding );
paddingBorder.install( (JComponent) c );
}
lastRendererComponent = (c != renderer) ? new WeakReference<>( c ) : null;
return c; return c;
} }
@@ -779,49 +769,69 @@ public class FlatComboBoxUI
//---- class CellPaddingBorder -------------------------------------------- //---- class CellPaddingBorder --------------------------------------------
/** /**
* Cell padding border used only in popup list. * Cell padding border used in popup list and for current value if not editable.
* * <p>
* The insets are the union of the cell padding and the renderer border insets, * The insets are the union of the cell padding and the renderer border insets,
* which vertically aligns text in popup list with text in combobox. * which vertically aligns text in popup list with text in combobox.
* * <p>
* The renderer border is painted on the outside of this border. * The renderer border is painted on the outer side of this border.
*/ */
private static class CellPaddingBorder private static class CellPaddingBorder
extends AbstractBorder extends AbstractBorder
{ {
private final Insets padding; private final Insets padding;
private JComponent rendererComponent;
private Border rendererBorder; private Border rendererBorder;
CellPaddingBorder( Insets padding ) { CellPaddingBorder( Insets padding ) {
this.padding = padding; this.padding = padding;
} }
void install( JComponent rendererComponent ) { void install( Component c ) {
Border oldBorder = rendererComponent.getBorder(); if( !(c instanceof JComponent) )
if( !(oldBorder instanceof CellPaddingBorder) ) {
rendererBorder = oldBorder;
rendererComponent.setBorder( this );
}
}
static void uninstall( Object o ) {
if( o instanceof WeakReference )
o = ((WeakReference<?>)o).get();
if( !(o instanceof JComponent) )
return; return;
JComponent rendererComponent = (JComponent) o; JComponent jc = (JComponent) c;
Border border = rendererComponent.getBorder(); Border oldBorder = jc.getBorder();
if( border instanceof CellPaddingBorder ) { if( oldBorder == this )
CellPaddingBorder paddingBorder = (CellPaddingBorder) border; return; // already installed
rendererComponent.setBorder( paddingBorder.rendererBorder );
paddingBorder.rendererBorder = null; // component already has a padding border --> uninstall it
} // (may happen if single renderer instance is used in multiple comboboxes)
if( oldBorder instanceof CellPaddingBorder )
((CellPaddingBorder)oldBorder).uninstall();
// this border can be installed only at one component
// (may happen if a renderer returns varying components)
uninstall();
// remember component where this border was installed for uninstall
rendererComponent = jc;
// remember old border and replace it
rendererBorder = jc.getBorder();
rendererComponent.setBorder( this );
}
/**
* Uninstall border from previously installed component.
* Because this border is installed in PopupListCellRenderer.getListCellRendererComponent(),
* there is no single place to uninstall it.
* This is the reason why this method is called from various places.
*/
void uninstall() {
if( rendererComponent == null )
return;
if( rendererComponent.getBorder() == this )
rendererComponent.setBorder( rendererBorder );
rendererComponent = null;
rendererBorder = null;
} }
@Override @Override
public Insets getBorderInsets( Component c, Insets insets ) { public Insets getBorderInsets( Component c, Insets insets ) {
Insets padding = scale( this.padding );
if( rendererBorder != null ) { if( rendererBorder != null ) {
Insets insideInsets = rendererBorder.getBorderInsets( c ); Insets insideInsets = rendererBorder.getBorderInsets( c );
insets.top = Math.max( padding.top, insideInsets.top ); insets.top = Math.max( padding.top, insideInsets.top );

View File

@@ -21,6 +21,7 @@ import java.awt.Color;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.event.FocusListener; import java.awt.event.FocusListener;
import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeEvent;
import javax.swing.JComponent; import javax.swing.JComponent;
@@ -65,6 +66,8 @@ public class FlatEditorPaneUI
protected boolean isIntelliJTheme; protected boolean isIntelliJTheme;
protected Color focusedBackground; protected Color focusedBackground;
private Insets defaultMargin;
private Object oldHonorDisplayProperties; private Object oldHonorDisplayProperties;
private FocusListener focusListener; private FocusListener focusListener;
@@ -81,6 +84,8 @@ public class FlatEditorPaneUI
isIntelliJTheme = UIManager.getBoolean( "Component.isIntelliJTheme" ); isIntelliJTheme = UIManager.getBoolean( "Component.isIntelliJTheme" );
focusedBackground = UIManager.getColor( prefix + ".focusedBackground" ); focusedBackground = UIManager.getColor( prefix + ".focusedBackground" );
defaultMargin = UIManager.getInsets( prefix + ".margin" );
// use component font and foreground for HTML text // use component font and foreground for HTML text
oldHonorDisplayProperties = getComponent().getClientProperty( JEditorPane.HONOR_DISPLAY_PROPERTIES ); oldHonorDisplayProperties = getComponent().getClientProperty( JEditorPane.HONOR_DISPLAY_PROPERTIES );
getComponent().putClientProperty( JEditorPane.HONOR_DISPLAY_PROPERTIES, true ); getComponent().putClientProperty( JEditorPane.HONOR_DISPLAY_PROPERTIES, true );
@@ -128,15 +133,19 @@ public class FlatEditorPaneUI
@Override @Override
public Dimension getPreferredSize( JComponent c ) { public Dimension getPreferredSize( JComponent c ) {
return applyMinimumWidth( c, super.getPreferredSize( c ), minimumWidth ); return applyMinimumWidth( c, super.getPreferredSize( c ), minimumWidth, defaultMargin );
} }
@Override @Override
public Dimension getMinimumSize( JComponent c ) { public Dimension getMinimumSize( JComponent c ) {
return applyMinimumWidth( c, super.getMinimumSize( c ), minimumWidth ); return applyMinimumWidth( c, super.getMinimumSize( c ), minimumWidth, defaultMargin );
} }
static Dimension applyMinimumWidth( JComponent c, Dimension size, int minimumWidth ) { static Dimension applyMinimumWidth( JComponent c, Dimension size, int minimumWidth, Insets defaultMargin ) {
// do not apply minimum width if JTextComponent.margin is set
if( !FlatTextFieldUI.hasDefaultMargins( c, defaultMargin ) )
return size;
// Assume that text area is in a scroll pane (that displays the border) // Assume that text area is in a scroll pane (that displays the border)
// and subtract 1px border line width. // and subtract 1px border line width.
// Using "(scale( 1 ) * 2)" instead of "scale( 2 )" to deal with rounding // Using "(scale( 1 ) * 2)" instead of "scale( 2 )" to deal with rounding

View File

@@ -39,8 +39,6 @@ import javax.swing.plaf.ComponentUI;
* *
* <!-- FlatTextFieldUI --> * <!-- FlatTextFieldUI -->
* *
* @uiDefault TextComponent.arc int
* @uiDefault Component.focusWidth int
* @uiDefault Component.minimumWidth int * @uiDefault Component.minimumWidth int
* @uiDefault Component.isIntelliJTheme boolean * @uiDefault Component.isIntelliJTheme boolean
* @uiDefault FormattedTextField.placeholderForeground Color * @uiDefault FormattedTextField.placeholderForeground Color

View File

@@ -22,7 +22,10 @@ import java.awt.Dimension;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.GridBagConstraints; import java.awt.GridBagConstraints;
import java.awt.Insets; import java.awt.Insets;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.UIManager; import javax.swing.UIManager;
import javax.swing.border.Border; import javax.swing.border.Border;
@@ -160,12 +163,30 @@ public class FlatOptionPaneUI
if( msg instanceof String && BasicHTML.isHTMLString( (String) msg ) ) if( msg instanceof String && BasicHTML.isHTMLString( (String) msg ) )
maxll = Integer.MAX_VALUE; maxll = Integer.MAX_VALUE;
// fix right-to-left alignment if super.addMessageComponents() breaks longer lines
// into multiple labels and puts them into a box that aligns them to the left
if( msg instanceof Box ) {
Box box = (Box) msg;
if( "OptionPane.verticalBox".equals( box.getName() ) &&
box.getLayout() instanceof BoxLayout &&
((BoxLayout)box.getLayout()).getAxis() == BoxLayout.Y_AXIS )
{
box.addPropertyChangeListener( "componentOrientation", e -> {
float alignX = box.getComponentOrientation().isLeftToRight() ? 0 : 1;
for( Component c : box.getComponents() ) {
if( c instanceof JLabel && "OptionPane.label".equals( c.getName() ) )
((JLabel)c).setAlignmentX( alignX );
}
} );
}
}
super.addMessageComponents( container, cons, msg, maxll, internallyCreated ); super.addMessageComponents( container, cons, msg, maxll, internallyCreated );
} }
private void updateChildPanels( Container c ) { private void updateChildPanels( Container c ) {
for( Component child : c.getComponents() ) { for( Component child : c.getComponents() ) {
if( child instanceof JPanel ) { if( child.getClass() == JPanel.class ) {
JPanel panel = (JPanel)child; JPanel panel = (JPanel)child;
// make sub-panel non-opaque for OptionPane.background // make sub-panel non-opaque for OptionPane.background
@@ -177,9 +198,8 @@ public class FlatOptionPaneUI
panel.setBorder( new NonUIResourceBorder( border ) ); panel.setBorder( new NonUIResourceBorder( border ) );
} }
if( child instanceof Container ) { if( child instanceof Container )
updateChildPanels( (Container) child ); updateChildPanels( (Container) child );
}
} }
} }

View File

@@ -16,30 +16,31 @@
package com.formdev.flatlaf.ui; package com.formdev.flatlaf.ui;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.Graphics2D; import java.awt.Insets;
import java.awt.Shape;
import java.awt.Toolkit; import java.awt.Toolkit;
import java.awt.event.FocusListener;
import java.awt.event.KeyAdapter; import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
import java.awt.event.KeyListener; import java.awt.event.KeyListener;
import java.beans.PropertyChangeEvent; import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.Icon; import javax.swing.Icon;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.LookAndFeel; import javax.swing.LookAndFeel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager; import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI; import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicPasswordFieldUI; import javax.swing.text.DefaultEditorKit;
import javax.swing.text.Caret; import javax.swing.text.Element;
import javax.swing.text.JTextComponent; import javax.swing.text.JTextComponent;
import com.formdev.flatlaf.util.HiDPIUtils; import javax.swing.text.PasswordView;
import javax.swing.text.View;
/** /**
* Provides the Flat LaF UI delegate for {@link javax.swing.JPasswordField}. * Provides the Flat LaF UI delegate for {@link javax.swing.JPasswordField}.
* *
* <!-- BasicPasswordFieldUI --> * <!-- BasicTextFieldUI -->
* *
* @uiDefault PasswordField.font Font * @uiDefault PasswordField.font Font
* @uiDefault PasswordField.background Color * @uiDefault PasswordField.background Color
@@ -52,74 +53,66 @@ import com.formdev.flatlaf.util.HiDPIUtils;
* @uiDefault PasswordField.inactiveForeground Color used if not enabled (yes, this is confusing; this should be named disabledForeground) * @uiDefault PasswordField.inactiveForeground Color used if not enabled (yes, this is confusing; this should be named disabledForeground)
* @uiDefault PasswordField.border Border * @uiDefault PasswordField.border Border
* @uiDefault PasswordField.margin Insets * @uiDefault PasswordField.margin Insets
* @uiDefault PasswordField.echoChar character
* @uiDefault PasswordField.caretBlinkRate int default is 500 milliseconds * @uiDefault PasswordField.caretBlinkRate int default is 500 milliseconds
* *
* <!-- FlatPasswordFieldUI --> * <!-- FlatTextFieldUI -->
* *
* @uiDefault Component.minimumWidth int * @uiDefault Component.minimumWidth int
* @uiDefault Component.isIntelliJTheme boolean * @uiDefault Component.isIntelliJTheme boolean
* @uiDefault PasswordField.placeholderForeground Color * @uiDefault PasswordField.placeholderForeground Color
* @uiDefault PasswordField.focusedBackground Color optional * @uiDefault PasswordField.focusedBackground Color optional
* @uiDefault PasswordField.showCapsLock boolean
* @uiDefault PasswordField.capsLockIcon Icon
* @uiDefault TextComponent.selectAllOnFocusPolicy String never, once (default) or always * @uiDefault TextComponent.selectAllOnFocusPolicy String never, once (default) or always
* @uiDefault TextComponent.selectAllOnMouseClick boolean * @uiDefault TextComponent.selectAllOnMouseClick boolean
* *
* <!-- FlatPasswordFieldUI -->
*
* @uiDefault PasswordField.echoChar character
* @uiDefault PasswordField.showCapsLock boolean
* @uiDefault PasswordField.capsLockIcon Icon
*
* @author Karl Tauber * @author Karl Tauber
*/ */
public class FlatPasswordFieldUI public class FlatPasswordFieldUI
extends BasicPasswordFieldUI extends FlatTextFieldUI
{ {
protected int minimumWidth;
protected boolean isIntelliJTheme;
protected Color placeholderForeground;
protected Color focusedBackground;
protected boolean showCapsLock; protected boolean showCapsLock;
protected Icon capsLockIcon; protected Icon capsLockIcon;
private FocusListener focusListener;
private KeyListener capsLockListener; private KeyListener capsLockListener;
public static ComponentUI createUI( JComponent c ) { public static ComponentUI createUI( JComponent c ) {
return new FlatPasswordFieldUI(); return new FlatPasswordFieldUI();
} }
@Override
protected String getPropertyPrefix() {
return "PasswordField";
}
@Override @Override
protected void installDefaults() { protected void installDefaults() {
super.installDefaults(); super.installDefaults();
String prefix = getPropertyPrefix(); String prefix = getPropertyPrefix();
minimumWidth = UIManager.getInt( "Component.minimumWidth" ); Character echoChar = (Character) UIManager.get( prefix + ".echoChar" );
isIntelliJTheme = UIManager.getBoolean( "Component.isIntelliJTheme" ); if( echoChar != null )
placeholderForeground = UIManager.getColor( prefix + ".placeholderForeground" ); LookAndFeel.installProperty( getComponent(), "echoChar", echoChar );
focusedBackground = UIManager.getColor( prefix + ".focusedBackground" );
showCapsLock = UIManager.getBoolean( "PasswordField.showCapsLock" ); showCapsLock = UIManager.getBoolean( "PasswordField.showCapsLock" );
capsLockIcon = UIManager.getIcon( "PasswordField.capsLockIcon" ); capsLockIcon = UIManager.getIcon( "PasswordField.capsLockIcon" );
LookAndFeel.installProperty( getComponent(), "opaque", false );
MigLayoutVisualPadding.install( getComponent() );
} }
@Override @Override
protected void uninstallDefaults() { protected void uninstallDefaults() {
super.uninstallDefaults(); super.uninstallDefaults();
placeholderForeground = null;
focusedBackground = null;
capsLockIcon = null; capsLockIcon = null;
MigLayoutVisualPadding.uninstall( getComponent() );
} }
@Override @Override
protected void installListeners() { protected void installListeners() {
super.installListeners(); super.installListeners();
// necessary to update focus border and background
focusListener = new FlatUIUtils.RepaintFocusListener( getComponent(), null );
// update caps lock indicator // update caps lock indicator
capsLockListener = new KeyAdapter() { capsLockListener = new KeyAdapter() {
@Override @Override
@@ -131,12 +124,13 @@ public class FlatPasswordFieldUI
repaint( e ); repaint( e );
} }
private void repaint( KeyEvent e ) { private void repaint( KeyEvent e ) {
if( e.getKeyCode() == KeyEvent.VK_CAPS_LOCK ) if( e.getKeyCode() == KeyEvent.VK_CAPS_LOCK ) {
e.getComponent().repaint(); e.getComponent().repaint();
scrollCaretToVisible();
}
} }
}; };
getComponent().addFocusListener( focusListener );
getComponent().addKeyListener( capsLockListener ); getComponent().addKeyListener( capsLockListener );
} }
@@ -144,59 +138,74 @@ public class FlatPasswordFieldUI
protected void uninstallListeners() { protected void uninstallListeners() {
super.uninstallListeners(); super.uninstallListeners();
getComponent().removeFocusListener( focusListener );
getComponent().removeKeyListener( capsLockListener ); getComponent().removeKeyListener( capsLockListener );
focusListener = null;
capsLockListener = null; capsLockListener = null;
} }
@Override @Override
protected Caret createCaret() { protected void installKeyboardActions() {
return new FlatCaret( UIManager.getString( "TextComponent.selectAllOnFocusPolicy" ), super.installKeyboardActions();
UIManager.getBoolean( "TextComponent.selectAllOnMouseClick" ) );
// map "select-word" action (double-click) to "select-line" action
ActionMap map = SwingUtilities.getUIActionMap( getComponent() );
if( map != null && map.get( DefaultEditorKit.selectWordAction ) != null ) {
Action selectLineAction = map.get( DefaultEditorKit.selectLineAction );
if( selectLineAction != null )
map.put( DefaultEditorKit.selectWordAction, selectLineAction );
}
} }
@Override @Override
protected void propertyChange( PropertyChangeEvent e ) { public View create( Element elem ) {
super.propertyChange( e ); return new PasswordView( elem );
FlatTextFieldUI.propertyChange( getComponent(), e );
} }
@Override @Override
protected void paintSafely( Graphics g ) { protected void paintSafely( Graphics g ) {
FlatTextFieldUI.paintBackground( g, getComponent(), isIntelliJTheme, focusedBackground ); // safe and restore clipping area because super.paintSafely() modifies it
FlatTextFieldUI.paintPlaceholder( g, getComponent(), placeholderForeground ); // and the caps lock icon would be truncated
paintCapsLock( g ); Shape oldClip = g.getClip();
super.paintSafely( g );
g.setClip( oldClip );
super.paintSafely( HiDPIUtils.createGraphicsTextYCorrection( (Graphics2D) g ) ); paintCapsLock( g );
} }
protected void paintCapsLock( Graphics g ) { protected void paintCapsLock( Graphics g ) {
if( !showCapsLock ) if( !isCapsLockVisible() )
return; return;
JTextComponent c = getComponent(); JTextComponent c = getComponent();
if( !FlatUIUtils.isPermanentFocusOwner( c ) ||
!Toolkit.getDefaultToolkit().getLockingKeyState( KeyEvent.VK_CAPS_LOCK ) )
return;
int y = (c.getHeight() - capsLockIcon.getIconHeight()) / 2; int y = (c.getHeight() - capsLockIcon.getIconHeight()) / 2;
int x = c.getWidth() - capsLockIcon.getIconWidth() - y; int x = c.getComponentOrientation().isLeftToRight()
? c.getWidth() - capsLockIcon.getIconWidth() - y
: y;
capsLockIcon.paintIcon( c, g, x, y ); capsLockIcon.paintIcon( c, g, x, y );
} }
@Override /**
protected void paintBackground( Graphics g ) { * @since 1.4
// background is painted elsewhere */
protected boolean isCapsLockVisible() {
if( !showCapsLock )
return false;
JTextComponent c = getComponent();
return FlatUIUtils.isPermanentFocusOwner( c ) &&
Toolkit.getDefaultToolkit().getLockingKeyState( KeyEvent.VK_CAPS_LOCK );
} }
/**
* @since 1.4
*/
@Override @Override
public Dimension getPreferredSize( JComponent c ) { protected Insets getPadding() {
return FlatTextFieldUI.applyMinimumWidth( c, super.getPreferredSize( c ), minimumWidth ); Insets padding = super.getPadding();
} if( !isCapsLockVisible() )
return padding;
@Override boolean ltr = getComponent().getComponentOrientation().isLeftToRight();
public Dimension getMinimumSize( JComponent c ) { int iconWidth = capsLockIcon.getIconWidth();
return FlatTextFieldUI.applyMinimumWidth( c, super.getMinimumSize( c ), minimumWidth ); return FlatUIUtils.addInsets( padding, new Insets( 0, ltr ? 0 : iconWidth, 0, ltr ? iconWidth : 0 ) );
} }
} }

View File

@@ -44,6 +44,7 @@ import javax.swing.Popup;
import javax.swing.PopupFactory; import javax.swing.PopupFactory;
import javax.swing.RootPaneContainer; import javax.swing.RootPaneContainer;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import javax.swing.ToolTipManager;
import javax.swing.UIManager; import javax.swing.UIManager;
import javax.swing.border.Border; import javax.swing.border.Border;
import com.formdev.flatlaf.FlatClientProperties; import com.formdev.flatlaf.FlatClientProperties;
@@ -260,13 +261,7 @@ public class FlatPopupFactory
} }
private boolean wasInvokedFromToolTipManager() { private boolean wasInvokedFromToolTipManager() {
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); return StackUtils.wasInvokedFrom( ToolTipManager.class.getName(), "showTipWindow", 8 );
for( StackTraceElement stackTraceElement : stackTrace ) {
if( "javax.swing.ToolTipManager".equals( stackTraceElement.getClassName() ) &&
"showTipWindow".equals( stackTraceElement.getMethodName() ) )
return true;
}
return false;
} }
//---- class NonFlashingPopup --------------------------------------------- //---- class NonFlashingPopup ---------------------------------------------
@@ -494,6 +489,9 @@ public class FlatPopupFactory
JLayeredPane layeredPane = ((RootPaneContainer)window).getLayeredPane(); JLayeredPane layeredPane = ((RootPaneContainer)window).getLayeredPane();
layeredPane.add( dropShadowPanel, JLayeredPane.POPUP_LAYER, 0 ); layeredPane.add( dropShadowPanel, JLayeredPane.POPUP_LAYER, 0 );
moveMediumWeightDropShadow();
resizeMediumWeightDropShadow();
mediumPanelListener = new ComponentListener() { mediumPanelListener = new ComponentListener() {
@Override @Override
public void componentShown( ComponentEvent e ) { public void componentShown( ComponentEvent e ) {
@@ -509,17 +507,12 @@ public class FlatPopupFactory
@Override @Override
public void componentMoved( ComponentEvent e ) { public void componentMoved( ComponentEvent e ) {
if( dropShadowPanel != null && mediumWeightPanel != null ) { moveMediumWeightDropShadow();
Point location = mediumWeightPanel.getLocation();
Insets insets = dropShadowPanel.getInsets();
dropShadowPanel.setLocation( location.x - insets.left, location.y - insets.top );
}
} }
@Override @Override
public void componentResized( ComponentEvent e ) { public void componentResized( ComponentEvent e ) {
if( dropShadowPanel != null ) resizeMediumWeightDropShadow();
dropShadowPanel.setSize( FlatUIUtils.addInsets( mediumWeightPanel.getSize(), dropShadowPanel.getInsets() ) );
} }
}; };
mediumWeightPanel.addComponentListener( mediumPanelListener ); mediumWeightPanel.addComponentListener( mediumPanelListener );
@@ -535,5 +528,18 @@ public class FlatPopupFactory
parent.repaint( bounds.x, bounds.y, bounds.width, bounds.height ); parent.repaint( bounds.x, bounds.y, bounds.width, bounds.height );
} }
} }
private void moveMediumWeightDropShadow() {
if( dropShadowPanel != null && mediumWeightPanel != null ) {
Point location = mediumWeightPanel.getLocation();
Insets insets = dropShadowPanel.getInsets();
dropShadowPanel.setLocation( location.x - insets.left, location.y - insets.top );
}
}
private void resizeMediumWeightDropShadow() {
if( dropShadowPanel != null && mediumWeightPanel != null )
dropShadowPanel.setSize( FlatUIUtils.addInsets( mediumWeightPanel.getSize(), dropShadowPanel.getInsets() ) );
}
} }
} }

View File

@@ -342,7 +342,7 @@ public class FlatRootPaneUI
? getSizeFunc.apply( rootPane.getContentPane() ) ? getSizeFunc.apply( rootPane.getContentPane() )
: rootPane.getSize(); : rootPane.getSize();
int width = Math.max( titlePaneSize.width, contentSize.width ); int width = contentSize.width; // title pane width is not considered here
int height = titlePaneSize.height + contentSize.height; int height = titlePaneSize.height + contentSize.height;
if( titlePane == null || !titlePane.isMenuBarEmbedded() ) { if( titlePane == null || !titlePane.isMenuBarEmbedded() ) {
JMenuBar menuBar = rootPane.getJMenuBar(); JMenuBar menuBar = rootPane.getJMenuBar();

View File

@@ -21,6 +21,7 @@ import java.awt.Color;
import java.awt.Component; import java.awt.Component;
import java.awt.Container; import java.awt.Container;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.awt.Insets; import java.awt.Insets;
@@ -123,9 +124,6 @@ public class FlatSpinnerUI
buttonPressedArrowColor = UIManager.getColor( "Spinner.buttonPressedArrowColor" ); buttonPressedArrowColor = UIManager.getColor( "Spinner.buttonPressedArrowColor" );
padding = UIManager.getInsets( "Spinner.padding" ); padding = UIManager.getInsets( "Spinner.padding" );
// scale
padding = scale( padding );
MigLayoutVisualPadding.install( spinner ); MigLayoutVisualPadding.install( spinner );
} }
@@ -184,6 +182,7 @@ public class FlatSpinnerUI
if( textField != null ) if( textField != null )
textField.setOpaque( false ); textField.setOpaque( false );
updateEditorPadding();
updateEditorColors(); updateEditorColors();
return editor; return editor;
} }
@@ -194,6 +193,8 @@ public class FlatSpinnerUI
removeEditorFocusListener( oldEditor ); removeEditorFocusListener( oldEditor );
addEditorFocusListener( newEditor ); addEditorFocusListener( newEditor );
updateEditorPadding();
updateEditorColors(); updateEditorColors();
} }
@@ -209,6 +210,12 @@ public class FlatSpinnerUI
textField.removeFocusListener( getHandler() ); textField.removeFocusListener( getHandler() );
} }
private void updateEditorPadding() {
JTextField textField = getEditorTextField( spinner.getEditor() );
if( textField != null )
textField.putClientProperty( FlatClientProperties.TEXT_FIELD_PADDING, padding );
}
private void updateEditorColors() { private void updateEditorColors() {
JTextField textField = getEditorTextField( spinner.getEditor() ); JTextField textField = getEditorTextField( spinner.getEditor() );
if( textField != null ) { if( textField != null ) {
@@ -373,6 +380,7 @@ public class FlatSpinnerUI
@Override @Override
public Dimension preferredLayoutSize( Container parent ) { public Dimension preferredLayoutSize( Container parent ) {
Insets insets = parent.getInsets(); Insets insets = parent.getInsets();
Insets padding = scale( FlatSpinnerUI.this.padding );
Dimension editorSize = (editor != null) ? editor.getPreferredSize() : new Dimension( 0, 0 ); Dimension editorSize = (editor != null) ? editor.getPreferredSize() : new Dimension( 0, 0 );
// the arrows width is the same as the inner height so that the arrows area is square // the arrows width is the same as the inner height so that the arrows area is square
@@ -397,15 +405,19 @@ public class FlatSpinnerUI
if( nextButton == null && previousButton == null ) { if( nextButton == null && previousButton == null ) {
if( editor != null ) if( editor != null )
editor.setBounds( FlatUIUtils.subtractInsets( r, padding ) ); editor.setBounds( r );
return; return;
} }
Rectangle editorRect = new Rectangle( r ); Rectangle editorRect = new Rectangle( r );
Rectangle buttonsRect = new Rectangle( r ); Rectangle buttonsRect = new Rectangle( r );
// limit buttons width to height of a raw spinner (without insets)
FontMetrics fm = spinner.getFontMetrics( spinner.getFont() );
int maxButtonWidth = fm.getHeight() + scale( padding.top ) + scale( padding.bottom );
// make button area square (if spinner has preferred height) // make button area square (if spinner has preferred height)
int buttonsWidth = parent.getPreferredSize().height - insets.top - insets.bottom; int buttonsWidth = Math.min( parent.getPreferredSize().height - insets.top - insets.bottom, maxButtonWidth );
buttonsRect.width = buttonsWidth; buttonsRect.width = buttonsWidth;
if( parent.getComponentOrientation().isLeftToRight() ) { if( parent.getComponentOrientation().isLeftToRight() ) {
@@ -417,7 +429,7 @@ public class FlatSpinnerUI
} }
if( editor != null ) if( editor != null )
editor.setBounds( FlatUIUtils.subtractInsets( editorRect, padding ) ); editor.setBounds( editorRect );
int nextHeight = (buttonsRect.height / 2) + (buttonsRect.height % 2); // round up int nextHeight = (buttonsRect.height / 2) + (buttonsRect.height % 2); // round up
if( nextButton != null ) if( nextButton != null )

View File

@@ -842,6 +842,17 @@ public class FlatTabbedPaneUI
paintTabArea( g, tabPlacement, selectedIndex ); paintTabArea( g, tabPlacement, selectedIndex );
} }
@Override
protected void paintTabArea( Graphics g, int tabPlacement, int selectedIndex ) {
// need to set rendering hints here too because this method is also invoked
// from BasicTabbedPaneUI.ScrollableTabPanel.paintComponent()
Object[] oldHints = FlatUIUtils.setRenderingHints( g );
super.paintTabArea( g, tabPlacement, selectedIndex );
FlatUIUtils.resetRenderingHints( g, oldHints );
}
@Override @Override
protected void paintTab( Graphics g, int tabPlacement, Rectangle[] rects, protected void paintTab( Graphics g, int tabPlacement, Rectangle[] rects,
int tabIndex, Rectangle iconRect, Rectangle textRect ) int tabIndex, Rectangle iconRect, Rectangle textRect )

View File

@@ -94,6 +94,12 @@ public class FlatTableHeaderUI
bottomSeparatorColor = null; bottomSeparatorColor = null;
} }
// overridden and made public to allow usage in custom renderers
@Override
public int getRolloverColumn() {
return super.getRolloverColumn();
}
@Override @Override
public void paint( Graphics g, JComponent c ) { public void paint( Graphics g, JComponent c ) {
TableColumnModel columnModel = header.getColumnModel(); TableColumnModel columnModel = header.getColumnModel();

View File

@@ -240,7 +240,7 @@ public class FlatTableUI
if( isDragging && if( isDragging &&
SystemInfo.isJava_9_orLater && SystemInfo.isJava_9_orLater &&
((horizontalLines && y1 == y2) || (verticalLines && x1 == x2)) && ((horizontalLines && y1 == y2) || (verticalLines && x1 == x2)) &&
wasInvokedFromPaintDraggedArea() ) wasInvokedFromMethod( "paintDraggedArea" ) )
{ {
if( y1 == y2 ) { if( y1 == y2 ) {
// horizontal grid line // horizontal grid line
@@ -282,22 +282,8 @@ public class FlatTableUI
return wasInvokedFromMethod( "paintGrid" ); return wasInvokedFromMethod( "paintGrid" );
} }
private boolean wasInvokedFromPaintDraggedArea() {
return wasInvokedFromMethod( "paintDraggedArea" );
}
private boolean wasInvokedFromMethod( String methodName ) { private boolean wasInvokedFromMethod( String methodName ) {
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace(); return StackUtils.wasInvokedFrom( BasicTableUI.class.getName(), methodName, 8 );
for( int i = 0; i < 10 || i < stackTrace.length; i++ ) {
if( "javax.swing.plaf.basic.BasicTableUI".equals( stackTrace[i].getClassName() ) ) {
String methodName2 = stackTrace[i].getMethodName();
if( "paintCell".equals( methodName2 ) )
return false;
if( methodName.equals( methodName2 ) )
return true;
}
}
return false;
} }
}; };
} }

View File

@@ -20,6 +20,7 @@ import java.awt.Color;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.event.FocusListener; import java.awt.event.FocusListener;
import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeEvent;
import javax.swing.JComponent; import javax.swing.JComponent;
@@ -67,6 +68,8 @@ public class FlatTextAreaUI
protected Color inactiveBackground; protected Color inactiveBackground;
protected Color focusedBackground; protected Color focusedBackground;
private Insets defaultMargin;
private FocusListener focusListener; private FocusListener focusListener;
public static ComponentUI createUI( JComponent c ) { public static ComponentUI createUI( JComponent c ) {
@@ -90,6 +93,8 @@ public class FlatTextAreaUI
disabledBackground = UIManager.getColor( "TextArea.disabledBackground" ); disabledBackground = UIManager.getColor( "TextArea.disabledBackground" );
inactiveBackground = UIManager.getColor( "TextArea.inactiveBackground" ); inactiveBackground = UIManager.getColor( "TextArea.inactiveBackground" );
focusedBackground = UIManager.getColor( "TextArea.focusedBackground" ); focusedBackground = UIManager.getColor( "TextArea.focusedBackground" );
defaultMargin = UIManager.getInsets( "TextArea.margin" );
} }
@Override @Override
@@ -170,7 +175,7 @@ public class FlatTextAreaUI
if( c instanceof JTextArea && ((JTextArea)c).getColumns() > 0 ) if( c instanceof JTextArea && ((JTextArea)c).getColumns() > 0 )
return size; return size;
return FlatEditorPaneUI.applyMinimumWidth( c, size, minimumWidth ); return FlatEditorPaneUI.applyMinimumWidth( c, size, minimumWidth, defaultMargin );
} }
@Override @Override

View File

@@ -24,8 +24,10 @@ import java.awt.FontMetrics;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.awt.Insets; import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.event.FocusListener; import java.awt.event.FocusListener;
import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeEvent;
import java.util.Objects;
import javax.swing.JComboBox; import javax.swing.JComboBox;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.JSpinner; import javax.swing.JSpinner;
@@ -40,6 +42,7 @@ import javax.swing.text.JTextComponent;
import com.formdev.flatlaf.FlatClientProperties; import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.util.HiDPIUtils; import com.formdev.flatlaf.util.HiDPIUtils;
import com.formdev.flatlaf.util.JavaCompatibility; import com.formdev.flatlaf.util.JavaCompatibility;
import com.formdev.flatlaf.util.UIScale;
/** /**
* Provides the Flat LaF UI delegate for {@link javax.swing.JTextField}. * Provides the Flat LaF UI delegate for {@link javax.swing.JTextField}.
@@ -78,6 +81,8 @@ public class FlatTextFieldUI
protected Color placeholderForeground; protected Color placeholderForeground;
protected Color focusedBackground; protected Color focusedBackground;
private Insets defaultMargin;
private FocusListener focusListener; private FocusListener focusListener;
public static ComponentUI createUI( JComponent c ) { public static ComponentUI createUI( JComponent c ) {
@@ -94,6 +99,8 @@ public class FlatTextFieldUI
placeholderForeground = UIManager.getColor( prefix + ".placeholderForeground" ); placeholderForeground = UIManager.getColor( prefix + ".placeholderForeground" );
focusedBackground = UIManager.getColor( prefix + ".focusedBackground" ); focusedBackground = UIManager.getColor( prefix + ".focusedBackground" );
defaultMargin = UIManager.getInsets( prefix + ".margin" );
LookAndFeel.installProperty( getComponent(), "opaque", false ); LookAndFeel.installProperty( getComponent(), "opaque", false );
MigLayoutVisualPadding.install( getComponent() ); MigLayoutVisualPadding.install( getComponent() );
@@ -142,6 +149,7 @@ public class FlatTextFieldUI
switch( e.getPropertyName() ) { switch( e.getPropertyName() ) {
case FlatClientProperties.PLACEHOLDER_TEXT: case FlatClientProperties.PLACEHOLDER_TEXT:
case FlatClientProperties.COMPONENT_ROUND_RECT: case FlatClientProperties.COMPONENT_ROUND_RECT:
case FlatClientProperties.TEXT_FIELD_PADDING:
c.repaint(); c.repaint();
break; break;
@@ -154,7 +162,7 @@ public class FlatTextFieldUI
@Override @Override
protected void paintSafely( Graphics g ) { protected void paintSafely( Graphics g ) {
paintBackground( g, getComponent(), isIntelliJTheme, focusedBackground ); paintBackground( g, getComponent(), isIntelliJTheme, focusedBackground );
paintPlaceholder( g, getComponent(), placeholderForeground ); paintPlaceholder( g );
super.paintSafely( HiDPIUtils.createGraphicsTextYCorrection( (Graphics2D) g ) ); super.paintSafely( HiDPIUtils.createGraphicsTextYCorrection( (Graphics2D) g ) );
} }
@@ -210,7 +218,9 @@ public class FlatTextFieldUI
return background; return background;
} }
static void paintPlaceholder( Graphics g, JTextComponent c, Color placeholderForeground ) { protected void paintPlaceholder( Graphics g ) {
JTextComponent c = getComponent();
// check whether text component is empty // check whether text component is empty
if( c.getDocument().getLength() > 0 ) if( c.getDocument().getLength() > 0 )
return; return;
@@ -225,16 +235,14 @@ public class FlatTextFieldUI
return; return;
// compute placeholder location // compute placeholder location
Insets insets = c.getInsets(); Rectangle r = getVisibleEditorRect();
FontMetrics fm = c.getFontMetrics( c.getFont() ); FontMetrics fm = c.getFontMetrics( c.getFont() );
int x = insets.left; int y = r.y + fm.getAscent() + ((r.height - fm.getHeight()) / 2);
int y = insets.top + fm.getAscent() + ((c.getHeight() - insets.top - insets.bottom - fm.getHeight()) / 2);
// paint placeholder // paint placeholder
g.setColor( placeholderForeground ); g.setColor( placeholderForeground );
String clippedPlaceholder = JavaCompatibility.getClippedString( jc, fm, String clippedPlaceholder = JavaCompatibility.getClippedString( c, fm, (String) placeholder, r.width );
(String) placeholder, c.getWidth() - insets.left - insets.right ); FlatUIUtils.drawString( c, g, clippedPlaceholder, r.x, y );
FlatUIUtils.drawString( c, g, clippedPlaceholder, x, y );
} }
@Override @Override
@@ -247,11 +255,15 @@ public class FlatTextFieldUI
return applyMinimumWidth( c, super.getMinimumSize( c ), minimumWidth ); return applyMinimumWidth( c, super.getMinimumSize( c ), minimumWidth );
} }
static Dimension applyMinimumWidth( JComponent c, Dimension size, int minimumWidth ) { private Dimension applyMinimumWidth( JComponent c, Dimension size, int minimumWidth ) {
// do not apply minimum width if JTextField.columns is set // do not apply minimum width if JTextField.columns is set
if( c instanceof JTextField && ((JTextField)c).getColumns() > 0 ) if( c instanceof JTextField && ((JTextField)c).getColumns() > 0 )
return size; return size;
// do not apply minimum width if JTextComponent.margin is set
if( !hasDefaultMargins( c, defaultMargin ) )
return size;
// do not apply minimum width if used in combobox or spinner // do not apply minimum width if used in combobox or spinner
Container parent = c.getParent(); Container parent = c.getParent();
if( parent instanceof JComboBox || if( parent instanceof JComboBox ||
@@ -264,4 +276,41 @@ public class FlatTextFieldUI
size.width = Math.max( size.width, scale( minimumWidth ) + Math.round( focusWidth * 2 ) ); size.width = Math.max( size.width, scale( minimumWidth ) + Math.round( focusWidth * 2 ) );
return size; return size;
} }
static boolean hasDefaultMargins( JComponent c, Insets defaultMargin ) {
Insets margin = ((JTextComponent)c).getMargin();
return margin instanceof UIResource && Objects.equals( margin, defaultMargin );
}
@Override
protected Rectangle getVisibleEditorRect() {
Rectangle r = super.getVisibleEditorRect();
if( r != null ) {
// remove padding
Insets padding = getPadding();
if( padding != null ) {
r = FlatUIUtils.subtractInsets( r, padding );
r.width = Math.max( r.width, 0 );
r.height = Math.max( r.height, 0 );
}
}
return r;
}
/**
* @since 1.4
*/
protected Insets getPadding() {
Object padding = getComponent().getClientProperty( FlatClientProperties.TEXT_FIELD_PADDING );
return (padding instanceof Insets) ? UIScale.scale( (Insets) padding ) : null;
}
/**
* @since 1.4
*/
protected void scrollCaretToVisible() {
Caret caret = getComponent().getCaret();
if( caret instanceof FlatCaret )
((FlatCaret)caret).scrollCaretToVisible();
}
} }

View File

@@ -20,6 +20,7 @@ import java.awt.Color;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.event.FocusListener; import java.awt.event.FocusListener;
import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeEvent;
import javax.swing.JComponent; import javax.swing.JComponent;
@@ -62,6 +63,8 @@ public class FlatTextPaneUI
protected boolean isIntelliJTheme; protected boolean isIntelliJTheme;
protected Color focusedBackground; protected Color focusedBackground;
private Insets defaultMargin;
private Object oldHonorDisplayProperties; private Object oldHonorDisplayProperties;
private FocusListener focusListener; private FocusListener focusListener;
@@ -78,6 +81,8 @@ public class FlatTextPaneUI
isIntelliJTheme = UIManager.getBoolean( "Component.isIntelliJTheme" ); isIntelliJTheme = UIManager.getBoolean( "Component.isIntelliJTheme" );
focusedBackground = UIManager.getColor( prefix + ".focusedBackground" ); focusedBackground = UIManager.getColor( prefix + ".focusedBackground" );
defaultMargin = UIManager.getInsets( prefix + ".margin" );
// use component font and foreground for HTML text // use component font and foreground for HTML text
oldHonorDisplayProperties = getComponent().getClientProperty( JEditorPane.HONOR_DISPLAY_PROPERTIES ); oldHonorDisplayProperties = getComponent().getClientProperty( JEditorPane.HONOR_DISPLAY_PROPERTIES );
getComponent().putClientProperty( JEditorPane.HONOR_DISPLAY_PROPERTIES, true ); getComponent().putClientProperty( JEditorPane.HONOR_DISPLAY_PROPERTIES, true );
@@ -117,12 +122,12 @@ public class FlatTextPaneUI
@Override @Override
public Dimension getPreferredSize( JComponent c ) { public Dimension getPreferredSize( JComponent c ) {
return FlatEditorPaneUI.applyMinimumWidth( c, super.getPreferredSize( c ), minimumWidth ); return FlatEditorPaneUI.applyMinimumWidth( c, super.getPreferredSize( c ), minimumWidth, defaultMargin );
} }
@Override @Override
public Dimension getMinimumSize( JComponent c ) { public Dimension getMinimumSize( JComponent c ) {
return FlatEditorPaneUI.applyMinimumWidth( c, super.getMinimumSize( c ), minimumWidth ); return FlatEditorPaneUI.applyMinimumWidth( c, super.getMinimumSize( c ), minimumWidth, defaultMargin );
} }
@Override @Override

View File

@@ -22,6 +22,7 @@ import java.awt.event.ContainerEvent;
import java.awt.event.ContainerListener; import java.awt.event.ContainerListener;
import javax.swing.AbstractButton; import javax.swing.AbstractButton;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.UIManager;
import javax.swing.border.Border; import javax.swing.border.Border;
import javax.swing.plaf.ComponentUI; import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicToolBarUI; import javax.swing.plaf.basic.BasicToolBarUI;
@@ -41,15 +42,47 @@ import javax.swing.plaf.basic.BasicToolBarUI;
* @uiDefault ToolBar.floatingForeground Color * @uiDefault ToolBar.floatingForeground Color
* @uiDefault ToolBar.isRollover boolean * @uiDefault ToolBar.isRollover boolean
* *
* <!-- FlatToolBarUI -->
*
* @uiDefault ToolBar.focusableButtons boolean
*
* @author Karl Tauber * @author Karl Tauber
*/ */
public class FlatToolBarUI public class FlatToolBarUI
extends BasicToolBarUI extends BasicToolBarUI
{ {
/** @since 1.4 */
protected boolean focusableButtons;
public static ComponentUI createUI( JComponent c ) { public static ComponentUI createUI( JComponent c ) {
return new FlatToolBarUI(); return new FlatToolBarUI();
} }
@Override
public void installUI( JComponent c ) {
super.installUI( c );
// disable focusable state of buttons (when switching from another Laf)
if( !focusableButtons )
setButtonsFocusable( false );
}
@Override
public void uninstallUI( JComponent c ) {
super.uninstallUI( c );
// re-enable focusable state of buttons (when switching to another Laf)
if( !focusableButtons )
setButtonsFocusable( true );
}
@Override
protected void installDefaults() {
super.installDefaults();
focusableButtons = UIManager.getBoolean( "ToolBar.focusableButtons" );
}
@Override @Override
protected ContainerListener createToolBarContListener() { protected ContainerListener createToolBarContListener() {
return new ToolBarContListener() { return new ToolBarContListener() {
@@ -57,22 +90,36 @@ public class FlatToolBarUI
public void componentAdded( ContainerEvent e ) { public void componentAdded( ContainerEvent e ) {
super.componentAdded( e ); super.componentAdded( e );
Component c = e.getChild(); if( !focusableButtons ) {
if( c instanceof AbstractButton ) Component c = e.getChild();
c.setFocusable( false ); if( c instanceof AbstractButton )
c.setFocusable( false );
}
} }
@Override @Override
public void componentRemoved( ContainerEvent e ) { public void componentRemoved( ContainerEvent e ) {
super.componentRemoved( e ); super.componentRemoved( e );
Component c = e.getChild(); if( !focusableButtons ) {
if( c instanceof AbstractButton ) Component c = e.getChild();
c.setFocusable( true ); if( c instanceof AbstractButton )
c.setFocusable( true );
}
} }
}; };
} }
/**
* @since 1.4
*/
protected void setButtonsFocusable( boolean focusable ) {
for( Component c : toolBar.getComponents() ) {
if( c instanceof AbstractButton )
c.setFocusable( focusable );
}
}
// disable rollover border // disable rollover border
@Override protected void setBorderToRollover( Component c ) {} @Override protected void setBorderToRollover( Component c ) {}
@Override protected void setBorderToNonRollover( Component c ) {} @Override protected void setBorderToNonRollover( Component c ) {}

View File

@@ -94,6 +94,11 @@ public class FlatUIUtils
} }
public static Insets addInsets( Insets insets1, Insets insets2 ) { public static Insets addInsets( Insets insets1, Insets insets2 ) {
if( insets1 == null )
return insets2;
if( insets2 == null )
return insets1;
return new Insets( return new Insets(
insets1.top + insets2.top, insets1.top + insets2.top,
insets1.left + insets2.left, insets1.left + insets2.left,

View File

@@ -181,8 +181,12 @@ public abstract class FlatWindowResizer
protected abstract boolean isWindowResizable(); protected abstract boolean isWindowResizable();
protected abstract Rectangle getWindowBounds(); protected abstract Rectangle getWindowBounds();
protected abstract void setWindowBounds( Rectangle r ); protected abstract void setWindowBounds( Rectangle r );
protected abstract boolean limitToParentBounds();
protected abstract Rectangle getParentBounds();
protected abstract boolean honorMinimumSizeOnResize(); protected abstract boolean honorMinimumSizeOnResize();
protected abstract boolean honorMaximumSizeOnResize();
protected abstract Dimension getWindowMinimumSize(); protected abstract Dimension getWindowMinimumSize();
protected abstract Dimension getWindowMaximumSize();
protected void beginResizing( int direction ) {} protected void beginResizing( int direction ) {}
protected void endResizing() {} protected void endResizing() {}
@@ -283,6 +287,16 @@ public abstract class FlatWindowResizer
} }
} }
@Override
protected boolean limitToParentBounds() {
return false;
}
@Override
protected Rectangle getParentBounds() {
return null;
}
@Override @Override
protected boolean honorMinimumSizeOnResize() { protected boolean honorMinimumSizeOnResize() {
return return
@@ -290,11 +304,21 @@ public abstract class FlatWindowResizer
(honorDialogMinimumSizeOnResize && window instanceof Dialog); (honorDialogMinimumSizeOnResize && window instanceof Dialog);
} }
@Override
protected boolean honorMaximumSizeOnResize() {
return false;
}
@Override @Override
protected Dimension getWindowMinimumSize() { protected Dimension getWindowMinimumSize() {
return window.getMinimumSize(); return window.getMinimumSize();
} }
@Override
protected Dimension getWindowMaximumSize() {
return window.getMaximumSize();
}
@Override @Override
boolean isDialog() { boolean isDialog() {
return window instanceof Dialog; return window instanceof Dialog;
@@ -354,16 +378,36 @@ public abstract class FlatWindowResizer
desktopManager.get().resizeFrame( getFrame(), r.x, r.y, r.width, r.height ); desktopManager.get().resizeFrame( getFrame(), r.x, r.y, r.width, r.height );
} }
@Override
protected boolean limitToParentBounds() {
return true;
}
@Override
protected Rectangle getParentBounds() {
return getFrame().getParent().getBounds();
}
@Override @Override
protected boolean honorMinimumSizeOnResize() { protected boolean honorMinimumSizeOnResize() {
return true; return true;
} }
@Override
protected boolean honorMaximumSizeOnResize() {
return true;
}
@Override @Override
protected Dimension getWindowMinimumSize() { protected Dimension getWindowMinimumSize() {
return getFrame().getMinimumSize(); return getFrame().getMinimumSize();
} }
@Override
protected Dimension getWindowMaximumSize() {
return getFrame().getMaximumSize();
}
@Override @Override
protected void beginResizing( int direction ) { protected void beginResizing( int direction ) {
desktopManager.get().beginResizingFrame( getFrame(), direction ); desktopManager.get().beginResizingFrame( getFrame(), direction );
@@ -521,7 +565,7 @@ debug*/
int xOnScreen = e.getXOnScreen(); int xOnScreen = e.getXOnScreen();
int yOnScreen = e.getYOnScreen(); int yOnScreen = e.getYOnScreen();
// Get current window bounds and compute new bounds based them. // Get current window bounds and compute new bounds based on them.
// This is necessary because window manager may alter window bounds while resizing. // This is necessary because window manager may alter window bounds while resizing.
// E.g. when having two monitors with different scale factors and resizing // E.g. when having two monitors with different scale factors and resizing
// a window on first screen to the second screen, then the window manager may // a window on first screen to the second screen, then the window manager may
@@ -535,41 +579,72 @@ debug*/
// top // top
if( resizeDir == N_RESIZE_CURSOR || resizeDir == NW_RESIZE_CURSOR || resizeDir == NE_RESIZE_CURSOR ) { if( resizeDir == N_RESIZE_CURSOR || resizeDir == NW_RESIZE_CURSOR || resizeDir == NE_RESIZE_CURSOR ) {
newBounds.y = yOnScreen - dragTopOffset; newBounds.y = yOnScreen - dragTopOffset;
if( limitToParentBounds() && newBounds.y < 0 )
newBounds.y = 0;
newBounds.height += (oldBounds.y - newBounds.y); newBounds.height += (oldBounds.y - newBounds.y);
} }
// bottom // bottom
if( resizeDir == S_RESIZE_CURSOR || resizeDir == SW_RESIZE_CURSOR || resizeDir == SE_RESIZE_CURSOR ) if( resizeDir == S_RESIZE_CURSOR || resizeDir == SW_RESIZE_CURSOR || resizeDir == SE_RESIZE_CURSOR ) {
newBounds.height = (yOnScreen + dragBottomOffset) - newBounds.y; newBounds.height = (yOnScreen + dragBottomOffset) - newBounds.y;
if( limitToParentBounds() ) {
int parentHeight = getParentBounds().height;
if( newBounds.y + newBounds.height > parentHeight )
newBounds.height = parentHeight - newBounds.y;
}
}
// left // left
if( resizeDir == W_RESIZE_CURSOR || resizeDir == NW_RESIZE_CURSOR || resizeDir == SW_RESIZE_CURSOR ) { if( resizeDir == W_RESIZE_CURSOR || resizeDir == NW_RESIZE_CURSOR || resizeDir == SW_RESIZE_CURSOR ) {
newBounds.x = xOnScreen - dragLeftOffset; newBounds.x = xOnScreen - dragLeftOffset;
if( limitToParentBounds() && newBounds.x < 0 )
newBounds.x = 0;
newBounds.width += (oldBounds.x - newBounds.x); newBounds.width += (oldBounds.x - newBounds.x);
} }
// right // right
if( resizeDir == E_RESIZE_CURSOR || resizeDir == NE_RESIZE_CURSOR || resizeDir == SE_RESIZE_CURSOR ) if( resizeDir == E_RESIZE_CURSOR || resizeDir == NE_RESIZE_CURSOR || resizeDir == SE_RESIZE_CURSOR ) {
newBounds.width = (xOnScreen + dragRightOffset) - newBounds.x; newBounds.width = (xOnScreen + dragRightOffset) - newBounds.x;
if( limitToParentBounds() ) {
int parentWidth = getParentBounds().width;
if( newBounds.x + newBounds.width > parentWidth )
newBounds.width = parentWidth - newBounds.x;
}
}
// apply minimum window size // apply minimum window size
Dimension minimumSize = honorMinimumSizeOnResize() ? getWindowMinimumSize() : null; Dimension minimumSize = honorMinimumSizeOnResize() ? getWindowMinimumSize() : null;
if( minimumSize == null ) if( minimumSize == null )
minimumSize = UIScale.scale( new Dimension( 150, 50 ) ); minimumSize = UIScale.scale( new Dimension( 150, 50 ) );
if( newBounds.width < minimumSize.width ) { if( newBounds.width < minimumSize.width )
if( newBounds.x != oldBounds.x ) changeWidth( oldBounds, newBounds, minimumSize.width );
newBounds.x -= (minimumSize.width - newBounds.width); if( newBounds.height < minimumSize.height )
newBounds.width = minimumSize.width; changeHeight( oldBounds, newBounds, minimumSize.height );
}
if( newBounds.height < minimumSize.height ) { // apply maximum window size
if( newBounds.y != oldBounds.y ) if( honorMaximumSizeOnResize() ) {
newBounds.y -= (minimumSize.height - newBounds.height); Dimension maximumSize = getWindowMaximumSize();
newBounds.height = minimumSize.height; if( newBounds.width > maximumSize.width )
changeWidth( oldBounds, newBounds, maximumSize.width );
if( newBounds.height > maximumSize.height )
changeHeight( oldBounds, newBounds, maximumSize.height );
} }
// set window bounds // set window bounds
if( !newBounds.equals( oldBounds ) ) if( !newBounds.equals( oldBounds ) )
setWindowBounds( newBounds ); setWindowBounds( newBounds );
} }
private void changeWidth( Rectangle oldBounds, Rectangle newBounds, int width ) {
if( newBounds.x != oldBounds.x )
newBounds.x -= (width - newBounds.width);
newBounds.width = width;
}
private void changeHeight( Rectangle oldBounds, Rectangle newBounds, int height ) {
if( newBounds.y != oldBounds.y )
newBounds.y -= (height - newBounds.height);
newBounds.height = height;
}
} }
} }

View File

@@ -25,6 +25,8 @@ import java.awt.Point;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.awt.Window; import java.awt.Window;
import java.awt.geom.AffineTransform; import java.awt.geom.AffineTransform;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Collections; import java.util.Collections;
import java.util.IdentityHashMap; import java.util.IdentityHashMap;
import java.util.List; import java.util.List;
@@ -289,6 +291,7 @@ class FlatWindowsNativeWindowBorder
//---- class WndProc ------------------------------------------------------ //---- class WndProc ------------------------------------------------------
private class WndProc private class WndProc
implements PropertyChangeListener
{ {
// WM_NCHITTEST mouse position codes // WM_NCHITTEST mouse position codes
private static final int private static final int
@@ -313,18 +316,36 @@ class FlatWindowsNativeWindowBorder
// remove the OS window title bar // remove the OS window title bar
updateFrame( hwnd, (window instanceof JFrame) ? ((JFrame)window).getExtendedState() : 0 ); updateFrame( hwnd, (window instanceof JFrame) ? ((JFrame)window).getExtendedState() : 0 );
// set window background (used when resizing window)
updateWindowBackground();
window.addPropertyChangeListener( "background", this );
} }
void uninstall() { void uninstall() {
window.removePropertyChangeListener( "background", this );
uninstallImpl( hwnd ); uninstallImpl( hwnd );
// cleanup // cleanup
window = null; window = null;
} }
@Override
public void propertyChange( PropertyChangeEvent e ) {
updateWindowBackground();
}
private void updateWindowBackground() {
Color bg = window.getBackground();
if( bg != null )
setWindowBackground( hwnd, bg.getRed(), bg.getGreen(), bg.getBlue() );
}
private native long installImpl( Window window ); private native long installImpl( Window window );
private native void uninstallImpl( long hwnd ); private native void uninstallImpl( long hwnd );
private native void updateFrame( long hwnd, int state ); private native void updateFrame( long hwnd, int state );
private native void setWindowBackground( long hwnd, int r, int g, int b );
private native void showWindow( long hwnd, int cmd ); private native void showWindow( long hwnd, int cmd );
// invoked from native code // invoked from native code

View File

@@ -0,0 +1,50 @@
/*
* 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 java.util.function.BiPredicate;
/**
* @author Karl Tauber
*/
class StackUtils
{
private static final StackUtils INSTANCE = new StackUtilsImpl();
// hide from javadoc
StackUtils() {
}
/**
* Checks whether current method was invoked from the given class and method.
*/
public static boolean wasInvokedFrom( String className, String methodName, int limit ) {
return wasInvokedFrom( (c,m) -> c.equals( className ) && m.equals( methodName ), limit );
}
/**
* Checks whether current method was invoked from a class and method using the given predicate,
* which gets the class name of the stack frame as first parameter and the method name as second parameter.
*/
public static boolean wasInvokedFrom( BiPredicate<String, String> predicate, int limit ) {
return INSTANCE.wasInvokedFromImpl( predicate, limit );
}
boolean wasInvokedFromImpl( BiPredicate<String, String> predicate, int limit ) {
throw new UnsupportedOperationException();
}
}

View File

@@ -0,0 +1,41 @@
/*
* 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 java.util.function.BiPredicate;
/**
* @author Karl Tauber
*/
class StackUtilsImpl
extends StackUtils
{
@Override
boolean wasInvokedFromImpl( BiPredicate<String, String> predicate, int limit ) {
int count = -2;
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
for( StackTraceElement stackTraceElement : stackTrace ) {
if( predicate.test( stackTraceElement.getClassName(), stackTraceElement.getMethodName() ) )
return true;
count++;
if( limit > 0 && count > limit )
return false;
}
return false;
}
}

View File

@@ -0,0 +1,37 @@
/*
* 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 java.util.function.BiPredicate;
/**
* @author Karl Tauber
*/
class StackUtilsImpl
extends StackUtils
{
@Override
boolean wasInvokedFromImpl( BiPredicate<String, String> predicate, int limit ) {
return StackWalker.getInstance().walk( stream -> {
if( limit > 0 )
stream = stream.limit( limit + 2 );
return stream.anyMatch( f -> {
return predicate.test( f.getClassName(), f.getMethodName() );
} );
} );
}
}

View File

@@ -514,6 +514,17 @@ ScrollPane.fillUpperCorner = true
ScrollPane.smoothScrolling = true ScrollPane.smoothScrolling = true
#---- SearchField ----
SearchField.searchIconColor = fadeout(Actions.GreyInline,10%,lazy)
SearchField.searchIconHoverColor = fadeout(Actions.GreyInline,30%,lazy)
SearchField.searchIconPressedColor = fadeout(Actions.GreyInline,50%,lazy)
SearchField.clearIconColor = fadeout(Actions.GreyInline,50%,lazy)
SearchField.clearIconHoverColor = $SearchField.clearIconColor
SearchField.clearIconPressedColor = fadeout(Actions.GreyInline,20%,lazy)
#---- Separator ---- #---- Separator ----
Separator.height = 3 Separator.height = 3
@@ -752,6 +763,7 @@ ToolBar.separatorWidth = 7
ToolBar.separatorColor = $Separator.foreground ToolBar.separatorColor = $Separator.foreground
ToolBar.spacingBorder = $Button.toolbar.spacingInsets ToolBar.spacingBorder = $Button.toolbar.spacingInsets
ToolBar.focusableButtons = false
#---- ToolTipManager ---- #---- ToolTipManager ----

View File

@@ -0,0 +1,203 @@
/*
* 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.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Insets;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.LineBorder;
import javax.swing.plaf.basic.BasicComboBoxEditor;
import javax.swing.plaf.basic.BasicComboBoxRenderer;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.MethodSource;
import com.formdev.flatlaf.util.UIScale;
/**
* @author Karl Tauber
*/
public class TestFlatComponentSizes
{
@BeforeAll
static void setup() {
TestUtils.setup( false );
}
@AfterAll
static void cleanup() {
TestUtils.cleanup();
}
static float[] factors() {
return TestUtils.FACTORS;
}
@ParameterizedTest
@MethodSource( "factors" )
void sizes( float factor ) {
TestUtils.scaleFont( factor );
// should have same default size (minimumWidth is 64)
JTextField textField = new JTextField();
JFormattedTextField formattedTextField = new JFormattedTextField();
JPasswordField passwordField = new JPasswordField();
JSpinner spinner = new JSpinner();
Dimension textFieldSize = textField.getPreferredSize();
assertEquals( textFieldSize, formattedTextField.getPreferredSize() );
assertEquals( textFieldSize, passwordField.getPreferredSize() );
assertEquals( textFieldSize, spinner.getPreferredSize() );
// should have same default size (minimumWidth is 72)
JButton button = new JButton( "text" );
JComboBox<String> comboBox = new JComboBox<>();
JComboBox<String> comboBoxEditable = new JComboBox<>();
comboBoxEditable.setEditable( true );
Dimension buttonSize = button.getPreferredSize();
assertEquals( buttonSize, comboBox.getPreferredSize() );
assertEquals( buttonSize, comboBoxEditable.getPreferredSize() );
// should have same height
JToggleButton toggleButton = new JToggleButton( "text" );
assertEquals( textFieldSize.height, button.getPreferredSize().height );
assertEquals( textFieldSize.height, toggleButton.getPreferredSize().height );
// should have same size
JCheckBox checkBox = new JCheckBox( "text" );
JRadioButton radioButton = new JRadioButton( "text" );
assertEquals( checkBox.getPreferredSize(), radioButton.getPreferredSize() );
// should have same size
JMenu menu = new JMenu( "text" );
JMenuItem menuItem = new JMenuItem( "text" );
JCheckBoxMenuItem checkBoxMenuItem = new JCheckBoxMenuItem( "text" );
JRadioButtonMenuItem radioButtonMenuItem = new JRadioButtonMenuItem( "text" );
Dimension menuSize = menu.getPreferredSize();
assertEquals( menuSize, menuItem.getPreferredSize() );
assertEquals( menuSize, checkBoxMenuItem.getPreferredSize() );
assertEquals( menuSize, radioButtonMenuItem.getPreferredSize() );
TestUtils.resetFont();
}
@ParameterizedTest
@MethodSource( "factors" )
void comboBox( float factor ) {
TestUtils.scaleFont( factor );
String[] items = { "t" };
JComboBox<String> comboBox = new JComboBox<>( items );
JComboBox<String> comboBox2 = new JComboBox<>( items );
JComboBox<String> comboBox3 = new JComboBox<>( items );
JComboBox<String> comboBox4 = new JComboBox<>( items );
applyCustomComboBoxRendererBorder( comboBox2, new LineBorder( Color.orange, UIScale.scale( 6 ) ) );
applyCustomComboBoxRendererBorder( comboBox3, new BorderWithIcon() );
applyCustomComboBoxRendererBorder( comboBox4, null );
Dimension size = comboBox.getPreferredSize();
assertEquals( size.width, comboBox2.getPreferredSize().width );
assertEquals( size.height - (2 * UIScale.scale( 2 )) + (2 * UIScale.scale( 6 )), comboBox2.getPreferredSize().height );
assertEquals( size, comboBox3.getPreferredSize() );
assertEquals( size, comboBox4.getPreferredSize() );
TestUtils.resetFont();
}
@SuppressWarnings( "unchecked" )
private void applyCustomComboBoxRendererBorder( JComboBox<String> comboBox, Border border ) {
BasicComboBoxRenderer customRenderer = new BasicComboBoxRenderer();
customRenderer.setBorder( border );
comboBox.setRenderer( customRenderer );
}
@ParameterizedTest
@MethodSource( "factors" )
void comboBoxEditable( float factor ) {
TestUtils.scaleFont( factor );
String[] items = { "t" };
JComboBox<String> comboBox = new JComboBox<>( items );
JComboBox<String> comboBox2 = new JComboBox<>( items );
JComboBox<String> comboBox3 = new JComboBox<>( items );
JComboBox<String> comboBox4 = new JComboBox<>( items );
comboBox.setEditable( true );
comboBox2.setEditable( true );
comboBox3.setEditable( true );
comboBox4.setEditable( true );
applyCustomComboBoxEditorBorder( comboBox2, new LineBorder( Color.orange, UIScale.scale( 6 ) ) );
applyCustomComboBoxEditorBorder( comboBox3, new BorderWithIcon() );
applyCustomComboBoxEditorBorder( comboBox4, null );
Dimension size = comboBox.getPreferredSize();
assertEquals( size.width, comboBox2.getPreferredSize().width );
assertEquals( size.height - (2 * UIScale.scale( 2 )) + (2 * UIScale.scale( 6 )), comboBox2.getPreferredSize().height );
assertEquals( size, comboBox3.getPreferredSize() );
assertEquals( size, comboBox4.getPreferredSize() );
TestUtils.resetFont();
}
private void applyCustomComboBoxEditorBorder( JComboBox<String> comboBox, Border border ) {
JTextField customTextField = new JTextField();
if( border != null )
customTextField.setBorder( border );
comboBox.setEditor( new BasicComboBoxEditor() {
@Override
protected JTextField createEditorComponent() {
return customTextField;
}
} );
}
//---- class BorderWithIcon -----------------------------------------------
private static class BorderWithIcon
implements Border
{
@Override
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
}
@Override
public boolean isBorderOpaque() {
return false;
}
@Override
public Insets getBorderInsets( Component c ) {
return new Insets( 0, 0, 0, UIScale.scale( 16 ) + 4 );
}
}
}

View File

@@ -0,0 +1,31 @@
/*
* 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 org.junit.jupiter.api.BeforeAll;
/**
* @author Karl Tauber
*/
public class TestFlatComponentSizesWithFocus
extends TestFlatComponentSizes
{
@BeforeAll
static void setup() {
TestUtils.setup( true );
}
}

View File

@@ -0,0 +1,53 @@
/*
* 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 java.awt.Font;
import javax.swing.UIManager;
import com.formdev.flatlaf.FlatIntelliJLaf;
import com.formdev.flatlaf.FlatLightLaf;
import com.formdev.flatlaf.FlatSystemProperties;
/**
* @author Karl Tauber
*/
public class TestUtils
{
public static final float[] FACTORS = new float[] { 1f, 1.25f, 1.5f, 1.75f, 2f, 2.25f, 2.5f, 2.75f, 3f, 3.25f, 3.5f, 3.75f, 4f, 5f, 6f };
public static void setup( boolean withFocus ) {
System.setProperty( FlatSystemProperties.UI_SCALE, "1x" );
if( withFocus )
FlatIntelliJLaf.setup();
else
FlatLightLaf.setup();
System.clearProperty( FlatSystemProperties.UI_SCALE );
}
public static void cleanup() {
UIManager.put( "defaultFont", null );
}
public static void scaleFont( float factor ) {
Font defaultFont = UIManager.getLookAndFeelDefaults().getFont( "defaultFont" );
UIManager.put( "defaultFont", defaultFont.deriveFont( (float) Math.round( defaultFont.getSize() * factor ) ) );
}
public static void resetFont() {
UIManager.put( "defaultFont", null );
}
}

View File

@@ -1,7 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"> <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<g fill="none" fill-rule="evenodd"> <g fill="none" fill-rule="evenodd">
<rect width="16" height="16" fill="#6E6E6E" rx="3"/> <rect width="16" height="16" fill="#6E6E6E" rx="3"/>
<rect width="6" height="2" x="5" y="12" fill="#FFF"/> <rect width="6" height="2" x="5" y="11.5" fill="#FFF"/>
<path fill="#FFF" d="M2,8 L8,2 L14,8 L11,8 L11,10 L5,10 L5,8 L2,8 Z"/> <path fill="#FFF" d="M2,8 L8,2 L14,8 L11,8 L11,10 L5,10 L5,8 L2,8 Z"/>
</g> </g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 326 B

After

Width:  |  Height:  |  Size: 328 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<path fill="#7F8B91" fill-opacity=".5" fill-rule="evenodd" d="M8,1.75 C11.4517797,1.75 14.25,4.54822031 14.25,8 C14.25,11.4517797 11.4517797,14.25 8,14.25 C4.54822031,14.25 1.75,11.4517797 1.75,8 C1.75,4.54822031 4.54822031,1.75 8,1.75 Z M10.5,4.5 L8,7 L5.5,4.5 L4.5,5.5 L7,8 L4.5,10.5 L5.5,11.5 L8,9 L10.5,11.5 L11.5,10.5 L9,8 L11.5,5.5 L10.5,4.5 Z"/>
</svg>

After

Width:  |  Height:  |  Size: 446 B

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<path fill="none" stroke="#7F8B91" stroke-linecap="square" stroke-opacity=".5" d="M5,5 L11,11 M5,11 L11,5"/>
</svg>

After

Width:  |  Height:  |  Size: 202 B

View File

@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<g fill="none" fill-opacity=".9" fill-rule="evenodd">
<polygon fill="#7F8B91" points="10.813 9.75 14 12.938 12.938 14 9.75 10.813"/>
<path fill="#7F8B91" d="M7,2 C9.76142375,2 12,4.23857625 12,7 C12,9.76142375 9.76142375,12 7,12 C4.23857625,12 2,9.76142375 2,7 C2,4.23857625 4.23857625,2 7,2 Z M7,3 C4.790861,3 3,4.790861 3,7 C3,9.209139 4.790861,11 7,11 C9.209139,11 11,9.209139 11,7 C11,4.790861 9.209139,3 7,3 Z"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 526 B

View File

@@ -0,0 +1,7 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<g fill="none" fill-opacity=".9" fill-rule="evenodd">
<polygon fill="#7F8B91" points="8.813 9.75 12 12.938 10.938 14 7.75 10.813"/>
<path fill="#7F8B91" d="M5,2 C7.76142375,2 10,4.23857625 10,7 C10,9.76142375 7.76142375,12 5,12 C2.23857625,12 0,9.76142375 0,7 C0,4.23857625 2.23857625,2 5,2 Z M5,3 C2.790861,3 1,4.790861 1,7 C1,9.209139 2.790861,11 5,11 C7.209139,11 9,9.209139 9,7 C9,4.790861 7.209139,3 5,3 Z"/>
<polygon fill="#7F8B91" points="11 7 16 7 13.5 10"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 579 B

View File

@@ -28,6 +28,7 @@ import javax.swing.plaf.metal.MetalLookAndFeel;
import javax.swing.plaf.nimbus.NimbusLookAndFeel; import javax.swing.plaf.nimbus.NimbusLookAndFeel;
import com.formdev.flatlaf.*; import com.formdev.flatlaf.*;
import com.formdev.flatlaf.extras.FlatAnimatedLafChange; import com.formdev.flatlaf.extras.FlatAnimatedLafChange;
import com.formdev.flatlaf.util.LoggingFacade;
import com.formdev.flatlaf.util.SystemInfo; import com.formdev.flatlaf.util.SystemInfo;
import com.formdev.flatlaf.util.UIScale; import com.formdev.flatlaf.util.UIScale;
import net.miginfocom.layout.ConstraintParser; import net.miginfocom.layout.ConstraintParser;
@@ -240,7 +241,7 @@ class ControlBar
frame.setSize( Math.max( prefSize.width, width ), Math.max( prefSize.height, height ) ); frame.setSize( Math.max( prefSize.width, width ), Math.max( prefSize.height, height ) );
} catch( Exception ex ) { } catch( Exception ex ) {
ex.printStackTrace(); LoggingFacade.INSTANCE.logSevere( null, ex );
} }
} ); } );
} }

View File

@@ -34,6 +34,7 @@ import com.formdev.flatlaf.extras.FlatUIDefaultsInspector;
import com.formdev.flatlaf.extras.components.FlatButton; import com.formdev.flatlaf.extras.components.FlatButton;
import com.formdev.flatlaf.extras.components.FlatButton.ButtonType; import com.formdev.flatlaf.extras.components.FlatButton.ButtonType;
import com.formdev.flatlaf.extras.FlatSVGUtils; import com.formdev.flatlaf.extras.FlatSVGUtils;
import com.formdev.flatlaf.ui.FlatUIUtils;
import com.formdev.flatlaf.ui.JBRCustomDecorations; import com.formdev.flatlaf.ui.JBRCustomDecorations;
import com.formdev.flatlaf.util.SystemInfo; import com.formdev.flatlaf.util.SystemInfo;
import net.miginfocom.layout.ConstraintParser; import net.miginfocom.layout.ConstraintParser;
@@ -185,6 +186,8 @@ class DemoFrame
Font font = UIManager.getFont( "defaultFont" ); Font font = UIManager.getFont( "defaultFont" );
Font newFont = StyleContext.getDefaultStyleContext().getFont( fontFamily, font.getStyle(), font.getSize() ); Font newFont = StyleContext.getDefaultStyleContext().getFont( fontFamily, font.getStyle(), font.getSize() );
// StyleContext.getFont() may return a UIResource, which would cause loosing user scale factor on Windows
newFont = FlatUIUtils.nonUIResource( newFont );
UIManager.put( "defaultFont", newFont ); UIManager.put( "defaultFont", newFont );
FlatLaf.updateUI(); FlatLaf.updateUI();

View File

@@ -25,6 +25,7 @@ import com.formdev.flatlaf.FlatLightLaf;
import com.formdev.flatlaf.FlatPropertiesLaf; import com.formdev.flatlaf.FlatPropertiesLaf;
import com.formdev.flatlaf.IntelliJTheme; import com.formdev.flatlaf.IntelliJTheme;
import com.formdev.flatlaf.demo.intellijthemes.IJThemesPanel; import com.formdev.flatlaf.demo.intellijthemes.IJThemesPanel;
import com.formdev.flatlaf.util.LoggingFacade;
import com.formdev.flatlaf.util.StringUtils; import com.formdev.flatlaf.util.StringUtils;
/** /**
@@ -83,7 +84,7 @@ public class DemoPrefs
UIManager.setLookAndFeel( lafClassName ); UIManager.setLookAndFeel( lafClassName );
} }
} catch( Throwable ex ) { } catch( Throwable ex ) {
ex.printStackTrace(); LoggingFacade.INSTANCE.logSevere( null, ex );
// fallback // fallback
FlatLightLaf.setup(); FlatLightLaf.setup();

View File

@@ -22,6 +22,7 @@ import java.nio.charset.StandardCharsets;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.StandardOpenOption; import java.nio.file.StandardOpenOption;
import com.formdev.flatlaf.util.LoggingFacade;
/** /**
* This tool creates look and feel classes for all themes listed in themes.json. * This tool creates look and feel classes for all themes listed in themes.json.
@@ -120,7 +121,7 @@ public class IJThemesClassGenerator
Files.write( out, content.getBytes( StandardCharsets.ISO_8859_1 ), Files.write( out, content.getBytes( StandardCharsets.ISO_8859_1 ),
StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING ); StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING );
} catch( IOException ex ) { } catch( IOException ex ) {
ex.printStackTrace(); LoggingFacade.INSTANCE.logSevere( null, ex );
} }
} }

View File

@@ -26,6 +26,7 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import com.formdev.flatlaf.json.Json; import com.formdev.flatlaf.json.Json;
import com.formdev.flatlaf.util.LoggingFacade;
import com.formdev.flatlaf.util.StringUtils; import com.formdev.flatlaf.util.StringUtils;
/** /**
@@ -46,7 +47,7 @@ class IJThemesManager
try( Reader reader = new InputStreamReader( getClass().getResourceAsStream( "themes.json" ), StandardCharsets.UTF_8 ) ) { try( Reader reader = new InputStreamReader( getClass().getResourceAsStream( "themes.json" ), StandardCharsets.UTF_8 ) ) {
json = (Map<String, Object>) Json.parse( reader ); json = (Map<String, Object>) Json.parse( reader );
} catch( IOException ex ) { } catch( IOException ex ) {
ex.printStackTrace(); LoggingFacade.INSTANCE.logSevere( null, ex );
return; return;
} }

View File

@@ -52,6 +52,7 @@ import com.formdev.flatlaf.IntelliJTheme;
import com.formdev.flatlaf.demo.DemoPrefs; import com.formdev.flatlaf.demo.DemoPrefs;
import com.formdev.flatlaf.extras.FlatAnimatedLafChange; import com.formdev.flatlaf.extras.FlatAnimatedLafChange;
import com.formdev.flatlaf.extras.FlatSVGIcon; import com.formdev.flatlaf.extras.FlatSVGIcon;
import com.formdev.flatlaf.util.LoggingFacade;
import com.formdev.flatlaf.util.StringUtils; import com.formdev.flatlaf.util.StringUtils;
import net.miginfocom.swing.*; import net.miginfocom.swing.*;
@@ -259,7 +260,7 @@ public class IJThemesPanel
try { try {
UIManager.setLookAndFeel( themeInfo.lafClassName ); UIManager.setLookAndFeel( themeInfo.lafClassName );
} catch( Exception ex ) { } catch( Exception ex ) {
ex.printStackTrace(); LoggingFacade.INSTANCE.logSevere( null, ex );
showInformationDialog( "Failed to create '" + themeInfo.lafClassName + "'.", ex ); showInformationDialog( "Failed to create '" + themeInfo.lafClassName + "'.", ex );
} }
} else if( themeInfo.themeFile != null ) { } else if( themeInfo.themeFile != null ) {
@@ -273,7 +274,7 @@ public class IJThemesPanel
DemoPrefs.getState().put( DemoPrefs.KEY_LAF_THEME, DemoPrefs.FILE_PREFIX + themeInfo.themeFile ); DemoPrefs.getState().put( DemoPrefs.KEY_LAF_THEME, DemoPrefs.FILE_PREFIX + themeInfo.themeFile );
} catch( Exception ex ) { } catch( Exception ex ) {
ex.printStackTrace(); LoggingFacade.INSTANCE.logSevere( null, ex );
showInformationDialog( "Failed to load '" + themeInfo.themeFile + "'.", ex ); showInformationDialog( "Failed to load '" + themeInfo.themeFile + "'.", ex );
} }
} else { } else {

View File

@@ -23,6 +23,7 @@ import java.net.URLConnection;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.StandardCopyOption; import java.nio.file.StandardCopyOption;
import com.formdev.flatlaf.util.LoggingFacade;
/** /**
* This tool updates all IntelliJ themes listed in themes.json by downloading * This tool updates all IntelliJ themes listed in themes.json by downloading
@@ -61,7 +62,7 @@ public class IJThemesUpdater
URLConnection con = url.openConnection(); URLConnection con = url.openConnection();
Files.copy( con.getInputStream(), out, StandardCopyOption.REPLACE_EXISTING ); Files.copy( con.getInputStream(), out, StandardCopyOption.REPLACE_EXISTING );
} catch( IOException ex ) { } catch( IOException ex ) {
ex.printStackTrace(); LoggingFacade.INSTANCE.logSevere( null, ex );
} }
} }
} }

View File

@@ -42,6 +42,7 @@ import com.formdev.flatlaf.FlatLaf.DisabledIconProvider;
import com.formdev.flatlaf.ui.FlatUIUtils; import com.formdev.flatlaf.ui.FlatUIUtils;
import com.formdev.flatlaf.util.Graphics2DProxy; import com.formdev.flatlaf.util.Graphics2DProxy;
import com.formdev.flatlaf.util.GrayFilter; import com.formdev.flatlaf.util.GrayFilter;
import com.formdev.flatlaf.util.LoggingFacade;
import com.formdev.flatlaf.util.MultiResolutionImageSupport; import com.formdev.flatlaf.util.MultiResolutionImageSupport;
import com.formdev.flatlaf.util.UIScale; import com.formdev.flatlaf.util.UIScale;
import com.kitfox.svg.SVGDiagram; import com.kitfox.svg.SVGDiagram;
@@ -335,7 +336,7 @@ public class FlatSVGIcon
try { try {
diagram = svgUniverse.getDiagram( url.toURI() ); diagram = svgUniverse.getDiagram( url.toURI() );
} catch( URISyntaxException ex ) { } catch( URISyntaxException ex ) {
ex.printStackTrace(); LoggingFacade.INSTANCE.logSevere( "FlatLaf: Failed to load SVG icon '" + url + "'.", ex );
} }
} }

View File

@@ -52,6 +52,7 @@ import com.formdev.flatlaf.ui.FlatUIUtils;
import com.formdev.flatlaf.util.DerivedColor; import com.formdev.flatlaf.util.DerivedColor;
import com.formdev.flatlaf.util.GrayFilter; import com.formdev.flatlaf.util.GrayFilter;
import com.formdev.flatlaf.util.HSLColor; import com.formdev.flatlaf.util.HSLColor;
import com.formdev.flatlaf.util.LoggingFacade;
import com.formdev.flatlaf.util.ScaledEmptyBorder; import com.formdev.flatlaf.util.ScaledEmptyBorder;
import com.formdev.flatlaf.util.UIScale; import com.formdev.flatlaf.util.UIScale;
@@ -377,11 +378,12 @@ public class FlatUIDefaultsInspector
} }
private Properties loadDerivedColorKeys() { private Properties loadDerivedColorKeys() {
String name = "/com/formdev/flatlaf/extras/resources/DerivedColorKeys.properties";
Properties properties = new Properties(); Properties properties = new Properties();
try( InputStream in = getClass().getResourceAsStream( "/com/formdev/flatlaf/extras/resources/DerivedColorKeys.properties" ) ) { try( InputStream in = getClass().getResourceAsStream( name ) ) {
properties.load( in ); properties.load( in );
} catch( IOException ex ) { } catch( IOException ex ) {
ex.printStackTrace(); LoggingFacade.INSTANCE.logSevere( "FlatLaf: Failed to load '" + name + "'.", ex );
} }
return properties; return properties;
} }

View File

@@ -20,6 +20,7 @@ import java.awt.Color;
import java.awt.Insets; import java.awt.Insets;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.UIManager; import javax.swing.UIManager;
import com.formdev.flatlaf.util.LoggingFacade;
/** /**
* Base interface for all FlatLaf component extensions. * Base interface for all FlatLaf component extensions.
@@ -87,7 +88,7 @@ public interface FlatComponentExtension
try { try {
return Enum.valueOf( enumType, (String) value ); return Enum.valueOf( enumType, (String) value );
} catch( IllegalArgumentException ex ) { } catch( IllegalArgumentException ex ) {
ex.printStackTrace(); LoggingFacade.INSTANCE.logSevere( "FlatLaf: Unknown enum value '" + value + "' in enum '" + enumType.getName() + "'.", ex );
} }
} }
return defaultValue; return defaultValue;

View File

@@ -18,6 +18,7 @@ package com.formdev.flatlaf.extras.components;
import static com.formdev.flatlaf.FlatClientProperties.*; import static com.formdev.flatlaf.FlatClientProperties.*;
import java.awt.Color; import java.awt.Color;
import java.awt.Insets;
import javax.swing.JFormattedTextField; import javax.swing.JFormattedTextField;
import com.formdev.flatlaf.extras.components.FlatTextField.SelectAllOnFocusPolicy; import com.formdev.flatlaf.extras.components.FlatTextField.SelectAllOnFocusPolicy;
@@ -61,6 +62,27 @@ public class FlatFormattedTextField
} }
/**
* Returns the padding of the text.
*
* @since 1.4
*/
public Insets getPadding() {
return (Insets) getClientProperty( TEXT_FIELD_PADDING );
}
/**
* Specifies the padding of the text.
* This changes the location and size of the text view within the component bounds,
* but does not affect the size of the component.
*
* @since 1.4
*/
public void setPadding( Insets padding ) {
putClientProperty( TEXT_FIELD_PADDING, padding );
}
/** /**
* Returns minimum width of a component. * Returns minimum width of a component.
*/ */

View File

@@ -18,6 +18,7 @@ package com.formdev.flatlaf.extras.components;
import static com.formdev.flatlaf.FlatClientProperties.*; import static com.formdev.flatlaf.FlatClientProperties.*;
import java.awt.Color; import java.awt.Color;
import java.awt.Insets;
import javax.swing.JPasswordField; import javax.swing.JPasswordField;
import com.formdev.flatlaf.extras.components.FlatTextField.SelectAllOnFocusPolicy; import com.formdev.flatlaf.extras.components.FlatTextField.SelectAllOnFocusPolicy;
@@ -61,6 +62,27 @@ public class FlatPasswordField
} }
/**
* Returns the padding of the text.
*
* @since 1.4
*/
public Insets getPadding() {
return (Insets) getClientProperty( TEXT_FIELD_PADDING );
}
/**
* Specifies the padding of the text.
* This changes the location and size of the text view within the component bounds,
* but does not affect the size of the component.
*
* @since 1.4
*/
public void setPadding( Insets padding ) {
putClientProperty( TEXT_FIELD_PADDING, padding );
}
/** /**
* Returns minimum width of a component. * Returns minimum width of a component.
*/ */

View File

@@ -18,6 +18,7 @@ package com.formdev.flatlaf.extras.components;
import static com.formdev.flatlaf.FlatClientProperties.*; import static com.formdev.flatlaf.FlatClientProperties.*;
import java.awt.Color; import java.awt.Color;
import java.awt.Insets;
import javax.swing.JTextField; import javax.swing.JTextField;
/** /**
@@ -63,6 +64,27 @@ public class FlatTextField
} }
/**
* Returns the padding of the text.
*
* @since 1.4
*/
public Insets getPadding() {
return (Insets) getClientProperty( TEXT_FIELD_PADDING );
}
/**
* Specifies the padding of the text.
* This changes the location and size of the text view within the component bounds,
* but does not affect the size of the component.
*
* @since 1.4
*/
public void setPadding( Insets padding ) {
putClientProperty( TEXT_FIELD_PADDING, padding );
}
/** /**
* Returns minimum width of a component. * Returns minimum width of a component.
*/ */

View File

@@ -28,6 +28,8 @@ import java.awt.Point;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.awt.Window; import java.awt.Window;
import java.awt.geom.AffineTransform; import java.awt.geom.AffineTransform;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Collections; import java.util.Collections;
import java.util.IdentityHashMap; import java.util.IdentityHashMap;
import java.util.List; import java.util.List;
@@ -47,6 +49,7 @@ import com.sun.jna.Structure.FieldOrder;
import com.sun.jna.platform.win32.Advapi32Util; import com.sun.jna.platform.win32.Advapi32Util;
import com.sun.jna.platform.win32.BaseTSD; import com.sun.jna.platform.win32.BaseTSD;
import com.sun.jna.platform.win32.BaseTSD.ULONG_PTR; import com.sun.jna.platform.win32.BaseTSD.ULONG_PTR;
import com.sun.jna.platform.win32.GDI32;
import com.sun.jna.platform.win32.Shell32; import com.sun.jna.platform.win32.Shell32;
import com.sun.jna.platform.win32.User32; import com.sun.jna.platform.win32.User32;
import com.sun.jna.platform.win32.WTypes.LPWSTR; import com.sun.jna.platform.win32.WTypes.LPWSTR;
@@ -282,11 +285,12 @@ public class FlatWindowsNativeWindowBorder
//---- class WndProc ------------------------------------------------------ //---- class WndProc ------------------------------------------------------
private class WndProc private class WndProc
implements WindowProc implements WindowProc, PropertyChangeListener
{ {
private static final int GWLP_WNDPROC = -4; private static final int GWLP_WNDPROC = -4;
private static final int private static final int
WM_ERASEBKGND = 0x0014,
WM_NCCALCSIZE = 0x0083, WM_NCCALCSIZE = 0x0083,
WM_NCHITTEST = 0x0084, WM_NCHITTEST = 0x0084,
WM_NCRBUTTONUP = 0x00A5, WM_NCRBUTTONUP = 0x00A5,
@@ -326,6 +330,7 @@ public class FlatWindowsNativeWindowBorder
private final HWND hwnd; private final HWND hwnd;
private final BaseTSD.LONG_PTR defaultWndProc; private final BaseTSD.LONG_PTR defaultWndProc;
private int wmSizeWParam = -1; private int wmSizeWParam = -1;
private HBRUSH background;
private int titleBarHeight; private int titleBarHeight;
private Rectangle[] hitTestSpots; private Rectangle[] hitTestSpots;
@@ -345,9 +350,15 @@ public class FlatWindowsNativeWindowBorder
// remove the OS window title bar // remove the OS window title bar
updateFrame( (window instanceof JFrame) ? ((JFrame)window).getExtendedState() : 0 ); updateFrame( (window instanceof JFrame) ? ((JFrame)window).getExtendedState() : 0 );
// set window background (used when resizing window)
updateWindowBackground();
window.addPropertyChangeListener( "background", this );
} }
void uninstall() { void uninstall() {
window.removePropertyChangeListener( "background", this );
// restore original window procedure // restore original window procedure
if( SystemInfo.isX86_64 ) if( SystemInfo.isX86_64 )
User32Ex.INSTANCE.SetWindowLongPtr( hwnd, GWLP_WNDPROC, defaultWndProc ); User32Ex.INSTANCE.SetWindowLongPtr( hwnd, GWLP_WNDPROC, defaultWndProc );
@@ -358,6 +369,8 @@ public class FlatWindowsNativeWindowBorder
updateFrame( 0 ); updateFrame( 0 );
// cleanup // cleanup
if( background != null )
GDI32.INSTANCE.DeleteObject( background );
window = null; window = null;
} }
@@ -382,6 +395,26 @@ public class FlatWindowsNativeWindowBorder
wmSizeWParam = -1; wmSizeWParam = -1;
} }
@Override
public void propertyChange( PropertyChangeEvent evt ) {
updateWindowBackground();
}
private void updateWindowBackground() {
Color bg = window.getBackground();
if( bg != null )
setWindowBackground( bg.getRed(), bg.getGreen(), bg.getBlue() );
}
private void setWindowBackground( int r, int g, int b ) {
// delete old background brush
if( background != null )
GDI32.INSTANCE.DeleteObject( background );
// create new background brush
background = GDI32Ex.INSTANCE.CreateSolidBrush( RGB( r, g, b ) );
}
/** /**
* NOTE: This method is invoked on the AWT-Windows thread (not the AWT-EventQueue thread). * NOTE: This method is invoked on the AWT-Windows thread (not the AWT-EventQueue thread).
*/ */
@@ -408,6 +441,9 @@ public class FlatWindowsNativeWindowBorder
wParam = new WPARAM( wmSizeWParam ); wParam = new WPARAM( wmSizeWParam );
break; break;
case WM_ERASEBKGND:
return WmEraseBkgnd( hwnd, uMsg, wParam, lParam );
case WM_DESTROY: case WM_DESTROY:
return WmDestroy( hwnd, uMsg, wParam, lParam ); return WmDestroy( hwnd, uMsg, wParam, lParam );
} }
@@ -432,11 +468,30 @@ public class FlatWindowsNativeWindowBorder
// cleanup // cleanup
windowsMap.remove( window ); windowsMap.remove( window );
if( background != null )
GDI32.INSTANCE.DeleteObject( background );
window = null; window = null;
return lResult; return lResult;
} }
/**
* Handle WM_ERASEBKGND
*
* https://docs.microsoft.com/en-us/windows/win32/winmsg/wm-erasebkgnd
*/
LRESULT WmEraseBkgnd( HWND hwnd, int uMsg, WPARAM wParam, LPARAM lParam ) {
if( background == null )
return new LRESULT( 0 );
// fill background
HDC hdc = new HDC( wParam.toPointer() );
RECT rect = new RECT();
User32.INSTANCE.GetClientRect( hwnd, rect );
User32Ex.INSTANCE.FillRect( hdc, rect, background );
return new LRESULT( 1 );
}
/** /**
* Handle WM_NCCALCSIZE * Handle WM_NCCALCSIZE
* *
@@ -637,6 +692,13 @@ public class FlatWindowsNativeWindowBorder
return (short) ((lParam.longValue() >> 16) & 0xffff); return (short) ((lParam.longValue() >> 16) & 0xffff);
} }
/**
* Same implementation as RGB(r,g,b) macro in wingdi.h.
*/
private DWORD RGB( int r, int g, int b ) {
return new DWORD( (r & 0xff) | ((g & 0xff) << 8) | ((b & 0xff) << 16) );
}
/** /**
* Opens the window's system menu. * Opens the window's system menu.
* The system menu is the menu that opens when the user presses Alt+Space or * The system menu is the menu that opens when the user presses Alt+Space or
@@ -690,6 +752,8 @@ public class FlatWindowsNativeWindowBorder
LONG_PTR SetWindowLong( HWND hWnd, int nIndex, LONG_PTR wndProc ); LONG_PTR SetWindowLong( HWND hWnd, int nIndex, LONG_PTR wndProc );
LRESULT CallWindowProc( LONG_PTR lpPrevWndFunc, HWND hWnd, int uMsg, WPARAM wParam, LPARAM lParam ); LRESULT CallWindowProc( LONG_PTR lpPrevWndFunc, HWND hWnd, int uMsg, WPARAM wParam, LPARAM lParam );
int FillRect( HDC hDC, RECT lprc, HBRUSH hbr );
int GetDpiForWindow( HWND hwnd ); int GetDpiForWindow( HWND hwnd );
int GetSystemMetricsForDpi( int nIndex, int dpi ); int GetSystemMetricsForDpi( int nIndex, int dpi );
@@ -702,6 +766,16 @@ public class FlatWindowsNativeWindowBorder
BOOL TrackPopupMenu( HMENU hMenu, int uFlags, int x, int y, int nReserved, HWND hWnd, RECT prcRect ); BOOL TrackPopupMenu( HMENU hMenu, int uFlags, int x, int y, int nReserved, HWND hWnd, RECT prcRect );
} }
//---- interface GDI32Ex --------------------------------------------------
private interface GDI32Ex
extends GDI32
{
GDI32Ex INSTANCE = Native.load( "gdi32", GDI32Ex.class, W32APIOptions.DEFAULT_OPTIONS );
HBRUSH CreateSolidBrush( DWORD color );
}
//---- class NCCALCSIZE_PARAMS -------------------------------------------- //---- class NCCALCSIZE_PARAMS --------------------------------------------
@FieldOrder( { "rgrc" } ) @FieldOrder( { "rgrc" } )

View File

@@ -73,8 +73,8 @@ library {
linkerArgs.addAll( toolChain.map { linkerArgs.addAll( toolChain.map {
when( it ) { when( it ) {
is Gcc, is Clang -> listOf( "-l${jawt}", "-lUser32", "-lshell32", "-lAdvAPI32", "-lKernel32" ) is Gcc, is Clang -> listOf( "-l${jawt}", "-lUser32", "-lGdi32", "-lshell32", "-lAdvAPI32", "-lKernel32" )
is VisualCpp -> listOf( "${jawt}.lib", "User32.lib", "shell32.lib", "AdvAPI32.lib", "Kernel32.lib", "/NODEFAULTLIB" ) is VisualCpp -> listOf( "${jawt}.lib", "User32.lib", "Gdi32.lib", "shell32.lib", "AdvAPI32.lib", "Kernel32.lib", "/NODEFAULTLIB" )
else -> emptyList() else -> emptyList()
} }
} ) } )

View File

@@ -52,6 +52,13 @@ JNIEXPORT void JNICALL Java_com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder
FlatWndProc::updateFrame( reinterpret_cast<HWND>( hwnd ), state ); FlatWndProc::updateFrame( reinterpret_cast<HWND>( hwnd ), state );
} }
extern "C"
JNIEXPORT void JNICALL Java_com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_00024WndProc_setWindowBackground
( JNIEnv* env, jobject obj, jlong hwnd, jint r, jint g, jint b )
{
FlatWndProc::setWindowBackground( reinterpret_cast<HWND>( hwnd ), r, g, b );
}
extern "C" extern "C"
JNIEXPORT void JNICALL Java_com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_00024WndProc_showWindow JNIEXPORT void JNICALL Java_com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_00024WndProc_showWindow
( JNIEnv* env, jobject obj, jlong hwnd, jint cmd ) ( JNIEnv* env, jobject obj, jlong hwnd, jint cmd )
@@ -80,6 +87,7 @@ FlatWndProc::FlatWndProc() {
hwnd = NULL; hwnd = NULL;
defaultWndProc = NULL; defaultWndProc = NULL;
wmSizeWParam = -1; wmSizeWParam = -1;
background = NULL;
} }
HWND FlatWndProc::install( JNIEnv *env, jobject obj, jobject window ) { HWND FlatWndProc::install( JNIEnv *env, jobject obj, jobject window ) {
@@ -128,6 +136,8 @@ void FlatWndProc::uninstall( JNIEnv *env, jobject obj, HWND hwnd ) {
// cleanup // cleanup
env->DeleteGlobalRef( fwp->obj ); env->DeleteGlobalRef( fwp->obj );
if( fwp->background != NULL )
::DeleteObject( fwp->background );
delete fwp; delete fwp;
} }
@@ -174,8 +184,23 @@ void FlatWndProc::updateFrame( HWND hwnd, int state ) {
fwp->wmSizeWParam = -1; fwp->wmSizeWParam = -1;
} }
void FlatWndProc::setWindowBackground( HWND hwnd, int r, int g, int b ) {
FlatWndProc* fwp = (FlatWndProc*) hwndMap->get( hwnd );
if( fwp == NULL )
return;
// delete old background brush
if( fwp->background != NULL )
::DeleteObject( fwp->background );
// create new background brush
fwp->background = ::CreateSolidBrush( RGB( r, g, b ) );
}
LRESULT CALLBACK FlatWndProc::StaticWindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) { LRESULT CALLBACK FlatWndProc::StaticWindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ) {
FlatWndProc* fwp = (FlatWndProc*) hwndMap->get( hwnd ); FlatWndProc* fwp = (FlatWndProc*) hwndMap->get( hwnd );
if( fwp == NULL )
return 0;
return fwp->WindowProc( hwnd, uMsg, wParam, lParam ); return fwp->WindowProc( hwnd, uMsg, wParam, lParam );
} }
@@ -204,12 +229,16 @@ LRESULT CALLBACK FlatWndProc::WindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, L
wParam = wmSizeWParam; wParam = wmSizeWParam;
break; break;
case WM_ERASEBKGND:
return WmEraseBkgnd( hwnd, uMsg, wParam, lParam );
case WM_DESTROY: case WM_DESTROY:
return WmDestroy( hwnd, uMsg, wParam, lParam ); return WmDestroy( hwnd, uMsg, wParam, lParam );
} }
return ::CallWindowProc( defaultWndProc, hwnd, uMsg, wParam, lParam ); return ::CallWindowProc( defaultWndProc, hwnd, uMsg, wParam, lParam );
} }
/** /**
* Handle WM_DESTROY * Handle WM_DESTROY
* *
@@ -223,6 +252,8 @@ LRESULT FlatWndProc::WmDestroy( HWND hwnd, int uMsg, WPARAM wParam, LPARAM lPara
// cleanup // cleanup
getEnv()->DeleteGlobalRef( obj ); getEnv()->DeleteGlobalRef( obj );
if( background != NULL )
::DeleteObject( background );
hwndMap->remove( hwnd ); hwndMap->remove( hwnd );
delete this; delete this;
@@ -230,6 +261,23 @@ LRESULT FlatWndProc::WmDestroy( HWND hwnd, int uMsg, WPARAM wParam, LPARAM lPara
return ::CallWindowProc( defaultWndProc2, hwnd, uMsg, wParam, lParam ); return ::CallWindowProc( defaultWndProc2, hwnd, uMsg, wParam, lParam );
} }
/**
* Handle WM_ERASEBKGND
*
* https://docs.microsoft.com/en-us/windows/win32/winmsg/wm-erasebkgnd
*/
LRESULT FlatWndProc::WmEraseBkgnd( HWND hwnd, int uMsg, WPARAM wParam, LPARAM lParam ) {
if( background == NULL )
return FALSE;
// fill background
HDC hdc = (HDC) wParam;
RECT rect;
::GetClientRect( hwnd, &rect );
::FillRect( hdc, &rect, background );
return TRUE;
}
/** /**
* Handle WM_NCCALCSIZE * Handle WM_NCCALCSIZE
* *

View File

@@ -26,6 +26,7 @@ public:
static HWND install( JNIEnv *env, jobject obj, jobject window ); static HWND install( JNIEnv *env, jobject obj, jobject window );
static void uninstall( JNIEnv *env, jobject obj, HWND hwnd ); static void uninstall( JNIEnv *env, jobject obj, HWND hwnd );
static void updateFrame( HWND hwnd, int state ); static void updateFrame( HWND hwnd, int state );
static void setWindowBackground( HWND hwnd, int r, int g, int b );
private: private:
static int initialized; static int initialized;
@@ -41,6 +42,7 @@ private:
HWND hwnd; HWND hwnd;
WNDPROC defaultWndProc; WNDPROC defaultWndProc;
int wmSizeWParam; int wmSizeWParam;
HBRUSH background;
FlatWndProc(); FlatWndProc();
static void initIDs( JNIEnv *env, jobject obj ); static void initIDs( JNIEnv *env, jobject obj );
@@ -48,6 +50,7 @@ private:
static LRESULT CALLBACK StaticWindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); static LRESULT CALLBACK StaticWindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
LRESULT CALLBACK WindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam ); LRESULT CALLBACK WindowProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam );
LRESULT WmDestroy( HWND hwnd, int uMsg, WPARAM wParam, LPARAM lParam ); LRESULT WmDestroy( HWND hwnd, int uMsg, WPARAM wParam, LPARAM lParam );
LRESULT WmEraseBkgnd( HWND hwnd, int uMsg, WPARAM wParam, LPARAM lParam );
LRESULT WmNcCalcSize( HWND hwnd, int uMsg, WPARAM wParam, LPARAM lParam ); LRESULT WmNcCalcSize( HWND hwnd, int uMsg, WPARAM wParam, LPARAM lParam );
LRESULT WmNcHitTest( HWND hwnd, int uMsg, WPARAM wParam, LPARAM lParam ); LRESULT WmNcHitTest( HWND hwnd, int uMsg, WPARAM wParam, LPARAM lParam );

View File

@@ -39,6 +39,14 @@ JNIEXPORT void JNICALL Java_com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder
JNIEXPORT void JNICALL Java_com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_00024WndProc_updateFrame JNIEXPORT void JNICALL Java_com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_00024WndProc_updateFrame
(JNIEnv *, jobject, jlong, jint); (JNIEnv *, jobject, jlong, jint);
/*
* Class: com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_WndProc
* Method: setWindowBackground
* Signature: (JIII)V
*/
JNIEXPORT void JNICALL Java_com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_00024WndProc_setWindowBackground
(JNIEnv *, jobject, jlong, jint, jint, jint);
/* /*
* Class: com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_WndProc * Class: com_formdev_flatlaf_ui_FlatWindowsNativeWindowBorder_WndProc
* Method: showWindow * Method: showWindow

View File

@@ -42,3 +42,18 @@ JXTitledPanel.borderColor = $Button.borderColor
JXTitledPanel.titleBackground = $TaskPane.titleBackgroundGradientStart JXTitledPanel.titleBackground = $TaskPane.titleBackgroundGradientStart
JXTitledPanel.titleForeground = $TaskPane.titleForeground JXTitledPanel.titleForeground = $TaskPane.titleForeground
JXTitledPanel.captionInsets = 4,10,4,10 JXTitledPanel.captionInsets = 4,10,4,10
#---- SearchField ----
SearchField.icon = com.formdev.flatlaf.icons.FlatSearchIcon
SearchField.rolloverIcon = lazy(SearchField.icon)
SearchField.pressedIcon = lazy(SearchField.icon)
SearchField.popupIcon = com.formdev.flatlaf.icons.FlatSearchWithHistoryIcon
SearchField.popupRolloverIcon = lazy(SearchField.popupIcon)
SearchField.popupPressedIcon = lazy(SearchField.popupIcon)
SearchField.clearIcon = com.formdev.flatlaf.icons.FlatClearIcon
SearchField.clearRolloverIcon = lazy(SearchField.clearIcon)
SearchField.clearPressedIcon = lazy(SearchField.clearIcon)

View File

@@ -879,6 +879,25 @@ ScrollPane.smoothScrolling true
ScrollPaneUI com.formdev.flatlaf.ui.FlatScrollPaneUI ScrollPaneUI com.formdev.flatlaf.ui.FlatScrollPaneUI
#---- SearchField ----
SearchField.clearIcon [lazy] 16,16 com.formdev.flatlaf.icons.FlatClearIcon [UI]
SearchField.clearIconColor [lazy] #7f8b9180 50% javax.swing.plaf.ColorUIResource [UI]
SearchField.clearIconHoverColor [lazy] #7f8b9180 50% javax.swing.plaf.ColorUIResource [UI]
SearchField.clearIconPressedColor [lazy] #7f8b91cc 80% javax.swing.plaf.ColorUIResource [UI]
SearchField.clearPressedIcon [lazy] 16,16 com.formdev.flatlaf.icons.FlatClearIcon [UI]
SearchField.clearRolloverIcon [lazy] 16,16 com.formdev.flatlaf.icons.FlatClearIcon [UI]
SearchField.icon [lazy] 16,16 com.formdev.flatlaf.icons.FlatSearchIcon [UI]
SearchField.popupIcon [lazy] 16,16 com.formdev.flatlaf.icons.FlatSearchWithHistoryIcon [UI]
SearchField.popupPressedIcon [lazy] 16,16 com.formdev.flatlaf.icons.FlatSearchWithHistoryIcon [UI]
SearchField.popupRolloverIcon [lazy] 16,16 com.formdev.flatlaf.icons.FlatSearchWithHistoryIcon [UI]
SearchField.pressedIcon [lazy] 16,16 com.formdev.flatlaf.icons.FlatSearchIcon [UI]
SearchField.rolloverIcon [lazy] 16,16 com.formdev.flatlaf.icons.FlatSearchIcon [UI]
SearchField.searchIconColor [lazy] #7f8b91e6 90% javax.swing.plaf.ColorUIResource [UI]
SearchField.searchIconHoverColor [lazy] #7f8b91b3 70% javax.swing.plaf.ColorUIResource [UI]
SearchField.searchIconPressedColor [lazy] #7f8b9180 50% javax.swing.plaf.ColorUIResource [UI]
#---- Separator ---- #---- Separator ----
Separator.background #3c3f41 javax.swing.plaf.ColorUIResource [UI] Separator.background #3c3f41 javax.swing.plaf.ColorUIResource [UI]
@@ -1249,6 +1268,7 @@ ToolBar.dockingBackground #3c3f41 javax.swing.plaf.ColorUIResource [UI]
ToolBar.dockingForeground #bbbbbb javax.swing.plaf.ColorUIResource [UI] ToolBar.dockingForeground #bbbbbb javax.swing.plaf.ColorUIResource [UI]
ToolBar.floatingBackground #3c3f41 javax.swing.plaf.ColorUIResource [UI] ToolBar.floatingBackground #3c3f41 javax.swing.plaf.ColorUIResource [UI]
ToolBar.floatingForeground #888888 javax.swing.plaf.ColorUIResource [UI] ToolBar.floatingForeground #888888 javax.swing.plaf.ColorUIResource [UI]
ToolBar.focusableButtons false
ToolBar.font [active] $defaultFont [UI] ToolBar.font [active] $defaultFont [UI]
ToolBar.foreground #bbbbbb javax.swing.plaf.ColorUIResource [UI] ToolBar.foreground #bbbbbb javax.swing.plaf.ColorUIResource [UI]
ToolBar.gripColor #adadad javax.swing.plaf.ColorUIResource [UI] ToolBar.gripColor #adadad javax.swing.plaf.ColorUIResource [UI]

View File

@@ -884,6 +884,25 @@ ScrollPane.smoothScrolling true
ScrollPaneUI com.formdev.flatlaf.ui.FlatScrollPaneUI ScrollPaneUI com.formdev.flatlaf.ui.FlatScrollPaneUI
#---- SearchField ----
SearchField.clearIcon [lazy] 16,16 com.formdev.flatlaf.icons.FlatClearIcon [UI]
SearchField.clearIconColor [lazy] #7f8b9180 50% javax.swing.plaf.ColorUIResource [UI]
SearchField.clearIconHoverColor [lazy] #7f8b9180 50% javax.swing.plaf.ColorUIResource [UI]
SearchField.clearIconPressedColor [lazy] #7f8b91cc 80% javax.swing.plaf.ColorUIResource [UI]
SearchField.clearPressedIcon [lazy] 16,16 com.formdev.flatlaf.icons.FlatClearIcon [UI]
SearchField.clearRolloverIcon [lazy] 16,16 com.formdev.flatlaf.icons.FlatClearIcon [UI]
SearchField.icon [lazy] 16,16 com.formdev.flatlaf.icons.FlatSearchIcon [UI]
SearchField.popupIcon [lazy] 16,16 com.formdev.flatlaf.icons.FlatSearchWithHistoryIcon [UI]
SearchField.popupPressedIcon [lazy] 16,16 com.formdev.flatlaf.icons.FlatSearchWithHistoryIcon [UI]
SearchField.popupRolloverIcon [lazy] 16,16 com.formdev.flatlaf.icons.FlatSearchWithHistoryIcon [UI]
SearchField.pressedIcon [lazy] 16,16 com.formdev.flatlaf.icons.FlatSearchIcon [UI]
SearchField.rolloverIcon [lazy] 16,16 com.formdev.flatlaf.icons.FlatSearchIcon [UI]
SearchField.searchIconColor [lazy] #7f8b91e6 90% javax.swing.plaf.ColorUIResource [UI]
SearchField.searchIconHoverColor [lazy] #7f8b91b3 70% javax.swing.plaf.ColorUIResource [UI]
SearchField.searchIconPressedColor [lazy] #7f8b9180 50% javax.swing.plaf.ColorUIResource [UI]
#---- Separator ---- #---- Separator ----
Separator.background #f2f2f2 javax.swing.plaf.ColorUIResource [UI] Separator.background #f2f2f2 javax.swing.plaf.ColorUIResource [UI]
@@ -1254,6 +1273,7 @@ ToolBar.dockingBackground #f2f2f2 javax.swing.plaf.ColorUIResource [UI]
ToolBar.dockingForeground #000000 javax.swing.plaf.ColorUIResource [UI] ToolBar.dockingForeground #000000 javax.swing.plaf.ColorUIResource [UI]
ToolBar.floatingBackground #f2f2f2 javax.swing.plaf.ColorUIResource [UI] ToolBar.floatingBackground #f2f2f2 javax.swing.plaf.ColorUIResource [UI]
ToolBar.floatingForeground #8c8c8c javax.swing.plaf.ColorUIResource [UI] ToolBar.floatingForeground #8c8c8c javax.swing.plaf.ColorUIResource [UI]
ToolBar.focusableButtons false
ToolBar.font [active] $defaultFont [UI] ToolBar.font [active] $defaultFont [UI]
ToolBar.foreground #000000 javax.swing.plaf.ColorUIResource [UI] ToolBar.foreground #000000 javax.swing.plaf.ColorUIResource [UI]
ToolBar.gripColor #afafaf javax.swing.plaf.ColorUIResource [UI] ToolBar.gripColor #afafaf javax.swing.plaf.ColorUIResource [UI]

View File

@@ -194,6 +194,7 @@ ComboBox.buttonBackground #f0f0f0 javax.swing.plaf.ColorUIResource [UI]
ComboBox.buttonDarkShadow #696969 javax.swing.plaf.ColorUIResource [UI] ComboBox.buttonDarkShadow #696969 javax.swing.plaf.ColorUIResource [UI]
ComboBox.buttonDisabledArrowColor #ababab javax.swing.plaf.ColorUIResource [UI] ComboBox.buttonDisabledArrowColor #ababab javax.swing.plaf.ColorUIResource [UI]
ComboBox.buttonEditableBackground #cccccc javax.swing.plaf.ColorUIResource [UI] ComboBox.buttonEditableBackground #cccccc javax.swing.plaf.ColorUIResource [UI]
ComboBox.buttonFocusedBackground #ffff00 javax.swing.plaf.ColorUIResource [UI]
ComboBox.buttonHighlight #ffffff javax.swing.plaf.ColorUIResource [UI] ComboBox.buttonHighlight #ffffff javax.swing.plaf.ColorUIResource [UI]
ComboBox.buttonHoverArrowColor #ff0000 javax.swing.plaf.ColorUIResource [UI] ComboBox.buttonHoverArrowColor #ff0000 javax.swing.plaf.ColorUIResource [UI]
ComboBox.buttonPressedArrowColor #0000ff javax.swing.plaf.ColorUIResource [UI] ComboBox.buttonPressedArrowColor #0000ff javax.swing.plaf.ColorUIResource [UI]
@@ -202,6 +203,7 @@ ComboBox.buttonStyle auto
ComboBox.disabledBackground #e0e0e0 javax.swing.plaf.ColorUIResource [UI] ComboBox.disabledBackground #e0e0e0 javax.swing.plaf.ColorUIResource [UI]
ComboBox.disabledForeground #000088 javax.swing.plaf.ColorUIResource [UI] ComboBox.disabledForeground #000088 javax.swing.plaf.ColorUIResource [UI]
ComboBox.editorColumns 0 ComboBox.editorColumns 0
ComboBox.focusedBackground #ffff88 javax.swing.plaf.ColorUIResource [UI]
ComboBox.font [active] $defaultFont [UI] ComboBox.font [active] $defaultFont [UI]
ComboBox.foreground #ff0000 javax.swing.plaf.ColorUIResource [UI] ComboBox.foreground #ff0000 javax.swing.plaf.ColorUIResource [UI]
ComboBox.isEnterSelectablePopup false ComboBox.isEnterSelectablePopup false
@@ -209,6 +211,7 @@ ComboBox.maximumRowCount 15
ComboBox.minimumWidth 72 ComboBox.minimumWidth 72
ComboBox.noActionOnKeyNavigation false ComboBox.noActionOnKeyNavigation false
ComboBox.padding 2,6,2,6 javax.swing.plaf.InsetsUIResource [UI] ComboBox.padding 2,6,2,6 javax.swing.plaf.InsetsUIResource [UI]
ComboBox.popupBackground #ffffcc javax.swing.plaf.ColorUIResource [UI]
ComboBox.selectionBackground #00aa00 javax.swing.plaf.ColorUIResource [UI] ComboBox.selectionBackground #00aa00 javax.swing.plaf.ColorUIResource [UI]
ComboBox.selectionForeground #ffff00 javax.swing.plaf.ColorUIResource [UI] ComboBox.selectionForeground #ffff00 javax.swing.plaf.ColorUIResource [UI]
ComboBox.timeFactor 1000 ComboBox.timeFactor 1000
@@ -265,6 +268,7 @@ EditorPane.border [lazy] 0,0,0,0 false com.formdev.flatlaf.ui.F
EditorPane.caretBlinkRate 500 EditorPane.caretBlinkRate 500
EditorPane.caretForeground #0000ff javax.swing.plaf.ColorUIResource [UI] EditorPane.caretForeground #0000ff javax.swing.plaf.ColorUIResource [UI]
EditorPane.disabledBackground #e0e0e0 javax.swing.plaf.ColorUIResource [UI] EditorPane.disabledBackground #e0e0e0 javax.swing.plaf.ColorUIResource [UI]
EditorPane.focusedBackground #ffff88 javax.swing.plaf.ColorUIResource [UI]
EditorPane.font [active] $defaultFont [UI] EditorPane.font [active] $defaultFont [UI]
EditorPane.foreground #ff0000 javax.swing.plaf.ColorUIResource [UI] EditorPane.foreground #ff0000 javax.swing.plaf.ColorUIResource [UI]
EditorPane.inactiveBackground #f0f0f0 javax.swing.plaf.ColorUIResource [UI] EditorPane.inactiveBackground #f0f0f0 javax.swing.plaf.ColorUIResource [UI]
@@ -304,6 +308,7 @@ FormattedTextField.border [lazy] 1,1,1,1 false com.formdev.flatlaf.ui.F
FormattedTextField.caretBlinkRate 500 FormattedTextField.caretBlinkRate 500
FormattedTextField.caretForeground #0000ff javax.swing.plaf.ColorUIResource [UI] FormattedTextField.caretForeground #0000ff javax.swing.plaf.ColorUIResource [UI]
FormattedTextField.disabledBackground #e0e0e0 javax.swing.plaf.ColorUIResource [UI] FormattedTextField.disabledBackground #e0e0e0 javax.swing.plaf.ColorUIResource [UI]
FormattedTextField.focusedBackground #ffff88 javax.swing.plaf.ColorUIResource [UI]
FormattedTextField.font [active] $defaultFont [UI] FormattedTextField.font [active] $defaultFont [UI]
FormattedTextField.foreground #ff0000 javax.swing.plaf.ColorUIResource [UI] FormattedTextField.foreground #ff0000 javax.swing.plaf.ColorUIResource [UI]
FormattedTextField.inactiveBackground #f0f0f0 javax.swing.plaf.ColorUIResource [UI] FormattedTextField.inactiveBackground #f0f0f0 javax.swing.plaf.ColorUIResource [UI]
@@ -700,6 +705,7 @@ PasswordField.caretBlinkRate 500
PasswordField.caretForeground #0000ff javax.swing.plaf.ColorUIResource [UI] PasswordField.caretForeground #0000ff javax.swing.plaf.ColorUIResource [UI]
PasswordField.disabledBackground #e0e0e0 javax.swing.plaf.ColorUIResource [UI] PasswordField.disabledBackground #e0e0e0 javax.swing.plaf.ColorUIResource [UI]
PasswordField.echoChar '\u2022' PasswordField.echoChar '\u2022'
PasswordField.focusedBackground #ffff88 javax.swing.plaf.ColorUIResource [UI]
PasswordField.font [active] $defaultFont [UI] PasswordField.font [active] $defaultFont [UI]
PasswordField.foreground #ff0000 javax.swing.plaf.ColorUIResource [UI] PasswordField.foreground #ff0000 javax.swing.plaf.ColorUIResource [UI]
PasswordField.inactiveBackground #f0f0f0 javax.swing.plaf.ColorUIResource [UI] PasswordField.inactiveBackground #f0f0f0 javax.swing.plaf.ColorUIResource [UI]
@@ -877,6 +883,25 @@ ScrollPane.smoothScrolling true
ScrollPaneUI com.formdev.flatlaf.ui.FlatScrollPaneUI ScrollPaneUI com.formdev.flatlaf.ui.FlatScrollPaneUI
#---- SearchField ----
SearchField.clearIcon [lazy] 16,16 com.formdev.flatlaf.icons.FlatClearIcon [UI]
SearchField.clearIconColor [lazy] #7f8b9180 50% javax.swing.plaf.ColorUIResource [UI]
SearchField.clearIconHoverColor [lazy] #7f8b9180 50% javax.swing.plaf.ColorUIResource [UI]
SearchField.clearIconPressedColor [lazy] #7f8b91cc 80% javax.swing.plaf.ColorUIResource [UI]
SearchField.clearPressedIcon [lazy] 16,16 com.formdev.flatlaf.icons.FlatClearIcon [UI]
SearchField.clearRolloverIcon [lazy] 16,16 com.formdev.flatlaf.icons.FlatClearIcon [UI]
SearchField.icon [lazy] 16,16 com.formdev.flatlaf.icons.FlatSearchIcon [UI]
SearchField.popupIcon [lazy] 16,16 com.formdev.flatlaf.icons.FlatSearchWithHistoryIcon [UI]
SearchField.popupPressedIcon [lazy] 16,16 com.formdev.flatlaf.icons.FlatSearchWithHistoryIcon [UI]
SearchField.popupRolloverIcon [lazy] 16,16 com.formdev.flatlaf.icons.FlatSearchWithHistoryIcon [UI]
SearchField.pressedIcon [lazy] 16,16 com.formdev.flatlaf.icons.FlatSearchIcon [UI]
SearchField.rolloverIcon [lazy] 16,16 com.formdev.flatlaf.icons.FlatSearchIcon [UI]
SearchField.searchIconColor [lazy] #7f8b91e6 90% javax.swing.plaf.ColorUIResource [UI]
SearchField.searchIconHoverColor [lazy] #7f8b91b3 70% javax.swing.plaf.ColorUIResource [UI]
SearchField.searchIconPressedColor [lazy] #7f8b9180 50% javax.swing.plaf.ColorUIResource [UI]
#---- Separator ---- #---- Separator ----
Separator.background #ccffcc javax.swing.plaf.ColorUIResource [UI] Separator.background #ccffcc javax.swing.plaf.ColorUIResource [UI]
@@ -935,6 +960,7 @@ Spinner.disabledBackground #e0e0e0 javax.swing.plaf.ColorUIResource [UI]
Spinner.disabledForeground #000088 javax.swing.plaf.ColorUIResource [UI] Spinner.disabledForeground #000088 javax.swing.plaf.ColorUIResource [UI]
Spinner.editorAlignment 11 Spinner.editorAlignment 11
Spinner.editorBorderPainted false Spinner.editorBorderPainted false
Spinner.focusedBackground #ffff88 javax.swing.plaf.ColorUIResource [UI]
Spinner.font [active] $defaultFont [UI] Spinner.font [active] $defaultFont [UI]
Spinner.foreground #ff0000 javax.swing.plaf.ColorUIResource [UI] Spinner.foreground #ff0000 javax.swing.plaf.ColorUIResource [UI]
Spinner.padding 2,6,2,6 javax.swing.plaf.InsetsUIResource [UI] Spinner.padding 2,6,2,6 javax.swing.plaf.InsetsUIResource [UI]
@@ -1111,6 +1137,7 @@ TextArea.border [lazy] 0,0,0,0 false com.formdev.flatlaf.ui.F
TextArea.caretBlinkRate 500 TextArea.caretBlinkRate 500
TextArea.caretForeground #0000ff javax.swing.plaf.ColorUIResource [UI] TextArea.caretForeground #0000ff javax.swing.plaf.ColorUIResource [UI]
TextArea.disabledBackground #e0e0e0 javax.swing.plaf.ColorUIResource [UI] TextArea.disabledBackground #e0e0e0 javax.swing.plaf.ColorUIResource [UI]
TextArea.focusedBackground #ffff88 javax.swing.plaf.ColorUIResource [UI]
TextArea.font [active] $defaultFont [UI] TextArea.font [active] $defaultFont [UI]
TextArea.foreground #ff0000 javax.swing.plaf.ColorUIResource [UI] TextArea.foreground #ff0000 javax.swing.plaf.ColorUIResource [UI]
TextArea.inactiveBackground #f0f0f0 javax.swing.plaf.ColorUIResource [UI] TextArea.inactiveBackground #f0f0f0 javax.swing.plaf.ColorUIResource [UI]
@@ -1136,6 +1163,7 @@ TextField.caretBlinkRate 500
TextField.caretForeground #0000ff javax.swing.plaf.ColorUIResource [UI] TextField.caretForeground #0000ff javax.swing.plaf.ColorUIResource [UI]
TextField.darkShadow #696969 javax.swing.plaf.ColorUIResource [UI] TextField.darkShadow #696969 javax.swing.plaf.ColorUIResource [UI]
TextField.disabledBackground #e0e0e0 javax.swing.plaf.ColorUIResource [UI] TextField.disabledBackground #e0e0e0 javax.swing.plaf.ColorUIResource [UI]
TextField.focusedBackground #ffff88 javax.swing.plaf.ColorUIResource [UI]
TextField.font [active] $defaultFont [UI] TextField.font [active] $defaultFont [UI]
TextField.foreground #ff0000 javax.swing.plaf.ColorUIResource [UI] TextField.foreground #ff0000 javax.swing.plaf.ColorUIResource [UI]
TextField.highlight #ffffff javax.swing.plaf.ColorUIResource [UI] TextField.highlight #ffffff javax.swing.plaf.ColorUIResource [UI]
@@ -1157,6 +1185,7 @@ TextPane.border [lazy] 0,0,0,0 false com.formdev.flatlaf.ui.F
TextPane.caretBlinkRate 500 TextPane.caretBlinkRate 500
TextPane.caretForeground #0000ff javax.swing.plaf.ColorUIResource [UI] TextPane.caretForeground #0000ff javax.swing.plaf.ColorUIResource [UI]
TextPane.disabledBackground #e0e0e0 javax.swing.plaf.ColorUIResource [UI] TextPane.disabledBackground #e0e0e0 javax.swing.plaf.ColorUIResource [UI]
TextPane.focusedBackground #ffff88 javax.swing.plaf.ColorUIResource [UI]
TextPane.font [active] $defaultFont [UI] TextPane.font [active] $defaultFont [UI]
TextPane.foreground #ff0000 javax.swing.plaf.ColorUIResource [UI] TextPane.foreground #ff0000 javax.swing.plaf.ColorUIResource [UI]
TextPane.inactiveBackground #f0f0f0 javax.swing.plaf.ColorUIResource [UI] TextPane.inactiveBackground #f0f0f0 javax.swing.plaf.ColorUIResource [UI]
@@ -1253,6 +1282,7 @@ ToolBar.dockingBackground #ccffcc javax.swing.plaf.ColorUIResource [UI]
ToolBar.dockingForeground #ff0000 javax.swing.plaf.ColorUIResource [UI] ToolBar.dockingForeground #ff0000 javax.swing.plaf.ColorUIResource [UI]
ToolBar.floatingBackground #ccffcc javax.swing.plaf.ColorUIResource [UI] ToolBar.floatingBackground #ccffcc javax.swing.plaf.ColorUIResource [UI]
ToolBar.floatingForeground #000088 javax.swing.plaf.ColorUIResource [UI] ToolBar.floatingForeground #000088 javax.swing.plaf.ColorUIResource [UI]
ToolBar.focusableButtons true
ToolBar.font [active] $defaultFont [UI] ToolBar.font [active] $defaultFont [UI]
ToolBar.foreground #ff0000 javax.swing.plaf.ColorUIResource [UI] ToolBar.foreground #ff0000 javax.swing.plaf.ColorUIResource [UI]
ToolBar.gripColor #afafaf javax.swing.plaf.ColorUIResource [UI] ToolBar.gripColor #afafaf javax.swing.plaf.ColorUIResource [UI]

View File

@@ -51,6 +51,7 @@ public class FlatBaselineTest
JFormattedTextField formattedTextField1 = new JFormattedTextField(); JFormattedTextField formattedTextField1 = new JFormattedTextField();
JPasswordField passwordField1 = new JPasswordField(); JPasswordField passwordField1 = new JPasswordField();
JComboBox<String> comboBox1 = new JComboBox<>(); JComboBox<String> comboBox1 = new JComboBox<>();
JComboBox<String> comboBox2 = new JComboBox<>();
JSpinner spinner1 = new JSpinner(); JSpinner spinner1 = new JSpinner();
JLabel label6 = new JLabel(); JLabel label6 = new JLabel();
JScrollPane scrollPane1 = new JScrollPane(); JScrollPane scrollPane1 = new JScrollPane();
@@ -88,7 +89,7 @@ public class FlatBaselineTest
//======== this ======== //======== this ========
setLayout(new MigLayout( setLayout(new MigLayout(
"insets dialog,hidemode 3,debug", "insets dialog,hidemode 3",
// columns // columns
"[fill]" + "[fill]" +
"[fill]" + "[fill]" +
@@ -96,6 +97,7 @@ public class FlatBaselineTest
"[fill]" + "[fill]" +
"[fill]" + "[fill]" +
"[fill]" + "[fill]" +
"[fill]" +
"[fill]", "[fill]",
// rows // rows
"[]" + "[]" +
@@ -130,7 +132,7 @@ public class FlatBaselineTest
//---- textField4 ---- //---- textField4 ----
textField4.setText("Dext field"); textField4.setText("Dext field");
add(textField4, "cell 6 0"); add(textField4, "cell 7 0");
//---- label2 ---- //---- label2 ----
label2.setText("Dext"); label2.setText("Dext");
@@ -147,8 +149,20 @@ public class FlatBaselineTest
//---- passwordField1 ---- //---- passwordField1 ----
passwordField1.setText("Dext"); passwordField1.setText("Dext");
add(passwordField1, "cell 3 1"); add(passwordField1, "cell 3 1");
//---- comboBox1 ----
comboBox1.setModel(new DefaultComboBoxModel<>(new String[] {
"Dext"
}));
add(comboBox1, "cell 4 1"); add(comboBox1, "cell 4 1");
add(spinner1, "cell 5 1");
//---- comboBox2 ----
comboBox2.setModel(new DefaultComboBoxModel<>(new String[] {
"Dext"
}));
comboBox2.setEditable(true);
add(comboBox2, "cell 5 1");
add(spinner1, "cell 6 1");
//---- label6 ---- //---- label6 ----
label6.setText("Dext"); label6.setText("Dext");
@@ -171,7 +185,7 @@ public class FlatBaselineTest
//---- textField2 ---- //---- textField2 ----
textField2.setText("Dext field"); textField2.setText("Dext field");
add(textField2, "cell 6 2"); add(textField2, "cell 7 2");
//---- label7 ---- //---- label7 ----
label7.setText("Dext"); label7.setText("Dext");
@@ -230,18 +244,18 @@ public class FlatBaselineTest
//---- textField3 ---- //---- textField3 ----
textField3.setText("Dext field"); textField3.setText("Dext field");
add(textField3, "cell 6 3"); add(textField3, "cell 7 3");
//---- label3 ---- //---- label3 ----
label3.setText("Dext"); label3.setText("Dext");
add(label3, "cell 0 4"); add(label3, "cell 0 4");
add(slider1, "cell 1 4 6 1"); add(slider1, "cell 1 4 7 1");
//---- slider6 ---- //---- slider6 ----
slider6.setPaintTicks(true); slider6.setPaintTicks(true);
slider6.setMajorTickSpacing(25); slider6.setMajorTickSpacing(25);
slider6.setMinorTickSpacing(5); slider6.setMinorTickSpacing(5);
add(slider6, "cell 1 4 6 1"); add(slider6, "cell 1 4 7 1");
//---- label8 ---- //---- label8 ----
label8.setText("Dext"); label8.setText("Dext");
@@ -251,14 +265,14 @@ public class FlatBaselineTest
slider7.setPaintLabels(true); slider7.setPaintLabels(true);
slider7.setMajorTickSpacing(25); slider7.setMajorTickSpacing(25);
slider7.setMinorTickSpacing(5); slider7.setMinorTickSpacing(5);
add(slider7, "cell 1 5 6 1"); add(slider7, "cell 1 5 7 1");
//---- slider8 ---- //---- slider8 ----
slider8.setPaintLabels(true); slider8.setPaintLabels(true);
slider8.setPaintTicks(true); slider8.setPaintTicks(true);
slider8.setMajorTickSpacing(25); slider8.setMajorTickSpacing(25);
slider8.setMinorTickSpacing(5); slider8.setMinorTickSpacing(5);
add(slider8, "cell 1 5 6 1"); add(slider8, "cell 1 5 7 1");
//---- label4 ---- //---- label4 ----
label4.setText("Dext"); label4.setText("Dext");
@@ -266,13 +280,13 @@ public class FlatBaselineTest
//---- progressBar1 ---- //---- progressBar1 ----
progressBar1.setValue(30); progressBar1.setValue(30);
add(progressBar1, "cell 1 6 6 1"); add(progressBar1, "cell 1 6 7 1");
//---- progressBar3 ---- //---- progressBar3 ----
progressBar3.setStringPainted(true); progressBar3.setStringPainted(true);
progressBar3.setValue(30); progressBar3.setValue(30);
add(progressBar3, "cell 1 6 6 1"); add(progressBar3, "cell 1 6 7 1");
add(separator1, "cell 1 6 6 1"); add(separator1, "cell 1 6 7 1");
//---- label5 ---- //---- label5 ----
label5.setText("Dext"); label5.setText("Dext");
@@ -280,26 +294,26 @@ public class FlatBaselineTest
//---- slider2 ---- //---- slider2 ----
slider2.setOrientation(SwingConstants.VERTICAL); slider2.setOrientation(SwingConstants.VERTICAL);
add(slider2, "cell 1 7 6 1"); add(slider2, "cell 1 7 7 1");
//---- slider3 ---- //---- slider3 ----
slider3.setOrientation(SwingConstants.VERTICAL); slider3.setOrientation(SwingConstants.VERTICAL);
slider3.setPaintTicks(true); slider3.setPaintTicks(true);
slider3.setMajorTickSpacing(25); slider3.setMajorTickSpacing(25);
slider3.setMinorTickSpacing(5); slider3.setMinorTickSpacing(5);
add(slider3, "cell 1 7 6 1"); add(slider3, "cell 1 7 7 1");
//---- progressBar2 ---- //---- progressBar2 ----
progressBar2.setOrientation(SwingConstants.VERTICAL); progressBar2.setOrientation(SwingConstants.VERTICAL);
progressBar2.setValue(30); progressBar2.setValue(30);
add(progressBar2, "cell 1 7 6 1"); add(progressBar2, "cell 1 7 7 1");
//---- progressBar4 ---- //---- progressBar4 ----
progressBar4.setOrientation(SwingConstants.VERTICAL); progressBar4.setOrientation(SwingConstants.VERTICAL);
progressBar4.setStringPainted(true); progressBar4.setStringPainted(true);
progressBar4.setValue(30); progressBar4.setValue(30);
add(progressBar4, "cell 1 7 6 1"); add(progressBar4, "cell 1 7 7 1");
add(hSpacer1, "cell 1 7 6 1,growx"); add(hSpacer1, "cell 1 7 7 1,growx");
//---- label9 ---- //---- label9 ----
label9.setText("Dext"); label9.setText("Dext");
@@ -310,7 +324,7 @@ public class FlatBaselineTest
slider4.setPaintLabels(true); slider4.setPaintLabels(true);
slider4.setMajorTickSpacing(25); slider4.setMajorTickSpacing(25);
slider4.setMinorTickSpacing(5); slider4.setMinorTickSpacing(5);
add(slider4, "cell 1 8 6 1"); add(slider4, "cell 1 8 7 1");
//---- slider5 ---- //---- slider5 ----
slider5.setOrientation(SwingConstants.VERTICAL); slider5.setOrientation(SwingConstants.VERTICAL);
@@ -318,8 +332,8 @@ public class FlatBaselineTest
slider5.setPaintTicks(true); slider5.setPaintTicks(true);
slider5.setMajorTickSpacing(25); slider5.setMajorTickSpacing(25);
slider5.setMinorTickSpacing(5); slider5.setMinorTickSpacing(5);
add(slider5, "cell 1 8 6 1"); add(slider5, "cell 1 8 7 1");
add(hSpacer2, "cell 1 8 6 1,growx"); add(hSpacer2, "cell 1 8 7 1,growx");
// JFormDesigner - End of component initialization //GEN-END:initComponents // JFormDesigner - End of component initialization //GEN-END:initComponents
} }

View File

@@ -1,4 +1,4 @@
JFDML JFormDesigner: "7.0.2.0.298" Java: "15" encoding: "UTF-8" JFDML JFormDesigner: "7.0.4.0.360" Java: "16" encoding: "UTF-8"
new FormModel { new FormModel {
contentType: "form/swing" contentType: "form/swing"
@@ -7,8 +7,8 @@ new FormModel {
"JavaCodeGenerator.defaultVariableLocal": true "JavaCodeGenerator.defaultVariableLocal": true
} }
add( new FormContainer( "com.formdev.flatlaf.testing.FlatTestPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { add( new FormContainer( "com.formdev.flatlaf.testing.FlatTestPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "insets dialog,hidemode 3,debug" "$layoutConstraints": "insets dialog,hidemode 3"
"$columnConstraints": "[fill][fill][fill][fill][fill][fill][fill]" "$columnConstraints": "[fill][fill][fill][fill][fill][fill][fill][fill]"
"$rowConstraints": "[][][50][::80][][][][][]" "$rowConstraints": "[][][50][::80][][][][][]"
} ) { } ) {
name: "this" name: "this"
@@ -46,7 +46,7 @@ new FormModel {
name: "textField4" name: "textField4"
"text": "Dext field" "text": "Dext field"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 6 0" "value": "cell 7 0"
} ) } )
add( new FormComponent( "javax.swing.JLabel" ) { add( new FormComponent( "javax.swing.JLabel" ) {
name: "label2" name: "label2"
@@ -74,16 +74,33 @@ new FormModel {
} ) } )
add( new FormComponent( "javax.swing.JComboBox" ) { add( new FormComponent( "javax.swing.JComboBox" ) {
name: "comboBox1" name: "comboBox1"
"model": new javax.swing.DefaultComboBoxModel {
selectedItem: "Dext"
addElement( "Dext" )
}
auxiliary() { auxiliary() {
"JavaCodeGenerator.typeParameters": "String" "JavaCodeGenerator.typeParameters": "String"
} }
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 4 1" "value": "cell 4 1"
} ) } )
add( new FormComponent( "javax.swing.JComboBox" ) {
name: "comboBox2"
"model": new javax.swing.DefaultComboBoxModel {
selectedItem: "Dext"
addElement( "Dext" )
}
"editable": true
auxiliary() {
"JavaCodeGenerator.typeParameters": "String"
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 5 1"
} )
add( new FormComponent( "javax.swing.JSpinner" ) { add( new FormComponent( "javax.swing.JSpinner" ) {
name: "spinner1" name: "spinner1"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 5 1" "value": "cell 6 1"
} ) } )
add( new FormComponent( "javax.swing.JLabel" ) { add( new FormComponent( "javax.swing.JLabel" ) {
name: "label6" name: "label6"
@@ -112,7 +129,7 @@ new FormModel {
name: "textField2" name: "textField2"
"text": "Dext field" "text": "Dext field"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 6 2" "value": "cell 7 2"
} ) } )
add( new FormComponent( "javax.swing.JLabel" ) { add( new FormComponent( "javax.swing.JLabel" ) {
name: "label7" name: "label7"
@@ -184,7 +201,7 @@ new FormModel {
name: "textField3" name: "textField3"
"text": "Dext field" "text": "Dext field"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 6 3" "value": "cell 7 3"
} ) } )
add( new FormComponent( "javax.swing.JLabel" ) { add( new FormComponent( "javax.swing.JLabel" ) {
name: "label3" name: "label3"
@@ -195,7 +212,7 @@ new FormModel {
add( new FormComponent( "javax.swing.JSlider" ) { add( new FormComponent( "javax.swing.JSlider" ) {
name: "slider1" name: "slider1"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 4 6 1" "value": "cell 1 4 7 1"
} ) } )
add( new FormComponent( "javax.swing.JSlider" ) { add( new FormComponent( "javax.swing.JSlider" ) {
name: "slider6" name: "slider6"
@@ -203,7 +220,7 @@ new FormModel {
"majorTickSpacing": 25 "majorTickSpacing": 25
"minorTickSpacing": 5 "minorTickSpacing": 5
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 4 6 1" "value": "cell 1 4 7 1"
} ) } )
add( new FormComponent( "javax.swing.JLabel" ) { add( new FormComponent( "javax.swing.JLabel" ) {
name: "label8" name: "label8"
@@ -217,7 +234,7 @@ new FormModel {
"majorTickSpacing": 25 "majorTickSpacing": 25
"minorTickSpacing": 5 "minorTickSpacing": 5
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 5 6 1" "value": "cell 1 5 7 1"
} ) } )
add( new FormComponent( "javax.swing.JSlider" ) { add( new FormComponent( "javax.swing.JSlider" ) {
name: "slider8" name: "slider8"
@@ -226,7 +243,7 @@ new FormModel {
"majorTickSpacing": 25 "majorTickSpacing": 25
"minorTickSpacing": 5 "minorTickSpacing": 5
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 5 6 1" "value": "cell 1 5 7 1"
} ) } )
add( new FormComponent( "javax.swing.JLabel" ) { add( new FormComponent( "javax.swing.JLabel" ) {
name: "label4" name: "label4"
@@ -238,19 +255,19 @@ new FormModel {
name: "progressBar1" name: "progressBar1"
"value": 30 "value": 30
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 6 6 1" "value": "cell 1 6 7 1"
} ) } )
add( new FormComponent( "javax.swing.JProgressBar" ) { add( new FormComponent( "javax.swing.JProgressBar" ) {
name: "progressBar3" name: "progressBar3"
"stringPainted": true "stringPainted": true
"value": 30 "value": 30
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 6 6 1" "value": "cell 1 6 7 1"
} ) } )
add( new FormComponent( "javax.swing.JSeparator" ) { add( new FormComponent( "javax.swing.JSeparator" ) {
name: "separator1" name: "separator1"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 6 6 1" "value": "cell 1 6 7 1"
} ) } )
add( new FormComponent( "javax.swing.JLabel" ) { add( new FormComponent( "javax.swing.JLabel" ) {
name: "label5" name: "label5"
@@ -262,7 +279,7 @@ new FormModel {
name: "slider2" name: "slider2"
"orientation": 1 "orientation": 1
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 7 6 1" "value": "cell 1 7 7 1"
} ) } )
add( new FormComponent( "javax.swing.JSlider" ) { add( new FormComponent( "javax.swing.JSlider" ) {
name: "slider3" name: "slider3"
@@ -271,14 +288,14 @@ new FormModel {
"majorTickSpacing": 25 "majorTickSpacing": 25
"minorTickSpacing": 5 "minorTickSpacing": 5
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 7 6 1" "value": "cell 1 7 7 1"
} ) } )
add( new FormComponent( "javax.swing.JProgressBar" ) { add( new FormComponent( "javax.swing.JProgressBar" ) {
name: "progressBar2" name: "progressBar2"
"orientation": 1 "orientation": 1
"value": 30 "value": 30
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 7 6 1" "value": "cell 1 7 7 1"
} ) } )
add( new FormComponent( "javax.swing.JProgressBar" ) { add( new FormComponent( "javax.swing.JProgressBar" ) {
name: "progressBar4" name: "progressBar4"
@@ -286,12 +303,12 @@ new FormModel {
"stringPainted": true "stringPainted": true
"value": 30 "value": 30
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 7 6 1" "value": "cell 1 7 7 1"
} ) } )
add( new FormComponent( "com.jformdesigner.designer.wrapper.HSpacer" ) { add( new FormComponent( "com.jformdesigner.designer.wrapper.HSpacer" ) {
name: "hSpacer1" name: "hSpacer1"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 7 6 1,growx" "value": "cell 1 7 7 1,growx"
} ) } )
add( new FormComponent( "javax.swing.JLabel" ) { add( new FormComponent( "javax.swing.JLabel" ) {
name: "label9" name: "label9"
@@ -306,7 +323,7 @@ new FormModel {
"majorTickSpacing": 25 "majorTickSpacing": 25
"minorTickSpacing": 5 "minorTickSpacing": 5
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 8 6 1" "value": "cell 1 8 7 1"
} ) } )
add( new FormComponent( "javax.swing.JSlider" ) { add( new FormComponent( "javax.swing.JSlider" ) {
name: "slider5" name: "slider5"
@@ -316,12 +333,12 @@ new FormModel {
"majorTickSpacing": 25 "majorTickSpacing": 25
"minorTickSpacing": 5 "minorTickSpacing": 5
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 8 6 1" "value": "cell 1 8 7 1"
} ) } )
add( new FormComponent( "com.jformdesigner.designer.wrapper.HSpacer" ) { add( new FormComponent( "com.jformdesigner.designer.wrapper.HSpacer" ) {
name: "hSpacer2" name: "hSpacer2"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 8 6 1,growx" "value": "cell 1 8 7 1,growx"
} ) } )
}, new FormLayoutConstraints( null ) { }, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 0, 0 ) "location": new java.awt.Point( 0, 0 )

View File

@@ -20,6 +20,7 @@ import java.awt.*;
import javax.swing.*; import javax.swing.*;
import javax.swing.border.*; import javax.swing.border.*;
import javax.swing.plaf.basic.BasicComboBoxEditor; import javax.swing.plaf.basic.BasicComboBoxEditor;
import javax.swing.plaf.basic.BasicComboBoxRenderer;
import com.formdev.flatlaf.icons.FlatFileViewFloppyDriveIcon; import com.formdev.flatlaf.icons.FlatFileViewFloppyDriveIcon;
import com.formdev.flatlaf.util.UIScale; import com.formdev.flatlaf.util.UIScale;
import net.miginfocom.swing.*; import net.miginfocom.swing.*;
@@ -42,9 +43,24 @@ public class FlatCustomBordersTest
} ); } );
} }
@SuppressWarnings( "unchecked" )
FlatCustomBordersTest() { FlatCustomBordersTest() {
initComponents(); initComponents();
applyCustomBorders(); applyCustomBorders();
applySpecialComboBoxRenderers();
DefaultComboBoxModel<String> model = new DefaultComboBoxModel<>( new String[] {
"text",
"123",
"4567",
"abc",
"def"
} );
for( Component c : getComponents() ) {
if( c instanceof JComboBox )
((JComboBox<String>)c).setModel( model );
}
} }
@Override @Override
@@ -99,6 +115,40 @@ public class FlatCustomBordersTest
applyCustomComboBoxEditorBorderWithIcon( comboBox20 ); applyCustomComboBoxEditorBorderWithIcon( comboBox20 );
applyCustomComboBoxEditorBorder( comboBox21, null ); applyCustomComboBoxEditorBorder( comboBox21, null );
applyCustomComboBoxEditorBorder( comboBox22, null ); applyCustomComboBoxEditorBorder( comboBox22, null );
applyCustomComboBoxRendererBorder( comboBox23 );
applyCustomComboBoxRendererBorder( comboBox24 );
applyCustomComboBoxRendererBorderWithIcon( comboBox25 );
applyCustomComboBoxRendererBorderWithIcon( comboBox26 );
applyCustomComboBoxRendererBorder( comboBox27, null );
applyCustomComboBoxRendererBorder( comboBox28, null );
}
@SuppressWarnings( "unchecked" )
private void applySpecialComboBoxRenderers() {
BasicComboBoxRenderer sharedRenderer = new BasicComboBoxRenderer();
sharedRenderer.setBorder( new LineBorder( ORANGE, UIScale.scale( 2 ) ) );
comboBox29.setRenderer( sharedRenderer );
comboBox30.setRenderer( sharedRenderer );
comboBox31.setRenderer( new ListCellRenderer<String>() {
JLabel l1 = new JLabel();
JLabel l2 = new JLabel();
@Override
public Component getListCellRendererComponent( JList<? extends String> list,
String value, int index, boolean isSelected, boolean cellHasFocus )
{
JLabel l = (index % 2 == 0) ? l1 : l2;
l.setText( (value != null) ? value.toString() : "" );
l.setBorder( new LineBorder( (index % 2 == 0) ? GREEN : RED, UIScale.scale( 2 ) ) );
l.setBackground( isSelected ? list.getSelectionBackground() : list.getBackground() );
l.setForeground( isSelected ? list.getSelectionForeground() : list.getForeground() );
l.setFont( list.getFont() );
l.setOpaque( true );
return l;
}
} );
} }
private void applyCustomInsideBorder( JComponent c, String uiKey ) { private void applyCustomInsideBorder( JComponent c, String uiKey ) {
@@ -110,7 +160,7 @@ public class FlatCustomBordersTest
} }
private void applyCustomComboBoxEditorBorder( JComboBox<String> comboBox ) { private void applyCustomComboBoxEditorBorder( JComboBox<String> comboBox ) {
applyCustomComboBoxEditorBorder( comboBox, new LineBorder( ORANGE, UIScale.scale( 3 ) ) ); applyCustomComboBoxEditorBorder( comboBox, new LineBorder( ORANGE, UIScale.scale( 6 ) ) );
} }
private void applyCustomComboBoxEditorBorderWithIcon( JComboBox<String> comboBox ) { private void applyCustomComboBoxEditorBorderWithIcon( JComboBox<String> comboBox ) {
@@ -129,6 +179,21 @@ public class FlatCustomBordersTest
} ); } );
} }
private void applyCustomComboBoxRendererBorder( JComboBox<String> comboBox ) {
applyCustomComboBoxRendererBorder( comboBox, new LineBorder( ORANGE, UIScale.scale( 6 ) ) );
}
private void applyCustomComboBoxRendererBorderWithIcon( JComboBox<String> comboBox ) {
applyCustomComboBoxRendererBorder( comboBox, new BorderWithIcon() );
}
@SuppressWarnings( "unchecked" )
private void applyCustomComboBoxRendererBorder( JComboBox<String> comboBox, Border border ) {
BasicComboBoxRenderer customRenderer = new BasicComboBoxRenderer();
customRenderer.setBorder( border );
comboBox.setRenderer( customRenderer );
}
private void initComponents() { private void initComponents() {
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents // JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
label1 = new JLabel(); label1 = new JLabel();
@@ -152,10 +217,16 @@ public class FlatCustomBordersTest
comboBox2 = new JComboBox<>(); comboBox2 = new JComboBox<>();
comboBox3 = new JComboBox<>(); comboBox3 = new JComboBox<>();
comboBox4 = new JComboBox<>(); comboBox4 = new JComboBox<>();
comboBox23 = new JComboBox<>();
comboBox25 = new JComboBox<>();
comboBox27 = new JComboBox<>();
comboBox5 = new JComboBox<>(); comboBox5 = new JComboBox<>();
comboBox6 = new JComboBox<>(); comboBox6 = new JComboBox<>();
comboBox7 = new JComboBox<>(); comboBox7 = new JComboBox<>();
comboBox8 = new JComboBox<>(); comboBox8 = new JComboBox<>();
comboBox24 = new JComboBox<>();
comboBox26 = new JComboBox<>();
comboBox28 = new JComboBox<>();
comboBox9 = new JComboBox<>(); comboBox9 = new JComboBox<>();
comboBox10 = new JComboBox<>(); comboBox10 = new JComboBox<>();
comboBox11 = new JComboBox<>(); comboBox11 = new JComboBox<>();
@@ -188,6 +259,11 @@ public class FlatCustomBordersTest
textField6 = new JTextField(); textField6 = new JTextField();
textField7 = new JTextField(); textField7 = new JTextField();
textField8 = new JTextField(); textField8 = new JTextField();
label11 = new JLabel();
label12 = new JLabel();
comboBox29 = new JComboBox<>();
comboBox30 = new JComboBox<>();
comboBox31 = new JComboBox<>();
//======== this ======== //======== this ========
setLayout(new MigLayout( setLayout(new MigLayout(
@@ -212,6 +288,8 @@ public class FlatCustomBordersTest
"[]" + "[]" +
"[]" + "[]" +
"[]" + "[]" +
"[]para" +
"[]" +
"[]")); "[]"));
//---- label1 ---- //---- label1 ----
@@ -289,6 +367,9 @@ public class FlatCustomBordersTest
add(comboBox2, "cell 2 3"); add(comboBox2, "cell 2 3");
add(comboBox3, "cell 3 3"); add(comboBox3, "cell 3 3");
add(comboBox4, "cell 4 3"); add(comboBox4, "cell 4 3");
add(comboBox23, "cell 5 3");
add(comboBox25, "cell 6 3");
add(comboBox27, "cell 7 3");
//---- comboBox5 ---- //---- comboBox5 ----
comboBox5.putClientProperty("JComponent.roundRect", true); comboBox5.putClientProperty("JComponent.roundRect", true);
@@ -306,6 +387,18 @@ public class FlatCustomBordersTest
comboBox8.putClientProperty("JComponent.roundRect", true); comboBox8.putClientProperty("JComponent.roundRect", true);
add(comboBox8, "cell 4 4"); add(comboBox8, "cell 4 4");
//---- comboBox24 ----
comboBox24.putClientProperty("JComponent.roundRect", true);
add(comboBox24, "cell 5 4");
//---- comboBox26 ----
comboBox26.putClientProperty("JComponent.roundRect", true);
add(comboBox26, "cell 6 4");
//---- comboBox28 ----
comboBox28.putClientProperty("JComponent.roundRect", true);
add(comboBox28, "cell 7 4");
//---- comboBox9 ---- //---- comboBox9 ----
comboBox9.setEditable(true); comboBox9.setEditable(true);
add(comboBox9, "cell 1 5"); add(comboBox9, "cell 1 5");
@@ -435,6 +528,17 @@ public class FlatCustomBordersTest
textField8.putClientProperty("JComponent.roundRect", true); textField8.putClientProperty("JComponent.roundRect", true);
textField8.setText("text"); textField8.setText("text");
add(textField8, "cell 4 10"); add(textField8, "cell 4 10");
//---- label11 ----
label11.setText("JComboBox with shared renderer:");
add(label11, "cell 1 11 2 1");
//---- label12 ----
label12.setText("JComboBox with renderer that uses varying components:");
add(label12, "cell 3 11 3 1");
add(comboBox29, "cell 1 12");
add(comboBox30, "cell 2 12");
add(comboBox31, "cell 3 12");
// JFormDesigner - End of component initialization //GEN-END:initComponents // JFormDesigner - End of component initialization //GEN-END:initComponents
} }
@@ -460,10 +564,16 @@ public class FlatCustomBordersTest
private JComboBox<String> comboBox2; private JComboBox<String> comboBox2;
private JComboBox<String> comboBox3; private JComboBox<String> comboBox3;
private JComboBox<String> comboBox4; private JComboBox<String> comboBox4;
private JComboBox<String> comboBox23;
private JComboBox<String> comboBox25;
private JComboBox<String> comboBox27;
private JComboBox<String> comboBox5; private JComboBox<String> comboBox5;
private JComboBox<String> comboBox6; private JComboBox<String> comboBox6;
private JComboBox<String> comboBox7; private JComboBox<String> comboBox7;
private JComboBox<String> comboBox8; private JComboBox<String> comboBox8;
private JComboBox<String> comboBox24;
private JComboBox<String> comboBox26;
private JComboBox<String> comboBox28;
private JComboBox<String> comboBox9; private JComboBox<String> comboBox9;
private JComboBox<String> comboBox10; private JComboBox<String> comboBox10;
private JComboBox<String> comboBox11; private JComboBox<String> comboBox11;
@@ -496,6 +606,11 @@ public class FlatCustomBordersTest
private JTextField textField6; private JTextField textField6;
private JTextField textField7; private JTextField textField7;
private JTextField textField8; private JTextField textField8;
private JLabel label11;
private JLabel label12;
private JComboBox<String> comboBox29;
private JComboBox<String> comboBox30;
private JComboBox<String> comboBox31;
// JFormDesigner - End of variables declaration //GEN-END:variables // JFormDesigner - End of variables declaration //GEN-END:variables
//---- class BorderWithIcon ----------------------------------------------- //---- class BorderWithIcon -----------------------------------------------
@@ -508,6 +623,9 @@ public class FlatCustomBordersTest
@Override @Override
public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) { public void paintBorder( Component c, Graphics g, int x, int y, int width, int height ) {
icon.paintIcon( c, g, x + width - icon.getIconWidth() - 2, y + ((height - icon.getIconHeight()) / 2) ); icon.paintIcon( c, g, x + width - icon.getIconWidth() - 2, y + ((height - icon.getIconHeight()) / 2) );
g.setColor( RED );
g.drawRect( x, y, width - 1, height - 1 );
} }
@Override @Override

View File

@@ -1,4 +1,4 @@
JFDML JFormDesigner: "7.0.2.0.298" Java: "15" encoding: "UTF-8" JFDML JFormDesigner: "7.0.4.0.360" Java: "16" encoding: "UTF-8"
new FormModel { new FormModel {
contentType: "form/swing" contentType: "form/swing"
@@ -6,7 +6,7 @@ new FormModel {
add( new FormContainer( "com.formdev.flatlaf.testing.FlatTestPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { add( new FormContainer( "com.formdev.flatlaf.testing.FlatTestPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "ltr,insets dialog,hidemode 3" "$layoutConstraints": "ltr,insets dialog,hidemode 3"
"$columnConstraints": "[][fill][fill][fill][fill][fill][fill][fill]" "$columnConstraints": "[][fill][fill][fill][fill][fill][fill][fill]"
"$rowConstraints": "[][][][][][][][][][][]" "$rowConstraints": "[][][][][][][][][][][]para[][]"
} ) { } ) {
name: "this" name: "this"
add( new FormComponent( "javax.swing.JLabel" ) { add( new FormComponent( "javax.swing.JLabel" ) {
@@ -147,6 +147,30 @@ new FormModel {
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 4 3" "value": "cell 4 3"
} ) } )
add( new FormComponent( "javax.swing.JComboBox" ) {
name: "comboBox23"
auxiliary() {
"JavaCodeGenerator.typeParameters": "String"
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 5 3"
} )
add( new FormComponent( "javax.swing.JComboBox" ) {
name: "comboBox25"
auxiliary() {
"JavaCodeGenerator.typeParameters": "String"
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 6 3"
} )
add( new FormComponent( "javax.swing.JComboBox" ) {
name: "comboBox27"
auxiliary() {
"JavaCodeGenerator.typeParameters": "String"
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 7 3"
} )
add( new FormComponent( "javax.swing.JComboBox" ) { add( new FormComponent( "javax.swing.JComboBox" ) {
name: "comboBox5" name: "comboBox5"
"$client.JComponent.roundRect": true "$client.JComponent.roundRect": true
@@ -183,6 +207,33 @@ new FormModel {
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 4 4" "value": "cell 4 4"
} ) } )
add( new FormComponent( "javax.swing.JComboBox" ) {
name: "comboBox24"
"$client.JComponent.roundRect": true
auxiliary() {
"JavaCodeGenerator.typeParameters": "String"
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 5 4"
} )
add( new FormComponent( "javax.swing.JComboBox" ) {
name: "comboBox26"
"$client.JComponent.roundRect": true
auxiliary() {
"JavaCodeGenerator.typeParameters": "String"
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 6 4"
} )
add( new FormComponent( "javax.swing.JComboBox" ) {
name: "comboBox28"
"$client.JComponent.roundRect": true
auxiliary() {
"JavaCodeGenerator.typeParameters": "String"
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 7 4"
} )
add( new FormComponent( "javax.swing.JComboBox" ) { add( new FormComponent( "javax.swing.JComboBox" ) {
name: "comboBox9" name: "comboBox9"
"editable": true "editable": true
@@ -427,6 +478,42 @@ new FormModel {
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 4 10" "value": "cell 4 10"
} ) } )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label11"
"text": "JComboBox with shared renderer:"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 11 2 1"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label12"
"text": "JComboBox with renderer that uses varying components:"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 3 11 3 1"
} )
add( new FormComponent( "javax.swing.JComboBox" ) {
name: "comboBox29"
auxiliary() {
"JavaCodeGenerator.typeParameters": "String"
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 12"
} )
add( new FormComponent( "javax.swing.JComboBox" ) {
name: "comboBox30"
auxiliary() {
"JavaCodeGenerator.typeParameters": "String"
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 12"
} )
add( new FormComponent( "javax.swing.JComboBox" ) {
name: "comboBox31"
auxiliary() {
"JavaCodeGenerator.typeParameters": "String"
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 3 12"
} )
}, new FormLayoutConstraints( null ) { }, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 0, 0 ) "location": new java.awt.Point( 0, 0 )
"size": new java.awt.Dimension( 915, 715 ) "size": new java.awt.Dimension( 915, 715 )

View File

@@ -89,6 +89,15 @@ public class FlatInternalFrameTest
}; };
internalFrame.setContentPane( panel ); internalFrame.setContentPane( panel );
if( minSizeCheckBox.isSelected() ) {
internalFrame.setMinimumSize( new Dimension( 300, 150 ) );
panel.add( new JLabel( "min 300,150" ) );
}
if( maxSizeCheckBox.isSelected() ) {
internalFrame.setMaximumSize( new Dimension( 400, 200 ) );
panel.add( new JLabel( "max 400,200" ) );
}
if( !palette.getComponentOrientation().isLeftToRight() ) if( !palette.getComponentOrientation().isLeftToRight() )
internalFrame.setComponentOrientation( ComponentOrientation.RIGHT_TO_LEFT ); internalFrame.setComponentOrientation( ComponentOrientation.RIGHT_TO_LEFT );
@@ -123,6 +132,8 @@ public class FlatInternalFrameTest
maximizableCheckBox = new JCheckBox(); maximizableCheckBox = new JCheckBox();
iconCheckBox = new FlatTriStateCheckBox(); iconCheckBox = new FlatTriStateCheckBox();
menuBarCheckBox = new JCheckBox(); menuBarCheckBox = new JCheckBox();
minSizeCheckBox = new JCheckBox();
maxSizeCheckBox = new JCheckBox();
titleLabel = new JLabel(); titleLabel = new JLabel();
titleField = new JTextField(); titleField = new JTextField();
createFrameButton = new JButton(); createFrameButton = new JButton();
@@ -158,6 +169,8 @@ public class FlatInternalFrameTest
"[fill]0" + "[fill]0" +
"[]0" + "[]0" +
"[]0" + "[]0" +
"[]0" +
"[]0" +
"[]unrel" + "[]unrel" +
"[]unrel")); "[]unrel"));
@@ -189,18 +202,26 @@ public class FlatInternalFrameTest
menuBarCheckBox.setText("Menu Bar"); menuBarCheckBox.setText("Menu Bar");
paletteContentPane.add(menuBarCheckBox, "cell 1 2"); paletteContentPane.add(menuBarCheckBox, "cell 1 2");
//---- minSizeCheckBox ----
minSizeCheckBox.setText("Minimum size 300,150");
paletteContentPane.add(minSizeCheckBox, "cell 0 3 2 1,alignx left,growx 0");
//---- maxSizeCheckBox ----
maxSizeCheckBox.setText("Maximum size 400,200");
paletteContentPane.add(maxSizeCheckBox, "cell 0 4 2 1,alignx left,growx 0");
//---- titleLabel ---- //---- titleLabel ----
titleLabel.setText("Frame title:"); titleLabel.setText("Frame title:");
paletteContentPane.add(titleLabel, "cell 0 3"); paletteContentPane.add(titleLabel, "cell 0 5");
paletteContentPane.add(titleField, "cell 1 3"); paletteContentPane.add(titleField, "cell 1 5");
//---- createFrameButton ---- //---- createFrameButton ----
createFrameButton.setText("Create Frame"); createFrameButton.setText("Create Frame");
createFrameButton.addActionListener(e -> createInternalFrame()); createFrameButton.addActionListener(e -> createInternalFrame());
paletteContentPane.add(createFrameButton, "cell 1 4,alignx right,growx 0"); paletteContentPane.add(createFrameButton, "cell 1 6,alignx right,growx 0");
} }
desktopPane.add(palette, JLayeredPane.PALETTE_LAYER); desktopPane.add(palette, JLayeredPane.PALETTE_LAYER);
palette.setBounds(15, 25, 275, 185); palette.setBounds(15, 25, 275, 275);
} }
add(desktopPane, "cell 0 0,width 600,height 600"); add(desktopPane, "cell 0 0,width 600,height 600");
@@ -234,6 +255,8 @@ public class FlatInternalFrameTest
private JCheckBox maximizableCheckBox; private JCheckBox maximizableCheckBox;
private FlatTriStateCheckBox iconCheckBox; private FlatTriStateCheckBox iconCheckBox;
private JCheckBox menuBarCheckBox; private JCheckBox menuBarCheckBox;
private JCheckBox minSizeCheckBox;
private JCheckBox maxSizeCheckBox;
private JLabel titleLabel; private JLabel titleLabel;
private JTextField titleField; private JTextField titleField;
private JButton createFrameButton; private JButton createFrameButton;

View File

@@ -1,4 +1,4 @@
JFDML JFormDesigner: "7.0.3.1.342" Java: "16" encoding: "UTF-8" JFDML JFormDesigner: "7.0.4.0.360" Java: "16" encoding: "UTF-8"
new FormModel { new FormModel {
contentType: "form/swing" contentType: "form/swing"
@@ -14,7 +14,7 @@ new FormModel {
add( new FormContainer( "javax.swing.JInternalFrame", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { add( new FormContainer( "javax.swing.JInternalFrame", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "hidemode 3" "$layoutConstraints": "hidemode 3"
"$columnConstraints": "[fill][fill]" "$columnConstraints": "[fill][fill]"
"$rowConstraints": "[fill]0[]0[]0[]unrel[]unrel" "$rowConstraints": "[fill]0[]0[]0[]0[]0[]unrel[]unrel"
} ) { } ) {
name: "palette" name: "palette"
"visible": true "visible": true
@@ -62,29 +62,41 @@ new FormModel {
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 2" "value": "cell 1 2"
} ) } )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "minSizeCheckBox"
"text": "Minimum size 300,150"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 3 2 1,alignx left,growx 0"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "maxSizeCheckBox"
"text": "Maximum size 400,200"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 4 2 1,alignx left,growx 0"
} )
add( new FormComponent( "javax.swing.JLabel" ) { add( new FormComponent( "javax.swing.JLabel" ) {
name: "titleLabel" name: "titleLabel"
"text": "Frame title:" "text": "Frame title:"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 3" "value": "cell 0 5"
} ) } )
add( new FormComponent( "javax.swing.JTextField" ) { add( new FormComponent( "javax.swing.JTextField" ) {
name: "titleField" name: "titleField"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 3" "value": "cell 1 5"
} ) } )
add( new FormComponent( "javax.swing.JButton" ) { add( new FormComponent( "javax.swing.JButton" ) {
name: "createFrameButton" name: "createFrameButton"
"text": "Create Frame" "text": "Create Frame"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "createInternalFrame", false ) ) addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "createInternalFrame", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 4,alignx right,growx 0" "value": "cell 1 6,alignx right,growx 0"
} ) } )
}, new FormLayoutConstraints( null ) { }, new FormLayoutConstraints( null ) {
"x": 15 "x": 15
"y": 25 "y": 25
"width": 275 "width": 275
"height": 185 "height": 275
"layer": 100 "layer": 100
} ) } )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {

View File

@@ -89,6 +89,10 @@ public class FlatOptionPaneTest
JPanel panel6 = new JPanel(); JPanel panel6 = new JPanel();
customOptionPane = new JOptionPane(); customOptionPane = new JOptionPane();
FlatOptionPaneTest.ShowDialogLinkLabel customShowDialogLabel = new FlatOptionPaneTest.ShowDialogLinkLabel(); FlatOptionPaneTest.ShowDialogLinkLabel customShowDialogLabel = new FlatOptionPaneTest.ShowDialogLinkLabel();
JLabel rightToLeftLabel = new JLabel();
JPanel panel10 = new JPanel();
JOptionPane rightToLeftOptionPane = new JOptionPane();
rightToLeftShowDialogLabel = new FlatOptionPaneTest.ShowDialogLinkLabel();
//======== this ======== //======== this ========
setBorder(BorderFactory.createEmptyBorder()); setBorder(BorderFactory.createEmptyBorder());
@@ -109,6 +113,7 @@ public class FlatOptionPaneTest
"[top]" + "[top]" +
"[top]" + "[top]" +
"[top]" + "[top]" +
"[top]" +
"[top]")); "[top]"));
//---- plainLabel ---- //---- plainLabel ----
@@ -283,6 +288,28 @@ public class FlatOptionPaneTest
customShowDialogLabel.setOptionPane(customOptionPane); customShowDialogLabel.setOptionPane(customOptionPane);
customShowDialogLabel.setTitleLabel(customLabel); customShowDialogLabel.setTitleLabel(customLabel);
panel9.add(customShowDialogLabel, "cell 2 7"); panel9.add(customShowDialogLabel, "cell 2 7");
//---- rightToLeftLabel ----
rightToLeftLabel.setText("Right-to-left:");
panel9.add(rightToLeftLabel, "cell 0 8");
//======== panel10 ========
{
panel10.setBorder(LineBorder.createGrayLineBorder());
panel10.setLayout(new BorderLayout());
//---- rightToLeftOptionPane ----
rightToLeftOptionPane.setMessageType(JOptionPane.INFORMATION_MESSAGE);
rightToLeftOptionPane.setMessage("\u0627\u0644\u0645\u0627\u062f\u0629 1 \u064a\u0648\u0644\u062f \u062c\u0645\u064a\u0639 \u0627\u0644\u0646\u0627\u0633 \u0623\u062d\u0631\u0627\u0631\u064b\u0627 \u0645\u062a\u0633\u0627\u0648\u064a\u0646 \u0641\u064a \u0627\u0644\u0643\u0631\u0627\u0645\u0629 \u0648\u0627\u0644\u062d\u0642\u0648\u0642. \u0648\u0642\u062f \u0648\u0647\u0628\u0648\u0627 \u0639\u0642\u0644\u0627\u064b \u0648\u0636\u0645\u064a\u0631\u064b\u0627 \u0648\u0639\u0644\u064a\u0647\u0645 \u0623\u0646 \u064a\u0639\u0627\u0645\u0644 \u0628\u0639\u0636\u0647\u0645 \u0628\u0639\u0636\u064b\u0627 \u0628\u0631\u0648\u062d \u0627\u0644\u0625\u062e\u0627\u0621.\n\u0627\u0644\u0645\u0627\u062f\u0629 1 \u064a\u0648\u0644\u062f \u062c\u0645\u064a\u0639 \u0627\u0644\u0646\u0627\u0633 \u0623\u062d\u0631\u0627\u0631\u064b\u0627 \u0645\u062a\u0633\u0627\u0648\u064a\u0646 \u0641\u064a \u0627\u0644\u0643\u0631\u0627\u0645\u0629 \u0648\u0627\u0644\u062d\u0642\u0648\u0642. \u0648\u0642\u062f \u0648\u0647\u0628\u0648\u0627 \u0639\u0642\u0644\u0627\u064b \u0648\u0636\u0645\u064a\u0631\u064b\u0627 \u0648\u0639\u0644\u064a\u0647\u0645 \u0623\u0646 \u064a\u0639\u0627\u0645\u0644 \u0628\u0639\u0636\u0647\u0645 \u0628\u0639\u0636\u064b\u0627 \u0628\u0631\u0648\u062d \u0627\u0644\u0625\u062e\u0627\u0621.\n\n\u0627\u0644\u0645\u0627\u062f\u0629 1 \u064a\u0648\u0644\u062f \u062c\u0645\u064a\u0639 \u0627\u0644\u0646\u0627\u0633 \u0623\u062d\u0631\u0627\u0631\u064b\u0627 \u0645\u062a\u0633\u0627\u0648\u064a\u0646 \u0641\u064a \u0627\u0644\u0643\u0631\u0627\u0645\u0629 \n\u0648\u0627\u0644\u062d\u0642\u0648\u0642. \u0648\u0642\u062f \u0648\u0647\u0628\u0648\u0627 \u0639\u0642\u0644\u0627\u064b \u0648\u0636\u0645\u064a\u0631\u064b\u0627 \u0648\u0639\u0644\u064a\u0647\u0645 \u0623\u0646 \u064a\u0639\u0627\u0645\u0644 \u0628\u0639\u0636\u0647\u0645 \u0628\u0639\u0636\u064b\u0627 \u0628\u0631\u0648\u062d \u0627\u0644\u0625\u062e\u0627\u0621.");
rightToLeftOptionPane.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);
panel10.add(rightToLeftOptionPane, BorderLayout.CENTER);
}
panel9.add(panel10, "cell 1 8");
//---- rightToLeftShowDialogLabel ----
rightToLeftShowDialogLabel.setOptionPane(rightToLeftOptionPane);
rightToLeftShowDialogLabel.setTitleLabel(rightToLeftLabel);
panel9.add(rightToLeftShowDialogLabel, "cell 2 8");
} }
setViewportView(panel9); setViewportView(panel9);
// JFormDesigner - End of component initialization //GEN-END:initComponents // JFormDesigner - End of component initialization //GEN-END:initComponents
@@ -293,6 +320,7 @@ public class FlatOptionPaneTest
private FlatOptionPaneTest.ShowDialogLinkLabel errorShowDialogLabel; private FlatOptionPaneTest.ShowDialogLinkLabel errorShowDialogLabel;
private FlatOptionPaneTest.ShowDialogLinkLabel informationShowDialogLabel; private FlatOptionPaneTest.ShowDialogLinkLabel informationShowDialogLabel;
private JOptionPane customOptionPane; private JOptionPane customOptionPane;
private FlatOptionPaneTest.ShowDialogLinkLabel rightToLeftShowDialogLabel;
// JFormDesigner - End of variables declaration //GEN-END:variables // JFormDesigner - End of variables declaration //GEN-END:variables
//---- class ShowDialogLinkLabel ------------------------------------------ //---- class ShowDialogLinkLabel ------------------------------------------
@@ -315,9 +343,15 @@ public class FlatOptionPaneTest
} }
private void showDialog() { private void showDialog() {
Component parent = SwingUtilities.windowForComponent( this );
// use optionPane as parent if component orientation is different
if( parent.getComponentOrientation().isLeftToRight() != optionPane.getComponentOrientation().isLeftToRight() )
parent = optionPane;
if( optionPane.getWantsInput() ) { if( optionPane.getWantsInput() ) {
JOptionPane.showInputDialog( JOptionPane.showInputDialog(
getParent(), parent,
optionPane.getMessage(), optionPane.getMessage(),
titleLabel.getText() + " Title", titleLabel.getText() + " Title",
optionPane.getMessageType(), optionPane.getMessageType(),
@@ -326,7 +360,7 @@ public class FlatOptionPaneTest
null ); null );
} else { } else {
JOptionPane.showOptionDialog( JOptionPane.showOptionDialog(
getParent(), parent,
optionPane.getMessage(), optionPane.getMessage(),
titleLabel.getText() + " Title", titleLabel.getText() + " Title",
optionPane.getOptionType(), optionPane.getOptionType(),

View File

@@ -1,4 +1,4 @@
JFDML JFormDesigner: "7.0.1.0.272" Java: "13.0.2" encoding: "UTF-8" JFDML JFormDesigner: "7.0.4.0.360" Java: "16" encoding: "UTF-8"
new FormModel { new FormModel {
contentType: "form/swing" contentType: "form/swing"
@@ -12,7 +12,7 @@ new FormModel {
add( new FormContainer( "com.formdev.flatlaf.demo.ScrollablePanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { add( new FormContainer( "com.formdev.flatlaf.demo.ScrollablePanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "flowy,ltr,insets dialog,hidemode 3" "$layoutConstraints": "flowy,ltr,insets dialog,hidemode 3"
"$columnConstraints": "[][][fill]" "$columnConstraints": "[][][fill]"
"$rowConstraints": "[top][top][top][top][top][top][top][top]" "$rowConstraints": "[top][top][top][top][top][top][top][top][top]"
} ) { } ) {
name: "panel9" name: "panel9"
add( new FormComponent( "javax.swing.JLabel" ) { add( new FormComponent( "javax.swing.JLabel" ) {
@@ -240,10 +240,40 @@ new FormModel {
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 7" "value": "cell 2 7"
} ) } )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "rightToLeftLabel"
"text": "Right-to-left:"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 8"
} )
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class java.awt.BorderLayout ) ) {
name: "panel10"
"border": #LineBorder0
add( new FormComponent( "javax.swing.JOptionPane" ) {
name: "rightToLeftOptionPane"
"messageType": 1
"message": "المادة 1 يولد جميع الناس أحرارًا متساوين في الكرامة والحقوق. وقد وهبوا عقلاً وضميرًا وعليهم أن يعامل بعضهم بعضًا بروح الإخاء.\nالمادة 1 يولد جميع الناس أحرارًا متساوين في الكرامة والحقوق. وقد وهبوا عقلاً وضميرًا وعليهم أن يعامل بعضهم بعضًا بروح الإخاء.\n\nالمادة 1 يولد جميع الناس أحرارًا متساوين في الكرامة \nوالحقوق. وقد وهبوا عقلاً وضميرًا وعليهم أن يعامل بعضهم بعضًا بروح الإخاء."
"componentOrientation": sfield java.awt.ComponentOrientation RIGHT_TO_LEFT
}, new FormLayoutConstraints( class java.lang.String ) {
"value": "Center"
} )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 8"
} )
add( new FormComponent( "com.formdev.flatlaf.testing.FlatOptionPaneTest$ShowDialogLinkLabel" ) {
name: "rightToLeftShowDialogLabel"
"optionPane": new FormReference( "rightToLeftOptionPane" )
"titleLabel": new FormReference( "rightToLeftLabel" )
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 8"
} )
} ) } )
}, new FormLayoutConstraints( null ) { }, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 0, 0 ) "location": new java.awt.Point( 0, 0 )
"size": new java.awt.Dimension( 840, 900 ) "size": new java.awt.Dimension( 895, 1080 )
} ) } )
} }
} }

View File

@@ -0,0 +1,361 @@
/*
* 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.testing;
import java.awt.*;
import java.awt.Point;
import javax.swing.*;
import com.formdev.flatlaf.util.Animator;
import net.miginfocom.swing.*;
/**
* @author Karl Tauber
*/
public class FlatPopupTest
extends FlatTestPanel
{
private Popup popup;
public static void main( String[] args ) {
SwingUtilities.invokeLater( () -> {
FlatTestFrame frame = FlatTestFrame.create( args, "FlatPopupTest" );
frame.showFrame( FlatPopupTest::new );
} );
}
FlatPopupTest() {
initComponents();
}
private void showPopupMenu() {
popupMenu1.show( showPopupMenuButton, 0, showPopupMenuButton.getHeight() );
}
private void showLargePopupMenu() {
popupMenu2.show( showLargePopupMenuButton, 0, showLargePopupMenuButton.getHeight() );
}
private void showPopup() {
showPopup( 0, 0 );
}
private void showPopup( int xoffset, int yoffset ) {
hidePopup();
Point pt = showPopupButton.getLocationOnScreen();
popup = PopupFactory.getSharedInstance().getPopup( showPopupButton, popupPanel,
pt.x + xoffset, pt.y + showPopupButton.getHeight() + yoffset );
popup.show();
}
private void hidePopup() {
if( popup == null )
return;
popup.hide();
popup = null;
}
private void movePopupDown() {
movePopup( 0, 600 );
}
private void movePopupRight() {
movePopup( 600, 0 );
}
private void movePopup( int xoffset, int yoffset ) {
showPopup();
Animator animator = new Animator( 1000, fraction -> {
System.out.println(fraction);
showPopup( (int) (fraction * xoffset), (int) (fraction * yoffset) );
} );
animator.start();
}
private void initComponents() {
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
label1 = new JLabel();
label2 = new JLabel();
showPopupMenuButton = new JButton();
showLargePopupMenuButton = new JButton();
showPopupButton = new JButton();
hidePopupButton = new JButton();
movePopupDownButton = new JButton();
movePopuprightButton = new JButton();
label4 = new JLabel();
popupMenu1 = new JPopupMenu();
menuItem1 = new JMenuItem();
menuItem2 = new JMenuItem();
menu1 = new JMenu();
menuItem3 = new JMenuItem();
menuItem4 = new JMenuItem();
popupPanel = new JPanel();
label3 = new JLabel();
popupMenu2 = new JPopupMenu();
menuItem5 = new JMenuItem();
menuItem6 = new JMenuItem();
menuItem7 = new JMenuItem();
menuItem8 = new JMenuItem();
menuItem9 = new JMenuItem();
menuItem10 = new JMenuItem();
menuItem11 = new JMenuItem();
menuItem12 = new JMenuItem();
menuItem13 = new JMenuItem();
menuItem14 = new JMenuItem();
menuItem15 = new JMenuItem();
menuItem16 = new JMenuItem();
menuItem17 = new JMenuItem();
menuItem18 = new JMenuItem();
menuItem19 = new JMenuItem();
menuItem20 = new JMenuItem();
menuItem21 = new JMenuItem();
menu2 = new JMenu();
menuItem22 = new JMenuItem();
menuItem23 = new JMenuItem();
//======== this ========
setLayout(new MigLayout(
"ltr,insets dialog,hidemode 3",
// columns
"[fill]" +
"[fill]" +
"[fill]" +
"[fill]",
// rows
"[]" +
"[]" +
"[]" +
"[]" +
"[]" +
"[]"));
//---- label1 ----
label1.setText("Label with light-weight tooltip");
label1.setToolTipText("some tip");
add(label1, "cell 0 0");
//---- label2 ----
label2.setText("Label with heavy-weight tooltip");
label2.setToolTipText("some tip\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20\n21\n22\n23\n24\n25");
add(label2, "cell 0 1");
//---- showPopupMenuButton ----
showPopupMenuButton.setText("show light-weight JPopupMenu");
showPopupMenuButton.addActionListener(e -> showPopupMenu());
add(showPopupMenuButton, "cell 0 2");
//---- showLargePopupMenuButton ----
showLargePopupMenuButton.setText("show heavy-weight JPopupMenu");
showLargePopupMenuButton.addActionListener(e -> showLargePopupMenu());
add(showLargePopupMenuButton, "cell 0 3");
//---- showPopupButton ----
showPopupButton.setText("show medium-weight popup");
showPopupButton.addActionListener(e -> showPopup());
add(showPopupButton, "cell 0 4");
//---- hidePopupButton ----
hidePopupButton.setText("hide");
hidePopupButton.addActionListener(e -> hidePopup());
add(hidePopupButton, "cell 1 4");
//---- movePopupDownButton ----
movePopupDownButton.setText("move down");
movePopupDownButton.addActionListener(e -> movePopupDown());
add(movePopupDownButton, "cell 2 4");
//---- movePopuprightButton ----
movePopuprightButton.setText("move right");
movePopuprightButton.addActionListener(e -> movePopupRight());
add(movePopuprightButton, "cell 3 4");
//---- label4 ----
label4.setText("(switches to heavy-weight when moving outside of window)");
add(label4, "cell 0 5 4 1,alignx right,growx 0");
//======== popupMenu1 ========
{
//---- menuItem1 ----
menuItem1.setText("text");
popupMenu1.add(menuItem1);
//---- menuItem2 ----
menuItem2.setText("text");
popupMenu1.add(menuItem2);
//======== menu1 ========
{
menu1.setText("text");
//---- menuItem3 ----
menuItem3.setText("text");
menu1.add(menuItem3);
//---- menuItem4 ----
menuItem4.setText("text");
menu1.add(menuItem4);
}
popupMenu1.add(menu1);
}
//======== popupPanel ========
{
popupPanel.setBackground(new Color(153, 255, 153));
popupPanel.setLayout(new MigLayout(
"hidemode 3",
// columns
"[fill]",
// rows
"[]"));
//---- label3 ----
label3.setText("popup");
popupPanel.add(label3, "cell 0 0");
}
//======== popupMenu2 ========
{
//---- menuItem5 ----
menuItem5.setText("text");
popupMenu2.add(menuItem5);
//---- menuItem6 ----
menuItem6.setText("text");
popupMenu2.add(menuItem6);
//---- menuItem7 ----
menuItem7.setText("text");
popupMenu2.add(menuItem7);
//---- menuItem8 ----
menuItem8.setText("text");
popupMenu2.add(menuItem8);
//---- menuItem9 ----
menuItem9.setText("text");
popupMenu2.add(menuItem9);
//---- menuItem10 ----
menuItem10.setText("text");
popupMenu2.add(menuItem10);
//---- menuItem11 ----
menuItem11.setText("text");
popupMenu2.add(menuItem11);
//---- menuItem12 ----
menuItem12.setText("text");
popupMenu2.add(menuItem12);
//---- menuItem13 ----
menuItem13.setText("text");
popupMenu2.add(menuItem13);
//---- menuItem14 ----
menuItem14.setText("text");
popupMenu2.add(menuItem14);
//---- menuItem15 ----
menuItem15.setText("text");
popupMenu2.add(menuItem15);
//---- menuItem16 ----
menuItem16.setText("text");
popupMenu2.add(menuItem16);
//---- menuItem17 ----
menuItem17.setText("text");
popupMenu2.add(menuItem17);
//---- menuItem18 ----
menuItem18.setText("text");
popupMenu2.add(menuItem18);
//---- menuItem19 ----
menuItem19.setText("text");
popupMenu2.add(menuItem19);
//---- menuItem20 ----
menuItem20.setText("text");
popupMenu2.add(menuItem20);
//---- menuItem21 ----
menuItem21.setText("text");
popupMenu2.add(menuItem21);
//======== menu2 ========
{
menu2.setText("text");
//---- menuItem22 ----
menuItem22.setText("text");
menu2.add(menuItem22);
//---- menuItem23 ----
menuItem23.setText("text");
menu2.add(menuItem23);
}
popupMenu2.add(menu2);
}
// JFormDesigner - End of component initialization //GEN-END:initComponents
}
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
private JLabel label1;
private JLabel label2;
private JButton showPopupMenuButton;
private JButton showLargePopupMenuButton;
private JButton showPopupButton;
private JButton hidePopupButton;
private JButton movePopupDownButton;
private JButton movePopuprightButton;
private JLabel label4;
private JPopupMenu popupMenu1;
private JMenuItem menuItem1;
private JMenuItem menuItem2;
private JMenu menu1;
private JMenuItem menuItem3;
private JMenuItem menuItem4;
private JPanel popupPanel;
private JLabel label3;
private JPopupMenu popupMenu2;
private JMenuItem menuItem5;
private JMenuItem menuItem6;
private JMenuItem menuItem7;
private JMenuItem menuItem8;
private JMenuItem menuItem9;
private JMenuItem menuItem10;
private JMenuItem menuItem11;
private JMenuItem menuItem12;
private JMenuItem menuItem13;
private JMenuItem menuItem14;
private JMenuItem menuItem15;
private JMenuItem menuItem16;
private JMenuItem menuItem17;
private JMenuItem menuItem18;
private JMenuItem menuItem19;
private JMenuItem menuItem20;
private JMenuItem menuItem21;
private JMenu menu2;
private JMenuItem menuItem22;
private JMenuItem menuItem23;
// JFormDesigner - End of variables declaration //GEN-END:variables
}

View File

@@ -0,0 +1,206 @@
JFDML JFormDesigner: "7.0.4.0.360" Java: "16" encoding: "UTF-8"
new FormModel {
contentType: "form/swing"
root: new FormRoot {
add( new FormContainer( "com.formdev.flatlaf.testing.FlatTestPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "ltr,insets dialog,hidemode 3"
"$columnConstraints": "[fill][fill][fill][fill]"
"$rowConstraints": "[][][][][][]"
} ) {
name: "this"
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label1"
"text": "Label with light-weight tooltip"
"toolTipText": "some tip"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 0"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label2"
"text": "Label with heavy-weight tooltip"
"toolTipText": "some tip\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16\n17\n18\n19\n20\n21\n22\n23\n24\n25"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 1"
} )
add( new FormComponent( "javax.swing.JButton" ) {
name: "showPopupMenuButton"
"text": "show light-weight JPopupMenu"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "showPopupMenu", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 2"
} )
add( new FormComponent( "javax.swing.JButton" ) {
name: "showLargePopupMenuButton"
"text": "show heavy-weight JPopupMenu"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "showLargePopupMenu", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 3"
} )
add( new FormComponent( "javax.swing.JButton" ) {
name: "showPopupButton"
"text": "show medium-weight popup"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "showPopup", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 4"
} )
add( new FormComponent( "javax.swing.JButton" ) {
name: "hidePopupButton"
"text": "hide"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "hidePopup", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 4"
} )
add( new FormComponent( "javax.swing.JButton" ) {
name: "movePopupDownButton"
"text": "move down"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "movePopupDown", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 4"
} )
add( new FormComponent( "javax.swing.JButton" ) {
name: "movePopuprightButton"
"text": "move right"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "movePopupRight", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 3 4"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label4"
"text": "(switches to heavy-weight when moving outside of window)"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 5 4 1,alignx right,growx 0"
} )
}, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 0, 0 )
"size": new java.awt.Dimension( 490, 350 )
} )
add( new FormContainer( "javax.swing.JPopupMenu", new FormLayoutManager( class javax.swing.JPopupMenu ) ) {
name: "popupMenu1"
add( new FormComponent( "javax.swing.JMenuItem" ) {
name: "menuItem1"
"text": "text"
} )
add( new FormComponent( "javax.swing.JMenuItem" ) {
name: "menuItem2"
"text": "text"
} )
add( new FormContainer( "javax.swing.JMenu", new FormLayoutManager( class javax.swing.JMenu ) ) {
name: "menu1"
"text": "text"
add( new FormComponent( "javax.swing.JMenuItem" ) {
name: "menuItem3"
"text": "text"
} )
add( new FormComponent( "javax.swing.JMenuItem" ) {
name: "menuItem4"
"text": "text"
} )
} )
}, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 5, 395 )
} )
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "hidemode 3"
"$columnConstraints": "[fill]"
"$rowConstraints": "[]"
} ) {
name: "popupPanel"
"background": new java.awt.Color( 153, 255, 153, 255 )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label3"
"text": "popup"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 0"
} )
}, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 225, 395 )
"size": new java.awt.Dimension( 200, 200 )
} )
add( new FormContainer( "javax.swing.JPopupMenu", new FormLayoutManager( class javax.swing.JPopupMenu ) ) {
name: "popupMenu2"
add( new FormComponent( "javax.swing.JMenuItem" ) {
name: "menuItem5"
"text": "text"
} )
add( new FormComponent( "javax.swing.JMenuItem" ) {
name: "menuItem6"
"text": "text"
} )
add( new FormComponent( "javax.swing.JMenuItem" ) {
name: "menuItem7"
"text": "text"
} )
add( new FormComponent( "javax.swing.JMenuItem" ) {
name: "menuItem8"
"text": "text"
} )
add( new FormComponent( "javax.swing.JMenuItem" ) {
name: "menuItem9"
"text": "text"
} )
add( new FormComponent( "javax.swing.JMenuItem" ) {
name: "menuItem10"
"text": "text"
} )
add( new FormComponent( "javax.swing.JMenuItem" ) {
name: "menuItem11"
"text": "text"
} )
add( new FormComponent( "javax.swing.JMenuItem" ) {
name: "menuItem12"
"text": "text"
} )
add( new FormComponent( "javax.swing.JMenuItem" ) {
name: "menuItem13"
"text": "text"
} )
add( new FormComponent( "javax.swing.JMenuItem" ) {
name: "menuItem14"
"text": "text"
} )
add( new FormComponent( "javax.swing.JMenuItem" ) {
name: "menuItem15"
"text": "text"
} )
add( new FormComponent( "javax.swing.JMenuItem" ) {
name: "menuItem16"
"text": "text"
} )
add( new FormComponent( "javax.swing.JMenuItem" ) {
name: "menuItem17"
"text": "text"
} )
add( new FormComponent( "javax.swing.JMenuItem" ) {
name: "menuItem18"
"text": "text"
} )
add( new FormComponent( "javax.swing.JMenuItem" ) {
name: "menuItem19"
"text": "text"
} )
add( new FormComponent( "javax.swing.JMenuItem" ) {
name: "menuItem20"
"text": "text"
} )
add( new FormComponent( "javax.swing.JMenuItem" ) {
name: "menuItem21"
"text": "text"
} )
add( new FormContainer( "javax.swing.JMenu", new FormLayoutManager( class javax.swing.JMenu ) ) {
name: "menu2"
"text": "text"
add( new FormComponent( "javax.swing.JMenuItem" ) {
name: "menuItem22"
"text": "text"
} )
add( new FormComponent( "javax.swing.JMenuItem" ) {
name: "menuItem23"
"text": "text"
} )
} )
}, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 5, 505 )
} )
}
}

View File

@@ -0,0 +1,236 @@
/*
* 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.testing;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.plaf.metal.MetalLookAndFeel;
import javax.swing.plaf.nimbus.NimbusLookAndFeel;
import com.formdev.flatlaf.FlatDarculaLaf;
import com.formdev.flatlaf.FlatDarkLaf;
import com.formdev.flatlaf.FlatIntelliJLaf;
import com.formdev.flatlaf.FlatLaf;
import com.formdev.flatlaf.FlatLightLaf;
import com.formdev.flatlaf.FlatSystemProperties;
import com.formdev.flatlaf.demo.DemoPrefs;
import com.formdev.flatlaf.extras.FlatInspector;
import com.formdev.flatlaf.extras.FlatUIDefaultsInspector;
import com.formdev.flatlaf.util.SystemInfo;
import com.formdev.flatlaf.util.UIScale;
import net.miginfocom.swing.MigLayout;
/**
* @author Karl Tauber
*/
public class FlatSingleComponentTest
extends JFrame
{
private static final String PREFS_ROOT_PATH = "/flatlaf-test-single";
private static final String KEY_SCALE_FACTOR = "scaleFactor";
private final JLabel infoLabel;
private JComponent createSingleComponent() {
return new JButton( "hello" );
}
public static void main( String[] args ) {
DemoPrefs.init( PREFS_ROOT_PATH );
// set scale factor
if( System.getProperty( FlatSystemProperties.UI_SCALE ) == null ) {
String scaleFactor = DemoPrefs.getState().get( KEY_SCALE_FACTOR, null );
if( scaleFactor != null )
System.setProperty( FlatSystemProperties.UI_SCALE, scaleFactor );
}
// install inspectors
FlatInspector.install( "ctrl shift alt X" );
FlatUIDefaultsInspector.install( "ctrl shift alt Y" );
// disable animated Laf change
System.setProperty( "flatlaf.animatedLafChange", "false" );
// test loading custom defaults from package
FlatLaf.registerCustomDefaultsSource( "com.formdev.flatlaf.testing.customdefaults" );
// set look and feel
DemoPrefs.setupLaf( args );
// create and show frame
new FlatSingleComponentTest();
}
private FlatSingleComponentTest() {
super( "FlatSingleComponentTest" );
setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
JComponent c = createSingleComponent();
Container contentPane = getContentPane();
contentPane.setLayout( new MigLayout( null, null, "[][grow]") );
contentPane.add( c );
infoLabel = new JLabel();
infoLabel.setEnabled( false );
contentPane.add( infoLabel, "newline, aligny bottom,growy 0" );
// register F1, F2, ... keys to switch to Light, Dark or other LaFs
registerSwitchToLookAndFeel( "F1", FlatLightLaf.class.getName() );
registerSwitchToLookAndFeel( "F2", FlatDarkLaf.class.getName() );
registerSwitchToLookAndFeel( "F3", FlatIntelliJLaf.class.getName() );
registerSwitchToLookAndFeel( "F4", FlatDarculaLaf.class.getName() );
registerSwitchToLookAndFeel( "F8", FlatTestLaf.class.getName() );
if( SystemInfo.isWindows )
registerSwitchToLookAndFeel( "F9", "com.sun.java.swing.plaf.windows.WindowsLookAndFeel" );
else if( SystemInfo.isMacOS )
registerSwitchToLookAndFeel( "F9", "com.apple.laf.AquaLookAndFeel" );
else if( SystemInfo.isLinux )
registerSwitchToLookAndFeel( "F9", "com.sun.java.swing.plaf.gtk.GTKLookAndFeel" );
registerSwitchToLookAndFeel( "F12", MetalLookAndFeel.class.getName() );
registerSwitchToLookAndFeel( "F11", NimbusLookAndFeel.class.getName() );
// register Alt+F1, F2, ... keys to change scale factor
registerScaleFactor( "alt F1", "1" );
registerScaleFactor( "alt F2", "1.25" );
registerScaleFactor( "alt F3", "1.5" );
registerScaleFactor( "alt F4", "1.75" );
registerScaleFactor( "alt F5", "2" );
registerScaleFactor( "alt F6", "2.5" );
registerScaleFactor( "alt F7", "3" );
registerScaleFactor( "alt F8", "3.5" );
registerScaleFactor( "alt F9", "4" );
registerScaleFactor( "alt F10", "5" );
registerScaleFactor( "alt F11", "6" );
registerScaleFactor( "alt F12", null );
// register ESC key to close frame
((JComponent)getContentPane()).registerKeyboardAction(
e -> {
dispose();
},
KeyStroke.getKeyStroke( KeyEvent.VK_ESCAPE, 0, false ),
JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT );
// update info
addWindowListener( new WindowAdapter() {
@Override
public void windowOpened( WindowEvent e ) {
updateInfo();
}
} );
// update info when moved to another screen
addComponentListener( new ComponentAdapter() {
@Override
public void componentMoved( ComponentEvent e ) {
updateInfo();
}
} );
UIManager.addPropertyChangeListener( e -> {
if( "lookAndFeel".equals( e.getPropertyName() ) ) {
EventQueue.invokeLater( () -> {
// update info because user scale factor may change
updateInfo();
} );
}
} );
UIScale.addPropertyChangeListener( e -> {
// update info because user scale factor may change
updateInfo();
} );
setMinimumSize( UIScale.scale( new Dimension( 300, 150 ) ) );
pack();
setLocationRelativeTo( null );
setVisible( true );
}
private void updateInfo() {
double systemScaleFactor = UIScale.getSystemScaleFactor( getGraphicsConfiguration() );
float userScaleFactor = UIScale.getUserScaleFactor();
infoLabel.setText( " (Java " + System.getProperty( "java.version" )
+ (systemScaleFactor != 1 ? ("; system scale factor " + systemScaleFactor) : "")
+ (userScaleFactor != 1 ? ("; user scale factor " + userScaleFactor) : "")
+ (systemScaleFactor == 1 && userScaleFactor == 1 ? "; no scaling" : "")
+ ")" );
}
private void registerSwitchToLookAndFeel( String keyStrokeStr, String lafClassName ) {
KeyStroke keyStroke = KeyStroke.getKeyStroke( keyStrokeStr );
if( keyStroke == null )
throw new IllegalArgumentException( "Invalid key stroke '" + keyStrokeStr + "'" );
((JComponent)getContentPane()).registerKeyboardAction(
e -> {
applyLookAndFeel( lafClassName );
},
keyStroke,
JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT );
}
private void applyLookAndFeel( String lafClassName ) {
try {
UIManager.setLookAndFeel( lafClassName );
FlatLaf.updateUI();
} catch( Exception ex ) {
ex.printStackTrace();
}
}
private void registerScaleFactor( String keyStrokeStr, String scaleFactor ) {
KeyStroke keyStroke = KeyStroke.getKeyStroke( keyStrokeStr );
if( keyStroke == null )
throw new IllegalArgumentException( "Invalid key stroke '" + keyStrokeStr + "'" );
((JComponent)getContentPane()).registerKeyboardAction(
e -> {
applyScaleFactor( scaleFactor );
},
keyStroke,
JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT );
}
private void applyScaleFactor( String scaleFactor ) {
if( scaleFactor != null ) {
System.setProperty( FlatSystemProperties.UI_SCALE, scaleFactor );
DemoPrefs.getState().put( KEY_SCALE_FACTOR, scaleFactor );
} else {
System.clearProperty( FlatSystemProperties.UI_SCALE );
DemoPrefs.getState().remove( KEY_SCALE_FACTOR );
}
applyLookAndFeel( UIManager.getLookAndFeel().getClass().getName() );
pack();
}
}

View File

@@ -16,8 +16,13 @@
package com.formdev.flatlaf.testing; package com.formdev.flatlaf.testing;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Insets;
import javax.swing.*; import javax.swing.*;
import javax.swing.border.*;
import javax.swing.text.DefaultEditorKit; import javax.swing.text.DefaultEditorKit;
import com.formdev.flatlaf.FlatClientProperties;
import net.miginfocom.swing.*; import net.miginfocom.swing.*;
/** /**
@@ -41,16 +46,40 @@ public class FlatTextComponentsTest
textField1.setText( "new text" ); textField1.setText( "new text" );
} }
private void paddingChanged() {
Insets padding = new Insets(
(int) topPaddingField.getValue(),
(int) leftPaddingField.getValue(),
(int) bottomPaddingField.getValue(),
(int) rightPaddingField.getValue() );
if( padding.equals( new Insets( 0, 0, 0, 0 ) ) )
padding = null;
for( Component c : getComponents() ) {
if( c instanceof JTextField )
((JTextField)c).putClientProperty( FlatClientProperties.TEXT_FIELD_PADDING, padding );
}
}
private void initComponents() { private void initComponents() {
// JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents // JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents
JLabel textFieldLabel = new JLabel(); JLabel textFieldLabel = new JLabel();
textField1 = new JTextField(); textField1 = new JTextField();
JTextField textField3 = new JTextField(); JTextField textField3 = new JTextField();
JTextField textField2 = new JTextField(); JTextField textField2 = new JTextField();
JButton button1 = new JButton();
JLabel formattedTextFieldLabel = new JLabel(); JLabel formattedTextFieldLabel = new JLabel();
JFormattedTextField formattedTextField1 = new JFormattedTextField(); JFormattedTextField formattedTextField1 = new JFormattedTextField();
JFormattedTextField formattedTextField3 = new JFormattedTextField(); JFormattedTextField formattedTextField3 = new JFormattedTextField();
JPanel panel1 = new JPanel();
JButton button1 = new JButton();
JLabel leftPaddingLabel = new JLabel();
leftPaddingField = new JSpinner();
JLabel rightPaddingLabel = new JLabel();
rightPaddingField = new JSpinner();
JLabel topPaddingLabel = new JLabel();
topPaddingField = new JSpinner();
JLabel bottomPaddingLabel = new JLabel();
bottomPaddingField = new JSpinner();
JLabel passwordFieldLabel = new JLabel(); JLabel passwordFieldLabel = new JLabel();
JPasswordField passwordField1 = new JPasswordField(); JPasswordField passwordField1 = new JPasswordField();
JPasswordField passwordField3 = new JPasswordField(); JPasswordField passwordField3 = new JPasswordField();
@@ -74,10 +103,18 @@ public class FlatTextComponentsTest
JComboBox<String> comboBox3 = new JComboBox<>(); JComboBox<String> comboBox3 = new JComboBox<>();
JLabel spinnerLabel = new JLabel(); JLabel spinnerLabel = new JLabel();
JSpinner spinner1 = new JSpinner(); JSpinner spinner1 = new JSpinner();
JSpinner spinner2 = new JSpinner(); JLabel label2 = new JLabel();
JSpinner spinner3 = new JSpinner();
JComboBox<String> comboBox2 = new JComboBox<>(); JComboBox<String> comboBox2 = new JComboBox<>();
JSpinner spinner2 = new JSpinner();
JLabel label1 = new JLabel();
JComboBox<String> comboBox5 = new JComboBox<>();
JSpinner spinner4 = new JSpinner();
JLabel label3 = new JLabel();
JComboBox<String> comboBox4 = new JComboBox<>(); JComboBox<String> comboBox4 = new JComboBox<>();
JSpinner spinner3 = new JSpinner();
JLabel label4 = new JLabel();
JComboBox<String> comboBox6 = new JComboBox<>();
JSpinner spinner5 = new JSpinner();
JPopupMenu popupMenu1 = new JPopupMenu(); JPopupMenu popupMenu1 = new JPopupMenu();
JMenuItem cutMenuItem = new JMenuItem(); JMenuItem cutMenuItem = new JMenuItem();
JMenuItem copyMenuItem = new JMenuItem(); JMenuItem copyMenuItem = new JMenuItem();
@@ -102,8 +139,12 @@ public class FlatTextComponentsTest
"[50,fill]" + "[50,fill]" +
"[]" + "[]" +
"[]para" + "[]para" +
"[40]" +
"[40]" +
"[]" + "[]" +
"[]" + "[]" +
"[::14]" +
"[::14]" +
"[]" + "[]" +
"[]")); "[]"));
@@ -134,12 +175,6 @@ public class FlatTextComponentsTest
textField2.setName("textField2"); textField2.setName("textField2");
add(textField2, "cell 3 0"); add(textField2, "cell 3 0");
//---- button1 ----
button1.setText("change text");
button1.setName("button1");
button1.addActionListener(e -> changeText());
add(button1, "cell 4 0");
//---- formattedTextFieldLabel ---- //---- formattedTextFieldLabel ----
formattedTextFieldLabel.setText("JFormattedTextField:"); formattedTextFieldLabel.setText("JFormattedTextField:");
formattedTextFieldLabel.setDisplayedMnemonic('F'); formattedTextFieldLabel.setDisplayedMnemonic('F');
@@ -159,6 +194,70 @@ public class FlatTextComponentsTest
formattedTextField3.setName("formattedTextField3"); formattedTextField3.setName("formattedTextField3");
add(formattedTextField3, "cell 2 1,growx"); add(formattedTextField3, "cell 2 1,growx");
//======== panel1 ========
{
panel1.setBorder(new TitledBorder("Control"));
panel1.setName("panel1");
panel1.setLayout(new MigLayout(
"hidemode 3",
// columns
"[fill]" +
"[fill]",
// rows
"[]" +
"[]" +
"[]" +
"[]" +
"[]"));
//---- button1 ----
button1.setText("change text");
button1.setName("button1");
button1.addActionListener(e -> changeText());
panel1.add(button1, "cell 0 0 2 1,alignx left,growx 0");
//---- leftPaddingLabel ----
leftPaddingLabel.setText("Left padding:");
leftPaddingLabel.setName("leftPaddingLabel");
panel1.add(leftPaddingLabel, "cell 0 1");
//---- leftPaddingField ----
leftPaddingField.setName("leftPaddingField");
leftPaddingField.addChangeListener(e -> paddingChanged());
panel1.add(leftPaddingField, "cell 1 1");
//---- rightPaddingLabel ----
rightPaddingLabel.setText("Right padding:");
rightPaddingLabel.setName("rightPaddingLabel");
panel1.add(rightPaddingLabel, "cell 0 2");
//---- rightPaddingField ----
rightPaddingField.setName("rightPaddingField");
rightPaddingField.addChangeListener(e -> paddingChanged());
panel1.add(rightPaddingField, "cell 1 2");
//---- topPaddingLabel ----
topPaddingLabel.setText("Top padding:");
topPaddingLabel.setName("topPaddingLabel");
panel1.add(topPaddingLabel, "cell 0 3");
//---- topPaddingField ----
topPaddingField.setName("topPaddingField");
topPaddingField.addChangeListener(e -> paddingChanged());
panel1.add(topPaddingField, "cell 1 3");
//---- bottomPaddingLabel ----
bottomPaddingLabel.setText("Bottom padding:");
bottomPaddingLabel.setName("bottomPaddingLabel");
panel1.add(bottomPaddingLabel, "cell 0 4");
//---- bottomPaddingField ----
bottomPaddingField.setName("bottomPaddingField");
bottomPaddingField.addChangeListener(e -> paddingChanged());
panel1.add(bottomPaddingField, "cell 1 4");
}
add(panel1, "cell 4 0 1 6,aligny top,growy 0");
//---- passwordFieldLabel ---- //---- passwordFieldLabel ----
passwordFieldLabel.setText("JPasswordField:"); passwordFieldLabel.setText("JPasswordField:");
passwordFieldLabel.setDisplayedMnemonic('P'); passwordFieldLabel.setDisplayedMnemonic('P');
@@ -301,7 +400,7 @@ public class FlatTextComponentsTest
comboBox3.setPrototypeDisplayValue("12345"); comboBox3.setPrototypeDisplayValue("12345");
comboBox3.setComponentPopupMenu(popupMenu1); comboBox3.setComponentPopupMenu(popupMenu1);
comboBox3.setName("comboBox3"); comboBox3.setName("comboBox3");
add(comboBox3, "cell 2 6,growx"); add(comboBox3, "cell 2 6,growx,wmin 50");
//---- spinnerLabel ---- //---- spinnerLabel ----
spinnerLabel.setText("JSpinner:"); spinnerLabel.setText("JSpinner:");
@@ -315,23 +414,67 @@ public class FlatTextComponentsTest
spinner1.setName("spinner1"); spinner1.setName("spinner1");
add(spinner1, "cell 1 7,growx"); add(spinner1, "cell 1 7,growx");
//---- spinner2 ---- //---- label2 ----
spinner2.setName("spinner2"); label2.setText("<html>Large row height:<br>(default pref height)</html>");
add(spinner2, "cell 1 8,growx,height 40"); label2.setName("label2");
add(label2, "cell 0 8,aligny top,growy 0");
//---- spinner3 ----
spinner3.setName("spinner3");
add(spinner3, "cell 1 9,growx,hmax 14");
//---- comboBox2 ---- //---- comboBox2 ----
comboBox2.setEditable(true); comboBox2.setEditable(true);
comboBox2.setName("comboBox2"); comboBox2.setName("comboBox2");
add(comboBox2, "cell 1 10,growx,height 40"); add(comboBox2, "cell 1 8,grow");
//---- spinner2 ----
spinner2.setName("spinner2");
add(spinner2, "cell 1 9,grow");
//---- label1 ----
label1.setText("Large pref height:");
label1.setName("label1");
add(label1, "cell 0 10,aligny top,growy 0");
//---- comboBox5 ----
comboBox5.setPreferredSize(new Dimension(60, 40));
comboBox5.setEditable(true);
comboBox5.setName("comboBox5");
add(comboBox5, "cell 1 10,growx");
//---- spinner4 ----
spinner4.setPreferredSize(new Dimension(60, 40));
spinner4.setName("spinner4");
add(spinner4, "cell 1 11,growx");
//---- label3 ----
label3.setText("<html>Small row height:<br>(default pref height)</html>");
label3.setName("label3");
add(label3, "cell 0 12 1 2,aligny top,growy 0");
//---- comboBox4 ---- //---- comboBox4 ----
comboBox4.setEditable(true); comboBox4.setEditable(true);
comboBox4.setName("comboBox4"); comboBox4.setName("comboBox4");
add(comboBox4, "cell 1 11,growx,hmax 14"); add(comboBox4, "cell 1 12,growx");
//---- spinner3 ----
spinner3.setName("spinner3");
add(spinner3, "cell 1 13,growx");
//---- label4 ----
label4.setText("Small pref height:");
label4.setName("label4");
add(label4, "cell 0 14 1 2,aligny top,growy 0");
//---- comboBox6 ----
comboBox6.setEditable(true);
comboBox6.setPreferredSize(new Dimension(60, 14));
comboBox6.setMinimumSize(new Dimension(60, 14));
comboBox6.setName("comboBox6");
add(comboBox6, "cell 1 14,growx");
//---- spinner5 ----
spinner5.setMinimumSize(new Dimension(60, 14));
spinner5.setPreferredSize(new Dimension(60, 14));
spinner5.setName("spinner5");
add(spinner5, "cell 1 15,growx,hmax 14");
//======== popupMenu1 ======== //======== popupMenu1 ========
{ {
@@ -361,5 +504,9 @@ public class FlatTextComponentsTest
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables // JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
private JTextField textField1; private JTextField textField1;
private JSpinner leftPaddingField;
private JSpinner rightPaddingField;
private JSpinner topPaddingField;
private JSpinner bottomPaddingField;
// JFormDesigner - End of variables declaration //GEN-END:variables // JFormDesigner - End of variables declaration //GEN-END:variables
} }

View File

@@ -1,4 +1,4 @@
JFDML JFormDesigner: "7.0.3.1.342" Java: "16" encoding: "UTF-8" JFDML JFormDesigner: "7.0.4.0.360" Java: "16" encoding: "UTF-8"
new FormModel { new FormModel {
contentType: "form/swing" contentType: "form/swing"
@@ -10,7 +10,7 @@ new FormModel {
add( new FormContainer( "com.formdev.flatlaf.testing.FlatTestPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { add( new FormContainer( "com.formdev.flatlaf.testing.FlatTestPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "ltr,insets dialog,hidemode 3" "$layoutConstraints": "ltr,insets dialog,hidemode 3"
"$columnConstraints": "[][][::100][100,fill][fill]" "$columnConstraints": "[][][::100][100,fill][fill]"
"$rowConstraints": "[][][][50,fill][50,fill][50,fill][][]para[][][][]" "$rowConstraints": "[][][][50,fill][50,fill][50,fill][][]para[40][40][][][::14][::14][][]"
} ) { } ) {
name: "this" name: "this"
add( new FormComponent( "javax.swing.JLabel" ) { add( new FormComponent( "javax.swing.JLabel" ) {
@@ -47,13 +47,6 @@ new FormModel {
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 3 0" "value": "cell 3 0"
} ) } )
add( new FormComponent( "javax.swing.JButton" ) {
name: "button1"
"text": "change text"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "changeText", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 4 0"
} )
add( new FormComponent( "javax.swing.JLabel" ) { add( new FormComponent( "javax.swing.JLabel" ) {
name: "formattedTextFieldLabel" name: "formattedTextFieldLabel"
"text": "JFormattedTextField:" "text": "JFormattedTextField:"
@@ -76,6 +69,83 @@ new FormModel {
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 1,growx" "value": "cell 2 1,growx"
} ) } )
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "hidemode 3"
"$columnConstraints": "[fill][fill]"
"$rowConstraints": "[][][][][]"
} ) {
name: "panel1"
"border": new javax.swing.border.TitledBorder( "Control" )
add( new FormComponent( "javax.swing.JButton" ) {
name: "button1"
"text": "change text"
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "changeText", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 0 2 1,alignx left,growx 0"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "leftPaddingLabel"
"text": "Left padding:"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 1"
} )
add( new FormComponent( "javax.swing.JSpinner" ) {
name: "leftPaddingField"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
addEvent( new FormEvent( "javax.swing.event.ChangeListener", "stateChanged", "paddingChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 1"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "rightPaddingLabel"
"text": "Right padding:"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 2"
} )
add( new FormComponent( "javax.swing.JSpinner" ) {
name: "rightPaddingField"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
addEvent( new FormEvent( "javax.swing.event.ChangeListener", "stateChanged", "paddingChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 2"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "topPaddingLabel"
"text": "Top padding:"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 3"
} )
add( new FormComponent( "javax.swing.JSpinner" ) {
name: "topPaddingField"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
addEvent( new FormEvent( "javax.swing.event.ChangeListener", "stateChanged", "paddingChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 3"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "bottomPaddingLabel"
"text": "Bottom padding:"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 4"
} )
add( new FormComponent( "javax.swing.JSpinner" ) {
name: "bottomPaddingField"
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
addEvent( new FormEvent( "javax.swing.event.ChangeListener", "stateChanged", "paddingChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 4"
} )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 4 0 1 6,aligny top,growy 0"
} )
add( new FormComponent( "javax.swing.JLabel" ) { add( new FormComponent( "javax.swing.JLabel" ) {
name: "passwordFieldLabel" name: "passwordFieldLabel"
"text": "JPasswordField:" "text": "JPasswordField:"
@@ -217,7 +287,7 @@ new FormModel {
"prototypeDisplayValue": "12345" "prototypeDisplayValue": "12345"
"componentPopupMenu": #FormReference0 "componentPopupMenu": #FormReference0
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 6,growx" "value": "cell 2 6,growx,wmin 50"
} ) } )
add( new FormComponent( "javax.swing.JLabel" ) { add( new FormComponent( "javax.swing.JLabel" ) {
name: "spinnerLabel" name: "spinnerLabel"
@@ -233,15 +303,11 @@ new FormModel {
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 7,growx" "value": "cell 1 7,growx"
} ) } )
add( new FormComponent( "javax.swing.JSpinner" ) { add( new FormComponent( "javax.swing.JLabel" ) {
name: "spinner2" name: "label2"
"text": "<html>Large row height:<br>(default pref height)</html>"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 8,growx,height 40" "value": "cell 0 8,aligny top,growy 0"
} )
add( new FormComponent( "javax.swing.JSpinner" ) {
name: "spinner3"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 9,growx,hmax 14"
} ) } )
add( new FormComponent( "javax.swing.JComboBox" ) { add( new FormComponent( "javax.swing.JComboBox" ) {
name: "comboBox2" name: "comboBox2"
@@ -250,7 +316,40 @@ new FormModel {
"JavaCodeGenerator.typeParameters": "String" "JavaCodeGenerator.typeParameters": "String"
} }
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 10,growx,height 40" "value": "cell 1 8,grow"
} )
add( new FormComponent( "javax.swing.JSpinner" ) {
name: "spinner2"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 9,grow"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label1"
"text": "Large pref height:"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 10,aligny top,growy 0"
} )
add( new FormComponent( "javax.swing.JComboBox" ) {
name: "comboBox5"
"preferredSize": new java.awt.Dimension( 60, 40 )
"editable": true
auxiliary() {
"JavaCodeGenerator.typeParameters": "String"
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 10,growx"
} )
add( new FormComponent( "javax.swing.JSpinner" ) {
name: "spinner4"
"preferredSize": new java.awt.Dimension( 60, 40 )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 11,growx"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label3"
"text": "<html>Small row height:<br>(default pref height)</html>"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 12 1 2,aligny top,growy 0"
} ) } )
add( new FormComponent( "javax.swing.JComboBox" ) { add( new FormComponent( "javax.swing.JComboBox" ) {
name: "comboBox4" name: "comboBox4"
@@ -259,11 +358,40 @@ new FormModel {
"JavaCodeGenerator.typeParameters": "String" "JavaCodeGenerator.typeParameters": "String"
} }
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 11,growx,hmax 14" "value": "cell 1 12,growx"
} )
add( new FormComponent( "javax.swing.JSpinner" ) {
name: "spinner3"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 13,growx"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label4"
"text": "Small pref height:"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 14 1 2,aligny top,growy 0"
} )
add( new FormComponent( "javax.swing.JComboBox" ) {
name: "comboBox6"
"editable": true
"preferredSize": new java.awt.Dimension( 60, 14 )
"minimumSize": new java.awt.Dimension( 60, 14 )
auxiliary() {
"JavaCodeGenerator.typeParameters": "String"
}
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 14,growx"
} )
add( new FormComponent( "javax.swing.JSpinner" ) {
name: "spinner5"
"minimumSize": new java.awt.Dimension( 60, 14 )
"preferredSize": new java.awt.Dimension( 60, 14 )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 15,growx,hmax 14"
} ) } )
}, new FormLayoutConstraints( null ) { }, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 0, 0 ) "location": new java.awt.Point( 0, 0 )
"size": new java.awt.Dimension( 530, 580 ) "size": new java.awt.Dimension( 530, 660 )
} ) } )
add( new FormContainer( "javax.swing.JPopupMenu", new FormLayoutManager( class javax.swing.JPopupMenu ) ) { add( new FormContainer( "javax.swing.JPopupMenu", new FormLayoutManager( class javax.swing.JPopupMenu ) ) {
name: "popupMenu1" name: "popupMenu1"
@@ -280,7 +408,7 @@ new FormModel {
"text": "Paste" "text": "Paste"
} ) } )
}, new FormLayoutConstraints( null ) { }, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 0, 680 ) "location": new java.awt.Point( 0, 705 )
"size": new java.awt.Dimension( 91, 87 ) "size": new java.awt.Dimension( 91, 87 )
} ) } )
} }

View File

@@ -124,6 +124,11 @@ public class FlatSwingXTest
JTextField textField3 = new JTextField(); JTextField textField3 = new JTextField();
JLabel label10 = new JLabel(); JLabel label10 = new JLabel();
JTextField textField4 = new JTextField(); JTextField textField4 = new JTextField();
JLabel label11 = new JLabel();
JXSearchField xSearchField1 = new JXSearchField();
JXSearchField xSearchField2 = new JXSearchField();
JXSearchField xSearchField3 = new JXSearchField();
JXSearchField xSearchField4 = new JXSearchField();
JButton button1 = new JButton(); JButton button1 = new JButton();
JButton button2 = new JButton(); JButton button2 = new JButton();
@@ -146,6 +151,8 @@ public class FlatSwingXTest
"[]" + "[]" +
"[]" + "[]" +
"[]" + "[]" +
"[]" +
"[]" +
"[37]")); "[37]"));
//---- label1 ---- //---- label1 ----
@@ -425,6 +432,30 @@ public class FlatSwingXTest
} }
add(xTitledPanel2, "cell 3 8,grow"); add(xTitledPanel2, "cell 3 8,grow");
//---- label11 ----
label11.setText("JXSearchField:");
add(label11, "cell 0 9");
//---- xSearchField1 ----
xSearchField1.setText("abc");
add(xSearchField1, "cell 1 9,growx");
//---- xSearchField2 ----
xSearchField2.setEnabled(false);
xSearchField2.setText("abc");
add(xSearchField2, "cell 2 9,growx");
//---- xSearchField3 ----
xSearchField3.setRecentSearchesSaveKey("flatlaf.swingx.search.recent");
xSearchField3.setText("abc");
add(xSearchField3, "cell 1 10,growx");
//---- xSearchField4 ----
xSearchField4.setRecentSearchesSaveKey("flatlaf.swingx.search.recent");
xSearchField4.setEnabled(false);
xSearchField4.setText("abc");
add(xSearchField4, "cell 2 10,growx");
//---- button1 ---- //---- button1 ----
button1.setText("<"); button1.setText("<");

View File

@@ -1,4 +1,4 @@
JFDML JFormDesigner: "7.0.0.0.194" Java: "11.0.2" encoding: "UTF-8" JFDML JFormDesigner: "7.0.4.0.360" Java: "16" encoding: "UTF-8"
new FormModel { new FormModel {
contentType: "form/swing" contentType: "form/swing"
@@ -9,7 +9,7 @@ new FormModel {
add( new FormContainer( "com.formdev.flatlaf.testing.FlatTestPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { add( new FormContainer( "com.formdev.flatlaf.testing.FlatTestPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "ltr,insets dialog,hidemode 3" "$layoutConstraints": "ltr,insets dialog,hidemode 3"
"$columnConstraints": "[left][][][][fill]" "$columnConstraints": "[left][][][][fill]"
"$rowConstraints": "[]0[][]0[top][][][][][][37]" "$rowConstraints": "[]0[][]0[top][][][][][][][][37]"
} ) { } ) {
name: "this" name: "this"
add( new FormComponent( "javax.swing.JLabel" ) { add( new FormComponent( "javax.swing.JLabel" ) {
@@ -354,6 +354,40 @@ new FormModel {
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 3 8,grow" "value": "cell 3 8,grow"
} ) } )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "label11"
"text": "JXSearchField:"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 9"
} )
add( new FormComponent( "org.jdesktop.swingx.JXSearchField" ) {
name: "xSearchField1"
"text": "abc"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 9,growx"
} )
add( new FormComponent( "org.jdesktop.swingx.JXSearchField" ) {
name: "xSearchField2"
"enabled": false
"text": "abc"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 9,growx"
} )
add( new FormComponent( "org.jdesktop.swingx.JXSearchField" ) {
name: "xSearchField3"
"recentSearchesSaveKey": "flatlaf.swingx.search.recent"
"text": "abc"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 10,growx"
} )
add( new FormComponent( "org.jdesktop.swingx.JXSearchField" ) {
name: "xSearchField4"
"recentSearchesSaveKey": "flatlaf.swingx.search.recent"
"enabled": false
"text": "abc"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 2 10,growx"
} )
}, new FormLayoutConstraints( null ) { }, new FormLayoutConstraints( null ) {
"location": new java.awt.Point( 0, 0 ) "location": new java.awt.Point( 0, 0 )
"size": new java.awt.Dimension( 700, 600 ) "size": new java.awt.Dimension( 700, 600 )

View File

@@ -29,6 +29,7 @@ import java.util.Locale;
import javax.swing.UIDefaults; import javax.swing.UIDefaults;
import javax.swing.UIManager; import javax.swing.UIManager;
import com.formdev.flatlaf.*; import com.formdev.flatlaf.*;
import com.formdev.flatlaf.testing.FlatTestLaf;
/** /**
* Collects all FlatLaf UI defaults keys and dumps them to a file. * Collects all FlatLaf UI defaults keys and dumps them to a file.
@@ -60,6 +61,7 @@ public class UIDefaultsKeysDump
collectKeys( FlatDarkLaf.class.getName(), keys ); collectKeys( FlatDarkLaf.class.getName(), keys );
collectKeys( FlatIntelliJLaf.class.getName(), keys ); collectKeys( FlatIntelliJLaf.class.getName(), keys );
collectKeys( FlatDarculaLaf.class.getName(), keys ); collectKeys( FlatDarculaLaf.class.getName(), keys );
collectKeys( FlatTestLaf.class.getName(), keys );
// write key file // write key file
try( Writer fileWriter = new BufferedWriter( new FileWriter( keysFile ) ) ) { try( Writer fileWriter = new BufferedWriter( new FileWriter( keysFile ) ) ) {

View File

@@ -400,6 +400,11 @@ ToggleButton.pressedBackground = #FFC800
ToggleButton.toolbar.selectedBackground = #ddd ToggleButton.toolbar.selectedBackground = #ddd
#---- ToolBar ----
ToolBar.focusableButtons = true
#---- ToolTip ---- #---- ToolTip ----
ToolTip.background = #eef ToolTip.background = #eef

View File

@@ -18,6 +18,8 @@ Button.default.background
Button.default.boldText Button.default.boldText
Button.default.borderColor Button.default.borderColor
Button.default.borderWidth Button.default.borderWidth
Button.default.endBackground
Button.default.endBorderColor
Button.default.focusColor Button.default.focusColor
Button.default.focusedBackground Button.default.focusedBackground
Button.default.focusedBorderColor Button.default.focusedBorderColor
@@ -25,12 +27,16 @@ Button.default.foreground
Button.default.hoverBackground Button.default.hoverBackground
Button.default.hoverBorderColor Button.default.hoverBorderColor
Button.default.pressedBackground Button.default.pressedBackground
Button.default.startBackground
Button.default.startBorderColor
Button.defaultButtonFollowsFocus Button.defaultButtonFollowsFocus
Button.disabledBackground Button.disabledBackground
Button.disabledBorderColor Button.disabledBorderColor
Button.disabledForeground Button.disabledForeground
Button.disabledSelectedBackground Button.disabledSelectedBackground
Button.disabledText Button.disabledText
Button.endBackground
Button.endBorderColor
Button.focusInputMap Button.focusInputMap
Button.focusedBackground Button.focusedBackground
Button.focusedBorderColor Button.focusedBorderColor
@@ -49,6 +55,8 @@ Button.rollover
Button.selectedBackground Button.selectedBackground
Button.selectedForeground Button.selectedForeground
Button.shadow Button.shadow
Button.startBackground
Button.startBorderColor
Button.textIconGap Button.textIconGap
Button.textShiftOffset Button.textShiftOffset
Button.toolbar.hoverBackground Button.toolbar.hoverBackground
@@ -142,6 +150,7 @@ ComboBox.buttonBackground
ComboBox.buttonDarkShadow ComboBox.buttonDarkShadow
ComboBox.buttonDisabledArrowColor ComboBox.buttonDisabledArrowColor
ComboBox.buttonEditableBackground ComboBox.buttonEditableBackground
ComboBox.buttonFocusedBackground
ComboBox.buttonHighlight ComboBox.buttonHighlight
ComboBox.buttonHoverArrowColor ComboBox.buttonHoverArrowColor
ComboBox.buttonPressedArrowColor ComboBox.buttonPressedArrowColor
@@ -150,6 +159,7 @@ ComboBox.buttonStyle
ComboBox.disabledBackground ComboBox.disabledBackground
ComboBox.disabledForeground ComboBox.disabledForeground
ComboBox.editorColumns ComboBox.editorColumns
ComboBox.focusedBackground
ComboBox.font ComboBox.font
ComboBox.foreground ComboBox.foreground
ComboBox.isEnterSelectablePopup ComboBox.isEnterSelectablePopup
@@ -157,6 +167,7 @@ ComboBox.maximumRowCount
ComboBox.minimumWidth ComboBox.minimumWidth
ComboBox.noActionOnKeyNavigation ComboBox.noActionOnKeyNavigation
ComboBox.padding ComboBox.padding
ComboBox.popupBackground
ComboBox.selectionBackground ComboBox.selectionBackground
ComboBox.selectionForeground ComboBox.selectionForeground
ComboBox.timeFactor ComboBox.timeFactor
@@ -197,6 +208,7 @@ EditorPane.caretBlinkRate
EditorPane.caretForeground EditorPane.caretForeground
EditorPane.disabledBackground EditorPane.disabledBackground
EditorPane.focusInputMap EditorPane.focusInputMap
EditorPane.focusedBackground
EditorPane.font EditorPane.font
EditorPane.foreground EditorPane.foreground
EditorPane.inactiveBackground EditorPane.inactiveBackground
@@ -226,6 +238,7 @@ FormattedTextField.caretBlinkRate
FormattedTextField.caretForeground FormattedTextField.caretForeground
FormattedTextField.disabledBackground FormattedTextField.disabledBackground
FormattedTextField.focusInputMap FormattedTextField.focusInputMap
FormattedTextField.focusedBackground
FormattedTextField.font FormattedTextField.font
FormattedTextField.foreground FormattedTextField.foreground
FormattedTextField.inactiveBackground FormattedTextField.inactiveBackground
@@ -295,7 +308,9 @@ JXBusyLabel.baseColor
JXBusyLabel.highlightColor JXBusyLabel.highlightColor
JXDatePicker.border JXDatePicker.border
JXHeader.background JXHeader.background
JXHeader.descriptionForeground
JXHeader.startBackground JXHeader.startBackground
JXHeader.titleForeground
JXMonthView.arrowColor JXMonthView.arrowColor
JXMonthView.background JXMonthView.background
JXMonthView.daysOfTheWeekForeground JXMonthView.daysOfTheWeekForeground
@@ -475,6 +490,11 @@ OptionPane.buttonPadding
OptionPane.errorIcon OptionPane.errorIcon
OptionPane.font OptionPane.font
OptionPane.foreground OptionPane.foreground
OptionPane.icon.errorColor
OptionPane.icon.foreground
OptionPane.icon.informationColor
OptionPane.icon.questionColor
OptionPane.icon.warningColor
OptionPane.iconMessageGap OptionPane.iconMessageGap
OptionPane.informationIcon OptionPane.informationIcon
OptionPane.maxCharactersPerLine OptionPane.maxCharactersPerLine
@@ -500,6 +520,7 @@ PasswordField.caretForeground
PasswordField.disabledBackground PasswordField.disabledBackground
PasswordField.echoChar PasswordField.echoChar
PasswordField.focusInputMap PasswordField.focusInputMap
PasswordField.focusedBackground
PasswordField.font PasswordField.font
PasswordField.foreground PasswordField.foreground
PasswordField.inactiveBackground PasswordField.inactiveBackground
@@ -629,6 +650,21 @@ ScrollPane.font
ScrollPane.foreground ScrollPane.foreground
ScrollPane.smoothScrolling ScrollPane.smoothScrolling
ScrollPaneUI ScrollPaneUI
SearchField.clearIcon
SearchField.clearIconColor
SearchField.clearIconHoverColor
SearchField.clearIconPressedColor
SearchField.clearPressedIcon
SearchField.clearRolloverIcon
SearchField.icon
SearchField.popupIcon
SearchField.popupPressedIcon
SearchField.popupRolloverIcon
SearchField.pressedIcon
SearchField.rolloverIcon
SearchField.searchIconColor
SearchField.searchIconHoverColor
SearchField.searchIconPressedColor
Separator.background Separator.background
Separator.foreground Separator.foreground
Separator.height Separator.height
@@ -651,11 +687,14 @@ Slider.foreground
Slider.highlight Slider.highlight
Slider.horizontalSize Slider.horizontalSize
Slider.hoverThumbColor Slider.hoverThumbColor
Slider.hoverTrackColor
Slider.minimumHorizontalSize Slider.minimumHorizontalSize
Slider.minimumVerticalSize Slider.minimumVerticalSize
Slider.onlyLeftMouseButtonDrag Slider.onlyLeftMouseButtonDrag
Slider.pressedThumbColor Slider.pressedThumbColor
Slider.pressedTrackColor
Slider.shadow Slider.shadow
Slider.thumbBorderColor
Slider.thumbColor Slider.thumbColor
Slider.thumbSize Slider.thumbSize
Slider.tickColor Slider.tickColor
@@ -678,6 +717,7 @@ Spinner.disabledBackground
Spinner.disabledForeground Spinner.disabledForeground
Spinner.editorAlignment Spinner.editorAlignment
Spinner.editorBorderPainted Spinner.editorBorderPainted
Spinner.focusedBackground
Spinner.font Spinner.font
Spinner.foreground Spinner.foreground
Spinner.padding Spinner.padding
@@ -753,6 +793,7 @@ TabbedPane.tabHeight
TabbedPane.tabInsets TabbedPane.tabInsets
TabbedPane.tabRunOverlay TabbedPane.tabRunOverlay
TabbedPane.tabSelectionHeight TabbedPane.tabSelectionHeight
TabbedPane.tabSeparatorColor
TabbedPane.tabSeparatorsFullHeight TabbedPane.tabSeparatorsFullHeight
TabbedPane.tabWidthMode TabbedPane.tabWidthMode
TabbedPane.tabsOpaque TabbedPane.tabsOpaque
@@ -820,6 +861,7 @@ TextArea.caretBlinkRate
TextArea.caretForeground TextArea.caretForeground
TextArea.disabledBackground TextArea.disabledBackground
TextArea.focusInputMap TextArea.focusInputMap
TextArea.focusedBackground
TextArea.font TextArea.font
TextArea.foreground TextArea.foreground
TextArea.inactiveBackground TextArea.inactiveBackground
@@ -838,6 +880,7 @@ TextField.caretForeground
TextField.darkShadow TextField.darkShadow
TextField.disabledBackground TextField.disabledBackground
TextField.focusInputMap TextField.focusInputMap
TextField.focusedBackground
TextField.font TextField.font
TextField.foreground TextField.foreground
TextField.highlight TextField.highlight
@@ -856,6 +899,7 @@ TextPane.caretBlinkRate
TextPane.caretForeground TextPane.caretForeground
TextPane.disabledBackground TextPane.disabledBackground
TextPane.focusInputMap TextPane.focusInputMap
TextPane.focusedBackground
TextPane.font TextPane.font
TextPane.foreground TextPane.foreground
TextPane.inactiveBackground TextPane.inactiveBackground
@@ -865,6 +909,7 @@ TextPane.selectionBackground
TextPane.selectionForeground TextPane.selectionForeground
TextPaneUI TextPaneUI
TitlePane.background TitlePane.background
TitlePane.borderColor
TitlePane.buttonHoverBackground TitlePane.buttonHoverBackground
TitlePane.buttonMaximizedHeight TitlePane.buttonMaximizedHeight
TitlePane.buttonPressedBackground TitlePane.buttonPressedBackground
@@ -902,9 +947,11 @@ ToggleButton.disabledBackground
ToggleButton.disabledSelectedBackground ToggleButton.disabledSelectedBackground
ToggleButton.disabledText ToggleButton.disabledText
ToggleButton.focusInputMap ToggleButton.focusInputMap
ToggleButton.focusedBackground
ToggleButton.font ToggleButton.font
ToggleButton.foreground ToggleButton.foreground
ToggleButton.highlight ToggleButton.highlight
ToggleButton.hoverBackground
ToggleButton.iconTextGap ToggleButton.iconTextGap
ToggleButton.light ToggleButton.light
ToggleButton.margin ToggleButton.margin
@@ -916,6 +963,7 @@ ToggleButton.shadow
ToggleButton.tab.disabledUnderlineColor ToggleButton.tab.disabledUnderlineColor
ToggleButton.tab.focusBackground ToggleButton.tab.focusBackground
ToggleButton.tab.hoverBackground ToggleButton.tab.hoverBackground
ToggleButton.tab.selectedBackground
ToggleButton.tab.underlineColor ToggleButton.tab.underlineColor
ToggleButton.tab.underlineHeight ToggleButton.tab.underlineHeight
ToggleButton.textIconGap ToggleButton.textIconGap
@@ -933,6 +981,7 @@ ToolBar.dockingBackground
ToolBar.dockingForeground ToolBar.dockingForeground
ToolBar.floatingBackground ToolBar.floatingBackground
ToolBar.floatingForeground ToolBar.floatingForeground
ToolBar.focusableButtons
ToolBar.font ToolBar.font
ToolBar.foreground ToolBar.foreground
ToolBar.gripColor ToolBar.gripColor
@@ -962,6 +1011,7 @@ Tree.dropCellBackground
Tree.dropCellForeground Tree.dropCellForeground
Tree.dropLineColor Tree.dropLineColor
Tree.editorBorder Tree.editorBorder
Tree.editorBorderSelectionColor
Tree.expandedIcon Tree.expandedIcon
Tree.focusInputMap Tree.focusInputMap
Tree.focusInputMap.RightToLeft Tree.focusInputMap.RightToLeft