eclipse的JDT的hover是如何显示出来的

56 篇文章 0 订阅

1.什么是JDT的hover。

见下图:

2. hover中的不同的字体,和颜色是如何显示出来的。

其实在对应的hover中,返回的是String类型,内容是html,然后通过org.eclipse.swt.browser.Browser显示出来的。


3.工作原理:

3.1 add MouseTracker to current SourceViewer, when you open java file.
org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditor$AdaptedSourceViewer
    --> org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitEditor$AdaptedSourceViewer

    /**
     * After this method has been executed the caller knows that any installed text hover has been installed.
     */
    private void ensureHoverControlManagerInstalled() {
        if (fTextHovers != null && !fTextHovers.isEmpty() && fHoverControlCreator != null && fTextHoverManager == null) {
            fTextHoverManager= new TextViewerHoverManager(this, fHoverControlCreator);
            fTextHoverManager.install(this.getTextWidget());
            fTextHoverManager.setSizeConstraints(TEXT_HOVER_WIDTH_CHARS, TEXT_HOVER_HEIGHT_CHARS, false, true);
            fTextHoverManager.setInformationControlReplacer(new StickyHoverManager(this));
        }
    }
    --> org.eclipse.jface.text.TextViewerHoverManager
    public void install(Control subjectControl) {
        if (fSubjectControl != null && !fSubjectControl.isDisposed() && fSubjectControlDisposeListener != null)
            fSubjectControl.removeDisposeListener(fSubjectControlDisposeListener);

        fSubjectControl= subjectControl;

        if (fSubjectControl != null)
            fSubjectControl.addDisposeListener(getSubjectControlDisposeListener());

        if (fInformationControlCloser != null)
            fInformationControlCloser.setSubjectControl(subjectControl);

        setEnabled(true);
        fDisposed= false;
    }
    --> org.eclipse.jface.text.TextViewerHoverManager
    public void setEnabled(boolean enabled) {

        boolean was= isEnabled();
        super.setEnabled(enabled);
        boolean is= isEnabled();

        if (was != is && fMouseTracker != null) {
            if (is)
                fMouseTracker.start(getSubjectControl());
            else
                fMouseTracker.stop();
        }
    }

    --> org.eclipse.jface.text.AbstractHoverInformationControlManager$MouseTracker
        public void start(Control subjectControl) {
            fSubjectControl= subjectControl;
            if (fSubjectControl != null && !fSubjectControl.isDisposed())
                fSubjectControl.addMouseTrackListener(this);

            fIsInRestartMode= false;
            fIsComputing= false;
            fMouseLostWhileComputing= false;
            fShellDeactivatedWhileComputing= false;
        }

