关于JTextField限制输入字符长度的问题,因为没提供现成的api,所以我们得自己动手,来实现这个功能,网上也有很多这样的资料,大多是在JTextField的Document的insertString方法中动手脚,比较当前文本框的字符长度和最大长度,如果输入不涉及中文,该方法也堪称完美了。     细心的童鞋可能会发现,在swing里输入中文,有的是下方弹出一个小方框,显示当前输入的字母;有的是直接将这些字母显示在了文本输入框里,打完一个字词时,将这些字母清除掉,再将中文显示上去。这两种不同的显示方式取决于System.getProperty("java.awt.im.style")的值是不是"below-the-spot",如果是,输入框下方就显示一个小窗口(如果为null好像也是这样),这种情况下,上面的解决办法也没有问题;如果不是,即字母显示在文本输入框中,那么在输入字符接近或达到最大长度时,会出现吃掉前面的字符的情况。    
此问题的原因在于,在输入中文时,将键入的字母(暂且称之为“临时字母”吧)打印在了输入框内,假如是j,按第二个字母时(假如是i),会把之前的临时字母(j)删除,再用insertString插入ji,再输入n时,把ji删除,再插入jin,JTextField的公共方法是无法区分临时字母的,如果插入ji时达到了长度上限,插入失败,再输入n,删除ji,此时ji并未插入,所以就删除了左边的字符,此时就出现了吃掉左边字符的问题。

接下来说解决办法: 重写Document里的方法

public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
if (a == null) {
int allowCount = maxLength - getLength();
if (allowCount > 0) {
if (allowCount < str.length())
str = str.substring(0, allowCount);
} else
return;
}
super.insertString(offs, str, a);
}

经调试跟踪,插入临时字母时AttributeSet a都不是null,而输入英文或中文上屏时,a都为空,所以临时字母能够正常插入,删除时,就不会拿正常输入的字符当替死鬼了。 到此,问题已经基本解决了,只是到了长度上限,还能敲入临时字母,虽然切换输出法、失去焦点啥的,临时字母会自动被删除(所以说基本没什么问题了,除非你不是根据鼠标键盘操作去getText,要不getText是不会获取到临时字母的),但如果有点完美主义的话,心里还是有点不舒服,为啥就不能让它在达到最大长度时,连临时字母也不能输入了?     因为临时字母的删除再插入,在insertString、remove等处已经发生了,又不方便跟正常删除插入进行区分,所以往上找,找到了输入法事件处理的代码,在此处就能比较根本地解决问题了

private int composedLen;
@Override
protected void processInputMethodEvent(InputMethodEvent e) {
if (e.getID() == InputMethodEvent.INPUT_METHOD_TEXT_CHANGED) {
if (e.getCommittedCharacterCount() == 0) {
AttributedCharacterIterator aci = e.getText();
if (getDocument().getLength() - composedLen >= maxLength) {
e.consume();
composedLen = 0;
} else
composedLen = aci != null ? aci.getEndIndex()
- aci.getBeginIndex() : 0;
} else
composedLen = 0;
}
super.processInputMethodEvent(e);
}

在JTextField里重写processInputMethodEvent方法,并定义一个composedLen变量,用来记录文本中的临时字母的长度,文本长度减去临时字母的长度,就得到了真正输入的字符的长度了,如果这个长度大于等于上限,就消耗掉这个事件(e.consume()),让它失效。介绍下里面的方法,e.getCommittedCharacterCount()得到的是提交的字符数,也就是中文上屏时,中文的字符个数,aci.getEndIndex() - aci.getBeginIndex()得到的是文本的长度,可能是上屏的中文,也可能是临时字母。

如果你对我用insertString里的AttributeSet a是否为null作为判断依据有所质疑的话(JDK升级后,这规则还有效吗?),也可以把composedLen传到insertString里,作为判断依据。

OK,大功告成了,虽然没写多少内容,但找出问题和解决问题的过程,还是花了我一些时间的,有点啰嗦,就不写了

http://www.cnblogs.com/trytocatch/archive/2012/11/30/jtextfield_maxlength.html

