Java:我的JFormattedTextField中有害行为的来源在哪里? [英] Java: where is source of unwanted behavior in my JFormattedTextField?

查看:107
本文介绍了Java:我的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),然后将焦点从格式化的文本字段移开,整个字段包括 s被删除.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