java Swing用户界面组件文本输入:文本域+密码域+格式化的输入域

愿天堂没有BUG

共 17273字,需浏览 35分钟

 ·

2022-06-12 10:59

文本输入

现在终于可以开始介绍Swing用户界面组件了。首先,介绍具有用户输入和编辑文本功能的组件。文本域(JTextField)组件和文本区(JTextArea)组件用于获取文本输入。文本域只能接收单行文本输入而文本区可以接收多行文本输入。

这两个类都继承于JTextComponent类。由于JTextComponent类是抽象类,所以不能构造这个类的对象。另外,在Java中常会看到这种情况,当查看API文档时,发现自己正在寻找的方法实际上来自父类JTextComponent,而不是来自派生类自身。例如,在一个文本域和文本区内获取(get)、设置(set)文本的方法实际上都是JTextComponent类中的方法。

javax.swing.text.JTextComponent 1.2

• void setText(String t)

改变文本组件的文本。

参数:t 新文本

• String getText( )

返回文本组件中的文本。

• void setEditable(boolean b)

确定用户是否可以编辑JTextComponent的内容。

文本域

把文本域添加到窗口中的常用办法是把它添加到面板或者其他容器中,这与添加按钮完全一样:

JPanel panel = new JPanel( );

JTextField textField = new JTextField("Default input", 20);

panel.add(textField);

这段代码将添加一个文本域,同时通过放入一个字符串“Default input”来对它进行初始化。

构造器的第二个参数设置了文本域的宽度。在这个例子中,宽度值为20“列”。但是,这里所说的列不是一个精确的测量单位。一列就是在当前使用的字体下一个字符的宽度。如果希望文本域最多能够输入n个字符,就应该把宽度设置为n列。在实际中,这样做效果不是很好,应该将最大输入长度再多设1~2个字符。列数只是给AWT设定首选(preferred)大小的一个提示。如果布局管理器需要缩放这个文本域,它会调整文本域的大小。在JTextField的构造器中设定的列宽度并不是用户能输入的字符个数的上限。用户可以输入一个更长的字符串,但是当文本长度超过文本域长度时输入就会滚动。用户通常不喜欢滚动文本域,因此应该尽量把文本域设置得大一些。如果需要在运行时重新设置列数,可以使用setColumns方法。

提示:使用setColumns方法改变文本框的大小之后,需要调用包含这个文本框的容器的revalidate方法。

textField.setColumns(10);

panel.revalidate( );

revalidate方法会重新计算容器内所有组件的大小,并且对它们重新进行布局。调用revalidate方法以后,布局管理器会重新设置容器的大小,然后就可以看到改变尺寸后的文本域了。

revalidate方法是JComponent类中的方法。它并不是马上就改变组件大小,而是标记该组件需要改变大小。这样就避免了多个组件都要改变大小时带来的重复计算。

但是,如果想重新计算一个JFrame中的所有组件,就需要调用validate方法—JFrame没有扩展JComponent。

通常情况下,希望用户在文本域中添加文本(或者编辑已经存在的文本)。文本域一般初始为空白。只要不为JTextField构造器提供字符串参数,就可以建立一个空白的文本域。

JTextField textField = new JTextField(20);

可以在任何时候调用setText方法来改变文本域中的内容。这个方法是从前面提到的JTextComponent中继承而来的。例如:

textField. setText("Hello!");

并且,在前面已经提到,可以调用getText方法提取用户键入的文本。这个方法返回用户输入的文本。如果想要把getText方法返回的文本域中的数据内容的前后空格去掉,就应该调用trim方法:

String text = textField.getText( ).trim( );

如果想要改变显示文本的字体,就使用setFont方法。

javax.swing.JTextField 1.2

• JTextField(int cols)

构造一个指定列数的空JTextField。

参数:cols 文本域中的列数

• JTextField(String text, int cols)

构造一个指定列数、指定初始字符串的JTextField。

参数:text 显示文本

cols 列数

• void setColumns(int cols)

告知文本域使用的列数。

参数:cols 列数

javax.swing.JComponent 1.2

• void revalidate( )

重新计算组件的位置和大小。

java.awt.Component 1.0

• void validate( )

重新计算组件的位置和大小。如果组件是容器,容器的位置和大小将被重新计算。

标签与标签组件

