软件开发

当前位置:首页 > 软件开发

《Java核心技术高级特性》(第六章)(续)

3.过滤器

格式化文本框的基本功能对于大多数用户来说很直观,而且也足够用了。但是,我们还可以添加- - 些精化的功能,例如同时还要防止用户键入非数字字符,我们可以用文档过滤器( document filter)来实现这个行为。回忆-下,在模型-视图-控制器架构中,控制器将输人事件转译成了修改文本框底层文档的命令,这个底层文档也就是存储在PlainDocument对象中的文本字符串。例如,每当控制器处理的命令会导致在该文档中插人字符串时,它就会调用“插入字符串”命令。要插人的字符串可以是单个的字符,也可以是粘贴缓冲区中的内容。文档过滤器可以拦截这个命令,并修改字符串或放弃插人操作。下面是过滤器的insertString方法的代码,该方法对要插入的字符串进行分析,并只插人那些数字和负号(一)字符。(这段代码可以处理第I卷第3章中描述的补充Unicode字符,请参见第1章StringBui1der类。)

public void insertring(FilterBypass fb, int offset, String string, AttributeSet attr)
throws BadLocati onException
Stringbuilder builder = new StringBuilder(string);
for (int i■builder.lengthO - 1; i >= 0; i--)
int cp = builder. codePointAt(i);
if (ICharacter.igit(cp) &cp != '")
builder.deleteCharAt(i);
if (Characer.isSupplementaryCodePoint(cp))
{
builder.deleteCharAt(i);
、]
super.insertString(fb, offset, builder. toStringO, attr); 
}

还应该覆盖DocumentFilter类的rep1ace方法,该方法在文本被选中并被替换时调用。rep1ace 方法的实现很直观,参见程序清单6-21。

现在需要安装文档过滤器。但是,没有很直观的方法可以实现这个任务,必须覆盖某个格式器类的getDocumentFilter方法,然后将这个格式器的一个对象传递给JF ormattedTextField。整数文本框使用的是用NumberF ormat . getInteger Instance( )初始化的Internati onalFormatter。下 面展示了如何安装格式器以产生所需的过滤器:

JFomattedTextField intField = new JFomattedTextField(new
Interationlaroratter(Numberormat.getIntegerInstanceO)
{
private DocumentFilter filter = new IntFilter0;
protected DocumentFilter getDocumentFilter0
return filter;
}
});

口注意: JavaSE 文档声明DocumentFilter类被设计为禁止子类化。直到Java SE 1.3,文本框中的过滤机制才通过扩展PlainDocument类和覆盖insertstring与replace方法得到了实现。现在,P1ainDocument 类有了可插拔的过滤器,这是一项极佳的改进。如果过滤器在格式器类中也是可插拔的,那么这项改进就更好了。唉,但是它不是,我们必须子类化格式器。

试验- -下本节最后的FormatTest示例程序,其中第三个文本框就安装了一个过滤器,这样就只能插入数字和负号字符了。注意,现在你仍旧可以键入诸如“1-2-3” 这样的无效字符串。通常,通过过滤机制来避免所有无效字符串是不可能的。例如,字符串“-”是无效的,但是过滤器不能拒绝它,因为它是合法字符串“-1”的前缀。即使过滤器不能进行完美的保护,但是使用它们来拒绝明显无效的输人仍旧是有意义的。

O提示:过滤机制的另一种用法是将一个字符串的所有字符都转为大写。这样的过滤器很容易编写,在其insertstring和replace方法中,将要插入的字符串转换成大写,然后调用超类的方法即可。

4.校验器

还有一种很有用的机制,可以就无效输人对用户发出警告,这就是在任意的JComponent.上附着一个校 验器( verifier)。如果该构件失去了焦点,那么校验器就会被查询。如果校验器报告该构件的内容无效,那么该构件就会立即重新获得焦点。这样,用户就被强制要求在进行其他输人之前先订正刚输入的内容。

校验器必须扩展Inputverifier类并定义verify方法,而定义检查格式化文本框的校验器非常容易。JF ormattedTextField类的1sEditValid方法将调用格式器,并且在格式器可以将文本字符申转换为对象时返回true。下面是- -个校验器:

intild.setInputerifier(new InputVerifierO
public boolean verify(Component component)
JFomattedTextField field = (FomattedTextField) component;
return field.isEditValidO;

我们可以将它附着到任何JF ormattedTextField.上。

在示例程序中的第四个文本框就附着了一个校验器。试着在其中键入无效数字(例如x1729),然后按下TAB键,或者用鼠标点击其他文本框。注意,该文本框会立即重新得到焦点。但是,如果你点击OK按钮,动作监听器就会调用getValue,它会报告最后一个有效值。

但是,校验器并非总是很安全。如果点击了某个按钮,而这个按钮在无效构件再次获得焦点之前通知了它的动作监听器,那么这个动作监听器就会从未通过校验的构件中得到--个无效的结果。这种行为的原因在于:用户可能希望点击Cancel按钮,而无需订正无效输人。

5.其他的标准格式器

除了整数格式器, JF ormattedTextField还支持若干种其他的格式器。NumberFormat类有下列静态方法:

getNumberInstance
getCurrencyInstance
getPercentInstance

它们将分别产生用于浮点数字、货币值和百分比的格式器。例如,通过下面的调用可以获得用于输入货币值的文本框。

FomattedTextField currencyField ■new JFormattedTextField(NumberFormat.getCurrencyInstanceO);

要编辑日期和时间,可以调用DateF ormat类的下列静态方法之- -:

getDateInstance
getTimeInstance
getDateTimeInstance

例如: .

JFormattedTextField dateField = new JFomattedTextField(DateFomat.getDateInstanceO);

所产生的文本框将用默认格式或下面的“中等长度”格式来编辑日期:

Aug 5, 2007

也可以选择使用“短”格式

8/5/07

方法是调用下面的语句:

DateFormat, getDateInstance(OateFomat.SHORT)

口注意:默认情况下,日期格式器是很“宽容”的,也就是说,像2002年2月31号这样的无效日期将会滚动到下一个有效日期2002年3月3日。这种行为可能会让用户觉得意外,此时,可以在DateFormat对象上调用setLeni ent(false)。

对于任何类,只要它有一个接受字符串参数的构造器,以及相匹配的toString方法,那么Defau1tF ormatter就可以格式化它的对象。例如,URL 类有一个URL(String)构造器,可以从字符串中构建URL,例如:

URL url = new UIT'ttp://orstnancco");


相关内容

文章评论

表情

共 0 条评论,查看全部
  • 这篇文章还没有收到评论,赶紧来抢沙发吧~