user3653831
user3653831

Reputation: 235

Handling date format in JSpinner with SpinDateModel

I have the following lines of code:

    SpinnerDateModel spinMod=new SpinnerDateModel();
    JSpinner spin=new JSpinner(spinMod);
    //spin.setEditor(new JSpinner.DateEditor(spin,"dd.mm.yyyy"));

When I display the spinner I can edit it and write in the month field any two-digit number I want.

If I click on the JSpinner side I can only increase and decrease the month or day numbers so that their values are legal. But, if I add the last outcommented line, this wouldn't work, either.

The question is how to make the JSpinner accept only legal dates with the custom format.

Also, if I make an ActionListener added to a button that gets the date, I get a "correct date" by applying getValue() directly to the JSpinner, but a wrong one (the one entered) if I apply the date editor's format to the value obtained from the JSpinner. I want the action listener to get the correct value in my custom format and I want the JSpinner to only accept input in the custom format. Is that possible?

My test code is below:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.util.*;
import java.text.*; //for the date format

public class TestDates{

    JLabel jl=new JLabel("Date:");
    JFrame jf=new JFrame("Test SpinnerDateFormat");

    JButton jb=new JButton("Get Date");
    SpinnerDateModel spinMod=new SpinnerDateModel();
    JSpinner spin=new JSpinner(spinMod);

    class jbHandler implements ActionListener{
        public void actionPerformed(ActionEvent evt){
            JSpinner.DateEditor de=(JSpinner.DateEditor)spin.getEditor();
            String wrongDate=de.getFormat().format(spin.getValue());
            Date okDate=(Date)spin.getValue();
            System.out.println(">>>\n"+wrongDate+"\n"+okDate);
        }
    }

    JPanel pane=new JPanel();

    public TestDates(){

        jf.setLocationRelativeTo(null);
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        pane.add(jl);

        jb.addActionListener(new jbHandler());
        pane.add(jb);

        spin.setValue(new Date());//this doesn't work properly with the custom format
        spin.setEditor(new JSpinner.DateEditor(spin,"dd.mm.yyyy"));
        pane.add(spin);

        jf.add(pane);
        jf.pack();
        jf.setVisible(true);
    }

    public static void main(String[] args){

    SwingUtilities.invokeLater(new Runnable(){
        public void run(){
            TestDates tdate=new TestDates();
        }
        });
    }
}

Upvotes: 2

Views: 9034

Answers (1)

dic19
dic19

Reputation: 17971

If I click on the JSpinner side I can only increase and decrease the month or day numbers so that their values are legal. But, if I add the last outcommented line, this wouldn't work, either.

The problem is a little (but pretty common) mistake in your date pattern at this line:

spin.setEditor(new JSpinner.DateEditor(spin,"dd.mm.yyyy"));

In this pattern "mm" refers to minutes not months, thus causing different outputs. The correct pattern is:

spin.setEditor(new JSpinner.DateEditor(spin,"dd.MM.yyyy"));

The question is how to make the JSpinner accept only legal dates with the custom format.

If you want to prevent users to type invalid dates, then you need to play with editor's formatter and disallow invalid inputs. See the following snippet:

SpinnerDateModel model = new SpinnerDateModel();
JSpinner spinner = new JSpinner(model);

JSpinner.DateEditor editor = new JSpinner.DateEditor(spinner, "dd.MM.yyyy");
DateFormatter formatter = (DateFormatter)editor.getTextField().getFormatter();
formatter.setAllowsInvalid(false); // this makes what you want
formatter.setOverwriteMode(true);

Custom date-time formats

See Customizing Formats trail.

See also the following table extracted from Date and Time Patterns section in SimpleDateFormat javadoc:

enter image description here

Upvotes: 5

Related Questions