微调器未正确重绘

Spinner Is Not Correctly Redrawn

我有一个奇怪的案例,SWT 微调器拒绝重绘。

我在下面添加了一个工作示例。虽然在每次单击按钮时都会调用绘制侦听器,但在将鼠标移到微调器控件上之前,显示的内容不会发生变化。 (此外,如果鼠标悬停在小箭头上,文本“”也会绘制在那里。)

Display display = new Display();
Shell shell = new Shell(display);
shell.setLayout(new FillLayout());

Spinner spinner = new Spinner(shell, SWT.BORDER);
spinner.addListener(SWT.Paint, e -> {
    if ("overlay".equals(spinner.getData("test")) && !spinner.isFocusControl()) {
    e.gc.setForeground(display.getSystemColor(SWT.COLOR_DARK_GRAY));
    e.gc.drawText("<overlay>", 0, 0, false);
    }
});

Button button = new Button(shell, SWT.PUSH);
button.setText("Overlay!");
button.addListener(SWT.Selection, e -> {
    spinner.setData("test", "overlay");
    spinner.redraw();
});

button = new Button(shell, SWT.PUSH);
button.setText("Remove");
button.addListener(SWT.Selection, e -> {
    spinner.setData("test", null);
    spinner.redraw();
});

shell.setSize(300, 80);
shell.open();

while (!shell.isDisposed()) {
    if (!display.readAndDispatch()) {
        display.sleep();
    }
}
display.dispose();

如果您插入 Text 小部件,一切都会按预期进行。那么 Spinner 有什么问题呢?

(我正在构建 SWT 3.7)

正如@greg-449 评论的那样,控件不应该被 PaintListeners 绘制。在大多数情况下,这会干扰 window 系统绘制的内容。

如果你想要一个叠加层,你可能想尝试将 Canvas 放置在 Spinner 的客户区之上,然后在其上绘制。

覆盖控件必须从父布局中排除,例如使用 GridData#exclude 或使用 FormLayout.

另一个需要处理的障碍可能是发送到覆盖控件但可能需要转发到 Spinner 的鼠标事件。

当然还有在 Spinner 失去或获得焦点时显示和隐藏叠加控件的 FocusListeners。