标签是容纳文本的组件。它们没有任何修饰(例如没有边界),也不响应用户输入。可以利用标签标识组件。例如,与按钮不同,文本域没有标签标识它们。要想用标识符标识这种不带标签的组件,应该

1)用相应的文本构造JLabel组件。

2)将标签组件放置在离需要标识的组件足够近的地方,这样用户就会知道标签标识的组件。

JLabel的构造器允许指定初始文本和图标,也可以选择内容的排列方式。可以用SwingConstants接口中的常量来指定排列方式。这个接口定义了几个很有用的常量,如LEFT、RIGHT、CENTER、NORTH、EAST等。JLabel是实现该接口的一个Swing类。因此,可以指定右对齐标签:

JLabel label = new JLabel("Minutes", SwingConstants.RIGHT);

或者

JLabel label = new JLabel("Minutes", JLabel.RIGHT);

利用setText和setIcon方法可以在运行期间设置标签的文本和图标。

提示:从JDK 1.3开始,可以在按钮、标签和菜单项上使用无格式文本和HTML文本。

我们不推荐在按钮上使用HTML文本—这样会影响观感。但是HTML文本在标签中是非常有效的。只要简单地将标签字符串放置在. . .中即可:

label = new JLabel("Requiredentry:");

警告—包含HTML标签的第一个组件需要延迟一段时间才能显示出来,这是因为需要加载相当复杂的HTML显示代码。

与其他组件一样,标签也可以放置在容器中。这就是说,可以利用前面讲述的技巧把标签放置在任何需要的地方。

javax.swing.JLabel 1.2

• JLabel(String text)

构造左对齐文本的标签。

参数:text 标签中的文本

• JLabel(Icon icon)

构造左对齐图标的标签。

参数:icon 标签中的图标

• JLabel(String text, int align)

构造指定文本和排列方式的标签。

参数:text 标签中的文本

align 一个SwingConstants的常量LEFT、CENTER或者RIGHT

• JLabel(String text, Icon icon, int align)

构造具有文本和图标的标签。图标位于文本的左侧。

参数:text

标签中的文本

icon

标签中的图标

align

一个SwingConstants的常量LEFT、CENTER或者RIGHT

• void setText(String text)

设定标签的文本。

参数:text

标签中的文本

• void setIcon(Icon icon)

设定标签的图标。

参数:icon

标签中的图标

文本域变化跟踪

让我们应用文本域来完成一些操作。图9-12展示了运行例9-2的应用程序的外观。这个程序显示了一个时钟,并且带有两个文本域用来输入小时和分钟。只要这两个文本域中的内容发生改变,时钟就会跟着改变。


跟踪文本域的每一次变化需要费点功夫。首先,需要注意,监视击键并不是一个好主意。有些击键(如箭头键)并不改变文本。而且,对于某些观感来说,鼠标动作也会导致文本改变。在本章开头已经看到,Swing文本域以一种非常通用的方法来实现:在文本域中看到的字符串只是底层数据结构(模型)的可视化表现(视图)。当然,对于一个简单的文本域来说,二者之间没有太大的区别。

视图是显示字符串,而模型是字符串对象。但是同样的体系结构也用于更高级的编辑组件。这些组件可以通过字体、段落以及其他更加复杂的数据结构标识的属性来提供格式化文本。所有文本组件的模型都由Document接口描述,既包括无格式的文本,也包括格式化的文本(例如HTML)。当数据改变后,可以要求文档(而非文本组件)给予通告,这将需要安装一个文档监听器(document listener):

textField.getDocument( ).addDocumentListener(listener);

当文本发生改变后,下面所列的DocumentListener方法中的一个会被调用:

void insertUpdate(DocumentEvent event)

void removeUpdate(DocumentEvent event)

void changedUpdate(DocumentEvent event)

当添加或者删除字符时,应该调用前两个方法。文本域根本不会调用第三个方法。对于复杂的文档类型来说,当一些内容发生变化时(例如改变格式),就会调用第三个方法。遗憾的是,没有任何回调方法会通告文本已改变—通常无需考虑它是如何改变的。而且这里也没有适配器类,因此文档监听器必须实现这三个方法。下面是程序代码:

private class ClockFieldListener implements DocumentListener{public void insertUpdate(DocumentEvent event) { setClock( ); }public void removeUpdate(DocumentEvent event) { setClock( ); }public void changedUpdate(DocumentEvent event) {}
}

