-
FEATURED COMPONENTS
First time here? Check out the FAQ!
Hi,
we have some lists with quite huge data. We noticed that DataBinding does Loading on Demand, but we have some issues with it.
We want to show several 1000 entries per page. For that we implemented an own BindingListModel that's capable of dynamically load the data.
But it seems ZK builds an empty canvas in the background for each Item, and not only for the visible ones. So i ran into out of memory problems after a few reloads or when the list gets too big (like > 20000 records).
I prepared a sample that demonstrates my problem. You will notice that it takes some time to load it initally and if you do reloads on the page the JVM will suffer on OutOfMemory-Exceptions after the 3rd or 4th reload.
Won't it be possible to change the behaviour that there are only rows / canvases instantiated for visible items?
I think this would solve all my problems...
Any hints / comments?
Setting a pagesize to less < 5000 annoys the users and is not a real option. And there seems to be a Bug with paging: Everything is preloaded and Dynamic loading is not working any more....
Cheers,
chris
<?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit" ?> <zk> <window id="mainwin" xmlns:a="http://www.zkoss.org/2005/zk/annotation"> <zscript> public class Person { private String _name; public Person(String name) { _name = name; } public String getName() { return _name; } } public class DataLoaderModel extends AbstractListModel implements BindingListModel { //-- ListModel --// public int getSize() { return 10000; } public Object getElementAt(int j) { System.out.println(j); Person personx = new Person("Name "+j); return personx; } public void sort(Comparator cmpr, boolean ascending) {} public int indexOf(Object obj) { return 0; } } DataLoaderModel model = new DataLoaderModel(); System.out.println("Hello World"); </zscript> <div style="height: 100%; position: absolute;"> <listbox width="400px" rows="0" vflex="true" model="@{model}"> <listitem _var="@{person}"> <listcell label="@{person.name}"/> </listitem> </listbox> </div> </window> </zk>
For paging with really huge data you should handle the paging yourself.
Check the Load on Demand Smalltalk.
I prefer small pagesizes (that fit on one page) with short response time. Why do you prefer so big pages?
Note: i have also done, some growing models. They start with an initalsize and growing when the use shows a item i.e. greater 80%.
Here some running demos with 46.000 records:
Growing model with Paging
Growing model with Scrolling/Live Data
However, in my "real life" applications i avoid such huge lists. I offer filters and sortoptions, so that there is no need for such long lists.
/Robert
Hi again,
Robert inspired me a lot with the Growing Model, thanks to him ;)
But now, just over upgrading to ZK-3.5, it seems the behavior has changed. We now have the "fine" summary bar where pages can be accessed directly and the row counts are summarized.
But it doesn't seem to be able to cope with huge lists. I attached a new sample with a paging size of 50.
The attached sample with a total row count of 30000 shows for the initial view. but if an other user accesses the same page or the same user does a simple reload of the page, the VM (with standard memory settings) runs out of memory. if you increase the row count to 40000 the page never shows up...
Any hints to cope with this?
Thanks,
chris
<?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit" arg0="mainwin"?> <zk> <window id="mainwin"> <zscript> public class Person { private String _name; public Person(String name) { _name = name; } public String getName() { return _name; } } public class DataLoaderModel extends AbstractListModel implements BindingListModel { //-- ListModel --// public int getSize() { return 30000; } public Object getElementAt(int j) { System.out.println(j); Person personx = new Person("Name "+j); return personx; } public void sort(Comparator cmpr, boolean ascending) {} public int indexOf(Object obj) { return 0; } } DataLoaderModel model = new DataLoaderModel(); System.out.println("Hello World"); </zscript> <div style="height: 100%; position: absolute;"> <listbox width="400px" rows="0" vflex="true" model="@{model}" mold="paging" pageSize="50"> <listitem _var="@{person}"> <listcell label="@{person.name}"/> </listitem> </listbox> </div> </window> </zk>
Hi robertpic71 Im was loooking for a sample like your Growing model with Scrolling/Live Data.
Could you provide me the source code for the growing model with scrolling? Seems nobody wants to use anymore the paging controls but the simple scrolling is better. So the last versions of zk seems not provide that functionality.
Greetings!
Hi fidox,
The growing model with scrolling can automatically be done by ZK5, you can see the demo of the Listbox Live Data(20,000).
thank you very much, jumperchen!
I want my listbox grows all available space on the browser. So how can I use rows="0" and live-data at the same time?
By the way, seems this functionality is very unstable? I was trying with 100,000 records and I get a OutOfMemory exception. If the listbox doesn't load records until it's shown why spend a lot of time on starting to display records, and then throws OutOfMemoryExceptions?
Greetings!
Hi,
That is an issue of your server setting , in your case, each object will consume some memories but I think that nobody will design the use case like you did to load 100,000 records per session at the meantime.
Hi,
I am interested to add some more points here because i am also getting such type of error. User wants to see even >40,000 records in one page without pagination which is possible in simple html. Then why java?? Zk framework??
sample code:
java class:
package ctrl;
import java.util.*;
import org.zkoss.zk.ui.Component;
import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.util.GenericForwardComposer;
import org.zkoss.zul.*;
public class MyComposer extends GenericForwardComposer {
Listbox listbox;
Grid grid;
@Override
public void doAfterCompose(Component comp) throws Exception {
super.doAfterCompose(comp);
List<String> items2 = new ArrayList<String>();
for (int j = 0; j < 20000; ++j) {
items2.add("option " + j);
}
listbox.setItemRenderer(new ListitemRenderer() {
@Override
public void render(Listitem item, Object data) throws Exception {
if (data == null) return;
Map<String, String> params = new HashMap<String, String>();
params.put("name", (String) data);
for (int i = 0; i < 10; i++) {
Executions.createComponents("listcell.zul", item, params);
}
}
});
grid.setRowRenderer(new RowRenderer() {
@Override
public void render(Row row, Object data) throws Exception {
if (data == null) return;
String label = (String) data;
for (int i = 0; i < 10; i++) {
row.appendChild(new Toolbarbutton(label + "-" +(i + 1)));
}
}
});
ListModel list = new ListModelList(items2);
listbox.setModel(list);
grid.setModel(list);
}
}
Zul files:
index.zul:
<?xml version="1.0" encoding="UTF-8"?>
<?taglib uri="http://www.zkoss.org/dsp/web/core" prefix="c"?>
<zk xmlns="http://www.zkoss.org/2005/zul"
xmlns:n="http://www.zkoss.org/2005/zk/native">
<window width="1060px" apply="ctrl.MyComposer">
<tabbox width="1100px">
<tabs>
<tab label="Tab 0"/>
<tab label="Tab 1"/>
</tabs>
<tabpanels>
<tabpanel>
<listbox id="listbox" width="1000px" height="500px">
<listhead>
<listheader label="column1" style="width:80px" />
<listheader label="column2" style="width:80px" />
<listheader label="column3" style="width:80px" />
<listheader label="column4" style="width:80px" />
<listheader label="column5" style="width:80px" />
<listheader label="column6" style="width:80px" />
<listheader label="column7" style="width:80px" />
<listheader label="column8" style="width:80px" />
<listheader label="column9" style="width:80px" />
<listheader label="column10" style="width:80px" />
</listhead>
</listbox>
</tabpanel>
<tabpanel>
<grid id="grid" height="500px" width="1000px">
<columns>
<column label="column1" width="100px"
style="background:#FFFF80;font-weight: bold" align="center" />
<column label="column2" width="100px"
style="background:#FFFF80;font-weight: bold" align="center" />
<column label="column3" width="100px"
style="background:#FFFF80;font-weight: bold" align="center" />
<column label="column4" width="100px"
style="background:#FFFF80;font-weight: bold" align="center" />
<column label="column5" width="100px"
style="background:#FFFF80;font-weight: bold" align="center" />
<column label="column6" width="100px"
style="background:#FFFF80;font-weight: bold" align="center" />
<column label="column7" width="100px"
style="background:#FFFF80;font-weight: bold" align="center" />
<column label="column8" width="100px"
style="background:#FFFF80;font-weight: bold" align="center" />
<column label="column9" width="100px"
style="background:#FFFF80;font-weight: bold" align="center" />
<column label="column10" width="100px"
style="background:#FFFF80;font-weight: bold" align="center" />
</columns>
</grid>
</tabpanel>
</tabpanels>
</tabbox>
</window>
</zk>
listcell.zul:
<listcell>
<toolbarbutton label="${arg.name}-1" /> </listcell>
Observed:
IE6 or IE7 browser hanged and i got Outof memory exception "script error". How is it possible without pagination??? Even Renderer concept also failed here.
If it is a server related setting problem then FYI: i am using this variable in classpath: "-Xms1024m -Xmx1024m" , so how i will solve it??
Hi!
My problem is a little bit different, I don't want to show a lot of records in a listbox. Im only want to show the records to fit the screen, (30 or 40 records depending of screen resolution).
What I was trying to develop is a single CRUD of one table with 600.000 records. Oviously I don't want to show all these records in a listbox. The user have a simple filter field to lookup what he need. But I can't know the size of the datasource on every invocation. Could be 100.000 or 200.000 records, Why not?
On others frameworks (smartgwt or swing, for example) The view doesn't matter the size of the datasource, They only take the records they need to show and don't touch the others. If the user scroll, the listbox release the old records and store the new items. So we have never OutOfMemory exceptions because in most of cases we haven't more of 100 or 200 records in memory.
But seems zk do something with the datasource before display the sercods. If I increment the size of the datasource the time of listbox loading increments a lot but always show the same records. My datasource implementation is this, to avoid external issues:
public class TestListModel implements ListModel { @Override public Object getElementAt(int index) { return "value " + index; } @Override public int getSize() { return 1000; } @Override public void removeListDataListener(ListDataListener l) { } @Override public void addListDataListener(ListDataListener l) { } }
What I can't understand is because the datasource size is so important if at the end I only show 20 or 30 records?
<listbox id="usersList" rows="10"> <listhead> <listheader label="Id" width="120px" sort="auto" /> </listhead> </listbox>
At the end, what I need is develop a simple CRUD without worry about table record count. The user at the end will decide how use the filter and sortoptions provided by the application.
Hi fidox,
therefore you can use the paging mechanism and let them work on database side. There are a few smalltalks about it.
best
Stephan
Asked: 2008-09-02 16:56:48 +0800
Seen: 4,212 times
Last updated: Mar 30 '10