突出显示时更改SWT树节点文本前景

时间:2014-01-22 09:09:38

标签: java swt jface treeviewer

我是SWT / JFace技术的新手,我发现了一个让我发疯的问题。在Eclipse RCP应用程序中,我有一个视图,其中我放置了一个带有JFace TreeViewer的SWT树,它通过标签提供程序提供标签和图标。根据客户的要求,树的背景颜色为深蓝色,字体颜色为白色。当选择节点时,这种颜色组合导致节点文本的可视化不良,文本不适合树区域,我们将鼠标指针放在节点上。不知何故,出现了“本土突出显示”。这可以在下图中看到。

enter image description here

另一方面,当我们没有选择放置鼠标的节点时,不会发生此问题。突出显示会更改字体的颜色以使其更加明显。这可以在下图中看到。

enter image description here

在做了一些研究后我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; } } } 添加一个监听器(即使没有处理事件的代码)也会产生两个新问题。

  1. 这使得SWT或JFace可以绘制树节点的图标 您可以在下图中看到错误的位置。

    enter image description here

  2. 树根节点的亮点是完全错误的。就像你一样 可以在下图中看到,该节点似乎在突出显示 2种不同的方式和图标重复。

    enter image description here

  3. 我的问题基本上是两个。

    1. 您认为主要问题有一个更简单的解决方案吗?什么 我想显示一个选定的节点(第一个图像之一) 以与第二张图像相同的方式。我想改变 所选节点的前景色,使其更加明显。

    2. 如果使用SWT.EraseItem方法,有什么办法吗? 在正确的位置显示图标?这种行为是否已知 错误?

    3. 提前致谢。

2 个答案:

答案 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的不同,计算可能会有些偏差。