Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 344279 - Table: BackgroundColor is ignored after removing Listener to PaintItem / MeasureItem in combination with setRedraw
Summary: Table: BackgroundColor is ignored after removing Listener to PaintItem / Meas...
Status: CLOSED WONTFIX
Alias: None
Product: Platform
Classification: Eclipse Project
Component: SWT (show other bugs)
Version: 3.6.2   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: Platform-SWT-Inbox CLA
QA Contact:
URL:
Whiteboard: stalebug
Keywords:
Depends on:
Blocks:
 
Reported: 2011-04-29 09:46 EDT by Markus Kuhn CLA
Modified: 2019-11-14 02:22 EST (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Markus Kuhn CLA 2011-04-29 09:46:15 EDT
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();
   }
}
Comment 1 Markus Kuhn CLA 2011-04-29 09:53:34 EDT
WORKAROUND:
Call setRedraw(true) before calling removeListener for PaintItem/MeasureItem.
Comment 2 Lars Vogel CLA 2019-11-14 02:22:51 EST
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.