[Bug] Sender something different than expected

NFOBoy

Active Member
Licensed User
Longtime User
Attached, find my cmlPreference library (Class Multi Language for the first three letters)

In it I have multiple classes of multi-language objects that add functionality to normal objects (labels, checkboxes, etc)

Under 2.52 this library compiled and ran just fine as is, and I could export out to working library.

Under 2.7 I now get:
B4X:
cmlpage_updatelanguage (java line: 810)
java.lang.RuntimeException: java.lang.RuntimeException: java.lang.ClassCastException: b4a.pasagosoft.mlimageview.cmlcheckboxgroup cannot be cast to android.widget.CheckBox
   at anywheresoftware.b4a.keywords.Common.CallSub4(Common.java:847)
   at anywheresoftware.b4a.keywords.Common.CallSubNew(Common.java:785)
   at b4a.pasagosoft.mlimageview.cmlpage._updatelanguage(cmlpage.java:810)
   at b4a.pasagosoft.mlimageview.cmlpage._vvvvvvvvvvvv7(cmlpage.java:282)
   at b4a.pasagosoft.mlimageview.preferences._activity_create(preferences.java:440)
   at java.lang.reflect.Method.invokeNative(Native Method)
   at java.lang.reflect.Method.invoke(Method.java:511)
   at anywheresoftware.b4a.BA.raiseEvent2(BA.java:169)
   at b4a.pasagosoft.mlimageview.preferences.afterFirstLayout(preferences.java:89)


   at b4a.pasagosoft.mlimageview.preferences.access$100(preferences.java:16)
   at b4a.pasagosoft.mlimageview.preferences$WaitForLayout.run(preferences.java:74)
   at android.os.Handler.handleCallback(Handler.java:615)
   at android.os.Handler.dispatchMessage(Handler.java:92)
   at android.os.Looper.loop(Looper.java:137)
   at android.app.ActivityThread.main(ActivityThread.java:4898)
   at java.lang.reflect.Method.invokeNative(Native Method)
   at java.lang.reflect.Method.invoke(Method.java:511)
   at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1006)
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:773)
   at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.RuntimeException: java.lang.ClassCastException: b4a.pasagosoft.mlimageview.cmlcheckboxgroup cannot be cast to android.widget.CheckBox
   at anywheresoftware.b4a.keywords.Common.CallSub4(Common.java:847)
   at anywheresoftware.b4a.keywords.Common.CallSubNew(Common.java:785)
   at b4a.pasagosoft.mlimageview.cmlcheckboxgroup._updatelanguage(cmlcheckboxgroup.java:394)
   at b4a.pasagosoft.mlimageview.cmlcheckboxgroup.callSub(cmlcheckboxgroup.java:411)
   at anywheresoftware.b4a.keywords.Common.CallSub4(Common.java:818)
   ... 19 more
Caused by: java.lang.ClassCastException: b4a.pasagosoft.mlimageview.cmlcheckboxgroup cannot be cast to android.widget.CheckBox
   at b4a.pasagosoft.mlimageview.cmlcheckbox._newme_checkedchange(cmlcheckbox.java:341)
   at b4a.pasagosoft.mlimageview.cmlcheckbox._updatelanguage(cmlcheckbox.java:655)
   at b4a.pasagosoft.mlimageview.cmlcheckbox.callSub(cmlcheckbox.java:682)
   at anywheresoftware.b4a.keywords.Common.CallSub4(Common.java:818)
   ... 23 more

As I run through the code, in the cmlCheckBoxGroup updateLanguage function, I need to go through and update each checkbox is calling for the update, so I call UpdateLanguage for each Checkbox that is part of the group:

B4X:
Public Sub UpdateLanguage()

If mapTitles.ContainsKey(prefLanguage.value) Then
   strTitle = mapTitles.Get(prefLanguage.value)
Else
   strTitle = mapTitles.GetValueAt(0)
End If

Dim lbl As Label
For i = 0 To mapOfMe.Size-1
   lbl = mapOfMe.GetValueAt(i)
   If lbl.IsInitialized Then
      lbl.Text = strTitle
   End If
Next

For i = 0 To mapViews.Size-1
   CallSub(mapViews.GetValueAt(i), "UpdateLanguage")
Next


   

End Sub

Which I follow into the cmlCheckBox (which is just added functionality on top of checkbox) to:

B4X:
Public Sub UpdateLanguage()

If mapText.ContainsKey(prefLanguage.value) Then
   strText = mapText.get(prefLanguage.value)
Else
   strText = mapText.GetValueAt(0)
End If

Dim lbl As Label
For i = 0 To mapofme.Size-1
   lbl = mapofme.GetValueAt(i)
   If lbl.IsInitialized Then
      lbl.Text = strText
   End If
