Javafx Datepicker validation - datepicker

we tried to validate a javafx datepicker. So we use:
if (fromDatePicker.getValue() == null) {
sb.append("No valid from date!\n");
} else {
System.out.println(fromDatePicker.getValue().toString());
if (!DateUtil
.validEnglishDate(fromDatePicker.getValue().toString())) {
sb.append("No valid from date. Use the format yyyy-MM-dd.\n");
}
}
But at the moment it's impossible to get an invalid Date with the datepicker, because all invalid date's are changed to the start value.
So we asked us is it possible to get an invalid Date with the javafx datepicker?
***** EDIT *****
Example: we have the following datepicker:
DatePicker[2015-05-12]
now we entered "fjdfk" in the DatePicker so we have:
DatePicker[fjdfk]
on save the data's the datepicker changes automatical to DatePicker[2015-05-12]

You could use the DatePicker#setConverter(StringConverter<LocalDate>) to catch any parse exception and warn the user in consequence. Here is a sample :
public class SecureLocalDateStringConverter extends StringConverter<LocalDate> {
/**
* The date pattern that is used for conversion. Change as you wish.
*/
private static final String DATE_PATTERN = "dd/MM/yyyy";
/**
* The date formatter.
*/
public static final DateTimeFormatter DATE_FORMATTER =
DateTimeFormatter.ofPattern(DATE_PATTERN);
private boolean hasParseError = false;
public boolean hasParseError(){
return hasParseError;
}
#Override
public String toString(LocalDate localDate) {
return DATE_FORMATTER.format(localDate);
}
#Override
public LocalDate fromString(String formattedString) {
try {
LocalDate date=LocalDate.from(DATE_FORMATTER.parse(formattedString));
hasParseError=false;
return date;
} catch (DateTimeParseException parseExc){
hasParseError=true;
return null;
}
}
}
From your control, you'll just have to call converter#hasParseError(), converter being the one you set with DatePicker#setConverter(StringConverter<LocalDate>)

Related

Quarkus GraalVM native image DateTimeFormatter and Localization

I tried to use localization in java to print date with local style.
I already make a similar functionality with numbers and currencies but I failed to apply the same behavior to date.
As I learning when I posted this topics few days ago, GraalVM Quarkus Locale in native mode , use localization in native mode need to use create an "#AutomaticFeature".
This trick works for numbers and currencies :
#AutomaticFeature
public class NativeNumberFormatFeature implements Feature {
#Override
public void beforeAnalysis(BeforeAnalysisAccess access) {
ImageSingletons
.lookup(RuntimeClassInitializationSupport.class)
.initializeAtBuildTime(NumberFormatSupport.class, this.getClass().getName());
ImageSingletons.add(NumberFormatSupport.class, new NumberFormatSupport());
}
}
public class NumberFormatSupport {
private Map<Locale, NumberFormat> numberInstancesByLocale;
private Map<Locale, Map<String, NumberFormat>> currencyInstancesByLocale;
public NumberFormatSupport() {
numberInstancesByLocale = new HashMap<>();
currencyInstancesByLocale = new HashMap<>();
for (Locale locale : Locale.getAvailableLocales()) {
numberInstancesByLocale.put(locale, NumberFormat.getNumberInstance(locale));
currencyInstancesByLocale.put(locale, new HashMap<>());
for (Currency currency : Currency.getAvailableCurrencies()) {
currencyInstancesByLocale.get(locale).put(currency.getCurrencyCode(), NumberFormat.getCurrencyInstance(locale));
currencyInstancesByLocale.get(locale).get(currency.getCurrencyCode()).setCurrency(currency);
}
}
}
public NumberFormat getNumberFormat(Locale locale) {
return (NumberFormat) numberInstancesByLocale.get(locale).clone();
}
public NumberFormat getCurrencyFormat(Locale locale, Currency currency) {
return (NumberFormat) currencyInstancesByLocale.get(locale).get(currency.getCurrencyCode()).clone();
}
}
But it's not works with DateTimeFormatter :
#AutomaticFeature
public class NativeDateFormatterFeature implements Feature {
#Override
public void beforeAnalysis(BeforeAnalysisAccess access) {
ImageSingletons
.lookup(RuntimeClassInitializationSupport.class)
.initializeAtBuildTime(DateFormatterSupport.class, this.getClass().getName());
ImageSingletons.add(DateFormatterSupport.class, new DateFormatterSupport());
}
}
public class DateFormatterSupport {
private Map<Locale, DateTimeFormatter> dateTimeFormatterByLocale;
public DateFormatterSupport() {
dateTimeFormatterByLocale = Arrays.stream(Locale.getAvailableLocales()).collect(Collectors.toMap(
Function.identity(),
l -> DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM).withLocale(l)));
}
public DateTimeFormatter get(Locale locale) {
return dateTimeFormatterByLocale.get(locale);
}
}
In development mode all is ok but in native mode, locale is ignore. Style is always le same, month name isn't translate.
I was looking for a solution on google but i didn't find anything so I ask on StackOverflow.
I am at your disposal if needed.
Regards,
Stéphane.
I don't understand why, but the following solution works :
public class DateFormatterSupport {
private Map<Locale, DateTimeFormatter> dateTimeFormatterByLocale;
public DateFormatterSupport() {
dateTimeFormatterByLocale = Arrays.stream(Locale.getAvailableLocales()).collect(Collectors.toMap(
Function.identity(),
l -> DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM).withLocale(l)));
Arrays.stream(Locale.getAvailableLocales()).forEach(locale -> {
dateTimeFormatterByLocale.get(locale).format(LocalDate.now());
});
}
public DateTimeFormatter get(Locale locale) {
return dateTimeFormatterByLocale.get(locale);
}
}

