如何解决JTextField输入过度灵敏导致光标跳框的问题
解决方案
问题根源
你当前使用keyPressed事件的时机不对:按键按下时,输入的字符还未写入JTextField,此时A_RUCE.getText()仍为空,会立刻触发焦点跳转。等字符实际写入时,焦点已经在第二个输入框,导致看起来像是跳过了一个框。
方法一:改用keyReleased事件(简单快速)
监听按键释放事件,此时字符已经写入输入框,判断文本长度为1时跳转焦点,同时可以统一处理字母大小写(符合MOD26运算的需求):
A_RUCE.addKeyListener(new KeyAdapter(){ @Override public void keyReleased(KeyEvent e){ String value = A_RUCE.getText(); // 输入一个字母后跳转 if(value.length() == 1){ // 统一转为大写(可根据需求改小写) A_RUCE.setText(value.toUpperCase()); B_RUCE.requestFocus(); // 如果是最后一个输入框,替换为第一个输入框即可,比如: // if(currentField == Z_RUCE) A_RUCE.requestFocus(); } } });
方法二:使用DocumentListener(更可靠)
直接监听输入框文本内容的变更,不受键盘事件时机影响,适合复杂场景:
// 给第一个输入框添加文本监听 A_RUCE.getDocument().addDocumentListener(new DocumentListener() { @Override public void insertUpdate(DocumentEvent e) { focusNextField(A_RUCE, B_RUCE); } @Override public void removeUpdate(DocumentEvent e) {} @Override public void changedUpdate(DocumentEvent e) {} }); // 通用跳转方法,可复用给所有输入框 private void focusNextField(JTextField currentField, JTextField nextField) { String text = currentField.getText(); // 只保留第一个字母并转大写 if(text.length() > 0){ text = text.substring(0, 1).toUpperCase(); currentField.setText(text); nextField.requestFocus(); // 最后一个输入框跳转回第一个: // if(nextField == null) A_RUCE.requestFocus(); } }
额外优化:限制输入内容(可选)
为了符合MOD26的需求,可以给输入框添加过滤器,只允许输入单个字母,避免无效输入:
import javax.swing.text.AttributeSet; import javax.swing.text.BadLocationException; import javax.swing.text.DocumentFilter; import javax.swing.text.AbstractDocument; // 创建字母过滤器 DocumentFilter singleLetterFilter = new DocumentFilter() { @Override public void insertString(FilterBypass fb, int offset, String string, AttributeSet attr) throws BadLocationException { // 限制只能输入1个字母,自动转大写 if(fb.getDocument().getLength() + string.length() <= 1 && string.matches("[a-zA-Z]")){ super.insertString(fb, offset, string.toUpperCase(), attr); } } @Override public void replace(FilterBypass fb, int offset, int length, String text, AttributeSet attrs) throws BadLocationException { if(fb.getDocument().getLength() - length + text.length() <= 1 && text.matches("[a-zA-Z]")){ super.replace(fb, offset, length, text.toUpperCase(), attrs); } } }; // 给所有输入框应用过滤器 ((AbstractDocument)A_RUCE.getDocument()).setDocumentFilter(singleLetterFilter); ((AbstractDocument)B_RUCE.getDocument()).setDocumentFilter(singleLetterFilter); // ...其他输入框同理
内容的提问来源于stack exchange,提问作者Thomas Farkas
相关产品推荐
相关产品推荐

