PasswordField: reveal button is now hidden (and turned off) if password field is disabled (issue #501)

This commit is contained in:
Karl Tauber
2022-09-11 17:05:48 +02:00
parent cbd80252ed
commit 596ff3382d
4 changed files with 107 additions and 38 deletions

View File

@@ -10,6 +10,8 @@ FlatLaf Change Log
This gives FlatLaf windows a more "native" feeling. (issue #482)
- MenuBar: Support different menu selection style UI defaults for `MenuBar` and
`MenuItem`. (issue #587)
- PasswordField: Reveal button is now hidden (and turned off) if password field
is disabled. (issue #501)
- TabbedPane: New option to disable tab run rotation in wrap layout. Set UI
value `TabbedPane.rotateTabRuns` to `false`. (issue #574)
- Native window decorations (Windows 10/11 only): Added client property to mark

View File

@@ -23,6 +23,7 @@ import java.awt.Toolkit;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.beans.PropertyChangeEvent;
import java.util.Map;
import javax.swing.Action;
import javax.swing.ActionMap;
@@ -291,6 +292,7 @@ public class FlatPasswordFieldUI
protected void installRevealButton() {
if( showRevealButton ) {
revealButton = createRevealButton();
updateRevealButton();
installLayout();
getComponent().add( revealButton );
}
@@ -298,28 +300,64 @@ public class FlatPasswordFieldUI
/** @since 2 */
protected JToggleButton createRevealButton() {
JToggleButton button = new JToggleButton( revealIcon );
JPasswordField c = (JPasswordField) getComponent();
JToggleButton button = new JToggleButton( revealIcon, !c.echoCharIsSet() );
button.setName( "PasswordField.revealButton" );
prepareLeadingOrTrailingComponent( button );
button.putClientProperty( FlatClientProperties.STYLE_CLASS, "inTextField revealButton" );
if( FlatClientProperties.clientPropertyBoolean( getComponent(), KEY_REVEAL_SELECTED, false ) ) {
if( FlatClientProperties.clientPropertyBoolean( c, KEY_REVEAL_SELECTED, false ) ) {
button.setSelected( true );
updateEchoChar( true );
}
button.addActionListener( e -> {
boolean selected = button.isSelected();
updateEchoChar( selected );
getComponent().putClientProperty( KEY_REVEAL_SELECTED, selected );
c.putClientProperty( KEY_REVEAL_SELECTED, selected );
} );
return button;
}
/** @since 2.5 */
protected void updateRevealButton() {
if( revealButton == null )
return;
JTextComponent c = getComponent();
boolean visible = c.isEnabled();
if( visible != revealButton.isVisible() ) {
revealButton.setVisible( visible );
c.revalidate();
c.repaint();
if( !visible ) {
revealButton.setSelected( false );
updateEchoChar( false );
getComponent().putClientProperty( KEY_REVEAL_SELECTED, null );
}
}
}
@Override
protected void propertyChange( PropertyChangeEvent e ) {
super.propertyChange( e );
switch( e.getPropertyName() ) {
case "enabled":
updateRevealButton();
break;
}
}
private void updateEchoChar( boolean selected ) {
char newEchoChar = selected
? 0
: (echoChar != null ? echoChar : '*');
JPasswordField c = (JPasswordField) getComponent();
if( newEchoChar == c.getEchoChar() )
return;
// set echo char
LookAndFeel.installProperty( c, "echoChar", newEchoChar );
// check whether was able to set echo char via LookAndFeel.installProperty()

View File

@@ -25,6 +25,7 @@ import java.util.function.Supplier;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.text.DefaultEditorKit;
import javax.swing.text.JTextComponent;
import com.formdev.flatlaf.FlatClientProperties;
import com.formdev.flatlaf.util.UIScale;
import net.miginfocom.swing.*;
@@ -46,6 +47,14 @@ public class FlatTextComponentsTest
initComponents();
}
private void editableChanged() {
boolean editable = editableCheckBox.isSelected();
for( Component c : getComponents() ) {
if( c instanceof JTextComponent )
((JTextComponent)c).setEditable( editable );
}
}
private void changeText() {
textField1.setText( "new text" );
}
@@ -166,6 +175,7 @@ public class FlatTextComponentsTest
JFormattedTextField formattedTextField1 = new JFormattedTextField();
JFormattedTextField formattedTextField3 = new JFormattedTextField();
JPanel panel1 = new JPanel();
editableCheckBox = new JCheckBox();
JButton button1 = new JButton();
JLabel leftPaddingLabel = new JLabel();
leftPaddingField = new JSpinner();
@@ -321,6 +331,7 @@ public class FlatTextComponentsTest
"[]" +
"[]" +
"[]" +
"[]" +
"[]0" +
"[]" +
"[]0" +
@@ -330,84 +341,90 @@ public class FlatTextComponentsTest
"[]" +
"[]"));
//---- editableCheckBox ----
editableCheckBox.setText("editable");
editableCheckBox.setSelected(true);
editableCheckBox.addActionListener(e -> editableChanged());
panel1.add(editableCheckBox, "cell 0 0 2 1,alignx left,growx 0");
//---- button1 ----
button1.setText("change text");
button1.addActionListener(e -> changeText());
panel1.add(button1, "cell 0 0 2 1,alignx left,growx 0");
panel1.add(button1, "cell 0 1 2 1,alignx left,growx 0");
//---- leftPaddingLabel ----
leftPaddingLabel.setText("Left padding:");
panel1.add(leftPaddingLabel, "cell 0 1");
panel1.add(leftPaddingLabel, "cell 0 2");
//---- leftPaddingField ----
leftPaddingField.addChangeListener(e -> paddingChanged());
panel1.add(leftPaddingField, "cell 1 1");
panel1.add(leftPaddingField, "cell 1 2");
//---- rightPaddingLabel ----
rightPaddingLabel.setText("Right padding:");
panel1.add(rightPaddingLabel, "cell 0 2");
panel1.add(rightPaddingLabel, "cell 0 3");
//---- rightPaddingField ----
rightPaddingField.addChangeListener(e -> paddingChanged());
panel1.add(rightPaddingField, "cell 1 2");
panel1.add(rightPaddingField, "cell 1 3");
//---- topPaddingLabel ----
topPaddingLabel.setText("Top padding:");
panel1.add(topPaddingLabel, "cell 0 3");
panel1.add(topPaddingLabel, "cell 0 4");
//---- topPaddingField ----
topPaddingField.addChangeListener(e -> paddingChanged());
panel1.add(topPaddingField, "cell 1 3");
panel1.add(topPaddingField, "cell 1 4");
//---- bottomPaddingLabel ----
bottomPaddingLabel.setText("Bottom padding:");
panel1.add(bottomPaddingLabel, "cell 0 4");
panel1.add(bottomPaddingLabel, "cell 0 5");
//---- bottomPaddingField ----
bottomPaddingField.addChangeListener(e -> paddingChanged());
panel1.add(bottomPaddingField, "cell 1 4");
panel1.add(bottomPaddingField, "cell 1 5");
//---- leadingIconCheckBox ----
leadingIconCheckBox.setText("leading icon");
leadingIconCheckBox.addActionListener(e -> leadingIcon());
panel1.add(leadingIconCheckBox, "cell 0 5 2 1,alignx left,growx 0");
panel1.add(leadingIconCheckBox, "cell 0 6 2 1,alignx left,growx 0");
//---- trailingIconCheckBox ----
trailingIconCheckBox.setText("trailing icon");
trailingIconCheckBox.addActionListener(e -> trailingIcon());
panel1.add(trailingIconCheckBox, "cell 0 6 2 1,alignx left,growx 0");
panel1.add(trailingIconCheckBox, "cell 0 7 2 1,alignx left,growx 0");
//---- leadingComponentCheckBox ----
leadingComponentCheckBox.setText("leading component");
leadingComponentCheckBox.addActionListener(e -> leadingComponent());
panel1.add(leadingComponentCheckBox, "cell 0 7 2 1,alignx left,growx 0");
panel1.add(leadingComponentCheckBox, "cell 0 8 2 1,alignx left,growx 0");
//---- trailingComponentCheckBox ----
trailingComponentCheckBox.setText("trailing component");
trailingComponentCheckBox.addActionListener(e -> trailingComponent());
panel1.add(trailingComponentCheckBox, "cell 0 8 2 1,alignx left,growx 0");
panel1.add(trailingComponentCheckBox, "cell 0 9 2 1,alignx left,growx 0");
//---- leadingComponentVisibleCheckBox ----
leadingComponentVisibleCheckBox.setText("leading component visible");
leadingComponentVisibleCheckBox.setSelected(true);
leadingComponentVisibleCheckBox.addActionListener(e -> leadingComponentVisible());
panel1.add(leadingComponentVisibleCheckBox, "cell 0 9 2 1,alignx left,growx 0");
panel1.add(leadingComponentVisibleCheckBox, "cell 0 10 2 1,alignx left,growx 0");
//---- trailingComponentVisibleCheckBox ----
trailingComponentVisibleCheckBox.setText("trailing component visible");
trailingComponentVisibleCheckBox.setSelected(true);
trailingComponentVisibleCheckBox.addActionListener(e -> trailingComponentVisible());
panel1.add(trailingComponentVisibleCheckBox, "cell 0 10 2 1,alignx left,growx 0");
panel1.add(trailingComponentVisibleCheckBox, "cell 0 11 2 1,alignx left,growx 0");
//---- showClearButtonCheckBox ----
showClearButtonCheckBox.setText("clear button");
showClearButtonCheckBox.addActionListener(e -> showClearButton());
panel1.add(showClearButtonCheckBox, "cell 0 11 2 1,alignx left,growx 0");
panel1.add(showClearButtonCheckBox, "cell 0 12 2 1,alignx left,growx 0");
//---- showRevealButtonCheckBox ----
showRevealButtonCheckBox.setText("password reveal button");
showRevealButtonCheckBox.addActionListener(e -> showRevealButton());
panel1.add(showRevealButtonCheckBox, "cell 0 12 2 1,alignx left,growx 0");
panel1.add(showRevealButtonCheckBox, "cell 0 13 2 1,alignx left,growx 0");
}
add(panel1, "cell 4 0 1 10,aligny top,growy 0");
@@ -660,6 +677,7 @@ public class FlatTextComponentsTest
// JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables
private JTextField textField1;
private JCheckBox editableCheckBox;
private JSpinner leftPaddingField;
private JSpinner rightPaddingField;
private JSpinner topPaddingField;

View File

@@ -76,23 +76,34 @@ 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" )
"$client.FlatLaf.internal.testing.ignore": true
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "editableCheckBox"
"text": "editable"
"selected": true
auxiliary() {
"JavaCodeGenerator.variableLocal": false
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "editableChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 0 2 1,alignx left,growx 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 0 0 2 1,alignx left,growx 0"
"value": "cell 0 1 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"
"value": "cell 0 2"
} )
add( new FormComponent( "javax.swing.JSpinner" ) {
name: "leftPaddingField"
@@ -101,13 +112,13 @@ new FormModel {
}
addEvent( new FormEvent( "javax.swing.event.ChangeListener", "stateChanged", "paddingChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 1"
"value": "cell 1 2"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "rightPaddingLabel"
"text": "Right padding:"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 2"
"value": "cell 0 3"
} )
add( new FormComponent( "javax.swing.JSpinner" ) {
name: "rightPaddingField"
@@ -116,13 +127,13 @@ new FormModel {
}
addEvent( new FormEvent( "javax.swing.event.ChangeListener", "stateChanged", "paddingChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 2"
"value": "cell 1 3"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "topPaddingLabel"
"text": "Top padding:"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 3"
"value": "cell 0 4"
} )
add( new FormComponent( "javax.swing.JSpinner" ) {
name: "topPaddingField"
@@ -131,13 +142,13 @@ new FormModel {
}
addEvent( new FormEvent( "javax.swing.event.ChangeListener", "stateChanged", "paddingChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 3"
"value": "cell 1 4"
} )
add( new FormComponent( "javax.swing.JLabel" ) {
name: "bottomPaddingLabel"
"text": "Bottom padding:"
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 4"
"value": "cell 0 5"
} )
add( new FormComponent( "javax.swing.JSpinner" ) {
name: "bottomPaddingField"
@@ -146,7 +157,7 @@ new FormModel {
}
addEvent( new FormEvent( "javax.swing.event.ChangeListener", "stateChanged", "paddingChanged", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 1 4"
"value": "cell 1 5"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "leadingIconCheckBox"
@@ -156,7 +167,7 @@ new FormModel {
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "leadingIcon", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 5 2 1,alignx left,growx 0"
"value": "cell 0 6 2 1,alignx left,growx 0"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "trailingIconCheckBox"
@@ -166,7 +177,7 @@ new FormModel {
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "trailingIcon", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 6 2 1,alignx left,growx 0"
"value": "cell 0 7 2 1,alignx left,growx 0"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "leadingComponentCheckBox"
@@ -176,7 +187,7 @@ new FormModel {
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "leadingComponent", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 7 2 1,alignx left,growx 0"
"value": "cell 0 8 2 1,alignx left,growx 0"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "trailingComponentCheckBox"
@@ -186,7 +197,7 @@ new FormModel {
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "trailingComponent", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 8 2 1,alignx left,growx 0"
"value": "cell 0 9 2 1,alignx left,growx 0"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "leadingComponentVisibleCheckBox"
@@ -197,7 +208,7 @@ new FormModel {
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "leadingComponentVisible", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 9 2 1,alignx left,growx 0"
"value": "cell 0 10 2 1,alignx left,growx 0"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "trailingComponentVisibleCheckBox"
@@ -208,7 +219,7 @@ new FormModel {
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "trailingComponentVisible", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 10 2 1,alignx left,growx 0"
"value": "cell 0 11 2 1,alignx left,growx 0"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "showClearButtonCheckBox"
@@ -218,7 +229,7 @@ new FormModel {
}
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"
"value": "cell 0 12 2 1,alignx left,growx 0"
} )
add( new FormComponent( "javax.swing.JCheckBox" ) {
name: "showRevealButtonCheckBox"
@@ -228,7 +239,7 @@ new FormModel {
}
addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "showRevealButton", false ) )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 0 12 2 1,alignx left,growx 0"
"value": "cell 0 13 2 1,alignx left,growx 0"
} )
}, new FormLayoutConstraints( class net.miginfocom.layout.CC ) {
"value": "cell 4 0 1 10,aligny top,growy 0"