How to apply a formatter to a unique form in Play 2?

My application is using Play 2.3.7.
I have a form that needs a special formatter for a date. So I do this in the method of my controller that creates the form and renders the view :
Formatters.register(Date.class, new SimpleFormatter<Date>() {
private SimpleDateFormat formatter = new SimpleDateFormat("MM/dd/yyyy");
#Override
public Date parse(String input, Locale locale) throws ParseException {
try {
return formatter.parse(input);
} catch (ParseException e) {
// We catch the error because it should be transparent for the user
Logger.error(e.getLocalizedMessage(), e);
return null;
}
}
#Override
public String print(Date input, Locale locale) {
return formatter.format(input);
}
});
The problem is that this formatter is applied globally to all my application. And my other forms are using another date format : dd/MM/yyyy HH:mm:ss (french format).
So how can I apply a formatter to only one form or at least, unregister a formatter ?
Thanks
You can use one of Formats annotations and annotate a form field as follows:
public class SampleForm {
#Formats.DateTime(pattern = "yyyy-MM-dd HH:mm:ss")
private Date date;
...
}

Jersey2 Custom Date convertor

Has anyone created a CustomConvertor class for Jersey2 to convert
ISO 8601 dates to Date /Epoch time?
I pass date as query param in ISO_8601_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"; I need to convert to epoch seconds. I have all that is necessary, I am lost in gluing it up.
I want the custom convertor to kick in once we see the DateEpochMarker interface. I use jersey 2
what is step which I am missing?
Could some one please help me out?
I have a customer Convertor, a marker Interface and resource method.
public class DateToEpochConvertor implements ParamConverter<Long> {
private static final String ISO_8601_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSZ";
#Override
public Long fromString(String value) {
DateFormat df1 = new SimpleDateFormat(ISO_8601_FORMAT);
Date date = new Date();
try {
date = df1.parse(value);
} catch (ParseException e) {
throw new WebApplicationException("The Date "+value+" is not in the ISO 8601 Format ");
}
return date.getTime();
}
#Override
public String toString(Long value) {
DateFormat df1 = new SimpleDateFormat(ISO_8601_FORMAT);
Date dt = new Date();
dt.setTime(value);
return df1.format(dt);
}
}
Marker Interface
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.PARAMETER)
public #interface DateEpochMarker {}
Resource Method
#GET
#Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
#Path("/epochtime")
public Long getEpochTime(#DateEpochMarker #QueryParam("startTime") Long startEpochTime){
return startEpochTime;
}
I feel foolish to answer my own Question.
Somehow I was not been able to make the above working, what I ended up was using custom Jodatime Convertor.
Pasting the code so that anyone stumbling upon the same query might have a answer
#Provider
public class DateTimeParamConverterProvider implements ParamConverterProvider {
private static final Logger LOGGER = org.slf4j.LoggerFactory.getLogger(DateTimeParamConverterProvider.class);
#Override
public <T> ParamConverter<T> getConverter(Class<T> type, Type genericType, Annotation[] annotations) {
if (type.equals(DateTime.class)) {
return (ParamConverter<T>) new DateTimeParamConverter();
} else {
return null;
}
}
private static class DateTimeParamConverter implements ParamConverter<DateTime> {
#Override
public DateTime fromString(String value) {
LOGGER.debug("The ISO Date that is provided is {}", value);
try {
return ISODateTimeFormat.dateTimeNoMillis().parseDateTime(value);
} catch (IllegalArgumentException e) {
return ISODateTimeFormat.dateTime().parseDateTime(value);
}
}
#Override
public String toString(DateTime value) {
return value.toString();
}
}
}

