2

JFace 中的另一个错误?我使用标准机制实现了一个自定义工具提示:CellLabelProvider实现方法getToolTipText()

一切似乎都很好,但事实并非如此。

我有一个视图和一个编辑器,它们都显示带有这些自定义工具提示的表格。如果您已聚焦编辑器并将鼠标悬停在其单元格上,您会看到其工具提示。正确的。如果您将鼠标悬停在视图的表格单元格上,您会看到它们的工具提示。正确的。

但是:如果您碰巧将鼠标移到顶部提示并再次移出,焦点将从编辑器转移到视图(反之亦然)!

我不明白这是怎么回事。这确实很让人分心。

有人见过这个吗?如果没有,请尝试一下!

要重现,请使用取自JFaceSnippets 3.11的这段代码:

package org.eclipse.jface.snippets.viewers;

import org.eclipse.jface.viewers.CellLabelProvider;
import org.eclipse.jface.viewers.ColumnViewerToolTipSupport;
import org.eclipse.jface.viewers.IStructuredContentProvider;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.jface.window.ToolTip;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

/**
 * Explore New API: JFace custom tooltips drawing.
 * 
 * @author Tom Schindl <tom.schindl@bestsolution.at>
 * @since 3.3
 */
public class Snippet011CustomTooltips {
    private static class MyContentProvider implements IStructuredContentProvider {
        @Override
        public Object[] getElements( final Object inputElement ) {
            return new String[] { "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten" };
        }

        @Override
        public void dispose() {
        }

        @Override
        public void inputChanged( final Viewer viewer, final Object oldInput, final Object newInput ) {
        }
    }

    /**
     * @param args
     */
    public static void main( final String[] args ) {
        final Display display = new Display();
        final Shell shell = new Shell( display );
        shell.setLayout( new FillLayout( SWT.VERTICAL ) );

        final Text t = new Text( shell, SWT.MULTI );
        t.setText( "1) Make sure focus is somewhere here. See the blinking caret!\n"
                + "2) Now get a tooltip displayed in the table by hovering there with the mouse cursor\n"
                + "3a) If you move the cursor INSIDE the tooltip just shortly and out again, the input focus will be stolen from this text field\n"
                + "3b) If you DO NOT move the cursor INSIDE the tooltip, input focus will remain with the text edit field\n\n"
                + "=> to me, this is a bug!" );

        final TableViewer v = new TableViewer( shell, SWT.FULL_SELECTION );
        v.getTable().setLinesVisible( true );
        v.getTable().setHeaderVisible( true );
        v.setContentProvider( new MyContentProvider() );
        ColumnViewerToolTipSupport.enableFor( v, ToolTip.NO_RECREATE );

        final CellLabelProvider labelProvider = new CellLabelProvider() {
            @Override
            public String getToolTipText( final Object element ) {
                return "Tooltip (" + element + ") - if you move HERE, the table will grab input focus!";
            }

            @Override
            public void update( final ViewerCell cell ) {
                cell.setText( cell.getElement().toString() );
            }
        };

        final TableViewerColumn column = new TableViewerColumn( v, SWT.NONE );
        column.setLabelProvider( labelProvider );
        column.getColumn().setText( "Table" );
        column.getColumn().setWidth( 100 );

        v.setInput( "" );

        shell.setSize( 800, 400 );
        shell.open();

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

        display.dispose();
    }

}
4

1 回答 1

1

我同意你的观点,这种行为很奇怪,我也称它为错误。仅仅因为工具提示标签已被处理而将焦点移至基础表没有任何明显意义。

问题是由以下ColumnViewerToolTipSupport.afterHideToolTip()方法引起的:

protected void afterHideToolTip(Event event) {
    super.afterHideToolTip(event);

    // Clear the restored value else this could be a source of a leak
    setData(VIEWER_CELL_KEY, null);
    if (event != null && event.widget != viewer.getControl()) {
        viewer.getControl().setFocus();
    }
}

如果您没有将鼠标移到工具提示中,而只是从您悬停的单元格上移开,则传递给的事件afterHideToolTip()为空,并且setFocus()不会进行调用。

如果您将鼠标移入工具提示,然后离开,则传递给的事件afterHideToolTip()显然是由工具提示的标签本身在它消亡时生成的。

摆弄我们可以使用的几个参数对行为没有影响:useNativeToolTips()返回true,传递RECREATE而不是NO_RECREATE......

您甚至不能 subclassColumnViewerToolTipSupport和 override afterHideToolTipEvent(),删除那个神秘setFocus()的调用,因为表查看器引用ColumnViewerToolTipSupport.viewer具有私有访问权限。

我能看到的唯一行动方案是提交一个错误,看看您是否可以从 JFace 开发人员那里获得一些建议。我很想知道这个setFocus()电话背后的想法是什么。

于 2013-02-21T15:01:11.310 回答