setClock方法使用getText方法从文本域中获得当前用户输入的字符串。不过,得到的只是字符串。

需要使用我们熟悉的(也许是笨拙的)方法将它们转换成整数,如下所示:

int hours = Integer.parseInt(hourField.getText( ).trim( ));

int minutes = Integer.parseInt(minuteField.getText( ).trim( ));

但是当用户在文本域中输入了非整数字符串,如“two”或者文本域中为空时,这段代码就会产生错误。在这种情况下,可以捕获parseInt方法抛出的NumberFormatException异常,如果文本域中的内容不是数字,就不更新时钟了。在下一节中,将会看到如何在第一时间阻止用户的无效输入。

注意:除了监听文档事件以外,还可以把动作事件监听器添加到文本域中。当用户按下ENTER键时,该动作监听器就会得到通知。我们不推荐此方法,因为用户常常忘记在输入完数据后再敲一下回车键。如果使用一个动作监听器,就应该同时也安装一个焦点监听器,这样当用户离开文本域时就会得到通知。

最后,说明ClockPanel构造器如何设置首选的大小:

当框架的pack方法计算框架大小时,将使用面板首选的大小。

例9-2 TextTest.java







javax.swing.JComponent 1.2

• void setPreferredSize(Dimension d)

设置组件首选的大小。

javax.swing.text.Document 1.2

• int getLength( )

返回当前文档中的字符个数。

• String getText(int offset, int length)

返回文档中给定部分所包含的文本。

参数:offset 文本的起始偏移量

Length 需要的字符串长度

• void addDocumentListener(DocumentListener listener)

注册监听器来监听文档改变时的通知。

javax.swing.event.DocumentEvent 1.2

• Document getDocument( )

获得作为事件源的文档。

javax.swing.event.DocumentListener 1.2

• void changedUpdate(DocumentEvent event)

当一个属性或者属性集发生改变时被调用。

• void insertUpdate(DocumentEvent event)

当文档发生一个插入操作时被调用。

• void removeUpdate(DocumentEvent event)

当文档的一部分被删除时被调用。

密码域

密码域是一种特殊的文本域。为了避免有某种企图的人看到密码,用户输入的字符不显示出来。每个输入的字符都用回显字符(echo character)表示,通常用星号“*”取代。Swing提供了JPasswordField类来实现这样的文本域。

密码域是另一个模型-视图-控制器体系模式的例子。密码域采用与规则的文本域相同的模型来存储数据,但是它的视图改为显示回显字符,而不是实际的字符。

javax.swing.JPasswordField 1.2

• JPasswordField(String text, int columns)

构造一个新的密码域。

参数:text 将要显示的文本,没有相应的文本则为null

columns 列数

• void setEchoChar(char echo)

为密码域设置回显字符。注意,特殊的观感可以选择自己的回显字符。0表示重置为默认的回显字符。

参数:echo 代替文本字符显示的回显字符

• char[ ] getPassword( )

返回密码域中的文本。为了安全起见,在使用之后应该覆写返回的数组内容。(密码并不是以字符串String型返回的,因为字符串一直保留在虚拟机上,直到垃圾回收。)

格式化的输入域

在上一个例子中,希望用户输入数字,而不是任意的字符串。就是说只允许用户输入0~9的数字加上连字符(-)。并且如果是连字符,必须是输入的第一个符号。

从表面上看,对输入进行检验十分简单。我们可以为文本域安装一个键盘监听器,并且销毁所有非数字或连字符的键盘事件。遗憾的是,这只是一种简单的方法,尽管常常推荐大家用这种方法处理输入检验,但实际上效果并不好。首先,不是每个由有效输入字符组合的字符串都是有效的数值,比如--3和3-3就是非法的,尽管它们都由有效输入字符组成。其次,也是更重要的是,有些改变文本的方法与击键无关。在某些观感上,一些特定的键组合用于实现剪切、复制和粘贴文本操作。例如,在Metal观感上,组合键CTRL+V把缓冲区中的内容粘贴到文本域中。所以,需要监视以保证用户粘贴的是一个有效的字符。很明显,试图通过过滤击键来确保文本域中内容的有效性是一件很困难的事情。当然这也不是应用程序程序员要关注的问题。

