JTextField限制输入长度的完美解决方案(转)
关于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限制输入长度的完美解决方案(转)的更多相关文章
- 记一次js中和php中的字符串长度计算截取的终极问题和完美解决方案
1.js是用unicode算长度的,比如单字节的算1,中文也算1,但是正常我们想让两个单字节算1,如何计算这个长度 第一种解决方案,用正则,如下 /[\u0x00-\u0xff]/,天真的想着,这样就 ...
- DevExpress控件cxGrid实现多列模糊匹配输入的完美解决方案
本方案不需要修改控件源码,是完美解决cxgrid或TcxDBExtLookupComboBox支持多列模糊匹配快速输入的最佳方案!! 转自https://blog.csdn.net/qq5643020 ...
- iOS 限制TextField输入长度(标准)
iOS 限制TextField输入长度(标准) 网上有很多限制textField输入长度方法,但是我觉得都不是很完美,准确来说可以说是不符合实际开发的要求,因此在这里整理一下textField限制输入 ...
- Xcode6.1标准Framework静态库制作方法。工程转Framework,静态库加xib和图片。完美解决方案。
http://www.cocoachina.com/bbs/read.php?tid-282490.html Xcode6.1标准Framework静态库制作方法.工程转Framework,静态库加x ...
- iOS- UITextField限制输入长度
限制输入长度的问题,在这里完美的解决了! //先创建一个textField 和 一个button. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ...
- iOS之限制TextField的输入长度
网上有很多限制textField输入长度方法,但是我觉得都不是很完美,准确来说可以说是不符合实际开发的要求,因此在这里整理一下textField限制输入长度的方法.我所采用的并不是监听方法而是最不同的 ...
- html5点击input没有出现光标完美解决方案
html5点击input没有出现光标完美解决方案 <pre> <input type="text" placeholder="输入姓名" cl ...
- PyCharm 中文 字符 python 报错 的 完美 解决方案!
PyCharm 中文 字符 python 报错 的 完美 解决方案! #_*_ coding:utf-8_*_ https://www.python.org/dev/peps/pep-0263/ 到p ...
- Apache服务器网站访问伪静态内页出现No input file specified.的完美解决方案
原文地址:Apache服务器网站访问伪静态内页出现No input file specified.的完美解决方案 启用REWRITE的伪静态功能的时候,首页可以访问,而访问内页的时候,就提示:&quo ...
随机推荐
- 深入了解回调函数Java
打回来.我第一次看到Java编程思想,后来Observer模式也适用于一个回调函数的想法.但是,一直没有重视,在处于劣势的最终面试,越来越明白为什么那么多人说Java编程思想,这本书应该是一遍又一遍, ...
- 成都传智职工high翻竞赛场
日前,由石羊街道总工会.天府新谷园区党委联合主办的“2013年职工趣味竞赛”盛大开幕.传智播客成都java培训中心员工积极参与,活跃在各大项目的比赛中,员工们用笑脸.身影告诉大家:竞赛场上,我们hig ...
- SpringMVC单文件上传、多文件上传、文件列表显示、文件下载(转)
林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 本文详细讲解了SpringMVC实例单文件上传.多文件上传.文件列表显示.文件下载. 本文工程 ...
- JSP-简单的练习省略显示长字符串
<%@ page contentType="text/html; charset=gb2312" %> <!-- JSP指令标签 --> <%@ pa ...
- Android Widget 小部件(一) 简单实现
在屏幕上加入Widget:或长按屏幕空白处,或找到WidgetPreview App选择. 原生系统4.0下面使用长按方式,4.0及以上 打开WIDGETS 创建Widget的一般步骤: 在menif ...
- iOS 8 新特性
这篇文章会介绍iOS8开发相关的主要特性. App 插件 通过支持插件,iOS8让我们可以系统指定的区域进行扩展,也就是为用户的特定需求提供自定义的方法.例如:可以通过App插件帮助用户分享他们的内容 ...
- Sails.js中文文档
Sails.js中文文档 http://sailsdoc.swift.ren/ Sails.js是一个Web框架,可以于轻松构建自定义,企业级Node.js Apps.它在设计上类似于像Ruby ...
- (五岁以下儿童)NS3样本演示:桥模块演示样品csma-bridge.cc凝视程序
(五岁以下儿童)NS3:桥模块演示样品csma-bridge.cc凝视程序 1.Ns3 bridge模csma-bridge.cc演示示例程序的目光 // Network topology // // ...
- POJ3467(预处理)
Cross Counting Time Limit: 1000MS Memory Limit: 131072K Total Submissions: 1331 Accepted: 375 De ...
- hive的udf制剂
1.配置环境 1.介绍jar包裹:hive-exec-0.8.0.jar 和 hadoop-core-0.20.2.jar 2.书写udf性能 1.extends UDF 2.又一次定义UDF的eva ...