Hello, I was trying to have a list of a million items. I tried with a simple JList:
new JList(new AbstractListModel() {
public int getSize() {
return 1,000,000;
}
public String getElementAt(int i) {
return "Item #" + i;
}
};
It takes about 3 seconds for the list to pop up on my computer (P4 2.4GHz, 1G RAM, command: java -Xmx512m BigList), once I add a simple renderer for this JList, it takes over 7 seconds -- This quite surprises me, as I don't see this happening for JTable, it both take about 3 seconds for a simple 1,000,000-row JTable with and without a simple renderer.
The renderers are simple as this:
SimpleRenderer extends JLabel implements ListCellRenderer {
public Component getListCellRendererComponent(...) {
this.setText((String) value);
return this;
}
}
In my project, I need to use list instead of table, and I don't understand why JList suffers with a simple renderer. I heard that SWT/JFace is super fast compared with AWT/Swing, so I gave it a try.
However, after several hours of googling and writing small snippets, I found that it seems SWT/JFace is much worse in this one million test.
It seems that SWT can only handle about 100,000 items, and it runs over 20 seconds to bring out the list. I trid 1,000,000 with it, the list never show up, and the keeps a 100% cpu usage forever.
I read the source code, and found that SWT list simply push the list.add(String) operation to the OS:
OS.SendMessage (handle, OS.LB_ADDSTRING, 0, buffer);
Then I tried to use the MVC approach of SWT/JFace and looked into ListViewer, I had no luck either, the result is the same. I did't find a flexible way to specify a list using a model as flexible as Swing's ListModel, instead, I had to use this:
listViewer = new ListViewer(shell, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION);
listViewer.setContentProvider(new IStructuredContentProvider() {
public Object[] getElements(Object input) {
String[] strs = new String[100000];
for (int i = 0; i < strs.length; i ++) {
strs[i] = "Pets " + i;
}
return strs;
}
}
It's really painful that the IContentProvider always expect me to specify an array, isn't this stiff? I want to just tell it how many items there are and give it an simple algorithm to calculate the labels based on the item indices, but I didn't find a way to do that.
Is SWT/JFace really slow, or there are other APIs in it that I'm not aware of? I'm quite a newbie to SWT/JFace, and the only tutorial I got is by googling and the API reference that comes with Eclipse.
Also, does anyone have a hint why JList performs bad when a simple custom renderer is added while JTable doesn't have this problem?
Thanks
Johan
new JList(new AbstractListModel() {
public int getSize() {
return 1,000,000;
}
public String getElementAt(int i) {
return "Item #" + i;
}
};
It takes about 3 seconds for the list to pop up on my computer (P4 2.4GHz, 1G RAM, command: java -Xmx512m BigList), once I add a simple renderer for this JList, it takes over 7 seconds -- This quite surprises me, as I don't see this happening for JTable, it both take about 3 seconds for a simple 1,000,000-row JTable with and without a simple renderer.
The renderers are simple as this:
SimpleRenderer extends JLabel implements ListCellRenderer {
public Component getListCellRendererComponent(...) {
this.setText((String) value);
return this;
}
}
In my project, I need to use list instead of table, and I don't understand why JList suffers with a simple renderer. I heard that SWT/JFace is super fast compared with AWT/Swing, so I gave it a try.
However, after several hours of googling and writing small snippets, I found that it seems SWT/JFace is much worse in this one million test.
It seems that SWT can only handle about 100,000 items, and it runs over 20 seconds to bring out the list. I trid 1,000,000 with it, the list never show up, and the keeps a 100% cpu usage forever.
I read the source code, and found that SWT list simply push the list.add(String) operation to the OS:
OS.SendMessage (handle, OS.LB_ADDSTRING, 0, buffer);
Then I tried to use the MVC approach of SWT/JFace and looked into ListViewer, I had no luck either, the result is the same. I did't find a flexible way to specify a list using a model as flexible as Swing's ListModel, instead, I had to use this:
listViewer = new ListViewer(shell, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION);
listViewer.setContentProvider(new IStructuredContentProvider() {
public Object[] getElements(Object input) {
String[] strs = new String[100000];
for (int i = 0; i < strs.length; i ++) {
strs[i] = "Pets " + i;
}
return strs;
}
}
It's really painful that the IContentProvider always expect me to specify an array, isn't this stiff? I want to just tell it how many items there are and give it an simple algorithm to calculate the labels based on the item indices, but I didn't find a way to do that.
Is SWT/JFace really slow, or there are other APIs in it that I'm not aware of? I'm quite a newbie to SWT/JFace, and the only tutorial I got is by googling and the API reference that comes with Eclipse.
Also, does anyone have a hint why JList performs bad when a simple custom renderer is added while JTable doesn't have this problem?
Thanks
Johan