Search code examples
javaswtstyledtext

Calculate StyledText height using text content


Given a StyledText, initializied with SWT.MULTI and SWT.WRAP, I need to calculate the appropriate height hint based on the appropriate lines count for the content.

In this image you can see how the editor is resized when the content changes

enter image description here

The code that calculates the lines to display is the following

private int calcRealLinesCount() {
  final int componentWidth = styledText.getSize().x;
  final int dumbLinesCount = styledText.getLineCount();
  int realLinesCount = 0;

  for (int i = 0; i < dumbLinesCount; i++) {
    final String lineText = styledText.getLine(i);
    final Point lineTextExtent = styledTextGc.textExtent(lineText);
    final double lines = lineTextExtent.x / (double) componentWidth;
    realLinesCount += (int) Math.max(1D, Math.ceil(lines));
  }

  return Math.max(dumbLinesCount, realLinesCount);
}

The lines count is then used to get the appropriate height

((GridData) layoutData).heightHint = realLinesCount * fontHeight;

However, this code does not consider word wraps, and I cannot think of a way to do it.
Any ideas? Could I do this in a different way?


Solution

  • Thanks to Greg for the JFaceTextUtil#computeLineHeight hint.
    I could not use that directly, but I've at least learned how JFace does what I need.

    The following is what I'm using now to get a StyledText's line height:

    private int computeRealLineHeight(final int lineIndex) {
      final int startOffset = styledText.getOffsetAtLine(lineIndex);
      final String lineText = styledText.getLine(lineIndex);
    
      if (lineText.isEmpty()) {
        return styledText.getLineHeight(startOffset);
      }
    
      final int endOffset = startOffset + lineText.length() - 1;
      final Rectangle textBounds = styledText.getTextBounds(startOffset, endOffset);
      return textBounds.height;
    }