【问题标题】:How to determine the correct position of an Image inside of a CTabItem如何确定 CTabItem 内图像的正确位置
【发布时间】:2015-05-11 16:36:58
【问题描述】:

我将一些CTabItems 和Images 添加到CTabFolder

CTabFolder tabFolder = new CTabFolder(someSection, SWT.BORDER);
ImageDescriptor deleteImageDesc = sharedImages.getImageDescriptor(ISharedImages.IMG_ETOOL_DELETE);
Image deleteImage = deleteImageDesc.createImage();
CTabItem tabItem = new CTabItem(tabFolder, SWT.NONE);
tabItem.setImage(deleteImage);
// add more tabs...

然后我想创建一个ToolTip,如果用户将鼠标移到deleteImage 上,它就会出现。

ToolTip deleteToolTip = new ToolTip(getShell(), SWT.BALOON);
deleteToolTip.setMessage("Delete");
tabFolder.addMouseTrackListener(new MouseTrackAdapter()
{
    @Override
    public void mouseHover(MouseEvent e)
    {
        toolTip.setLocation(tabFolder.toDisplay(e.x, e.y));
        toolTip.setVisible(doesAnyOfTabImagesContainPoint(mousePosition));
    }
});

要实现方法doesAnyOfTabImagesContainPoint,我需要确定每个deleteImage 的位置。因为CTabItem 不是Control 我不能使用方法toDisplay。我尝试通过手动确定deleteImage 相对于tabFolder 的位置来解决这个问题。这会有所帮助,因为MouseEvent 持有的鼠标位置也相对于tabFolder

private boolean doesAnyOfTabImagesContainPoint(Point p)
{
    for (CTabItem tabItem : tabFolder.getItems())
    {
        Image i = tabItem.getImage();
        Rectangle tabItemBounds = tabItem.getBounds();
        Rectangle imageBounds = i.getBounds();
        imageBounds.x += tabItemBounds.x;
        imageBounds.y += tabItemBounds.y;
        if (imageBounds.contains(p))
            return true;
    }
    return false;
}

正常工作的要求是i.getBounds() 返回的Rectangle 相对于tabItem 具有正确的位置。但是它返回的 (0, 0, 16, 16) 不可能是正确的。

解决此问题的一种肮脏方法是仅添加一些常量:

imageBounds.x += bsTabBounds.x + 4;
imageBounds.y += bsTabBounds.y + 3;

但我想知道是否有更好的方法。我正在尝试调查CTabFolder 如何定位选项卡的图像,但目前还没有成功。任何帮助,将不胜感激。提前致谢。

编辑: 出于测试目的,这是我从ISharedImages 获得的提取图像,已修改以查看其边框:

【问题讨论】:

  • 对我的回答有任何反馈吗?
  • 如果您的解决方案对我有用,我很高兴您感兴趣。抱歉耽搁了,我这周一直在度假。我在家测试了您的代码,看起来简化示例没有出现问题。但是我需要在实际应用中对此进行测试,以做出最终决定是否真的解决了问题。我会在星期一一上班就做。

标签: java swt tooltip ctabitem


【解决方案1】:

试一下下面的代码。这是基于我的回答here

public static void main(String[] args)
{
    Display display = Display.getDefault();
    final Shell shell = new Shell(display);
    shell.setLayout(new FillLayout());

    final TabFolder folder = new TabFolder(shell, SWT.NONE);

    TabItem item = new TabItem(folder, SWT.NONE);
    item.setImage(display.getSystemImage(SWT.ICON_ERROR));
    item.setText("Text");

    folder.addListener(SWT.MouseMove, event -> {
        TabFolder curFolder = (TabFolder) event.widget;
        Point eventLocation = new Point(event.x, event.y);
        TabItem theItem = curFolder.getItem(eventLocation);

        if (theItem == null)
            return;

        Image image = theItem.getImage();

        if (eventLocation.x >= curFolder.getClientArea().x + theItem.getBounds().x + image.getBounds().x
                && eventLocation.x <= curFolder.getClientArea().x + theItem.getBounds().x + image.getBounds().x + image.getBounds().width
                && eventLocation.y >= theItem.getBounds().y + image.getBounds().y
                && eventLocation.y <= theItem.getBounds().y + image.getBounds().y + image.getBounds().height)
        {
            System.out.println("show tooltip");
        }
    });


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

我已经在 Windows 7 上对其进行了测试,它似乎运行良好。

【讨论】:

  • 我调整了我的应用程序以使用您的代码,但不幸的是它不起作用。我从 org.ecrilpse.ui 中提取了使用过的图像并对其进行了修改以查看边框。这是一个屏幕截图,您可以看到工具提示出现在不应该出现的位置:i.imgur.com/ZT46ZHh.png
  • @DannyLo 这很有趣。不幸的是,我真的不明白为什么会这样。
  • 我刚刚编辑了我的问题,为该图像提供了边框,也许你可以在你的系统上测试它。
  • @DannyLo 我试了一下,但我找不到找回那些丢失的神奇 2 像素的方法。我的猜测是它是实际文件夹“左侧”的空间,但我不确定。
  • 更多好奇心:在我的应用程序内部,左边的间隙只有 1 个神奇像素。垂直间距相同:4 像素。
猜你喜欢
  • 1970-01-01
  • 2021-05-23
  • 2022-06-29
  • 1970-01-01
  • 2016-03-11
  • 1970-01-01
  • 2013-08-25
  • 2021-10-16
  • 1970-01-01
相关资源
最近更新 更多