Android Question What am I doing wrong???

Troberg

Well-Known Member
Licensed User
Longtime User
Trying to run this code gives me an error:

B4X:
  Dim SCR As cSCRAbout
  Dim pan As Panel
  pan.Initialize("pan")
  CallSub2(SCR, "Initialize", pan)

The signature of the sub I'm calling:

B4X:
Public Sub Initialize(HostPanel As Panel)

The error:

java.lang.RuntimeException: java.lang.ClassCastException: anywheresoftware.b4a.objects.PanelWrapper cannot be cast to anywheresoftware.b4a.BA

Yikes. What am I doing wrong?
 

DonManfred

Expert
Licensed User
Longtime User
Upvote 0

Cableguy

Expert
Licensed User
Longtime User
You need to use the Me word to reference the calling activity object (not the Activity as GUI)
 
Upvote 0

Troberg

Well-Known Member
Licensed User
Longtime User
I don't get it. This is the description of CallSub2:

CallSub2(Component As Object, Sub As String, Argument As Object) As Object

As I understood it, the arguments are:

Component: The component in which the sub I want to call is.
Sub: The sub to call.
Argument: The argument to send to the sub.

SCR is not a panel, it's a class, which, among other things, can hold a reference to a panel.

Let's just go back one step. This is what I want to accomplish:

I have an object. It can be one of several classes, but I know they all have an Initialize, that takes a panel as argument. I want to call that initialize, without having to know exactly which class it is. How do I do that?
 
Upvote 0

keirS

Well-Known Member
Licensed User
Longtime User
Either the JavaObject Library or Reflection library can do this.

B4X:
Dim SCR As cSCRAbout
Dim pan As Panel
pan.Initialize("pan")
Dim j As JavaObject = SCR
j.RunMethod("Initialize", Array As Object(pan))
 
Upvote 0

thedesolatesoul

Expert
Licensed User
Longtime User
This is strange.
I think its an issue with Initialize method only, as it also takes a ba object (which is hidden in B4A always).
Can you not just call SCR.Initialize(pan)? (Considering at this stage you already know what the object is and the params that initialize will take)
 
Upvote 0

Troberg

Well-Known Member
Licensed User
Longtime User
Can you not just call SCR.Initialize(pan)? (Considering at this stage you already know what the object is and the params that initialize will take)

Nope, this is a simplified example. In the real world implementation, I won't know.

I 've already checked if it's just Initialize by simply renaming it, and it didn't help.

I'll try some more tomorrow, now, I've got other things to do.
 
Upvote 0

thedesolatesoul

Expert
Licensed User
Longtime User
At least from my tests it only shows Initialize that throws this exception:

B4X:
java.lang.RuntimeException: java.lang.ClassCastException: anywheresoftware.b4a.objects.PanelWrapper cannot be cast to anywheresoftware.b4a.BA
    at anywheresoftware.b4a.keywords.Common.CallSub4(Common.java:876)
    at anywheresoftware.b4a.keywords.Common.CallSubNew2(Common.java:820)
    at b4a.example.main._activity_create(main.java:344)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:187)
    at b4a.example.main.afterFirstLayout(main.java:100)
    at b4a.example.main.access$100(main.java:17)
    at b4a.example.main$WaitForLayout.run(main.java:78)
    at android.os.Handler.handleCallback(Handler.java:739)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:135)
    at android.app.ActivityThread.main(ActivityThread.java:5221)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Caused by: java.lang.ClassCastException: anywheresoftware.b4a.objects.PanelWrapper cannot be cast to anywheresoftware.b4a.BA
    at b4a.example.clstest.callSub(clstest.java:48)
    at anywheresoftware.b4a.keywords.Common.CallSub4(Common.java:847)
    ... 16 more
java.lang.RuntimeException: java.lang.ClassCastException: anywheresoftware.b4a.objects.PanelWrapper cannot be cast to anywheresoftware.b4a.BA

I'm pretty certain its a bug* related only to the Initialize method.
 
Last edited:
Upvote 0

Troberg

Well-Known Member
Licensed User
Longtime User
OK, now I've solved it. I removed the argument from Initialize, and added a Setup sub that does what Initialize did. Now, I can initialize in the context where the SCR is created, and set the host panel and other setup stuff later, when the hostpanel is klnown.

Code:

B4X:
Sub RegisterSCRs()
    Dim SCR As cSCRAbout: SCR.Initialize() :AddSCR(SCR)
End Sub

Sub AddSCR(SCR As Object)
    Dim pan As Panel
    pan.Initialize("pan")
    pan.Color=Colors.Transparent
    pan.Visible= False
    panBack.AddView(pan,100%x,200%x,0%y,100%y) 'Add it outside the screen, so we can slide it in with a cool animation
    CallSub2(SCR, "Setup", pan)
    SCRs.Put(SCR, SCR)
End Sub

As you see, now the only thing that needs to be done to add another SCR is to add another line in RegisterSCRs, and, apart form the name of your class, it's a simple copy-paste.

Example:

B4X:
Sub RegisterSCRs()
    Dim SCR As cSCRAbout: SCR.Initialize() :AddSCR(SCR)
    Dim SCR As cSCRSettings: SCR.Initialize() :AddSCR(SCR)
    Dim SCR As cSCRMySCR: SCR.Initialize() :AddSCR(SCR)
End Sub

(Yeah, I know, several commands on one line is not very pretty, but, in this case, when it's just copy-paste, I think it makes the code clearer.)
 
Upvote 0

Reviewnow

Active Member
Licensed User
Longtime User
Sorry I am kind of confused about your method here or maybe you can explain the concept
Would this not be easier ?

B4X:
Sub AboutPanel() as Panel
    Dim pan As Panel
    pan.Initialize("pan")
    pan.Color=Colors.Transparent
    pan.Visible= False
   
    ''' Add whatever you want to PAN
    'pan.addview(x,x,x,x,x)
   
    Return pan
End Sub

Sub RegisterSCRs()
' add the cSCRAbout.AboutPanel
panBack.AddView(cSCRAbout.AboutPanel,100%x,200%x,0%y,100%y)  'Still copy and paste
End Sub
 
Upvote 0

Troberg

Well-Known Member
Licensed User
Longtime User
Nope, that would not be generic enough. I want to be able to add new SCRs with as little code as possible. With my method, it's a one line (although with three commands) copy-paste. I would have preferred to not even need that line, but that's not possible in Android.

Why? Well, I intend this framework to be used in a project with several developer. To minimize how much people need to do in the Main activity, I want to make the line between different parts as clear as possible. This way, everybody can work in their own class, then just add one line to the Main activity for it to be included in the app.

So, it's all about separation of concern.
 
Upvote 0
Top