Android Question B4XProgressBar java.lang.NullPointerException

RB Smissaert

Well-Known Member
Licensed User
Longtime User
Trying out this class:

https://www.b4x.com/android/forum/threads/b4x-xui-b4xprogressbar.90826/

I am using the unaltered class and use it like this from Main:

B4X:
Sub TestProgressBar
 Dim i As Int
 pnlFindPat.LoadLayout("progressbar")
 ProgressBar1.Initialize("Main", "B4XProgressBar1")
 For i = 0 To 100
  ProgressBar1.Progress = i
  Sleep(100)
 Next
End Sub

All is fine up to the ProgressBar1.Progress = i (the progressbar shows in the panel) and then gives me the mentioned error in this code in the class:

B4X:
Private Sub DrawValue(Value As Float)
 Log("DrawValue, cvs.TargetView.Tag: " & cvs.TargetView.Tag) 'this is fine
 Log("DrawValue, cvs.TargetRect.Width: " & cvs.TargetRect.Width) 'this is fine
 cvs.ClearRect(cvs.TargetRect)  '<<<<<< error here: java.lang.NullPointerException: null receiver
 If vertical Then
  cvs.DrawLine(cvs.TargetRect.CenterX, 0, cvs.TargetRect.CenterX, cvs.TargetRect.Bottom, bcolor, thickness)
  cvs.DrawLine(cvs.TargetRect.CenterX, 0, cvs.TargetRect.CenterX,  Value / 100 * cvs.TargetRect.Bottom, pcolor, thickness)
 Else
  cvs.DrawLine(0, cvs.TargetRect.CenterY, cvs.TargetRect.Right, cvs.TargetRect.CenterY, bcolor, thickness)
  cvs.DrawLine(0, cvs.TargetRect.CenterY, Value / 100 * cvs.TargetRect.Right, cvs.TargetRect.CenterY, pcolor, thickness)
 End If
 cvs.Invalidate
End Sub

The posted example (in the above URL) works fine.

Any idea what could be the problem here?

RBS
 

jimmyF

Active Member
Licensed User
Longtime User
Do you find that you absolutely need the Sleep(100) command?

I would try it without, just from experiences I have had using sleep, when calling Drawing routines.
 
Upvote 0

RB Smissaert

Well-Known Member
Licensed User
Longtime User
You should add the ProgressBar in the Designer and
remove ProgressBar1.Initialize("Main", "B4XProgressBar1") from the code.

The ProgressBar is added in the designer.
I only added the initialize to the code as I had the mentioned problem.
Removing the initialize from the code makes no difference.

RBS
 
Upvote 0

klaus

Expert
Licensed User
Longtime User
I copied your routine into Erels' demo program, without the ProgressBar1.Initialize("Main", "B4XProgressBar1") line and adapting the view name.
And it works.
So, the problem must be somewhere else.
Post your project so we could have a look at and find where the problem is.
 
Upvote 0

RB Smissaert

Well-Known Member
Licensed User
Longtime User
I copied your routine into Erels' demo program, without the ProgressBar1.Initialize("Main", "B4XProgressBar1") line and adapting the view name.
And it works.
So, the problem must be somewhere else.
Post your project so we could have a look at and find where the problem is.

Yes, I expected that should work and I know the problem is somewhere else.
Problem is that this is a very large project, so I can't post it.

Not sure it is relevant, but I have this in the log:
Class not found: b4a.example.b4xprogressbar, trying: b4a.project1.b4xprogressbar
and sofar been unable to get rid of it. I removed the class and readded it (making a completely new class, so not
adding an existing one), but no success.

RBS
 
Upvote 0

AnandGupta

Expert
Licensed User
Longtime User
Yes, I expected that should work and I know the problem is somewhere else.
Problem is that this is a very large project, so I can't post it.

When the project is large to be posted, then you will have to debug and fix it yourself. I can give my suggestion of how I debug large projects for this type of errors occurring after adding some new codes/functions/libraries.

  1. disable/comment out all codes but the most relevant ones.
  2. add logs for functions which will be performed.
  3. keep the progress bar related code, this is giving error.
  4. if it works OK, then start commenting/ enabling the codes one by one.
I understand, you know these steps but this is the only way as of now.

Regards,

Anand
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
Class not found: b4a.example.b4xprogressbar, trying: b4a.project1.b4xprogressbar
Do NOT use layouts from another app in yours.

Create a new layout for your app.
 
Upvote 0

RB Smissaert