3.2 when you hover mouse on target SourceViewer, it will show hover
        org.eclipse.jface.text.AbstractHoverInformationControlManager$MouseTracker
        public void mouseHover(MouseEvent event) {
            if (fIsComputing || fIsInRestartMode ||
                    (fSubjectControl != null && !fSubjectControl.isDisposed() && fSubjectControl.getShell() != fSubjectControl.getShell().getDisplay().getActiveShell())) {
                if (DEBUG)
                    System.out.println("AbstractHoverInformationControlManager...mouseHover: @ " + event.x + "/" + event.y + " : hover cancelled: fIsComputing= " + fIsComputing + ", fIsInRestartMode= " + fIsInRestartMode); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
                return;
            }

            fIsInRestartMode= true;
            fIsComputing= true;
            fMouseLostWhileComputing= false;
            fShellDeactivatedWhileComputing= false;

            fHoverEventStateMask= event.stateMask;
            fHoverEvent= event;
            fHoverArea= new Rectangle(event.x - EPSILON, event.y - EPSILON, 2 * EPSILON, 2 * EPSILON );
            if (fHoverArea.x < 0)
                fHoverArea.x= 0;
            if (fHoverArea.y < 0)
                fHoverArea.y= 0;
            setSubjectArea(fHoverArea);

            if (fSubjectControl != null && !fSubjectControl.isDisposed()) {
                fSubjectControl.addMouseMoveListener(this);
                fSubjectControl.getShell().addShellListener(this);
            }
            doShowInformation();
        }

     --> org.eclipse.jface.text.AbstractInformationControlManager
    protected void doShowInformation() {
        fSubjectArea= null;
        fInformation= null;
        computeInformation();
    }

    --> org.eclipse.jface.text.TextViewerHoverManager
    protected void computeInformation() {
    //create a thread(Text Viewer Hover Presenter) to show hover
    }
   ...   
   --> org.eclipse.jface.text.AbstractInformationControlManager.internalShowInformationControl(Rectangle, Object) to create control to show the text.
	private void internalShowInformationControl(Rectangle subjectArea, Object information) {
		if (this instanceof InformationControlReplacer) {
			((InformationControlReplacer) this).showInformationControl(subjectArea, information);
			return;
		}

		IInformationControl informationControl= getInformationControl();
		if (informationControl != null) {

			Point sizeConstraints= computeSizeConstraints(fSubjectControl, fSubjectArea, informationControl);
			if (informationControl instanceof IInformationControlExtension3) {
				IInformationControlExtension3 iControl3= (IInformationControlExtension3) informationControl;
				Rectangle trim= iControl3.computeTrim();
				sizeConstraints.x += trim.width;
				sizeConstraints.y += trim.height;
			}
			informationControl.setSizeConstraints(sizeConstraints.x, sizeConstraints.y);

			if (informationControl instanceof IInformationControlExtension2)
				((IInformationControlExtension2)informationControl).setInput(information);
			else
				informationControl.setInformation(information.toString());

			if (informationControl instanceof IInformationControlExtension) {
				IInformationControlExtension extension= (IInformationControlExtension)informationControl;
				if (!extension.hasContents())
					return;
			}

			Point size= null;
			Point location= null;
			Rectangle bounds= restoreInformationControlBounds();

			if (bounds != null) {
				if (bounds.x > -1 && bounds.y > -1)
					location= Geometry.getLocation(bounds);

				if (bounds.width > -1 && bounds.height > -1)
					size= Geometry.getSize(bounds);
			}

			if (size == null)
				size= informationControl.computeSizeHint();

			if (fEnforceAsMinimalSize)
				size= Geometry.max(size, sizeConstraints);
			if (fEnforceAsMaximalSize)
				size= Geometry.min(size, sizeConstraints);

			if (location == null)
				location= computeInformationControlLocation(subjectArea, size);

			Rectangle controlBounds= Geometry.createRectangle(location, size);
			cropToClosestMonitor(controlBounds);
			location= Geometry.getLocation(controlBounds);
			size= Geometry.getSize(controlBounds);
			informationControl.setLocation(location);
			informationControl.setSize(size.x, size.y);

			showInformationControl(subjectArea);
		}
	}

    --> org.eclipse.jface.text.AbstractInformationControlManager
    protected void showInformationControl(Rectangle subjectArea) {
        fInformationControl.setVisible(true);
        
        if (fInformationControl == null)
            return; // could already be disposed if setVisible(..) runs the display loop
        
        if (fTakesFocusWhenVisible)
            fInformationControl.setFocus();

        if (fInformationControlCloser != null)
            fInformationControlCloser.start(subjectArea);
    }


org.eclipse.jdt.internal.ui.text.java.hover.JavadocHover$HoverControlCreator
    public IInformationControl doCreateInformationControl(Shell parent) {
            String tooltipAffordanceString= fAdditionalInfoAffordance ? JavaPlugin.getAdditionalInfoAffordanceString() : EditorsUI.getTooltipAffordanceString();
            if (BrowserInformationControl.isAvailable(parent)) {
                String font= PreferenceConstants.APPEARANCE_JAVADOC_FONT;
                BrowserInformationControl iControl= new BrowserInformationControl(parent, font, tooltipAffordanceString) {
                    /*
                     * @see org.eclipse.jface.text.IInformationControlExtension5#getInformationPresenterControlCreator()
                     */
                    @Override
                    public IInformationControlCreator getInformationPresenterControlCreator() {
                        return fInformationPresenterControlCreator;
                    }
                };
                addLinkListener(iControl);
                return iControl;
            } else {
                return new DefaultInformationControl(parent, tooltipAffordanceString);
            }
        }

