private void setHeaderComponent(JComponent c) {
    boolean doRevalidate = false;
    if (myHeaderComponent != null) {
      myHeaderPanel.remove(myHeaderComponent);
      myHeaderPanel.add(myCaption, BorderLayout.NORTH);
      myHeaderComponent = null;
      doRevalidate = true;
    }

    if (c != null) {
      myHeaderPanel.remove(myCaption);
      myHeaderPanel.add(c, BorderLayout.NORTH);
      myHeaderComponent = c;

      final Dimension size = myContent.getSize();
      if (size.height < c.getPreferredSize().height * 2) {
        size.height += c.getPreferredSize().height;
        setSize(size);
      }

      doRevalidate = true;
    }

    if (doRevalidate) myContent.revalidate();
  }
  @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;
  }
 public void setAdText(@NotNull final String s, int alignment) {
   if (myAdComponent == null) {
     myAdComponent =
         HintUtil.createAdComponent(s, BorderFactory.createEmptyBorder(1, 5, 1, 5), alignment);
     JPanel wrapper =
         new JPanel(new BorderLayout()) {
           @Override
           protected void paintComponent(Graphics g) {
             g.setColor(Gray._135);
             g.drawLine(0, 0, getWidth(), 0);
             super.paintComponent(g);
           }
         };
     wrapper.setOpaque(false);
     wrapper.setBorder(new EmptyBorder(1, 0, 0, 0));
     wrapper.add(myAdComponent, BorderLayout.CENTER);
     myContent.add(wrapper, BorderLayout.SOUTH);
     pack(false, true);
   } else {
     myAdComponent.setText(s);
     myAdComponent.setHorizontalAlignment(alignment);
   }
 }
  AbstractPopup init(
      final Project project,
      @NotNull final JComponent component,
      @Nullable final JComponent preferredFocusedComponent,
      final boolean requestFocus,
      final boolean focusable,
      final boolean forceHeavyweight,
      final boolean movable,
      final String dimensionServiceKey,
      final boolean resizable,
      @Nullable final String caption,
      @Nullable final Computable<Boolean> callback,
      final boolean cancelOnClickOutside,
      @Nullable final Set<JBPopupListener> listeners,
      final boolean useDimServiceForXYLocation,
      InplaceButton commandButton,
      @Nullable final IconButton cancelButton,
      @Nullable final MouseChecker cancelOnMouseOutCallback,
      final boolean cancelOnWindow,
      @Nullable final ActiveIcon titleIcon,
      final boolean cancelKeyEnabled,
      final boolean locateBycontent,
      final boolean placeWithinScreenBounds,
      @Nullable final Dimension minSize,
      float alpha,
      @Nullable MaskProvider maskProvider,
      boolean inStack,
      boolean modalContext,
      @Nullable Component[] focusOwners,
      @Nullable String adText,
      int adTextAlignment,
      final boolean headerAlwaysFocusable,
      @NotNull List<Pair<ActionListener, KeyStroke>> keyboardActions,
      Component settingsButtons,
      @Nullable final Processor<JBPopup> pinCallback,
      boolean mayBeParent,
      boolean showShadow) {
    if (requestFocus && !focusable) {
      assert false
          : "Incorrect argument combination: requestFocus="
              + requestFocus
              + " focusable="
              + focusable;
    }

    myActivityKey = new UiActivity.Focus("Popup:" + this);
    myProject = project;
    myComponent = component;
    myPopupBorder = PopupBorder.Factory.create(true, showShadow);
    myShadowed = showShadow;
    myPaintShadow =
        showShadow
            && !SystemInfo.isMac
            && !movable
            && !resizable
            && Registry.is("ide.popup.dropShadow");
    myContent = createContentPanel(resizable, myPopupBorder, isToDrawMacCorner() && resizable);
    myMayBeParent = mayBeParent;

    myContent.add(component, BorderLayout.CENTER);
    if (adText != null) {
      setAdText(adText, adTextAlignment);
    }

    myCancelKeyEnabled = cancelKeyEnabled;
    myLocateByContent = locateBycontent;
    myLocateWithinScreen = placeWithinScreenBounds;
    myAlpha = alpha;
    myMaskProvider = maskProvider;
    myInStack = inStack;
    myModalContext = modalContext;
    myFocusOwners = focusOwners;
    myHeaderAlwaysFocusable = headerAlwaysFocusable;
    myMovable = movable;

    ActiveIcon actualIcon = titleIcon == null ? new ActiveIcon(EmptyIcon.ICON_0) : titleIcon;

    myHeaderPanel = new JPanel(new BorderLayout());

    if (caption != null) {
      if (caption.length() > 0) {
        myCaption = new TitlePanel(actualIcon.getRegular(), actualIcon.getInactive());
        ((TitlePanel) myCaption).setText(caption);
      } else {
        myCaption = new CaptionPanel();
      }

      if (pinCallback != null) {
        myCaption.setButtonComponent(
            new InplaceButton(
                new IconButton(
                    "Pin",
                    IconLoader.getIcon("/general/autohideOff.png"),
                    IconLoader.getIcon("/general/autohideOff.png"),
                    IconLoader.getIcon("/general/autohideOffInactive.png")),
                new ActionListener() {
                  public void actionPerformed(final ActionEvent e) {
                    pinCallback.process(AbstractPopup.this);
                  }
                }));
      } else if (cancelButton != null) {
        myCaption.setButtonComponent(
            new InplaceButton(
                cancelButton,
                new ActionListener() {
                  public void actionPerformed(final ActionEvent e) {
                    cancel();
                  }
                }));
      } else if (commandButton != null) {
        myCaption.setButtonComponent(commandButton);
      }
    } else {
      myCaption = new CaptionPanel();
      myCaption.setBorder(null);
      myCaption.setPreferredSize(new Dimension(0, 0));
    }

    setWindowActive(myHeaderAlwaysFocusable);

    myHeaderPanel.add(myCaption, BorderLayout.NORTH);
    myContent.add(myHeaderPanel, BorderLayout.NORTH);

    myForcedHeavyweight = true;
    myResizable = resizable;
    myPreferredFocusedComponent = preferredFocusedComponent;
    myRequestFocus = requestFocus;
    myFocusable = focusable;
    myDimensionServiceKey = dimensionServiceKey;
    myCallBack = callback;
    myCancelOnClickOutside = cancelOnClickOutside;
    myCancelOnMouseOutCallback = cancelOnMouseOutCallback;
    myListeners = listeners == null ? new HashSet<JBPopupListener>() : listeners;
    myUseDimServiceForXYLocation = useDimServiceForXYLocation;
    myCancelOnWindow = cancelOnWindow;
    myMinSize = minSize;

    for (Pair<ActionListener, KeyStroke> pair : keyboardActions) {
      myContent.registerKeyboardAction(
          pair.getFirst(), pair.getSecond(), JComponent.WHEN_IN_FOCUSED_WINDOW);
    }

    if (settingsButtons != null) {
      myCaption.addSettingsComponent(settingsButtons);
    }

    return this;
  }