Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feature] possibility to implement custom line number formatting #518

Merged
merged 4 commits into from
Aug 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions RSyntaxTextArea/src/main/java/org/fife/ui/rtextarea/Gutter.java
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,11 @@ public class Gutter extends JPanel {
*/
private int lineNumberingStartIndex;

/**
* Formats line numbers into a string to be displayed.
*/
private LineNumberFormatter lineNumberFormatter;

/**
* The font used to render line numbers.
*/
Expand Down Expand Up @@ -152,6 +157,7 @@ public Gutter(RTextArea textArea) {
lineNumberColor = LineNumberList.DEFAULT_LINE_NUMBER_COLOR;
lineNumberFont = RTextArea.getDefaultFont();
lineNumberingStartIndex = 1;
lineNumberFormatter = LineNumberList.DEFAULT_LINE_NUMBER_FORMATTER;
iconRowHeaderInheritsGutterBackground = false;

setTextArea(textArea);
Expand Down Expand Up @@ -438,6 +444,17 @@ public int getLineNumberingStartIndex() {
return lineNumberingStartIndex;
}

/**
* Returns the line number formatter. The default value is
* {@link LineNumberList#DEFAULT_LINE_NUMBER_FORMATTER}
*
* @return The formatter
* @see #setLineNumberFormatter(LineNumberFormatter)
*/
public LineNumberFormatter getLineNumberFormatter() {
return lineNumberFormatter;
}


/**
* Returns <code>true</code> if the line numbers are enabled and visible.
Expand Down Expand Up @@ -919,6 +936,21 @@ public void setLineNumberingStartIndex(int index) {
}


/**
* Sets a custom line number formatter. Can be called when other number
* formats are needed like hindu-arabic numerals.
*
* @param formatter The new line number formatter
* @see #getLineNumberFormatter()
*/
public void setLineNumberFormatter(LineNumberFormatter formatter) {
if (formatter != lineNumberFormatter) {
lineNumberFormatter = formatter;
lineNumberList.setLineNumberFormatter(formatter);
}
}


/**
* Toggles whether line numbers are visible.<p>
*
Expand Down Expand Up @@ -1004,6 +1036,8 @@ public void setTextArea(RTextArea textArea) {
getCurrentLineNumberColor());
lineNumberList.setLineNumberingStartIndex(
getLineNumberingStartIndex());
lineNumberList.setLineNumberFormatter(
getLineNumberFormatter());
}
else {
lineNumberList.setTextArea(textArea);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* 29/07/2023
*
* LineNumber - Format line numbers into a comprehensible String.
*
* This library is distributed under a modified BSD license. See the included
* LICENSE file for details.
*/
package org.fife.ui.rtextarea;

/**
* Formats line numbers into a comprehensible String to be
* displayed to the user.
* */
public interface LineNumberFormatter {
/**
* Formats the given line number into a String.
*
* @param lineNumber the line number
* @return the formatted line number
*/
String format(int lineNumber);

/**
* Returns the maximum number of characters of any string returned
* by {@link #format} provided a certain maximum line number.
*
* @param maxLineNumber the maximum line number
* @return the maximum length
*/
int getMaxLength(int maxLineNumber);
}
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,19 @@ public class LineNumberList extends AbstractGutterComponent
*/
private int lineNumberingStartIndex;

/**
* Formats line numbers into a string to be displayed.
*/
private LineNumberFormatter lineNumberFormatter = DEFAULT_LINE_NUMBER_FORMATTER;

/**
* The color of current line number.
*/
private Color currentLineNumberColor;

public static final Color DEFAULT_LINE_NUMBER_COLOR = Color.GRAY;

public static final LineNumberFormatter DEFAULT_LINE_NUMBER_FORMATTER = new SimpleLineNumberFormatter();

/**
* Constructs a new <code>LineNumberList</code> using default values for
Expand Down Expand Up @@ -197,6 +203,18 @@ public int getLineNumberingStartIndex() {
}


/**
* Returns the line number formatter. The default value is
* {@link LineNumberList#DEFAULT_LINE_NUMBER_FORMATTER}
*
* @return The formatter
* @see #setLineNumberFormatter(LineNumberFormatter)
*/
public LineNumberFormatter getLineNumberFormatter() {
return lineNumberFormatter;
}


@Override
public Dimension getPreferredSize() {
int h = textArea!=null ? textArea.getHeight() : 100; // Arbitrary
Expand Down Expand Up @@ -392,7 +410,7 @@ protected void paintComponent(Graphics g) {
int rhs = getWidth() - rhsBorderWidth;
int line = topLine + 1; // TODO: Simplify me
while (y<visibleRect.y+visibleRect.height+ascent && line<=textArea.getLineCount()) {
String number = Integer.toString(line + getLineNumberingStartIndex() - 1);
String number = getLineNumberFormatter().format(line + getLineNumberingStartIndex() - 1);
int width = metrics.stringWidth(number);
if (currentLine + 1 == line + getLineNumberingStartIndex() - 1) {
Color color = currentLineNumberColor != null ? currentLineNumberColor :
Expand Down Expand Up @@ -659,6 +677,22 @@ public void setLineNumberingStartIndex(int index) {
}


/**
* Sets a custom line number formatter. Can be called when other number
* formats are needed like hindu-arabic numerals.
*
* @param formatter The new line number formatter
* @see #getLineNumberFormatter()
*/
public void setLineNumberFormatter(LineNumberFormatter formatter) {
if (formatter != lineNumberFormatter) {
lineNumberFormatter = formatter;
updateCellWidths();
repaint();
}
}


/**
* Sets the text area being displayed.
*
Expand Down Expand Up @@ -719,13 +753,11 @@ void updateCellWidths() {
Font font = getFont();
if (font!=null) {
FontMetrics fontMetrics = getFontMetrics(font);
int count = 0;
int lineCount = textArea.getLineCount() +
getLineNumberingStartIndex() - 1;
do {
lineCount = lineCount/10;
count++;
} while (lineCount >= 10);
LineNumberFormatter formatter = getLineNumberFormatter() == null?
DEFAULT_LINE_NUMBER_FORMATTER: getLineNumberFormatter();
int count = formatter.getMaxLength(lineCount);
cellWidth += fontMetrics.charWidth('9')*(count+1) + 3;
}
}
Expand Down Expand Up @@ -817,4 +849,23 @@ public void uninstall(RTextArea textArea) {
}


private static class SimpleLineNumberFormatter implements LineNumberFormatter {
@Override
public String format(int lineNumber) {
return Integer.toString(lineNumber);
}

@Override
public int getMaxLength(int maxLineNumber) {
int count = 0;
do {
maxLineNumber = maxLineNumber /10;
count++;
} while (maxLineNumber >= 10);

return count;
}
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
import org.fife.ui.rtextarea.FoldIndicatorStyle;
import org.fife.ui.rtextarea.Gutter;
import org.fife.ui.rtextarea.RTextScrollPane;
import org.fife.ui.rtextarea.LineNumberFormatter;
import org.fife.ui.rtextarea.LineNumberList;


/**
Expand Down Expand Up @@ -140,6 +142,18 @@ private JMenuBar createMenuBar() {
foldStyleSubMenu.add(classicStyleItem);
foldStyleSubMenu.add(modernStyleItem);
menu.add(foldStyleSubMenu);
JMenu lineNumberFormatSubMenu = new JMenu("Line Number Format");
JRadioButtonMenuItem normalStyleItem = new JRadioButtonMenuItem(
new LineNumberFormatAction("Normal", LineNumberList.DEFAULT_LINE_NUMBER_FORMATTER));
JRadioButtonMenuItem hinduArabicStyleItem = new JRadioButtonMenuItem(
new LineNumberFormatAction("Hindu-Arabic", new HinduArabicLineNumberFormatter()));
normalStyleItem.setSelected(true);
bg = new ButtonGroup();
bg.add(normalStyleItem);
bg.add(hinduArabicStyleItem);
lineNumberFormatSubMenu.add(normalStyleItem);
lineNumberFormatSubMenu.add(hinduArabicStyleItem);
menu.add(lineNumberFormatSubMenu);
JCheckBoxMenuItem cbItem = new JCheckBoxMenuItem(new CodeFoldingAction());
cbItem.setSelected(true);
menu.add(cbItem);
Expand Down Expand Up @@ -409,6 +423,25 @@ public void actionPerformed(ActionEvent e) {

}

/**
* Changes how line numbers are displayed.
*/
private class LineNumberFormatAction extends AbstractAction {

private final LineNumberFormatter formatter;

LineNumberFormatAction(String name, LineNumberFormatter formatter) {
this.formatter = formatter;
putValue(NAME, name);
}

@Override
public void actionPerformed(ActionEvent e) {
scrollPane.getGutter().setLineNumberFormatter(formatter);
}

}

/**
* Changes the look and feel of the demo application.
*/
Expand Down Expand Up @@ -561,5 +594,35 @@ public void actionPerformed(ActionEvent e) {

}

/**
* Formats line numbers into Hindu-Arabic numerals.
*/
private static class HinduArabicLineNumberFormatter implements LineNumberFormatter {
private static final String[] NUMERALS = {
"٠", "١", "٢", "٣", "٤", "٥", "٦", "٧", "٨", "٩"
};

@Override
public String format(int lineNumber) {
if (lineNumber == 0) {
return NUMERALS[0];
}

StringBuilder sb = new StringBuilder();
while (lineNumber > 0) {
int digit = lineNumber % 10;
sb.insert(0, NUMERALS[digit]);
lineNumber /= 10;
}

return sb.toString();
}

@Override
public int getMaxLength(int maxLineNumber) {
return String.valueOf(maxLineNumber).length();
}
}


}