B4J Question MeasureMultiHeightText not working?

Andrew (Digitwell)

Well-Known Member
Licensed User
Longtime User
I have a Custom View which contains 3 labels. The contents resizes the height of the control based on the contents of the labels.

The custom view works fine on B4a and B4i but on B4j the labels are not resized.

Attached is a sample program which demonstrates the problem. In the real program I am reading the strings from a remote database.

I am using the code from here to MeasureMultiheightText in B4j.

Any ideas what I am doing wrong here.

Android output
1633952191780.png


B4j Output
1633952260053.png
 

Attachments

  • MeasureTextHeight.zip
    19.4 KB · Views: 165

Erel

B4X founder
Staff member
Licensed User
Longtime User
The problem is somewhere else. Check this code:
B4X:
private Sub setupcontents
    clv.Add(CreateAnEntry(clv.AsView.Width,"top","This is some text that should wrap in because it is longer than the width of the panel. Note it does not have any CR's in it","bot"),0)
    clv.Add(CreateAnEntry(clv.AsView.Width,"This is some text that should wrap in because it is longer than the width of the panel. Note it does not have any CR's in it","mid","bot"),0)
    clv.Add(CreateAnEntry(clv.AsView.Width,"top","mid","This is some text that should wrap in because it is longer than the width of the panel. Note it does not have any CR's in it"),0)
End Sub

private Sub CreateAnEntry(w As Int, t1 As String,t2 As String,t3 As String) As B4XView
    Dim p As B4XView = xui.CreatePanel("")
    Dim s As String = t1 & CRLF & t2 & CRLF & t3
    Dim fnt As B4XFont = xui.CreateDefaultFont(15)
    Dim height As Int = MeasureMultilineTextHeight(fnt, w - 10dip, s)
    p.SetLayoutAnimated(0, 0, 0, w, height + 10dip)
    Dim lbl As B4XView = XUIViewsUtils.CreateLabel
    lbl.As(Label).WrapText = True
    lbl.Font = fnt
    lbl.Text = s
    lbl.TextColor = xui.Color_Black
    p.AddView(lbl, 5dip, 5dip, w - 10dip, height)
    Return p
End Sub

#if b4j
Private Sub MeasureMultilineTextHeight (Font As Font, Width As Double, Text As String) As Double
    Dim jo As JavaObject = Me
    Return jo.RunMethod("MeasureMultilineTextHeight", Array(Font, Text, Width))
End Sub

#if Java
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import javafx.scene.text.Font;
import javafx.scene.text.TextBoundsType;
public double MeasureMultilineTextHeight(Font f, String text, double width) throws Exception {
  Method m = Class.forName("com.sun.javafx.scene.control.skin.Utils").getDeclaredMethod("computeTextHeight",
  Font.class, String.class, double.class, TextBoundsType.class);
  m.setAccessible(true);
  return (Double)m.invoke(null, f, text, width, TextBoundsType.LOGICAL_VERTICAL_CENTER);
  }
#End If
#End If
#End Region

1634018214529.png
 
Upvote 0

Andrew (Digitwell)

Well-Known Member
Licensed User
Longtime User
Ok, I got it to work.

I needed to change the parameters of the Measure functions to use B4xFont and B4xView.

B4X:
' Changed definition of lbl to b4xview from label
Public Sub MeasureMultiTextHeight(lbl As B4XView, width As Int, text As Object) As Int
    If (text.As(String).Length = 0) Then Return 0
    #if b4a
    Private su As StringUtils
    Return su.MeasureMultilineTextHeight(lbl, text)
    #else if b4i
    Dim plbl As Label
    plbl.Initialize("")
    plbl.Width = width
    plbl.Multiline = True
    XUIViewsUtils.SetTextOrCSBuilderToLabel(plbl,text)
    plbl.SizeToFit   
    Return plbl.Height
    #else if b4j
    Return MeasureMultilineTextHeight(lbl.Font, lbl.Width,text)
    #End If
    
End Sub
' Java Multi height text https://www.b4x.com/android/forum/threads/measure-multiline-text-height.84331/
#if b4j

'changed definition of fnt to b4xfont
Sub MeasureMultilineTextHeight (Font As B4XFont, Width As Double, Text As String) As Double
    Dim jo As JavaObject = Me
    Return jo.RunMethod("MeasureMultilineTextHeight", Array(Font, Text, Width))
End Sub


#if Java
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import javafx.scene.text.Font;
import javafx.scene.text.TextBoundsType;
public double MeasureMultilineTextHeight(Font f, String text, double width) throws Exception {
  Method m = Class.forName("com.sun.javafx.scene.control.skin.Utils").getDeclaredMethod("computeTextHeight",
  Font.class, String.class, double.class, TextBoundsType.class);
  m.setAccessible(true);
  return (Double)m.invoke(null, f, text, width, TextBoundsType.LOGICAL_VERTICAL_CENTER);
  }
#End If


#End If

#End Region
 
Upvote 0
Top