B4J Library Use SVG files like any other image : JavafxSVG

I'm not quite sure how I have missed this library for so long, but I stumbled across it yesterday. I won't say it's a wrap of the javafxSVG github library as I only had to write 9 lines of code, it's more of an interface. Anyway, the github project can be found here and there is an interesting blog post here. The blog states that the project uses a non public API, I can't find any information about it but it is still available in Java 14 I just tested it.

You need to download some additional jars, which I have zipped and uploaded to my Dropbox, Get them here and unzip the file into your B4j Additional libraries folder. It will create a subfolder called javafxSVG, leave the additional jars in there.

The library creates a java Image loader instance that allows SVG files to be loaded into an Imageview (including B4xImageView) and anywhere else you would use images. Even in the designer, you just have to override the file extension in the file open dialog.

As in the example app, the SVGImageLoaderFactory class should be declared and initialized as soon as possible, so right at the top of Appstart is a good place. And that is all that is needed.

B4X:
Sub AppStart (Form1 As Form, Args() As String)
    Dim SVG As SVGImageLoaderFactory
    SVG.Initialize(False)

    .
    .
    .

The TrySizeFromFile option in the initialize call is added for completeness, but if the file does not specify a size, nothing is shown so use with cautiion.

The example app is just to prove it works, you only really need to download the B4xlib or the .bas file. There may be an issue with some SVG files if they have space or comments at the head of the file. See the blog post for more info.

1613379877610.png


An SVG in an B4xImageview, and added to a button from the designer.


For java 11 & 14 you need an additional line in the Main module before Process_Globals:
B4X:
#VirtualMachineArgs: --add-opens javafx.graphics/com.sun.javafx.iio.common=ALL-UNNAMED --add-opens javafx.graphics/com.sun.javafx.iio=ALL-UNNAMED

The example app has been updated with this line.


B4jPackager

To create a package with the integrated packager you need to add the VMArgs as a PackagerProperty:

B4X:
#PackagerProperty: VMArgs = --add-opens javafx.graphics/com.sun.javafx.iio.common=b4j --add-opens javafx.graphics/com.sun.javafx.iio=b4j

NOTE: these are slightly different to the #VirtualMachineArgs as the target module needs to be specified for the packager, which is b4j instead of ALL-UNNAMED.


I've added some conditional compilation configurations to the example to manage the switching of the parameters. If you want to use them, you will need to provide the paths to your java javac.exe for each version, if not just comment or delete them and manage the required parameters yourself.




Dependencies:
  • JavaObject
  • XUI Views
  • Additional jars, download link is above.
Update: I thought I should add a B4xlib as well.

Let me know how you get on with it.
 

Attachments

  • JavaFXSVG.zip
    33.7 KB · Views: 73
  • SVGImageLoaderFactory.bas
    1.4 KB · Views: 73
  • JavaFXSVG-b4xlib.b4xlib
    1.1 KB · Views: 77
Last edited:

stevel05

Expert
Licensed User
I have found a problem running this in release mode in java11/14. Works OK in java 8. Please hold off if you want to use it in the latter. I will look for a solution.

Edit: See post #3

This is now resolved, see posts #3 & #7
 
Last edited:

stevel05

Expert
Licensed User
For java 11 & 14 you need an additional line to the Main module before Process_Globals:
B4X:
#VirtualMachineArgs: --add-opens javafx.graphics/com.sun.javafx.iio.common=ALL-UNNAMED, --add-opens javafx.graphics/com.sun.javafx.iio=ALL-UNNAMED

I still need to work out how to add this to the packager for release. I will let you know.
 

stevel05

Expert
Licensed User
Check the release_java_modules.txt file
Thanks Erel,

I've found the correct content for the release_java_modules.txt file and learnt a lot about the java 11 dependencies management in the process. Are you suggesting running the stand alone packager and overwriting the file in the assets directory, or is there a way to do it with the integrated packager?
 

stevel05

Expert
Licensed User
OK I found that I can pass the required add-opens to the Integrated Packager using #PackagerProperty: VMArgs.

That works nicely,
 
Last edited:

stevel05

Expert
Licensed User
B4jPackager (Java 11 & 14)

To create a package with the integrated packager you need to add the VMArgs as a PackagerProperty:

B4X:
#PackagerProperty: VMArgs = --add-opens javafx.graphics/com.sun.javafx.iio.common=b4j --add-opens javafx.graphics/com.sun.javafx.iio=b4j
NOTE: these are slightly different to the #VirtualMachineArgs as the target module needs to be specified for the packager, which is b4j instead of ALL-UNNAMED.
 
Last edited:

stevel05

Expert
Licensed User
It took a bit of studying, but worth it. I understand it better now.
 
Top