也许你会感到奇怪,在JDK 1.4之前,没有输入数值的组件。从本书的第1版开始,我们就提供了一个用于输入格式化整型的文本域IntTextField。(在每个新版本中,都会改变一些不成熟的验证机制的实现。)最终,在JDK 1.4中,Swing设计者面对问题,提供了一个多功能的JFormattedTextField类,这个类不仅可以用于输入数值,也可以用于输入时间和更加复杂的格式化数值,如IP地址。

1. 整型输入

下面先从一个简单的例子开始:整型输入的文本域。

JFormattedTextField intField = new JFormattedTextField(NumberFormat.getIntegerInstance( ));

NumberFormat. getIntegerInstance返回一个用当前地区采用的格式来格式化整型数值的格式器对象。在US地区,逗号是十进制数的分隔符,允许用户输入如1,729的数值。在卷II的国际化章节中将详细地解释如何选择其他的地区。

对任何文本域,可以设置列数:

intField.setColumns(6);

可以用setValue方法设置一个默认值。这个方法有一个Object类型的参数,需要把int值包装成Integer对象:

intField.setValue(new Integer(100));

通常,用户在多个文本域中输入,然后点击一个按钮读取所有值。当点击按钮时,可以用getValue方法读取用户输入的数值。这个方法将返回一个Object结果,需要将它强制类型转换为相应的类型。如果用户对数值进行编辑,JFormattedTextField就会返回一个Long类型的对象。然而,如果用户没有做任何修改,就会返回原来的Integer对象。因此,应该把返回值转换成通用的超类Number:

Number value = (Number) intField.getValue( );

int v = value.intValue( );

在没有考查用户进行非法输入后会发生什么事情之前,格式化文本域不会引起人们太大的兴趣。下面就讨论这个问题。

2. 失去焦点的行为

试想一下当用户在文本域中输入之后会发生什么情况。用户输入后最终决定离开这个区域,也许是通过鼠标点击另一个组件。于是,文本域就失去焦点(lose focus)。I型光标在文本域中也不见了。键盘输入将作用于另一个组件。

当格式化的文本域失去焦点时,格式器查看用户输入的文本字符串。如果格式器知道如何把文本字符串转换为对象,文本就有效,否则就无效。可以用isEditValid方法检测文本域的当前内容是否有效。

失去焦点的默认行为被称为“提交或恢复”。如果文本字符串是有效的,它将被提交(commit)。

格式器将它转换为对象,该对象成为当前文本域的值(就是如前所述的getValue方法返回的值)。

然后,该值被转换为字符串,成为文本域内可见的文本字符串。例如,整型格式器认为输入1729是有效的,设置当前值为new Long(1729),并且把它转换为带有逗号的字符串:1,729。

相反地,如果文本字符串无效,当前值就不会改变。文本域恢复表示原值的字符串。例如,如果用户输入错误的值(像x1),那么在文本域失去焦点时就会恢复原值。

注意:如果文本字符串以一个整型开头,那么整型格式器就认为它是有效的。例如1729x是一个有效的字符串。它将被转换为1729,然后格式化为字符串1,729。

可以用setFocusLostBehavior方法设置其他行为。“提交”行为和默认行为有一些微小的差别。

如果文本字符串无效,文本字符串和文本域的值都不变—它们现在不同步。“持续”行为更加保守,即使文本字符串有效,文本域和当前值也不会改变。要调用commitEdit、setValue或者setText方法保证它们同步。最后,“恢复”行为似乎没什么用。无论何时失去焦点,用户输入都将被抛弃,文本字符串恢复到原值。

注意:通常,“提交或恢复”默认行为是合理的。只是存在一个潜在的问题。假设一个对话框包含一个整型值的文本域。用户输入字符串“1729”,前面有空格,然后点击OK按钮。空格导致数字无效,文本域值恢复到原值。OK按钮的动作监视器得到文本域值并且关闭对话框。用户并不知道他们输入的新值没有被接受。

在这样的情况下,选择“提交”行为可能更合适,并且让OK按钮监听器在关闭对话框前检测所有文本框内的值是否有效。

3. 过滤器

