java - 将密码字符替换为 JPasswordField 中的点

标签 java swing character look-and-feel jpasswordfield

JPasswordField 的默认密码符号是一个点。

enter image description here

但这将被 Java Look and Feel 替换为星号。

enter image description here

有没有办法在加载外观后将此符号再次替换为点?

我已经知道在加载外观代码之前初始化或创建 JFrame 对象会执行此操作,因此请建议一些其他操作,例如 setEchoChar(char c)

最佳答案

enter image description here

import java.awt.*;
import javax.swing.*;
import javax.swing.plaf.basic.*;
import javax.swing.text.*;

public class PasswordCharacterTest {
  public JComponent makeUI() {
    //@see com/sun/java/swing/plaf/windows/WindowsLookAndFeel.java
    //"PasswordField.echoChar", new XPValue(new Character((char)0x25CF), new Character('*')),
    JPasswordField pf1 = new JPasswordField(24);
    pf1.setEchoChar('\u25CF');
    JPasswordField pf2 = new JPasswordField(24) {
      @Override public void updateUI() {
        super.updateUI();
        setUI(MyPasswordFieldUI.createUI(this));
      }
    };
    JPanel p = new JPanel();
    p.add(pf1);
    p.add(pf2);
    p.setBorder(BorderFactory.createEmptyBorder(20, 5, 10, 5));
    return p;
  }
  public static void main(String... args) {
    EventQueue.invokeLater(() -> {
      JFrame f = new JFrame();
      f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
      f.getContentPane().add(new PasswordCharacterTest().makeUI());
      f.setSize(320, 240);
      f.setResizable(false);
      f.setLocationRelativeTo(null);
      f.setVisible(true);
    });
  }
}

class MyPasswordFieldUI extends BasicPasswordFieldUI {
  public static MyPasswordFieldUI createUI(JPasswordField c) {
    //TEST: c.setEchoChar('W');
    c.setEchoChar('O');
    return new MyPasswordFieldUI();
  }
  @Override public View create(Element elem) {
    return new MyPasswordView(elem);
  }
  private static class MyPasswordView extends PasswordView {
    @Override protected int drawEchoCharacter(Graphics g, int x, int y, char c) {
      Graphics2D g2 = (Graphics2D) g.create();
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                          RenderingHints.VALUE_ANTIALIAS_ON);
      FontMetrics fm = g2.getFontMetrics();
      int r = fm.charWidth(c) - 2;
      g2.setPaint(Color.RED);
      g2.fillOval(x + 1, y + 3 - fm.getAscent(), r, r);
      g2.dispose();
      return x + fm.charWidth(c);
    }
    protected MyPasswordView(Element element) {
      super(element);
    }
  }
}

关于java - 将密码字符替换为 JPasswordField 中的点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40359824/

相关文章:

java - 使用 CMake 时如何在 Gradle 构建脚本中设置 NDK 路径?

c - 使用sscanf从c中的字符串中提取

java - 将多行文本追加到 JTextArea?

c++ - 检查字符串是否包含非字母数字字符

Vim 在腻子上显示奇怪的字符

java - 无法解析 Java 上 OAuth2 类的导入

java - Media Player播放每个声音文件两次

java - 如何从小程序连接到SQL数据库

java - Component.setBounds 调用 Component.repaint?

java - 使用 Sea Glass 外观自定义 JPanel