B4J Question Creating own events (from library)?

KMatle

Expert
Licensed User
Longtime User

Roycefer

Well-Known Member
Licensed User
Longtime User
There are few different ways to do this. If you want to raise an event sub in the Main thread from a non-Main thread, your best bet is to call ba.raiseEventFromDifferentThread(). In this way, the target sub will be executed in the Main thread and can access UI elements and it doesn't matter from which thread it is being called. If you use this method correctly, developers who use your library will be able to use the Sender keyword in their event subs.

You can also use CallSubDelayed which is a member function of anywheresoftware.b4a.keywords.Common. This will follow the normal rules of CallSubDelayed usage. There is no access to the Sender keyword using this method.

If you want to directly call an event sub in a blocking fashion (perhaps you need the return value of the event sub before you continue to the next line) then you will want your event sub to execute in the same thread as that from which it is being called. In this case, I use straight-forward Java reflection to call the target sub.

Whichever path you take, make sure to use the @Events annotation. It will make life a lot easier for the users of your library.
 
Upvote 0

jmon

Well-Known Member
Licensed User
Longtime User
He probably means in a normal b4j library and not a java one.

You can have a look at one of my b4j class https://www.b4x.com/android/forum/threads/jshellqueue.58315/

First you need to store the module that your library will call to raise the event. You also need to store the name of the event.

After that you just use CallSub or CallSubDelayed to call your event.
B4X:
CallSub(Module, EventName & "_QueueFinished")
.

Also you can add
B4X:
#event:QueueFinished
at the top of your library to tell the IDE of the names of your events and provide the autocomplete feature.

EDIT:I think the example of jShellQueue doesn't have the source code. Check out this library instead https://www.b4x.com/android/forum/threads/jwebimageview.62883/ which will be a good example.
 
Last edited:
Upvote 0

KMatle

Expert
Licensed User
Longtime User
After that you just use CallSub or CallSubDelayed to call your event.

Nice one.

As I see you initialize with

B4X:
iv1.Initialize(apWiv, Me, "iv")

handing over the parent object/module. A lot of examples do it like this.

How do I get the caller Module from the lib like other lib's do it without (like HttpUtils doesn't need to initialize it with "me")?
 
Upvote 0

jmon

Well-Known Member
Licensed User
Longtime User
You also need to add
B4X:
#raisesSynchronousEvents:yourFunctionName
At the top of your library for all the functions calling events with CallSub.
 
Upvote 0
Top