Android Question [SOLVED] How to display messages from different modules using a subroutine located in one of them?

oleg_

Member
Licensed User
I already have a rather complex program (B4XPages) in which among other things I want to display messages from different modules using a subroutine located in one of these modules.
In B4A, an error was received with the message "java.lang.NullPointerException: null receiver". Then I decided to make a simplified program with the same task. As a result, this simplified program gives me error message on the same line, but this time the message is different (both in B4A and B4J):
Error occurred on line: 36 (B4XMainPage)
java.lang.RuntimeException: Object should first be initialized (B4XView).

B4XMainPage:
Sub Class_Globals
    Private Root As B4XView
    Private xui As XUI
'    Private Activity As Activity
    Public Label1 As B4XView
    Private Cl As Class1
End Sub

Public Sub Initialize
    Cl.Initialize
'    B4XPages.GetManager.LogEvents = True
End Sub

'This event will be called once, before the page becomes visible.
Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    Root.LoadLayout("MainPage")
 
End Sub

'You can see the list of page related events in the B4XPagesManager object. The event name is B4XPage.

Private Sub Button1_Click
    sub_Info ("Message from B4XMainPage")
    Cl.Sub_in_Class1
End Sub

Public Sub sub_Info (Message As String)
    Label1.Text = Label1.Text  & Message & CRLF    <---------- This line causes the error
End Sub

Class1:
Sub Class_Globals
    Private Root As B4XView 'ignore
    Private xui As XUI 'ignore
    Private MainPage As B4XMainPage
 
End Sub

'You can add more parameters here.
Public Sub Initialize As Object
    Return Me
End Sub

'This event will be called once, before the page becomes visible.
Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    'load the layout to Root

End Sub

Public Sub Sub_in_Class1
    MainPage.Initialize
    MainPage.sub_Info ("Message from Class1")
End Sub

P.S.
01.jpg
 

Attachments

  • Label_Initialize_problem.zip
    8.7 KB · Views: 22
Last edited:
Solution
In this thread, I have already been sent a lot of code fragments, but no one has yet uploaded just a small working program based on my simplest version with its amendments. Well, so that I could understand the general mechanism of work.
Indeed, as DonManfred said, you should pass b4xmainpage to class1 instead of reinitializing it.
03.zip is attached

Jerryk

Member
Licensed User
Longtime User
B4X:
 If SubExists(mCallBack, mEventName & "_Message") Then
        CallSubDelayed2(mCallBack,  mEventName & "_Message", myMessage)
 End If
 
Upvote 0

Jerryk

Member
Licensed User
Longtime User
Module1:
Sub ShowMessage(m As String)
    Log(m)
End Sub

Module2:
 If SubExists(Module1, "ShowMessage") Then
     CallSubDelayed2(Module1, "ShowMessage", "Hello")
 End If
 
Upvote 0

oleg_

Member
Licensed User
Can you upload the small test program?
Erel, I have already uploaded my first version of a simple test program in my first post in this thread.
Here is the second try, taking into account advice from Jerryk.
This time the program also throws an error, but this time the message is different:

*** Service (starter) Create ***
** Service (starter) Start **
** Activity (main) Create (first time) **
Call B4XPages.GetManager.LogEvents = True to enable logging B4XPages events.
** Activity (main) Resume **
Error occurred on line: 38 (B4XMainPage)
java.lang.Exception: Sub sub_in_class1 signature does not match expected signature.
public static anywheresoftware.b4a.pc.RemoteObject b4a.example.class1_subs_0._sub_in_class1(anywheresoftware.b4a.pc.RemoteObject) throws java.lang.Exception
class anywheresoftware.b4a.pc.RemoteObject, Null,

In attempt number three I simplified it even more. The result is this:

