void () { Disposer.register(((EditorImpl)myEditor).getDisposable(), this); myEditor.getFoldingModel().addListener(new FoldingListener() { @Override public void onFoldProcessingEnd() { revalidateComponents(); } }, this); myEditor.getDocument().addDocumentListener(new DocumentListener() { private int linesBefore; @Override public void beforeDocumentChange(@NotNull DocumentEvent event) { linesBefore = event.getDocument().getLineCount(); } @Override public void documentChanged(@NotNull DocumentEvent event) { if (linesBefore != event.getDocument().getLineCount() && !event.getDocument().isInBulkUpdate()) { int y = myEditor.logicalPositionToXY(new LogicalPosition(event.getDocument().getLineNumber(event.getOffset()), 0)).y; revalidateComponents(y); } } @Override public void bulkUpdateFinished(@NotNull Document document) { revalidateComponents(); } }, this); myEditor.getInlayModel().addListener(new InlayModel.SimpleAdapter() { @Override public void onUpdated(@NotNull Inlay<?> inlay, int changeFlags) { if ((changeFlags & InlayModel.ChangeFlags.HEIGHT_CHANGED) != 0 && inlay.getRenderer() instanceof MyRenderer) { JComponent component = (JComponent)inlay.getRenderer(); // This method can be called while validating the same component. Prevent resetting parent validation flags. if (component.isValid()) { component.revalidate(); } } } @Override public void onRemoved(@NotNull Inlay<?> inlay) { Disposer.dispose(inlay); } }, this); ComponentAdapter viewportListener = new ComponentAdapter() { @Override public void componentResized(ComponentEvent e) { revalidateComponents(); } }; JViewport viewport = myEditor.getScrollPane().getViewport(); viewport.addComponentListener(viewportListener); Disposer.register(this, () -> viewport.removeComponentListener(viewportListener)); myEditor.addEditorMouseListener(myResizeListener); myEditor.addEditorMouseMotionListener(myResizeListener); }