javaswingdatenetbeans

How to allow date input in yyyy-MM-dd format without external libraries?


I'm building a Java Swing application where users need to enter a date in the format yyyy-MM-dd.

I want to use only standard Swing and Java components, without external libraries like JCalendar or JDateChooser.

The date values I'm working with are of type java.sql.Date. If needed, I can convert from java.util.Date. I'm using NetBeans GUI Builder to design the form visually I used java.sql.date because it is the type of data that would be needed to then make the query towards the database

I tried

  1. JFormattedTextField with a DateFormatter and yyyy-MM-dd pattern

  2. Works, but requires the user to manually type the dashes, or parsing fails.

  3. MaskFormatter ("####-##-##")

  4. Enforces the visual format but accepts invalid dates like 3202-15-59.

enter image description here

enter image description here


Solution

  • MaskFormatter can do it. You just need to override its stringToValue method, so it disallows invalid dates:

    import java.time.LocalDate;
    import java.time.format.DateTimeParseException;
    import java.text.ParseException;
    import java.io.Serial;
    import javax.swing.text.MaskFormatter;
    
    public class DateFormatter
    extends MaskFormatter {
        @Serial
        private static final long serialVersionUID = 1;
    
        @SuppressWarnings("this-escape")
        public DateFormatter() {
            try {
                setMask("####-##-##");
            } catch (ParseException e) {
                throw new RuntimeException(e);
            }
            setPlaceholder("\u2007");
        }
    
        @Override
        public Object stringToValue(String text)
        throws ParseException {
            try {
                return LocalDate.parse(text);
            } catch (DateTimeParseException e) {
                ParseException pe = new ParseException(text, e.getErrorIndex());
                pe.initCause(e);
                throw pe;
            }
        }
    }
    

    And as many others have mentioned, avoid using java.sql.Date. All JDBC drivers can use java.time.LocalDate for reading and writing SQL Date values.