-
FEATURED COMPONENTS
First time here? Check out the FAQ!
Hello:
I'm getting a "IllegalArgumentException" binding checkbox using MVVM.
org.zkoss.zel.ELException: java.lang.IllegalArgumentException
>>java.lang.IllegalArgumentException
>> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>> at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>> at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>> at java.lang.reflect.Method.invoke(Method.java:597)
>> at org.zkoss.zel.BeanELResolver.setValue(BeanELResolver.java:139)
>> at org.zkoss.zel.CompositeELResolver.setValue(CompositeELResolver.java:83)
>> at org.zkoss.zel.CompositeELResolver.setValue(CompositeELResolver.java:83)
>> at org.zkoss.xel.zel.XelELResolver.setValue(XelELResolver.java:114)
>> at org.zkoss.bind.xel.zel.BindELResolver.setValue(BindELResolver.java:102)
>> at org.zkoss.zel.impl.parser.AstValue.setValue(AstValue.java:215)
>> at org.zkoss.zel.impl.ValueExpressionImpl.setValue(ValueExpressionImpl.java:256)
>> at org.zkoss.xel.zel.ELXelExpression.setValue(ELXelExpression.java:50)
<window id="wCampaignEdit" title="Administración de campaña" border="normal" apply="org.zkoss.bind.BindComposer" viewModel="@id('vm') @init('cestel.jdialer.admin.vm.CampaignEditVM')"> ... ... <groupbox form="@id('fx') @load(vm.argData) @save(vm.argData, before='save') @save(vm.argData, before='add')" closable="false"> ... <textbox value="@bind(fx.url)" cols="20" maxlength="256" /> <checkbox checked="@bind(fx.activa)" label="Activa"/> ...
Also with "checked="@load(fx.activa)". The rest of de fields (textbox, intbox, datebox... ) works well.
Regards,
Re
Could you check the fx.activa is not null? checked is primitive, i guess if fx.activa is null then we will get IllegalArgumentException exception.
Yes. In fact, I did:
<checkbox value="@bind(fx.activa)" label="@load(fx.activa)"/>
to check fx.activa is true (I can read "true" as label).
why not post some reproducible code here, it is always easier to check with some reproducible code.
I found the problem. It's about the lifecycle because the onCreate event of the window (where the variable associated to the checkbox is initialized) runs after @Init annotated method of the VM. From what I see, the checkbox should be initialized in the @Init annotated.
Not so with the rest of bound variables and components like textbox, datebox, etc... where can be initialized before (on the onCreate method of the window).
Thank you
Regards
Hello, I am facing the error but I don't see it as a solution for my problem.
I am trying to have a listbox to select an item, and shows a window with it's detail info (one of its attributes being boolean, I am trying to use a checkbox).
I am basically doing the same thing as what's on this page (http://www.zkoss.org/zkdemo/grid/data_binding) but this one has no checkbox. If I remove the checkbox, and show the value within a textbox, it works fine.
My samplecode (zul file) :
<zk> <div apply="org.zkoss.bind.BindComposer" viewModel="@id('vm') @init('webui.vm.RestaurantsViewModel')" style="padding:10px;"> <vlayout spacing="10px" width="100%"> <listbox id="restaurantsListBox" mold="paging" pageSize="10" model="@load(vm.restaurants)" selectedItem="@bind(vm.selectedRestaurant)" onSelect='restaurantWindow.visible=true' > <listhead> <listheader label="Nom" sortAscending="@load(vm.compareByNameAsc)" sortDescending="@load(vm.compareByNameDesc)" /> </listhead> <template name="model" var="restaurant" > <listitem> <listcell label="@load(restaurant.name)" /> </listitem> </template> </listbox> <window id="restaurantWindow" visible="false" sclass="restaurant-preview" title="@load(vm.selectedRestaurant.nameFormatted)" width="100%" height="400" vflex="true" border="normal"> <checkbox id="priceLevel2" label="$$" checked="@load(vm.selectedRestaurant.priceLevel2)"></checkbox> <textbox value="@load(vm.selectedRestaurant.priceLevel2)"/> ...
The listbox allows me to select one entry, and shows its detail infos.
If I replace checkbox with the textbox, the value for "vm.selectedRestaurant.priceLevel2" shows "true".
For the ViewModel :
ublic class RestaurantsViewModel { private Restaurant selectedRestaurant; private static RestaurantDAO getRestaurantDAO() { return new RestaurantDAOImpl(); } public List<Restaurant> getRestaurants() { System.out.println("getRestaurants"); return new ArrayList<Restaurant>(getRestaurantDAO().listAll()); } public Restaurant getSelectedRestaurant() { return selectedRestaurant; } public void setSelectedRestaurant(Restaurant selectedRestaurant) { this.selectedRestaurant = selectedRestaurant; }
And the Restaurant.java is something like this :
public class Restaurant { String name; boolean priceLevel2; ... //and its getter/setters methods }
The Exception happen when loading the whole page. So at that time, "selectedItem="@bind(vm.selectedRestaurant)" is obviously null, until the user selects an item from the listbox. I guess, at that time, we get IllegalArgumentException for :
<checkbox id="priceLevel2" label="$$" checked="@load(vm.selectedRestaurantPriceLevel2)"></checkbox>
It's wierd that it works well if it's a <textbox>, <intbox>, etc. but not with <checkbox> ? Should I do it in a different way ?
note : newbie here & I am doing all within a Eclipse/Google App Engine test environment.
Quick Update : I found a workaround after reviewing one more time the example on http://www.zkoss.org/zkdemo/grid/data_binding
The main difference was that I didn't initialize "selectedRestaurant" : I had no init() method at first.
So, just for this issue with Checkbox, it seems that I have to force the listbox to have its first row preselected at load time in order to make sure the "selectedRestaurant" is not null. I don't know if its by design or if it's a bug that this behavior is needed.
My ViewModel looks like this now :
public class RestaurantsViewModel { private Restaurant selectedRestaurant; private List<Restaurant> restaurants = new ArrayList<Restaurant>(getRestaurantDAO().listAll()); @Init // Initialize public void init() { selectedRestaurant = restaurants.get(0); // Selected First One } private static RestaurantDAO getRestaurantDAO() { return new RestaurantDAOImpl(); } public List<Restaurant> getRestaurants() { System.out.println("getRestaurants"); return restaurants; } public Restaurant getSelectedRestaurant() { return selectedRestaurant; } public void setSelectedRestaurant(Restaurant selectedRestaurant) { this.selectedRestaurant = selectedRestaurant; }
looks like a value coerce issue for a null to a primitive boolean,
try this.
<checkbox id="priceLevel2" label="$$" checked="@load(vm.selectedRestaurant eq null ? false : vm.selectedRestaurant.priceLevel2)"/>
or you could write a converter for convert any object to boolean
<checkbox id="priceLevel2" label="$$" checked="@load(vm.selectedRestaurant.priceLevel2) @converter('foo.BooleanConverter')"/>
you have to write a converter, if you need to save to value back to the selected bean value. (@save(vm.selected.......))
I've hit this same problem with checkbox. I've tried adding a converter, see below, but I get an error
<checkbox label="Fixed" checked="@init(true) @load(not empty vm.selectedResource ? fx.durationFixed : true) @converter('org.zkoss.bind.converter.ObjectBooleanConverter') @save(fx.durationFixed,before='save')" />
I think it relates to http://tracker.zkoss.org/browse/ZK-1259 , which happened when using form binding.
anyway, could you post a bug with code if the case are reproducible.
Asked: 2012-06-22 08:31:52 +0800
Seen: 570 times
Last updated: Aug 06 '13