Compare commits

..

48 Commits
1.2 ... 1.4

Author SHA1 Message Date
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
Karl Tauber
1e869973d4 release 1.3 2021-07-02 10:40:27 +02:00
Karl Tauber
731c8962c9 added missing since 1.3 2021-07-02 10:21:55 +02:00
Karl Tauber
294b8bb789 Extras: FlatInspector: fixed border value when class hierarchy is enabled 2021-07-02 10:14:51 +02:00
Karl Tauber
4f9b819f48 Spinner: reduced gap between up and down arrows, which was increased by previous commit (issue #329) 2021-06-30 18:57:54 +02:00
Karl Tauber
5318d5fa8e ScrollBar: fixed left/top arrow icon location (if visible) (issue #329)
(tested using FlatPaintingTest)
2021-06-30 18:47:16 +02:00
Karl Tauber
98b156bdde TextComponents: use focusedBackground also if not editable (but enabled)
(PR #338)
2021-06-30 00:01:33 +02:00
Karl Tauber
511dd02107 JIDE: build using latest version of JIDE library com.formdev:jide-oss:3.7.12 2021-06-29 22:58:42 +02:00
Karl Tauber
f1f7a2e7b6 Extras: FlatInspector: fixed missing "UI" row on Java 9+ 2021-06-27 23:19:36 +02:00
Karl Tauber
d557cf5427 FlatTestFrame: do not print stack trace if lafs.properties does not exist 2021-06-27 21:36:49 +02:00
Karl Tauber
39d2941099 removed duplicate ; 2021-06-25 10:48:00 +02:00
Karl Tauber
2a732306a1 ComboBox: renamed UI key ComboBox.popupFocusedBackground to ComboBox.popupBackground 2021-06-22 08:59:11 +02:00
Karl Tauber
8a72b30cbc Merge pull request #338 from Chrriis/focusedBackground
Issue #335: allow a different background on focus
2021-06-15 11:57:17 +02:00
Karl Tauber
ed9cb0f918 Spinner: support Spinner.focusedBackground
ComboBox:
- prefer explicit set background color over focusedBackground
- if ComboBox.buttonFocusedBackground is not specified use ComboBox.focusedBackground
- added ComboBox.popupFocusedBackground

(issue #335)
2021-06-15 11:50:30 +02:00
Karl Tauber
7e0915cb9c FlatBorder: refractored ComboBox, ScrollPane and Spinner focus owner checking to UI delegates (for later usage) 2021-06-13 11:21:55 +02:00
Karl Tauber
a51294d570 TextComponents:
- use focusedBackground only if editable (and enabled)
- prefer explicit set background color over focusedBackground
- added FlatTextFieldUI.getBackground() used by all text components
- support EditorPane.focusedBackground
- support TextPane.focusedBackground

(issue #335)
2021-06-12 20:46:59 +02:00
Karl Tauber
d962f218a1 ToolTip: fixed positioning of huge tooltips (issue #333) 2021-06-11 20:53:09 +02:00
Karl Tauber
7b248427f0 fixed white lines at bottom and right side of window (in dark themes on HiDPI screens with scaling enabled) 2021-06-11 16:16:41 +02:00
Christopher Deckers
b99fb8b11f Use focused background color for combo popups. 2021-06-09 09:56:50 +02:00
Christopher Deckers
26250e790f Issue #335: allow a different background on focus. 2021-06-08 10:12:59 +02:00
Karl Tauber
b26dbe81f4 README.md: changed deprecated FlatLightLaf.install() to FlatLightLaf.setup() 2021-06-01 16:23:54 +02:00
Karl Tauber
903212345b .gitbugtraq added (for SmartGit) 2021-06-01 16:21:58 +02:00
70 changed files with 2098 additions and 437 deletions

8
.gitbugtraq Normal file
View File

@@ -0,0 +1,8 @@
# links issue numbers in git commit messages to issue tracker
# https://github.com/mstrap/bugtraq
# for SmartGit - https://www.syntevo.com/smartgit/
[bugtraq]
url = "https://github.com/JFormDesigner/FlatLaf/issues/%BUGID%"
loglinkregex = "#[0-9]{1,5}"
logregex = "[0-9]{1,5}"

View File

@@ -1,6 +1,70 @@
FlatLaf Change Log FlatLaf Change Log
================== ==================
## 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 values
`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
#### New features and improvements
- TextComponents, ComboBox and Spinner: Support different background color when
component is focused (use UI values `TextField.focusedBackground`,
`PasswordField.focusedBackground`, `FormattedTextField.focusedBackground`,
`TextArea.focusedBackground`, `TextPane.focusedBackground`,
`EditorPane.focusedBackground`, `ComboBox.focusedBackground`,
`ComboBox.buttonFocusedBackground`, `ComboBox.popupBackground` and
`Spinner.focusedBackground`). (issue #335)
#### Fixed bugs
- Fixed white lines at bottom and right side of window (in dark themes on HiDPI
screens with scaling enabled).
- ScrollBar: Fixed left/top arrow icon location (if visible). (issue #329)
- Spinner: Fixed up/down arrow icon location.
- ToolTip: Fixed positioning of huge tooltips. (issue #333)
## 1.2 ## 1.2
#### New features and improvements #### New features and improvements

View File

@@ -76,11 +76,11 @@ Addons
Getting started Getting started
--------------- ---------------
To enable FlatLaf, add following code to your main method before you create any To use FlatLaf, add following code to your main method before you create any
Swing component: Swing component:
~~~java ~~~java
FlatLightLaf.install(); FlatLightLaf.setup();
// create UI here... // create UI here...
~~~ ~~~

View File

@@ -14,8 +14,8 @@
* limitations under the License. * limitations under the License.
*/ */
val releaseVersion = "1.2" val releaseVersion = "1.4"
val developmentVersion = "1.3-SNAPSHOT" val developmentVersion = "1.5-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

@@ -128,7 +128,7 @@ class LinuxFontPolicy
// find last word in family // find last word in family
int index = family.lastIndexOf( ' ' ); int index = family.lastIndexOf( ' ' );
if( index < 0 ) if( index < 0 )
return createFont( "Dialog", style, size, dsize );; return createFont( "Dialog", style, size, dsize );
// check whether last work contains some font weight (e.g. Ultra-Bold or Heavy) // check whether last work contains some font weight (e.g. Ultra-Bold or Heavy)
String lastWord = family.substring( index + 1 ).toLowerCase(); String lastWord = family.substring( index + 1 ).toLowerCase();
@@ -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

@@ -48,8 +48,8 @@ public class FlatArrowButton
protected final Color pressedBackground; protected final Color pressedBackground;
private int arrowWidth = DEFAULT_ARROW_WIDTH; private int arrowWidth = DEFAULT_ARROW_WIDTH;
private int xOffset = 0; private float xOffset = 0;
private int yOffset = 0; private float yOffset = 0;
private boolean hover; private boolean hover;
private boolean pressed; private boolean pressed;
@@ -117,19 +117,19 @@ public class FlatArrowButton
return pressed; return pressed;
} }
public int getXOffset() { public float getXOffset() {
return xOffset; return xOffset;
} }
public void setXOffset( int xOffset ) { public void setXOffset( float xOffset ) {
this.xOffset = xOffset; this.xOffset = xOffset;
} }
public int getYOffset() { public float getYOffset() {
return yOffset; return yOffset;
} }
public void setYOffset( int yOffset ) { public void setYOffset( float yOffset ) {
this.yOffset = yOffset; this.yOffset = yOffset;
} }

View File

@@ -22,17 +22,12 @@ import java.awt.Component;
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.KeyboardFocusManager;
import java.awt.Paint; import java.awt.Paint;
import javax.swing.JComboBox; import javax.swing.JComboBox;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.JScrollPane; import javax.swing.JScrollPane;
import javax.swing.JSpinner; import javax.swing.JSpinner;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.JTree;
import javax.swing.JViewport; import javax.swing.JViewport;
import javax.swing.SwingUtilities;
import javax.swing.UIManager; import javax.swing.UIManager;
import javax.swing.plaf.basic.BasicBorders; import javax.swing.plaf.basic.BasicBorders;
import com.formdev.flatlaf.FlatClientProperties; import com.formdev.flatlaf.FlatClientProperties;
@@ -164,37 +159,13 @@ public class FlatBorder
} }
protected boolean isFocused( Component c ) { protected boolean isFocused( Component c ) {
if( c instanceof JScrollPane ) { if( c instanceof JScrollPane )
JViewport viewport = ((JScrollPane)c).getViewport(); return FlatScrollPaneUI.isPermanentFocusOwner( (JScrollPane) c );
Component view = (viewport != null) ? viewport.getView() : null; else if( c instanceof JComboBox )
if( view != null ) { return FlatComboBoxUI.isPermanentFocusOwner( (JComboBox<?>) c );
if( FlatUIUtils.isPermanentFocusOwner( view ) ) else if( c instanceof JSpinner )
return true; return FlatSpinnerUI.isPermanentFocusOwner( (JSpinner) c );
else
if( (view instanceof JTable && ((JTable)view).isEditing()) ||
(view instanceof JTree && ((JTree)view).isEditing()) )
{
Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
if( focusOwner != null )
return SwingUtilities.isDescendingFrom( focusOwner, view );
}
}
return false;
} else if( c instanceof JComboBox && ((JComboBox<?>)c).isEditable() ) {
Component editorComponent = ((JComboBox<?>)c).getEditor().getEditorComponent();
return (editorComponent != null) ? FlatUIUtils.isPermanentFocusOwner( editorComponent ) : false;
} else if( c instanceof JSpinner ) {
if( FlatUIUtils.isPermanentFocusOwner( c ) )
return true;
JComponent editor = ((JSpinner)c).getEditor();
if( editor instanceof JSpinner.DefaultEditor ) {
JTextField textField = ((JSpinner.DefaultEditor)editor).getTextField();
if( textField != null )
return FlatUIUtils.isPermanentFocusOwner( textField );
}
return false;
} else
return FlatUIUtils.isPermanentFocusOwner( c ); return FlatUIUtils.isPermanentFocusOwner( c );
} }
@@ -205,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

@@ -501,9 +501,9 @@ public class FlatButtonUI
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 ) {
// 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;

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,6 +17,7 @@
package com.formdev.flatlaf.ui; package com.formdev.flatlaf.ui;
import static com.formdev.flatlaf.util.UIScale.scale; import static com.formdev.flatlaf.util.UIScale.scale;
import 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;
@@ -39,7 +40,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;
@@ -61,13 +61,13 @@ import javax.swing.UIManager;
import javax.swing.border.AbstractBorder; import javax.swing.border.AbstractBorder;
import javax.swing.border.Border; import javax.swing.border.Border;
import javax.swing.plaf.ComponentUI; import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.UIResource;
import javax.swing.plaf.basic.BasicComboBoxUI; import javax.swing.plaf.basic.BasicComboBoxUI;
import javax.swing.plaf.basic.BasicComboPopup; import javax.swing.plaf.basic.BasicComboPopup;
import javax.swing.plaf.basic.ComboPopup; import javax.swing.plaf.basic.ComboPopup;
import javax.swing.text.JTextComponent; import javax.swing.text.JTextComponent;
import com.formdev.flatlaf.FlatClientProperties; import com.formdev.flatlaf.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}.
@@ -92,14 +92,17 @@ import com.formdev.flatlaf.util.UIScale;
* @uiDefault Component.borderColor Color * @uiDefault Component.borderColor Color
* @uiDefault Component.disabledBorderColor Color * @uiDefault Component.disabledBorderColor Color
* @uiDefault ComboBox.editableBackground Color optional; defaults to ComboBox.background * @uiDefault ComboBox.editableBackground Color optional; defaults to ComboBox.background
* @uiDefault ComboBox.focusedBackground Color optional
* @uiDefault ComboBox.disabledBackground Color * @uiDefault ComboBox.disabledBackground Color
* @uiDefault ComboBox.disabledForeground Color * @uiDefault ComboBox.disabledForeground Color
* @uiDefault ComboBox.buttonBackground Color * @uiDefault ComboBox.buttonBackground Color
* @uiDefault ComboBox.buttonEditableBackground Color * @uiDefault ComboBox.buttonEditableBackground Color
* @uiDefault ComboBox.buttonFocusedBackground Color optional; defaults to ComboBox.focusedBackground
* @uiDefault ComboBox.buttonArrowColor Color * @uiDefault ComboBox.buttonArrowColor Color
* @uiDefault ComboBox.buttonDisabledArrowColor Color * @uiDefault ComboBox.buttonDisabledArrowColor Color
* @uiDefault ComboBox.buttonHoverArrowColor Color * @uiDefault ComboBox.buttonHoverArrowColor Color
* @uiDefault ComboBox.buttonPressedArrowColor Color * @uiDefault ComboBox.buttonPressedArrowColor Color
* @uiDefault ComboBox.popupBackground Color optional
* *
* @author Karl Tauber * @author Karl Tauber
*/ */
@@ -115,21 +118,25 @@ public class FlatComboBoxUI
protected Color disabledBorderColor; protected Color disabledBorderColor;
protected Color editableBackground; protected Color editableBackground;
protected Color focusedBackground;
protected Color disabledBackground; protected Color disabledBackground;
protected Color disabledForeground; protected Color disabledForeground;
protected Color buttonBackground; protected Color buttonBackground;
protected Color buttonEditableBackground; protected Color buttonEditableBackground;
protected Color buttonFocusedBackground;
protected Color buttonArrowColor; protected Color buttonArrowColor;
protected Color buttonDisabledArrowColor; protected Color buttonDisabledArrowColor;
protected Color buttonHoverArrowColor; protected Color buttonHoverArrowColor;
protected Color buttonPressedArrowColor; protected Color buttonPressedArrowColor;
protected Color popupBackground;
private MouseListener hoverListener; private MouseListener hoverListener;
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();
@@ -195,23 +202,26 @@ public class FlatComboBoxUI
disabledBorderColor = UIManager.getColor( "Component.disabledBorderColor" ); disabledBorderColor = UIManager.getColor( "Component.disabledBorderColor" );
editableBackground = UIManager.getColor( "ComboBox.editableBackground" ); editableBackground = UIManager.getColor( "ComboBox.editableBackground" );
focusedBackground = UIManager.getColor( "ComboBox.focusedBackground" );
disabledBackground = UIManager.getColor( "ComboBox.disabledBackground" ); disabledBackground = UIManager.getColor( "ComboBox.disabledBackground" );
disabledForeground = UIManager.getColor( "ComboBox.disabledForeground" ); disabledForeground = UIManager.getColor( "ComboBox.disabledForeground" );
buttonBackground = UIManager.getColor( "ComboBox.buttonBackground" ); buttonBackground = UIManager.getColor( "ComboBox.buttonBackground" );
buttonFocusedBackground = UIManager.getColor( "ComboBox.buttonFocusedBackground" );
buttonEditableBackground = UIManager.getColor( "ComboBox.buttonEditableBackground" ); buttonEditableBackground = UIManager.getColor( "ComboBox.buttonEditableBackground" );
buttonArrowColor = UIManager.getColor( "ComboBox.buttonArrowColor" ); buttonArrowColor = UIManager.getColor( "ComboBox.buttonArrowColor" );
buttonDisabledArrowColor = UIManager.getColor( "ComboBox.buttonDisabledArrowColor" ); buttonDisabledArrowColor = UIManager.getColor( "ComboBox.buttonDisabledArrowColor" );
buttonHoverArrowColor = UIManager.getColor( "ComboBox.buttonHoverArrowColor" ); buttonHoverArrowColor = UIManager.getColor( "ComboBox.buttonHoverArrowColor" );
buttonPressedArrowColor = UIManager.getColor( "ComboBox.buttonPressedArrowColor" ); buttonPressedArrowColor = UIManager.getColor( "ComboBox.buttonPressedArrowColor" );
popupBackground = UIManager.getColor( "ComboBox.popupBackground" );
// set maximumRowCount // set maximumRowCount
int maximumRowCount = UIManager.getInt( "ComboBox.maximumRowCount" ); int maximumRowCount = UIManager.getInt( "ComboBox.maximumRowCount" );
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 );
} }
@@ -224,16 +234,22 @@ public class FlatComboBoxUI
disabledBorderColor = null; disabledBorderColor = null;
editableBackground = null; editableBackground = null;
focusedBackground = null;
disabledBackground = null; disabledBackground = null;
disabledForeground = null; disabledForeground = null;
buttonBackground = null; buttonBackground = null;
buttonEditableBackground = null; buttonEditableBackground = null;
buttonFocusedBackground = null;
buttonArrowColor = null; buttonArrowColor = null;
buttonDisabledArrowColor = null; buttonDisabledArrowColor = null;
buttonHoverArrowColor = null; buttonHoverArrowColor = null;
buttonPressedArrowColor = null; buttonPressedArrowColor = null;
popupBackground = null;
paddingBorder.uninstall();
MigLayoutVisualPadding.uninstall( comboBox ); MigLayoutVisualPadding.uninstall( comboBox );
} }
@@ -260,11 +276,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 ) );
}
} }
}; };
} }
@@ -355,6 +366,7 @@ public class FlatComboBoxUI
editor.applyComponentOrientation( comboBox.getComponentOrientation() ); editor.applyComponentOrientation( comboBox.getComponentOrientation() );
updateEditorPadding();
updateEditorColors(); updateEditorColors();
// macOS // macOS
@@ -371,6 +383,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
@@ -423,7 +454,11 @@ public class FlatComboBoxUI
// paint arrow button background // paint arrow button background
if( enabled && !isCellRenderer ) { if( enabled && !isCellRenderer ) {
g2.setColor( paintButton ? buttonEditableBackground : buttonBackground ); g2.setColor( paintButton
? buttonEditableBackground
: (buttonFocusedBackground != null || focusedBackground != null) && isPermanentFocusOwner( comboBox )
? (buttonFocusedBackground != null ? buttonFocusedBackground : focusedBackground)
: buttonBackground );
Shape oldClip = g2.getClip(); Shape oldClip = g2.getClip();
if( isLeftToRight ) if( isLeftToRight )
g2.clipRect( arrowX, 0, width - arrowX, height ); g2.clipRect( arrowX, 0, width - arrowX, height );
@@ -451,30 +486,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
@@ -483,9 +512,20 @@ public class FlatComboBoxUI
} }
protected Color getBackground( boolean enabled ) { protected Color getBackground( boolean enabled ) {
return enabled if( enabled ) {
? (editableBackground != null && comboBox.isEditable() ? editableBackground : comboBox.getBackground()) Color background = comboBox.getBackground();
: (isIntelliJTheme ? FlatUIUtils.getParentBackground( comboBox ) : disabledBackground);
// always use explicitly set color
if( !(background instanceof UIResource) )
return background;
// focused
if( focusedBackground != null && isPermanentFocusOwner( comboBox ) )
return focusedBackground;
return (editableBackground != null && comboBox.isEditable()) ? editableBackground : background;
} else
return isIntelliJTheme ? FlatUIUtils.getParentBackground( comboBox ) : disabledBackground;
} }
protected Color getForeground( boolean enabled ) { protected Color getForeground( boolean enabled ) {
@@ -495,77 +535,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;
} }
@@ -576,6 +588,17 @@ public class FlatComboBoxUI
return parentParent != null && !comboBox.getBackground().equals( parentParent.getBackground() ); return parentParent != null && !comboBox.getBackground().equals( parentParent.getBackground() );
} }
/**
* @since 1.3
*/
public static boolean isPermanentFocusOwner( JComboBox<?> comboBox ) {
if( comboBox.isEditable() ) {
Component editorComponent = comboBox.getEditor().getEditorComponent();
return (editorComponent != null) ? FlatUIUtils.isPermanentFocusOwner( editorComponent ) : false;
} else
return FlatUIUtils.isPermanentFocusOwner( comboBox );
}
//---- class FlatComboBoxButton ------------------------------------------- //---- class FlatComboBoxButton -------------------------------------------
protected class FlatComboBoxButton protected class FlatComboBoxButton
@@ -618,13 +641,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();
@@ -688,6 +709,8 @@ public class FlatComboBoxUI
super.configureList(); super.configureList();
list.setCellRenderer( new PopupListCellRenderer() ); list.setCellRenderer( new PopupListCellRenderer() );
if( popupBackground != null )
list.setBackground( popupBackground );
} }
@Override @Override
@@ -701,6 +724,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
@@ -710,22 +746,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;
} }
@@ -735,49 +764,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

@@ -17,15 +17,16 @@
package com.formdev.flatlaf.ui; package com.formdev.flatlaf.ui;
import static com.formdev.flatlaf.util.UIScale.scale; import static com.formdev.flatlaf.util.UIScale.scale;
import java.awt.Color;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.awt.event.FocusListener;
import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeEvent;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.JEditorPane; import javax.swing.JEditorPane;
import javax.swing.UIManager; import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI; import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.UIResource;
import javax.swing.plaf.basic.BasicEditorPaneUI; import javax.swing.plaf.basic.BasicEditorPaneUI;
import javax.swing.text.JTextComponent; import javax.swing.text.JTextComponent;
import com.formdev.flatlaf.FlatClientProperties; import com.formdev.flatlaf.FlatClientProperties;
@@ -53,6 +54,7 @@ import com.formdev.flatlaf.util.HiDPIUtils;
* *
* @uiDefault Component.minimumWidth int * @uiDefault Component.minimumWidth int
* @uiDefault Component.isIntelliJTheme boolean * @uiDefault Component.isIntelliJTheme boolean
* @uiDefault EditorPane.focusedBackground Color optional
* *
* @author Karl Tauber * @author Karl Tauber
*/ */
@@ -61,8 +63,10 @@ public class FlatEditorPaneUI
{ {
protected int minimumWidth; protected int minimumWidth;
protected boolean isIntelliJTheme; protected boolean isIntelliJTheme;
protected Color focusedBackground;
private Object oldHonorDisplayProperties; private Object oldHonorDisplayProperties;
private FocusListener focusListener;
public static ComponentUI createUI( JComponent c ) { public static ComponentUI createUI( JComponent c ) {
return new FlatEditorPaneUI(); return new FlatEditorPaneUI();
@@ -72,8 +76,10 @@ public class FlatEditorPaneUI
protected void installDefaults() { protected void installDefaults() {
super.installDefaults(); super.installDefaults();
String prefix = getPropertyPrefix();
minimumWidth = UIManager.getInt( "Component.minimumWidth" ); minimumWidth = UIManager.getInt( "Component.minimumWidth" );
isIntelliJTheme = UIManager.getBoolean( "Component.isIntelliJTheme" ); isIntelliJTheme = UIManager.getBoolean( "Component.isIntelliJTheme" );
focusedBackground = UIManager.getColor( prefix + ".focusedBackground" );
// 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 );
@@ -84,9 +90,28 @@ public class FlatEditorPaneUI
protected void uninstallDefaults() { protected void uninstallDefaults() {
super.uninstallDefaults(); super.uninstallDefaults();
focusedBackground = null;
getComponent().putClientProperty( JEditorPane.HONOR_DISPLAY_PROPERTIES, oldHonorDisplayProperties ); getComponent().putClientProperty( JEditorPane.HONOR_DISPLAY_PROPERTIES, oldHonorDisplayProperties );
} }
@Override
protected void installListeners() {
super.installListeners();
// necessary to update focus background
focusListener = new FlatUIUtils.RepaintFocusListener( getComponent(), c -> focusedBackground != null );
getComponent().addFocusListener( focusListener );
}
@Override
protected void uninstallListeners() {
super.uninstallListeners();
getComponent().removeFocusListener( focusListener );
focusListener = null;
}
@Override @Override
protected void propertyChange( PropertyChangeEvent e ) { protected void propertyChange( PropertyChangeEvent e ) {
super.propertyChange( e ); super.propertyChange( e );
@@ -128,14 +153,11 @@ public class FlatEditorPaneUI
@Override @Override
protected void paintBackground( Graphics g ) { protected void paintBackground( Graphics g ) {
JTextComponent c = getComponent(); paintBackground( g, getComponent(), isIntelliJTheme, focusedBackground );
// for compatibility with IntelliJ themes
if( isIntelliJTheme && (!c.isEnabled() || !c.isEditable()) && (c.getBackground() instanceof UIResource) ) {
FlatUIUtils.paintParentBackground( g, c );
return;
} }
super.paintBackground( g ); static void paintBackground( Graphics g, JTextComponent c, boolean isIntelliJTheme, Color focusedBackground ) {
g.setColor( FlatTextFieldUI.getBackground( c, isIntelliJTheme, focusedBackground ) );
g.fillRect( 0, 0, c.getWidth(), c.getHeight() );
} }
} }

View File

@@ -39,11 +39,10 @@ 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
* @uiDefault FormattedTextField.focusedBackground Color optional
* @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
* *

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,11 +198,10 @@ 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 );
} }
} }
}
private Component findByName( Container c, String name ) { private Component findByName( Container c, String name ) {
for( Component child : c.getComponents() ) { for( Component child : c.getComponents() ) {

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,68 +53,67 @@ 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.showCapsLock boolean * @uiDefault PasswordField.focusedBackground Color optional
* @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 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 );
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;
capsLockIcon = null; capsLockIcon = null;
MigLayoutVisualPadding.uninstall( getComponent() );
} }
@Override @Override
protected void installListeners() { protected void installListeners() {
super.installListeners(); super.installListeners();
focusListener = new FlatUIUtils.RepaintFocusListener( getComponent() ); // update caps lock indicator
capsLockListener = new KeyAdapter() { capsLockListener = new KeyAdapter() {
@Override @Override
public void keyPressed( KeyEvent e ) { public void keyPressed( KeyEvent e ) {
@@ -124,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 );
} }
@@ -137,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 ); // 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

@@ -20,12 +20,16 @@ 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.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Insets; import java.awt.Insets;
import java.awt.MouseInfo; import java.awt.MouseInfo;
import java.awt.Panel; import java.awt.Panel;
import java.awt.Point; import java.awt.Point;
import java.awt.PointerInfo; import java.awt.PointerInfo;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.Window; import java.awt.Window;
import java.awt.event.ComponentEvent; import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener; import java.awt.event.ComponentListener;
@@ -40,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;
@@ -63,7 +68,7 @@ public class FlatPopupFactory
public Popup getPopup( Component owner, Component contents, int x, int y ) public Popup getPopup( Component owner, Component contents, int x, int y )
throws IllegalArgumentException throws IllegalArgumentException
{ {
Point pt = fixToolTipLocation( contents, x, y ); Point pt = fixToolTipLocation( owner, contents, x, y );
if( pt != null ) { if( pt != null ) {
x = pt.x; x = pt.x;
y = pt.y; y = pt.y;
@@ -207,13 +212,13 @@ public class FlatPopupFactory
/** /**
* Usually ToolTipManager places a tooltip at (mouseLocation.x, mouseLocation.y + 20). * Usually ToolTipManager places a tooltip at (mouseLocation.x, mouseLocation.y + 20).
* In case that the tooltip would be partly outside of the screen, * In case that the tooltip would be partly outside of the screen,
* ToolTipManagerthe changes the location so that the entire tooltip fits on screen. * the ToolTipManager changes the location so that the entire tooltip fits on screen.
* But this can place the tooltip under the mouse location and hide the owner component. * But this can place the tooltip under the mouse location and hide the owner component.
* <p> * <p>
* This method checks whether the current mouse location is within tooltip bounds * This method checks whether the current mouse location is within tooltip bounds
* and corrects the y-location so that the tooltip is placed above the mouse location. * and corrects the y-location so that the tooltip is placed above the mouse location.
*/ */
private Point fixToolTipLocation( Component contents, int x, int y ) { private Point fixToolTipLocation( Component owner, Component contents, int x, int y ) {
if( !(contents instanceof JToolTip) || !wasInvokedFromToolTipManager() ) if( !(contents instanceof JToolTip) || !wasInvokedFromToolTipManager() )
return null; return null;
@@ -229,18 +234,34 @@ public class FlatPopupFactory
if( !tipBounds.contains( mouseLocation ) ) if( !tipBounds.contains( mouseLocation ) )
return null; return null;
// place tooltip above mouse location // find GraphicsConfiguration at mouse location (similar to ToolTipManager.getDrawingGC())
return new Point( x, mouseLocation.y - tipSize.height - UIScale.scale( 20 ) ); GraphicsConfiguration gc = null;
for( GraphicsDevice device : GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices() ) {
GraphicsConfiguration dgc = device.getDefaultConfiguration();
if( dgc.getBounds().contains( mouseLocation ) ) {
gc = dgc;
break;
}
}
if( gc == null )
gc = owner.getGraphicsConfiguration();
if( gc == null )
return null;
Rectangle screenBounds = gc.getBounds();
Insets screenInsets = Toolkit.getDefaultToolkit().getScreenInsets( gc );
int screenTop = screenBounds.y + screenInsets.top;
// place tooltip above mouse location if there is enough space
int newY = mouseLocation.y - tipSize.height - UIScale.scale( 20 );
if( newY < screenTop )
return null;
return new Point( x, newY );
} }
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 ---------------------------------------------

View File

@@ -27,6 +27,8 @@ import java.awt.Insets;
import java.awt.LayoutManager; import java.awt.LayoutManager;
import java.awt.LayoutManager2; import java.awt.LayoutManager2;
import java.awt.Window; import java.awt.Window;
import java.awt.event.HierarchyEvent;
import java.awt.event.HierarchyListener;
import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeEvent;
import java.util.function.Function; import java.util.function.Function;
import javax.swing.JComponent; import javax.swing.JComponent;
@@ -79,6 +81,7 @@ public class FlatRootPaneUI
private Object nativeWindowBorderData; private Object nativeWindowBorderData;
private LayoutManager oldLayout; private LayoutManager oldLayout;
private HierarchyListener hierarchyListener;
public static ComponentUI createUI( JComponent c ) { public static ComponentUI createUI( JComponent c ) {
return new FlatRootPaneUI(); return new FlatRootPaneUI();
@@ -136,6 +139,39 @@ public class FlatRootPaneUI
c.putClientProperty( "jetbrains.awt.windowDarkAppearance", FlatLaf.isLafDark() ); c.putClientProperty( "jetbrains.awt.windowDarkAppearance", FlatLaf.isLafDark() );
} }
@Override
protected void installListeners( JRootPane root ) {
super.installListeners( root );
if( SystemInfo.isJava_9_orLater ) {
// On HiDPI screens, where scaling is used, there may be white lines at the
// bottom and at the right side of the window when it is initially shown.
// This is very disturbing in dark themes, but hard to notice in light themes.
// Seems to be a rounding issue when Swing adds dirty region of window
// using RepaintManager.nativeAddDirtyRegion().
hierarchyListener = e -> {
if( (e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0 &&
rootPane.getParent() instanceof Window )
{
// add whole root pane to dirty regions when window is initially shown
rootPane.getParent().repaint( rootPane.getX(), rootPane.getY(),
rootPane.getWidth(), rootPane.getHeight() );
}
};
root.addHierarchyListener( hierarchyListener );
}
}
@Override
protected void uninstallListeners( JRootPane root ) {
super.uninstallListeners( root );
if( SystemInfo.isJava_9_orLater ) {
root.removeHierarchyListener( hierarchyListener );
hierarchyListener = null;
}
}
/** /**
* @since 1.1.2 * @since 1.1.2
*/ */
@@ -306,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

@@ -19,6 +19,7 @@ package com.formdev.flatlaf.ui;
import java.awt.Component; import java.awt.Component;
import java.awt.Graphics; import java.awt.Graphics;
import java.awt.Insets; import java.awt.Insets;
import java.awt.KeyboardFocusManager;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.awt.event.ContainerEvent; import java.awt.event.ContainerEvent;
import java.awt.event.ContainerListener; import java.awt.event.ContainerListener;
@@ -34,11 +35,13 @@ import javax.swing.JComponent;
import javax.swing.JScrollBar; import javax.swing.JScrollBar;
import javax.swing.JScrollPane; import javax.swing.JScrollPane;
import javax.swing.JTable; import javax.swing.JTable;
import javax.swing.JTree;
import javax.swing.JViewport; import javax.swing.JViewport;
import javax.swing.LookAndFeel; import javax.swing.LookAndFeel;
import javax.swing.ScrollPaneConstants; import javax.swing.ScrollPaneConstants;
import javax.swing.Scrollable; import javax.swing.Scrollable;
import javax.swing.SwingConstants; import javax.swing.SwingConstants;
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.BasicScrollPaneUI; import javax.swing.plaf.basic.BasicScrollPaneUI;
@@ -329,6 +332,31 @@ public class FlatScrollPaneUI
paint( g, c ); paint( g, c );
} }
/**
* @since 1.3
*/
public static boolean isPermanentFocusOwner( JScrollPane scrollPane ) {
JViewport viewport = scrollPane.getViewport();
Component view = (viewport != null) ? viewport.getView() : null;
if( view == null )
return false;
// check whether view is focus owner
if( FlatUIUtils.isPermanentFocusOwner( view ) )
return true;
// check whether editor component in JTable or JTree is focus owner
if( (view instanceof JTable && ((JTable)view).isEditing()) ||
(view instanceof JTree && ((JTree)view).isEditing()) )
{
Component focusOwner = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
if( focusOwner != null )
return SwingUtilities.isDescendingFrom( focusOwner, view );
}
return false;
}
//---- class Handler ------------------------------------------------------ //---- class Handler ------------------------------------------------------
/** /**
@@ -350,11 +378,13 @@ public class FlatScrollPaneUI
@Override @Override
public void focusGained( FocusEvent e ) { public void focusGained( FocusEvent e ) {
// necessary to update focus border
scrollpane.repaint(); scrollpane.repaint();
} }
@Override @Override
public void focusLost( FocusEvent e ) { public void focusLost( FocusEvent e ) {
// necessary to update focus border
scrollpane.repaint(); scrollpane.repaint();
} }
} }

View File

@@ -39,6 +39,7 @@ import javax.swing.LookAndFeel;
import javax.swing.SwingConstants; import javax.swing.SwingConstants;
import javax.swing.UIManager; import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI; import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.UIResource;
import javax.swing.plaf.basic.BasicSpinnerUI; import javax.swing.plaf.basic.BasicSpinnerUI;
import com.formdev.flatlaf.FlatClientProperties; import com.formdev.flatlaf.FlatClientProperties;
@@ -65,6 +66,7 @@ import com.formdev.flatlaf.FlatClientProperties;
* @uiDefault Component.disabledBorderColor Color * @uiDefault Component.disabledBorderColor Color
* @uiDefault Spinner.disabledBackground Color * @uiDefault Spinner.disabledBackground Color
* @uiDefault Spinner.disabledForeground Color * @uiDefault Spinner.disabledForeground Color
* @uiDefault Spinner.focusedBackground Color optional
* @uiDefault Spinner.buttonBackground Color * @uiDefault Spinner.buttonBackground Color
* @uiDefault Spinner.buttonArrowColor Color * @uiDefault Spinner.buttonArrowColor Color
* @uiDefault Spinner.buttonDisabledArrowColor Color * @uiDefault Spinner.buttonDisabledArrowColor Color
@@ -87,6 +89,7 @@ public class FlatSpinnerUI
protected Color disabledBorderColor; protected Color disabledBorderColor;
protected Color disabledBackground; protected Color disabledBackground;
protected Color disabledForeground; protected Color disabledForeground;
protected Color focusedBackground;
protected Color buttonBackground; protected Color buttonBackground;
protected Color buttonArrowColor; protected Color buttonArrowColor;
protected Color buttonDisabledArrowColor; protected Color buttonDisabledArrowColor;
@@ -112,6 +115,7 @@ public class FlatSpinnerUI
disabledBorderColor = UIManager.getColor( "Component.disabledBorderColor" ); disabledBorderColor = UIManager.getColor( "Component.disabledBorderColor" );
disabledBackground = UIManager.getColor( "Spinner.disabledBackground" ); disabledBackground = UIManager.getColor( "Spinner.disabledBackground" );
disabledForeground = UIManager.getColor( "Spinner.disabledForeground" ); disabledForeground = UIManager.getColor( "Spinner.disabledForeground" );
focusedBackground = UIManager.getColor( "Spinner.focusedBackground" );
buttonBackground = UIManager.getColor( "Spinner.buttonBackground" ); buttonBackground = UIManager.getColor( "Spinner.buttonBackground" );
buttonArrowColor = UIManager.getColor( "Spinner.buttonArrowColor" ); buttonArrowColor = UIManager.getColor( "Spinner.buttonArrowColor" );
buttonDisabledArrowColor = UIManager.getColor( "Spinner.buttonDisabledArrowColor" ); buttonDisabledArrowColor = UIManager.getColor( "Spinner.buttonDisabledArrowColor" );
@@ -119,9 +123,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 );
} }
@@ -133,6 +134,7 @@ public class FlatSpinnerUI
disabledBorderColor = null; disabledBorderColor = null;
disabledBackground = null; disabledBackground = null;
disabledForeground = null; disabledForeground = null;
focusedBackground = null;
buttonBackground = null; buttonBackground = null;
buttonArrowColor = null; buttonArrowColor = null;
buttonDisabledArrowColor = null; buttonDisabledArrowColor = null;
@@ -179,6 +181,7 @@ public class FlatSpinnerUI
if( textField != null ) if( textField != null )
textField.setOpaque( false ); textField.setOpaque( false );
updateEditorPadding();
updateEditorColors(); updateEditorColors();
return editor; return editor;
} }
@@ -189,6 +192,8 @@ public class FlatSpinnerUI
removeEditorFocusListener( oldEditor ); removeEditorFocusListener( oldEditor );
addEditorFocusListener( newEditor ); addEditorFocusListener( newEditor );
updateEditorPadding();
updateEditorColors(); updateEditorColors();
} }
@@ -204,6 +209,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 ) {
@@ -221,10 +232,34 @@ public class FlatSpinnerUI
: null; : null;
} }
/**
* @since 1.3
*/
public static boolean isPermanentFocusOwner( JSpinner spinner ) {
if( FlatUIUtils.isPermanentFocusOwner( spinner ) )
return true;
JTextField textField = getEditorTextField( spinner.getEditor() );
return (textField != null)
? FlatUIUtils.isPermanentFocusOwner( textField )
: false;
}
protected Color getBackground( boolean enabled ) { protected Color getBackground( boolean enabled ) {
return enabled if( enabled ) {
? spinner.getBackground() Color background = spinner.getBackground();
: (isIntelliJTheme ? FlatUIUtils.getParentBackground( spinner ) : disabledBackground);
// always use explicitly set color
if( !(background instanceof UIResource) )
return background;
// focused
if( focusedBackground != null && isPermanentFocusOwner( spinner ) )
return focusedBackground;
return background;
} else
return isIntelliJTheme ? FlatUIUtils.getParentBackground( spinner ) : disabledBackground;
} }
protected Color getForeground( boolean enabled ) { protected Color getForeground( boolean enabled ) {
@@ -250,7 +285,7 @@ public class FlatSpinnerUI
FlatArrowButton button = new FlatArrowButton( direction, arrowType, buttonArrowColor, FlatArrowButton button = new FlatArrowButton( direction, arrowType, buttonArrowColor,
buttonDisabledArrowColor, buttonHoverArrowColor, null, buttonPressedArrowColor, null ); buttonDisabledArrowColor, buttonHoverArrowColor, null, buttonPressedArrowColor, null );
button.setName( name ); button.setName( name );
button.setYOffset( (direction == SwingConstants.NORTH) ? 1 : -1 ); button.setYOffset( (direction == SwingConstants.NORTH) ? 1.25f : -1.25f );
if( direction == SwingConstants.NORTH ) if( direction == SwingConstants.NORTH )
installNextButtonListeners( button ); installNextButtonListeners( button );
else else
@@ -344,6 +379,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
@@ -368,7 +404,7 @@ 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;
} }
@@ -388,7 +424,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 )
@@ -405,6 +441,7 @@ public class FlatSpinnerUI
@Override @Override
public void focusGained( FocusEvent e ) { public void focusGained( FocusEvent e ) {
// necessary to update focus border
spinner.repaint(); spinner.repaint();
// if spinner gained focus, transfer it to the editor text field // if spinner gained focus, transfer it to the editor text field
@@ -417,6 +454,7 @@ public class FlatSpinnerUI
@Override @Override
public void focusLost( FocusEvent e ) { public void focusLost( FocusEvent e ) {
// necessary to update focus border
spinner.repaint(); spinner.repaint();
} }

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

@@ -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.event.FocusListener;
import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeEvent;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.JTextArea; import javax.swing.JTextArea;
@@ -52,6 +53,7 @@ import com.formdev.flatlaf.util.HiDPIUtils;
* @uiDefault Component.isIntelliJTheme boolean * @uiDefault Component.isIntelliJTheme boolean
* @uiDefault TextArea.disabledBackground Color used if not enabled * @uiDefault TextArea.disabledBackground Color used if not enabled
* @uiDefault TextArea.inactiveBackground Color used if not editable * @uiDefault TextArea.inactiveBackground Color used if not editable
* @uiDefault TextArea.focusedBackground Color optional
* *
* @author Karl Tauber * @author Karl Tauber
*/ */
@@ -63,6 +65,9 @@ public class FlatTextAreaUI
protected Color background; protected Color background;
protected Color disabledBackground; protected Color disabledBackground;
protected Color inactiveBackground; protected Color inactiveBackground;
protected Color focusedBackground;
private FocusListener focusListener;
public static ComponentUI createUI( JComponent c ) { public static ComponentUI createUI( JComponent c ) {
return new FlatTextAreaUI(); return new FlatTextAreaUI();
@@ -84,6 +89,7 @@ public class FlatTextAreaUI
background = UIManager.getColor( "TextArea.background" ); background = UIManager.getColor( "TextArea.background" );
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" );
} }
@Override @Override
@@ -93,6 +99,24 @@ public class FlatTextAreaUI
background = null; background = null;
disabledBackground = null; disabledBackground = null;
inactiveBackground = null; inactiveBackground = null;
focusedBackground = null;
}
@Override
protected void installListeners() {
super.installListeners();
// necessary to update focus background
focusListener = new FlatUIUtils.RepaintFocusListener( getComponent(), c -> focusedBackground != null );
getComponent().addFocusListener( focusListener );
}
@Override
protected void uninstallListeners() {
super.uninstallListeners();
getComponent().removeFocusListener( focusListener );
focusListener = null;
} }
@Override @Override
@@ -156,14 +180,6 @@ public class FlatTextAreaUI
@Override @Override
protected void paintBackground( Graphics g ) { protected void paintBackground( Graphics g ) {
JTextComponent c = getComponent(); FlatEditorPaneUI.paintBackground( g, getComponent(), isIntelliJTheme, focusedBackground );
// for compatibility with IntelliJ themes
if( isIntelliJTheme && (!c.isEnabled() || !c.isEditable()) && (c.getBackground() instanceof UIResource) ) {
FlatUIUtils.paintParentBackground( g, c );
return;
}
super.paintBackground( g );
} }
} }

View File

@@ -24,6 +24,7 @@ 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 javax.swing.JComboBox; import javax.swing.JComboBox;
@@ -40,6 +41,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}.
@@ -64,6 +66,7 @@ import com.formdev.flatlaf.util.JavaCompatibility;
* @uiDefault Component.minimumWidth int * @uiDefault Component.minimumWidth int
* @uiDefault Component.isIntelliJTheme boolean * @uiDefault Component.isIntelliJTheme boolean
* @uiDefault TextField.placeholderForeground Color * @uiDefault TextField.placeholderForeground Color
* @uiDefault TextField.focusedBackground Color optional
* @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
* *
@@ -75,6 +78,7 @@ public class FlatTextFieldUI
protected int minimumWidth; protected int minimumWidth;
protected boolean isIntelliJTheme; protected boolean isIntelliJTheme;
protected Color placeholderForeground; protected Color placeholderForeground;
protected Color focusedBackground;
private FocusListener focusListener; private FocusListener focusListener;
@@ -90,6 +94,7 @@ public class FlatTextFieldUI
minimumWidth = UIManager.getInt( "Component.minimumWidth" ); minimumWidth = UIManager.getInt( "Component.minimumWidth" );
isIntelliJTheme = UIManager.getBoolean( "Component.isIntelliJTheme" ); isIntelliJTheme = UIManager.getBoolean( "Component.isIntelliJTheme" );
placeholderForeground = UIManager.getColor( prefix + ".placeholderForeground" ); placeholderForeground = UIManager.getColor( prefix + ".placeholderForeground" );
focusedBackground = UIManager.getColor( prefix + ".focusedBackground" );
LookAndFeel.installProperty( getComponent(), "opaque", false ); LookAndFeel.installProperty( getComponent(), "opaque", false );
@@ -101,6 +106,7 @@ public class FlatTextFieldUI
super.uninstallDefaults(); super.uninstallDefaults();
placeholderForeground = null; placeholderForeground = null;
focusedBackground = null;
MigLayoutVisualPadding.uninstall( getComponent() ); MigLayoutVisualPadding.uninstall( getComponent() );
} }
@@ -109,7 +115,8 @@ public class FlatTextFieldUI
protected void installListeners() { protected void installListeners() {
super.installListeners(); super.installListeners();
focusListener = new FlatUIUtils.RepaintFocusListener( getComponent() ); // necessary to update focus border and background
focusListener = new FlatUIUtils.RepaintFocusListener( getComponent(), null );
getComponent().addFocusListener( focusListener ); getComponent().addFocusListener( focusListener );
} }
@@ -137,6 +144,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;
@@ -148,8 +156,8 @@ public class FlatTextFieldUI
@Override @Override
protected void paintSafely( Graphics g ) { protected void paintSafely( Graphics g ) {
paintBackground( g, getComponent(), isIntelliJTheme ); paintBackground( g, getComponent(), isIntelliJTheme, focusedBackground );
paintPlaceholder( g, getComponent(), placeholderForeground ); paintPlaceholder( g );
super.paintSafely( HiDPIUtils.createGraphicsTextYCorrection( (Graphics2D) g ) ); super.paintSafely( HiDPIUtils.createGraphicsTextYCorrection( (Graphics2D) g ) );
} }
@@ -159,7 +167,7 @@ public class FlatTextFieldUI
// background is painted elsewhere // background is painted elsewhere
} }
static void paintBackground( Graphics g, JTextComponent c, boolean isIntelliJTheme ) { static void paintBackground( Graphics g, JTextComponent c, boolean isIntelliJTheme, Color focusedBackground ) {
// do not paint background if: // do not paint background if:
// - not opaque and // - not opaque and
// - border is not a flat border and // - border is not a flat border and
@@ -180,19 +188,34 @@ public class FlatTextFieldUI
try { try {
FlatUIUtils.setRenderingHints( g2 ); FlatUIUtils.setRenderingHints( g2 );
Color background = c.getBackground(); g2.setColor( getBackground( c, isIntelliJTheme, focusedBackground ) );
g2.setColor( !(background instanceof UIResource)
? background
: (isIntelliJTheme && (!c.isEnabled() || !c.isEditable())
? FlatUIUtils.getParentBackground( c )
: background) );
FlatUIUtils.paintComponentBackground( g2, 0, 0, c.getWidth(), c.getHeight(), focusWidth, arc ); FlatUIUtils.paintComponentBackground( g2, 0, 0, c.getWidth(), c.getHeight(), focusWidth, arc );
} finally { } finally {
g2.dispose(); g2.dispose();
} }
} }
static void paintPlaceholder( Graphics g, JTextComponent c, Color placeholderForeground ) { static Color getBackground( JTextComponent c, boolean isIntelliJTheme, Color focusedBackground ) {
Color background = c.getBackground();
// always use explicitly set color
if( !(background instanceof UIResource) )
return background;
// focused
if( focusedBackground != null && FlatUIUtils.isPermanentFocusOwner( c ) )
return focusedBackground;
// for compatibility with IntelliJ themes
if( isIntelliJTheme && (!c.isEnabled() || !c.isEditable()) )
return FlatUIUtils.getParentBackground( c );
return background;
}
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;
@@ -207,16 +230,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
@@ -246,4 +267,36 @@ 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;
} }
@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

@@ -16,17 +16,17 @@
package com.formdev.flatlaf.ui; package com.formdev.flatlaf.ui;
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.event.FocusListener;
import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeEvent;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.JEditorPane; import javax.swing.JEditorPane;
import javax.swing.UIManager; import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI; import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.UIResource;
import javax.swing.plaf.basic.BasicTextPaneUI; import javax.swing.plaf.basic.BasicTextPaneUI;
import javax.swing.text.JTextComponent;
import com.formdev.flatlaf.util.HiDPIUtils; import com.formdev.flatlaf.util.HiDPIUtils;
/** /**
@@ -51,6 +51,7 @@ import com.formdev.flatlaf.util.HiDPIUtils;
* *
* @uiDefault Component.minimumWidth int * @uiDefault Component.minimumWidth int
* @uiDefault Component.isIntelliJTheme boolean * @uiDefault Component.isIntelliJTheme boolean
* @uiDefault TextPane.focusedBackground Color optional
* *
* @author Karl Tauber * @author Karl Tauber
*/ */
@@ -59,8 +60,10 @@ public class FlatTextPaneUI
{ {
protected int minimumWidth; protected int minimumWidth;
protected boolean isIntelliJTheme; protected boolean isIntelliJTheme;
protected Color focusedBackground;
private Object oldHonorDisplayProperties; private Object oldHonorDisplayProperties;
private FocusListener focusListener;
public static ComponentUI createUI( JComponent c ) { public static ComponentUI createUI( JComponent c ) {
return new FlatTextPaneUI(); return new FlatTextPaneUI();
@@ -70,8 +73,10 @@ public class FlatTextPaneUI
protected void installDefaults() { protected void installDefaults() {
super.installDefaults(); super.installDefaults();
String prefix = getPropertyPrefix();
minimumWidth = UIManager.getInt( "Component.minimumWidth" ); minimumWidth = UIManager.getInt( "Component.minimumWidth" );
isIntelliJTheme = UIManager.getBoolean( "Component.isIntelliJTheme" ); isIntelliJTheme = UIManager.getBoolean( "Component.isIntelliJTheme" );
focusedBackground = UIManager.getColor( prefix + ".focusedBackground" );
// 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 );
@@ -82,9 +87,28 @@ public class FlatTextPaneUI
protected void uninstallDefaults() { protected void uninstallDefaults() {
super.uninstallDefaults(); super.uninstallDefaults();
focusedBackground = null;
getComponent().putClientProperty( JEditorPane.HONOR_DISPLAY_PROPERTIES, oldHonorDisplayProperties ); getComponent().putClientProperty( JEditorPane.HONOR_DISPLAY_PROPERTIES, oldHonorDisplayProperties );
} }
@Override
protected void installListeners() {
super.installListeners();
// necessary to update focus background
focusListener = new FlatUIUtils.RepaintFocusListener( getComponent(), c -> focusedBackground != null );
getComponent().addFocusListener( focusListener );
}
@Override
protected void uninstallListeners() {
super.uninstallListeners();
getComponent().removeFocusListener( focusListener );
focusListener = null;
}
@Override @Override
protected void propertyChange( PropertyChangeEvent e ) { protected void propertyChange( PropertyChangeEvent e ) {
super.propertyChange( e ); super.propertyChange( e );
@@ -108,14 +132,6 @@ public class FlatTextPaneUI
@Override @Override
protected void paintBackground( Graphics g ) { protected void paintBackground( Graphics g ) {
JTextComponent c = getComponent(); FlatEditorPaneUI.paintBackground( g, getComponent(), isIntelliJTheme, focusedBackground );
// for compatibility with IntelliJ themes
if( isIntelliJTheme && (!c.isEnabled() || !c.isEditable()) && (c.getBackground() instanceof UIResource) ) {
FlatUIUtils.paintParentBackground( g, c );
return;
}
super.paintBackground( g );
} }
} }

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 );
if( !focusableButtons ) {
Component c = e.getChild(); Component c = e.getChild();
if( c instanceof AbstractButton ) if( c instanceof AbstractButton )
c.setFocusable( false ); c.setFocusable( false );
} }
}
@Override @Override
public void componentRemoved( ContainerEvent e ) { public void componentRemoved( ContainerEvent e ) {
super.componentRemoved( e ); super.componentRemoved( e );
if( !focusableButtons ) {
Component c = e.getChild(); Component c = e.getChild();
if( c instanceof AbstractButton ) if( c instanceof AbstractButton )
c.setFocusable( true ); 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,
@@ -660,7 +665,7 @@ public class FlatUIUtils
* @since 1.1 * @since 1.1
*/ */
public static void paintArrow( Graphics2D g, int x, int y, int width, int height, public static void paintArrow( Graphics2D g, int x, int y, int width, int height,
int direction, boolean chevron, int arrowSize, int xOffset, int yOffset ) int direction, boolean chevron, int arrowSize, float xOffset, float yOffset )
{ {
// compute arrow width/height // compute arrow width/height
int aw = UIScale.scale( arrowSize + (chevron ? 0 : 1) ); int aw = UIScale.scale( arrowSize + (chevron ? 0 : 1) );
@@ -679,8 +684,10 @@ public class FlatUIUtils
int extra = chevron ? 1 : 0; int extra = chevron ? 1 : 0;
// compute arrow location // compute arrow location
int ax = x + Math.round( ((width - (aw + extra)) / 2f) + UIScale.scale( (float) xOffset ) ); float ox = ((width - (aw + extra)) / 2f) + UIScale.scale( xOffset );
int ay = y + Math.round( ((height - (ah + extra)) / 2f) + UIScale.scale( (float) yOffset ) ); float oy = ((height - (ah + extra)) / 2f) + UIScale.scale( yOffset );
int ax = x + ((direction == SwingConstants.WEST) ? -Math.round( -ox ) : Math.round( ox ));
int ay = y + ((direction == SwingConstants.NORTH) ? -Math.round( -oy ) : Math.round( oy ));
// paint arrow // paint arrow
g.translate( ax, ay ); g.translate( ax, ay );
@@ -837,18 +844,22 @@ debug*/
implements FocusListener implements FocusListener
{ {
private final Component repaintComponent; private final Component repaintComponent;
private final Predicate<Component> repaintCondition;
public RepaintFocusListener( Component repaintComponent ) { public RepaintFocusListener( Component repaintComponent, Predicate<Component> repaintCondition ) {
this.repaintComponent = repaintComponent; this.repaintComponent = repaintComponent;
this.repaintCondition = repaintCondition;
} }
@Override @Override
public void focusGained( FocusEvent e ) { public void focusGained( FocusEvent e ) {
if( repaintCondition == null || repaintCondition.test( repaintComponent ) )
repaintComponent.repaint(); repaintComponent.repaint();
} }
@Override @Override
public void focusLost( FocusEvent e ) { public void focusLost( FocusEvent e ) {
if( repaintCondition == null || repaintCondition.test( repaintComponent ) )
repaintComponent.repaint(); repaintComponent.repaint();
} }
} }

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

@@ -752,6 +752,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

@@ -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

@@ -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

@@ -44,6 +44,7 @@ import java.awt.event.WindowListener;
import java.beans.PropertyChangeListener; import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport; import java.beans.PropertyChangeSupport;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Method;
import javax.swing.AbstractButton; import javax.swing.AbstractButton;
import javax.swing.JComponent; import javax.swing.JComponent;
import javax.swing.JLayeredPane; import javax.swing.JLayeredPane;
@@ -64,6 +65,7 @@ import javax.swing.plaf.UIResource;
import javax.swing.text.JTextComponent; import javax.swing.text.JTextComponent;
import com.formdev.flatlaf.FlatClientProperties; import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.ui.FlatUIUtils; import com.formdev.flatlaf.ui.FlatUIUtils;
import com.formdev.flatlaf.util.SystemInfo;
import com.formdev.flatlaf.util.UIScale; import com.formdev.flatlaf.util.UIScale;
/** /**
@@ -478,9 +480,17 @@ public class FlatInspector
if( c instanceof JComponent ) { if( c instanceof JComponent ) {
try { try {
Object ui;
if( SystemInfo.isJava_9_orLater ) {
// Java 9+: use public method JComponent.getUI()
Method m = JComponent.class.getMethod( "getUI" );
ui = m.invoke( c );
} else {
// Java 8: read protected field 'ui'
Field f = JComponent.class.getDeclaredField( "ui" ); Field f = JComponent.class.getDeclaredField( "ui" );
f.setAccessible( true ); f.setAccessible( true );
Object ui = f.get( c ); ui = f.get( c );
}
appendRow( buf, "UI", (ui != null ? toString( ui.getClass(), classHierarchy ) : "null") ); appendRow( buf, "UI", (ui != null ? toString( ui.getClass(), classHierarchy ) : "null") );
} catch( Exception ex ) { } catch( Exception ex ) {
// ignore // ignore
@@ -553,6 +563,9 @@ public class FlatInspector
String simpleName = (dot >= 0) ? name.substring( dot + 1 ) : name; String simpleName = (dot >= 0) ? name.substring( dot + 1 ) : name;
buf.append( simpleName ).append( ' ' ).append( toDimmedText( "(" + pkg + ")" ) ); buf.append( simpleName ).append( ' ' ).append( toDimmedText( "(" + pkg + ")" ) );
if( UIResource.class.isAssignableFrom( cls ) )
buf.append( " UI" );
if( !classHierarchy ) if( !classHierarchy )
break; break;
@@ -613,11 +626,14 @@ public class FlatInspector
String s = toString( b.getClass(), classHierarchy ); String s = toString( b.getClass(), classHierarchy );
if( b instanceof EmptyBorder ) if( b instanceof EmptyBorder ) {
s += '(' + toString( ((EmptyBorder)b).getBorderInsets() ) + ')'; String borderInsets = " (" + toString( ((EmptyBorder)b).getBorderInsets() ) + ')';
int brIndex = s.indexOf( "<br>" );
if( b instanceof UIResource ) if( brIndex >= 0 )
s += " UI"; s = s.substring( 0, brIndex ) + borderInsets + s.substring( brIndex );
else
s += borderInsets;
}
return s; return s;
} }

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

@@ -23,7 +23,7 @@ dependencies {
implementation( project( ":flatlaf-core" ) ) implementation( project( ":flatlaf-core" ) )
// use compileOnly() because there are various JIDE libraries available on Maven Central // use compileOnly() because there are various JIDE libraries available on Maven Central
compileOnly( "com.formdev:jide-oss:3.7.11.1" ) compileOnly( "com.formdev:jide-oss:3.7.12" )
} }
java { java {

View File

@@ -156,7 +156,7 @@ public class FlatDatePickerUI
editor.setName( "dateField" ); editor.setName( "dateField" );
editor.setBorder( BorderFactory.createEmptyBorder() ); editor.setBorder( BorderFactory.createEmptyBorder() );
editor.setOpaque( false ); editor.setOpaque( false );
editor.addFocusListener( new FlatUIUtils.RepaintFocusListener( datePicker ) ); editor.addFocusListener( new FlatUIUtils.RepaintFocusListener( datePicker, null ) );
return editor; return editor;
} }

View File

@@ -33,7 +33,7 @@ dependencies {
implementation( "com.jgoodies:jgoodies-forms:1.9.0" ) implementation( "com.jgoodies:jgoodies-forms:1.9.0" )
implementation( "org.swinglabs.swingx:swingx-all:1.6.5-1" ) implementation( "org.swinglabs.swingx:swingx-all:1.6.5-1" )
implementation( "org.swinglabs.swingx:swingx-beaninfo:1.6.5-1" ) implementation( "org.swinglabs.swingx:swingx-beaninfo:1.6.5-1" )
implementation( "com.formdev:jide-oss:3.7.11.1" ) implementation( "com.formdev:jide-oss:3.7.12" )
implementation( "com.glazedlists:glazedlists:1.11.0" ) implementation( "com.glazedlists:glazedlists:1.11.0" )
implementation( "org.netbeans.api:org-openide-awt:RELEASE112" ) implementation( "org.netbeans.api:org-openide-awt:RELEASE112" )
} }

View File

@@ -1249,6 +1249,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

@@ -1254,6 +1254,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]
@@ -935,6 +941,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 +1118,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 +1144,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 +1166,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 +1263,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

@@ -147,7 +147,7 @@ public class FlatAnimatedIconTest
@Override @Override
public void paintIconAnimated( Component c, Graphics g, int x, int y, float animatedValue ) { public void paintIconAnimated( Component c, Graphics g, int x, int y, float animatedValue ) {
Color color = ColorFunctions.mix( onColor, offColor, animatedValue );; Color color = ColorFunctions.mix( onColor, offColor, animatedValue );
// border // border
g.setColor( color ); g.setColor( color );
@@ -190,7 +190,7 @@ public class FlatAnimatedIconTest
@Override @Override
public void paintIconAnimated( Component c, Graphics g, int x, int y, float animatedValue ) { public void paintIconAnimated( Component c, Graphics g, int x, int y, float animatedValue ) {
Color color = ColorFunctions.mix( onColor, offColor, animatedValue );; Color color = ColorFunctions.mix( onColor, offColor, animatedValue );
g.setColor( color ); g.setColor( color );
g.fillRoundRect( x, y, width, height, height, height ); g.fillRoundRect( x, y, width, height, height, height );

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,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

@@ -73,6 +73,25 @@ public class FlatPaintingTest
repaint(); repaint();
} }
private void offsetChanged() {
float offset = (float) offsetSpinner.getValue();
System.out.println( offset );
arrowPainter5.setYOffset( offset );
arrowPainter6.setYOffset( -offset );
arrowPainter7.setXOffset( offset );
arrowPainter8.setXOffset( -offset );
arrowPainter13.setYOffset( offset );
arrowPainter14.setYOffset( -offset );
arrowPainter15.setXOffset( offset );
arrowPainter16.setXOffset( -offset );
repaint();
}
private void vectorChanged() { private void vectorChanged() {
boolean vector = vectorCheckBox.isSelected(); boolean vector = vectorCheckBox.isSelected();
@@ -84,7 +103,7 @@ public class FlatPaintingTest
repaint(); repaint();
} }
private void checkBox1ActionPerformed() { private void arrowButtonChanged() {
boolean button = buttonCheckBox.isSelected(); boolean button = buttonCheckBox.isSelected();
FlatTestFrame.updateComponentsRecur( (Container) getViewport().getView(), (c, type) -> { FlatTestFrame.updateComponentsRecur( (Container) getViewport().getView(), (c, type) -> {
@@ -143,11 +162,11 @@ public class FlatPaintingTest
FlatPaintingTest.ArrowPainter arrowPainter3 = new FlatPaintingTest.ArrowPainter(); FlatPaintingTest.ArrowPainter arrowPainter3 = new FlatPaintingTest.ArrowPainter();
FlatPaintingTest.ArrowPainter arrowPainter4 = new FlatPaintingTest.ArrowPainter(); FlatPaintingTest.ArrowPainter arrowPainter4 = new FlatPaintingTest.ArrowPainter();
JPanel panel1 = new JPanel(); JPanel panel1 = new JPanel();
FlatPaintingTest.ArrowPainter arrowPainter5 = new FlatPaintingTest.ArrowPainter(); arrowPainter5 = new FlatPaintingTest.ArrowPainter();
FlatPaintingTest.ArrowPainter arrowPainter6 = new FlatPaintingTest.ArrowPainter(); arrowPainter6 = new FlatPaintingTest.ArrowPainter();
JPanel panel2 = new JPanel(); JPanel panel2 = new JPanel();
FlatPaintingTest.ArrowPainter arrowPainter7 = new FlatPaintingTest.ArrowPainter(); arrowPainter7 = new FlatPaintingTest.ArrowPainter();
FlatPaintingTest.ArrowPainter arrowPainter8 = new FlatPaintingTest.ArrowPainter(); arrowPainter8 = new FlatPaintingTest.ArrowPainter();
JPanel panel5 = new JPanel(); JPanel panel5 = new JPanel();
JLabel arrowWidthLabel = new JLabel(); JLabel arrowWidthLabel = new JLabel();
arrowWidthSpinner = new JSpinner(); arrowWidthSpinner = new JSpinner();
@@ -155,6 +174,8 @@ public class FlatPaintingTest
arrowHeightSpinner = new JSpinner(); arrowHeightSpinner = new JSpinner();
JLabel arrowSizeLabel = new JLabel(); JLabel arrowSizeLabel = new JLabel();
arrowSizeSpinner = new JSpinner(); arrowSizeSpinner = new JSpinner();
JLabel offsetLabel = new JLabel();
offsetSpinner = new JSpinner();
vectorCheckBox = new JCheckBox(); vectorCheckBox = new JCheckBox();
buttonCheckBox = new JCheckBox(); buttonCheckBox = new JCheckBox();
FlatPaintingTest.ArrowPainter arrowPainter9 = new FlatPaintingTest.ArrowPainter(); FlatPaintingTest.ArrowPainter arrowPainter9 = new FlatPaintingTest.ArrowPainter();
@@ -162,11 +183,11 @@ public class FlatPaintingTest
FlatPaintingTest.ArrowPainter arrowPainter11 = new FlatPaintingTest.ArrowPainter(); FlatPaintingTest.ArrowPainter arrowPainter11 = new FlatPaintingTest.ArrowPainter();
FlatPaintingTest.ArrowPainter arrowPainter12 = new FlatPaintingTest.ArrowPainter(); FlatPaintingTest.ArrowPainter arrowPainter12 = new FlatPaintingTest.ArrowPainter();
JPanel panel3 = new JPanel(); JPanel panel3 = new JPanel();
FlatPaintingTest.ArrowPainter arrowPainter13 = new FlatPaintingTest.ArrowPainter(); arrowPainter13 = new FlatPaintingTest.ArrowPainter();
FlatPaintingTest.ArrowPainter arrowPainter14 = new FlatPaintingTest.ArrowPainter(); arrowPainter14 = new FlatPaintingTest.ArrowPainter();
JPanel panel4 = new JPanel(); JPanel panel4 = new JPanel();
FlatPaintingTest.ArrowPainter arrowPainter15 = new FlatPaintingTest.ArrowPainter(); arrowPainter15 = new FlatPaintingTest.ArrowPainter();
FlatPaintingTest.ArrowPainter arrowPainter16 = new FlatPaintingTest.ArrowPainter(); arrowPainter16 = new FlatPaintingTest.ArrowPainter();
//======== this ======== //======== this ========
setBorder(null); setBorder(null);
@@ -519,6 +540,7 @@ public class FlatPaintingTest
"[]" + "[]" +
"[]" + "[]" +
"[]" + "[]" +
"[]" +
"[]")); "[]"));
//---- arrowWidthLabel ---- //---- arrowWidthLabel ----
@@ -548,17 +570,26 @@ public class FlatPaintingTest
arrowSizeSpinner.addChangeListener(e -> arrowSizeChanged()); arrowSizeSpinner.addChangeListener(e -> arrowSizeChanged());
panel5.add(arrowSizeSpinner, "cell 1 2"); panel5.add(arrowSizeSpinner, "cell 1 2");
//---- offsetLabel ----
offsetLabel.setText("Offset:");
panel5.add(offsetLabel, "cell 0 3");
//---- offsetSpinner ----
offsetSpinner.setModel(new SpinnerNumberModel(1.0F, null, null, 0.05F));
offsetSpinner.addChangeListener(e -> offsetChanged());
panel5.add(offsetSpinner, "cell 1 3");
//---- vectorCheckBox ---- //---- vectorCheckBox ----
vectorCheckBox.setText("vector"); vectorCheckBox.setText("vector");
vectorCheckBox.addActionListener(e -> vectorChanged()); vectorCheckBox.addActionListener(e -> vectorChanged());
panel5.add(vectorCheckBox, "cell 0 3 2 1,alignx left,growx 0"); panel5.add(vectorCheckBox, "cell 0 4 2 1,alignx left,growx 0");
//---- buttonCheckBox ---- //---- buttonCheckBox ----
buttonCheckBox.setText("FlatArrowButton"); buttonCheckBox.setText("FlatArrowButton");
buttonCheckBox.addActionListener(e -> checkBox1ActionPerformed()); buttonCheckBox.addActionListener(e -> arrowButtonChanged());
panel5.add(buttonCheckBox, "cell 0 4 2 1,alignx left,growx 0"); panel5.add(buttonCheckBox, "cell 0 5 2 1,alignx left,growx 0");
} }
flatTestPanel1.add(panel5, "cell 6 5,aligny top,growy 0"); flatTestPanel1.add(panel5, "cell 6 5 1 2,aligny top,growy 0");
//---- arrowPainter9 ---- //---- arrowPainter9 ----
arrowPainter9.setScale(8.0F); arrowPainter9.setScale(8.0F);
@@ -635,11 +666,20 @@ public class FlatPaintingTest
} }
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables // JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
private FlatPaintingTest.ArrowPainter arrowPainter5;
private FlatPaintingTest.ArrowPainter arrowPainter6;
private FlatPaintingTest.ArrowPainter arrowPainter7;
private FlatPaintingTest.ArrowPainter arrowPainter8;
private JSpinner arrowWidthSpinner; private JSpinner arrowWidthSpinner;
private JSpinner arrowHeightSpinner; private JSpinner arrowHeightSpinner;
private JSpinner arrowSizeSpinner; private JSpinner arrowSizeSpinner;
private JSpinner offsetSpinner;
private JCheckBox vectorCheckBox; private JCheckBox vectorCheckBox;
private JCheckBox buttonCheckBox; private JCheckBox buttonCheckBox;
private FlatPaintingTest.ArrowPainter arrowPainter13;
private FlatPaintingTest.ArrowPainter arrowPainter14;
private FlatPaintingTest.ArrowPainter arrowPainter15;
private FlatPaintingTest.ArrowPainter arrowPainter16;
// JFormDesigner - End of variables declaration //GEN-END:variables // JFormDesigner - End of variables declaration //GEN-END:variables
//---- class BorderPainter ------------------------------------------------ //---- class BorderPainter ------------------------------------------------
@@ -792,8 +832,8 @@ public class FlatPaintingTest
private int direction = SwingConstants.SOUTH; private int direction = SwingConstants.SOUTH;
private boolean chevron = true; private boolean chevron = true;
private int arrowSize = FlatArrowButton.DEFAULT_ARROW_WIDTH; private int arrowSize = FlatArrowButton.DEFAULT_ARROW_WIDTH;
private int xOffset = 0; private float xOffset = 0;
private int yOffset = 0; private float yOffset = 0;
private float scale = 1; private float scale = 1;
private boolean halfWidth; private boolean halfWidth;
private boolean halfHeight; private boolean halfHeight;
@@ -845,19 +885,19 @@ public class FlatPaintingTest
this.arrowSize = arrowSize; this.arrowSize = arrowSize;
} }
public int getXOffset() { public float getXOffset() {
return xOffset; return xOffset;
} }
public void setXOffset( int xOffset ) { public void setXOffset( float xOffset ) {
this.xOffset = xOffset; this.xOffset = xOffset;
} }
public int getYOffset() { public float getYOffset() {
return yOffset; return yOffset;
} }
public void setYOffset( int yOffset ) { public void setYOffset( float yOffset ) {
this.yOffset = yOffset; this.yOffset = yOffset;
} }

View File

@@ -1,4 +1,4 @@
JFDML JFormDesigner: "7.0.3.1.342" 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"
@@ -383,6 +383,9 @@ new FormModel {
"h": 10 "h": 10
"halfHeight": true "halfHeight": true
"YOffset": 1 "YOffset": 1
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
} ) } )
add( new FormComponent( "com.formdev.flatlaf.testing.FlatPaintingTest$ArrowPainter" ) { add( new FormComponent( "com.formdev.flatlaf.testing.FlatPaintingTest$ArrowPainter" ) {
name: "arrowPainter6" name: "arrowPainter6"
@@ -390,6 +393,9 @@ new FormModel {
"h": 10 "h": 10
"halfHeight": true "halfHeight": true
"YOffset": -1 "YOffset": -1
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
} ) } )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 4 5,align left top,grow 0 0" "value": "cell 4 5,align left top,grow 0 0"
@@ -403,6 +409,9 @@ new FormModel {
"w": 10 "w": 10
"halfWidth": true "halfWidth": true
"XOffset": 1 "XOffset": 1
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
} ) } )
add( new FormComponent( "com.formdev.flatlaf.testing.FlatPaintingTest$ArrowPainter" ) { add( new FormComponent( "com.formdev.flatlaf.testing.FlatPaintingTest$ArrowPainter" ) {
name: "arrowPainter8" name: "arrowPainter8"
@@ -411,6 +420,9 @@ new FormModel {
"w": 10 "w": 10
"halfWidth": true "halfWidth": true
"XOffset": -1 "XOffset": -1
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
} ) } )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 5 5,align left top,grow 0 0" "value": "cell 5 5,align left top,grow 0 0"
@@ -418,7 +430,7 @@ new FormModel {
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "hidemode 3" "$layoutConstraints": "hidemode 3"
"$columnConstraints": "[fill][fill]" "$columnConstraints": "[fill][fill]"
"$rowConstraints": "[][][][][]" "$rowConstraints": "[][][][][][]"
} ) { } ) {
name: "panel5" name: "panel5"
"border": new javax.swing.border.TitledBorder( "Arrow Control" ) "border": new javax.swing.border.TitledBorder( "Arrow Control" )
@@ -479,6 +491,25 @@ 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.JLabel" ) {
name: "offsetLabel"
"text": "Offset:"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 3"
} )
add( new FormComponent( "javax.swing.JSpinner" ) {
name: "offsetSpinner"
"model": new javax.swing.SpinnerNumberModel {
stepSize: 0.05f
value: 1.0f
}
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
addEvent( new FormEvent( "javax.swing.event.ChangeListener", "stateChanged", "offsetChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 3"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) { add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "vectorCheckBox" name: "vectorCheckBox"
"text": "vector" "text": "vector"
@@ -487,7 +518,7 @@ new FormModel {
} }
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "vectorChanged", false ) ) addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "vectorChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 3 2 1,alignx left,growx 0" "value": "cell 0 4 2 1,alignx left,growx 0"
} ) } )
add( new FormComponent( "javax.swing.JCheckBox" ) { add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "buttonCheckBox" name: "buttonCheckBox"
@@ -495,12 +526,12 @@ new FormModel {
auxiliary() { auxiliary() {
"JavaCodeGenerator.variableLocal": false "JavaCodeGenerator.variableLocal": false
} }
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "checkBox1ActionPerformed", false ) ) addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "arrowButtonChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 4 2 1,alignx left,growx 0" "value": "cell 0 5 2 1,alignx left,growx 0"
} ) } )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 6 5,aligny top,growy 0" "value": "cell 6 5 1 2,aligny top,growy 0"
} ) } )
add( new FormComponent( "com.formdev.flatlaf.testing.FlatPaintingTest$ArrowPainter" ) { add( new FormComponent( "com.formdev.flatlaf.testing.FlatPaintingTest$ArrowPainter" ) {
name: "arrowPainter9" name: "arrowPainter9"
@@ -545,6 +576,9 @@ new FormModel {
"chevron": false "chevron": false
"halfHeight": true "halfHeight": true
"YOffset": 1 "YOffset": 1
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
} ) } )
add( new FormComponent( "com.formdev.flatlaf.testing.FlatPaintingTest$ArrowPainter" ) { add( new FormComponent( "com.formdev.flatlaf.testing.FlatPaintingTest$ArrowPainter" ) {
name: "arrowPainter14" name: "arrowPainter14"
@@ -553,6 +587,9 @@ new FormModel {
"chevron": false "chevron": false
"halfHeight": true "halfHeight": true
"YOffset": -1 "YOffset": -1
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
} ) } )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 4 6,align left top,grow 0 0" "value": "cell 4 6,align left top,grow 0 0"
@@ -567,6 +604,9 @@ new FormModel {
"chevron": false "chevron": false
"halfWidth": true "halfWidth": true
"XOffset": 1 "XOffset": 1
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
} ) } )
add( new FormComponent( "com.formdev.flatlaf.testing.FlatPaintingTest$ArrowPainter" ) { add( new FormComponent( "com.formdev.flatlaf.testing.FlatPaintingTest$ArrowPainter" ) {
name: "arrowPainter16" name: "arrowPainter16"
@@ -576,6 +616,9 @@ new FormModel {
"chevron": false "chevron": false
"halfWidth": true "halfWidth": true
"XOffset": -1 "XOffset": -1
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
} ) } )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 5 6,align left top,grow 0 0" "value": "cell 5 6,align left top,grow 0 0"

View File

@@ -23,6 +23,7 @@ import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter; import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent; import java.awt.event.WindowEvent;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;
@@ -284,6 +285,8 @@ public class FlatTestFrame
Properties properties = new Properties(); Properties properties = new Properties();
try( InputStream in = new FileInputStream( "lafs.properties" ) ) { try( InputStream in = new FileInputStream( "lafs.properties" ) ) {
properties.load( in ); properties.load( in );
} catch( FileNotFoundException ex ) {
// ignore
} catch( IOException ex ) { } catch( IOException ex ) {
ex.printStackTrace(); ex.printStackTrace();
} }

View File

@@ -16,8 +16,12 @@
package com.formdev.flatlaf.testing; package com.formdev.flatlaf.testing;
import java.awt.Component;
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 +45,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();
@@ -134,12 +162,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 +181,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 +387,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:");
@@ -361,5 +447,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"
@@ -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"

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

@@ -130,6 +130,10 @@ ComboBox.background = #fff
ComboBox.buttonBackground = #f0f0f0 ComboBox.buttonBackground = #f0f0f0
ComboBox.buttonEditableBackground = #ccc ComboBox.buttonEditableBackground = #ccc
ComboBox.focusedBackground = #ff8
ComboBox.buttonFocusedBackground = #ff0
ComboBox.popupBackground = #ffc
#---- Component ---- #---- Component ----
@@ -152,6 +156,16 @@ Desktop.background = #afe
DesktopIcon.background = darken($Desktop.background,20%) DesktopIcon.background = darken($Desktop.background,20%)
#---- EditorPane ----
EditorPane.focusedBackground = #ff8
#---- FormattedTextField ----
FormattedTextField.focusedBackground = #ff8
#---- HelpButton ---- #---- HelpButton ----
HelpButton.focusedBackground = #0ff HelpButton.focusedBackground = #0ff
@@ -223,6 +237,11 @@ OptionPane.icon.warningColor = #fc0
OptionPane.icon.foreground = #fff OptionPane.icon.foreground = #fff
#---- PasswordField ----
PasswordField.focusedBackground = #ff8
#---- Popup ---- #---- Popup ----
Popup.dropShadowColor = #0f0 Popup.dropShadowColor = #0f0
@@ -280,6 +299,11 @@ Slider.disabledTrackColor = #ff8
Slider.disabledThumbColor = #880 Slider.disabledThumbColor = #880
#---- Spinner ----
Spinner.focusedBackground = #ff8
#---- SplitPane ---- #---- SplitPane ----
SplitPaneDivider.draggingColor = #800 SplitPaneDivider.draggingColor = #800
@@ -332,6 +356,21 @@ TableHeader.separatorColor = #0f0
TableHeader.bottomSeparatorColor = #0f0 TableHeader.bottomSeparatorColor = #0f0
#---- TextArea ----
TextArea.focusedBackground = #ff8
#---- TextField ----
TextField.focusedBackground = #ff8
#---- TextPane ----
TextPane.focusedBackground = #ff8
#---- TitledBorder ---- #---- TitledBorder ----
TitledBorder.titleColor = #f0f TitledBorder.titleColor = #f0f
@@ -361,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
@@ -651,11 +672,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 +702,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 +778,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 +846,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 +865,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 +884,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 +894,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 +932,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 +948,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 +966,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 +996,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