diff --git a/CHANGELOG.md b/CHANGELOG.md index 435808d2..b7545f86 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,12 +28,16 @@ FlatLaf Change Log setting UI default `OptionPane.showIcon` to `true`. (issue #416) - No longer show the Java "duke/cup" icon if no window icon image is set. (issue #416) -- TextField, FormattedTextField and PasswordField: Support leading and trailing - icons (set client property `JTextField.leadingIcon` or - `JTextField.trailingIcon` to a `javax.swing.Icon`). (PR #378; issue #368) -- TextField, FormattedTextField and PasswordField: Support leading and trailing - components (set client property `JTextField.leadingComponent` or - `JTextField.trailingComponent` to a `java.awt.Component`). (PR #386) +- TextField, FormattedTextField and PasswordField: + - Support leading and trailing icons (set client property + `JTextField.leadingIcon` or `JTextField.trailingIcon` to a + `javax.swing.Icon`). (PR #378; issue #368) + - Support leading and trailing components (set client property + `JTextField.leadingComponent` or `JTextField.trailingComponent` to a + `java.awt.Component`). (PR #386) + - Support "clear" (or "cancel") button to empty text field. Only shown if text + field is not empty, editable and enabled. (set client property + `JTextField.showClearButton` to `true`). (PR #TODO) - TextComponents: Double/triple-click-and-drag now extends selection by whole words/lines. - Theming improvements: Reworks core themes to make it easier to create new diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java index dd5e1242..ce55df19 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java @@ -903,6 +903,17 @@ public interface FlatClientProperties */ String TEXT_FIELD_TRAILING_COMPONENT = "JTextField.trailingComponent"; + /** + * Specifies whether a "clear" (or "cancel") button is shown on the trailing side + * if the text field is not empty, editable and enabled. Default is {@code false}. + *
+ * Component {@link javax.swing.JTextField} (and subclasses)
+ * Note: The components in the array must be in reverse (visual) order.
+ *
+ * @since 2
+ */
+ protected JComponent[] getTrailingComponents() {
+ return new JComponent[] { trailingComponent, clearButton };
+ }
+
/** @since 2 */
protected void prepareLeadingOrTrailingComponent( JComponent c ) {
c.putClientProperty( STYLE_CLASS, "inTextField" );
@@ -686,7 +825,8 @@ debug*/
}
}
- private void installLayout() {
+ /** @since 2 */
+ protected void installLayout() {
JTextComponent c = getComponent();
LayoutManager oldLayout = c.getLayout();
if( !(oldLayout instanceof FlatTextFieldLayout) )
@@ -731,25 +871,30 @@ debug*/
if( delegate != null )
delegate.layoutContainer( parent );
- if( leadingComponent == null && trailingComponent == null )
- return;
-
int ow = FlatUIUtils.getBorderFocusAndLineWidth( getComponent() );
int h = parent.getHeight() - ow - ow;
boolean ltr = isLeftToRight();
- JComponent leftComponent = ltr ? leadingComponent : trailingComponent;
- JComponent rightComponent = ltr ? trailingComponent : leadingComponent;
+ JComponent[] leftComponents = ltr ? getLeadingComponents() : getTrailingComponents();
+ JComponent[] rightComponents = ltr ? getTrailingComponents() : getLeadingComponents();
- // layout left component
- if( leftComponent != null && leftComponent.isVisible() ) {
- int w = leftComponent.getPreferredSize().width;
- leftComponent.setBounds( ow, ow, w, h );
+ // layout left components
+ int x = ow;
+ for( JComponent leftComponent : leftComponents ) {
+ if( leftComponent != null && leftComponent.isVisible() ) {
+ int cw = leftComponent.getPreferredSize().width;
+ leftComponent.setBounds( x, ow, cw, h );
+ x += cw;
+ }
}
- // layout right component
- if( rightComponent != null && rightComponent.isVisible() ) {
- int w = rightComponent.getPreferredSize().width;
- rightComponent.setBounds( parent.getWidth() - ow - w, ow, w, h );
+ // layout right components
+ x = parent.getWidth() - ow;
+ for( JComponent rightComponent : rightComponents ) {
+ if( rightComponent != null && rightComponent.isVisible() ) {
+ int cw = rightComponent.getPreferredSize().width;
+ x -= cw;
+ rightComponent.setBounds( x, ow, cw, h );
+ }
}
}
@@ -780,4 +925,24 @@ debug*/
((LayoutManager2)delegate).invalidateLayout( target );
}
}
+ //---- class FlatDocumentListener -----------------------------------------
+
+ private class FlatDocumentListener
+ implements DocumentListener
+ {
+ @Override
+ public void insertUpdate( DocumentEvent e ) {
+ documentChanged( e );
+ }
+
+ @Override
+ public void removeUpdate( DocumentEvent e ) {
+ documentChanged( e );
+ }
+
+ @Override
+ public void changedUpdate( DocumentEvent e ) {
+ documentChanged( e );
+ }
+ }
}
diff --git a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties
index 53879b71..f8ba150b 100644
--- a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties
+++ b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties
@@ -907,3 +907,16 @@ Tree.icon.openColor = @icon
[style]ToolBarSeparator.inTextField = \
separatorWidth: 3
+
+
+#---- clearButton ----
+# for clear/cancel button in text fields
+
+[style]Button.clearButton = \
+ icon: com.formdev.flatlaf.icons.FlatClearIcon; \
+ focusable: false; \
+ toolbar.margin: 1,1,1,1; \
+ toolbar.spacingInsets: 1,1,1,1; \
+ background: $TextField.background; \
+ toolbar.hoverBackground: $TextField.background; \
+ toolbar.pressedBackground: $TextField.background
diff --git a/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyleableInfo.java b/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyleableInfo.java
index e663fba6..7842df5d 100644
--- a/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyleableInfo.java
+++ b/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyleableInfo.java
@@ -823,7 +823,8 @@ public class TestFlatStyleableInfo
"focusedBackground", Color.class,
"iconTextGap", int.class,
"leadingIcon", Icon.class,
- "trailingIcon", Icon.class
+ "trailingIcon", Icon.class,
+ "showClearButton", boolean.class
);
// border
diff --git a/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyling.java b/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyling.java
index b63a234d..700ced80 100644
--- a/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyling.java
+++ b/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyling.java
@@ -1011,6 +1011,8 @@ public class TestFlatStyling
ui.applyStyle( "leadingIcon: com.formdev.flatlaf.icons.FlatSearchIcon" );
ui.applyStyle( "trailingIcon: com.formdev.flatlaf.icons.FlatClearIcon" );
+ ui.applyStyle( "showClearButton: true" );
+
// border
flatTextBorder( style -> ui.applyStyle( style ) );
diff --git a/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/BasicComponentsPanel.java b/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/BasicComponentsPanel.java
index dc9e05e3..a43d40a5 100644
--- a/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/BasicComponentsPanel.java
+++ b/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/BasicComponentsPanel.java
@@ -73,6 +73,10 @@ class BasicComponentsPanel
searchToolbar.addSeparator();
searchToolbar.add( regexButton );
compsTextField.putClientProperty( FlatClientProperties.TEXT_FIELD_TRAILING_COMPONENT, searchToolbar );
+
+ // show clear button (if text field is not empty)
+ compsTextField.putClientProperty( FlatClientProperties.TEXT_FIELD_SHOW_CLEAR_BUTTON, true );
+ clearTextField.putClientProperty( FlatClientProperties.TEXT_FIELD_SHOW_CLEAR_BUTTON, true );
}
private void initComponents() {
@@ -173,6 +177,7 @@ class BasicComponentsPanel
JTextField iconsTextField = new JTextField();
JLabel compsLabel = new JLabel();
compsTextField = new JTextField();
+ clearTextField = new JTextField();
JLabel fontsLabel = new JLabel();
JLabel h00Label = new JLabel();
JLabel h0Label = new JLabel();
@@ -734,6 +739,10 @@ class BasicComponentsPanel
add(compsLabel, "cell 0 15");
add(compsTextField, "cell 1 15 2 1,growx");
+ //---- clearTextField ----
+ clearTextField.setText("clear me");
+ add(clearTextField, "cell 3 15,growx");
+
//---- fontsLabel ----
fontsLabel.setText("Typography / Fonts:");
add(fontsLabel, "cell 0 16");
@@ -905,5 +914,6 @@ class BasicComponentsPanel
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
private JTextField compsTextField;
+ private JTextField clearTextField;
// JFormDesigner - End of variables declaration //GEN-END:variables
}
diff --git a/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/BasicComponentsPanel.jfd b/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/BasicComponentsPanel.jfd
index c5eb1554..b6d9a4b9 100644
--- a/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/BasicComponentsPanel.jfd
+++ b/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/BasicComponentsPanel.jfd
@@ -685,6 +685,15 @@ new FormModel {
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 15 2 1,growx"
} )
+ add( new FormComponent( "javax.swing.JTextField" ) {
+ name: "clearTextField"
+ "text": "clear me"
+ auxiliary() {
+ "JavaCodeGenerator.variableLocal": false
+ }
+ }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
+ "value": "cell 3 15,growx"
+ } )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "fontsLabel"
"text": "Typography / Fonts:"
diff --git a/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/components/FlatFormattedTextField.java b/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/components/FlatFormattedTextField.java
index 326930f7..c3aa8826 100644
--- a/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/components/FlatFormattedTextField.java
+++ b/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/components/FlatFormattedTextField.java
@@ -144,6 +144,26 @@ public class FlatFormattedTextField
}
+ /**
+ * Returns whether a "clear" (or "cancel") button is shown.
+ *
+ * @since 2
+ */
+ public boolean isShowClearButton() {
+ return getClientPropertyBoolean( TEXT_FIELD_SHOW_CLEAR_BUTTON, false );
+ }
+
+ /**
+ * Specifies whether a "clear" (or "cancel") button is shown on the trailing side
+ * if the text field is not empty, editable and enabled.
+ *
+ * @since 2
+ */
+ public void setShowClearButton( boolean showClearButton ) {
+ putClientPropertyBoolean( TEXT_FIELD_SHOW_CLEAR_BUTTON, showClearButton, false );
+ }
+
+
/**
* Returns whether all text is selected when the text component gains focus.
*/
diff --git a/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/components/FlatPasswordField.java b/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/components/FlatPasswordField.java
index cd7f2374..7c36be76 100644
--- a/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/components/FlatPasswordField.java
+++ b/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/components/FlatPasswordField.java
@@ -144,6 +144,26 @@ public class FlatPasswordField
}
+ /**
+ * Returns whether a "clear" (or "cancel") button is shown.
+ *
+ * @since 2
+ */
+ public boolean isShowClearButton() {
+ return getClientPropertyBoolean( TEXT_FIELD_SHOW_CLEAR_BUTTON, false );
+ }
+
+ /**
+ * Specifies whether a "clear" (or "cancel") button is shown on the trailing side
+ * if the text field is not empty, editable and enabled.
+ *
+ * @since 2
+ */
+ public void setShowClearButton( boolean showClearButton ) {
+ putClientPropertyBoolean( TEXT_FIELD_SHOW_CLEAR_BUTTON, showClearButton, false );
+ }
+
+
/**
* Returns whether all text is selected when the text component gains focus.
*/
diff --git a/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/components/FlatTextField.java b/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/components/FlatTextField.java
index c7747bf5..c2d14a07 100644
--- a/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/components/FlatTextField.java
+++ b/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/components/FlatTextField.java
@@ -143,6 +143,26 @@ public class FlatTextField
}
+ /**
+ * Returns whether a "clear" (or "cancel") button is shown.
+ *
+ * @since 2
+ */
+ public boolean isShowClearButton() {
+ return getClientPropertyBoolean( TEXT_FIELD_SHOW_CLEAR_BUTTON, false );
+ }
+
+ /**
+ * Specifies whether a "clear" (or "cancel") button is shown on the trailing side
+ * if the text field is not empty, editable and enabled.
+ *
+ * @since 2
+ */
+ public void setShowClearButton( boolean showClearButton ) {
+ putClientPropertyBoolean( TEXT_FIELD_SHOW_CLEAR_BUTTON, showClearButton, false );
+ }
+
+
// NOTE: enum names must be equal to allowed strings
public enum SelectAllOnFocusPolicy { never, once, always };
diff --git a/flatlaf-testing/dumps/uidefaults/FlatDarkLaf_1.8.0.txt b/flatlaf-testing/dumps/uidefaults/FlatDarkLaf_1.8.0.txt
index 7cf0ed6a..c1741a44 100644
--- a/flatlaf-testing/dumps/uidefaults/FlatDarkLaf_1.8.0.txt
+++ b/flatlaf-testing/dumps/uidefaults/FlatDarkLaf_1.8.0.txt
@@ -1421,6 +1421,7 @@ ViewportUI com.formdev.flatlaf.ui.FlatViewportUI
#---- [style]Button ----
+[style]Button.clearButton icon: com.formdev.flatlaf.icons.FlatClearIcon; focusable: false; toolbar.margin: 1,1,1,1; toolbar.spacingInsets: 1,1,1,1; background: $TextField.background; toolbar.hoverBackground: $TextField.background; toolbar.pressedBackground: $TextField.background
[style]Button.inTextField focusable: false; toolbar.margin: 1,1,1,1; toolbar.spacingInsets: 1,1,1,1; background: $TextField.background; toolbar.hoverBackground: lighten($TextField.background,4%,derived); toolbar.pressedBackground: lighten($TextField.background,6%,derived); toolbar.selectedBackground: lighten($TextField.background,12%,derived)
diff --git a/flatlaf-testing/dumps/uidefaults/FlatLightLaf_1.8.0.txt b/flatlaf-testing/dumps/uidefaults/FlatLightLaf_1.8.0.txt
index c0ae8ece..00d5267e 100644
--- a/flatlaf-testing/dumps/uidefaults/FlatLightLaf_1.8.0.txt
+++ b/flatlaf-testing/dumps/uidefaults/FlatLightLaf_1.8.0.txt
@@ -1426,6 +1426,7 @@ ViewportUI com.formdev.flatlaf.ui.FlatViewportUI
#---- [style]Button ----
+[style]Button.clearButton icon: com.formdev.flatlaf.icons.FlatClearIcon; focusable: false; toolbar.margin: 1,1,1,1; toolbar.spacingInsets: 1,1,1,1; background: $TextField.background; toolbar.hoverBackground: $TextField.background; toolbar.pressedBackground: $TextField.background
[style]Button.inTextField focusable: false; toolbar.margin: 1,1,1,1; toolbar.spacingInsets: 1,1,1,1; background: $TextField.background; toolbar.hoverBackground: darken($TextField.background,4%,derived); toolbar.pressedBackground: darken($TextField.background,8%,derived); toolbar.selectedBackground: darken($TextField.background,12%,derived)
diff --git a/flatlaf-testing/dumps/uidefaults/FlatTestLaf_1.8.0.txt b/flatlaf-testing/dumps/uidefaults/FlatTestLaf_1.8.0.txt
index be298499..204b1cd8 100644
--- a/flatlaf-testing/dumps/uidefaults/FlatTestLaf_1.8.0.txt
+++ b/flatlaf-testing/dumps/uidefaults/FlatTestLaf_1.8.0.txt
@@ -1439,6 +1439,7 @@ ViewportUI com.formdev.flatlaf.ui.FlatViewportUI
#---- [style]Button ----
+[style]Button.clearButton icon: com.formdev.flatlaf.icons.FlatClearIcon; focusable: false; toolbar.margin: 1,1,1,1; toolbar.spacingInsets: 1,1,1,1; background: $TextField.background; toolbar.hoverBackground: $TextField.background; toolbar.pressedBackground: $TextField.background
[style]Button.inTextField focusable: false; toolbar.margin: 1,1,1,1; toolbar.spacingInsets: 1,1,1,1
diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatTextComponentsTest.java b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatTextComponentsTest.java
index a0c66148..e3bfa84b 100644
--- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatTextComponentsTest.java
+++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatTextComponentsTest.java
@@ -121,6 +121,11 @@ public class FlatTextComponentsTest
}
}
+ private void showClearButton() {
+ putTextFieldClientProperty( FlatClientProperties.TEXT_FIELD_SHOW_CLEAR_BUTTON,
+ showClearButtonCheckBox.isSelected() );
+ }
+
private void putTextFieldClientProperty( String key, Object value ) {
for( Component c : getComponents() ) {
if( c instanceof JTextField )
@@ -168,6 +173,7 @@ public class FlatTextComponentsTest
trailingComponentCheckBox = new JCheckBox();
leadingComponentVisibleCheckBox = new JCheckBox();
trailingComponentVisibleCheckBox = new JCheckBox();
+ showClearButtonCheckBox = new JCheckBox();
JLabel passwordFieldLabel = new JLabel();
JPasswordField passwordField1 = new JPasswordField();
JPasswordField passwordField3 = new JPasswordField();
@@ -319,6 +325,7 @@ public class FlatTextComponentsTest
"[]0" +
"[]" +
"[]0" +
+ "[]" +
"[]"));
//---- button1 ----
@@ -404,6 +411,12 @@ public class FlatTextComponentsTest
trailingComponentVisibleCheckBox.setName("trailingComponentVisibleCheckBox");
trailingComponentVisibleCheckBox.addActionListener(e -> trailingComponentVisible());
panel1.add(trailingComponentVisibleCheckBox, "cell 0 10 2 1,alignx left,growx 0");
+
+ //---- showClearButtonCheckBox ----
+ showClearButtonCheckBox.setText("clear button");
+ showClearButtonCheckBox.setName("showClearButtonCheckBox");
+ showClearButtonCheckBox.addActionListener(e -> showClearButton());
+ panel1.add(showClearButtonCheckBox, "cell 0 11 2 1,alignx left,growx 0");
}
add(panel1, "cell 4 0 1 10,aligny top,growy 0");
@@ -719,6 +732,7 @@ public class FlatTextComponentsTest
private JCheckBox trailingComponentCheckBox;
private JCheckBox leadingComponentVisibleCheckBox;
private JCheckBox trailingComponentVisibleCheckBox;
+ private JCheckBox showClearButtonCheckBox;
private JTextField textField;
private JCheckBox dragEnabledCheckBox;
private JTextArea textArea;
diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatTextComponentsTest.jfd b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatTextComponentsTest.jfd
index 2dfcfb7b..06681160 100644
--- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatTextComponentsTest.jfd
+++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatTextComponentsTest.jfd
@@ -77,7 +77,7 @@ new FormModel {
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) {
"$layoutConstraints": "hidemode 3"
"$columnConstraints": "[fill][fill]"
- "$rowConstraints": "[][][][][][]0[][]0[][]0[]"
+ "$rowConstraints": "[][][][][][]0[][]0[][]0[][]"
} ) {
name: "panel1"
"border": new javax.swing.border.TitledBorder( "Control" )
@@ -210,6 +210,16 @@ new FormModel {
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 10 2 1,alignx left,growx 0"
} )
+ add( new FormComponent( "javax.swing.JCheckBox" ) {
+ name: "showClearButtonCheckBox"
+ "text": "clear button"
+ auxiliary() {
+ "JavaCodeGenerator.variableLocal": false
+ }
+ addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "showClearButton", false ) )
+ }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
+ "value": "cell 0 11 2 1,alignx left,growx 0"
+ } )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 4 0 1 10,aligny top,growy 0"
} )
diff --git a/flatlaf-theme-editor/src/main/resources/com/formdev/flatlaf/themeeditor/FlatLafUIKeys.txt b/flatlaf-theme-editor/src/main/resources/com/formdev/flatlaf/themeeditor/FlatLafUIKeys.txt
index 3257247b..b0340b10 100644
--- a/flatlaf-theme-editor/src/main/resources/com/formdev/flatlaf/themeeditor/FlatLafUIKeys.txt
+++ b/flatlaf-theme-editor/src/main/resources/com/formdev/flatlaf/themeeditor/FlatLafUIKeys.txt
@@ -1115,6 +1115,7 @@ ViewportUI
[style].monospaced
[style].semibold
[style].small
+[style]Button.clearButton
[style]Button.inTextField
[style]ToggleButton.inTextField
[style]ToolBar.inTextField
+ * Value type {@link java.lang.Boolean}
+ *
+ * @since 2
+ */
+ String TEXT_FIELD_SHOW_CLEAR_BUTTON = "JTextField.showClearButton";
+
//---- JToggleButton ------------------------------------------------------
/**
diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTextFieldUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTextFieldUI.java
index b6946080..62f9496e 100644
--- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTextFieldUI.java
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTextFieldUI.java
@@ -45,10 +45,13 @@ import javax.swing.JToggleButton;
import javax.swing.JToolBar;
import javax.swing.LookAndFeel;
import javax.swing.UIManager;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.UIResource;
import javax.swing.plaf.basic.BasicTextFieldUI;
import javax.swing.text.Caret;
+import javax.swing.text.Document;
import javax.swing.text.JTextComponent;
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
@@ -103,6 +106,10 @@ public class FlatTextFieldUI
/** @since 2 */ @Styleable protected Icon trailingIcon;
/** @since 2 */ protected JComponent leadingComponent;
/** @since 2 */ protected JComponent trailingComponent;
+ /** @since 2 */ protected JComponent clearButton;
+
+ // only used via styling (not in UI defaults, but has likewise client properties)
+ /** @since 2 */ @Styleable protected boolean showClearButton;
private Color oldDisabledBackground;
private Color oldInactiveBackground;
@@ -110,6 +117,7 @@ public class FlatTextFieldUI
private Insets defaultMargin;
private FocusListener focusListener;
+ private DocumentListener documentListener;
private Map