B4J Question [B4X] How Do I draw Text on a B4XImageView

MrKim

Well-Known Member
Licensed User
Longtime User
After spending my requisite two+ hours searching here and playing monkeys and typewriters I feel like I must be missing something.

I want it to work in B4J/B4A/B4i so I am trying to use a B4XImageView and B4XCanvas but B4XCanvas requires a B4XView and I don't HAVE a B4xView to draw on, I have a B4XImageView.
One of the many things I tried was adding a B4x view in code, but you can't initialize it so I tried adding a pane initializing it and then setting the B4xview to the pane even though that would mean different code for J/A/i. But this fails when I try to actually set the B4XImageView.SetBitmap.
B4X:
java.lang.ClassCastException: class anywheresoftware.b4j.objects.PaneWrapper$ConcretePaneWrapper$NonResizePane cannot be cast to class javafx.scene.image.ImageView (anywheresoftware.b4j.objects.PaneWrapper$ConcretePaneWrapper$NonResizePane is in unnamed module of loader 'app'; javafx.scene.image.ImageView is in module javafx.graphics of loader 'app')
Here is the code:
B4X:
        Dim Cnv As B4XCanvas, P As Pane, BXV As B4XView
        P.Initialize("")
        BXV = P
        IMV.Clear
        Cnv.Initialize(BXV)
        Cnv.DrawText($"File${CRLF}Missing!"$, IMV.mBase.Width / 2, IMV.mBase.Height / 2, xui.CreateDefaultBoldFont(20), xui.Color_Red, "CENTER")
        IMV.mBackgroundColor = xui.Color_Blue
        IMV.Clear
        IMV.setbitmap(BXV.GetBitmap)
Interestingly, this will give me the text I want, but it is evidently drawing on the base and I can't figure out how to clear it:
B4X:
        Dim Cnv As B4XCanvas
        Cnv.Initialize(IMV.mBase)
        Cnv.DrawText($"File${CRLF}Missing!"$, IMV.mBase.Width / 2, IMV.mBase.Height / 2, xui.CreateDefaultBoldFont(20), xui.Color_Red, "CENTER")
        IMV.mBackgroundColor = xui.Color_Blue
        IMV.Clear
What I am trying to do:
Get A file / path from the DB.
IF there is no file listed in the DB I hide the View
IF there is a file I Load it.
If the File is MISSING then I want to to say File Missing on the View.
Yes, I know there are a lot of other ways to solve this but this just seemed like the logical, simple way to do it. Now extra views to add/remove etc.
Also, setting the background color doesn't actually do anything until you .setbitmap which is OK unless the first image of the day is missing.
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
1621148669779.png


B4X:
Dim p As B4XView = xui.CreatePanel("")
p.SetLayoutAnimated(0, 0, 0, 100dip, 100dip)
cvs.Initialize(p)
'now you can draw
 
Upvote 0

MrKim

Well-Known Member
Licensed User
Longtime User
View attachment 113505

B4X:
Dim p As B4XView = xui.CreatePanel("")
p.SetLayoutAnimated(0, 0, 0, 100dip, 100dip)
cvs.Initialize(p)
'now you can draw
Thank you. Still took me some time to figure out because I was trying p.GetBitmap. Which fails. I still don't understand why that doesn't work.
BTW the other thing that threw me: .setbitmap does NOT show up as a property of B4XImageView when you press the dot. XUI Views Version 2.45.

Keep up the amazing work and thank you for your patience with this forgetful old hacker.
I should retire but I still enjoy what I do.
 
Upvote 0

klaus

Expert
Licensed User
Longtime User
To use B4XCanvas you need a B4XView which is a Panel in B4A and B4i or a Pane in B4J.
The code Erel suggested you:
B4X:
Dim p As B4XView = xui.CreatePanel("")
p.SetLayoutAnimated(0, 0, 0, 100dip, 100dip)
cvs.Initialize(p)
is this B4XView.
Then, with p.GetBitmap you can get the Bitmap and do whatever you want to do.
You can set it to B4XImageView1.Bitmap = p.Bitmap.

Sorry, but I am retired and 76.
 
Upvote 0

MrKim

Well-Known Member
Licensed User
Longtime User
To use B4XCanvas you need a B4XView which is a Panel in B4A and B4i or a Pane in B4J.
The code Erel suggested you:
B4X:
Dim p As B4XView = xui.CreatePanel("")
p.SetLayoutAnimated(0, 0, 0, 100dip, 100dip)
cvs.Initialize(p)
is this B4XView.
Then, with p.GetBitmap you can get the Bitmap and do whatever you want to do.
You can set it to B4XImageView1.Bitmap = p.Bitmap.

Sorry, but I am retired and 76.
I wish my mind was still as sharp as yours. I actually have a learning disability - very bad short term memory. That is why it is important for me to understand how this stuff works. I have a good logical mind so if I understand it I can remember it.

Forgive me, I am just trying to understand here. The example I found used.
B4XImageView1.setbitmap
I just went back to my test code and there is no p.Bitmap there IS a p.GetBitmap
and This FAILS
B4XImageView1.Bitmap = p.GetBitmap
B4X:
Error occurred on line: 50
java.lang.ClassCastException: class anywheresoftware.b4j.objects.PaneWrapper$ConcretePaneWrapper$NonResizePane cannot be cast to class javafx.scene.image.ImageView (anywheresoftware.b4j.objects.PaneWrapper$ConcretePaneWrapper$NonResizePane is in unnamed module of loader 'app'; javafx.scene.image.ImageView is in module javafx.graphics of loader 'app')
    at anywheresoftware.b4j.objects.ImageViewWrapper.GetImage(ImageViewWrapper.java:110)
    at anywheresoftware.b4a.objects.B4XViewWrapper.GetBitmap(B4XViewWrapper.java:570)
    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:566)
    at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:632)
    at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:234)
    at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:167)
    at jdk.internal.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at anywheresoftware.b4a.BA.raiseEvent2(BA.java:91)
    at anywheresoftware.b4a.shell.ShellBA.raiseEvent2(ShellBA.java:98)
    at anywheresoftware.b4a.BA$1.run(BA.java:216)
    at javafx.graphics/com.sun.javafx.application.PlatformImpl.lambda$runLater$10(PlatformImpl.java:428)
    at java.base/java.security.AccessController.doPrivileged(Native Method)
    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:834)
This also fails:
B4XImageView1.setbitmap(p.GetBitmap)
with the same error.
This does NOT Fail:
B4XImageView1.setbitmap(Cnv.CreateBitmap)
This also works
B4XImageView1.Bitmap = Cnv.CreateBitmap
Now I finally understand.
1621188469584.png

You can only get the Bitmap from an imageview in B4J.
Thanks for your help.
 
Upvote 0

klaus

Expert
Licensed User
Longtime User
Attached a small test project.
Sorry, one mistake in my previous post B4XImageView1.Bitmap = p.Bitmap should be B4XImageView1.Bitmap = cvs.CreateBitmap.
 

Attachments

  • TestB4XImageView.zip
    2.5 KB · Views: 290
Upvote 0

MrKim

Well-Known Member
Licensed User
Longtime User
Thanks all for your help. I thought this would be a SIMPLER solution to my problem. It turns out that while this worked in B4j, I had carriage returns in the text and while they were honored and measured in B4j, they were not in B4a which would have meant more code to get it looking right.

In the end it wound up being easier to just add a label and show or hide it when needed.
 
Upvote 0
Top