[Win32] Table and Tree use light background, if disabled and EraseItem event is registered
Describe the bug For a dark theme the background color of a disabled Tree or Table is white.
To Reproduce Run this snippet on Windows and toggle the "enabled" checkbox:
import org.eclipse.swt.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;
/**
* @author Thomas Singer
*/
public class DarkControlTest {
private static final Color DARK_GRAY = new Color(32, 32, 32);
private static final Color LIGHT_GRAY = new Color(200, 200, 200);
public static void main(String[] args) {
final Display display = new Display();
display.addListener(SWT.Skin, event -> {
if (event.widget instanceof Control control) {
control.setBackground(DARK_GRAY);
control.setForeground(LIGHT_GRAY);
if (control instanceof Table table) {
table.setHeaderBackground(DARK_GRAY);
table.setHeaderForeground(LIGHT_GRAY);
}
if (control instanceof Tree tree) {
tree.setHeaderBackground(DARK_GRAY);
tree.setHeaderForeground(LIGHT_GRAY);
}
}
});
final Shell shell = new Shell(display);
shell.setLayout(new GridLayout(2, true));
final Control table = createTable(shell);
final Control tree = createTree(shell);
final Button checkbox = new Button(shell, SWT.CHECK);
checkbox.setLayoutData(new GridData(SWT.BEGINNING, SWT.BEGINNING, false, false));
checkbox.setText("enabled");
checkbox.setSelection(true);
checkbox.addListener(SWT.Selection, event -> {
table.setEnabled(checkbox.getSelection());
tree.setEnabled(checkbox.getSelection());
});
shell.setSize(400, 300);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
private static Table createTable(Composite parent) {
final Table table = new Table(parent, SWT.BORDER);
table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
table.setHeaderVisible(true);
table.addListener(SWT.EraseItem, event -> {
final Rectangle clientArea = table.getClientArea();
event.gc.fillRectangle(clientArea.x, event.y, clientArea.width, event.height);
event.detail &= ~(SWT.FOREGROUND | SWT.BACKGROUND | SWT.HOT | SWT.SELECTED);
});
table.addListener(SWT.PaintItem, event -> {
event.gc.drawText(((Item)event.item).getText(), event.x, event.y);
});
final TableColumn column = new TableColumn(table, SWT.LEFT);
column.setText("Column");
column.setWidth(150);
new TableItem(table, SWT.LEFT).setText("Item 1");
new TableItem(table, SWT.LEFT).setText("Item 2");
return table;
}
private static Tree createTree(Composite parent) {
final Tree tree = new Tree(parent, SWT.BORDER);
tree.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
tree.setHeaderVisible(true);
tree.addListener(SWT.EraseItem, event -> {
event.gc.setClipping((Rectangle)null);
final Rectangle clientArea = tree.getClientArea();
event.gc.fillRectangle(clientArea.x, event.y, clientArea.width, event.height);
event.detail &= ~(SWT.FOREGROUND | SWT.BACKGROUND | SWT.HOT | SWT.SELECTED);
});
tree.addListener(SWT.PaintItem, event -> {
event.gc.drawText(((Item)event.item).getText(), event.x, event.y);
});
new TreeItem(tree, SWT.LEFT).setText("Item 1");
new TreeItem(tree, SWT.LEFT).setText("Item 2");
return tree;
}
}
Expected behavior In both cases, enabled and disabled, the set background color should be used.
Screenshots
enabled:
disabled:
Environment:
- Select the platform(s) on which the behavior is seen:
-
- [ ] All OS
-
- [x] Windows
-
- [ ] Linux
-
- [ ] macOS
Hi @tmssngr I tried a slight modification in your program as below
import org.eclipse.swt.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.widgets.*;
/**
* @author Thomas Singer
*/
public class DarkControlTest {
private static final Color DARK_GRAY = new Color(32, 32, 32);
private static final Color LIGHT_GRAY = new Color(200, 200, 200);
public static void main(String[] args) {
final Display display = new Display();
display.addListener(SWT.Skin, event -> {
if (event.widget instanceof Control control) {
control.setBackground(DARK_GRAY);
control.setForeground(LIGHT_GRAY);
if (control instanceof Table table) {
// table.setHeaderBackground(DARK_GRAY);
// table.setHeaderForeground(LIGHT_GRAY);
System.out.println(table.getBackground().getRGB() + "Before : table.getBackground().getRGB()");
table.setHeaderBackground(table.getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY));
table.setHeaderForeground(table.getDisplay().getSystemColor(SWT.COLOR_GRAY));
table.setBackground(table.getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY));
table.setForeground(table.getDisplay().getSystemColor(SWT.COLOR_GRAY));
System.out.println(table.getBackground().getRGB() + "After : table.getBackground().getRGB()");
}
if (control instanceof Tree tree) {
// tree.setHeaderBackground(DARK_GRAY);
// tree.setHeaderForeground(LIGHT_GRAY);
System.out.println(tree.getBackground().getRGB()+ "Before : tree.getBackground().getRGB()");
tree.setHeaderBackground(tree.getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY));
tree.setHeaderForeground(tree.getDisplay().getSystemColor(SWT.COLOR_GRAY));
tree.setBackground(tree.getDisplay().getSystemColor(SWT.COLOR_DARK_GRAY));
tree.setForeground(tree.getDisplay().getSystemColor(SWT.COLOR_GRAY));
System.out.println(tree.getBackground().getRGB()+ "After : tree.getBackground().getRGB()");
}
}
});
final Shell shell = new Shell(display);
shell.setLayout(new GridLayout(2, true));
final Control table = createTable(shell);
final Control tree = createTree(shell);
System.out.println(table.getBackground().getRGB() + "Just Created : table.getBackground().getRGB()");
System.out.println(tree.getBackground().getRGB()+ "Just Created : tree.getBackground().getRGB()");
final Button checkbox = new Button(shell, SWT.CHECK);
checkbox.setLayoutData(new GridData(SWT.BEGINNING, SWT.BEGINNING, false, false));
checkbox.setText("enabled");
checkbox.setSelection(true);
checkbox.addListener(SWT.Selection, event -> {
table.setEnabled(checkbox.getSelection());
tree.setEnabled(checkbox.getSelection());
});
shell.setSize(400, 300);
shell.open();
while (!shell.isDisposed()) {
if (!display.readAndDispatch()) {
display.sleep();
}
}
display.dispose();
}
private static Table createTable(Composite parent) {
final Table table = new Table(parent, SWT.BORDER);
table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
table.setHeaderVisible(true);
table.addListener(SWT.EraseItem, event -> {
final Rectangle clientArea = table.getClientArea();
event.gc.fillRectangle(clientArea.x, event.y, clientArea.width, event.height);
event.detail &= ~(SWT.FOREGROUND | SWT.BACKGROUND | SWT.HOT | SWT.SELECTED);
});
table.addListener(SWT.PaintItem, event -> {
event.gc.drawText(((Item)event.item).getText(), event.x, event.y);
});
final TableColumn column = new TableColumn(table, SWT.LEFT);
column.setText("Column");
column.setWidth(150);
new TableItem(table, SWT.LEFT).setText("Item 1");
new TableItem(table, SWT.LEFT).setText("Item 2");
return table;
}
private static Tree createTree(Composite parent) {
final Tree tree = new Tree(parent, SWT.BORDER);
tree.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
tree.setHeaderVisible(true);
tree.addListener(SWT.EraseItem, event -> {
event.gc.setClipping((Rectangle)null);
final Rectangle clientArea = tree.getClientArea();
event.gc.fillRectangle(clientArea.x, event.y, clientArea.width, event.height);
event.detail &= ~(SWT.FOREGROUND | SWT.BACKGROUND | SWT.HOT | SWT.SELECTED);
});
tree.addListener(SWT.PaintItem, event -> {
event.gc.drawText(((Item)event.item).getText(), event.x, event.y);
});
new TreeItem(tree, SWT.LEFT).setText("Item 1");
new TreeItem(tree, SWT.LEFT).setText("Item 2");
return tree;
}
}
Slight modifications done in display.addListener(), not much. My observation here is as below corresponds to RGB {255, 255, 255}Just Created : table.getBackground().getRGB() - white corresponds to RGB {128, 128, 128}After : table.getBackground().getRGB() - light gray corresponds to RGB {32, 32, 32}Before : table.getBackground().getRGB() - dark gray corresponds to RGB {0, 0, 0}Before : table.getBackground().getRGB() - black
So from this atleast i feel when first created all the widgets get background(white) then when skin is applied respective theme gets applied. On top of it as you set with setBackground gets applied.
Can you try this and see what you want can be achieved or not?
fyi : I tried to map colors from ControlExample -> Tree/Table -> change background "change" custom color palatte.
Sorry, I don't understand what you suggest. Your change only sets different gray colors, the problem remains.