格式化文本域的基本功能简单明了,在大多数情况已经够用了。但是,可以进一步得到改进。我们可能希望完全阻止用户输入非数字,这里可以用文档过滤器(document filter)达到此目的。回忆一下模型-视图-控制器体系,控制器把输入事件转化为命令修改文本域的底层文档,这就是说,文本字符串存储在PlainDocument对象中。例如,无论何时控制器处理命令,都会将文本插入文档中,这称为“插入字符串”命令。被插入的字符串可以是单个的字符,也可以粘贴缓冲区的内容。文档过滤器可以中途截取命令,并改变字符串或者取消插入。下面是过滤器的一段insertString方法代码,它将分析要插入的字符串,并且只将数字或者“-”符号插入到文档中。(这段代码的处理可参见第3章解释的辅助Unicode字符。请参看第12章的StringBuilder类。)



可以覆盖DocumentFilter类的replace方法,在文本被选择或替换的时候调用此方法。replace方法的实现非常简单,请参照本节最后的程序。

现在需要安装文档过滤器了。可惜的是没有一个直接的方法。需要覆盖格式器类的getDocumentFilter方法,并传递一个格式器类的对象给JFormattedTextField。整型文本域使用了InternationalFormatter,它用
NumberFormat.getIntegerInstance( )进行初始化。下面是安装格式器产生想要的过滤器的程序:


注意:在JDK文档中提到,为了避免子类化发明了DocumentFilter类。直到JDK 1.3,都是通过扩展PlainDocument类并且覆盖insertString和replace方法来实现文本域过滤的。

现在PlainDocument类有了可插拔的过滤器,这是一个显著的进步。如果在格式器类中有可插拔的过滤器会更好。然而,这里没有,我们必须子类化格式器。

试一下本节最后的FormatTest程序。第三个文本域安装了一个过滤器。只能插入数字或者负号“-”。注意,这里还可以输入无效的字符串,如“1-2-3”。通常,不可能通过过滤器避免所有的无效字符串。例如:字符串“-”是无效的,但是过滤器没有拒绝它,因为它是有效字符串“-1”的前缀。尽管过滤器没能给出完全的保护,但还是可以用来避免那些明显的无效输入。

提示:过滤器的另一个用途是把字符串中的所有字符变成大写。这样的过滤器很容易编写。在过滤器的insertString和replace方法中,把要被插入的字符串转换成大写,然后调用超类的方法。

4. 检验器

还有另外一种潜在的实用机制,它可以用来警告用户以避免无效的输入。可以给任何JComponent附加检验器(verifier)。如果组件失去焦点,就询问检验器。如果检验器报告组件中的内容是无效的,组件马上就会重获焦点。因此,用户在提供其他输入之前,必须先修正无效的内容。

检验器必须扩展抽象类InputVerifier,并且定义verify方法。定义检测格式化文本域的检验器是非常简单的。JFormattedTextField类的isEditValid方法调用格式器,如果格式器可以把文本字符串转化为对象则返回true。下面是检验器:

可以把它附加到任何JFormattedTextField中:

intField.setInputVerifier(new FormattedTextFieldVerifier( ));

然而,检验器并不是万无一失的。如果点击按钮,按钮会在无效组件重新获得焦点之前通知它的动作监听器。动作监听器就会从验证失败的组件得到无效的结果。采用这种处理方式的原因是,用户可能想点击Cancel,这时不需要对无效的输入进行修改。

在示例程序中的第4个文本域上附加了一个检验器。尝试输入一个无效的数字(如x1729)然后敲击Tab键或者用鼠标点击另外一个文本域。注意,这个文本域立刻获得焦点。但是,如果点击OK按钮,动作监听器将调用getValue报告上一个有效的数值。

5. 其他标准的格式

除了整型格式器以外,JFormattedTextField还支持几种其他的格式器。NumberFormat类有下面几个静态方法:

getNumberInstance

getCurrencyInstance

getPercentInstance

这些方法产生浮点数、货币数值和百分数格式器。例如,可以得到用于输入货币数值的文本域:

JFormattedTextField currencyField = new JFormattedTextField(NumberFormat.getCurrencyInstance( ));

编辑日期和时间需要调用DateFormat类的静态方法之一:

getDateInstance

getTimeInstance

getDateTimeInstance

例如:

JFormattedTextField dateField = new JFormattedTextField(DateFormat.getDateInstance( ));

这个文本域使用默认(“medium”)格式编辑日期:

Feb 24, 2002

可以选择一个“short”格式替代:

2/24/02

使用:

DateFormat.getDateInstance(DateFormat.SHORT)

