diff --git a/RSyntaxTextArea/src/main/java/org/fife/ui/rtextarea/Gutter.java b/RSyntaxTextArea/src/main/java/org/fife/ui/rtextarea/Gutter.java index a7e47c78f..5426fb4c8 100755 --- a/RSyntaxTextArea/src/main/java/org/fife/ui/rtextarea/Gutter.java +++ b/RSyntaxTextArea/src/main/java/org/fife/ui/rtextarea/Gutter.java @@ -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. */ @@ -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); @@ -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 true if the line numbers are enabled and visible. @@ -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.

* @@ -1004,6 +1036,8 @@ public void setTextArea(RTextArea textArea) { getCurrentLineNumberColor()); lineNumberList.setLineNumberingStartIndex( getLineNumberingStartIndex()); + lineNumberList.setLineNumberFormatter( + getLineNumberFormatter()); } else { lineNumberList.setTextArea(textArea); diff --git a/RSyntaxTextArea/src/main/java/org/fife/ui/rtextarea/LineNumberFormatter.java b/RSyntaxTextArea/src/main/java/org/fife/ui/rtextarea/LineNumberFormatter.java new file mode 100644 index 000000000..e98486fff --- /dev/null +++ b/RSyntaxTextArea/src/main/java/org/fife/ui/rtextarea/LineNumberFormatter.java @@ -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); +} diff --git a/RSyntaxTextArea/src/main/java/org/fife/ui/rtextarea/LineNumberList.java b/RSyntaxTextArea/src/main/java/org/fife/ui/rtextarea/LineNumberList.java index 336e00647..b06815cdf 100755 --- a/RSyntaxTextArea/src/main/java/org/fife/ui/rtextarea/LineNumberList.java +++ b/RSyntaxTextArea/src/main/java/org/fife/ui/rtextarea/LineNumberList.java @@ -82,6 +82,11 @@ 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. */ @@ -89,6 +94,7 @@ public class LineNumberList extends AbstractGutterComponent public static final Color DEFAULT_LINE_NUMBER_COLOR = Color.GRAY; + public static final LineNumberFormatter DEFAULT_LINE_NUMBER_FORMATTER = new SimpleLineNumberFormatter(); /** * Constructs a new LineNumberList using default values for @@ -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 @@ -392,7 +410,7 @@ protected void paintComponent(Graphics g) { int rhs = getWidth() - rhsBorderWidth; int line = topLine + 1; // TODO: Simplify me while (y= 10); + LineNumberFormatter formatter = getLineNumberFormatter() == null? + DEFAULT_LINE_NUMBER_FORMATTER: getLineNumberFormatter(); + int count = formatter.getMaxLength(lineCount); cellWidth += fontMetrics.charWidth('9')*(count+1) + 3; } } @@ -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; + } + } + + } diff --git a/RSyntaxTextAreaDemo/src/main/java/org/fife/ui/rsyntaxtextarea/demo/DemoRootPane.java b/RSyntaxTextAreaDemo/src/main/java/org/fife/ui/rsyntaxtextarea/demo/DemoRootPane.java index 0abf1f961..80cdecce3 100755 --- a/RSyntaxTextAreaDemo/src/main/java/org/fife/ui/rsyntaxtextarea/demo/DemoRootPane.java +++ b/RSyntaxTextAreaDemo/src/main/java/org/fife/ui/rsyntaxtextarea/demo/DemoRootPane.java @@ -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; /** @@ -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); @@ -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. */ @@ -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(); + } + } + }