绘制 Table 的单元格背景

Paint cell background of Table

我必须对我的 Table 实施选择,为此有必要将单元格的背景绘制为蓝色(稍后可能会将前景绘制为白色,但这是未来的问题)。

天真的方法是只使用像这样的绘画事件:

table.addListener(SWT.PaintItem, event -> {
        final boolean selection = // calulate somehow;

        if (selection) {
            event.gc.setForeground(this.table.getDisplay().getSystemColor(SWT.COLOR_LIST_SELECTION));
            Rectangle bounds = table.getItem(new Point(event.x, event.y)).getBounds();
            event.gc.fillRectangle(event.x, event.y, bounds.width, bounds.height);
        }
    });

然而,这会覆盖单元格中的所有内容,我需要自己绘制 table 的全部内容。那不是我现在真正想做的。

然后我尝试使用 TableItem#setBackground(Color),它被预制的选择和悬停颜色覆盖,即使它们被禁用也是如此:

 table.addListener(SWT.EraseItem, event -> {
        event.detail &= ~SWT.SELECTED;
        event.detail &= ~SWT.HOT;
        event.detail &= ~SWT.FOCUSED;
    });

因此 OS。

选中或悬停的行显示为白色

我也尝试了 EraseItemMeasureItem,希望找到一个在绘制单元格之前抛出的事件,以便我只能绘制背景。但是 EraseItem 会覆盖所有内容,而 MeasureItem 中的绘画不会执行任何操作。

有没有什么方法可以在不必手动绘制前景或被 table 的内置选择覆盖的情况下绘制单元格的背景?

正如 greg-449 所说,StyledCellLabelProvider 可能是要走的路:

tableViewerColumn.setLabelProvider(new StyledCellLabelProvider() {

    @Override
    public void update(ViewerCell cell) {
        cell.setText("Content");

        final int column = cell.getColumnIndex();
        final int row = Arrays.asList(tableViewer.getTable().getItems()).indexOf(cell.getItem());

        if (selection) {
            Display display = cell.getControl().getDisplay();
            cell.setBackground(display .getSystemColor(SWT.COLOR_LIST_SELECTION));
            cell.setForeground(display .getSystemColor(SWT.COLOR_LIST_SELECTION_TEXT));
        }

        super.update(cell);
    }
});

这会被系统的选择和悬停覆盖,直到您添加:

table.addListener(SWT.EraseItem, event -> event.detail &= ~SWT.HOT);
table.addListener(SWT.Selection, e -> table.setSelection(-1));