1

In my project I have a JTextField for dates to be entered in. I have an InputVerifier to ensure proper information is entered and to also do some work with it. One of the things I need is to get the DAY_OF_WEEK from the entered date. I do so with

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

I then print it to the screen, no matter what date is entered, the number shown is 4 but when I click out of the field and click back in without making changes, the proper number is printed to screen. I can't figure out why this is? Especially when the date in string form is printed correctly immediately after the field loses focus. Below is the method where this takes place:

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

Here is a small runnable program that I have been using basically as a sandbox: EDIT This is just a "sandbox" program I have been using before implementing to my main program so that I can test basically functionality. The end result of what I need is to have a JTextField taking in a string and then format it into a date in the format MM/dd/yyyy. Using this date, a JLabel is updated with the same date but in the format of MM/dd. Additionally, the JLabel next to it will update with the date minus one day of the previous date, and then the same deal with the remaining JLabel. The changing of colors was used to help me visualize the order of operations of the program. The textarea was just thrown in for me to click something to change focus. The button just prints the date entered in the JTextField

The important thing, and what is in question here is why in updatePrimer(String dateString) the correct day of the week is only printed correctly the second time the JTextField gains focus

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());

    }

}
exit_1
  • 1,240
  • 4
  • 13
  • 32
  • 1
    +1 did you tried by using JSpinner with SpinnerDateModel, value JFormattedTextField hard to be empty or null, this way – mKorbel May 07 '14 at 16:34
  • @mKorbel thanks for taking time to to read my question. Yes I have looked into it, unfortunately, my boss does not want a Spinner to be used. Only a textfield with a ` / / ` mask – exit_1 May 07 '14 at 16:38
  • So the first code block, is that where the problem is occurring? – Paul Samsotha May 07 '14 at 16:53
  • well I "think" so. it executes and prints a day of the week but it prints the wrong one, unless it regains focus, then it prints correctly. i also think maybe the problem could be with the inputverifier yielding focus but I dont think that makes sense when everything else I want from it works perfectly – exit_1 May 07 '14 at 17:02
  • Can you try and explain what is supposed to happen and what it's actually doing. I don't think I fully understand the question. I'm playing with your program now and not sure what to be looking for – Paul Samsotha May 07 '14 at 17:04
  • @peeskillet, sure give me a few minutes while I edit my question – exit_1 May 07 '14 at 17:06
  • @peeskillet I updated my question, hopefully it sheds more light on the matter. Essentially, if you run the program and type in a date in the JFormattedTextfield , then change focus, youll see an incorrect day of the week being printed to the console (specifically the number 4). now click on the JFormattedTextfield again, youll notice the correct day of the week printed in the console. thats what I can't figure out – exit_1 May 07 '14 at 17:23
  • If no one answers it by tomorrow, I'll have a look at it. Too lazy for debugging right now, sorry. – Paul Samsotha May 07 '14 at 17:43
  • no worries, I appreciate your time. – exit_1 May 07 '14 at 17:46

1 Answers1

0

After printing out my code and tracing my data through the program I discovered my problem.

In

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

the lines :

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

needed to be moved after the primer = simpleFormat.parse(dateString); try-catch block. My problem was that I was setting the time before setting the date.

exit_1
  • 1,240
  • 4
  • 13
  • 32