I'm trying to reliably count the number of lines (including those from line wraps and line breaks) in a JTextArea given a set width. I'm using this information to set the height of other components in my GUI (for example, for n lines, set n*height of a component).
I stumbled across this solution (reproduced below) but there is a problem with this. Sometimes it would miss a line if there isn't too much text on that line. For example, if a JTextArea of width 100 has 3 lines of text and on the 3rd line it only has say around width 15 of text, then it will only count 2 lines instead of 3.
public class MyTextArea extends JTextArea {
//...
public int countLines(int width) {
AttributedString text = new AttributedString(this.getText());
FontRenderContext frc = this.getFontMetrics(this.getFont()).getFontRenderContext();
AttributedCharacterIterator charIt = text.getIterator();
LineBreakMeasurer lineMeasurer = new LineBreakMeasurer(charIt, frc);
lineMeasurer.setPosition(charIt.getBeginIndex());
int noLines = 0;
while (lineMeasurer.getPosition() < charIt.getEndIndex()) {
lineMeasurer.nextLayout(width);
noLines++;
}
System.out.print("there are " + noLines + "lines" + System.getProperty("line.separator"));
return noLines;
}
}
Any idea what might be causing this issue? Are there any alternatives to counting lines in a JTextArea? Thanks.
So I came up with a simple solution that uses FontMetrics to calculate the display width of the text, and by splitting the text into string tokens, I can count how many lines there will be.
public int countLines(int width) {
FontMetrics fontMetrics = this.getFontMetrics(this.getFont());
String text = this.getText();
String[] tokens = text.split(" ");
String currentLine = "";
boolean beginningOfLine = true;
int noLines = 1;
for (int i = 0; i < tokens.length; i++) {
if (beginningOfLine) {
beginningOfLine = false;
currentLine = currentLine + tokens[i];
} else {
currentLine = currentLine + " " + tokens[i];
}
if (fontMetrics.stringWidth(currentLine) > width) {
currentLine = "";
beginningOfLine = true;
noLines++;
}
}
System.out.print("there are " + noLines + "lines" + System.getProperty("line.separator"));
return noLines;
}