Well-Known Member
Licensed User
Longtime User
When the project is large to be posted, then you will have to debug and fix it yourself. I can give my suggestion of how I debug large projects for this type of errors occurring after adding some new codes/functions/libraries.

  1. disable/comment out all codes but the most relevant ones.
  2. add logs for functions which will be performed.
  3. keep the progress bar related code, this is giving error.
  4. if it works OK, then start commenting/ enabling the codes one by one.
I understand, you know these steps but this is the only way as of now.

Regards,

Anand
Thanks.
I think I will need to fix the mentioned "class not found" problem first.

RBS
 
Upvote 0

RB Smissaert

Well-Known Member
Licensed User
Longtime User
The class not found warning should be ignored. It will be removed in the next version of B4A.

Where is the full error message?

This is the full error log:

Error occurred on line: 102 (B4XProgressBar)
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.graphics.RectF.round(android.graphics.Rect)' on a null object reference
at anywheresoftware.b4a.objects.B4XCanvas$B4XRect.toRect(B4XCanvas.java:164)
at anywheresoftware.b4a.objects.B4XCanvas.ClearRect(B4XCanvas.java:93)
at b4a.sqlitelight1.b4xprogressbar._drawvalue(b4xprogressbar.java:250)
at b4a.sqlitelight1.b4xprogressbar._setprogress(b4xprogressbar.java:84)
at b4a.sqlitelight1.main$ResumableSub_TestProgressBar.resume(main.java:8636)
at b4a.sqlitelight1.main._testprogressbar(main.java:8605)
at b4a.sqlitelight1.main._actionbar_menuitemclick(main.java:1466)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:732)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:351)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:144)
at anywheresoftware.b4a.BA$1.run(BA.java:335)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:6981)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1445)

Line 102 is this in
Private Sub DrawValue(Value As Float)

B4X:
cvs.ClearRect(oRect)

I added some logs to the class and can see that somewhere the passed customview (the progressbar) becomes un-initialized:

B4XProgressBar, Initialize
1 DesignerCreateView, mBase.IsInitialized: true
2 DesignerCreateView, mBase.IsInitialized: true
3 DesignerCreateView, mBase.IsInitialized: true
1 DrawValue, mBase.IsInitialized: true
2 DrawValue, mBase.IsInitialized: true
4 DesignerCreateView, mBase.IsInitialized: true
B4XProgressBar, DesignerCreateView
1 setProgress, mBase.IsInitialized: false

I simplified the class a bit, but get same error with the original code:

B4X:
#DesignerProperty: Key: BackgroundColor, DisplayName: Background Color, FieldType: Color, DefaultValue: 0xFF757575, Description: 
#DesignerProperty: Key: ProgressColor, DisplayName: Progress Color, FieldType: Color, DefaultValue: 0xFF38B8FF, Description: 
#DesignerProperty: Key: Thickness, DisplayName: Thickness, FieldType: Int, DefaultValue: 5, Description: 
#DesignerProperty: Key: Orientation, DisplayName: List Orientation, FieldType: String, DefaultValue: Horizontal, List: Vertical|Horizontal

Sub Class_Globals
 
 Private mEventName As String 'ignore
 Private mCallBack As Object 'ignore
 Private mBase As B4XView 'ignore
 Private xui As XUI 'ignore
 Private bcolor, pcolor As Int
 Private thickness As Float
 Private cvs As B4XCanvas
 Private oRect As B4XRect
 Private vertical As Boolean
 Private currentValue As Float
 Private DurationFromZeroTo100 As Int = 500
 
End Sub

Public Sub Initialize (Callback As Object, EventName As String)
 mEventName = EventName
 mCallBack = Callback
 Log("B4XProgressBar, Initialize")
End Sub

'Base type must be Object
Public Sub DesignerCreateView (Base As Object, Lbl As Label, Props As Map)
 mBase = Base
 Log("1 DesignerCreateView, mBase.IsInitialized: " & mBase.IsInitialized)
 bcolor = xui.PaintOrColorToColor(Props.Get("BackgroundColor"))
 pcolor = xui.PaintOrColorToColor(Props.Get("ProgressColor"))
 thickness = DipToCurrent(Props.Get("Thickness"))
 vertical = Props.Get("Orientation") = "Vertical"
 cvs.Initialize(mBase)
 Log("2 DesignerCreateView, mBase.IsInitialized: " & mBase.IsInitialized)
 oRect = cvs.TargetRect
 Log("3 DesignerCreateView, mBase.IsInitialized: " & mBase.IsInitialized)
 Base_Resize(mBase.Width, mBase.Height)
 Log("4 DesignerCreateView, mBase.IsInitialized: " & mBase.IsInitialized)
 Log("B4XProgressBar, DesignerCreateView")
