How to Use Formatted Text Fields
如何使用格式化的文本框
原文地址
格式化的文本框为开发者提供了一种在文本框中只输入有效字符集的方式。 尤其是 JFormattedTextField 类在功能上添加了继承自 JTextField 类的一个 formatter (格式化方法)和一个对象值。 formatter 将字段值翻译成它显示的文本,也将文本翻译成值。
Formatted text fields provide a way for developers to specify the valid set of characters that can be typed in a text field. Specifically, the JFormattedTextField class adds a formatter and an object value to the features inherited from the JTextField class. The formatter translates the field's value into the text it displays, and the text into the field's value.
Using the formatters that Swing provides, you can set up formatted text fields to type dates and numbers in localized formats. Another kind of formatter enables you to use a character mask to specify the set of characters that can be typed at each position in the field. For example, you can specify a mask for typing phone numbers in a particular format, such as (XX) X-XX-XX-XX-XX.
使 用 Swing 提供的 formatters,可以设置在文本字段中键入本地化的日期和数字。还有一种 formatter 可以让您使用一个字符掩码来特指可以在字段内每个位置上键入的字符集。例如,可以为键入一定格式的电话号码--如 (XX) X-XX-XX-XX-XX)--指定一个掩码。
If the possible values of a formatted text field have an obvious order, use a spinner instead. A spinner uses a formatted text field by default, but adds two buttons that enable the user to choose a value in a sequence.
如果格式化的文本字段的可能值具有明显顺序,那么应该改用 spinner。spinner 默认情况下使用一个格式化的文本字段,只是多加了两个按钮,以便用户选择序列中的一个值。
Another alternative or adjunct to using a formatted text field is installing an input verifier on the field. A component's input verifier is called when the component nearly loses the keyboard focus. The input verifier enables you to check whether the value of the component is valid and optionally change it or stop the focus from being transferred.
使用格式化的文本字段的另一个选择或另一个修饰方法是在字段上加装一个验证器。在组件即将失去键盘焦点时调用组件的输入验证器。输入验证器可以让您检查组件的值是否有效,然后选择修改该值或者选择停止传递。
This GUI uses formatted text fields to display numbers in four different formats.
GUI 使用格式化的文本字段以四种不同的格式显示数值。
A snapshot of FormattedTextFieldDemo
FormattedTextFieldDemo 屏幕截图
Try this:
尝试以下方法:
1. Click the Launch button to run FormattedTextFieldDemo using Java? Web Start (download JDK 6). Alternatively, to compile and run the example yourself, consult the example index.
1. 单击“启动”,使用 java web start (下载 JDK 6)运行 FormattedTextFieldDemo。您也可以自己编译和运行这个例子,请参考示例索引页。
启动 FormattedTextFieldDemo 应用程序
2. Experiment with different loan amounts, annual percentage rates (APRs), and loan lengths.
Note that as long as the text you type is valid, the Month Payment field is updated when you press Enter or move the focus out of the field that you are editing.
2. 实验填入一些其他贷款金额,年率(APRs)和贷款期限。请注意,只要您输入的值有效,那么月付(Month Payment)字段应付在按 Enter 键或将焦点移出所编译的字段的时候更新。
3. Type invalid text such as "abcd" in the Loan Amount field and then press Enter.
The Month Payment field remains the same. When you move the focus from the Loan Amount field, the text reverts to the field's last valid value.
3. 在贷款金额(Loan Amount)字段输入无效的文字,如“abcd”,然后按 Enter 键。月付字段保持不变。当焦点移出贷款金额(Loan Amount)字段时,文本又恢复到上次输入到该字段的有效值了。
4. Type marginally valid text such as "2000abcd" in the Loan Amount field and press Enter.
The Monthly Payment field is updated, though the Loan Amount field still displays 2000abcd. When you move the focus from the Loan Amount field, the text it displays is updated to a neatly formatted version of its value, for example, "2,000".
4.
在贷款金额(Loan Amount)字段输入有限的有效文本如 "2000abcd" 然后按 Enter 键。月付字段被更新,然而贷款金额字段仍显示 2000abcd。当焦点移出贷款金额(Loan Amount)字段时,文本被更新为原值的一个整齐的格式化的版本,如 "2000"。
以下为 FormattedTextFieldDemo.java 代码:
package components;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeEvent;
import java.text.*;
/**
* FormattedTextFieldDemo.java requires no other files.
*
* It implements a mortgage calculator that uses four
* JFormattedTextFields.
*/
public class FormattedTextFieldDemo extends JPanel
implements PropertyChangeListener {
//Values for the fields
private double amount = 100000;
private double rate = 7.5; //7.5%
private int numPeriods = 30;
//Labels to identify the fields
private JLabel amountLabel;
private JLabel rateLabel;
private JLabel numPeriodsLabel;
private JLabel paymentLabel;
//Strings for the labels
private static String amountString = "Loan Amount: ";
private static String rateString = "APR (%): ";
private static String numPeriodsString = "Years: ";
private static String paymentString = "Monthly Payment: ";
//Fields for data entry
private JFormattedTextField amountField;
private JFormattedTextField rateField;
private JFormattedTextField numPeriodsField;
private JFormattedTextField paymentField;
//Formats to format and parse numbers
private NumberFormat amountFormat;
private NumberFormat percentFormat;
private NumberFormat paymentFormat;
public FormattedTextFieldDemo() {
super(new BorderLayout());
setUpFormats();
double payment = computePayment(amount,
rate,
numPeriods);
//Create the labels.
amountLabel = new JLabel(amountString);
rateLabel = new JLabel(rateString);
numPeriodsLabel = new JLabel(numPeriodsString);
paymentLabel = new JLabel(paymentString);
//Create the text fields and set them up.
amountField = new JFormattedTextField(amountFormat);
amountField.setValue(new Double(amount));
amountField.setColumns(10);
amountField.addPropertyChangeListener("value", this);
rateField = new JFormattedTextField(percentFormat);
rateField.setValue(new Double(rate));
rateField.setColumns(10);
rateField.addPropertyChangeListener("value", this);
numPeriodsField = new JFormattedTextField();
numPeriodsField.setValue(new Integer(numPeriods));
numPeriodsField.setColumns(10);
numPeriodsField.addPropertyChangeListener("value", this);
paymentField = new JFormattedTextField(paymentFormat);
paymentField.setValue(new Double(payment));
paymentField.setColumns(10);
paymentField.setEditable(false);
paymentField.setForeground(Color.red);
//Tell accessibility tools about label/textfield pairs.
amountLabel.setLabelFor(amountField);
rateLabel.setLabelFor(rateField);
numPeriodsLabel.setLabelFor(numPeriodsField);
paymentLabel.setLabelFor(paymentField);
//Lay out the labels in a panel.
JPanel labelPane = new JPanel(new GridLayout(0,1));
labelPane.add(amountLabel);
labelPane.add(rateLabel);
labelPane.add(numPeriodsLabel);
labelPane.add(paymentLabel);
//Layout the text fields in a panel.
JPanel fieldPane = new JPanel(new GridLayout(0,1));
fieldPane.add(amountField);
fieldPane.add(rateField);
fieldPane.add(numPeriodsField);
fieldPane.add(paymentField);
//Put the panels in this panel, labels on left,
//text fields on right.
setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
add(labelPane, BorderLayout.CENTER);
add(fieldPane, BorderLayout.LINE_END);
}
/** Called when a field's "value" property changes. */
public void propertyChange(PropertyChangeEvent e) {
Object source = e.getSource();
if (source == amountField) {
amount = ((Number)amountField.getValue()).doubleValue();
} else if (source == rateField) {
rate = ((Number)rateField.getValue()).doubleValue();
} else if (source == numPeriodsField) {
numPeriods = ((Number)numPeriodsField.getValue()).intValue();
}
double payment = computePayment(amount, rate, numPeriods);
paymentField.setValue(new Double(payment));
}
/**
* Create the GUI and show it. For thread safety,
* this method should be invoked from the
* event dispatch thread.
*/
private static void createAndShowGUI() {
//Create and set up the window.
JFrame frame = new JFrame("FormattedTextFieldDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Add contents to the window.
frame.add(new FormattedTextFieldDemo());
//Display the window.
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
//Schedule a job for the event dispatch thread:
//creating and showing this application's GUI.
SwingUtilities.invokeLater(new Runnable() {
public void run() {
//Turn off metal's use of bold fonts
UIManager.put("swing.boldMetal", Boolean.FALSE);
createAndShowGUI();
}
});
}
//Compute the monthly payment based on the loan amount,
//APR, and length of loan.
double computePayment(double loanAmt, double rate, int numPeriods) {
double I, partial1, denominator, answer;
numPeriods *= 12; //get number of months
if (rate > 0.01) {
I = rate / 100.0 / 12.0; //get monthly rate from annual
partial1 = Math.pow((1 + I), (0.0 - numPeriods));
denominator = (1 - partial1) / I;
} else { //rate ~= 0
denominator = numPeriods;
}
answer = (-1 * loanAmt) / denominator;
return answer;
}
//Create and set up number formats. These objects also
//parse numbers input by user.
private void setUpFormats() {
amountFormat = NumberFormat.getNumberInstance();
percentFormat = NumberFormat.getNumberInstance();
percentFormat.setMinimumFractionDigits(3);
paymentFormat = NumberFormat.getCurrencyInstance();
}
}
|