【问题标题】:JTextField requires me to give it focus a second time before making proper updatesJTextField 要求我在进行适当更新之前再次关注它
【发布时间】:2014-06-24 18:10:11
【问题描述】:

在我的项目中,我有一个 JTextField 用于输入日期。我有一个 InputVerifier 以确保输入正确的信息并对其进行一些处理。我需要做的一件事是从输入的日期获取DAY_OF_WEEK。我这样做是用

Calendar calTest = Calendar.getInstance();
calTest.setTime(primer);
int day = calTest.get(Calendar.DAY_OF_WEEK);

然后我将其打印到屏幕上,无论输入什么日期,显示的数字都是4,但是当我单击该字段并重新单击而不进行更改时,正确的数字会打印到屏幕上。我想不通这是为什么?特别是当字段失去焦点后立即正确打印字符串形式的日期时。 以下是发生这种情况的方法:

private void updatePrimer(String dateString) {
    Calendar calTest = Calendar.getInstance();
    calTest.setTime(primer);
    int day = calTest.get(Calendar.DAY_OF_WEEK);
    try {
        primer = simpleFormat.parse(dateString);
    } catch (ParseException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    System.out.println(day);
    shortString = shortFormat.format(primer);
    System.out.println(shortString);
    labelTrip = true;
    stringTrip = dateString;
    updateLabels(labelTrip, stringTrip);
}

这是一个小型可运行程序,我基本上一直将其用作沙箱: 编辑 这只是我在实现主程序之前一直在使用的“沙盒”程序,以便我可以测试基本功能。我需要的最终结果是让JTextField 接收一个字符串,然后将其格式化为MM/dd/yyyy 格式的日期。使用此日期,JLabel 将更新为相同的日期,但格式为 MM/dd。此外,它旁边的JLabel 将更新日期减去前一天的日期,然后对剩余的 JLabel 进行相同的处理。颜色的变化用来帮助我可视化程序的操作顺序。 textarea 只是让我点击某些东西来改变焦点。该按钮只打印JTextField中输入的日期

重要的是,这里的问题是为什么在updatePrimer(String dateString) 中正确的星期几仅在 JTextField 第二次获得焦点时才正确打印

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.InputVerifier;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFormattedTextField;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.MaskFormatter;


public class Hello implements ActionListener{
    private JFrame frame = new JFrame();
    private JPanel panel = new JPanel();
    private Date endingDate = new Date();
    private Date primer = new Date();
    private String endingString = null;
    private SimpleDateFormat simpleFormat = new SimpleDateFormat("MM/dd/yyyy");
    private SimpleDateFormat shortFormat = new SimpleDateFormat("MM/dd");
    private JFormattedTextField weekEndingData = null;

    private JLabel dateData[] = new JLabel[3]; 
    private JTextArea ta = new JTextArea(20, 10);
    private JButton b = new JButton("click");
    private String shortString = null;
    private boolean labelTrip = false;
    private String stringTrip = null;
    private Calendar cal = Calendar.getInstance();
    private Color blank = Color.LIGHT_GRAY;

    public Hello() {
        b.addActionListener(this);

        weekEndingData = createFormattedTextField();
        simpleFormat.setLenient(false); 

        panel.add(weekEndingData);
        for (int i=0; i<3; i++){
            dateData[i] = new JLabel("12/34");
            dateData[i].setForeground(blank);
            panel.add(dateData[i]);
        }

        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");
    }

    private JFormattedTextField createFormattedTextField() {
        JFormattedTextField formattedField = null;
        try {
            MaskFormatter dateMask = new MaskFormatter("##/##/####");
            formattedField = new JFormattedTextField(dateMask);
        } catch (ParseException ex) {
            Logger.getLogger(Hello.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");
                    weekEndingData.setText("");
                }
                return valid;
            }

        };
        return verifier;
    }

    public boolean isValidDate(String dateString) {
        if (dateString.equals("  /  /    ")){
            resetLabels();
            return true; //returns true in order to allow user to accidentally click field and still yield focus 
        }
        else{
            try {
                simpleFormat.parse(dateString);
                updatePrimer(dateString);
                return true;
            } catch (ParseException ex) {
                resetLabels();
                return false;
            }

        }
    }

    private void updatePrimer(String dateString) {
        Calendar calTest = Calendar.getInstance();
        calTest.setTime(primer);
        int day = calTest.get(Calendar.DAY_OF_WEEK);
        try {
            primer = simpleFormat.parse(dateString);
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println(day);
        shortString = shortFormat.format(primer);
        System.out.println(shortString);
        labelTrip = true;
        stringTrip = dateString;
        updateLabels(labelTrip, stringTrip);
    }

    private void resetLabels() {
        weekEndingData.setValue(null);
        labelTrip = false;
        updateLabels(labelTrip, stringTrip);
    }

    private void updateLabels(boolean trip, String date) {
        boolean validUpdate = trip;
        if (validUpdate == false){
            for (int i = 0; i < 3; i++){
                dateData[i].setText("12/34");
                dateData[i].setForeground(blank);
            }
        }
        else if (validUpdate == true){
            try {
                cal.setTime(simpleFormat.parse(date));
            } catch (ParseException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            int day = -1;
            for (int i = 0; i < 3; i++){
                cal.add(Calendar.DATE, day);
                dateData[i].setText(shortFormat.format(cal.getTime()));
                dateData[i].setForeground(Color.GREEN);
            }

        }
    }

    public void actionPerformed(ActionEvent e) {
        /*System.out.println("Action performed");
        System.out.println(formattedField);
        endingDate = (Date) formattedField.getValue();

        System.out.println(endingDate);
        endingString = format.format(endingDate);
        System.out.println(endingString);*/
        System.out.println(weekEndingData.getText());

    }

}

【问题讨论】:

  • +1 你是否尝试过将 JSpinner 与 SpinnerDateModel 一起使用,值 JFormattedTextField 很难为空或为空,这种方式
  • @mKorbel 感谢您花时间阅读我的问题。是的,我已经调查过了,不幸的是,我的老板不希望使用 Spinner。只有带有`//`掩码的文本字段
  • 那么第一个代码块,问题出在哪里?
  • 嗯,我“认为”是的。它执行并打印一周中的一天,但打印错误的一天,除非它重新获得焦点,否则它会正确打印。我也认为问题可能出在 inputverifier 产生焦点但我认为当我想要的其他所有东西都能完美运行时这没有意义
  • 你能试着解释一下应该发生什么以及它实际上在做什么。我不认为我完全理解这个问题。我现在正在玩你的程序,不知道要寻找什么

标签: java swing date inputverifier


【解决方案1】:

在打印出我的代码并通过程序跟踪我的数据后,我发现了我的问题。

private void updatePrimer(String dateString) {
    Calendar calTest = Calendar.getInstance();
    calTest.setTime(primer);
    int day = calTest.get(Calendar.DAY_OF_WEEK);
    try {
        primer = simpleFormat.parse(dateString);
    } catch (ParseException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    System.out.println(day);
    shortString = shortFormat.format(primer);
    System.out.println(shortString);
    labelTrip = true;
    stringTrip = dateString;
    updateLabels(labelTrip, stringTrip);
}

线条:

calTest.setTime(primer);
int day = calTest.get(Calendar.DAY_OF_WEEK);

需要在primer = simpleFormat.parse(dateString); try-catch 块之后移动。我的问题是我在设置日期之前设置了时间。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多