我正在开发一个Java项目,从下面的代码中我可以看到我有一个JFormattedTextfield。我想做的是在日期字段中引入一些容差。就像用户输入02.02.2010或02.FEB.2010或02/02/2010一样,它不应该给出错误。我正在尝试搜索类似的东西,但我能找到的是Simpledateformat告诉使用预定义格式的示例。请让我知道或给出一些指示。谢谢。
DateFormat format = new SimpleDateFormat("dd/M/yyyy");
DateFormatter df = new DateFormatter(format);
JFormattedTextField dateField = new JFormattedTextField(df);
答案 0 :(得分:0)
这是一个想法的种子,基本上这是一个“多格式化程序”。这意味着,您可以向其提供任意数量的AbstractFormatter
,并且在请求时,它将扫描列表,直到找到能够解析/格式化所请求值的列表。
它有局限性......显然,你不能再使用任何类型的掩码,因为MultiFormatter
允许任意数量的不同,不兼容(就掩码而言)格式......
在测试期间,我没有在字段验证时,它始终默认为第一个格式化程序(格式化给定值)。您可以通过保留用于将文本解析为其Object
等效项的最后一个成功解析器的引用来解决此问题。当然,如果无法再次格式化给定的Object
并尝试其他格式化程序,那么您还需要准备好丢弃此格式化程序...
长短基本上是,结果“值”对于用户输入的内容是正确的。MultiFormatter
现在设置的方式,第一个格式化程序将成为新的“默认”格式化程序值...
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.text.DateFormatter;
import javax.swing.text.DefaultFormatter;
public class Test100 {
public static void main(String[] args) {
new Test100();
}
public Test100() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
DateFormatter[] formatters = new DateFormatter[]{
new DateFormatter(new SimpleDateFormat("dd.MM.yyyy")),
new DateFormatter(new SimpleDateFormat("dd.MMM.yyyy")),
new DateFormatter(new SimpleDateFormat("dd/MM/yyyy"))
};
MultiFormatter<DateFormatter> multiFormatter = new MultiFormatter<>(formatters);
JFormattedTextField ftf = new JFormattedTextField(multiFormatter);
ftf.setColumns(10);
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
frame.add(ftf, gbc);
frame.add(new JButton("Test Focus Lost"), gbc);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class MultiFormatter<F extends JFormattedTextField.AbstractFormatter> extends DefaultFormatter {
private List<F> formatters;
public MultiFormatter() {
}
public MultiFormatter(F... formatters) {
addFormatters(formatters);
}
public List<F> getFormatters() {
if (formatters == null) {
formatters = new ArrayList<>(25);
}
return formatters;
}
public void addFormatters(F... formatters) {
getFormatters().addAll(Arrays.asList(formatters));
}
@Override
public String valueToString(Object value) throws ParseException {
String text = null;
for (F formatter : getFormatters()) {
try {
text = formatter.valueToString(value);
break;
} catch (ParseException exp) {
}
}
if (text == null) {
throw new ParseException("Could not find valid parser for " + value, 0);
}
return text;
}
@Override
public Object stringToValue(String text) throws ParseException {
Object value = null;
for (F formatter : getFormatters()) {
try {
value = formatter.stringToValue(text);
break;
} catch (ParseException exp) {
}
}
if (text == null) {
throw new ParseException("Could not find valid parser for " + value, 0);
}
return value;
}
}
}