Next

newme_CheckedChange(myValue.value)

   

End Sub

Sub newofme_click
   For i = 0 To mapofme.Size-1
      If mapofme.GetValueAt(i) = Sender Then
         Dim cb As CheckBox
         cb = mapofcbme.GetValueAt(i)
      
         If myValue.value Then
            cb.Checked = False
         Else
            cb.Checked = True
         End If
      End If
   Next
   
End Sub

Sub newme_CheckedChange(Checked As Boolean)
   Dim cb As CheckBox
   cb = Sender
   myValue.value = Checked
   
   Dim cb As CheckBox
   For i = 0 To mapofcbme.Size-1
      cb = mapofcbme.GetValueAt(i)
      If cb.IsInitialized Then
         cb.Checked = Checked
      End If

   Next
   
   If mapSubTextChecked.Size > 0 AND mapSubTextNotChecked.Size > 0 Then
      'need to updated mapofsubme to new text
      
      Dim strSub As String
      
      If Checked Then
         If mapSubTextChecked.ContainsKey(prefLanguage.value) Then
            strSub = mapSubTextChecked.get(prefLanguage.value)
         Else
            strSub = mapSubTextChecked.GetValueAt(0)
         End If
         
         If strSub = "" Then 'this means nothing at either one... but should be something
            If mapSubTextNotChecked.ContainsKey(prefLanguage.value) Then
               strSub = mapSubTextNotChecked.get(prefLanguage.value)
            Else
               strSub = mapSubTextNotChecked.GetValueAt(0)
            End If
         End If
         
         
      
      Else
         If mapSubTextNotChecked.ContainsKey(prefLanguage.value) Then
            strSub = mapSubTextNotChecked.get(prefLanguage.value)
         Else
            strSub = mapSubTextNotChecked.GetValueAt(0)
         End If
         
         If strSub = "" Then 'this means nothing at either one... but should be something
            If mapSubTextChecked.ContainsKey(prefLanguage.value) Then
               strSub = mapSubTextChecked.get(prefLanguage.value)
            Else
               strSub = mapSubTextChecked.GetValueAt(0)
            End If
         End If
      End If
      
      Dim lbl As Label
      For i = 0 To mapofsubme.Size-1
         lbl = mapofsubme.GetValueAt(i)
         If lbl.IsInitialized Then
            lbl.Text = strSub
         End If
      Next
      
      subText = strSub
   End If
   
   If partOfGroup Then
      CallSub2(myParent, "CheckOne", Me)
   End If
   
   
   checkDependency
   
   
End Sub


In this part right here, is where the sender is being called a checkboxgroup,
but checkboxgroup called the updatelanguage function of the checkbox (and works great under 2.52)

B4X:
Dim cb As CheckBox
   cb = Sender
   myValue.value = Checked

So what has changed under 2.7? (I'm betting it has actually gotten better, and 2.52 missed some fatal flaw in my code... :) )

Ross
 

Attachments

  • cmlProject.zip
    96.6 KB · Views: 250

NFOBoy

Active Member
Licensed User
Longtime User
Erel, just to make sure I follow.

This is the sub that calls the checkedChange

B4X:
Public Sub UpdateLanguage()

If mapText.ContainsKey(prefLanguage.value) Then
   strText = mapText.get(prefLanguage.value)
Else
   strText = mapText.GetValueAt(0)
End If

Dim lbl As Label
For i = 0 To mapofme.Size-1
   lbl = mapofme.GetValueAt(i)
   If lbl.IsInitialized Then
      lbl.Text = strText
   End If
Next

newme_CheckedChange(myValue.value)

   

End Sub

This function is inside the class cmlCheckbox and newme is defined as
B4X:
Private newMe As CheckBox

inside Class cmlCheckbox

Now, as I think about this, I'm not sure I understand the logic that you are mentioning.

For my Class to call a function inside itself, I would think that the way I have written the sub is logical (and that is how it worked up until 2.7).

I do understand CallSub and Sender being set to the Class that called it. But, in my code, the Class function that is called by CallSub then calls an internal function, so that called Class is now the Sender... right?
 

NFOBoy

Active Member
Licensed User
Longtime User
Erel,

as I think about it more, from a Class perspective, that I am so used to asking who the sender is in that function, but, since it is inside a Class, that means that (for my purpose) the sender has to be itself, or that whatever is calling it wants the update to occur on that instance of the Class. So instead of setting my Checkbox to Sender, I set it to the checkBox instance of that instantiated Class (which appears to work).

(I am looping inside my head right now... but I should spiral out soon)
 
Top