/** * Selects a range of text in a text component. If the new selection is outside of the previous * viewable rectangle, then the view is centered around the new selection. * * @param textArea The text component whose selection is to be centered. * @param start The start of the range to select. * @param end The end of the range to select. */ private static void selectAndPossiblyCenter(JTextArea textArea, int start, int end) { textArea.setSelectionStart(start); textArea.setSelectionEnd(end); Rectangle r = null; try { r = textArea.modelToView(start); if (r == null) { // Not yet visible; i.e. JUnit tests return; } if (end != start) { r = r.union(textArea.modelToView(end)); } } catch (BadLocationException ble) { // Never happens ble.printStackTrace(); textArea.setSelectionStart(start); textArea.setSelectionEnd(end); return; } Rectangle visible = textArea.getVisibleRect(); // If the new selection is already in the view, don't scroll, // as that is visually jarring. if (visible.contains(r)) { textArea.setSelectionStart(start); textArea.setSelectionEnd(end); return; } visible.x = r.x - (visible.width - r.width) / 2; visible.y = r.y - (visible.height - r.height) / 2; Rectangle bounds = textArea.getBounds(); Insets i = textArea.getInsets(); bounds.x = i.left; bounds.y = i.top; bounds.width -= i.left + i.right; bounds.height -= i.top + i.bottom; if (visible.x < bounds.x) { visible.x = bounds.x; } if (visible.x + visible.width > bounds.x + bounds.width) { visible.x = bounds.x + bounds.width - visible.width; } if (visible.y < bounds.y) { visible.y = bounds.y; } if (visible.y + visible.height > bounds.y + bounds.height) { visible.y = bounds.y + bounds.height - visible.height; } textArea.scrollRectToVisible(visible); }
/** * Selects a range of text in a text component. If the new selection is outside of the previous * viewable rectangle, then the view is centered around the new selection. * * @param textArea The text component whose selection is to be centered. * @param start The start of the range to select. * @param end The end of the range to select. */ private static void selectAndPossiblyCenter(JTextArea textArea, int start, int end) { boolean foldsExpanded = false; if (textArea instanceof RSyntaxTextArea) { RSyntaxTextArea rsta = (RSyntaxTextArea) textArea; FoldManager fm = rsta.getFoldManager(); if (fm.isCodeFoldingSupportedAndEnabled()) { foldsExpanded = fm.ensureOffsetNotInClosedFold(start); foldsExpanded |= fm.ensureOffsetNotInClosedFold(end); } } textArea.setSelectionStart(start); textArea.setSelectionEnd(end); Rectangle r = null; try { r = textArea.modelToView(start); if (r == null) { // Not yet visible; i.e. JUnit tests return; } if (end != start) { r = r.union(textArea.modelToView(end)); } } catch (BadLocationException ble) { // Never happens ble.printStackTrace(); textArea.setSelectionStart(start); textArea.setSelectionEnd(end); return; } Rectangle visible = textArea.getVisibleRect(); // If the new selection is already in the view, don't scroll, // as that is visually jarring. if (!foldsExpanded && visible.contains(r)) { textArea.setSelectionStart(start); textArea.setSelectionEnd(end); return; } visible.x = r.x - (visible.width - r.width) / 2; visible.y = r.y - (visible.height - r.height) / 2; Rectangle bounds = textArea.getBounds(); Insets i = textArea.getInsets(); bounds.x = i.left; bounds.y = i.top; bounds.width -= i.left + i.right; bounds.height -= i.top + i.bottom; if (visible.x < bounds.x) { visible.x = bounds.x; } if (visible.x + visible.width > bounds.x + bounds.width) { visible.x = bounds.x + bounds.width - visible.width; } if (visible.y < bounds.y) { visible.y = bounds.y; } if (visible.y + visible.height > bounds.y + bounds.height) { visible.y = bounds.y + bounds.height - visible.height; } textArea.scrollRectToVisible(visible); }
private static int getTextAreaBaseline(JTextArea text, int height) { Insets insets = text.getInsets(); FontMetrics fm = text.getFontMetrics(text.getFont()); return insets.top + fm.getAscent(); }