Android Question What am I doing wrong???

Discussion in 'Android Questions' started by Troberg, Mar 28, 2015.

  1. Troberg

    Troberg Well-Known Member Licensed User

    Trying to run this code gives me an error:

    Code:
    Dim SCR As cSCRAbout
      
    Dim pan As Panel
      pan.Initialize(
    "pan")
      
    CallSub2(SCR, "Initialize", pan)
    The signature of the sub I'm calling:

    Code:
    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?
     
  2. DonManfred

    DonManfred Expert Licensed User

    Callsub2 needs an activity-object as first parameter. But you gave a reference to an Panel
     
    Troberg likes this.
  3. Cableguy

    Cableguy Expert Licensed User

    You need to use the Me word to reference the calling activity object (not the Activity as GUI)
     
    Troberg likes this.
  4. Troberg

    Troberg Well-Known Member Licensed 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?
     
    Cableguy likes this.
  5. keirS

    keirS Well-Known Member Licensed User

    Either the JavaObject Library or Reflection library can do this.

    Code:
    Dim SCR As cSCRAbout
    Dim pan As Panel
    pan.Initialize(
    "pan")
    Dim j As JavaObject = SCR
    j.RunMethod(
    "Initialize"Array As Object(pan))
     
    Troberg likes this.
  6. thedesolatesoul

    thedesolatesoul Expert Licensed 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)
     
    NJDude and Troberg like this.
  7. Troberg

    Troberg Well-Known Member Licensed User

    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.
     
  8. thedesolatesoul

    thedesolatesoul Expert Licensed User

    At least from my tests it only shows Initialize that throws this exception:

    Code:
    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: Mar 28, 2015
    keirS and NJDude like this.
  9. Erel

    Erel Administrator Staff Member Licensed User

    Why do you use CallSub here?

    CallSub will not work with the initialize method as the object is not yet ready to receive events.
     
    Troberg likes this.
  10. Troberg

    Troberg Well-Known Member Licensed 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:

    Code:
    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:

    Code:
    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.)
     
  11. Reviewnow

    Reviewnow Active Member Licensed User

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

    Code:
    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
     
    Troberg likes this.
  12. Troberg

    Troberg Well-Known Member Licensed 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.
     
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice