private static boolean fitsLayeredPane(
      JLayeredPane pane, JComponent component, RelativePoint desiredLocation, HintHint hintHint) {
    if (hintHint.isAwtTooltip()) {
      Dimension size = component.getPreferredSize();
      Dimension paneSize = pane.getSize();

      Point target = desiredLocation.getPointOn(pane).getPoint();
      Balloon.Position pos = hintHint.getPreferredPosition();
      int pointer = BalloonImpl.getPointerLength(pos, false) + BalloonImpl.getNormalInset();
      if (pos == Balloon.Position.above || pos == Balloon.Position.below) {
        boolean heightFit =
            target.y - size.height - pointer > 0
                || target.y + size.height + pointer < paneSize.height;
        return heightFit && size.width + pointer < paneSize.width;
      } else {
        boolean widthFit =
            target.x - size.width - pointer > 0 || target.x + size.width + pointer < paneSize.width;
        return widthFit && size.height + pointer < paneSize.height;
      }
    } else {
      final Rectangle lpRect =
          new Rectangle(
              pane.getLocationOnScreen().x,
              pane.getLocationOnScreen().y,
              pane.getWidth(),
              pane.getHeight());
      Rectangle componentRect =
          new Rectangle(
              desiredLocation.getScreenPoint().x,
              desiredLocation.getScreenPoint().y,
              component.getPreferredSize().width,
              component.getPreferredSize().height);
      return lpRect.contains(componentRect);
    }
  }
Пример #2
0
 public void showPopup() {
   layoutPopup();
   if (myVisible) {
     myPopupBalloon.getComponent().setVisible(true);
   } else {
     myPopupBalloon.show(myLayeredPane);
     myVisible = true;
   }
 }
Пример #3
0
  private void layoutPopup() {
    Dimension layeredSize = myLayeredPane.getSize();
    Dimension size = new Dimension(myPopupBalloon.getPreferredSize());
    Point location = myButtonLocation.compute();
    int x = layeredSize.width - size.width - 5;
    int fullHeight = location.y;

    if (x > location.x) {
      x = location.x - 20;
    }
    if (size.height > fullHeight) {
      size.height = fullHeight;
    }

    myPopupBalloon.setBounds(new Rectangle(x, fullHeight - size.height, size.width, size.height));
  }
  private void fixActualPoint(Point actualPoint) {
    if (!isAwtTooltip()) return;
    if (!myIsRealPopup) return;

    Dimension size = myComponent.getPreferredSize();
    Balloon.Position position = myHintHint.getPreferredPosition();
    int shift = BalloonImpl.getPointerLength(position, false);
    switch (position) {
      case below:
        actualPoint.y += shift;
        break;
      case above:
        actualPoint.y -= (shift + size.height);
        break;
      case atLeft:
        actualPoint.x -= (shift + size.width);
        break;
      case atRight:
        actualPoint.y += shift;
        break;
    }
  }
  /**
   * 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)));
    }
  }
Пример #6
0
  private void addToPopup(
      @NotNull final BalloonImpl balloon, @NotNull BalloonLayoutData layoutData) {
    layoutData.doLayout =
        new Runnable() {
          @Override
          public void run() {
            WelcomeBalloonLayoutImpl.this.layoutPopup();
          }
        };
    layoutData.configuration =
        layoutData.configuration.replace(
            JBUI.scale(myPopupBalloon == null ? 7 : 5), JBUI.scale(12));

    if (myPopupBalloon == null) {
      final JScrollPane pane =
          NotificationsManagerImpl.createBalloonScrollPane(myBalloonPanel, true);
      pane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
      pane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);

      pane.getVerticalScrollBar()
          .addComponentListener(
              new ComponentAdapter() {
                @Override
                public void componentShown(ComponentEvent e) {
                  pane.setBorder(
                      IdeBorderFactory.createEmptyBorder(SystemInfo.isMac ? 2 : 1, 0, 1, 1));
                }

                @Override
                public void componentHidden(ComponentEvent e) {
                  pane.setBorder(IdeBorderFactory.createEmptyBorder());
                }
              });

      myPopupBalloon =
          new BalloonImpl(
              pane,
              BORDER_COLOR,
              new Insets(0, 0, 0, 0),
              FILL_COLOR,
              true,
              false,
              false,
              false,
              true,
              0,
              false,
              false,
              null,
              false,
              0,
              0,
              0,
              0,
              false,
              null,
              null,
              false,
              false,
              false,
              null,
              false);
      myPopupBalloon.setAnimationEnabled(false);
      myPopupBalloon.setShadowBorderProvider(
          new NotificationBalloonShadowBorderProvider(FILL_COLOR, BORDER_COLOR));
      myPopupBalloon.setHideListener(
          new Runnable() {
            @Override
            public void run() {
              myPopupBalloon.getComponent().setVisible(false);
            }
          });
      myPopupBalloon.setActionProvider(
          new BalloonImpl.ActionProvider() {
            private BalloonImpl.ActionButton myAction;

            @NotNull
            @Override
            public List<BalloonImpl.ActionButton> createActions() {
              myAction =
                  myPopupBalloon
                  .new ActionButton(
                      AllIcons.Ide.Notification.Close, null, null, Consumer.EMPTY_CONSUMER);
              return Collections.singletonList(myAction);
            }

            @Override
            public void layout(@NotNull Rectangle bounds) {
              myAction.setBounds(0, 0, 0, 0);
            }
          });
    }

    myBalloonPanel.add(balloon.getContent());
    balloon.getContent().putClientProperty(TYPE_KEY, layoutData.type);
    Disposer.register(
        balloon,
        new Disposable() {
          @Override
          public void dispose() {
            myBalloons.remove(balloon);
            myBalloonPanel.remove(balloon.getContent());
            updatePopup();
          }
        });
    myBalloons.add(balloon);

    updatePopup();
  }