WARNING: package com.sun.javafx.embed.swing.oldimpl not in javafx.swing
Waiting for debugger to connect...
Program started.
Call B4XPages.GetManager.LogEvents = True to enable logging B4XPages events.
Error occurred on line: 44 (B4XMainPage)
java.lang.RuntimeException: Object should first be initialized (B4XView).
at anywheresoftware.b4a.AbsObjectWrapper.getObject(AbsObjectWrapper.java:49)
at anywheresoftware.b4a.objects.B4XViewWrapper.getNodeObject(B4XViewWrapper.java:123)
at anywheresoftware.b4a.objects.B4XViewWrapper.getText(B4XViewWrapper.java:338)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:629)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:234)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:167)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:111)
at anywheresoftware.b4a.shell.ShellBA.raiseEvent2(ShellBA.java:100)
at anywheresoftware.b4a.keywords.Common.CallSub4(Common.java:513)
at anywheresoftware.b4a.keywords.Common.access$0(Common.java:493)
at anywheresoftware.b4a.keywords.Common$CallSubDelayedHelper.run(Common.java:567)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:391)
at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$11(PlatformImpl.java:427)
at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:174)
at java.base/java.lang.Thread.run(Thread.java:832)
 

Attachments

  • 02.zip
    8.8 KB · Views: 17
  • 03.zip
    8.8 KB · Views: 27
Last edited:
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
Change your code to

B4X:
Private Sub Button1_Click
    Label1.Text = Cl.Sub_in_Class1
End Sub

and in your Class

B4X:
Public Sub Sub_in_Class1 As String
    Return "Message from Class1"
End Sub

- Reinitializing b4xmainpage is a big mistake! It IS already running! You would not get to click the button otherwise....

I suggest to learn how to work with classes
 
Last edited:
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
B4X:
'You can add more parameters here.
Public Sub Initialize As Object
    Return Me
End Sub

'This event will be called once, before the page becomes visible.
Private Sub B4XPage_Created (Root1 As B4XView)
    Root = Root1
    'load the layout to Root

End Sub

Public Sub Sub_in_Class1
    MainPage.Initialize
    MainPage.sub_Info ("Message from Class1")
End Sub
This is how to use the highligh... It is line 14
 
Upvote 0

oleg_

Member
Licensed User
Change your code to
B4X:
Private Sub Button1_Click
    Label1.Text = Cl.Sub_in_Class1
End Sub

and in your Class

B4X:
Public Sub Sub_in_Class1 As String
    Return "Message from Class1"
End Sub
Yes, it works, but it's completely useless in this form.
Look, in fact, I have 2 huge modules, from different places of which I need to output a large number of messages. Moreover, these messages are processed differently depending on certain conditions. In addition, some of them are also voiced. Well, that is, we definitely need a separate subroutine for these purposes, or maybe even a separate class, I’m not sure which is easier to do.
I uploaded a completely simplified version to understand the principle of operation.

- Reinitializing b4xmainpage is a big mistake! It IS already running! You would not get to click the button otherwise....

I suggest to learn how to work with classes
In this thread, I have already been sent a lot of code fragments, but no one has yet uploaded just a small working program based on my simplest version with its amendments. Well, so that I could understand the general mechanism of work.
 
Upvote 0

oleg_

Member
Licensed User
This is how to use the highligh... It is line 14
Just a try:
B4X:
Sub MainForm_Resize (Width As Double, Height As Double)
    B4XPages.Delegate.MainForm_Resize(Width, Height)
End Sub

Yes, it really works, but unfortunately it's not visible in the preview and it's misleading.
 
Upvote 0

teddybear

Well-Known Member
Licensed User
In this thread, I have already been sent a lot of code fragments, but no one has yet uploaded just a small working program based on my simplest version with its amendments. Well, so that I could understand the general mechanism of work.
Indeed, as DonManfred said, you should pass b4xmainpage to class1 instead of reinitializing it.
03.zip is attached
 

Attachments

  • 03.zip
    9.6 KB · Views: 20
Upvote 0
Solution
Top