Java:我的JFormattedTextField中有害行为的来源在哪里? [英] Java: where is source of unwanted behavior in my JFormattedTextField?
问题描述
我当前的Java项目要求我处理日期,并且通过研究和修改,我发现setLenient()
方法默认为true
.当我将其设置为false
时,我的代码开始出现问题.
My current Java project requires me to work with dates and through my research and tinkering around I discovered the setLenient()
method is defaulted to true
. When I set it to false
I begin to have problems with my code.
我用SimpleDateFormat
初始化了JFormattedTextField
.对于我的项目,我需要始终使用/
占位符,因此请使用此问题的答案,我能够以MM/dd/yyyy
I have a JFormattedTextField
intialized with a SimpleDateFormat
. For my project, I need to have /
placeholders always present so using the answer to this question, I was able to install /
s as place holders in the form of MM/dd/yyyy
当SimpleDateFormat
设置为setLenient(false)
时,输入的日期不完整(例如12/34/5),然后将焦点从格式化的文本字段移开,整个字段包括
When the SimpleDateFormat
is set to setLenient(false)
, and an incomplete date is entered (such as 12/34/5), and then have the focus shift away from the formatted textfield, the entire field including the /
s is removed.
当SimpleDateFormat
设置为setLenient(true)
时,不会发生这种情况.相反,一旦失去焦点,则将12/34/5的不完整条目设置为01/03/0006
.
When SimpleDateFormat
is set to setLenient(true)
, this doesn't happen. Instead, the incomplete entry of 12/34/5 is set to 01/03/0006
once focus is lost.
我需要能够在我的简单日期格式化程序上使用setLenient(false)
,同时还要始终具有/
占位符.我真的不知道核心问题在哪里,该程序的不良行为在哪里,我将不胜感激.
I need to be able to usesetLenient(false)
on my simple date formatter while also always having /
placeholders. I do not really know where the core issue lies in the unwanted behavior of the program and would appreciate any insight.
有关问题的简化程序:
public class Hello implements ActionListener{
private JFrame frame = new JFrame();
private JPanel panel = new JPanel();
private Date endingDate = new Date();
private String endingString = null;
private SimpleDateFormat dateFormatter = new SimpleDateFormat("MM/dd/yyyy");
private JFormattedTextField formattedText = new JFormattedTextField(dateFormatter);
private JLabel label1 = new JLabel();
private JLabel label2 = new JLabel();
private TextArea ta = new TextArea();
private Button b = new Button("click");
public Hello() {
//setPreferredSize(new Dimension(500,500));
b.addActionListener(this);
label1 = new JLabel("test");
label2 = new JLabel("test");
formattedText.setColumns(10);
dateFormatter.setLenient(false); // not efficient
try {
MaskFormatter dateMask = new MaskFormatter("##/##/####");
dateMask.install(formattedText);
} catch (ParseException ex) {
Logger.getLogger(Hello.class.getName()).log(Level.SEVERE, null, ex);
}
panel.add(formattedText);
panel.add(label1);
panel.add(label2);
panel.add(ta);
panel.add(b);
frame.add(panel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable(){
public void run(){
new Hello();
}
});
System.out.println("Hello, World");
}
public void actionPerformed(ActionEvent e) {
System.out.println("Action performed");
System.out.println(formattedText);
endingDate = (Date) formattedText.getValue();
System.out.println(endingDate);
endingString = dateFormatter.format(endingDate);
System.out.println(endingString);
}
}
推荐答案
您可以使用 InputVerifier
,将验证内容.如果日期无效,则可以弹出JOptionPane.
You can use an InputVerifier
that will verify the contents. If the date is not valid, you can popup a JOptionPane.
请参见下面的示例.我尝试解析方法isValidDate
中的输入.如果不是有效日期,它将返回false,从而导致InputVerifier
在其verify
方法中返回false.
See the example below. I try to parse the input in the method isValidDate
. If it's not a valid date, it will return false, causing the InputVerifier
to return false in it's verify
method.
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.Box;
import javax.swing.InputVerifier;
import javax.swing.JComponent;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;
import javax.swing.text.MaskFormatter;
public class InputVerifyDate {
private SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy");
public InputVerifyDate() {
JFormattedTextField formattedField = createFormattedTextField();
JTextField field = new JTextField(10);
format.setLenient(false);
Box box = Box.createVerticalBox();
box.add(formattedField);
box.add(Box.createVerticalStrut(10));
box.add(field);
box.setBorder(new EmptyBorder(10, 10, 10, 10));
JFrame frame = new JFrame();
frame.add(box);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private JFormattedTextField createFormattedTextField() {
JFormattedTextField formattedField = null;
try {
MaskFormatter dateMask = new MaskFormatter("##/##/####");
formattedField = new JFormattedTextField(dateMask);
} catch (ParseException ex) {
Logger.getLogger(InputVerifyDate.class.getName()).log(Level.SEVERE, null, ex);
}
formattedField.setColumns(10);
formattedField.setInputVerifier(getInputVerifier());
return formattedField;
}
private InputVerifier getInputVerifier() {
InputVerifier verifier = new InputVerifier() {
@Override
public boolean verify(JComponent input) {
JFormattedTextField field = (JFormattedTextField) input;
String text = field.getText();
return isValidDate(text);
}
@Override
public boolean shouldYieldFocus(JComponent input) {
boolean valid = verify(input);
if (!valid) {
JOptionPane.showMessageDialog(null, "Please enter a valid date in format dd/mm/yyyy");
}
return valid;
}
};
return verifier;
}
public boolean isValidDate(String dateString) {
try {
format.parse(dateString);
return true;
} catch (ParseException ex) {
return false;
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new InputVerifyDate();
}
});
}
}
这篇关于Java:我的JFormattedTextField中有害行为的来源在哪里?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!