B4J Question Labels/Textfields: Any updates about measuring the width?

Status
Not open for further replies.

KMatle

Expert
Licensed User
Longtime User
This snippet works for me but it's just a workaround. Are there any updates about measuring the needed width to show the complete text (single line)?

Note: I need to use TextFields in a TableView to let the user edit the data fast.

B4X:
Private Sub MeasureTextWidth (Text As String, Font As Font) As Float
  
    Dim lbl As Label
    lbl.Initialize("")
    lbl.Text = Text
    lbl.Font = Font
  
    MainForm.RootPane.AddNode(lbl, 0, 0, -1, -1) 'mBase is a B4XView panel.
    lbl.Snapshot
    lbl.RemoveNodeFromParent
    Return lbl.Width
End Sub
 

Daestrum

Expert
Licensed User
Longtime User
Not sure if this is accurate enough for you to use (it doesn't take into account font etc unless you set them)
B4X:
Dim txt As JavaObject
...
 txt.InitializeNewInstance("javafx.scene.text.Text",Array(st)) ' st is the string to measure
 Log(txt.RunMethodJO("getLayoutBounds",Null).runmethod("getWidth",Null))
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
Try this:
B4X:
Private  Sub MeasureTexWidthNoWrap(Text As String,ThisFont As Font) As Double
    Dim TB,Bounds As JavaObject
    TB.InitializeStatic("javafx.scene.text.TextBuilder")
    Bounds = TB.RunMethodJO("create",Null).RunMethodJO("text",Array(Text)).RunMethodJO("font",Array(ThisFont)).RunMethodJO("build",Null).RunMethodJO("getLayoutBounds",Null)
    Return Bounds.RunMethod("getWidth",Null)
End Sub
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
This looks promising and gives the same results as my first example, the applyCss method forces a layout pass on the Text object. From here : https://stackoverflow.com/questions/13015698/how-to-calculate-the-pixel-width-of-a-string-in-javafx

B4X:
Private  Sub MeasureTexWidth(Text As String,ThisFont As Font) As Double

    Dim TextObj As JavaObject
    TextObj.InitializeNewInstance("javafx.scene.text.Text",Array(Text))
    TextObj.RunMethod("setFont",Array(ThisFont))
    TextObj.RunMethod("applyCss",Null)
    Dim Bounds As JavaObject
    Bounds = TextObj.RunMethodJO("getLayoutBounds",Null)
    Return Bounds.RunMethod("getWidth",Null)
End Sub
 
Last edited:
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
you may need to add the offsets in the textfield for an exact fit, but they are easy to get
B4X:
asJO(tf).RunMethodJO("getInsets",Null).RunMethod("getLeft",Null) ' also getRight and add to width
 
Upvote 0

stevel05

Expert
Licensed User
Longtime User
If you are still using Java 7 you will need to replace the applyCss call with

B4X:
TextObj.RunMethod("snapshot",Array(Null,Null))
 
Upvote 0
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…