JFace TableViewer 上的本机工具提示无法正常工作

Native tooltips on JFace TableViewer not working flawlessly

我有一个包含多个列的 TableViewer,其中有些列有工具提示,有些则没有。通过

启用工具提示支持
ColumnViewerToolTipSupport.enableFor( tableViewer );

每一列都分配了一个 CellLabelProvider,其 getToolTipText() 方法是 returns null(无工具提示)或工具提示文本。

所有列都使用 原生工具提示 ,即各自的 useNativeToolTip() 实现 return true.

虽然所有这一切乍一看都有效,但将鼠标指针从没有工具提示的列移动到有工具提示的列时存在缺陷:后一列不显示其工具提示。

至少可以在 Windows 7.

上观察到所描述的行为

解决方法是构建自定义工具提示支持,使用 MouseMoveMouseHover 侦听器通过当前单元格中的 on 更新基础 Table 的工具提示。

class NativeViewerToolTipSupport {

  private final ExtendedTableViewer tableViewer;
  private final Listener mouseListener;

  NativeViewerToolTipSupport( ExtendedTableViewer tableViewer ) {
    this.tableViewer = tableViewer;
    this.tableViewer.getTable().setToolTipText( "" );
    this.mouseListener = this::handleMouseEvent;
  }

  void install() {
    tableViewer.getTable().addListener( SWT.Dispose, event -> uninstall() );
    tableViewer.getTable().addListener( SWT.MouseMove, mouseListener );
    tableViewer.getTable().addListener( SWT.MouseHover, mouseListener );
  }

  void uninstall() {
    tableViewer.getTable().removeListener( SWT.MouseMove, mouseListener );
    tableViewer.getTable().removeListener( SWT.MouseHover, mouseListener );
  }

  private void handleMouseEvent( Event event ) {
    String toolTipText = getToolTipText( event );
    if( !Objects.equals( tableViewer.getTable().getToolTipText(), toolTipText ) ) {
      tableViewer.getControl().setToolTipText( toolTipText );
    }
  }

  private String getToolTipText( Event event ) {
    String result = "";
    Point point = new Point( event.x, event.y );
    ViewerRow row = tableViewer.getViewerRow( point );
    if( row != null ) {
      ViewerCell cell = row.getCell( point );
      if( cell != null ) {
        CellLabelProvider labelProvider = tableViewer.getLabelProvider( cell.getColumnIndex() );
        if( labelProvider != null ) {
          result = labelProvider.getToolTipText( cell.getElement() );
        }
      }
    }
    return result;
  }

}

上面class需要找出当前鼠标位置的单元格,因此需要访问getViewerRow()。因此,它需要一个 TableViewer 派生的 class,使 getViewerRow() 可公开访问:

public class ExtendedTableViewer extends TableViewer {
  @Override
  public ViewerRow getViewerRow( Point point ) {
    return super.getViewerRow( point );
  }
}