注意:在默认情况下,数据格式是“不严格的”。也就是说,无效日期(February 31,2002)将滚动到下一个有效日期(March 3, 2002)。这种行为可能会让用户感到吃惊。在这种情况下,调用DateFormat对象的setLenient(false)方法。

DefaultFormatter可以格式化任何类的对象,只要该类有一个字符串类型参数的构造器和匹配的toString方法。例如,URL类有一个URL(String)构造器利用字符串构造URL,如:

URL url = new URL("http://java.sun.com");

因此,可以使用DefaultFormatter格式化URL对象。格式器针对文本域值调用toString方法来初始化文本域的文本。当文本域失去焦点时,格式器使用带有String参数的构造器构造相同类的新对象作为当前值。如果构造器抛出了异常,编辑就是无效的。可以在示例程序中试验一下,比如输入一个不以“http:”前缀开头的URL。

注意:在默认情况下,DefaultFormatter处于覆写(overwrite)状态。与其他格式器不同,也不很实用。可以调用setOverwriteMode (false)关闭覆写状态。

最后,MaskFormatter对包含一些常量和一些变量字符的固定大小的样式很有用。例如,社会保险号(如078-05-1120)可以用

new MaskFormatter("###-##-####")格式化。#符号表示一个单个数字,表9-2显示了可以用在掩码格式器的符号。


可以通过调用MaskFormatter类的下列方法之一限制输入文本域的字符:

setValidCharacters

setInvalidCharacters

例如,为了读取用字符表示的分数(比如A+或者F),可以使用MaskFormatter formatter = new MaskFormatter("U * ");

Formatter.setValidCharacters("ABCDF+-");

但是,没有方法能够指定第二个字符不能是一个字母。

注意,字符串是被掩码格式器格式化的,它和掩码具有完全相同的长度。如果用户在编辑过程中删除字符,那么它们将被占位符(holer character)替代。默认的占位字符是空格,可以使用setPlaceholderCharacter方法改变它,例如:

formatter.setPlaceholderCharacter('0');

在默认情况下,掩码格式器处于overtype状态,直观上是这样,可以在示例程序中试验一下。

同时也要注意^符号的位置在掩码中跳过了固定字符。

掩码格式器对于固定格式(比如社会保险号和美国电话号码)非常有效。然而,也要注意

到在掩码格式下不允许有任何不一致的地方。例如,国际电话号码就不能使用掩码格式器,因

为各个国家的电话号码可能有不同的位数。

6. 自定义格式器

如果所有的标准格式器都不适用,就需要定义自己的格式器,做这件事情很容易。下面看一下4字节的IP地址,例如:

130.65.86.66

不能使用MaskFormatter,因为每个字节可能表示为一位、两位或三位数字。同时,还希望在格式器中检查每个字节的最大值为255。

为了自定义格式器,扩展DefaultFormatter类并且覆盖其中的方法。

String valueToString(Object value)

Object stringToValue(String text)

第一个方法把值转换为显示在文本域中的字符串。第二个方法解析用户输入的文本并转换为对象。如果有一个方法出错,将抛出ParseException。

在示例中,把IP地址存储在长度为4的byte[ ]数组中。valueToString方法形成一个字符串,它用句号分隔字节。注意byte值是其值在-128到127之间的符号数。为了把负数转换为无符号整数值,需要加上256。


与之相反,如果字符串有效,stringToValue方法将解析并生成一个byte[ ]对象,如果无效,将抛出ParseException。



试一下示例中的IP地址域,如果输入一个无效的地址,地址域就将恢复成上一个有效地址。

例9-3的程序展示了不同格式化的文本域(参见图9-13)。点击OK按钮从域内得到当前值。

注意:“Swing Connection”在线新闻简讯有一篇简短的文章描述了一个格式器,该格式器匹配任何正则表达式。参看
http://java.sun.com/products/jfc/tsc/articles/reftf/。


例9-3 FormatTest.java











javax.swing.JFormattedTextField 1.4

• JFormattedTextField(Format fmt)

使用给定的格式构造一个文本域。

• JFormattedTextField(JFormattedTextField.AbstractFormatter formatter)

使用给定的格式器构造文本域。注意DefaultFormatter和InternationalFormatter是JFormattedText

Field.AbstractFormatter的子类。

• Object getValue( )

返回文本域的当前有效值。注意,它可能和正在编辑的字符串不一致。

