我需要一个只接受正整数作为输入的JTextField。我的实施大多有效。当您在字段中键入文本时,会显示数字,并且不会显示非数字。
但是构造函数的“text”参数存在问题。如果我传递一个包含正整数的String表示的String,我希望文本字段开始包含该字段,而是文本字段开始为空。例如,这样做会导致它出现我所描述的症状:new NumericTextField(“1”,5);
在初始化期间不会调用过度使用的insertString方法。
我做错了什么,我该如何解决?这是代码......
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.text.*;
/**
* A JTextField that only accepts characters that are digits. Also, the first character can't be "0".
*/
public class NumericTextField extends JTextField {
public class CustomFilterDocument extends PlainDocument {
public void insertString(int offset, String text, AttributeSet aset) throws BadLocationException {
if (isLegalValue(text)) {
super.insertString(offset, text, aset);
}
}
}
private static boolean isLegalValue(String text) {
if (text == null) {
return false;
}
int len = text.length();
for (int i = 0; i < len; i++) {
char c = text.charAt(i);
if (!Character.isDigit(c) || (i ==0 && c == '0')) {
return false;
}
}
return true;
}
public NumericTextField() {
super();
setDocument(new CustomFilterDocument());
}
public NumericTextField(int columns) {
super(columns);
setDocument(new CustomFilterDocument());
}
public NumericTextField(String text) {
super(text);
setDocument(new CustomFilterDocument());
}
public NumericTextField(String text, int columns) {
super(text, columns);
setDocument(new CustomFilterDocument());
}
}
固定版本(使用我从回复中学到的内容)如下所示:
public NumericTextField(String text) {
super(text);
initText(text);
}
public NumericTextField(String text, int columns) {
super(text, columns);
initText(text);
}
private void initText(String text) {
Document doc = new CustomFilterDocument();
try {
doc.insertString(0, text, null);
} catch (BadLocationException ble) {
}
setDocument(doc);
}
答案 0 :(得分:1)
问题是您要将文档设置为新文档。这将删除您通过构造函数传递的任何内容。
public NumericTextField(String text) {
super(text);
// This next line will erase the content on the current document
setDocument(new CustomFilterDocument());
}
答案 1 :(得分:0)
使用现有模型构建时,许多Swing组件并不是特别聪明,这种模型与整个模型理念相关。
通常,您不需要子类JTextField
(事实上,如果您使用DocumentFilter
,则不需要继承Document
。将文本插入文档,为文本字段创建,然后将文档设置到文本字段中。那里没有太多的开销。
如果你真的想,你可以继承JTextField
来覆盖奇怪命名的createDefaultModel
。如果你需要一些上下文变量,你不能通过构造函数传递它们,因为在调用此方法时它不会完成执行(实际上,不要触及this
)。但是,如果它是一个匿名内部类(并使用-target 1.4
或更高版本编译),那么您可以访问封闭方法的final
个本地字段。
答案 2 :(得分:0)
JTextComponent txt = new JFormattedTextField( new PositiveIntegerFormatter() );
txt.addPropertyChangeListener("value", yourPropertyChangeListener);
import javax.swing.text.DefaultFormatter;
import java.text.ParseException;
public class PositiveIntegerFormatter extends DefaultFormatter {
static final long serialVersionUID = 1l;
public PositiveIntegerFormatter() {
setValueClass(Integer.class);
setAllowsInvalid(false);
setCommitsOnValidEdit(true);
}
@Override
public Object stringToValue(String string) throws ParseException {
if (string.equals("")) return null;
Integer value = (Integer)super.stringToValue(string);
if ( Integer.signum(value.intValue()) < 0 ) throw new ParseException(string, 0);
return value;
}
}
将使用
调用yourPropertyChangeListenernew PropertyChangeEvent(“value”,Integer oldValue,Integer newValue)
(oldValue或newValue在“”文本案例中)为空
每次有效编辑后
请注意。 id不支持您正在使用的构造函数。 要设置文本和大小,您应该添加
txt.setText( String text );
txt.setPreferredSize( int x, int y );