自定義 LineNr extends JPanel 作為行號區,放置於 JScrollPane 左側(BorderLayout.WEST),文本區置於中央。覆寫 paint(Graphics g) 同步繪製行號。
paint() 結束後呼叫 LineNr.repaint() 觸發行號重繪。viewToModel() 轉換為文檔偏移量。Document.getDefaultRootElement().getElementIndex() 獲取起訖行號。public void paint(Graphics g) {
super.paint(g);
int start = pane.viewToModel(scrollPane.getViewport().getViewPosition());
int end = pane.viewToModel(new Point(
scrollPane.getViewport().getViewPosition().x + pane.getWidth(),
scrollPane.getViewport().getViewPosition().y + pane.getHeight()));
Document doc = pane.getDocument();
int startLine = doc.getDefaultRootElement().getElementIndex(start) + 1;
int endLine = doc.getDefaultRootElement().getElementIndex(end) + 1;
int fontHeight = g.getFontMetrics(pane.getFont()).getHeight();
int fontDesc = g.getFontMetrics(pane.getFont()).getDescent();
int y = pane.modelToView(start).y - scrollPane.getViewport().getViewPosition().y + fontHeight - fontDesc;
for (int line = startLine; line <= endLine; line++, y += fontHeight) {
g.drawString(Integer.toString(line), 0, y);
}
}
JFrame frame = new JFrame();
LineNr nr = new LineNr();
frame.add(nr, BorderLayout.WEST);
frame.add(nr.scrollPane, BorderLayout.CENTER);