我是SWT / JFace技术的新手,我发现了一个让我发疯的问题。在Eclipse RCP应用程序中,我有一个视图,其中我放置了一个带有JFace TreeViewer的SWT树,它通过标签提供程序提供标签和图标。根据客户的要求,树的背景颜色为深蓝色,字体颜色为白色。当选择节点时,这种颜色组合导致节点文本的可视化不良,文本不适合树区域,我们将鼠标指针放在节点上。不知何故,出现了“本土突出显示”。这可以在下图中看到。
另一方面,当我们没有选择放置鼠标的节点时,不会发生此问题。突出显示会更改字体的颜色以使其更加明显。这可以在下图中看到。
在做了一些研究后我found通过为SWT.EraseItem
事件添加一个监听器,我可以修改所选节点的背景颜色,然后禁用选择。这允许我定义自己的选择背景样式,并禁用SWT.SELECTED
的{{1}}标志,以强制操作系统突出显示,因为未选择节点。
event.detail
这种“解决方案”可能是合理的。我看到的主要缺点是我的选择样式仅适用于Windows 7默认视觉主题。对于那些“Windows经典”或“高对比度”,我会遇到可视化问题。此外(这是最烦人的问题),为private final class EraseItemListener implements Listener {
public void handleEvent(Event event) {
// Only perform the node highlight when it is selected.
if ((event.detail & SWT.SELECTED) == SWT.SELECTED) {
// Modify background, emulate Windows highlighting.
...
// Set Windows that we do not want to draw this item as a selection (we have already highlighted the item in our way).
event.detail &= ~SWT.SELECTED;
}
}
}
添加一个监听器(即使没有处理事件的代码)也会产生两个新问题。
这使得SWT或JFace可以绘制树节点的图标 您可以在下图中看到错误的位置。
树根节点的亮点是完全错误的。就像你一样 可以在下图中看到,该节点似乎在突出显示 2种不同的方式和图标重复。
我的问题基本上是两个。
您认为主要问题有一个更简单的解决方案吗?什么 我想显示一个选定的节点(第一个图像之一) 以与第二张图像相同的方式。我想改变 所选节点的前景色,使其更加明显。
如果使用SWT.EraseItem
方法,有什么办法吗?
在正确的位置显示图标?这种行为是否已知
错误?
提前致谢。
答案 0 :(得分:2)
如果您使用基于StyledCellLabelProvider
的标签提供商(可能是基于DelegatingStyledCellLabelProvider
的标签提供商),您可以指定COLORS_ON_SELECTION
以在选择时保留正常颜色。
如果这还不够好(这里没有Windows进行测试),您可以覆盖paint
方法 - 再次尝试使用event.detail &= ~SWT.SELECTED
来禁止正常的选择处理,甚至可以处理自己画画。
答案 1 :(得分:0)
只是偶然发现了这个旧帖子,并意识到它与a bug that I opened recently on eclipse相匹配。
要使文本具有正确的颜色,我的解决方法是使用PaintListener(用SWT.PaintItem
在树中注册)以另一种颜色覆盖文本:
private static class TreePaintListener implements Listener {
@Override
public void handleEvent(Event event) {
boolean isSelected = (event.detail & SWT.SELECTED) != 0;
if (isSelected && event.item instanceof TreeItem) {
TreeItem treeItem = (TreeItem) event.item;
Tree parent = treeItem.getParent();
GC gc = event.gc;
Color foreground = null/* Some Color */;
gc.setForeground(foreground);
Rectangle imageBounds = treeItem.getImageBounds(0);
Rectangle textBounds = treeItem.getTextBounds(0);
Point stringExtent = gc.stringExtent(treeItem.getText());
int offsetX = imageBounds.width != 0 ? imageBounds.height - imageBounds.width : 0;
int offsetY = (textBounds.height - stringExtent.y) / 2;
int x = textBounds.x + offsetX;
int y = textBounds.y + offsetY;
if (gc.getClipping().contains(x, y)) {
gc.drawString(treeItem.getText(), x, y);
}
}
}
}
但是,当定义了多个列(仅绘制了第一个)时,它仍然表现不佳,并且根据操作系统和DPI的不同,计算可能会有些偏差。