Android Question java.lang.IllegalArgumentException

D

Deleted member 103

Guest
Hello,

With this class I can customize the lyrics of Label and Button, and it actually works very well.
In Google Report comes but from time to time this crash report.

Class clsTextResizer:
B4X:
Sub Class_Globals
    Private bmp As Bitmap
    Private cvs As Canvas

    Private stu As StringUtils
    Private dt As Float
    Private h, Height As Int
    Private w, Width As Int
End Sub

'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize
    bmp.InitializeMutable(1dip, 1dip)
    cvs.Initialize2(bmp)
End Sub

#Region TextSize vom Label, EditText und Button ändern

'Der Parameter "Scale" bei Buttons nicht verwendet!
Public Sub SetTextSize(obj As View, txt As String, scale As Float, singleline As Boolean)
    'Log("SetTextSize: txt=" & txt & " :obj=" & obj)

    'WICHTIG! Die Width darf nicht weniger als null sein!
    If obj.Width < 1dip Then Return

    setSingleLine(obj, singleline)

    If obj Is Button Then
        Dim btn As Button = obj
        Height = btn.Height - 14dip
        Width = btn.Width - 10dip

        SetButtonTextSize(btn, txt)
    Else
        Dim lbl As Label = obj
        Height = lbl.Height * scale
        Width = lbl.Width - 5dip
        
        SetLabelTextSize(lbl, txt)
    End If
End Sub

'Sets the TextView to single line
Public Sub setSingleLine(TextView As View, SingleLine As Boolean)
    Dim jo = TextView As JavaObject
    jo.RunMethod("setSingleLine", Array As Object(SingleLine))
End Sub

Private Sub SetButtonTextSize(btn As Button, txt As String)   
    btn.TextSize = 6
    dt = btn.TextSize
    h = stu.MeasureMultilineTextHeight(btn, txt)
    w = cvs.MeasureStringWidth(txt, btn.Typeface, dt)
    Do While h <= Height
        dt = dt + 1
        btn.TextSize = dt
        h = stu.MeasureMultilineTextHeight(btn, txt)
        w = cvs.MeasureStringWidth(txt, btn.Typeface, dt)
        
        If w >= Width Or h > Height Then
            btn.TextSize = dt - 2
            Exit
        End If
    Loop
End Sub

Private Sub SetLabelTextSize(lbl As Label, txt As String)   
    lbl.TextSize = 6
    dt = lbl.TextSize
    h = stu.MeasureMultilineTextHeight(lbl, txt)
    w = cvs.MeasureStringWidth(txt, lbl.Typeface, dt)
    Do While h <= Height
        dt = dt + 1
        lbl.TextSize = dt
        h = stu.MeasureMultilineTextHeight(lbl, txt)
        w = cvs.MeasureStringWidth(txt, lbl.Typeface, dt)

'        Log(txt & ": w=" & w & " ;h=" & h)
'        Log(txt & ": Width=" & Width & " ;Height=" & Height)
    
        If w > Width Or h > Height Then
            lbl.TextSize = dt - 1
            Exit
        End If
    Loop
End Sub

#End Region



It would be nice if someone might find the mistake.
 

Attachments

  • clstextresizer.java
    13 KB · Views: 261
D

Deleted member 103

Guest
Alright, thanks again.

I think that these checks should be enough now.

B4X:
'Der Parameter "Scale" bei Buttons nicht verwendet!
Public Sub SetTextSize(obj As View, txt As String, scale As Float, singleline As Boolean)
    'Log("SetTextSize: txt=" & txt & " :obj=" & obj)

    'WICHTIG! Object muss initialisiert sein!
    If Not(obj.IsInitialized) Then Return

    'WICHTIG! Die Width darf nicht weniger als null sein!
    If obj.Width < 10dip Then Return

    setSingleLine(obj, singleline)

    If obj Is Button Then
        Dim btn As Button = obj
        Height = btn.Height - 14dip
        Width = btn.Width - 10dip

        SetButtonTextSize(btn, txt)
    Else
        Dim lbl As Label = obj
        Height = lbl.Height * scale
        Width = lbl.Width - 5dip
        
        SetLabelTextSize(lbl, txt)
    End If
End Sub
 
Last edited by a moderator:
Upvote 0
D

Deleted member 103

