当前位置: 代码迷 >> Eclipse >> eclipse的JDT的hover是怎么显示出来的
  详细解决方案

eclipse的JDT的hover是怎么显示出来的

热度:91   发布时间:2016-04-23 01:08:03.0
eclipse的JDT的hover是如何显示出来的

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>

显示效果:



  相关解决方案