📄 navigabletextpane.java
字号:
/* * FindBugs - Find Bugs in Java programs * Copyright (C) 2006, University of Maryland * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston MA 02111-1307, USA */package edu.umd.cs.findbugs.sourceViewer;import java.awt.Container;import java.awt.Rectangle;import java.io.Serializable;import java.util.Collection;import java.util.Comparator;import java.util.PriorityQueue;import javax.swing.JTextPane;import javax.swing.SwingUtilities;import javax.swing.text.BadLocationException;import javax.swing.text.Document;import javax.swing.text.Element;import javax.swing.text.StyledDocument;import edu.umd.cs.findbugs.gui2.MainFrame;/** * @author tuc */public class NavigableTextPane extends JTextPane { public NavigableTextPane() { } public NavigableTextPane(StyledDocument doc) { super(doc); } /** return the height of the parent (which is presumably a JViewport). * If there is no parent, return this.getHeight(). */ private int parentHeight() { Container parent = getParent(); if (parent != null) return parent.getHeight(); return getHeight(); // entire pane height, may be huge } public int getLineOffset(int line) throws BadLocationException { return lineToOffset(line); } private int lineToOffset(int line) throws BadLocationException { Document d = getDocument(); try { Element element = d.getDefaultRootElement().getElement(line-1); if (element == null) throw new BadLocationException("line "+line+" does not exist", -line); return element.getStartOffset(); } catch (ArrayIndexOutOfBoundsException aioobe) { BadLocationException ble = new BadLocationException("line "+line+" does not exist", -line); ble.initCause(aioobe); throw ble; } } private int offsetToY(int offset) throws BadLocationException { Rectangle r = modelToView(offset); return r.y; } private int lineToY(int line) throws BadLocationException { return offsetToY( lineToOffset(line) ); } private void scrollYToVisibleImpl(int y, int margin) { final Rectangle r = new Rectangle(0, y-margin, 4, 2*margin); SwingUtilities.invokeLater( new Runnable() { public void run() { scrollRectToVisible(r); } }); } private void scrollLineToVisibleImpl(int line, int margin) { try { int y = lineToY(line); scrollYToVisibleImpl(y, margin); } catch (BadLocationException ble) { if (MainFrame.DEBUG) ble.printStackTrace(); } } /** scroll the specified line into view, with a margin of 'margin' pixels above and below */ public void scrollLineToVisible(int line, int margin) { int maxMargin = (parentHeight() - 20) / 2; if (margin > maxMargin) margin = Math.max(0, maxMargin); scrollLineToVisibleImpl(line, margin); } /** scroll the specified line into the middle third of the view */ public void scrollLineToVisible(int line) { int margin = parentHeight() / 3; scrollLineToVisibleImpl(line, margin); } /** scroll the specified primary lines into view, along * with as many of the other lines as is convenient */ public void scrollLinesToVisible(int startLine, int endLine, Collection<Integer> otherLines) { int startY, endY; try { startY = lineToY(startLine); } catch (BadLocationException ble) { if (MainFrame.DEBUG) ble.printStackTrace(); return; // give up } try { endY = lineToY(endLine); } catch (BadLocationException ble) { endY = startY; // better than nothing } int max = parentHeight() - 0; if (endY-startY > max) { endY = startY+max; } else if (otherLines!=null && otherLines.size() > 0) { int origin = startY + endY / 2; PriorityQueue<Integer> pq = new PriorityQueue<Integer>(otherLines.size(), new DistanceComparator(origin)); for (int line : otherLines) { int otherY; try { otherY = lineToY(line); } catch (BadLocationException ble) { continue; // give up on this one } pq.add(otherY); } while ( !pq.isEmpty() ) { int y = pq.remove(); int lo = Math.min(startY, y); int hi = Math.max(endY, y); if (hi-lo > max) break; else { startY = lo; endY = hi; } } } scrollYToVisibleImpl((startY+endY)/2, max/2); } public static class DistanceComparator implements Comparator<Integer>, Serializable { private final int origin; public DistanceComparator(int origin) { this.origin = origin; } /* Returns a negative integer, zero, or a positive integer as * the first argument is farther from, equadistant, or closer * to (respectively) the origin. * This sounds backwards, but this way closer values get a * higher priority in the priority queue. */ public int compare(Integer a, Integer b) { return Math.abs(b-origin) - Math.abs(a-origin); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -