Consume typed key by implements KeyBindings

前端 未结 1 694
臣服心动
臣服心动 2020-12-11 12:21

Can you please help me how to use KeyBinding and with Consume for typed Chars together, same way as demostraded my SSCCE

相关标签:
1条回答
  • 2020-12-11 12:55

    For security, consider JPasswordField, illustrated here. This would allow use of a DocumentFilter, discussed here.

    Addendum: Even for the more general case, I'd use a DocumentFilter, as shown below. I'd use key bindings for sharing an Action among components, as shown in this keypad example.

    Addendum: To illustrate @kleopatra's comment, I've updated the code to bind ESC to Reset. As a practical matter, I'd use only keys that aren't already bound to text field actions or required for normal use.

    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();
                }
            });
        }
    }
    
    0 讨论(0)
提交回复
热议问题