JTextField限制输入长度的完美解决方案(转)的更多相关文章

  1. 记一次js中和php中的字符串长度计算截取的终极问题和完美解决方案

    1.js是用unicode算长度的,比如单字节的算1,中文也算1,但是正常我们想让两个单字节算1,如何计算这个长度 第一种解决方案,用正则,如下 /[\u0x00-\u0xff]/,天真的想着,这样就 ...

  2. DevExpress控件cxGrid实现多列模糊匹配输入的完美解决方案

    本方案不需要修改控件源码,是完美解决cxgrid或TcxDBExtLookupComboBox支持多列模糊匹配快速输入的最佳方案!! 转自https://blog.csdn.net/qq5643020 ...

  3. iOS 限制TextField输入长度(标准)

    iOS 限制TextField输入长度(标准) 网上有很多限制textField输入长度方法,但是我觉得都不是很完美,准确来说可以说是不符合实际开发的要求,因此在这里整理一下textField限制输入 ...

  4. Xcode6.1标准Framework静态库制作方法。工程转Framework,静态库加xib和图片。完美解决方案。

    http://www.cocoachina.com/bbs/read.php?tid-282490.html Xcode6.1标准Framework静态库制作方法.工程转Framework,静态库加x ...

  5. iOS- UITextField限制输入长度

    限制输入长度的问题,在这里完美的解决了! //先创建一个textField 和 一个button. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ...

  6. iOS之限制TextField的输入长度

    网上有很多限制textField输入长度方法,但是我觉得都不是很完美,准确来说可以说是不符合实际开发的要求,因此在这里整理一下textField限制输入长度的方法.我所采用的并不是监听方法而是最不同的 ...

  7. html5点击input没有出现光标完美解决方案

    html5点击input没有出现光标完美解决方案 <pre> <input type="text" placeholder="输入姓名" cl ...

  8. PyCharm 中文 字符 python 报错 的 完美 解决方案!

    PyCharm 中文 字符 python 报错 的 完美 解决方案! #_*_ coding:utf-8_*_ https://www.python.org/dev/peps/pep-0263/ 到p ...

  9. Apache服务器网站访问伪静态内页出现No input file specified.的完美解决方案

    原文地址:Apache服务器网站访问伪静态内页出现No input file specified.的完美解决方案 启用REWRITE的伪静态功能的时候,首页可以访问,而访问内页的时候,就提示:&quo ...

随机推荐

  1. Android Google Map v2具体解释:开发环境配置

    Android Google Map v2具体解释:开发环境配置                                       --转载请注明出处:coder-pig 说在前面: 说到地 ...

  2. nyoj 47 江 河问题 【贪婪】

    经典的贪婪. 两种方案:一个:让我们来最快,第二快,在过去的第一,最快的回.然后最慢,最慢第二,在过去.次最快的回来a[0]+a[1]+a[1]+a[n-1] 二:最快的和最慢的过去,最快的回来,最快 ...

  3. udacity android 学习笔记: lesson 4 part b

    udacity android 学习笔记: lesson 4 part b 作者:干货店打杂的 /titer1 /Archimedes 出处:https://code.csdn.net/titer1 ...

  4. 【翻译自mos文章】回收 asm磁盘空间的方法

    回收 asm磁盘空间的方法 參考原文: How To Reclaim Asm Disk Space? (Doc ID 351866.1) 适用于: Oracle Database - Enterpri ...

  5. virtio-netdev 发送数据包

    在前面几文中已经大体介绍了virtio的重要组成,包含virtio net设备的创建,vring的创建,与virtio设备的交互方式.我们就从网络数据包的发送角度来看下virtio的详细使用流程. [ ...

  6. CKEditor上传插件

    CKEditor上传插件 前言 CKEditor上传插件是不是免费的,与您分享在此开发.这个插件是基于ASP.NET MVC下开发的,假设是webform的用户或者其他语言的用户.能够參考把serve ...

  7. LCA 学习算法 (最近的共同祖先)poj 1330

    Nearest Common Ancestors Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 20983   Accept ...

  8. Dictionary带来的一种隐式内存泄漏

    当心Dictionary带来的一种隐式内存泄漏 最近在看Dictionary的源代码的时候, 突然想到Dictionary的不当使用中有一种隐含内存泄漏的可能. 简化使用场景 小A正在写一个简单的图书 ...

  9. 水题 hdu1002------用BigInteger解决大数问题

    Problem Description I have a very simple problem for you. Given two integers A and B, your job is to ...

  10. android性能测试内存泄漏

    1.什么是内存泄漏?     适用于该系统的内存使用内存泄漏,未回复(释放),该内存可以没有事业,也不能被其他人使用使用自己. 2.出有什么差别?    内存泄漏是分配出去的内存无法回收.    内存 ...