8

I'm using SWT (and Eclipse RCP) to render a table. My problem is that if I change the background of a cell (a ViewerCell in fact) I can see that it has the new color.

My problem is that if I select a row in my Table or if I hover over the row containing my cell in question then the selection/hover background overrides my cell color. How can I override this?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Adam Arold
  • 29,285
  • 22
  • 112
  • 207

2 Answers2

3

Problem solved with StyledCellLabelProvider. Tell me if you want to see some code. Edit: We use it do display validation errors so ignore the validation stuff here:

public class ValidationCellLabelProvider extends StyledCellLabelProvider {

    private static final int DELAY = 200;
    private static final int SHIFT_X = 5;
    private static final int SHIFT_Y = 5;
    private static final int DISPLAY = 5000;
    private CellLabelProvider provider;
    private String propertyName;
    private final StyleRange[] styleRanges = new StyleRange[1];

    /**
     * Default constructor.
     * @param provider provider
     * @param propertyName propertyName
     */
    public ValidationCellLabelProvider(CellLabelProvider provider, String propertyName) {
        super(StyledCellLabelProvider.COLORS_ON_SELECTION);
        this.provider = provider;
        this.propertyName = propertyName;
        this.setOwnerDrawEnabled(true);
    }

    @Override
    public void initialize(ColumnViewer viewer, ViewerColumn column) {
        super.initialize(viewer, column);
        final StyleRange styleRange = new StyleRange();
        styleRange.foreground = Display.getCurrent().getSystemColor(SWT.COLOR_WHITE);
        styleRange.background = Display.getCurrent().getSystemColor(SWT.COLOR_RED);
        styleRanges[0] = styleRange;
    }

    @Override
    public void update(ViewerCell cell) {
        provider.update(cell);
        if (cell.getStyleRanges() == null) {
            cell.setStyleRanges(styleRanges);
        }
        if (cell.getElement() instanceof IValidable) {
            IValidable model = (IValidable) cell.getElement();
            if (!ControllerRegistry.getCurrentViolations().getViolations(model.getModelId(), propertyName).isEmpty()) {
                if (cell.getText().isEmpty()) {
                    cell.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_RED));
                    cell.setImage(FieldDecorationRegistry.getDefault().getFieldDecoration(FieldDecorationRegistry.DEC_ERROR).getImage());
                } else {
                    if (styleRanges[0].length < cell.getText().length()) {
                        styleRanges[0].length = cell.getText().length();
                    }
                }
            } else {
                if (cell.getImage() != null) {
                    cell.setImage(null);
                }
                cell.setStyleRanges(null);
            }
        }
        super.update(cell);
    }

    //mine
    @Override
    protected void paint(Event event, Object element) {
        if (element instanceof IValidable) {
            IValidable model = (IValidable) element;
            if (!ControllerRegistry.getCurrentViolations().getViolations(model.getModelId(), propertyName).isEmpty()) {
                int width = 1000;
                int x = event.x;
                int y = event.y;

                int height = event.height - 1;
                GC gc = event.gc;

                Color oldBackground = gc.getBackground();

                gc.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_DARK_RED));

                gc.fillRectangle(x, y, width, height);

                gc.setBackground(oldBackground);
            }
        }
        super.paint(event, element);
    }

    //-----

    @Override
    public String getToolTipText(Object element) {
        String ret = null;
        if (element instanceof IValidable) {
            List<ConstraintViolation> constraintViolations = ControllerRegistry.getCurrentViolations().getViolations(
                    ((IValidable) element).getModelId(), propertyName);
            if (!constraintViolations.isEmpty()) {
                ret = ValidationHelper.getMessage(constraintViolations);
            }
        }
        if (ret != null) {
            ret = ret.length() > 0 ? ret.toString() : null;
        }
        return ret;
    }

    @Override
    public int getToolTipDisplayDelayTime(Object object) {
        return DELAY;
    }

    @Override
    public Point getToolTipShift(Object object) {
        return new Point(SHIFT_X, SHIFT_Y);
    }

    @Override
    public int getToolTipTimeDisplayed(Object object) {
        return DISPLAY;
    }

}
Adam Arold
  • 29,285
  • 22
  • 112
  • 207
0

The only option I see would be use an OwnerDrawLabelProvider and paint the whole cell yourself.

There is a way to prevent the table from drawing its selection background but the font color will still change to its selection color, so depending on your OS you might end up with white text on white background when a row is selected.

Frettman
  • 2,251
  • 1
  • 13
  • 9
  • It seems that I solved the problem with StyledCellLabelProvider. I will provide the solution if I finish with it. – Adam Arold Oct 27 '11 at 13:37