mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2025-12-07 22:40:53 +03:00
TextField: support "clear" (or "cancel") button to empty text field
This commit is contained in:
16
CHANGELOG.md
16
CHANGELOG.md
@@ -28,12 +28,16 @@ FlatLaf Change Log
|
|||||||
setting UI default `OptionPane.showIcon` to `true`. (issue #416)
|
setting UI default `OptionPane.showIcon` to `true`. (issue #416)
|
||||||
- No longer show the Java "duke/cup" icon if no window icon image is set.
|
- No longer show the Java "duke/cup" icon if no window icon image is set.
|
||||||
(issue #416)
|
(issue #416)
|
||||||
- TextField, FormattedTextField and PasswordField: Support leading and trailing
|
- TextField, FormattedTextField and PasswordField:
|
||||||
icons (set client property `JTextField.leadingIcon` or
|
- Support leading and trailing icons (set client property
|
||||||
`JTextField.trailingIcon` to a `javax.swing.Icon`). (PR #378; issue #368)
|
`JTextField.leadingIcon` or `JTextField.trailingIcon` to a
|
||||||
- TextField, FormattedTextField and PasswordField: Support leading and trailing
|
`javax.swing.Icon`). (PR #378; issue #368)
|
||||||
components (set client property `JTextField.leadingComponent` or
|
- Support leading and trailing components (set client property
|
||||||
`JTextField.trailingComponent` to a `java.awt.Component`). (PR #386)
|
`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
|
- TextComponents: Double/triple-click-and-drag now extends selection by whole
|
||||||
words/lines.
|
words/lines.
|
||||||
- Theming improvements: Reworks core themes to make it easier to create new
|
- Theming improvements: Reworks core themes to make it easier to create new
|
||||||
|
|||||||
@@ -903,6 +903,17 @@ public interface FlatClientProperties
|
|||||||
*/
|
*/
|
||||||
String TEXT_FIELD_TRAILING_COMPONENT = "JTextField.trailingComponent";
|
String TEXT_FIELD_TRAILING_COMPONENT = "JTextField.trailingComponent";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies whether a "clear" (or "cancel") button is shown on the trailing side
|
||||||
|
* if the text field is not empty, editable and enabled. Default is {@code false}.
|
||||||
|
* <p>
|
||||||
|
* <strong>Component</strong> {@link javax.swing.JTextField} (and subclasses)<br>
|
||||||
|
* <strong>Value type</strong> {@link java.lang.Boolean}
|
||||||
|
*
|
||||||
|
* @since 2
|
||||||
|
*/
|
||||||
|
String TEXT_FIELD_SHOW_CLEAR_BUTTON = "JTextField.showClearButton";
|
||||||
|
|
||||||
//---- JToggleButton ------------------------------------------------------
|
//---- JToggleButton ------------------------------------------------------
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -45,10 +45,13 @@ import javax.swing.JToggleButton;
|
|||||||
import javax.swing.JToolBar;
|
import javax.swing.JToolBar;
|
||||||
import javax.swing.LookAndFeel;
|
import javax.swing.LookAndFeel;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
|
import javax.swing.event.DocumentEvent;
|
||||||
|
import javax.swing.event.DocumentListener;
|
||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
import javax.swing.plaf.UIResource;
|
import javax.swing.plaf.UIResource;
|
||||||
import javax.swing.plaf.basic.BasicTextFieldUI;
|
import javax.swing.plaf.basic.BasicTextFieldUI;
|
||||||
import javax.swing.text.Caret;
|
import javax.swing.text.Caret;
|
||||||
|
import javax.swing.text.Document;
|
||||||
import javax.swing.text.JTextComponent;
|
import javax.swing.text.JTextComponent;
|
||||||
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
import com.formdev.flatlaf.ui.FlatStylingSupport.Styleable;
|
||||||
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
|
import com.formdev.flatlaf.ui.FlatStylingSupport.StyleableUI;
|
||||||
@@ -103,6 +106,10 @@ public class FlatTextFieldUI
|
|||||||
/** @since 2 */ @Styleable protected Icon trailingIcon;
|
/** @since 2 */ @Styleable protected Icon trailingIcon;
|
||||||
/** @since 2 */ protected JComponent leadingComponent;
|
/** @since 2 */ protected JComponent leadingComponent;
|
||||||
/** @since 2 */ protected JComponent trailingComponent;
|
/** @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 oldDisabledBackground;
|
||||||
private Color oldInactiveBackground;
|
private Color oldInactiveBackground;
|
||||||
@@ -110,6 +117,7 @@ public class FlatTextFieldUI
|
|||||||
private Insets defaultMargin;
|
private Insets defaultMargin;
|
||||||
|
|
||||||
private FocusListener focusListener;
|
private FocusListener focusListener;
|
||||||
|
private DocumentListener documentListener;
|
||||||
private Map<String, Object> oldStyleValues;
|
private Map<String, Object> oldStyleValues;
|
||||||
private AtomicBoolean borderShared;
|
private AtomicBoolean borderShared;
|
||||||
|
|
||||||
@@ -126,6 +134,7 @@ public class FlatTextFieldUI
|
|||||||
|
|
||||||
installLeadingComponent();
|
installLeadingComponent();
|
||||||
installTrailingComponent();
|
installTrailingComponent();
|
||||||
|
installClearButton();
|
||||||
|
|
||||||
installStyle();
|
installStyle();
|
||||||
}
|
}
|
||||||
@@ -134,6 +143,7 @@ public class FlatTextFieldUI
|
|||||||
public void uninstallUI( JComponent c ) {
|
public void uninstallUI( JComponent c ) {
|
||||||
uninstallLeadingComponent();
|
uninstallLeadingComponent();
|
||||||
uninstallTrailingComponent();
|
uninstallTrailingComponent();
|
||||||
|
uninstallClearButton();
|
||||||
|
|
||||||
super.uninstallUI( c );
|
super.uninstallUI( c );
|
||||||
|
|
||||||
@@ -196,6 +206,11 @@ public class FlatTextFieldUI
|
|||||||
|
|
||||||
getComponent().removeFocusListener( focusListener );
|
getComponent().removeFocusListener( focusListener );
|
||||||
focusListener = null;
|
focusListener = null;
|
||||||
|
|
||||||
|
if( documentListener != null ) {
|
||||||
|
getComponent().getDocument().removeDocumentListener( documentListener );
|
||||||
|
documentListener = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -254,9 +269,47 @@ public class FlatTextFieldUI
|
|||||||
c.revalidate();
|
c.revalidate();
|
||||||
c.repaint();
|
c.repaint();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case TEXT_FIELD_SHOW_CLEAR_BUTTON:
|
||||||
|
uninstallClearButton();
|
||||||
|
installClearButton();
|
||||||
|
c.revalidate();
|
||||||
|
c.repaint();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "enabled":
|
||||||
|
case "editable":
|
||||||
|
updateClearButton();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case "document":
|
||||||
|
if( documentListener != null ) {
|
||||||
|
if( e.getOldValue() instanceof Document )
|
||||||
|
((Document)e.getOldValue()).removeDocumentListener( documentListener );
|
||||||
|
if( e.getNewValue() instanceof Document )
|
||||||
|
((Document)e.getNewValue()).addDocumentListener( documentListener );
|
||||||
|
|
||||||
|
updateClearButton();
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 2 */
|
||||||
|
protected void installDocumentListener() {
|
||||||
|
if( documentListener != null )
|
||||||
|
return;
|
||||||
|
|
||||||
|
documentListener = new FlatDocumentListener();
|
||||||
|
getComponent().getDocument().addDocumentListener( documentListener );
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since 2 */
|
||||||
|
protected void documentChanged( DocumentEvent e ) {
|
||||||
|
if( clearButton != null )
|
||||||
|
updateClearButton();
|
||||||
|
}
|
||||||
|
|
||||||
/** @since 2 */
|
/** @since 2 */
|
||||||
protected void installStyle() {
|
protected void installStyle() {
|
||||||
try {
|
try {
|
||||||
@@ -275,10 +328,15 @@ public class FlatTextFieldUI
|
|||||||
protected void applyStyle( Object style ) {
|
protected void applyStyle( Object style ) {
|
||||||
oldDisabledBackground = disabledBackground;
|
oldDisabledBackground = disabledBackground;
|
||||||
oldInactiveBackground = inactiveBackground;
|
oldInactiveBackground = inactiveBackground;
|
||||||
|
boolean oldShowClearButton = showClearButton;
|
||||||
|
|
||||||
oldStyleValues = FlatStylingSupport.parseAndApply( oldStyleValues, style, this::applyStyleProperty );
|
oldStyleValues = FlatStylingSupport.parseAndApply( oldStyleValues, style, this::applyStyleProperty );
|
||||||
|
|
||||||
updateBackground();
|
updateBackground();
|
||||||
|
if( showClearButton != oldShowClearButton ) {
|
||||||
|
uninstallClearButton();
|
||||||
|
installClearButton();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @since 2 */
|
/** @since 2 */
|
||||||
@@ -474,10 +532,14 @@ debug*/
|
|||||||
size.width += getLeadingIconWidth() + getTrailingIconWidth();
|
size.width += getLeadingIconWidth() + getTrailingIconWidth();
|
||||||
|
|
||||||
// add width of leading and trailing components
|
// add width of leading and trailing components
|
||||||
if( leadingComponent != null && leadingComponent.isVisible() )
|
for( JComponent comp : getLeadingComponents() ) {
|
||||||
size.width += leadingComponent.getPreferredSize().width;
|
if( comp != null && comp.isVisible() )
|
||||||
if( trailingComponent != null && trailingComponent.isVisible() )
|
size.width += comp.getPreferredSize().width;
|
||||||
size.width += trailingComponent.getPreferredSize().width;
|
}
|
||||||
|
for( JComponent comp : getTrailingComponents() ) {
|
||||||
|
if( comp != null && comp.isVisible() )
|
||||||
|
size.width += comp.getPreferredSize().width;
|
||||||
|
}
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
@@ -558,17 +620,24 @@ debug*/
|
|||||||
boolean ltr = isLeftToRight();
|
boolean ltr = isLeftToRight();
|
||||||
|
|
||||||
// remove width of leading/trailing components
|
// remove width of leading/trailing components
|
||||||
JComponent leftComponent = ltr ? leadingComponent : trailingComponent;
|
JComponent[] leftComponents = ltr ? getLeadingComponents() : getTrailingComponents();
|
||||||
JComponent rightComponent = ltr ? trailingComponent : leadingComponent;
|
JComponent[] rightComponents = ltr ? getTrailingComponents() : getLeadingComponents();
|
||||||
boolean leftVisible = leftComponent != null && leftComponent.isVisible();
|
boolean leftVisible = false;
|
||||||
boolean rightVisible = rightComponent != null && rightComponent.isVisible();
|
boolean rightVisible = false;
|
||||||
if( leftVisible ) {
|
for( JComponent leftComponent : leftComponents ) {
|
||||||
int w = leftComponent.getPreferredSize().width;
|
if( leftComponent != null && leftComponent.isVisible() ) {
|
||||||
r.x += w;
|
int w = leftComponent.getPreferredSize().width;
|
||||||
r.width -= w;
|
r.x += w;
|
||||||
|
r.width -= w;
|
||||||
|
leftVisible = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for( JComponent rightComponent : rightComponents ) {
|
||||||
|
if( rightComponent != null && rightComponent.isVisible() ) {
|
||||||
|
r.width -= rightComponent.getPreferredSize().width;
|
||||||
|
rightVisible = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if( rightVisible )
|
|
||||||
r.width -= rightComponent.getPreferredSize().width;
|
|
||||||
|
|
||||||
// if a leading/trailing icons (or components) are shown, then the left/right margins are reduced
|
// 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
|
// to the top margin, which places the icon nicely centered on left/right side
|
||||||
@@ -671,6 +740,76 @@ debug*/
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @since 2 */
|
||||||
|
protected void installClearButton() {
|
||||||
|
JTextComponent c = getComponent();
|
||||||
|
if( clientPropertyBoolean( c, TEXT_FIELD_SHOW_CLEAR_BUTTON, showClearButton ) ) {
|
||||||
|
clearButton = createClearButton();
|
||||||
|
updateClearButton();
|
||||||
|
installDocumentListener();
|
||||||
|
installLayout();
|
||||||
|
c.add( clearButton );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since 2 */
|
||||||
|
protected JComponent createClearButton() {
|
||||||
|
JButton button = new JButton();
|
||||||
|
button.putClientProperty( STYLE_CLASS, "clearButton" );
|
||||||
|
button.putClientProperty( BUTTON_TYPE, BUTTON_TYPE_TOOLBAR_BUTTON );
|
||||||
|
button.setCursor( Cursor.getDefaultCursor() );
|
||||||
|
button.addActionListener( e -> {
|
||||||
|
getComponent().setText( "" );
|
||||||
|
} );
|
||||||
|
return button;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since 2 */
|
||||||
|
protected void uninstallClearButton() {
|
||||||
|
if( clearButton != null ) {
|
||||||
|
getComponent().remove( clearButton );
|
||||||
|
clearButton = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @since 2 */
|
||||||
|
protected void updateClearButton() {
|
||||||
|
if( clearButton == null )
|
||||||
|
return;
|
||||||
|
|
||||||
|
JTextComponent c = getComponent();
|
||||||
|
boolean visible = c.isEnabled() && c.isEditable() && c.getDocument().getLength() > 0;
|
||||||
|
if( visible != clearButton.isVisible() ) {
|
||||||
|
clearButton.setVisible( visible );
|
||||||
|
c.revalidate();
|
||||||
|
c.repaint();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns components placed at the leading side of the text field.
|
||||||
|
* The returned array may contain {@code null}.
|
||||||
|
* The default implementation returns {@link #leadingComponent}.
|
||||||
|
*
|
||||||
|
* @since 2
|
||||||
|
*/
|
||||||
|
protected JComponent[] getLeadingComponents() {
|
||||||
|
return new JComponent[] { leadingComponent };
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns components placed at the trailing side of the text field.
|
||||||
|
* The returned array may contain {@code null}.
|
||||||
|
* The default implementation returns {@link #trailingComponent} and {@link #clearButton}.
|
||||||
|
* <p>
|
||||||
|
* <strong>Note</strong>: The components in the array must be in reverse (visual) order.
|
||||||
|
*
|
||||||
|
* @since 2
|
||||||
|
*/
|
||||||
|
protected JComponent[] getTrailingComponents() {
|
||||||
|
return new JComponent[] { trailingComponent, clearButton };
|
||||||
|
}
|
||||||
|
|
||||||
/** @since 2 */
|
/** @since 2 */
|
||||||
protected void prepareLeadingOrTrailingComponent( JComponent c ) {
|
protected void prepareLeadingOrTrailingComponent( JComponent c ) {
|
||||||
c.putClientProperty( STYLE_CLASS, "inTextField" );
|
c.putClientProperty( STYLE_CLASS, "inTextField" );
|
||||||
@@ -686,7 +825,8 @@ debug*/
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void installLayout() {
|
/** @since 2 */
|
||||||
|
protected void installLayout() {
|
||||||
JTextComponent c = getComponent();
|
JTextComponent c = getComponent();
|
||||||
LayoutManager oldLayout = c.getLayout();
|
LayoutManager oldLayout = c.getLayout();
|
||||||
if( !(oldLayout instanceof FlatTextFieldLayout) )
|
if( !(oldLayout instanceof FlatTextFieldLayout) )
|
||||||
@@ -731,25 +871,30 @@ debug*/
|
|||||||
if( delegate != null )
|
if( delegate != null )
|
||||||
delegate.layoutContainer( parent );
|
delegate.layoutContainer( parent );
|
||||||
|
|
||||||
if( leadingComponent == null && trailingComponent == null )
|
|
||||||
return;
|
|
||||||
|
|
||||||
int ow = FlatUIUtils.getBorderFocusAndLineWidth( getComponent() );
|
int ow = FlatUIUtils.getBorderFocusAndLineWidth( getComponent() );
|
||||||
int h = parent.getHeight() - ow - ow;
|
int h = parent.getHeight() - ow - ow;
|
||||||
boolean ltr = isLeftToRight();
|
boolean ltr = isLeftToRight();
|
||||||
JComponent leftComponent = ltr ? leadingComponent : trailingComponent;
|
JComponent[] leftComponents = ltr ? getLeadingComponents() : getTrailingComponents();
|
||||||
JComponent rightComponent = ltr ? trailingComponent : leadingComponent;
|
JComponent[] rightComponents = ltr ? getTrailingComponents() : getLeadingComponents();
|
||||||
|
|
||||||
// layout left component
|
// layout left components
|
||||||
if( leftComponent != null && leftComponent.isVisible() ) {
|
int x = ow;
|
||||||
int w = leftComponent.getPreferredSize().width;
|
for( JComponent leftComponent : leftComponents ) {
|
||||||
leftComponent.setBounds( ow, ow, w, h );
|
if( leftComponent != null && leftComponent.isVisible() ) {
|
||||||
|
int cw = leftComponent.getPreferredSize().width;
|
||||||
|
leftComponent.setBounds( x, ow, cw, h );
|
||||||
|
x += cw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// layout right component
|
// layout right components
|
||||||
if( rightComponent != null && rightComponent.isVisible() ) {
|
x = parent.getWidth() - ow;
|
||||||
int w = rightComponent.getPreferredSize().width;
|
for( JComponent rightComponent : rightComponents ) {
|
||||||
rightComponent.setBounds( parent.getWidth() - ow - w, ow, w, h );
|
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 );
|
((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 );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -907,3 +907,16 @@ Tree.icon.openColor = @icon
|
|||||||
|
|
||||||
[style]ToolBarSeparator.inTextField = \
|
[style]ToolBarSeparator.inTextField = \
|
||||||
separatorWidth: 3
|
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
|
||||||
|
|||||||
@@ -823,7 +823,8 @@ public class TestFlatStyleableInfo
|
|||||||
"focusedBackground", Color.class,
|
"focusedBackground", Color.class,
|
||||||
"iconTextGap", int.class,
|
"iconTextGap", int.class,
|
||||||
"leadingIcon", Icon.class,
|
"leadingIcon", Icon.class,
|
||||||
"trailingIcon", Icon.class
|
"trailingIcon", Icon.class,
|
||||||
|
"showClearButton", boolean.class
|
||||||
);
|
);
|
||||||
|
|
||||||
// border
|
// border
|
||||||
|
|||||||
@@ -1011,6 +1011,8 @@ public class TestFlatStyling
|
|||||||
ui.applyStyle( "leadingIcon: com.formdev.flatlaf.icons.FlatSearchIcon" );
|
ui.applyStyle( "leadingIcon: com.formdev.flatlaf.icons.FlatSearchIcon" );
|
||||||
ui.applyStyle( "trailingIcon: com.formdev.flatlaf.icons.FlatClearIcon" );
|
ui.applyStyle( "trailingIcon: com.formdev.flatlaf.icons.FlatClearIcon" );
|
||||||
|
|
||||||
|
ui.applyStyle( "showClearButton: true" );
|
||||||
|
|
||||||
// border
|
// border
|
||||||
flatTextBorder( style -> ui.applyStyle( style ) );
|
flatTextBorder( style -> ui.applyStyle( style ) );
|
||||||
|
|
||||||
|
|||||||
@@ -73,6 +73,10 @@ class BasicComponentsPanel
|
|||||||
searchToolbar.addSeparator();
|
searchToolbar.addSeparator();
|
||||||
searchToolbar.add( regexButton );
|
searchToolbar.add( regexButton );
|
||||||
compsTextField.putClientProperty( FlatClientProperties.TEXT_FIELD_TRAILING_COMPONENT, searchToolbar );
|
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() {
|
private void initComponents() {
|
||||||
@@ -173,6 +177,7 @@ class BasicComponentsPanel
|
|||||||
JTextField iconsTextField = new JTextField();
|
JTextField iconsTextField = new JTextField();
|
||||||
JLabel compsLabel = new JLabel();
|
JLabel compsLabel = new JLabel();
|
||||||
compsTextField = new JTextField();
|
compsTextField = new JTextField();
|
||||||
|
clearTextField = new JTextField();
|
||||||
JLabel fontsLabel = new JLabel();
|
JLabel fontsLabel = new JLabel();
|
||||||
JLabel h00Label = new JLabel();
|
JLabel h00Label = new JLabel();
|
||||||
JLabel h0Label = new JLabel();
|
JLabel h0Label = new JLabel();
|
||||||
@@ -734,6 +739,10 @@ class BasicComponentsPanel
|
|||||||
add(compsLabel, "cell 0 15");
|
add(compsLabel, "cell 0 15");
|
||||||
add(compsTextField, "cell 1 15 2 1,growx");
|
add(compsTextField, "cell 1 15 2 1,growx");
|
||||||
|
|
||||||
|
//---- clearTextField ----
|
||||||
|
clearTextField.setText("clear me");
|
||||||
|
add(clearTextField, "cell 3 15,growx");
|
||||||
|
|
||||||
//---- fontsLabel ----
|
//---- fontsLabel ----
|
||||||
fontsLabel.setText("Typography / Fonts:");
|
fontsLabel.setText("Typography / Fonts:");
|
||||||
add(fontsLabel, "cell 0 16");
|
add(fontsLabel, "cell 0 16");
|
||||||
@@ -905,5 +914,6 @@ class BasicComponentsPanel
|
|||||||
|
|
||||||
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
|
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
|
||||||
private JTextField compsTextField;
|
private JTextField compsTextField;
|
||||||
|
private JTextField clearTextField;
|
||||||
// JFormDesigner - End of variables declaration //GEN-END:variables
|
// JFormDesigner - End of variables declaration //GEN-END:variables
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -685,6 +685,15 @@ new FormModel {
|
|||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
"value": "cell 1 15 2 1,growx"
|
"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" ) {
|
add( new FormComponent( "javax.swing.JLabel" ) {
|
||||||
name: "fontsLabel"
|
name: "fontsLabel"
|
||||||
"text": "Typography / Fonts:"
|
"text": "Typography / Fonts:"
|
||||||
|
|||||||
@@ -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.
|
* Returns whether all text is selected when the text component gains focus.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -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.
|
* Returns whether all text is selected when the text component gains focus.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -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
|
// NOTE: enum names must be equal to allowed strings
|
||||||
public enum SelectAllOnFocusPolicy { never, once, always };
|
public enum SelectAllOnFocusPolicy { never, once, always };
|
||||||
|
|
||||||
|
|||||||
@@ -1421,6 +1421,7 @@ ViewportUI com.formdev.flatlaf.ui.FlatViewportUI
|
|||||||
|
|
||||||
#---- [style]Button ----
|
#---- [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)
|
[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)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1426,6 +1426,7 @@ ViewportUI com.formdev.flatlaf.ui.FlatViewportUI
|
|||||||
|
|
||||||
#---- [style]Button ----
|
#---- [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)
|
[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)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1439,6 +1439,7 @@ ViewportUI com.formdev.flatlaf.ui.FlatViewportUI
|
|||||||
|
|
||||||
#---- [style]Button ----
|
#---- [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
|
[style]Button.inTextField focusable: false; toolbar.margin: 1,1,1,1; toolbar.spacingInsets: 1,1,1,1
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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 ) {
|
private void putTextFieldClientProperty( String key, Object value ) {
|
||||||
for( Component c : getComponents() ) {
|
for( Component c : getComponents() ) {
|
||||||
if( c instanceof JTextField )
|
if( c instanceof JTextField )
|
||||||
@@ -168,6 +173,7 @@ public class FlatTextComponentsTest
|
|||||||
trailingComponentCheckBox = new JCheckBox();
|
trailingComponentCheckBox = new JCheckBox();
|
||||||
leadingComponentVisibleCheckBox = new JCheckBox();
|
leadingComponentVisibleCheckBox = new JCheckBox();
|
||||||
trailingComponentVisibleCheckBox = new JCheckBox();
|
trailingComponentVisibleCheckBox = new JCheckBox();
|
||||||
|
showClearButtonCheckBox = new JCheckBox();
|
||||||
JLabel passwordFieldLabel = new JLabel();
|
JLabel passwordFieldLabel = new JLabel();
|
||||||
JPasswordField passwordField1 = new JPasswordField();
|
JPasswordField passwordField1 = new JPasswordField();
|
||||||
JPasswordField passwordField3 = new JPasswordField();
|
JPasswordField passwordField3 = new JPasswordField();
|
||||||
@@ -319,6 +325,7 @@ public class FlatTextComponentsTest
|
|||||||
"[]0" +
|
"[]0" +
|
||||||
"[]" +
|
"[]" +
|
||||||
"[]0" +
|
"[]0" +
|
||||||
|
"[]" +
|
||||||
"[]"));
|
"[]"));
|
||||||
|
|
||||||
//---- button1 ----
|
//---- button1 ----
|
||||||
@@ -404,6 +411,12 @@ public class FlatTextComponentsTest
|
|||||||
trailingComponentVisibleCheckBox.setName("trailingComponentVisibleCheckBox");
|
trailingComponentVisibleCheckBox.setName("trailingComponentVisibleCheckBox");
|
||||||
trailingComponentVisibleCheckBox.addActionListener(e -> trailingComponentVisible());
|
trailingComponentVisibleCheckBox.addActionListener(e -> trailingComponentVisible());
|
||||||
panel1.add(trailingComponentVisibleCheckBox, "cell 0 10 2 1,alignx left,growx 0");
|
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");
|
add(panel1, "cell 4 0 1 10,aligny top,growy 0");
|
||||||
|
|
||||||
@@ -719,6 +732,7 @@ public class FlatTextComponentsTest
|
|||||||
private JCheckBox trailingComponentCheckBox;
|
private JCheckBox trailingComponentCheckBox;
|
||||||
private JCheckBox leadingComponentVisibleCheckBox;
|
private JCheckBox leadingComponentVisibleCheckBox;
|
||||||
private JCheckBox trailingComponentVisibleCheckBox;
|
private JCheckBox trailingComponentVisibleCheckBox;
|
||||||
|
private JCheckBox showClearButtonCheckBox;
|
||||||
private JTextField textField;
|
private JTextField textField;
|
||||||
private JCheckBox dragEnabledCheckBox;
|
private JCheckBox dragEnabledCheckBox;
|
||||||
private JTextArea textArea;
|
private JTextArea textArea;
|
||||||
|
|||||||
@@ -77,7 +77,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": "[][][][][][]0[][]0[][]0[]"
|
"$rowConstraints": "[][][][][][]0[][]0[][]0[][]"
|
||||||
} ) {
|
} ) {
|
||||||
name: "panel1"
|
name: "panel1"
|
||||||
"border": new javax.swing.border.TitledBorder( "Control" )
|
"border": new javax.swing.border.TitledBorder( "Control" )
|
||||||
@@ -210,6 +210,16 @@ new FormModel {
|
|||||||
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
"value": "cell 0 10 2 1,alignx left,growx 0"
|
"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 ) {
|
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
|
||||||
"value": "cell 4 0 1 10,aligny top,growy 0"
|
"value": "cell 4 0 1 10,aligny top,growy 0"
|
||||||
} )
|
} )
|
||||||
|
|||||||
@@ -1115,6 +1115,7 @@ ViewportUI
|
|||||||
[style].monospaced
|
[style].monospaced
|
||||||
[style].semibold
|
[style].semibold
|
||||||
[style].small
|
[style].small
|
||||||
|
[style]Button.clearButton
|
||||||
[style]Button.inTextField
|
[style]Button.inTextField
|
||||||
[style]ToggleButton.inTextField
|
[style]ToggleButton.inTextField
|
||||||
[style]ToolBar.inTextField
|
[style]ToolBar.inTextField
|
||||||
|
|||||||
Reference in New Issue
Block a user