JFace查看器钢的自定义工具提示焦点

时间:2013-01-17 11:37:35

标签: java tooltip jface

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

所有似乎都很好,但它不是。

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

但是:如果您碰巧将鼠标移动到里面 tooptip并再次移出,焦点会从编辑器转移到视图(反之亦然)!!

我不知道这是怎么回事。这确实令人分心。

有没有人见过这个?如果没有,请试试吧!

要重现,请使用此片段,该片段取自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();
    }

}

1 个答案:

答案 0 :(得分:1)

我同意你的观点,这种行为很奇怪,我也称之为bug。仅仅因为已经处理了工具提示标签而将焦点移动到基础表上就没那么明显了。

问题是由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 ......

您甚至无法继承ColumnViewerToolTipSupport并覆盖afterHideToolTipEvent(),删除该神秘的setFocus()来电,因为表格查看器参考ColumnViewerToolTipSupport.viewer具有私人访问权限。

我能看到的唯一做法是提交一个错误,看看你是否可以从JFace开发者那里得到一些建议。我非常有兴趣了解setFocus()电话背后的想法。