4. 下面是System.out.println的html内容和在firefox下显示的效果。

<html><head><style CHARSET="ISO-8859-1" TYPE="text/css">/* Font definitions */
html         { font-family: 'Sans',sans-serif; font-size: 10pt; font-style: normal; font-weight: normal; }
body, h1, h2, h3, h4, h5, h6, p, table, td, caption, th, ul, ol, dl, li, dd, dt { font-size: 1em; }
pre          { font-family: monospace; }

/* Margins */
body	     { overflow: auto; margin-top: 0px; margin-bottom: 0.5em; margin-left: 0.3em; margin-right: 0px; }
h1           { margin-top: 0.3em; margin-bottom: 0.04em; }	
h2           { margin-top: 2em; margin-bottom: 0.25em; }
h3           { margin-top: 1.7em; margin-bottom: 0.25em; }
h4           { margin-top: 2em; margin-bottom: 0.3em; }
h5           { margin-top: 0px; margin-bottom: 0px; }
p            { margin-top: 1em; margin-bottom: 1em; }
pre          { margin-left: 0.6em; }
ul	         { margin-top: 0px; margin-bottom: 1em; margin-left: 1em; padding-left: 1em;}
li	         { margin-top: 0px; margin-bottom: 0px; } 
li p	     { margin-top: 0px; margin-bottom: 0px; } 
ol	         { margin-top: 0px; margin-bottom: 1em; margin-left: 1em; padding-left: 1em; }
dl	         { margin-top: 0px; margin-bottom: 1em; }
dt	         { margin-top: 0px; margin-bottom: 0px; font-weight: bold; }
dd	         { margin-top: 0px; margin-bottom: 0px; }

/* Styles and colors */
a:link	     { color: #0000FF; }
a:hover	     { color: #000080; }
a:visited    { text-decoration: underline; }
a.header:link    { text-decoration: none; color: #000000 }
a.header:visited { text-decoration: none; color: #000000 }
a.header:hover   { text-decoration: underline; color: #000080; }
h4           { font-style: italic; }
strong	     { font-weight: bold; }
em	         { font-style: italic; }
var	         { font-style: italic; }
th	         { font-weight: bold; }

/* Workarounds for new Javadoc stylesheet (1.7) */ 
ul.blockList li.blockList, ul.blockListLast li.blockList {
    list-style:none;
}
ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast {
    list-style:none;
}
</style>
<base href='http://download.oracle.com/javase/7/docs/api/java/io/PrintStream.html'>
</head><body style="overflow:hidden;" text="#000000" bgcolor="#ffffbf"><h5><div style='word-wrap: break-word; position: relative; margin-left: 20px; padding-top: 2px; '><a href=''><!--[if lte IE 6]><![if gte IE 5.5]>
<span alt='Open Declaration' style="border:none; position: absolute; width: 16px; height: 16px; left: -21px; filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='')"></span>
<![endif]><![endif]-->
<!--[if !IE]>-->
<img alt='Open Declaration' style='border:none; position: absolute; width: 16px; height: 16px; left: -21px; ' src='/>
<!--<![endif]-->
<!--[if gte IE 7]>
<img alt='Open Declaration' style='border:none; position: absolute; width: 16px; height: 16px; left: -21px; ' src='file:'/>
<![endif]-->
</a>void <a class='header' href=''>java</a>.<a class='header' href=''>io</a>.<a class='header' href=''>PrintStream</a>.println(<span style='font-weight:normal;'></span>int x)</div></h5><br><p>Prints an integer and then terminate the line.  This method behaves as
 though it invokes <code><code><a href=''>print(int)</a></code></code> and then
 <code><code><a href=''>println()</a></code></code>.<dl><dt>Parameters:</dt><dd><b>x</b>   The <code>int</code> to be printed.</dd></dl></body></html>

显示效果:



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值