The exception says the Bean Editor Model doesn't have a property called moneyDate
, which I've always thought was a bit unclear.
To explain, Tapestry doesn't know what an XMLGregorianCalendar
is, so when Tapestry creates the Bean Model for your grid, it helpfully ignores it.
Quick Solution
The quick way to solve this is to provide getters on your Money
entity that return standard JDK Calendar
s, and display these properties in your grid.
So in your entity:
public class Money {
@XmlSchemaType(name = "dateTime")
protected XMLGregorianCalendar moneyDate;
public Calendar getMoneyDataCalendar() {
return moneyDate.toGregorianCalendar();
}
...
}
Then use it in your grid:
<table t:type="grid" t:source="mylist" t:rowsPerPage="10" t:pagerPosition="both"
t:exclude="moneyId,moneyIO,moneyNextDate,moneyFinishDate,cliClientId"
t:reorder="moneyName,moneyPurpose,moneyAmount,moneyCurrency,moneyDateCalendar">
[Grid here] Note 'moneyDate' changed to 'moneyDateCalendar' above [/Grid here]
</table>
Long Solution
If you plan to display lots of XMLGregorianCalendar
s then the (more involved) solution is to tell Tapestry about XMLGregorianCalendars and how to display them.
First tell Tapestry to add XMLGregorianCalendar
to the Bean Model by adding this to your Module class:
@Contribute(DefaultDataTypeAnalyzer.class)
public static void contributeDefaultDataTypeAnalyzer(MappedConfiguration<Class<?>, String> config) {
config.add(XMLGregorianCalendar.class, "xmlGregorianCalendar");
}
Now tell Tapestry how to display the new "xmlGregorianCalendar"
. Add to your Module class:
@Contribute(BeanBlockSource.class)
public static void contributeDisplayBlocksForGrid(Configuration<BeanBlockContribution> config) {
config.add(new DisplayBlockContribution("xmlGregorianCalendar", "DisplayBlocks", "xmlGregorianCalendar"));
}
You now have to create a page called DisplayBlocks
with a component with an id xmlGregorianCalendar
:
public class DisplayBlocks {
@Inject
private Locale locale;
@Property
@Environmental
private PropertyOutputContext context;
private final DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.MEDIUM, locale);
public DateFormat getDateFormat(){
return dateFormat;
}
public Date getCalendarDate() {
XMLGregorianCalendar calendar = (XMLGregorianCalendar) context.getPropertyValue();
if (calendar == null)
return null;
return calendar.getTime();
}
}
<t:container xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd">
<t:block id="xmlGregorianCalendar">
<t:output value="calendarDate" format="dateFormat"/>
</t:block>
</t:container>
For more info look at the Tapestry source code and see how Tapestry configures itself. In particular look at:
org.apache.tapestry5.services.TapestryModule.contributeDefaultDataTypeAnalyzer()
org.apache.tapestry5.services.TapestryModule.provideDefaultBeanBlocks()
org.apache.tapestry5.corelib.pages.PropertyDisplayBlocks