EditorEx () { ThreadingAssertions.assertEventDispatchThread(); EditorEx editor = createConsoleEditor(); registerConsoleEditorActions(editor); editor.getScrollPane().setBorder(IdeBorderFactory.createBorder(SideBorder.LEFT)); MouseAdapter mouseListener = new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { updateStickToEndState(editor, true); } @Override public void mouseDragged(MouseEvent e) { updateStickToEndState(editor, false); } @Override public void mouseWheelMoved(MouseWheelEvent e) { if (e.isShiftDown()) return; // ignore horizontal scrolling updateStickToEndState(editor, false); } }; editor.getScrollPane().addMouseWheelListener(mouseListener); editor.getScrollPane().getVerticalScrollBar().addMouseListener(mouseListener); editor.getScrollPane().getVerticalScrollBar().addMouseMotionListener(mouseListener); editor.getScrollingModel().addVisibleAreaListener(e -> { // There is a possible case that the console text is populated while the console is not shown (e.g., we're debugging and // 'Debugger' tab is active while 'Console' is not). It's also possible that newly added text contains long lines that // are soft-wrapped. We want to update viewport position then when the console becomes visible. Rectangle oldR = e.getOldRectangle(); if (oldR != null && oldR.height <= 0 && e.getNewRectangle().height > 0 && isStickingToEnd(editor)) { scrollToEnd(editor); } }); return editor; }