@Override
 public boolean isVisible() {
   if (myIsRealPopup) {
     return myPopup != null && myPopup.isVisible();
   }
   if (myCurrentIdeTooltip != null) {
     return myComponent.isShowing()
         || IdeTooltipManager.getInstance().isQueuedToShow(myCurrentIdeTooltip);
   }
   return myComponent.isShowing();
 }
  @NotNull
  @Override
  public BalloonBuilder createHtmlTextBalloonBuilder(
      @NotNull final String htmlContent,
      @Nullable final Icon icon,
      final Color fillColor,
      @Nullable final HyperlinkListener listener) {

    JEditorPane text =
        IdeTooltipManager.initPane(htmlContent, new HintHint().setAwtTooltip(true), null);

    if (listener != null) {
      text.addHyperlinkListener(listener);
    }
    text.setEditable(false);
    NonOpaquePanel.setTransparent(text);
    text.setBorder(null);

    JLabel label = new JLabel();
    final JPanel content =
        new NonOpaquePanel(
            new BorderLayout(
                (int) (label.getIconTextGap() * 1.5), (int) (label.getIconTextGap() * 1.5)));

    final NonOpaquePanel textWrapper = new NonOpaquePanel(new GridBagLayout());
    JScrollPane scrolledText = new JScrollPane(text);
    scrolledText.setBackground(fillColor);
    scrolledText.getViewport().setBackground(fillColor);
    scrolledText.getViewport().setBorder(null);
    scrolledText.setBorder(null);
    textWrapper.add(scrolledText);
    content.add(textWrapper, BorderLayout.CENTER);

    final NonOpaquePanel north = new NonOpaquePanel(new BorderLayout());
    north.add(new JLabel(icon), BorderLayout.NORTH);
    content.add(north, BorderLayout.WEST);

    content.setBorder(new EmptyBorder(2, 4, 2, 4));

    final BalloonBuilder builder = createBalloonBuilder(content);

    builder.setFillColor(fillColor);

    return builder;
  }
  @Override
  public void setLocation(@NotNull RelativePoint point) {
    if (isRealPopup()) {
      myPopup.setLocation(point.getScreenPoint());
    } else {
      if (myCurrentIdeTooltip != null) {
        Point screenPoint = point.getScreenPoint();
        if (!screenPoint.equals(
            new RelativePoint(myCurrentIdeTooltip.getComponent(), myCurrentIdeTooltip.getPoint())
                .getScreenPoint())) {
          myCurrentIdeTooltip.setPoint(point.getPoint());
          myCurrentIdeTooltip.setComponent(point.getComponent());
          IdeTooltipManager.getInstance().show(myCurrentIdeTooltip, true, false);
        }
      } else {
        Point targetPoint = point.getPoint(myComponent.getParent());
        myComponent.setLocation(targetPoint);

        myComponent.revalidate();
        myComponent.repaint();
      }
    }
  }
  /**
   * Shows the hint in the layered pane. Coordinates <code>x</code> and <code>y</code> are in <code>
   * parentComponent</code> coordinate system. Note that the component appears on 250 layer.
   */
  @Override
  public void show(
      @NotNull final JComponent parentComponent,
      final int x,
      final int y,
      final JComponent focusBackComponent,
      @NotNull final HintHint hintHint) {
    myParentComponent = parentComponent;
    myHintHint = hintHint;

    myFocusBackComponent = focusBackComponent;

    LOG.assertTrue(myParentComponent.isShowing());
    myEscListener = new MyEscListener();
    myComponent.registerKeyboardAction(
        myEscListener,
        KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0),
        JComponent.WHEN_IN_FOCUSED_WINDOW);
    myComponent.registerKeyboardAction(
        myEscListener, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_FOCUSED);
    final JLayeredPane layeredPane = parentComponent.getRootPane().getLayeredPane();

    myComponent.validate();

    if (!myForceShowAsPopup
        && (myForceLightweightPopup
            || fitsLayeredPane(
                layeredPane,
                myComponent,
                new RelativePoint(parentComponent, new Point(x, y)),
                hintHint))) {
      beforeShow();
      final Dimension preferredSize = myComponent.getPreferredSize();

      if (hintHint.isAwtTooltip()) {
        IdeTooltip tooltip =
            new IdeTooltip(
                hintHint.getOriginalComponent(),
                hintHint.getOriginalPoint(),
                myComponent,
                hintHint,
                myComponent) {
              @Override
              protected boolean canAutohideOn(TooltipEvent event) {
                if (event.getInputEvent() instanceof MouseEvent) {
                  return !(hintHint.isContentActive() && event.isIsEventInsideBalloon());
                } else if (event.getAction() != null) {
                  return false;
                } else {
                  return true;
                }
              }

              @Override
              protected void onHidden() {
                fireHintHidden();
                TooltipController.getInstance().resetCurrent();
              }

              @Override
              public boolean canBeDismissedOnTimeout() {
                return false;
              }
            }.setToCenterIfSmall(hintHint.isMayCenterTooltip())
                .setPreferredPosition(hintHint.getPreferredPosition())
                .setHighlighterType(hintHint.isHighlighterType())
                .setTextForeground(hintHint.getTextForeground())
                .setTextBackground(hintHint.getTextBackground())
                .setBorderColor(hintHint.getBorderColor())
                .setBorderInsets(hintHint.getBorderInsets())
                .setFont(hintHint.getTextFont())
                .setCalloutShift(hintHint.getCalloutShift())
                .setPositionChangeShift(
                    hintHint.getPositionChangeX(), hintHint.getPositionChangeY())
                .setExplicitClose(hintHint.isExplicitClose())
                .setHint(true);
        myComponent.validate();
        myCurrentIdeTooltip =
            IdeTooltipManager.getInstance()
                .show(tooltip, hintHint.isShowImmediately(), hintHint.isAnimationEnabled());
      } else {
        final Point layeredPanePoint =
            SwingUtilities.convertPoint(parentComponent, x, y, layeredPane);
        myComponent.setBounds(
            layeredPanePoint.x, layeredPanePoint.y, preferredSize.width, preferredSize.height);
        layeredPane.add(myComponent, JLayeredPane.POPUP_LAYER);

        myComponent.validate();
        myComponent.repaint();
      }
    } else {
      myIsRealPopup = true;
      Point actualPoint = new Point(x, y);
      JComponent actualComponent = new OpaquePanel(new BorderLayout());
      actualComponent.add(myComponent, BorderLayout.CENTER);
      if (isAwtTooltip()) {
        fixActualPoint(actualPoint);

        int inset = BalloonImpl.getNormalInset();
        actualComponent.setBorder(new LineBorder(hintHint.getTextBackground(), inset));
        actualComponent.setBackground(hintHint.getTextBackground());
        actualComponent.validate();
      }

      myPopup =
          JBPopupFactory.getInstance()
              .createComponentPopupBuilder(actualComponent, myFocusRequestor)
              .setRequestFocus(myFocusRequestor != null)
              .setFocusable(myFocusRequestor != null)
              .setResizable(myResizable)
              .setMovable(myTitle != null)
              .setTitle(myTitle)
              .setModalContext(false)
              .setShowShadow(isRealPopup() && !isForceHideShadow())
              .setCancelKeyEnabled(false)
              .setCancelOnClickOutside(myCancelOnClickOutside)
              .setCancelCallback(
                  new Computable<Boolean>() {
                    @Override
                    public Boolean compute() {
                      onPopupCancel();
                      return true;
                    }
                  })
              .setCancelOnOtherWindowOpen(myCancelOnOtherWindowOpen)
              .createPopup();

      beforeShow();
      myPopup.show(new RelativePoint(myParentComponent, new Point(actualPoint.x, actualPoint.y)));
    }
  }