This is my solution thus far, the core principle centered around the fact that the line height returned by the FontMetrics
class in javafx is (marginally) off of the actual line height determined by a Text
node, which resulted in the basic idea of using this type of node as a helper.
Count lines with active wrap text
Basically determine the actual line height by using a helper Text
node for measurement, resetting and restoring the wrapping width on that helper and recording the change in height.
Count lines without active wrap text
This is the easiest: In that case the size of the paragraphs
property corresponds directly to the number of lines:
Putting it all together it could look something like this:
/**
* Calculates the current amount of rows in the textarea regardless
* of "wordWrap" set to {@code true} or {@code false}.
*
* @return the current count of rows; {@code 0} if the count could not be determined
*/
private int getRowCount() {
int currentRowCount = 0;
Text helper = new Text();
/*
* Little performance improvement: If "wrapText" is set to false, then the
* list of paragraphs directly corresponds to the line count, otherwise we need
* to get creative...
*/
if(this.textArea.isWrapText()) {
// text needs to be on the scene
Text text = (Text) textArea.lookup(".text");
if(text == null) {
return currentRowCount;
}
/*
* Now we just count the paragraphs: If the paragraph size is less
* than the current wrappingWidth then increment; Otherwise use our
* Text helper instance to calculate the change in height for the
* current paragraph with "wrappingWidth" set to the actual
* wrappingWidth of the TextArea text
*/
helper.setFont(textArea.getFont());
for (CharSequence paragraph : textArea.getParagraphs()) {
helper.setText(paragraph.toString());
Bounds localBounds = helper.getBoundsInLocal();
double paragraphWidth = localBounds.getWidth();
if(paragraphWidth > text.getWrappingWidth()) {
double oldHeight = localBounds.getHeight();
// this actually sets the automatic size adjustment into motion...
helper.setWrappingWidth(text.getWrappingWidth());
double newHeight = helper.getBoundsInLocal().getHeight();
// ...and we reset it after computation
helper.setWrappingWidth(0.0D);
int paragraphLineCount = Double.valueOf(newHeight / oldHeight).intValue();
currentRowCount += paragraphLineCount;
} else {
currentRowCount += 1;
}
}
} else {
currentRowCount = textArea.getParagraphs().size();
}
return currentRowCount;
}
Hope this helps!