• void setValue(Object value)

设置给定对象的值。如果格式器不能将对象转换为字符串,操作失败。

• void commitEdit( )

用正在编辑的字符串设置文本域的有效值。如果格式器无法转换该字符串,操作可能失败。

• boolean isEditValid( )

检测正在编辑的一个字符串是否代表了一个有效值。

• void setFocusLostBehavior(int behavior)

• int getFocusLostBehavior( )

设置或得到“失去焦点”的行为。behavior的合法值可以是JFormattedTextField类的常量

COMMIT_ OR_REVERT、REVERT、COMMIT和PERSIST。

java.text.DateFormat 1.1

• static DateFormat getDateInstance( )

• static DateFormat getDateInstance(int dateStyle)

• static DateFormat getTimeInstance( )

• static DateFormat getTimeInstance(int timeStyle)

• static DateFormat getDateTimeInstance( )

• static DateFormat getDateTimeInstance(int dateStyle, int timeStyle)

返回Date对象产生的日期、时间或日期与时间。dateStyle与timeStyle的合法值是DateFormat类的常量SHORT、MEDIUM、LONG、FULL以及DEFAULT。

javax.swing.JFormattedTextField.AbstractFormatter 1.4

• abstract String valueToString(Object value)

将一个值转换为可编辑字符串。如果value不适合这个格式器将抛出ParseException异常。

• abstract Object stringToValue(String s)

将一个字符串转换为值。如果s不适合这个格式抛出ParseException异常。

• DocumentFilter getDocumentFilter( )

覆盖该方法以提供一个文档过滤器,用来限制对文本域的输入。返回值是null表示不需要过滤器。

javax.swing.text.DefaultFormatter 1.3

• void setOverwriteMode(boolean mode)

• boolean getOverwriteMode( )

设置或得到覆写的方式。如果mode为true,编辑文本时用新的字符覆写已有的字符。

javax.swing.text.DocumentFilter 1.4

• void insertString(DocumentFilter.FilterBypass bypass, int offset, String text, AttributeSet attrib)

字符串插入文档之前调用这一方法。可以覆盖该方法并修改字符串。也可以不调用 super.insert

String禁止插入,或者调用bypass方法修改文档而不使用过滤器。

参数:bypass 一个对象,允许执行屏蔽过滤器的编辑命令

offset 插入文本处的偏移

text 将要插入的字符

attrib 插入文本的格式属性

• void replace(DocumentFilter.FilterBypass bypass, int offset, int length, String text, AttributeSet attrib)

该方法在使用新字符串替换部分文档之前调用。可以覆盖该方法并修改字符串。也可以调用super.replace禁止替换,或者调用bypass方法修改文档而不使用过滤器。

参数:bypass 一个对象,允许你执行一个屏蔽过滤器的编辑命令

offset 插入文本处的偏移

length 被替换部分的长度

text 将要插入的字符

attrib 插入文本的格式属性

• void remove(DocumentFilter.FilterBypass bypass, int offset, int length)

在文档的一部分被删除(removed)之前调用。如果需要分析删除的效果,调用bypass.getDocument( ) 获得文档。

参数:bypass 一个对象,允许你执行一个屏蔽过滤器的编辑命令

offset 被删除部分的偏移

length 被删除部分的长度

javax.swing.text.MaskFormatter 1.4

• MaskFormatter(String mask)

用给定的掩码构造掩码格式器。掩码符号参看表9-2。

• void setValidCharacters(String characters)

• String getValidCharacters( )

设置或得到有效的编辑字符。只有给定字符串中的字符才能作为掩码的可变部分。

• void setInvalidCharacters(String characters)

• String getInvalidCharacters( )

设置或得到无效的编辑字符。任何给定字符串中的字符都不能输入。

• void setPlaceholderCharacter(char ch)

• char getPlaceholderCharacter( )

设置或得到占位符,在用户没有提供时该占位符作为掩码的可变字符使用。默认的占位符是空格。

• void setPlaceholder(String s)

• String getPlaceholder( )

设置或得到占位符字符串。如果用户没有提供掩码中所有的可变字符则使用其尾部。如果是null或比掩码短,用占位符填充剩余的输入。

• void setValueContainsLiteralCharacters(boolean b)

• boolean getValueContainsLiteralCharacters( )

