Jface TreeViewer Tooltip消失过快,如何延长显示时长?
Jface TreeViewer自定义Tooltip在Linux下消失过快的解决方法
问题背景
使用Eclipse Jface开发Java项目,实现TreeViewer树项悬停时显示自定义Tooltip,Windows系统运行正常,但Linux(RH8)环境下Tooltip消失过快。已迁移至Java11,无法回退至旧版Jface 3.8.0,尝试过Jface 3.15~3.27版本、MouseEnter/MouseMove监听器、延长隐藏延迟等方案均未解决问题。
可行解决方案
1. 重写ToolTip的getHideDelay方法,强制覆盖GTK限制
GTK环境下SWT ToolTip的隐藏延迟可能被系统主题或GTK机制覆盖,重写getHideDelay方法可绕过该限制,同时改用MouseMove监听器持续重置计时器:
private void createBasicToolTip(TreeViewer viewer) { ToolTip tooltip = new ToolTip(viewer.getTree()) { @Override protected Composite createToolTipContentArea(Event event, Composite parent) { Composite composite = new Composite(parent, SWT.NONE); composite.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_GRAY)); composite.setLayout(new FillLayout()); TreeItem item = viewer.getTree().getItem(new Point(event.x, event.y)); if (item != null && item.getData() != null) { Label label = new Label(composite, SWT.NONE); label.setText((String) item.getData()); label.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_GRAY)); } return composite; } // 强制返回自定义隐藏时长,不受GTK系统设置影响 @Override public int getHideDelay() { return 5000; // 固定5秒显示时长 } }; tooltip.setPopupDelay(500); tooltip.setHideDelay(5000); tooltip.setShift(new Point(-5, -5)); // 鼠标移动时持续触发Tooltip,重置隐藏计时器 viewer.getTree().addListener(SWT.MouseMove, event -> { Point point = new Point(event.x, event.y); TreeItem item = viewer.getTree().getItem(point); if (item == null || item.getData() == null) { tooltip.hide(); } else { tooltip.show(point); } }); }
2. 自定义Shell模拟Tooltip,完全控制显示逻辑
如果Jface ToolTip的GTK限制无法绕过,可自行创建Shell作为自定义Tooltip,完全掌控显示/隐藏时机:
private Shell customTooltipShell; private TreeItem currentHoverItem; private void createCustomToolTip(TreeViewer viewer) { Tree tree = viewer.getTree(); Display display = tree.getDisplay(); // 创建无焦点、置顶的Tooltip Shell customTooltipShell = new Shell(tree.getShell(), SWT.ON_TOP | SWT.NO_FOCUS | SWT.TOOL); customTooltipShell.setBackground(display.getSystemColor(SWT.COLOR_INFO_BACKGROUND)); FillLayout layout = new FillLayout(); layout.marginWidth = 5; layout.marginHeight = 5; customTooltipShell.setLayout(layout); Label tooltipLabel = new Label(customTooltipShell, SWT.NONE); tooltipLabel.setForeground(display.getSystemColor(SWT.COLOR_INFO_FOREGROUND)); tooltipLabel.setBackground(display.getSystemColor(SWT.COLOR_INFO_BACKGROUND)); // 鼠标移动时更新Tooltip内容和位置 tree.addListener(SWT.MouseMove, event -> { Point point = new Point(event.x, event.y); TreeItem item = tree.getItem(point); if (item == null || item.getData() == null) { hideCustomTooltip(); currentHoverItem = null; return; } if (currentHoverItem != item) { currentHoverItem = item; tooltipLabel.setText((String) item.getData()); customTooltipShell.pack(); // 计算显示位置(偏移鼠标位置) Point treeLocation = tree.toDisplay(point); customTooltipShell.setLocation(treeLocation.x + 10, treeLocation.y + 10); showCustomTooltip(); } }); // 鼠标离开树控件时隐藏Tooltip tree.addListener(SWT.MouseExit, event -> { hideCustomTooltip(); currentHoverItem = null; }); } private void showCustomTooltip() { if (!customTooltipShell.isVisible()) { customTooltipShell.setVisible(true); // 延迟5秒自动隐藏 customTooltipShell.getDisplay().timerExec(5000, () -> { if (!customTooltipShell.isDisposed()) { customTooltipShell.setVisible(false); } }); } } private void hideCustomTooltip() { if (customTooltipShell.isVisible()) { customTooltipShell.setVisible(false); } }
3. 修改Linux GTK系统配置
若允许调整系统设置,可通过修改GTK配置文件全局调整Tooltip时长:
- 创建或编辑
~/.config/gtk-3.0/settings.ini文件,添加以下内容:
[Settings] gtk-tooltip-delay=500 # 弹出延迟(毫秒) gtk-tooltip-timeout=5000 # 显示时长(毫秒)
- 保存后重启应用生效
内容的提问来源于stack exchange,提问作者Etienne
相关产品推荐
相关产品推荐