Guest
Unfortunately, the last measures have not been enough.
After the implementation of crashlytics now these errors come.







Can that be the "1dpi" is too little?
B4X:
Public Sub Initialize
    bmp.InitializeMutable(1dip, 1dip)
    cvs.Initialize2(bmp)
End Sub
 
Upvote 0
D

Deleted member 103

Guest
OK, thanks, I'll try.
 
Upvote 0
D

Deleted member 103

Guest
Unfortunately, that was not enough.




 
Upvote 0
D

Deleted member 103

Guest
You need to debug your code and make sure never to call MeasureMultilineTextHeight with width or height < 10.
The problem is that I can not reproduce the error on my test devices.

That should have worked with this code already, right?

B4X:
    'WICHTIG! Die Width darf nicht weniger als null sein!
    If obj.Width < 10dip Then Return

B4X:
'Der Parameter "Scale" bei Buttons nicht verwendet!
Public Sub SetTextSize(obj As View, txt As String, scale As Float, singleline As Boolean)
    'Log("SetTextSize: txt=" & txt & " :obj=" & obj)

    'WICHTIG! Object muss initialisiert sein!
    If Not(obj.IsInitialized) Then Return

    'WICHTIG! Die Width darf nicht weniger als null sein!
    If obj.Width < 10dip Then Return

    setSingleLine(obj, singleline)

    If obj Is Button Then
        Dim btn As Button = obj
        Height = btn.Height - 14dip
        Width = btn.Width - 10dip

        SetButtonTextSize(btn, txt)
    Else
        Dim lbl As Label = obj
        Height = lbl.Height * scale
        Width = lbl.Width - 5dip
        
        SetLabelTextSize(lbl, txt)
    End If
End Sub
 
Upvote 0
D

Deleted member 103

Guest
The code is not the same. Where is the "while" loop?
That's still the same code from the top.
I just changed "bmp.InitializeMutable (1, 1) 'ignore", I did not want to be so petty.

B4X:
Sub Class_Globals
   Private bmp As Bitmap
   Private cvs As Canvas

   Private stu As StringUtils
   Private dt As Float
   Private h, Height As Int
   Private w, Width As Int
End Sub

'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize
   bmp.InitializeMutable(2, 2) 'ignore
   cvs.Initialize2(bmp)
End Sub

#Region TextSize vom Label, EditText und Button ändern

'Der Parameter "Scale" bei Buttons nicht verwendet!
Public Sub SetTextSize(obj As View, txt As String, scale As Float, singleline As Boolean)
   'Log("SetTextSize: txt=" & txt & " :obj=" & obj)

   'WICHTIG! Object muss initialisiert sein!
   If Not(obj.IsInitialized) Then Return

   'WICHTIG! Die Width darf nicht weniger als 10dip sein!
   If obj.Width < 10dip Then Return

   setSingleLine(obj, singleline)

   If obj Is Button Then
       Dim btn As Button = obj
       Height = btn.Height - 14dip
       Width = btn.Width - 10dip

       SetButtonTextSize(btn, txt)
   Else
       Dim lbl As Label = obj
       Height = lbl.Height * scale
       Width = lbl.Width - 5dip
       
       SetLabelTextSize(lbl, txt)
   End If
End Sub

'Sets the TextView to single line
Public Sub setSingleLine(TextView As View, SingleLine As Boolean)
   Dim jo = TextView As JavaObject
   jo.RunMethod("setSingleLine", Array As Object(SingleLine))
End Sub

Private Sub SetButtonTextSize(btn As Button, txt As String)   
   btn.TextSize = 6
   dt = btn.TextSize
   h = stu.MeasureMultilineTextHeight(btn, txt)
   w = cvs.MeasureStringWidth(txt, btn.Typeface, dt)
   Do While h <= Height
       dt = dt + 1
       btn.TextSize = dt
       h = stu.MeasureMultilineTextHeight(btn, txt)
       w = cvs.MeasureStringWidth(txt, btn.Typeface, dt)
       
       If w >= Width Or h > Height Then
           btn.TextSize = dt - 2
           Exit
       End If
   Loop
End Sub

