Created
March 1, 2022 10:18
-
-
Save marius-m/26aba39c50062b34d1a0bf809858a350 to your computer and use it in GitHub Desktop.
Line count mechanism in JTextArea
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package lt.linecounter | |
import java.awt.Font | |
import java.awt.FontMetrics | |
import java.awt.Insets | |
import java.awt.font.LineBreakMeasurer | |
import java.awt.font.TextAttribute | |
import java.text.AttributedString | |
import java.text.BreakIterator | |
import javax.swing.JTextArea | |
class TextAreaLineCounter( | |
private val textArea: JTextArea | |
) { | |
private val font: Font | |
get() = textArea.font | |
private val fontMetrics: FontMetrics | |
get() = textArea.getFontMetrics(font) | |
private val insets: Insets | |
get() = textArea.insets | |
private val formatWidth: Float | |
get() = (textArea.width - insets.left - insets.right).toFloat() | |
fun countLines(): Int { | |
return countLinesInParagraphs( | |
textRaw = textArea.text, | |
font = font, | |
fontMetrics = fontMetrics, | |
formatWidth = formatWidth | |
) | |
} | |
private fun countLinesInParagraphs( | |
textRaw: String, | |
font: Font, | |
fontMetrics: FontMetrics, | |
formatWidth: Float | |
): Int { | |
val paragraphs: List<String> = textRaw.split("\n") | |
val lineCount = paragraphs.fold(0) { acc: Int, sentence: String -> | |
val newCount = acc + countLinesInSentence(sentence, font, fontMetrics, formatWidth) | |
newCount | |
} | |
return lineCount | |
} | |
private fun countLinesInSentence( | |
textRaw: String, | |
font: Font, | |
fontMetrics: FontMetrics, | |
formatWidth: Float | |
): Int { | |
val text = AttributedString(textRaw) | |
text.addAttribute(TextAttribute.FONT, font) | |
val frc = fontMetrics.fontRenderContext | |
val charIt = text.iterator | |
val lineMeasurer = LineBreakMeasurer( | |
charIt, | |
BreakIterator.getWordInstance(), | |
frc | |
) | |
lineMeasurer.position = charIt.beginIndex | |
var noLines = 0 | |
while (lineMeasurer.position < charIt.endIndex) { | |
lineMeasurer.nextLayout(formatWidth) | |
noLines++ | |
} | |
return noLines | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment