LightweightHint (@NotNull Editor editor, @NotNull Point p, boolean alignToRight, @NotNull TooltipGroup group, @NotNull HintHint hintHint, boolean highlightActions, boolean limitWidthToScreen, @Nullable TooltipReloader tooltipReloader) { if (myText == null) return null; //setup text //noinspection HardCodedStringLiteral String tooltipPreText = myText.replaceAll(String.valueOf(UIUtil.MNEMONIC), ""); String dressedText = dressDescription(editor, tooltipPreText, myCurrentWidth > 0); boolean expanded = myCurrentWidth > 0 && !dressedText.equals(tooltipPreText); JComponent contentComponent = editor.getContentComponent(); JComponent editorComponent = editor.getComponent(); if (!editorComponent.isShowing()) return null; JLayeredPane layeredPane = editorComponent.getRootPane().getLayeredPane(); String textToDisplay = colorizeSeparators(dressedText); JEditorPane editorPane = IdeTooltipManager.initPane(new Html(textToDisplay).setKeepFont(true), hintHint, layeredPane, limitWidthToScreen); UIUtil.enableEagerSoftWrapping(editorPane); editorPane.putClientProperty(UIUtil.TEXT_COPY_ROOT, Boolean.TRUE); hintHint.setContentActive(isContentAction(dressedText)); if (!hintHint.isAwtTooltip()) { correctLocation(editor, editorPane, p, alignToRight, expanded, myCurrentWidth); } JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(editorPane, true); scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED); scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); scrollPane.setOpaque(hintHint.isOpaqueAllowed()); scrollPane.getViewport().setOpaque(hintHint.isOpaqueAllowed()); scrollPane.setBackground(hintHint.getTextBackground()); scrollPane.getViewport().setBackground(hintHint.getTextBackground()); scrollPane.setViewportBorder(null); if (hintHint.isRequestFocus()) { editorPane.setFocusable(true); } List<AnAction> actions = new ArrayList<>(); JPanel grid = createMainPanel(hintHint, scrollPane, editorPane, highlightActions, !textToDisplay.equals(dressedText)); if (ScreenReader.isActive()) { grid.setFocusTraversalPolicyProvider(true); grid.setFocusTraversalPolicy(new LayoutFocusTraversalPolicy() { @Override public Component getDefaultComponent(Container aContainer) { return editorPane; } @Override public boolean getImplicitDownCycleTraversal() { return true; } }); } LightweightHint hint = new LightweightHint(grid) { @Override public void hide() { super.hide(); for (AnAction action: actions) { action.unregisterCustomShortcutSet(contentComponent); } } @Override protected boolean canAutoHideOn(TooltipEvent event) { if (!LineTooltipRenderer.this.canAutoHideOn(event)) { return false; } return super.canAutoHideOn(event); } }; TooltipReloader reloader = tooltipReloader == null ? toExpand -> reloadFor(hint, editor, p, editorPane, alignToRight, group, hintHint, toExpand) : tooltipReloader; ReloadHintAction reloadAction = new ReloadHintAction(hintHint, reloader, expanded); // an action to expand description when tooltip was shown after mouse move; need to unregister from editor component reloadAction.registerCustomShortcutSet(KeymapUtil.getActiveKeymapShortcuts(IdeActions.ACTION_SHOW_ERROR_DESCRIPTION), contentComponent); actions.add(reloadAction); editorPane.addHyperlinkListener(new HyperlinkListener() { @Override public void hyperlinkUpdate(HyperlinkEvent e) { if (e.getEventType() == HyperlinkEvent.EventType.EXITED) { return; } if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) { URL url = e.getURL(); if (url != null) { BrowserUtil.browse(url); hint.hide(); return; } String description = e.getDescription(); if (description != null && handle(description, editor)) { hint.hide(); return; } TooltipActionsLogger.logShowDescription(editor.getProject(), TooltipActionsLogger.Source.MoreLink, e.getInputEvent(), null); reloader.reload(!expanded); } } }); fillPanel(editor, grid, hint, hintHint, actions, reloader, highlightActions); return hint; }