diff --git a/CHANGELOG.md b/CHANGELOG.md index da6f25ae..435808d2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,7 +30,10 @@ FlatLaf Change Log (issue #416) - TextField, FormattedTextField and PasswordField: Support leading and trailing icons (set client property `JTextField.leadingIcon` or - `JTextField.trailingIcon` to an `Icon`). (PR #378; issue #368) + `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) - 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 4af43c96..ed3f3acc 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java @@ -763,9 +763,9 @@ public interface FlatClientProperties /** * Specifies a component that will be placed at the leading edge of the tabs area. *
- * For top and bottom tab placement, the layed out component size will be
+ * For top and bottom tab placement, the laid out component size will be
* the preferred component width and the tab area height.
- * For left and right tab placement, the layed out component size will be
+ * For left and right tab placement, the laid out component size will be
* the tab area width and the preferred component height.
*
* Component {@link javax.swing.JTabbedPane}
@@ -776,9 +776,9 @@ public interface FlatClientProperties
/**
* Specifies a component that will be placed at the trailing edge of the tabs area.
*
- * For top and bottom tab placement, the layed out component size will be
+ * For top and bottom tab placement, the laid out component size will be
* the available horizontal space (minimum is preferred component width) and the tab area height.
- * For left and right tab placement, the layed out component size will be
+ * For left and right tab placement, the laid out component size will be
* the tab area width and the available vertical space (minimum is preferred component height).
*
* Component {@link javax.swing.JTabbedPane}
@@ -863,6 +863,46 @@ public interface FlatClientProperties
*/
String TEXT_FIELD_TRAILING_ICON = "JTextField.trailingIcon";
+ /**
+ * Specifies a component that will be placed at the leading edge of the text field.
+ *
+ * The component will be positioned inside and aligned to the visible text field border. + * There is no gap between the visible border and the component. + * The laid out component size will be the preferred component width + * and the inner text field height. + *
+ * The component should be not opaque because the text field border is painted + * slightly inside the usually visible border in some cases. + * E.g. when focused (in some themes) or when an outline color is specified + * (see {@link #OUTLINE}. + *
+ * Component {@link javax.swing.JTextField} (and subclasses)
+ * Value type {@link java.awt.Component}
+ *
+ * @since 2
+ */
+ String TEXT_FIELD_LEADING_COMPONENT = "JTextField.leadingComponent";
+
+ /**
+ * Specifies a component that will be placed at the trailing edge of the text field.
+ *
+ * The component will be positioned inside and aligned to the visible text field border. + * There is no gap between the visible border and the component. + * The laid out component size will be the preferred component width + * and the inner text field height. + *
+ * The component should be not opaque because the text field border is painted + * slightly inside the usually visible border in some cases. + * E.g. when focused (in some themes) or when an outline color is specified + * (see {@link #OUTLINE}. + *
+ * Component {@link javax.swing.JTextField} (and subclasses)
+ * Value type {@link java.awt.Component}
+ *
+ * @since 2
+ */
+ String TEXT_FIELD_TRAILING_COMPONENT = "JTextField.trailingComponent";
+
//---- 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 6814e7f8..60db8663 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
@@ -19,12 +19,15 @@ package com.formdev.flatlaf.ui;
import static com.formdev.flatlaf.FlatClientProperties.*;
import static com.formdev.flatlaf.util.UIScale.scale;
import java.awt.Color;
+import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
+import java.awt.LayoutManager;
+import java.awt.LayoutManager2;
import java.awt.Rectangle;
import java.awt.event.FocusListener;
import java.beans.PropertyChangeEvent;
@@ -94,6 +97,8 @@ public class FlatTextFieldUI
/** @since 2 */ @Styleable protected Icon leadingIcon;
/** @since 2 */ @Styleable protected Icon trailingIcon;
+ /** @since 2 */ protected Component leadingComponent;
+ /** @since 2 */ protected Component trailingComponent;
private Color oldDisabledBackground;
private Color oldInactiveBackground;
@@ -115,11 +120,17 @@ public class FlatTextFieldUI
leadingIcon = clientProperty( c, TEXT_FIELD_LEADING_ICON, null, Icon.class );
trailingIcon = clientProperty( c, TEXT_FIELD_TRAILING_ICON, null, Icon.class );
+ installLeadingComponent();
+ installTrailingComponent();
+
installStyle();
}
@Override
public void uninstallUI( JComponent c ) {
+ uninstallLeadingComponent();
+ uninstallTrailingComponent();
+
super.uninstallUI( c );
leadingIcon = null;
@@ -225,6 +236,20 @@ public class FlatTextFieldUI
trailingIcon = (e.getNewValue() instanceof Icon) ? (Icon) e.getNewValue() : null;
c.repaint();
break;
+
+ case TEXT_FIELD_LEADING_COMPONENT:
+ uninstallLeadingComponent();
+ installLeadingComponent();
+ c.revalidate();
+ c.repaint();
+ break;
+
+ case TEXT_FIELD_TRAILING_COMPONENT:
+ uninstallTrailingComponent();
+ installTrailingComponent();
+ c.revalidate();
+ c.repaint();
+ break;
}
}
@@ -444,6 +469,12 @@ debug*/
// add width of leading and trailing icons
size.width += getLeadingIconWidth() + getTrailingIconWidth();
+ // add width of leading and trailing components
+ if( leadingComponent != null && leadingComponent.isVisible() )
+ size.width += leadingComponent.getPreferredSize().width;
+ if( trailingComponent != null && trailingComponent.isVisible() )
+ size.width += trailingComponent.getPreferredSize().width;
+
return size;
}
@@ -510,7 +541,8 @@ debug*/
/**
* Returns the rectangle used to paint leading and trailing icons.
* It invokes {@code super.getVisibleEditorRect()} and reduces left and/or
- * right margin if the text field has leading or trailing icons.
+ * right margin if the text field has leading or trailing icons or components.
+ * Also the preferred widths of leading and trailing components are removed.
*
* @since 2
*/
@@ -519,10 +551,24 @@ debug*/
if( r == null )
return null;
- // if a leading/trailing icon is shown, then the left/right margin is reduced
- // to the top margin, which places the icon nicely centered on left/right side
boolean ltr = isLeftToRight();
- if( ltr ? hasLeadingIcon() : hasTrailingIcon() ) {
+
+ // remove width of leading/trailing components
+ Component leftComponent = ltr ? leadingComponent : trailingComponent;
+ Component rightComponent = ltr ? trailingComponent : leadingComponent;
+ if( leftComponent != null ) {
+ int w = leftComponent.getPreferredSize().width;
+ r.x += w;
+ r.width -= w;
+ }
+ if( rightComponent != null )
+ r.width -= rightComponent.getPreferredSize().width;
+
+ // if a leading/trailing icons (or components) are shown, then the left/right margins are reduced
+ // to the top margin, which places the icon nicely centered on left/right side
+ if( (ltr ? hasLeadingIcon() : hasTrailingIcon()) ||
+ (leftComponent != null && leftComponent.isVisible()) )
+ {
// reduce left margin
Insets margin = getComponent().getMargin();
int newLeftMargin = Math.min( margin.left, margin.top );
@@ -532,7 +578,9 @@ debug*/
r.width += diff;
}
}
- if( ltr ? hasTrailingIcon() : hasLeadingIcon() ) {
+ if( (ltr ? hasTrailingIcon() : hasLeadingIcon()) ||
+ (rightComponent != null && rightComponent.isVisible()) )
+ {
// reduce right margin
Insets margin = getComponent().getMargin();
int newRightMargin = Math.min( margin.right, margin.top );
@@ -540,6 +588,10 @@ debug*/
r.width += scale( margin.right - newRightMargin );
}
+ // make sure that width and height are not negative
+ r.width = Math.max( r.width, 0 );
+ r.height = Math.max( r.height, 0 );
+
return r;
}
@@ -578,4 +630,135 @@ debug*/
if( caret instanceof FlatCaret )
((FlatCaret)caret).scrollCaretToVisible();
}
+
+ /** @since 2 */
+ protected void installLeadingComponent() {
+ JTextComponent c = getComponent();
+ leadingComponent = clientProperty( c, TEXT_FIELD_LEADING_COMPONENT, null, Component.class );
+ if( leadingComponent != null ) {
+ installLayout();
+ c.add( leadingComponent );
+ }
+ }
+
+ /** @since 2 */
+ protected void installTrailingComponent() {
+ JTextComponent c = getComponent();
+ trailingComponent = clientProperty( c, TEXT_FIELD_TRAILING_COMPONENT, null, Component.class );
+ if( trailingComponent != null ) {
+ installLayout();
+ c.add( trailingComponent );
+ }
+ }
+
+ /** @since 2 */
+ protected void uninstallLeadingComponent() {
+ if( leadingComponent != null ) {
+ getComponent().remove( leadingComponent );
+ leadingComponent = null;
+ }
+ }
+
+ /** @since 2 */
+ protected void uninstallTrailingComponent() {
+ if( trailingComponent != null ) {
+ getComponent().remove( trailingComponent );
+ trailingComponent = null;
+ }
+ }
+
+ private void installLayout() {
+ JTextComponent c = getComponent();
+ LayoutManager oldLayout = c.getLayout();
+ if( !(oldLayout instanceof FlatTextFieldLayout) )
+ c.setLayout( new FlatTextFieldLayout( oldLayout ) );
+ }
+
+ //---- class FlatTextFieldLayout ------------------------------------------
+
+ private class FlatTextFieldLayout
+ implements LayoutManager2, UIResource
+ {
+ private final LayoutManager delegate;
+
+ FlatTextFieldLayout( LayoutManager delegate ) {
+ this.delegate = delegate;
+ }
+
+ @Override
+ public void addLayoutComponent( String name, Component comp ) {
+ if( delegate != null )
+ delegate.addLayoutComponent( name, comp );
+ }
+
+ @Override
+ public void removeLayoutComponent( Component comp ) {
+ if( delegate != null )
+ delegate.removeLayoutComponent( comp );
+ }
+
+ @Override
+ public Dimension preferredLayoutSize( Container parent ) {
+ return (delegate != null) ? delegate.preferredLayoutSize( parent ) : null;
+ }
+
+ @Override
+ public Dimension minimumLayoutSize( Container parent ) {
+ return (delegate != null) ? delegate.minimumLayoutSize( parent ) : null;
+ }
+
+ @Override
+ public void layoutContainer( Container parent ) {
+ if( delegate != null )
+ delegate.layoutContainer( parent );
+
+ if( leadingComponent == null && trailingComponent == null )
+ return;
+
+ int ow = FlatUIUtils.getBorderFocusAndLineWidth( getComponent() );
+ int h = parent.getHeight() - ow - ow;
+ boolean ltr = isLeftToRight();
+ Component leftComponent = ltr ? leadingComponent : trailingComponent;
+ Component rightComponent = ltr ? trailingComponent : leadingComponent;
+
+ // layout left component
+ if( leftComponent != null && leftComponent.isVisible() ) {
+ int w = leftComponent.getPreferredSize().width;
+ leftComponent.setBounds( ow, ow, w, h );
+ }
+
+ // layout right component
+ if( rightComponent != null && rightComponent.isVisible() ) {
+ int w = rightComponent.getPreferredSize().width;
+ rightComponent.setBounds( parent.getWidth() - ow - w, ow, w, h );
+ }
+ }
+
+ @Override
+ public void addLayoutComponent( Component comp, Object constraints ) {
+ if( delegate instanceof LayoutManager2 )
+ ((LayoutManager2)delegate).addLayoutComponent( comp, constraints );
+ }
+
+ @Override
+ public Dimension maximumLayoutSize( Container target ) {
+ return (delegate instanceof LayoutManager2) ? ((LayoutManager2)delegate).maximumLayoutSize( target ) : null;
+ }
+
+ @Override
+ public float getLayoutAlignmentX( Container target ) {
+ return (delegate instanceof LayoutManager2) ? ((LayoutManager2)delegate).getLayoutAlignmentX( target ) : 0.5f;
+ }
+
+ @Override
+ public float getLayoutAlignmentY( Container target ) {
+ return (delegate instanceof LayoutManager2) ? ((LayoutManager2)delegate).getLayoutAlignmentY( target ) : 0.5f;
+ }
+
+ @Override
+ public void invalidateLayout( Container target ) {
+ if( delegate instanceof LayoutManager2 )
+ ((LayoutManager2)delegate).invalidateLayout( target );
+ }
+ }
}
diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatUIUtils.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatUIUtils.java
index 2c5cd1b9..fda0c1c8 100644
--- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatUIUtils.java
+++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatUIUtils.java
@@ -278,6 +278,32 @@ public class FlatUIUtils
: 0;
}
+ /**
+ * Returns the scaled line thickness used to compute the border insets.
+ *
+ * @since 2
+ */
+ public static float getBorderLineWidth( JComponent c ) {
+ FlatBorder border = getOutsideFlatBorder( c );
+ return (border != null)
+ ? UIScale.scale( (float) border.getLineWidth( c ) )
+ : 0;
+ }
+
+ /**
+ * Returns the scaled thickness of the border.
+ * This includes the outer focus border and the actual component border.
+ *
+ * @since 2
+ */
+ public static int getBorderFocusAndLineWidth( JComponent c ) {
+ FlatBorder border = getOutsideFlatBorder( c );
+ return (border != null)
+ ? Math.round( UIScale.scale( (float) border.getFocusWidth( c ) )
+ + UIScale.scale( (float) border.getLineWidth( c ) ) )
+ : 0;
+ }
+
/**
* Returns the scaled arc diameter of the border for the given component.
*/
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 b8f1a270..54126d8d 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
@@ -18,6 +18,7 @@ package com.formdev.flatlaf.extras.components;
import static com.formdev.flatlaf.FlatClientProperties.*;
import java.awt.Color;
+import java.awt.Component;
import java.awt.Insets;
import javax.swing.Icon;
import javax.swing.JFormattedTextField;
@@ -85,6 +86,64 @@ public class FlatFormattedTextField
}
+ /**
+ * Returns a component that will be placed at the leading edge of the text field.
+ *
+ * @since 2
+ */
+ public Component getLeadingComponent() {
+ return (Component) getClientProperty( TEXT_FIELD_LEADING_COMPONENT );
+ }
+
+ /**
+ * Specifies a component that will be placed at the leading edge of the text field.
+ *
+ * The component will be positioned inside and aligned to the visible text field border. + * There is no gap between the visible border and the component. + * The laid out component size will be the preferred component width + * and the inner text field height. + *
+ * The component should be not opaque because the text field border is painted + * slightly inside the usually visible border in some cases. + * E.g. when focused (in some themes) or when an outline color is specified + * (see {@link #setOutline(Object)}. + * + * @since 2 + */ + public void setLeadingComponent( Component leadingComponent ) { + putClientProperty( TEXT_FIELD_LEADING_COMPONENT, leadingComponent ); + } + + + /** + * Returns a component that will be placed at the trailing edge of the text field. + * + * @since 2 + */ + public Component getTrailingComponent() { + return (Component) getClientProperty( TEXT_FIELD_TRAILING_COMPONENT ); + } + + /** + * Specifies a component that will be placed at the trailing edge of the text field. + *
+ * The component will be positioned inside and aligned to the visible text field border. + * There is no gap between the visible border and the component. + * The laid out component size will be the preferred component width + * and the inner text field height. + *
+ * The component should be not opaque because the text field border is painted + * slightly inside the usually visible border in some cases. + * E.g. when focused (in some themes) or when an outline color is specified + * (see {@link #setOutline(Object)}. + * + * @since 2 + */ + public void setTrailingComponent( Component trailingComponent ) { + putClientProperty( TEXT_FIELD_TRAILING_COMPONENT, trailingComponent ); + } + + /** * 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 1078d368..392db28e 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 @@ -18,6 +18,7 @@ package com.formdev.flatlaf.extras.components; import static com.formdev.flatlaf.FlatClientProperties.*; import java.awt.Color; +import java.awt.Component; import java.awt.Insets; import javax.swing.Icon; import javax.swing.JPasswordField; @@ -85,6 +86,64 @@ public class FlatPasswordField } + /** + * Returns a component that will be placed at the leading edge of the text field. + * + * @since 2 + */ + public Component getLeadingComponent() { + return (Component) getClientProperty( TEXT_FIELD_LEADING_COMPONENT ); + } + + /** + * Specifies a component that will be placed at the leading edge of the text field. + *
+ * The component will be positioned inside and aligned to the visible text field border. + * There is no gap between the visible border and the component. + * The laid out component size will be the preferred component width + * and the inner text field height. + *
+ * The component should be not opaque because the text field border is painted + * slightly inside the usually visible border in some cases. + * E.g. when focused (in some themes) or when an outline color is specified + * (see {@link #setOutline(Object)}. + * + * @since 2 + */ + public void setLeadingComponent( Component leadingComponent ) { + putClientProperty( TEXT_FIELD_LEADING_COMPONENT, leadingComponent ); + } + + + /** + * Returns a component that will be placed at the trailing edge of the text field. + * + * @since 2 + */ + public Component getTrailingComponent() { + return (Component) getClientProperty( TEXT_FIELD_TRAILING_COMPONENT ); + } + + /** + * Specifies a component that will be placed at the trailing edge of the text field. + *
+ * The component will be positioned inside and aligned to the visible text field border. + * There is no gap between the visible border and the component. + * The laid out component size will be the preferred component width + * and the inner text field height. + *
+ * The component should be not opaque because the text field border is painted + * slightly inside the usually visible border in some cases. + * E.g. when focused (in some themes) or when an outline color is specified + * (see {@link #setOutline(Object)}. + * + * @since 2 + */ + public void setTrailingComponent( Component trailingComponent ) { + putClientProperty( TEXT_FIELD_TRAILING_COMPONENT, trailingComponent ); + } + + /** * 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 31d8850d..9bd0f98a 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 @@ -18,6 +18,7 @@ package com.formdev.flatlaf.extras.components; import static com.formdev.flatlaf.FlatClientProperties.*; import java.awt.Color; +import java.awt.Component; import java.awt.Insets; import javax.swing.Icon; import javax.swing.JTextField; @@ -84,6 +85,64 @@ public class FlatTextField } + /** + * Returns a component that will be placed at the leading edge of the text field. + * + * @since 2 + */ + public Component getLeadingComponent() { + return (Component) getClientProperty( TEXT_FIELD_LEADING_COMPONENT ); + } + + /** + * Specifies a component that will be placed at the leading edge of the text field. + *
+ * The component will be positioned inside and aligned to the visible text field border. + * There is no gap between the visible border and the component. + * The laid out component size will be the preferred component width + * and the inner text field height. + *
+ * The component should be not opaque because the text field border is painted + * slightly inside the usually visible border in some cases. + * E.g. when focused (in some themes) or when an outline color is specified + * (see {@link #setOutline(Object)}. + * + * @since 2 + */ + public void setLeadingComponent( Component leadingComponent ) { + putClientProperty( TEXT_FIELD_LEADING_COMPONENT, leadingComponent ); + } + + + /** + * Returns a component that will be placed at the trailing edge of the text field. + * + * @since 2 + */ + public Component getTrailingComponent() { + return (Component) getClientProperty( TEXT_FIELD_TRAILING_COMPONENT ); + } + + /** + * Specifies a component that will be placed at the trailing edge of the text field. + *
+ * The component will be positioned inside and aligned to the visible text field border. + * There is no gap between the visible border and the component. + * The laid out component size will be the preferred component width + * and the inner text field height. + *
+ * The component should be not opaque because the text field border is painted
+ * slightly inside the usually visible border in some cases.
+ * E.g. when focused (in some themes) or when an outline color is specified
+ * (see {@link #setOutline(Object)}.
+ *
+ * @since 2
+ */
+ public void setTrailingComponent( Component trailingComponent ) {
+ putClientProperty( TEXT_FIELD_TRAILING_COMPONENT, trailingComponent );
+ }
+
+
// NOTE: enum names must be equal to allowed strings
public enum SelectAllOnFocusPolicy { never, once, always };
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 e72cb16b..1af9ec05 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
@@ -21,6 +21,7 @@ import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Insets;
+import java.util.function.Supplier;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.text.DefaultEditorKit;
@@ -58,26 +59,54 @@ public class FlatTextComponentsTest
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 );
- }
+ putTextFieldClientProperty( FlatClientProperties.TEXT_FIELD_PADDING, padding );
}
private void leadingIcon() {
- applyIcon( FlatClientProperties.TEXT_FIELD_LEADING_ICON, leadingIconCheckBox.isSelected()
+ putTextFieldClientProperty( FlatClientProperties.TEXT_FIELD_LEADING_ICON, leadingIconCheckBox.isSelected()
? new TestIcon( 8, 16, Color.blue ) : null );
}
private void trailingIcon() {
- applyIcon( FlatClientProperties.TEXT_FIELD_TRAILING_ICON, trailingIconCheckBox.isSelected()
+ putTextFieldClientProperty( FlatClientProperties.TEXT_FIELD_TRAILING_ICON, trailingIconCheckBox.isSelected()
? new TestIcon( 24, 12, Color.magenta ) : null );
}
- private void applyIcon( String key, Icon icon ) {
+ private void leadingComponent() {
+ putTextFieldClientProperty( FlatClientProperties.TEXT_FIELD_LEADING_COMPONENT, () -> {
+ if( !leadingComponentCheckBox.isSelected() )
+ return null;
+
+ JLabel l = new JLabel( "lead" );
+ l.setOpaque( true );
+ l.setBackground( Color.green );
+ return l;
+ } );
+ }
+
+ private void trailingComponent() {
+ putTextFieldClientProperty( FlatClientProperties.TEXT_FIELD_TRAILING_COMPONENT, () -> {
+ if( !trailingComponentCheckBox.isSelected() )
+ return null;
+
+ JLabel l = new JLabel( "tr" );
+ l.setOpaque( true );
+ l.setBackground( Color.magenta );
+ return l;
+ } );
+ }
+
+ private void putTextFieldClientProperty( String key, Object value ) {
for( Component c : getComponents() ) {
if( c instanceof JTextField )
- ((JTextField)c).putClientProperty( key, icon );
+ ((JTextField)c).putClientProperty( key, value );
+ }
+ }
+
+ private void putTextFieldClientProperty( String key, Supplier