当前位置: 首页 > 面试题库 >

通过实现KeyBindings使用类型化的键

昝枫
2023-03-14
问题内容

能否请您帮我如何使用KeyBinding和一起Consume键入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所示。这将允许使用此处讨论的。DocumentFilter

附录:即使是更一般的情况,我也会使用DocumentFilter,如下所示。如键盘示例所示,我将使用按键绑定Action在组件之间共享。

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

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();
            }
        });
    }
}


 类似资料:
  • 问题内容: 我在某处看到了这种模式: 通过将新类型指定为泛型的实际类型来扩展泛型,此结构有点不寻常。有什么用?此模式有名称吗?有其他替代方式吗? 示例:https://code.google.com/p/selenium/wiki/LoadableComponent 跳到: 编辑:阅读响应后,似乎我需要改变编译器对类型检查的理解。在我的脑海中,我有这种模式的牛肉是,如果两个A需要相同,那么有没有办

  • 我正在使用Universal Java Matrix包,它的工作非常好,但是我不能让它在Gson中发挥出色--序列化似乎工作得很好,但这是更容易的部分,当然。 反序列化会产生一些问题,因为我正在尝试将JSON反序列化到一个类的实例中,这个类具有类型为DefaultDenseGenericMatrix2D的泛型私有成员,其中Square是我自己的类。DefaultDenseGenericMatrix

  • 问题内容: 我在Android应用程序(带有Gson库)中实现Json反序列化存在一些问题 我已经上了这样的课 反序列化的调用是: 问题是调用后的result.posts列表包含一个LinkedTreeMap对象数组(具有正确的值,因此问题是反序列化)而不是MyJson对象。当我使用MyObject而不是T时,一切运行正常并且MyObject是正确的。 那么,有什么方法可以在不创建自定义反序列化器

  • 问题内容: 我想制定一个具有以下目标的程序: 1)创建一个JButton 2)使用键绑定将按钮附加到一个键(“ A”键)3)单击“ A”时执行一些代码 这是我到目前为止的代码: 现在,在哪里添加我希望在按下按钮时执行的代码? 问题答案: 您需要添加一个动作监听器,专门用于actionPerformed。在构造函数内的某处声明此内容: 在此示例中,如果我们按F2,则等效于按下按钮。

  • 为便于开发,larva采用动态类型,于是首先遇到的一个问题就是,在转化为java的时候,如何处理动态类型带来的问题。乍一看,这个不是很复杂,已经有前车之鉴了,Cython就可以把python代码直接转化成C代码,我的做法和Cython有相似之处,但考虑效率问题,做了一点修改 (虽然第一版本并不实现class语法来自定义类,不过在论述这个问题的时候,假定有自定义类,因为主要矛盾就在自定义类的属性方面

  • 本文向大家介绍laravel通用化的CURD的实现,包括了laravel通用化的CURD的实现的使用技巧和注意事项,需要的朋友参考一下 说明 非常高效的处理laravel中curd的操作 安装 composer require shencongcong/laravel-curd ~1.0 laravel项目的 config/app.php 注册 ServiceProvider 使用 github地