关于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. 【原创】poj ----- 1182 食物链 解题报告

    题目地址: http://poj.org/problem?id=1182 题目内容: 食物链 Time Limit: 1000MS   Memory Limit: 10000K Total Submi ...

  2. Windows8.1硬盘安装Ubuntu14.04双系统参考教程和多硬盘的注意事项[画画]

    硬盘安装.无需光盘.U盘:Win8.1为主,Ubuntu14.04为辅,可将Windows或Ubuntu设置为开机默认启动项.在Ubuntu下可查看.操作Windows系统下的文件:适用于安装和14. ...

  3. 小巧的UML工具-UMLet

    画简单的UML图时非常方便 比如我画blog中的流程图就是用的UMLet

  4. uva 1401 dp+Trie

    http://uva.onlinejudge.org/index.php? option=com_onlinejudge&Itemid=8&page=show_problem& ...

  5. jdk阅读xml文件

    前言 你需要阅读的时间来写一个通用组件xml文件,但考虑到组件分布更容易,这样一来在第三方小引用jar包.因此,直接jdk内建的xml分析方法.可能都没有第三发的组件强大. 导入的文件: import ...

  6. 一篇非常全面的freemarker教程

    copy自http://demojava.iteye.com/blog/800204 下面内容所有是网上收集: FreeMarker的模板文件并不比HTML页面复杂多少,FreeMarker模板文件主 ...

  7. JavaFX它ListView使用

    ListView它是通过同一控制非.在JavaFX在.ListView此外,它拥有非常丰富的功能.下列.让我们来看看如何使用ListView. ListView位于javafx.scene.contr ...

  8. Android开发被添加到桌面快捷方式

    Android开发被添加到桌面快捷方式 对于一个希望拥有很多其它用户的应用来说.用户桌面能够说是全部软件的必争之地,假设用户在手机桌面上建立了该软件的快捷方式.用户将会更频繁地使用该软件. 因此,全部 ...

  9. GLEW_ERROR_NO_GL_VERSION的解决方法

    关于 GLenum err = glewInit(); if (GLEW_OK != err) fprintf(stderr, "error initializaing GLew %s\n& ...

  10. js中推断对象详细类型

    大家可能知道js中推断对象类型能够用typeof来推断. 看以下的情况 <script> alert(typeof 1);//number alert(typeof "2&quo ...