End Sub

Private Sub Base_Resize (Width As Double, Height As Double)
 cvs.Resize(Width, Height)
 'AnimateValueTo(currentValue)
 DrawValue(currentValue)
End Sub

Public Sub getProgress As Float
 Return currentValue
End Sub

Public Sub setProgress(v As Float)
 'AnimateValueTo(v)
 Log("1 setProgress, mBase.IsInitialized: " & mBase.IsInitialized)
 DrawValue(v)
 Log("2 setProgress, mBase.IsInitialized: " & mBase.IsInitialized)
End Sub

Private Sub DrawValue(Value As Float)

 cvs.ClearRect(oRect) 'error here: java.lang.NullPointerException: Attempt to invoke virtual method 'android.graphics.Rect                              'anywheresoftware.b4a.objects.B4XCanvas$B4XRect.toRect()' on a null object reference
 Log("2 DrawValue, mBase.IsInitialized: " & mBase.IsInitialized)
 If vertical Then
  cvs.DrawLine(oRect.CenterX, 0, oRect.CenterX, oRect.Bottom, bcolor, thickness)
  cvs.DrawLine(oRect.CenterX, 0, oRect.CenterX,  Value / 100 * oRect.Bottom, pcolor, thickness)
 Else
  cvs.DrawLine(0, oRect.CenterY, oRect.Right, oRect.CenterY, bcolor, thickness)
  cvs.DrawLine(0, oRect.CenterY, Value / 100 * oRect.Right, oRect.CenterY, pcolor, thickness)
 End If
 cvs.Invalidate
End Sub

This is the calling code from Main:

B4X:
Sub TestProgressBar
 Dim i As Int
 pnlFindPat.LoadLayout("ProgressBar")
 ProgressBar1.Progress = 100
 For i = 1 To 100
  ProgressBar1.Progress = i
  Sleep(100)
 Next
End Sub


RBS
 
Upvote 0

RB Smissaert

Well-Known Member
Licensed User
Longtime User
This is the full error log:

Error occurred on line: 102 (B4XProgressBar)
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.graphics.RectF.round(android.graphics.Rect)' on a null object reference
at anywheresoftware.b4a.objects.B4XCanvas$B4XRect.toRect(B4XCanvas.java:164)
at anywheresoftware.b4a.objects.B4XCanvas.ClearRect(B4XCanvas.java:93)
at b4a.sqlitelight1.b4xprogressbar._drawvalue(b4xprogressbar.java:250)
at b4a.sqlitelight1.b4xprogressbar._setprogress(b4xprogressbar.java:84)
at b4a.sqlitelight1.main$ResumableSub_TestProgressBar.resume(main.java:8636)
at b4a.sqlitelight1.main._testprogressbar(main.java:8605)
at b4a.sqlitelight1.main._actionbar_menuitemclick(main.java:1466)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:732)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:351)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
at java.lang.reflect.Method.invoke(Native Method)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:144)
at anywheresoftware.b4a.BA$1.run(BA.java:335)
at android.os.Handler.handleCallback(Handler.java:873)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:6981)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1445)

Line 102 is this in
Private Sub DrawValue(Value As Float)

B4X:
cvs.ClearRect(oRect)

I added some logs to the class and can see that somewhere the passed customview (the progressbar) becomes un-initialized:

B4XProgressBar, Initialize
1 DesignerCreateView, mBase.IsInitialized: true
2 DesignerCreateView, mBase.IsInitialized: true
3 DesignerCreateView, mBase.IsInitialized: true
1 DrawValue, mBase.IsInitialized: true
2 DrawValue, mBase.IsInitialized: true
4 DesignerCreateView, mBase.IsInitialized: true
B4XProgressBar, DesignerCreateView
1 setProgress, mBase.IsInitialized: false

I simplified the class a bit, but get same error with the original code:

B4X:
#DesignerProperty: Key: BackgroundColor, DisplayName: Background Color, FieldType: Color, DefaultValue: 0xFF757575, Description:
#DesignerProperty: Key: ProgressColor, DisplayName: Progress Color, FieldType: Color, DefaultValue: 0xFF38B8FF, Description:
#DesignerProperty: Key: Thickness, DisplayName: Thickness, FieldType: Int, DefaultValue: 5, Description:
#DesignerProperty: Key: Orientation, DisplayName: List Orientation, FieldType: String, DefaultValue: Horizontal, List: Vertical|Horizontal

Sub Class_Globals
 
 Private mEventName As String 'ignore
 Private mCallBack As Object 'ignore
 Private mBase As B4XView 'ignore
 Private xui As XUI 'ignore
 Private bcolor, pcolor As Int
 Private thickness As Float
 Private cvs As B4XCanvas
 Private oRect As B4XRect
 Private vertical As Boolean
 Private currentValue As Float
 Private DurationFromZeroTo100 As Int = 500
 
End Sub

Public Sub Initialize (Callback As Object, EventName As String)
 mEventName = EventName
 mCallBack = Callback
 Log("B4XProgressBar, Initialize")
End Sub

'Base type must be Object
Public Sub DesignerCreateView (Base As Object, Lbl As Label, Props As Map)
 mBase = Base
 Log("1 DesignerCreateView, mBase.IsInitialized: " & mBase.IsInitialized)
 bcolor = xui.PaintOrColorToColor(Props.Get("BackgroundColor"))
 pcolor = xui.PaintOrColorToColor(Props.Get("ProgressColor"))
 thickness = DipToCurrent(Props.Get("Thickness"))
 vertical = Props.Get("Orientation") = "Vertical"
 cvs.Initialize(mBase)
 Log("2 DesignerCreateView, mBase.IsInitialized: " & mBase.IsInitialized)
 oRect = cvs.TargetRect
 Log("3 DesignerCreateView, mBase.IsInitialized: " & mBase.IsInitialized)
 Base_Resize(mBase.Width, mBase.Height)
 Log("4 DesignerCreateView, mBase.IsInitialized: " & mBase.IsInitialized)
 Log("B4XProgressBar, DesignerCreateView")
End Sub

Private Sub Base_Resize (Width As Double, Height As Double)
 cvs.Resize(Width, Height)
 'AnimateValueTo(currentValue)
 DrawValue(currentValue)
End Sub

Public Sub getProgress As Float
 Return currentValue
End Sub

Public Sub setProgress(v As Float)
 'AnimateValueTo(v)
 Log("1 setProgress, mBase.IsInitialized: " & mBase.IsInitialized)
 DrawValue(v)
 Log("2 setProgress, mBase.IsInitialized: " & mBase.IsInitialized)
End Sub

Private Sub DrawValue(Value As Float)

 cvs.ClearRect(oRect) 'error here: java.lang.NullPointerException: Attempt to invoke virtual method 'android.graphics.Rect                              'anywheresoftware.b4a.objects.B4XCanvas$B4XRect.toRect()' on a null object reference
 Log("2 DrawValue, mBase.IsInitialized: " & mBase.IsInitialized)
 If vertical Then
  cvs.DrawLine(oRect.CenterX, 0, oRect.CenterX, oRect.Bottom, bcolor, thickness)
  cvs.DrawLine(oRect.CenterX, 0, oRect.CenterX,  Value / 100 * oRect.Bottom, pcolor, thickness)
 Else
  cvs.DrawLine(0, oRect.CenterY, oRect.Right, oRect.CenterY, bcolor, thickness)
  cvs.DrawLine(0, oRect.CenterY, Value / 100 * oRect.Right, oRect.CenterY, pcolor, thickness)
 End If
 cvs.Invalidate
End Sub

This is the calling code from Main:

B4X:
Sub TestProgressBar
 Dim i As Int
 pnlFindPat.LoadLayout("ProgressBar")
 ProgressBar1.Progress = 100
 For i = 1 To 100
  ProgressBar1.Progress = i
  Sleep(100)
 Next
End Sub


RBS

Solved this now and the answer was simple. I considered B4XProgressBar was a simple class, so I could instantiate with any name as normally you can with classes.
So I did in Main: Private ProgressBar1 as B4XProgressBar
I should do instead: Private B4XProgressBar1 As B4XProgressBar
so the class instance name is the same as the custom view name.
Then all was fine.

RBS
 
Upvote 0

RB Smissaert

Well-Known Member
Licensed User
Longtime User
The variable name is not important.

1. You must add the view with the designer.
2. If you encounter such issue again then upload a small project that demonstrates the issue. Make sure to use the non-modified version of B4XProgressBar.

I didn't think altering the variable name should make a difference, but it definitely did in this case.
Will see if I can reconstruct the error in a simple project and post that.
Probably will be difficult.

RBS
 
Upvote 0
Top