Displaying custom popups in RD mode that is sticky to the line

Hi there :wave:

Straight to the point - I wanted to create a popup that will stick to the line and persistent when scrolling away. And I want to make it working in RD mode.

I struggled a lot and found out eventually, that in RD mode the component structure is different and I need some other way. I found this:
PopupFactory.html#getPopup-java.awt.Component-java.awt.Component-int-int-

PopupFactory makes it possible to display a popup :rocket:

Now I’d like to access editors visible rect to know the bounds.
I tried editor.contentComponent.visibleRect but it returns width and height equal to 0.
To be precise: It returns zeros in RD mode. Returns correct values in the regular run.

Here is my result in the regular mode (and my goal):
scroll-away-ezgif.com-video-to-gif-converter

Can you help me? :pray:

Kind regards,
Mikołaj Kondratek

Hi @mik.kondratek,

For editors, it’s generally better to use offsets rather than component coordinates.

If you’re looking for a popup that sticks to a specific position and remains visible while scrolling, com.intellij.openapi.ui.popup.Balloon is a good option—it properly handles positioning even in RD mode.

Here’s an example of how you can create a popup that sticks to the caret position:

val position = VisualPosition(line, column) // Use LogicalPosition if needed
JBPopupFactory.getInstance()
  .createBalloonBuilder(content)
  .createBalloon()
  .show(object : PositionTracker<Balloon>(editor.contentComponent) {
    override fun recalculateLocation(balloon: Balloon): RelativePoint {
      // Convert stored position to editor coordinates
      return RelativePoint(editor.contentComponent, editor.visualPositionToXY(position))
    }
  }, Balloon.Position.above)
1 Like

Thanks Kate.

It’s good that it is super convenient to use. However, I noticed an issue. The popup overlaps top parts of the IDE and some bottom parts too (tool windows). It also sticks to the border when reached during the scroll. Looks kind of buggy. See the example:
overlaps-demo

Is it possible to keep it in the editor’s layer? So it’s position does not change even if we scroll so far away that the popup is no longer visible.