SmartGwt 2.5 DataSourceDateTimeField i18n validation error

I currently use smartGwt (version 2.5) inside an other framework (Broadleaf).
When i set the locale to french :
Date fields are well formated (DD/MM/YYYY) and the calendar is translated in french but when i change the date and save the form a popup appear with the error message :"Doit ĂȘtre une date" (Must be a date in english). The validator expect a date with MM/DD/YYYY format.
Link to the class used by the framework to create the date field : https://github.com/BroadleafCommerce/BroadleafCommerce/blob/BroadleafCommerce-2.2.x/admin/broadleaf-open-admin-platform/src/main/java/org/broadleafcommerce/openadmin/client/datasource/dynamic/module/BasicClientEntityModule.java
I found a post with same problem (forums.smartclient.com/showthread.php?t=19847) but there is no answer.
Please, let me know how to solve this problem
EDIT :
What i have tried :
#Override
public void onModuleLoad() {
DateUtil.setShortDateDisplayFormat(DateDisplayFormat.TOEUROPEANSHORTDATE);
DateUtil.setShortDateDisplayFormatter(new DateDisplayFormatter() {
#Override
public String format(Date date) {
if(date == null)
{
return null;
}
else{
final DateTimeFormat dateFormatter = DateTimeFormat.getFormat("DD/MM/YYYY");
return dateFormatter.format(date);
}
}
});
Because the code below is not allowed :
DateUtil.setShortDateDisplayFormatter(DateUtil.TOEUROPEANSHORTDATE);
I put my code during the application initialization but the problem still present :-(
Screenshot : http://www.hostingpics.net/viewer.php?id=989088date.png
Do you have an other idea?
Set date formatter of the field to DateDisplayFormat.TOEUROPEANSHORTDATE.
dateItem.setDateFormatter(DateDisplayFormat.TOEUROPEANSHORTDATE);
Also check display seconds in DateTimeItem (SmartGWT) to find another way to set a custom formatted date string when dateItem.useTextField is true.
As the forum thread indicates, its also possible to set default date/datetime format for the application using methods of com.smartgwt.client.util.DateUtil, which should be used only once, during application initialization (e.g.- EntryPoint).
DateUtil.setShortDateDisplayFormatter(DateUtil.TOEUROPEANSHORTDATE);
Problem solved !
You have to use the code below during application initialization :
private static final String DATE_FORMAT = "dd/MM/yyyy HH:mm";
public void onModuleLoad() {
DateUtil.setShortDateDisplayFormatter(new DateDisplayFormatter() {
#Override
public String format(Date date) {
if(date != null)
{
final DateTimeFormat dateFormatter = DateTimeFormat.getFormat(DATE_FORMAT);
return dateFormatter.format(date);
}
return null;
}
});
DateUtil.setDateParser(new DateParser()
{
public Date parse(String dateString)
{
try{
if(dateString != null){
final DateTimeFormat format = DateTimeFormat.getFormat(DATE_FORMAT);
return format.parse(dateString);
}
}catch(Exception e){
e.printStackTrace();
}
return null;
}
});
}

Post timestamp param as a Date for Play!Framework Models?

I'd like Play!Framework to convert a Timestamp sent via POST into a java.util.Date format in the Model, but I don't know if it's directly possible.
Here's my model :
public class Contact extends Model {
#Id
private Long id;
#Constraints.Required
private String name;
#JsonIgnore
#Temporal(TemporalType.TIMESTAMP)
private Date removed = null; // When the contact is no longer active
}
I tried to add #Formats.DateTime(pattern="?") to removed, but since DateTime use SimpleDateFormat, I wasn't able to found which pattern to use to convert a timestamp to the correct Date.
How can I do ?
Ok I'll answer myself on this, here's what I did (maybe not the best way to do it, but it works).
I don't use the Model to match the posted param to the removed value, but instead, I do this in my Controller :
String[] accepts = {"name", "datestamp"};
Form<Contact> form = Form.form(Contact.class).bindFromRequest(accepts);
Date date = null;
try {
date = new Date(Long.parseLong(form.field("datestamp").value()));
}
catch (NumberFormatException nfe) {}
if (date == null) {
form.reject("date", "error.invalid");
}
if (form.hasErrors()) {
return badRequest(form.errorsAsJson());
}
else {
Contact contact = form.get();
contact.setRemoved(date);
contact.save();
return ok();
}