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
JFormattedTextField with a DateFormatter
and yyyy-MM-dd
pattern
Works, but requires the user to manually type the dashes, or parsing fails.
MaskFormatter ("####-##-##")
Enforces the visual format but accepts invalid dates like 3202-15-59
.
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.