简体   繁体   English

JFace Viewer钢结构焦点的自定义工具提示

[英]Custom tooltip of JFace viewer steels focus

Another bug in JFace? JFace中的另一个错误? I implemented a custom tooltip using standard mechanisms: a CellLabelProvider implementing the method getToolTipText() . 我使用标准机制实现了自定义工具提示: CellLabelProvider实现了getToolTipText()方法。

Everything seems fine, but it isnt't. 一切似乎都很好,但事实并非如此。

I got a view and an editor, both showing tables with these custom tooltips. 我有一个视图和一个编辑器,都显示了带有这些自定义工具提示的表格。 If you have focused the editor and hover over its cells, you see its tooltips. 如果您已将编辑器聚焦并悬停在其单元格上,则会看到其工具提示。 Correct. 正确。 If you hover over the view's table's cells, you see their tooltips. 如果将鼠标悬停在视图表的单元格上方,则会看到其工具提示。 Correct. 正确。

BUT: if you happen to move the mouse inside the tooptip and move out again, the focus shifts from the editor to the view (and vice versa)!! 但是:如果你碰巧移动鼠标tooptip ,再搬走,从编辑到视图(反之亦然)的焦点转移!

I don't see how this is meant to be like it is. 我不知道这是怎么回事。 It is very distracting indeed. 确实,这很让人分心。

Did anybody ever see this? 有人看过吗? If not, try it, please! 如果没有,请尝试!

To reproduce, take this snippet, which is taken from JFaceSnippets 3.11 : 要重现,请使用此片段,该片段摘自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();
    }

}

I agree with you that this behavior is very odd, and I'd also call it a bug. 我同意您的看法,这种行为非常奇怪,我也称其为错误。 Moving the focus to the underlying table simply because the tool tip label has been disposed makes no sort of obvious sense. 仅因为已经放置了工具提示标签,就将焦点移到了基础表上没有任何明显的意义。

The problem is caused by the ColumnViewerToolTipSupport.afterHideToolTip() method: 该问题是由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();
    }
}

If you don't mouse into the tool tip, and simply move away from the cell you're hovering over, the event passed to afterHideToolTip() is null, and the setFocus() call is not made. 如果您没有将鼠标悬停在工具提示上,而只是将鼠标移开要悬停的单元格,则传递给afterHideToolTip()的事件为null,并且不会进行setFocus()调用。

If you do mouse into the tool tip, and then away, the event passed to afterHideToolTip() is apparently generated by the tool tip's label itself as it dies. 如果将鼠标移到工具提示中,然后移开,传递给afterHideToolTip()的事件显然是由工具提示的标签本身在死亡时生成的。

Fiddling around with the few parameters at our disposal had no effect on the behavior: having useNativeToolTips() return true, passing RECREATE instead of NO_RECREATE ... 摆弄我们可以使用的几个参数对行为没有任何影响: useNativeToolTips()返回true,传递RECREATE而不是NO_RECREATE ...

You can't even subclass ColumnViewerToolTipSupport and override afterHideToolTipEvent() , removing that mysterious setFocus() call, because the table viewer reference ColumnViewerToolTipSupport.viewer has private access. 您甚至无法ColumnViewerToolTipSupport子类,并重写afterHideToolTipEvent() ,从而删除该神秘的setFocus()调用,因为表查看器引用ColumnViewerToolTipSupport.viewer具有私有访问权限。

The only course of action I can see is to file a bug and see if you can get some advice from the JFace devs. 我唯一能看到的行动就是提交一个错误,看看是否可以从JFace开发人员那里得到一些建议。 I'd be very interested to learn what the thinking is behind that setFocus() call. 我非常有兴趣了解setFocus()调用背后的想法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM