| Summary: | Table: BackgroundColor is ignored after removing Listener to PaintItem / MeasureItem in combination with setRedraw | ||
|---|---|---|---|
| Product: | [Eclipse Project] Platform | Reporter: | Markus Kuhn <markus.kuhn> |
| Component: | SWT | Assignee: | Platform-SWT-Inbox <platform-swt-inbox> |
| Status: | CLOSED WONTFIX | QA Contact: | |
| Severity: | normal | ||
| Priority: | P3 | ||
| Version: | 3.6.2 | ||
| Target Milestone: | --- | ||
| Hardware: | PC | ||
| OS: | Windows XP | ||
| Whiteboard: | stalebug | ||
WORKAROUND: Call setRedraw(true) before calling removeListener for PaintItem/MeasureItem. 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. If the bug is still relevant, please remove the "stalebug" whiteboard tag. |
Build Identifier: 3659 The background of the Table is white, instead of the set background color. This happens under the following conditions: (1) App does "Custom Draw" of some TableItems. (2) If last TableItem, which needs "Custom Draw" is removed, the Listener to the events “PaintItem” and “MeasureItem” is removed. (3) The removing of the TableItem and Listener is done while the redraw is disabled. Reproducible: Always Steps to Reproduce: Run modified Snippet 230, which adds/removes "Custom Draw" TableItem every second. If "Custom Draw" TableItem is removed, the background is white instead of gray. -------------------------------- package org.eclipse.swt.snippets; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.layout.FillLayout; 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.TableColumn; import org.eclipse.swt.widgets.TableItem; /** * */ public class Snippet230R { public static void main (final String[] args) { System.out.println("SWT Version " + SWT.getVersion()); final Display display = new Display(); final Image image = display.getSystemImage(SWT.ICON_INFORMATION); final Shell shell = new Shell(display); shell.setText("Images on the right side of the TableItem"); shell.setLayout(new FillLayout()); final Table table = new Table(shell, SWT.MULTI | SWT.FULL_SELECTION); table.setHeaderVisible(true); table.setLinesVisible(true); table.setBackground(display.getSystemColor(SWT.COLOR_GRAY)); final int columnCount = 3; for (int i = 0; i < columnCount; i++) { final TableColumn column = new TableColumn(table, SWT.NONE); column.setText("Column " + i); } final int itemCount = 3; for (int i = 0; i < itemCount; i++) { final TableItem item = new TableItem(table, SWT.NONE); item.setText(new String[] {"item " + i + " a", "item " + i + " b", "item " + i + " c"}); } /* * NOTE: MeasureItem, PaintItem and EraseItem are called repeatedly. * Therefore, it is critical for performance that these methods be * as efficient as possible. */ final Listener paintListener = new Listener() { public void handleEvent (final Event event) { final Image image = (Image) event.item.getData(); if (image != null) { switch (event.type) { case SWT.MeasureItem: { final Rectangle rect = image.getBounds(); event.width += rect.width; event.height = Math.max(event.height, rect.height + 2); break; } case SWT.PaintItem: { final int x = event.x + event.width; final Rectangle rect = image.getBounds(); final int offset = Math.max(0, (event.height - rect.height) / 2); event.gc.drawImage(image, x, event.y + offset); break; } } } } }; display.timerExec(1000, new Runnable() { @Override public void run () { // switching off redraw, because in real app, big number of items may be added table.setRedraw(false); if (table.getItemCount() > itemCount) { // removing the TableItem, which contains the custom drawn image table.remove(1); // remove the listener, because custom drawn no longer needed table.removeListener(SWT.MeasureItem, paintListener); table.removeListener(SWT.PaintItem, paintListener); } else { // adding the TableItem, which contains the custom drawn image final TableItem item = new TableItem(table, SWT.NONE, 1); item.setText(new String[] {"a", "b", "c"}); item.setBackground(display.getSystemColor(SWT.COLOR_YELLOW)); item.setData(image); // setting the image which is drawn // add the listener, because custom drawn is needed table.addListener(SWT.MeasureItem, paintListener); table.addListener(SWT.PaintItem, paintListener); } table.setRedraw(true); display.timerExec(1000, this); } }); for (int i = 0; i < columnCount; i++) { table.getColumn(i).pack(); } shell.setSize(500, 500); shell.open(); while (!shell.isDisposed()) { if (!display.readAndDispatch()) { display.sleep(); } } if (image != null) { image.dispose(); } display.dispose(); } }