设置或得到“包含直接量字符的值”标志。如果该标志为true,文本域中的值包含掩码的直接量(非可变)部分。如果为false,直接量字符将被移除。默认值为true。

文本区

有时,用户的输入超过一行。正像前面提到的,需要使用JTextArea组件来接受这样的输入。当在程序中放置一个文本区组件时,用户就可以输入多行文本,并用ENTER键换行。每行都以一个'\n'结尾。如果需要将用户的输入分割为多个单独的行,可以使用StringTokenizer类(参见第12章)。图9-14显示了一个工作的文本区。


在JTextArea组件构造器中,可以指定文本区的行数和列数。例如:

textArea = new JTextArea(8,40); //8 lines of 40 columns each

与文本域一样,出于安全的考虑,应该把列数设置得大一些。用户不仅仅限于输入指定的行数和列数,当输入过长时,文本会滚动。也可以使用setColumns方法改变列数,用setRows方法改变行数。这些数值只是首选大小—布局管理器可能会对文本区进行缩放。

如果文本区的文本超出显示的范围,剩下的文本就会被剪裁掉。可以使用换行来避免裁剪过长的行:

textArea.setLineWrap(true); //long lines are wrapped

换行只是视觉效果;文档中的文本没有改变,在文本中没有插入'\n'字符。

在Swing中,文本区没有滚动条。如果需要滚动条,可以把文本区中插入一个滚动窗格(scroll pane)中。

textArea =new JTextArea(8, 40);

JScrollPane scrollPane = new JScrollPane(textArea);

现在滚动窗格管理文本区的视图。如果文本超出了文本区可以显示的范围,滚动条就会自动出现,并且在删除部分文本后,当文本能够显示在文本区范围内时,滚动条会再次消失。滚动是由滚动窗格内部处理的,编写程序时无需处理滚动事件。

提示:在Swing中,为组件增加滚动条的通用机制是将组件放置在滚动窗格中。

例9-4给出了文本区演示的完整代码。这个程序只能在文本区中修改文本。点击“Insert”将句子插入文本末尾。点击第二个按钮将打开和关闭换行(它的标签在“Wrap”和“No Wrap”之间切换)。当然,可以使用键盘来编辑文本区的文本。注意,可以高亮显示部分文本并且使用CTRL+X、CTRL+C和CTRL+V键来剪切、拷贝和粘贴文本。(快捷键有特定的观感效果。前面几个组合键在Metal、Windows和Mac中的观感效果相同。)

注意:JTextArea组件只显示无格式的文本,没有字体或者格式设置。如果想要显示格式化文本(如HTML或者RTF),就需要使用JEditorPane和JTextPane类。在卷II将详细讨论这几个类。

例9-4 TextAreaTest.java




javax.swing.JTextArea 1.2

• JTextArea(int rows, int cols)

构造一个新的文本区。

参数:rows 行数

cols 列数

• JTextArea(String text, int rows, int cols)

用一个初始文本构造一个新的文本区。

参数:text 初始文本

rows 行数

cols 列数

• void setColumns(int cols)

设置文本区应该使用的首选的列数。

参数:cols 列数

• void setRows(int rows)

设置文本区应该使用的首选的行数。

参数:rows 行数

• void append(String newText)

将给定的文本附加到文本区中已有文本的尾部。

参数:newText 要附加的文本

• void setLineWrap(boolean wrap)

打开或关闭换行。

参数:wrap 应该换行,则为true

• void setWrapStyleWord(boolean word)

如果word是true,超长的行会在字边界处换行。如果为false,超长的行将被截断而不考虑字边界。

• void setTabSize(int c)

设置跳格(tab stop)为c列。注意,跳格不会转化为空格,但是,它们能够让文本对齐到下一个跳格处。

参数:c 跳格的列数

javax.swing.JScrollPane 1.2

• JScrollPane(Component c)

创建一个显示指定组件内容的滚动窗格。当组件内容超过显示范围时,滚动条会自动出现。

参数:c 需要滚动的组件

那本篇就介绍到这里了,觉得不错的话,可以转发关注一波!!!

明天给大家分享选择组件这一块儿的内容~~~~~大家准时来围观哈~~

本文就是愿天堂没有BUG给大家分享的内容,大家有收获的话可以分享下,想学习更多的话可以到微信公众号里找我,我等你哦。

浏览 63
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报