/** * Returns the package of the specified completion. * * @param c The completion. * @param desc The description text being parsed. Used for errors if we cannot determine the * package. * @return The package. */ private String getPackage(Completion c, String desc) { String pkg = null; if (c instanceof JSClassCompletion) { pkg = ((JSClassCompletion) c).getPackageName(); } if (c instanceof JSCompletion) { String definedIn = ((JSCompletion) c).getEnclosingClassName(true); if (definedIn != null) { int lastDot = definedIn.lastIndexOf('.'); if (lastDot > -1) { pkg = definedIn.substring(0, lastDot); } } } else { Logger.logError( "Can't determine package from completion type: " + c.getClass() + " (" + c.toString() + ") - href: " + desc); } return pkg; }
protected void paintComponent(Graphics g) { // Set up rendering hints to look as close to native as possible Graphics2D g2d = (Graphics2D) g; Object old = null; // First, try to use the rendering hint set that is "native". Map hints = (Map) getToolkit().getDesktopProperty("awt.font.desktophints"); if (hints != null) { old = g2d.getRenderingHints(); g2d.addRenderingHints(hints); } // If a "native" set isn't found, just turn on standard text AA. else { old = g2d.getRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING); g2d.setRenderingHint( RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); } // if (jsc!=null) { // setText(null); // Stop "Foobar" from being painted // } // We never paint "selection" around the icon, to imitate Eclipse final int iconW = 18; int h = getHeight(); if (!selected) { g.setColor(getBackground()); g.fillRect(0, 0, getWidth(), h); } else { g.setColor(altBG != null && evenRow ? altBG : list.getBackground()); g.fillRect(0, 0, iconW, h); g.setColor(getBackground()); // Selection color g.fillRect(iconW, 0, getWidth() - iconW, h); } if (getIcon() != null) { int y = (h - getIcon().getIconHeight()) / 2; getIcon().paintIcon(this, g, 0, y); } int x = getX() + iconW + 2; g.setColor(selected ? list.getSelectionForeground() : list.getForeground()); if (jsc != null && !simpleText) { jsc.rendererText(g, x, g.getFontMetrics().getHeight(), selected); } else { Completion c = jsc != null ? (Completion) jsc : nonJavaCompletion; if (c != null) { g.drawString(c.toString(), x, g.getFontMetrics().getHeight()); } } // Restore rendering hints appropriately. if (hints != null) { g2d.addRenderingHints((Map) old); } else { g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, old); } }
/** * Returns the class for a completion (class completions return the class itself, member * completions return the enclosing class). */ private String getClass(Completion c, String desc) { String clazz = null; if (c instanceof JSClassCompletion) { clazz = ((JSClassCompletion) c).getClassName(true); } else if (c instanceof JSCompletion) { JSCompletion jsc = (JSCompletion) c; clazz = jsc.getEnclosingClassName(true); } else { Logger.logError( "Can't determine class from completion type: " + c.getClass() + " (" + c.toString() + ") - href: " + desc); } return clazz; }
/** {@inheritDoc} */ public void urlClicked(HyperlinkEvent e, Completion c, DescWindowCallback callback) { // A "real" URL (starts with http://, for example) should be opened // in the system browser, not the completion description window. URL url = e.getURL(); if (url != null) { // Try loading in external browser (Java 6+ only). try { Util.browse(new URI(url.toString())); } catch (/*IO*/ URISyntaxException ioe) { UIManager.getLookAndFeel().provideErrorFeedback(null); ioe.printStackTrace(); } return; } // A relative path URL (no leading "http://") results in a null URL. // Class should be in the same package as the one we're currently // viewing. Example: java.lang.String class documentation String desc = e.getDescription(); Logger.log(desc); if (desc != null) { if (isRelativeUrl(desc)) { int ext = desc.indexOf(".htm"); if (ext > -1) { // Could be <a href="Character.html#section"> link. A // popular href format is "../../util/Formatter.html#syntax". // We must determine "relative" package location. String anchor = getAnchor(desc); String clazz = desc.substring(0, ext); int backups = 0; while (clazz.startsWith("../")) { backups++; clazz = clazz.substring(3); } clazz = clazz.replace('/', '.'); String pkg = getPackage(c, desc); if (pkg != null) { clazz = doBackups(pkg, backups) + "." + clazz; JavaScriptLanguageSupport jls = getJavaScriptLanguageSupport(); ClassFile cf = jls.getJarManager().getClassEntry(clazz); if (cf != null) { JSClassCompletion cc = new JSClassCompletion(c.getProvider(), cf); callback.showSummaryFor(cc, anchor); } } } } // Could be format "com.mycompany.pkg.MyClass", with optional // #method() (for example, @see's). else { JavaScriptLanguageSupport jls = getJavaScriptLanguageSupport(); String clazz = desc; String member = null; int pound = desc.indexOf('#'); if (pound > -1) { // TODO: Handle properly member = clazz.substring(pound + 1); clazz = clazz.substring(0, pound); } // Just a class name, i.e. "String", "java.util.regex.Pattern". if (member == null) { boolean guessedPackage = false; if (clazz.indexOf('.') == -1) { String pkg = getPackage(c, desc); if (pkg != null) { clazz = pkg + "." + clazz; } guessedPackage = true; } ClassFile cf = jls.getJarManager().getClassEntry(clazz); if (cf == null && guessedPackage) { // Wasn't in the same package as "c", try java.lang int lastDot = clazz.lastIndexOf('.'); clazz = "java.lang." + clazz.substring(lastDot + 1); cf = jls.getJarManager().getClassEntry(clazz); } if (cf != null) { JSClassCompletion cc = new JSClassCompletion(c.getProvider(), cf); callback.showSummaryFor(cc, null); } else { UIManager.getLookAndFeel().provideErrorFeedback(null); Logger.log("Unknown class: " + clazz); } } // Member specified, such as "String#format(...)", // "java.util.regex.Pattern.compile(...)", or "#method()". else { boolean guessedPackage = false; if (pound == 0) { // Member of this class (i.e. "#foobar(bas)") // "clazz" was incorrect previously in this case clazz = getClass(c, desc); } else { // i.e. "String#CASE_INSENSITIVE_ORDER" // If no package specified, assume clazz is in the same // package as the currently displayed completion. if (clazz.indexOf('.') == -1) { String pkg = getPackage(c, desc); if (pkg != null) { clazz = pkg + "." + clazz; } guessedPackage = true; } } ClassFile cf = clazz != null ? jls.getJarManager().getClassEntry(clazz) : null; if (cf == null && guessedPackage) { // Wasn't in the same package as "c", try java.lang int lastDot = clazz.lastIndexOf('.'); clazz = "java.lang." + clazz.substring(lastDot + 1); cf = jls.getJarManager().getClassEntry(clazz); } if (cf != null) { Completion memberCompletion = null; int lparen = member.indexOf('('); if (lparen == -1) { // A field, or method with args omitted FieldInfo fi = cf.getFieldInfoByName(member); if (fi != null) { // Try fields first, it's most likely memberCompletion = new JSFieldCompletion(c.getProvider(), fi); } else { // Try methods second List miList = cf.getMethodInfoByName(member, -1); if (miList != null && miList.size() > 0) { MethodInfo mi = (MethodInfo) miList.get(0); // Just show the first if multiple memberCompletion = new JSFunctionCompletion(c.getProvider(), mi); } } } else { String[] args = getArgs(member); String methodName = member.substring(0, lparen); List miList = cf.getMethodInfoByName(methodName, args.length); if (miList != null && miList.size() > 0) { if (miList.size() > 1) { // TODO: Pick correct overload based on args Logger.log("Multiple overload support not yet implemented"); } else { MethodInfo mi = (MethodInfo) miList.get(0); memberCompletion = new JSFunctionCompletion(c.getProvider(), mi); } } } if (memberCompletion != null) { callback.showSummaryFor(memberCompletion, null); } } else { UIManager.getLookAndFeel().provideErrorFeedback(null); Logger.logError("Unknown class: " + clazz + " (href: " + desc + ")"); } } } } }