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?
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;
}
}
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.
来源:https://stackoverflow.com/questions/7891025/selection-and-hover-overrides-cell-background-color-in-an-swt-table-component