JTextField требует от меня, чтобы он сфокусировался во второй раз, прежде чем делать соответствующие обновления

В моем проекте у меня есть 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. Изменение цвета было использовано, чтобы помочь мне визуализировать порядок операций программы. Я только что добавил текстовую область, чтобы щелкнуть что-то, чтобы изменить фокус. Кнопка просто печатает дату, введенную в 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 ответ

Решение

После распечатки моего кода и отслеживания моих данных через программу я обнаружил свою проблему.

В

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. Моя проблема заключалась в том, что я устанавливал время до установки даты.

Другие вопросы по тегам