Private Sub SetLabelTextSize(lbl As Label, txt As String)   
   lbl.TextSize = 6
   dt = lbl.TextSize
   h = stu.MeasureMultilineTextHeight(lbl, txt)
   w = cvs.MeasureStringWidth(txt, lbl.Typeface, dt)
   Do While h <= Height
       dt = dt + 1
       lbl.TextSize = dt
       h = stu.MeasureMultilineTextHeight(lbl, txt)
       w = cvs.MeasureStringWidth(txt, lbl.Typeface, dt)

'       Log(txt & ": w=" & w & " ;h=" & h)
'       Log(txt & ": Width=" & Width & " ;Height=" & Height)
   
       If w > Width Or h > Height Then
           lbl.TextSize = dt - 1
           Exit
       End If
   Loop
End Sub

#End Region
 
Upvote 0
D

Deleted member 103

Guest
That should have no impact normal, right?
The variable can become negative, but in this operational nothing should make.

B4X:
        If w > Width Or h > Height Then
            lbl.TextSize = dt - 1
            Exit
        End If

But I will change it anyway.
B4X:
'Der Parameter "Scale" bei Buttons nicht verwendet!
Public Sub SetTextSize(obj As View, txt As String, scale As Float, singleline As Boolean)
   'Log("SetTextSize: txt=" & txt & " :obj=" & obj)

   'WICHTIG! Object muss initialisiert sein!
   If Not(obj.IsInitialized) Then Return

   'WICHTIG! Die Width darf nicht weniger als 10dip sein!
   If obj.Width < 10dip Then Return

   setSingleLine(obj, singleline)

   If obj Is Button Then
       Dim btn As Button = obj
       Height = btn.Height
       Width = btn.Width
       If btn.Height > 14dip Then Height = btn.Height - 14dip
       If btn.Width > 10dip Then Width = btn.Width - 10dip

       SetButtonTextSize(btn, txt)
   Else
       Dim lbl As Label = obj
       Height = lbl.Height * scale
       Width = lbl.Width
       If btn.Width > 5dip Then Width = lbl.Width - 5dip
       
       SetLabelTextSize(lbl, txt)
   End If
End Sub
 
Last edited by a moderator:
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
That should have no impact normal, right?
This bug will cause your app to crash.

If obj.width = 11dip and you substract 10dip from it then the width will be 1dip. This is too small (as the padding is also subtracted).

You should make sure to never call MeasureMultilineTextHeight with very small width or height.
 
Upvote 0
D

Deleted member 103

Guest
I apologize, but I do not change the view size, I only change the variables "Height" and "Width" for the IF query.

This ensures the view is not smaller than 10dip.
B4X:
   'WICHTIG! Die Width darf nicht weniger als 10dip sein!
   If obj.Width < 10dip Then Return

and here it should not matter if the variable "Width" or "Height" is smaller than 10dip.
B4X:
Private Sub SetLabelTextSize(lbl As Label, txt As String)   
   lbl.TextSize = 6
   dt = lbl.TextSize
   h = stu.MeasureMultilineTextHeight(lbl, txt)
   w = cvs.MeasureStringWidth(txt, lbl.Typeface, dt)
   Do While h <= Height
       dt = dt + 1
       lbl.TextSize = dt
       h = stu.MeasureMultilineTextHeight(lbl, txt)
       w = cvs.MeasureStringWidth(txt, lbl.Typeface, dt)

'       Log(txt & ": w=" & w & " ;h=" & h)
'       Log(txt & ": Width=" & Width & " ;Height=" & Height)
  
       If w > Width Or h > Height Then
           lbl.TextSize = dt - 1
           Exit
       End If
   Loop
End Sub
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
I now understand. Why have you added these two variables? They don't seem to do anything useful.

Now for the correct answer:
The code of MeasureMultilineTextHeight subtracts the left and right paddings.

In the material theme the paddings of buttons are:
B4X:
Dim p() As Int = Button1.Padding
Log((p(0) + p(2)) / GetDeviceLayoutValues.Scale) '23dip

This means that your check is not good enough for buttons. Either set the padding to 0, 0, 0, 0 or make sure that buttons width is 30dip+.
 
Upvote 0
D

Deleted member 103

Guest
Thanks, now I understand it better.

Why have you added these two variables? They don't seem to do anything useful.
I have added this so that view size is not changed.
 
Upvote 0
Cookies are required to use this site. You must accept them to continue using the site. Learn more…