Community
Participate
Working Groups
Calling getBounds was slow in 3.3.2 already, but we were not calling it. We are now calling getBounds from our owner draw code to force a repaint of a cell (and sometimes, we are doing it for every cell). We could avoid calling getBounds if you can promise us a repaint as a result of calling setText (with a different text).
It appears that the time is mainly spent on line 249 of TableItem.java: if (parent.fixScrollWidth) parent.setScrollWidth (null, true); (Caveat: I have come to this conclusion by poor man's profiling aka random sampling - pausing the debugger every now and then while waiting for the code to run.)
How many items were in the list, 2000?
Boris, we need to construct a benchmark. This code is NOT slow (but it's a start): import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Table; import org.eclipse.swt.widgets.TableItem; public class PR_228285 { public static void main(String[] args) { Display display = new Display(); Shell shell = new Shell(display); shell.setLayout(new GridLayout(1, false)); Table table = new Table(shell, SWT.SINGLE | SWT.FULL_SELECTION); table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); table.setLinesVisible(true); table.setHeaderVisible(true); table.addListener(SWT.MeasureItem, new Listener(){ public void handleEvent(Event event) { } }); table.addListener(SWT.EraseItem, new Listener(){ public void handleEvent(Event event) { } }); table.addListener(SWT.PaintItem, new Listener(){ public void handleEvent(Event event) { } }); Color blue = display.getSystemColor(SWT.COLOR_BLUE); for (int i = 0; i < 2000; i++) { TableItem tableItem = new TableItem(table, SWT.NONE); tableItem.setText("Fred"); tableItem.setForeground(blue); } shell.setSize(400, 800); shell.open(); long t1 = System.currentTimeMillis(); for (int i = 0; i < 2000; i++) { table.getItem (i).getBounds (); } long t2 = System.currentTimeMillis(); System.out.println(t2 - t1); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } display.dispose(); } }
Never mind, this code shows the problem (is this what JFace is doing)? public class PR_228285 { public static void main(String[] args) { Display display = new Display(); Shell shell = new Shell(display); shell.setLayout(new GridLayout(1, false)); Table table = new Table(shell, SWT.SINGLE | SWT.FULL_SELECTION); table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); table.setLinesVisible(true); table.setHeaderVisible(true); table.addListener(SWT.MeasureItem, new Listener(){ public void handleEvent(Event event) { } }); table.addListener(SWT.EraseItem, new Listener(){ public void handleEvent(Event event) { } }); table.addListener(SWT.PaintItem, new Listener(){ public void handleEvent(Event event) { } }); long t1 = System.currentTimeMillis(); Color blue = display.getSystemColor(SWT.COLOR_BLUE); for (int i = 0; i < 2000; i++) { TableItem tableItem = new TableItem(table, SWT.NONE); tableItem.setText("Fred"); tableItem.setForeground(blue); table.getItem (i).getBounds (); } long t2 = System.currentTimeMillis(); System.out.println(t2 - t1); shell.setSize(400, 800); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) display.sleep(); } display.dispose(); } }
(In reply to comment #2) > How many items were in the list, 2000? yes.(In reply to comment #4) > Never mind, this code shows the problem (is this what JFace is doing)? Yes, it looks very close to what JFace is doing in that case.
Not sure there's much I can do here. The trade off is between diffing the current item width every time anything affecting the item is changed and measuring the string multiple times or remembering that the bounds are wrong and computing it once when needed.
(In reply to comment #0) > We could avoid calling getBounds if you can promise us a repaint as a result of > calling setText (with a different text). Given that it does not look like you will be able to optimize getBounds(), could you look into promising a repaint upon calling setText()?
This bug hasn't had any activity in quite some time. Maybe the problem got resolved, was a duplicate of something else, or became less pressing for some reason - or maybe it's still relevant but just hasn't been looked at yet. If you have further information on the current state of the bug, please add it. The information can be, for example, that the problem still occurs, that you still want the feature, that more information is needed, or that the bug is (for whatever reason) no longer relevant.