Skip to content

Commit

Permalink
PasswordField: UI delegate FlatPasswordFieldUI now extends `FlatTex…
Browse files Browse the repository at this point in the history
…tFieldUI` (instead of `BasicPasswordFieldUI`) to avoid duplicate code and for easier extensibility (e.g. for #173 and #341)
  • Loading branch information
DevCharly committed Jul 2, 2021
1 parent 10bf129 commit c8998c2
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 64 deletions.
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
FlatLaf Change Log
==================

## 1.4-SNAPSHOT

#### New features and improvements

- PasswordField: UI delegate `FlatPasswordFieldUI` now extends `FlatTextFieldUI`
(instead of `BasicPasswordFieldUI`) to avoid duplicate code and for easier
extensibility.

#### Fixed bugs

- TBD


## 1.3

#### New features and improvements
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,6 @@
*
* <!-- FlatTextFieldUI -->
*
* @uiDefault TextComponent.arc int
* @uiDefault Component.focusWidth int
* @uiDefault Component.minimumWidth int
* @uiDefault Component.isIntelliJTheme boolean
* @uiDefault FormattedTextField.placeholderForeground Color
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,30 +16,30 @@

package com.formdev.flatlaf.ui;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.Toolkit;
import java.awt.event.FocusListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.beans.PropertyChangeEvent;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.LookAndFeel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicPasswordFieldUI;
import javax.swing.text.Caret;
import javax.swing.text.DefaultEditorKit;
import javax.swing.text.Element;
import javax.swing.text.JTextComponent;
import com.formdev.flatlaf.util.HiDPIUtils;
import javax.swing.text.PasswordView;
import javax.swing.text.View;

/**
* Provides the Flat LaF UI delegate for {@link javax.swing.JPasswordField}.
*
* <!-- BasicPasswordFieldUI -->
* <!-- BasicTextFieldUI -->
*
* @uiDefault PasswordField.font Font
* @uiDefault PasswordField.background Color
Expand All @@ -52,74 +52,66 @@
* @uiDefault PasswordField.inactiveForeground Color used if not enabled (yes, this is confusing; this should be named disabledForeground)
* @uiDefault PasswordField.border Border
* @uiDefault PasswordField.margin Insets
* @uiDefault PasswordField.echoChar character
* @uiDefault PasswordField.caretBlinkRate int default is 500 milliseconds
*
* <!-- FlatPasswordFieldUI -->
* <!-- FlatTextFieldUI -->
*
* @uiDefault Component.minimumWidth int
* @uiDefault Component.isIntelliJTheme boolean
* @uiDefault PasswordField.placeholderForeground Color
* @uiDefault PasswordField.focusedBackground Color optional
* @uiDefault PasswordField.showCapsLock boolean
* @uiDefault PasswordField.capsLockIcon Icon
* @uiDefault TextComponent.selectAllOnFocusPolicy String never, once (default) or always
* @uiDefault TextComponent.selectAllOnMouseClick boolean
*
* <!-- FlatPasswordFieldUI -->
*
* @uiDefault PasswordField.echoChar character
* @uiDefault PasswordField.showCapsLock boolean
* @uiDefault PasswordField.capsLockIcon Icon
*
* @author Karl Tauber
*/
public class FlatPasswordFieldUI
extends BasicPasswordFieldUI
extends FlatTextFieldUI
{
protected int minimumWidth;
protected boolean isIntelliJTheme;
protected Color placeholderForeground;
protected Color focusedBackground;
protected boolean showCapsLock;
protected Icon capsLockIcon;

private FocusListener focusListener;
private KeyListener capsLockListener;

public static ComponentUI createUI( JComponent c ) {
return new FlatPasswordFieldUI();
}

@Override
protected String getPropertyPrefix() {
return "PasswordField";
}

@Override
protected void installDefaults() {
super.installDefaults();

String prefix = getPropertyPrefix();
minimumWidth = UIManager.getInt( "Component.minimumWidth" );
isIntelliJTheme = UIManager.getBoolean( "Component.isIntelliJTheme" );
placeholderForeground = UIManager.getColor( prefix + ".placeholderForeground" );
focusedBackground = UIManager.getColor( prefix + ".focusedBackground" );
Character echoChar = (Character) UIManager.get( prefix + ".echoChar" );
if( echoChar != null )
LookAndFeel.installProperty( getComponent(), "echoChar", echoChar );

showCapsLock = UIManager.getBoolean( "PasswordField.showCapsLock" );
capsLockIcon = UIManager.getIcon( "PasswordField.capsLockIcon" );

LookAndFeel.installProperty( getComponent(), "opaque", false );

MigLayoutVisualPadding.install( getComponent() );
}

@Override
protected void uninstallDefaults() {
super.uninstallDefaults();

placeholderForeground = null;
focusedBackground = null;
capsLockIcon = null;

MigLayoutVisualPadding.uninstall( getComponent() );
}

@Override
protected void installListeners() {
super.installListeners();

// necessary to update focus border and background
focusListener = new FlatUIUtils.RepaintFocusListener( getComponent(), null );

// update caps lock indicator
capsLockListener = new KeyAdapter() {
@Override
Expand All @@ -136,39 +128,44 @@ private void repaint( KeyEvent e ) {
}
};

getComponent().addFocusListener( focusListener );
getComponent().addKeyListener( capsLockListener );
}

@Override
protected void uninstallListeners() {
super.uninstallListeners();

getComponent().removeFocusListener( focusListener );
getComponent().removeKeyListener( capsLockListener );
focusListener = null;
capsLockListener = null;
}

@Override
protected Caret createCaret() {
return new FlatCaret( UIManager.getString( "TextComponent.selectAllOnFocusPolicy" ),
UIManager.getBoolean( "TextComponent.selectAllOnMouseClick" ) );
protected void installKeyboardActions() {
super.installKeyboardActions();

// map "select-word" action (double-click) to "select-line" action
ActionMap map = SwingUtilities.getUIActionMap( getComponent() );
if( map != null && map.get( DefaultEditorKit.selectWordAction ) != null ) {
Action selectLineAction = map.get( DefaultEditorKit.selectLineAction );
if( selectLineAction != null )
map.put( DefaultEditorKit.selectWordAction, selectLineAction );
}
}

@Override
protected void propertyChange( PropertyChangeEvent e ) {
super.propertyChange( e );
FlatTextFieldUI.propertyChange( getComponent(), e );
public View create( Element elem ) {
return new PasswordView( elem );
}

@Override
protected void paintSafely( Graphics g ) {
FlatTextFieldUI.paintBackground( g, getComponent(), isIntelliJTheme, focusedBackground );
FlatTextFieldUI.paintPlaceholder( g, getComponent(), placeholderForeground );
paintCapsLock( g );
// safe and restore clipping area because super.paintSafely() modifies it
// and the caps lock icon would be truncated
Shape oldClip = g.getClip();
super.paintSafely( g );
g.setClip( oldClip );

super.paintSafely( HiDPIUtils.createGraphicsTextYCorrection( (Graphics2D) g ) );
paintCapsLock( g );
}

protected void paintCapsLock( Graphics g ) {
Expand All @@ -184,19 +181,4 @@ protected void paintCapsLock( Graphics g ) {
int x = c.getWidth() - capsLockIcon.getIconWidth() - y;
capsLockIcon.paintIcon( c, g, x, y );
}

@Override
protected void paintBackground( Graphics g ) {
// background is painted elsewhere
}

@Override
public Dimension getPreferredSize( JComponent c ) {
return FlatTextFieldUI.applyMinimumWidth( c, super.getPreferredSize( c ), minimumWidth );
}

@Override
public Dimension getMinimumSize( JComponent c ) {
return FlatTextFieldUI.applyMinimumWidth( c, super.getMinimumSize( c ), minimumWidth );
}
}

0 comments on commit c8998c2

Please sign in to comment.