B4J Question create label from code but wrap text and set size did not work

stephaniegl

New Member
I do create a label from code, and put it in a pane like this code below
B4X:
Public Sub make_Label(number As String, display As String) As Label
    Try
        Dim txtDesc As Label
        txtDesc.Initialize("txtDesc")
        
        Dim width As Double = Pane1.Width * 0.05
        Dim height As Double
        height = MeasureMultilineTextHeight(fx.DefaultFont(14),width,display)
        
        txtDesc.Font = fx.DefaultFont(14)
        txtDesc.Text=display
        txtDesc.WrapText=True
        txtDesc.Style =".label-enabled {-fx-text-fill: black;} .label-disabled {-fx-text-fill: black;}"
        
        Pane1.AddNode(txtDesc, 15dip, bblTop , width ,-1)
        bblTop = bblTop  + height + 10dip
    Catch
        Log(LastException)
    End Try
End Sub

If the label text width more than pane's width the label did not wrap the text and the label witdh did not set like the code.
For example if I input the text "Hello, this is the text to test if the label wrap text can wrap the text to multiline if the text is as long as this" the result in app like the attach pic.

Is anything wrong with my code or is there any solution for me?
 

zed

Active Member
Licensed User
Did you see that. It's a B4X library. It should work in B4J. (Post#4)
 
Upvote 0

stephaniegl

New Member
This is the solution to adjust the text size. In my problem, I need the text size as same as what I set first. But I need to adjust the size of label (not the text size) and adjust the text to be be wrap in the label.
 
Upvote 0

PaulMeuris

Well-Known Member
Licensed User
Did you find a solution?
If not, can you provide a project zip file with the code for the MeasureMultilineTextHeight subroutine?
The more information you add to your question, the better you can get the right help.
 
Upvote 0

PaulMeuris

Well-Known Member
Licensed User
You can use the MeasureText subroutine like in this example.
To make it all work the justify_text subroutine takes care of the wrapping.
Here's the code:
B4X:
Sub Class_Globals
    Private Root As B4XView
    Private xui As XUI
    Private fx As JFX
End Sub
Public Sub Initialize
    B4XPages.GetManager.LogEvents = True
End Sub
Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    Root.LoadLayout("MainPage")
    Dim top As Int = 100    ' position of the pane in root
    Dim left As Int = 50    ' position of the label in the pane
    Dim txt As String = $"this is a very long text to test the wrapping of the text in a label. There are more than one line of text to be displayed. Third line."$
    Dim pn As Pane = set_message(left,txt)
    Dim hpn As Int = pn.PrefHeight
    Root.AddView(pn,0,top,pn.Width,pn.Height)    ' the pane can also be added to a CustomListView
    top = top + hpn + 10
    Dim txt As String = $"Not so long second message."$
    Dim pn As Pane = set_message(left,txt)
    Root.AddView(pn,0,top,pn.Width,pn.Height)    ' the pane can also be added to a CustomListView (scrolling)
End Sub
Private Sub set_message(left As Int,msg As String) As Pane
    Dim pn As Pane
    pn.Initialize("")
    Dim lbl As Label
    lbl.Initialize("")
    lbl.Font = fx.DefaultFont(15)
    lbl.WrapText = True
    Dim strres As String = ""
    Dim lines As List = Regex.Split(Chr(10),msg)
    For j = 0 To lines.Size -1
        Dim result As List
        result.Initialize
        result = justify_text(lines.Get(j),80)        ' 80 = max. number of characters in one line
        For i = 0 To result.Size -1
            strres = strres & result.Get(i) & CRLF
        Next
    Next
    lbl.Text = strres
    Dim tm As TextMetric = MeasureText(lbl.text,fx.DefaultFont(15))    ' textmetric type in main module
    pn.SetLayoutAnimated(0, 0, 0, Round(tm.Width),Round(tm.Height)+10)
    lbl.PrefHeight = Round(tm.Height)
    CSSUtils.SetStyleProperty(lbl,"-fx-padding","3,0,0,3")
    CSSUtils.SetBorder(lbl,2,fx.Colors.Black,5)
    CSSUtils.SetBackgroundColor(lbl,fx.Colors.ARGB(255,196,255,182))
    pn.AddNode(lbl,left,0,lbl.Width,Round(tm.Height)+10)
    Return pn
End Sub
Public Sub MeasureText(Text As String,TFont As Font) As TextMetric
    Dim tm As TextMetric
    tm.Initialize
    Dim jo As JavaObject
    jo.InitializeNewInstance("javafx.scene.text.Text",Array(Text))
    jo.RunMethod("setFont",Array(TFont))
    tm.Width = jo.RunMethod("prefWidth",Array(-1.0))
    tm.Height = jo.RunMethod("prefHeight",Array(tm.Width))
    Return tm
End Sub
Public Sub justify_text(txt As String, len As Int) As List
    ' based on the article found on this website:
    ' https://www.malikbrowne.com/blog/text-justification-coding-question
    '
    Dim words As List = Regex.Split(" ",txt)
    Dim lines As List
    lines.Initialize
    Dim wordindex As Int = 0
    Do While wordindex < words.Size
        Dim w1 As String = words.Get(wordindex)
        Dim lettercount As Int = w1.Length
        Dim lastindex As Int = wordindex + 1
        Do While lastindex < words.Size
            Dim w2 As String = words.Get(lastindex)
            If w2.Length + lettercount + 1 > len Then Exit
            lettercount = lettercount + w2.Length + 1
            lastindex = lastindex + 1
        Loop
        ' add the words to a line and insert spaces
        Dim line As String = ""
        Dim diff As Int = lastindex - wordindex - 1
        If (lastindex = words.Size) Or (diff = 0) Then
            For i = wordindex To lastindex - 1
                line = line & words.Get(i) & " "
            Next
            line = line.SubString2(0,line.Length-1)        ' remove the last space
            For i = line.Length To len
                line = line & " "
            Next
        Else
            Dim spaces As Int = (len - lettercount) / diff
            Dim remainder As Int = (len - lettercount) Mod diff
            For i = wordindex To lastindex -1
                line = line & words.Get(i)
                If i < lastindex - 1 Then
                    Dim limit As Int
                    If i - wordindex < remainder Then
                        limit = spaces + 1
                    Else
                        limit = 0
                    End If
                    For j = 0 To limit
                        line = line & " "
                    Next
                End If
            Next
        End If
        lines.Add(line)
        wordindex = lastindex
    Loop
    Return lines
End Sub
Make sure to add the type variable in the Main module:
B4X:
    Type TextMetric(Width As Double, Height As Double)
You can also find the source code in the attachment (testenvironment73.zip)
NOTE: the CSSUtils are part of the XUI Views library.
 

Attachments

  • testenvironment73.zip
    3.6 KB · Views: 47
Last edited:
Upvote 0
Cookies are required to use this site. You must accept them to continue using the site. Learn more…