void (@NotNull ExecutionConsole executionConsole) { EdtExecutorService.getScheduledExecutorInstance().schedule(() -> { String shortcutText = KeymapUtil.getFirstKeyboardShortcutText( ActionManager.getInstance().getAction(RerunTestsAction.ID) ); if (shortcutText.isEmpty()) { return; } ConsoleView consoleView = UIUtil.findComponentOfType(executionConsole.getComponent(), ConsoleViewImpl.class); if (consoleView != null) { GotItMessage message = GotItMessage.createMessage(ExecutionBundle.message("popup.content.rerun.tests.with", shortcutText), ""); Disposable disposable = Disposer.newDisposable(); Disposer.register(executionConsole, disposable); message.setDisposable(disposable); message.setCallback(() -> PropertiesComponent.getInstance().setValue(KEY, true)); message.setShowCallout(false); JComponent consoleComponent = consoleView.getComponent(); message.show( new PositionTracker<>(consoleComponent) { @Override public RelativePoint recalculateLocation(@NotNull Balloon balloon) { RelativePoint point = RelativePoint.getSouthEastOf(consoleComponent); Insets shadowInsets = balloon instanceof BalloonImpl ? ((BalloonImpl)balloon).getShadowBorderInsets() : JBInsets.emptyInsets(); Dimension balloonContentSize = JBDimension.create(balloon.getPreferredSize(), true); JBInsets.removeFrom(balloonContentSize, shadowInsets); // compensate "-shift.top" from BalloonImpl.Below.getShiftedPoint(java.awt.Point, java.awt.Insets) point.getPoint().y += shadowInsets.top; int spacingFromEdges = JBUIScale.scale(12); point.getPoint().translate(-balloonContentSize.width / 2 - spacingFromEdges, -balloonContentSize.height / 2 - spacingFromEdges); return point; } }, Balloon.Position.below ); consoleComponent.addHierarchyListener(new HierarchyListener() { @Override public void hierarchyChanged(HierarchyEvent e) { if (!consoleComponent.isShowing()) { Disposer.dispose(disposable); consoleComponent.removeHierarchyListener(this); } } }); } }, 1000, TimeUnit.MILLISECONDS); }