gpt4 book ai didi

java - 通过实现 KeyBindings 使用键入的 key

转载 作者:行者123 更新时间:2023-11-29 06:02:30 26 4
gpt4 key购买 nike

能否请您帮助我如何将 KeyBindingConsume 一起用于键入的 Chars ,与演示我的 SSCCE 的方式相同 通过使用 KeyListener

import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.*;

public class Login {

private static final long serialVersionUID = 1L;
/* PassWord for unlock*/
private PswChecker checker = new PswChecker("pass");

public Login() {
JTextField firstField = new JTextField(10);
firstField.addKeyListener(passwordKeyListener);
JLabel firstLabel = new JLabel("Password is 'pass' ", JLabel.RIGHT);
firstLabel.setLabelFor(firstField);
JPanel p = new JPanel();
p.setLayout(new GridLayout(0, 2, 5, 5));
p.add(firstLabel);
p.add(firstField);
JFrame f = new JFrame("login");
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setContentPane(p);
f.setLocationByPlatform(true);
f.pack();
f.setVisible(true);
}
//
private KeyListener passwordKeyListener = new KeyListener() {

private boolean enabled = true;

@Override
public void keyTyped(KeyEvent e) {
if (!enabled) {
return;
}
if (e.getKeyChar() != KeyEvent.CHAR_UNDEFINED) {
boolean b = checker.accept(e.getKeyChar());
e.consume();
if (b) {
enabled = false;
if (e.getComponent() != null) {
e.getComponent().removeKeyListener(this);
}
unlock();
}
}
}

@Override
public void keyReleased(KeyEvent e) {
}

@Override
public void keyPressed(KeyEvent e) {
}
};

void unlock() {
JOptionPane.showMessageDialog(null, "unlocked");
}

public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {

public void run() {
Login log = new Login();
}
});
}

class PswChecker {

private String password = null;
private boolean unlocked = false;
private long lastInputTimestamp = 0L;
private int index = 0;

public PswChecker(String password) {
if (password == null) {
throw new IllegalArgumentException("Null password");
}
if (password.trim().length() == 0) {
throw new IllegalArgumentException("Empty password");
}
this.password = password;
}

public boolean accept(char c) {
if (unlocked) {
return true;
}
long timestamp = System.currentTimeMillis();
if (timestamp - lastInputTimestamp > 700) {
index = 0;
}
lastInputTimestamp = timestamp;
if (password.charAt(index) == c) {
index++;
} else {
if (password.charAt(0) == c) {
index = 1;
} else {
index = 0;
}
}
unlocked = (index == password.length());
return unlocked;
}

public boolean isUnlocked() {
return unlocked;
}

public boolean isLocked() {
return !unlocked;
}

@Override
public String toString() {
return unlocked ? "UNLOCKED" : "LOCKED";
}

/*private boolean check(String keystrokes, String password, boolean expectUnLocked) {
PswChecker checker = new PswChecker(password);
for (int i = 0; i < keystrokes.length(); i++) {
checker.accept(keystrokes.charAt(i));
}
return checker.isUnlocked();
}*/
}
}

最佳答案

为了安全,考虑JPasswordField ,图文并茂here .这将允许使用 DocumentFilter , 讨论 here .

附录:即使对于更一般的情况,我也会使用 DocumentFilter , 如下所示。我会用 key bindings用于在组件之间共享 Action,如 keypad example 所示.

附录:为了说明@kleopatra 的评论,我更新了代码以将ESC 绑定(bind)到Reset。实际上,我只会使用尚未绑定(bind)到文本字段操作或正常使用所需的键。

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;
import javax.swing.text.*;

/** @see https://stackoverflow.com/q/9610386/230513 */
public class Login {

private static final String PWD = "pass";
private static final String RESET = "Reset";
private PlainDocument doc = new PlainDocument();
private JTextField text = new JTextField(doc, "", 10);

public Login() {
doc.setDocumentFilter(new FieldFilter(PWD));
JLabel label = new JLabel("Password is '" + PWD + "'", JLabel.RIGHT);
label.setLabelFor(text);
text.setToolTipText("Press ESC to reset.");
text.getInputMap().put(
KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), RESET);
text.getActionMap().put(RESET, new Reset());
JPanel p = new JPanel();
p.setLayout(new GridLayout(0, 2, 5, 5));
p.add(label);
p.add(text);
JFrame f = new JFrame("Login");
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setContentPane(p);
f.setLocationByPlatform(true);
f.pack();
f.setVisible(true);
}

private static class FieldFilter extends DocumentFilter {

private String password;
private boolean unlocked;
private StringBuilder sb = new StringBuilder();

public FieldFilter(String password) {
this.password = password;
}

@Override
public void replace(FilterBypass fb, int offset, int length,
String text, AttributeSet attrs) throws BadLocationException {
if (unlocked) {
super.replace(fb, offset, length, text, attrs);
} else {
sb.append(text);
unlocked = password.equals(sb.toString());
}
}

public void reset() {
sb.delete(0, sb.length());
unlocked = false;
}
}

private static class Reset extends AbstractAction {

@Override
public void actionPerformed(ActionEvent e) {
JTextField jtf = (JTextField) e.getSource();
PlainDocument doc = (PlainDocument) jtf.getDocument();
try {
doc.remove(0, doc.getLength());
} catch (BadLocationException ex) {
ex.printStackTrace(System.err);
}
FieldFilter filter = (FieldFilter) doc.getDocumentFilter();
filter.reset();
}
}

public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {

@Override
public void run() {
Login log = new Login();
}
});
}
}

关于java - 通过实现 KeyBindings 使用键入的 key ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9610386/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com