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();
  }
 public void setLocation(@NotNull final Point screenPoint) {
   if (myPopup == null) {
     myForcedLocation = screenPoint;
   } else {
     moveTo(myContent, screenPoint, myLocateByContent ? myHeaderPanel.getPreferredSize() : null);
   }
 }
  @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 Point getLocationOnScreen() {
    Dimension headerCorrectionSize = myLocateByContent ? myHeaderPanel.getPreferredSize() : null;
    Point screenPoint = myContent.getLocationOnScreen();
    if (headerCorrectionSize != null) {
      screenPoint.y -= headerCorrectionSize.height;
    }

    return screenPoint;
  }
    public void paint(Graphics g) {
      super.paint(g);

      if (myResizable && myDrawMacCorner) {
        g.drawImage(
            ourMacCorner,
            getX() + getWidth() - ourMacCorner.getWidth(this),
            getY() + getHeight() - ourMacCorner.getHeight(this),
            this);
      }
    }
 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);
   }
 }
  public void show(Component owner, int aScreenX, int aScreenY, final boolean considerForcedXY) {
    if (ApplicationManagerEx.getApplicationEx() != null
        && ApplicationManager.getApplication().isHeadlessEnvironment()) return;
    if (isDisposed()) {
      throw new IllegalStateException(
          "Popup was already disposed. Recreate a new instance to show again");
    }

    assert ApplicationManager.getApplication().isDispatchThread();

    addActivity();

    final boolean shouldShow = beforeShow();
    if (!shouldShow) {
      removeActivity();
      return;
    }

    prepareToShow();

    if (myInStack) {
      myFocusTrackback = new FocusTrackback(this, owner, true);
      myFocusTrackback.setMustBeShown(true);
    }

    Dimension sizeToSet = null;

    if (myDimensionServiceKey != null) {
      sizeToSet = DimensionService.getInstance().getSize(myDimensionServiceKey, myProject);
    }

    if (myForcedSize != null) {
      sizeToSet = myForcedSize;
    }

    if (myMinSize == null) {
      myMinSize = myContent.getMinimumSize();
    }

    if (sizeToSet == null) {
      sizeToSet = myContent.getPreferredSize();
    }

    if (sizeToSet != null) {
      sizeToSet.width = Math.max(sizeToSet.width, myMinSize.width);
      sizeToSet.height = Math.max(sizeToSet.height, myMinSize.height);

      myContent.setSize(sizeToSet);
      myContent.setPreferredSize(sizeToSet);
    }

    Point xy = new Point(aScreenX, aScreenY);
    boolean adjustXY = true;
    if (myDimensionServiceKey != null) {
      final Point storedLocation =
          DimensionService.getInstance().getLocation(myDimensionServiceKey, myProject);
      if (storedLocation != null) {
        xy = storedLocation;
        adjustXY = false;
      }
    }

    if (adjustXY) {
      final Insets insets = myContent.getInsets();
      if (insets != null) {
        xy.x -= insets.left;
        xy.y -= insets.top;
      }
    }

    if (considerForcedXY && myForcedLocation != null) {
      xy = myForcedLocation;
    }

    if (myLocateByContent) {
      final Dimension captionSize = myHeaderPanel.getPreferredSize();
      xy.y -= captionSize.height;
    }

    Rectangle targetBounds = new Rectangle(xy, myContent.getPreferredSize());
    Insets insets = myPopupBorder.getBorderInsets(myContent);
    if (insets != null) {
      targetBounds.x += insets.left;
      targetBounds.y += insets.top;
    }

    Rectangle original = new Rectangle(targetBounds);
    if (myLocateWithinScreen) {
      ScreenUtil.moveRectangleToFitTheScreen(targetBounds);
    }

    if (myMouseOutCanceller != null) {
      myMouseOutCanceller.myEverEntered = targetBounds.equals(original);
    }

    myOwner = IdeFrameImpl.findNearestModalComponent(owner);
    if (myOwner == null) {
      myOwner = owner;
    }

    myRequestorComponent = owner;

    boolean forcedDialog = (SystemInfo.isMac && !(myOwner instanceof IdeFrame)) || myMayBeParent;

    PopupComponent.Factory factory = getFactory(myForcedHeavyweight || myResizable, forcedDialog);
    myNativePopup = factory.isNativePopup();
    myPopup = factory.getPopup(myOwner, myContent, targetBounds.x, targetBounds.y);

    if (myResizable) {
      final JRootPane root = myContent.getRootPane();
      final IdeGlassPaneImpl glass = new IdeGlassPaneImpl(root);
      root.setGlassPane(glass);

      final ResizeComponentListener resizeListener = new ResizeComponentListener(this, glass);
      glass.addMousePreprocessor(resizeListener, this);
      glass.addMouseMotionPreprocessor(resizeListener, this);
    }

    if (myCaption != null && myMovable) {
      final MoveComponentListener moveListener =
          new MoveComponentListener(myCaption) {
            public void mousePressed(final MouseEvent e) {
              super.mousePressed(e);
              if (e.isConsumed()) return;

              if (UIUtil.isCloseClick(e)) {
                if (myCaption.isWithinPanel(e)) {
                  cancel();
                }
              }
            }
          };
      ListenerUtil.addMouseListener(myCaption, moveListener);
      ListenerUtil.addMouseMotionListener(myCaption, moveListener);
      final MyContentPanel saved = myContent;
      Disposer.register(
          this,
          new Disposable() {
            public void dispose() {
              ListenerUtil.removeMouseListener(saved, moveListener);
              ListenerUtil.removeMouseMotionListener(saved, moveListener);
            }
          });
    }

    for (JBPopupListener listener : myListeners) {
      listener.beforeShown(new LightweightWindowEvent(this));
    }

    myPopup.setRequestFocus(myRequestFocus);
    myPopup.show();

    final Window window = SwingUtilities.getWindowAncestor(myContent);

    myWindowListener = new MyWindowListener();
    window.addWindowListener(myWindowListener);

    if (myFocusable) {
      window.setFocusableWindowState(true);
      window.setFocusable(true);
    }

    myWindow = updateMaskAndAlpha(window);

    if (myWindow instanceof JWindow) {
      ((JWindow) myWindow).getRootPane().putClientProperty(KEY, this);
    }

    if (myWindow != null) {
      // dialogwrapper-based popups do this internally through peer,
      // for other popups like jdialog-based we should exclude them manually, but
      // we still have to be able to use IdeFrame as parent
      if (!myMayBeParent && !(myWindow instanceof Frame)) {
        WindowManager.getInstance().doNotSuggestAsParent(myWindow);
      }
    }

    final Runnable afterShow =
        new Runnable() {
          public void run() {
            if (myPreferredFocusedComponent != null && myInStack && myFocusable) {
              myFocusTrackback.registerFocusComponent(myPreferredFocusedComponent);
            }

            removeActivity();

            afterShow();
          }
        };

    if (myRequestFocus) {
      getFocusManager()
          .requestFocus(
              new FocusCommand() {
                @Override
                public ActionCallback run() {
                  if (isDisposed()) {
                    removeActivity();
                    return new ActionCallback.Done();
                  }

                  _requestFocus();

                  final ActionCallback result = new ActionCallback();

                  final Runnable afterShowRunnable =
                      new Runnable() {
                        @Override
                        public void run() {
                          afterShow.run();
                          result.setDone();
                        }
                      };
                  if (myNativePopup) {
                    final FocusRequestor furtherRequestor = getFocusManager().getFurtherRequestor();
                    SwingUtilities.invokeLater(
                        new Runnable() {
                          @Override
                          public void run() {
                            if (isDisposed()) {
                              result.setRejected();
                              return;
                            }

                            furtherRequestor
                                .requestFocus(
                                    new FocusCommand() {
                                      @Override
                                      public ActionCallback run() {
                                        if (isDisposed()) {
                                          return new ActionCallback.Rejected();
                                        }

                                        _requestFocus();

                                        afterShowRunnable.run();

                                        return new ActionCallback.Done();
                                      }
                                    },
                                    true)
                                .notify(result)
                                .doWhenProcessed(
                                    new Runnable() {
                                      @Override
                                      public void run() {
                                        removeActivity();
                                      }
                                    });
                          }
                        });
                  } else {
                    afterShowRunnable.run();
                  }

                  return result;
                }
              },
              true)
          .doWhenRejected(
              new Runnable() {
                @Override
                public void run() {
                  afterShow.run();
                }
              });
    } else {
      SwingUtilities.invokeLater(
          new Runnable() {
            @Override
            public void run() {
              if (isDisposed()) {
                removeActivity();
                return;
              }

              afterShow.run();
            }
          });
    }
  }
  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;
  }