Skip to content

Commit 787f73d

Browse files
author
Cayci
committed
Display line numbers for the file being edited
1 parent 128678c commit 787f73d

File tree

2 files changed

+124
-7
lines changed

2 files changed

+124
-7
lines changed

app/src/processing/app/syntax/JEditTextArea.java

+39-7
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ public JEditTextArea(TextAreaDefaults defaults)
8787

8888
// Initialize some misc. stuff
8989
painter = new TextAreaPainter(this,defaults);
90+
editorLineNumbers = new TextAreaLineNumbers(defaults.font, defaults.bgcolor, defaults.fgcolor, (int) painter.getPreferredSize().getHeight());
9091
documentHandler = new DocumentHandler();
9192
eventListenerList = new EventListenerList();
9293
caretEvent = new MutableCaretEvent();
@@ -96,6 +97,7 @@ public JEditTextArea(TextAreaDefaults defaults)
9697

9798
// Initialize the GUI
9899
setLayout(new ScrollLayout());
100+
add(LEFT, editorLineNumbers);
99101
add(CENTER, painter);
100102
add(RIGHT, vertical = new JScrollBar(JScrollBar.VERTICAL));
101103
add(BOTTOM, horizontal = new JScrollBar(JScrollBar.HORIZONTAL));
@@ -315,6 +317,12 @@ public void updateScrollBars() {
315317
horizontal.setUnitIncrement(charWidth);
316318
horizontal.setBlockIncrement(width / 2);
317319
}
320+
updateLineNumbers();
321+
}
322+
323+
private void updateLineNumbers() {
324+
editorLineNumbers.updateLineNumbers(getFirstLine() + 1, Math.min(getFirstLine() + getVisibleLines() + 1, getLineCount()));
325+
editorLineNumbers.updateWidthForNumDigits(String.valueOf(getLineCount()).length());
318326
}
319327

