KeyPressed 字母验证和 KeyEvent 组合输入限制不起作用

问题描述

我需要输入一个名字,文本字段应该接受字母,直到 100 个字符,所以我使用了 Keypressed 并设置了字母验证以及输入的字符数限制,但是当我运行它时,我也可以输入数字和它没有输入字符数限制。

另外,我也有一个地址字段,它不需要验证,因为它可以接受字母和数字,但也有 100 个字符的输入字符数限制。我也将 Keypressed 用于这个,但我用 KeyTyped 尝试过,但效果不佳。我运行了这个程序,我可以输入任何字符,但它没有输入字符数限制。

这是我的名称代码

// ==UserScript==
// @name         New Userscript
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       You
// @match        https://stackoverflow.com/*
// @require      http://code.jquery.com/jquery-3.4.1.min.js 
// @grant        none
// ==/UserScript==

}

这是我的地址代码

private void jTextField1Keypressed(java.awt.event.KeyEvent evt) {                                       
String jj = jTextField1.getText();
int len = jj.length();
char ts = evt.getKeyChar();

if (Character.isLetter(ts) || Character.isWhitespace(ts) || Character.isISOControl(ts))
{
    jTextField1.setEditable(true);
}
else
{
    jTextField1.setEditable(false);
}

if (evt.getKeyChar()>='0' && evt.getKeyChar()<='9')
{
    if (len<100)
    {
        jTextField1.setEditable(true);
    }
    else
    {
        jTextField1.setEditable(false);
    }
}

解决方法

限制输入到字段中的字符数的最简单方法是限制字段的大小。

我创建这个 GUI 是为了向您展示如何将地址限制为 100 个字符。

Address GUI

我使用 JTextArea 作为地址,因为地址最多可以包含三行。通常,您会将 JTextArea 字符宽度设为 30。我将其设为 70,这样您就可以看到 LimitDocumentFilter 类的作用。

这是完整的可运行代码。

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.Toolkit;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DocumentFilter;
import javax.swing.text.PlainDocument;

public class AddressFieldLimit implements Runnable {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new AddressFieldLimit());
    }

    @Override
    public void run() {
        JFrame frame = new JFrame("Address Field Limit");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.add(createMainPanel(),BorderLayout.CENTER);

        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    private JPanel createMainPanel() {
        JPanel panel = new JPanel(new BorderLayout());
        panel.setBorder(BorderFactory.createEmptyBorder(5,5,5));

        JPanel innerPanel = new JPanel(new FlowLayout());

        JLabel label = new JLabel("Address:");
        innerPanel.add(label);

        JTextArea textArea = new JTextArea(3,70);
        LimitDocumentFilter limitfilter = new LimitDocumentFilter(100);
        ((PlainDocument) textArea.getDocument()).setDocumentFilter(limitfilter);
        innerPanel.add(textArea);

        panel.add(innerPanel,BorderLayout.CENTER);

        JButton button = new JButton("Submit");
        panel.add(button,BorderLayout.AFTER_LAST_LINE);

        return panel;
    }

    public class LimitDocumentFilter extends DocumentFilter {

        private int maxLength;

        public LimitDocumentFilter(int maxLength) {
            this.maxLength = maxLength;
        }

        @Override
        public void insertString(DocumentFilter.FilterBypass fb,int offset,String str,AttributeSet attr)
                throws BadLocationException {
            if ((fb.getDocument().getLength() + str.length()) <= this.maxLength)
                super.insertString(fb,offset,str,attr);
            else
                Toolkit.getDefaultToolkit().beep();
        }

        @Override
        public void replace(DocumentFilter.FilterBypass fb,int length,AttributeSet attrs)
                throws BadLocationException {
            if ((fb.getDocument().getLength() + str.length()) <= this.maxLength)
                super.replace(fb,length,attrs);
            else
                Toolkit.getDefaultToolkit().beep();
        }
        
    }

}