320328
/**
@@ -335,7 +343,7 @@ public void setFirstLine(int firstLine) {
335343
if (firstLine != vertical.getValue()) {
336344
updateScrollBars();
337345
}
338-
painter.repaint();
346+
repaintEditor();
339347
}
340348

341349
/**
@@ -377,7 +385,7 @@ public void setHorizontalOffset(int horizontalOffset)
377385
this.horizontalOffset = horizontalOffset;
378386
if(horizontalOffset != horizontal.getValue())
379387
updateScrollBars();
380-
painter.repaint();
388+
repaintEditor();
381389
}
382390

383391
/**
@@ -407,12 +415,17 @@ public boolean setOrigin(int firstLine, int horizontalOffset)
407415
if(changed)
408416
{
409417
updateScrollBars();
410-
painter.repaint();
418+
repaintEditor();
411419
}
412420

413421
return changed;
414422
}
415423

424+
private void repaintEditor() {
425+
painter.repaint();
426+
updateLineNumbers();
427+
}
428+
416429
/**
417430
* Ensures that the caret is visible by scrolling the text area if
418431
* necessary.
@@ -732,7 +745,7 @@ public void setDocument(SyntaxDocument document) {
732745

733746
select(0, 0);
734747
updateScrollBars();
735-
painter.repaint();
748+
repaintEditor();
736749
}
737750

738751

@@ -753,7 +766,7 @@ public void setDocument(SyntaxDocument document,
753766
select(start, stop);
754767
updateScrollBars();
755768
setScrollPosition(scroll);
756-
painter.repaint();
769+
repaintEditor();
757770
}
758771

759772

@@ -1747,6 +1760,7 @@ public void processKeyEvent(KeyEvent evt) {
17471760
}
17481761

17491762
// protected members
1763+
protected static String LEFT = "left";
17501764
protected static String CENTER = "center";
17511765
protected static String RIGHT = "right";
17521766
protected static String BOTTOM = "bottom";
@@ -1755,6 +1769,7 @@ public void processKeyEvent(KeyEvent evt) {
17551769
protected static Timer caretTimer;
17561770

17571771
protected TextAreaPainter painter;
1772+
protected TextAreaLineNumbers editorLineNumbers;
17581773

17591774
//protected EditPopupMenu popup;
17601775
protected JPopupMenu popup;
@@ -1881,7 +1896,9 @@ class ScrollLayout implements LayoutManager
18811896

18821897
public void addLayoutComponent(String name, Component comp)
18831898
{
1884-
if(name.equals(CENTER))
1899+
if(name.equals(LEFT))
1900+
left = comp;
1901+
else if(name.equals(CENTER))
18851902
center = comp;
18861903
else if(name.equals(RIGHT))
18871904
right = comp;
@@ -1893,6 +1910,8 @@ else if(name.equals(LEFT_OF_SCROLLBAR))
18931910

18941911
public void removeLayoutComponent(Component comp)
18951912
{
1913+
if(left == comp)
1914+
left = null;
18961915
if(center == comp)
18971916
center = null;
18981917
if(right == comp)
@@ -1913,6 +1932,8 @@ public Dimension preferredLayoutSize(Container parent)
19131932
Dimension centerPref = center.getPreferredSize();
19141933
dim.width += centerPref.width;
19151934
dim.height += centerPref.height;
1935+
Dimension leftPref = left.getPreferredSize();
1936+
dim.width += leftPref.width;
19161937
Dimension rightPref = right.getPreferredSize();
19171938
dim.width += rightPref.width;
19181939
Dimension bottomPref = bottom.getPreferredSize();
@@ -1931,6 +1952,8 @@ public Dimension minimumLayoutSize(Container parent)
19311952
Dimension centerPref = center.getMinimumSize();
19321953
dim.width += centerPref.width;
19331954
dim.height += centerPref.height;
1955+
Dimension leftPref = left.getMinimumSize();
1956+
dim.width += leftPref.width;
19341957
Dimension rightPref = right.getMinimumSize();
19351958
dim.width += rightPref.width;
19361959
Dimension bottomPref = bottom.getMinimumSize();
@@ -1950,11 +1973,19 @@ public void layoutContainer(Container parent)
19501973
int ibottom = insets.bottom;
19511974
int iright = insets.right;
19521975

1976+
int leftWidth = left.getSize().width;
19531977
int rightWidth = right.getPreferredSize().width;
19541978
int bottomHeight = bottom.getPreferredSize().height;
1955-
int centerWidth = size.width - rightWidth - ileft - iright;
1979+
int centerWidth = size.width - leftWidth - rightWidth - ileft - iright;
19561980
int centerHeight = size.height - bottomHeight - itop - ibottom;
19571981

1982+
left.setBounds(ileft,
1983+
itop,
1984+
leftWidth,
1985+
centerHeight);
1986+
1987+
ileft += leftWidth;
1988+
19581989
center.setBounds(ileft, // + LEFT_EXTRA,
19591990
itop,
19601991
centerWidth, // - LEFT_EXTRA,
@@ -1984,6 +2015,7 @@ public void layoutContainer(Container parent)
19842015
}
19852016

19862017
// private members
2018+
private Component left;
19872019
private Component center;
19882020
private Component right;
19892021
private Component bottom;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/*
2+
* TextAreaLineNumbers.java - Show line numbers for the open file in the editor
3+
* Copyright (C) 2013 Cayci Gorlitsky
4+
*
5+
* You may use and modify this package for any purpose. Redistribution is
6+
* permitted, in both source and binary form, provided that this notice
7+
* remains intact in all source distributions of this package.
8+
*/
9+
10+
package processing.app.syntax;
11+
12+
import java.awt.Color;
13+
import java.awt.Dimension;
14+
import java.awt.Font;
15+
import java.awt.Rectangle;
16+
17+
import javax.swing.JTextPane;
18+
import javax.swing.border.MatteBorder;
19+
import javax.swing.text.SimpleAttributeSet;
20+
import javax.swing.text.StyleConstants;
21+
22+
public class TextAreaLineNumbers extends JTextPane {
23+
24+
private final int LEFT_INDENT = 6;
25+
private final int RIGHT_INDENT = 6;
26+
private final int RIGHT_BORDER_WIDTH = 1;
27+
private final int PADDING_WIDTH = LEFT_INDENT + RIGHT_INDENT + RIGHT_BORDER_WIDTH;
28+
29+
private final int MIN_WIDTH;
30+
private final int DIGIT_WIDTH;
31+
private final int MIN_NUM_DIGITS = 2;
32+
33+
private int currStartNum = 0;
34+
private int currEndNum = 0;
35+
private int currNumDigits = MIN_NUM_DIGITS;
36+
37+
public TextAreaLineNumbers(Font font, Color bgcolor, Color fgcolor, int preferredHeight) {
38+
setFont(font);
39+
setBackground(bgcolor);
40+
setForeground(fgcolor);
41+
setOpaque(true);
42+
setEditable(false);
43+
setEnabled(false);
44+
setBorder(new MatteBorder(0, 0, 0, 1, new Color(240, 240, 240)));
45+
46+
SimpleAttributeSet attribs = new SimpleAttributeSet();
47+
StyleConstants.setAlignment(attribs , StyleConstants.ALIGN_RIGHT);
48+
StyleConstants.setLeftIndent(attribs , 6);
49+
StyleConstants.setRightIndent(attribs , 6);
50+
setParagraphAttributes(attribs,true);
51+
52+
DIGIT_WIDTH = getFontMetrics(getFont()).stringWidth("0");
53+
MIN_WIDTH = DIGIT_WIDTH * MIN_NUM_DIGITS + PADDING_WIDTH;
54+
55+
setPreferredSize(new Dimension(MIN_WIDTH, preferredHeight));
56+
}
57+
58+
public void updateLineNumbers(int startNum, int endNum) {
59+
if (currStartNum == startNum && currEndNum == endNum) {
60+
return;
61+
}
62+
currStartNum = startNum;
63+
currEndNum = endNum;
64+
65+
StringBuilder sb = new StringBuilder();
66+
for (int i = startNum; i < endNum; i++) {
67+
sb.append(i).append("\n");
68+
}
69+
sb.append(endNum);
70+
setText(sb.toString());
71+
72+
invalidate();
73+
}
74+
75+
public void updateWidthForNumDigits(int numDigits) {
76+
if (currNumDigits == numDigits) {
77+
return;
78+
}
79+
currNumDigits = numDigits;
80+
81+
setBounds(new Rectangle(Math.max(MIN_WIDTH, DIGIT_WIDTH * numDigits + PADDING_WIDTH), getHeight()));
82+
invalidate();
83+
}
84+
85+
}

0 commit comments

Comments
 (0)