JavaFX in py5 demo

The following source code demonstrates using JavaFX in py5 (Thonny editor). It is necessary to add javafx modules to a ‘jars’ folder in the same folder as the sketch. Javafx modules may be found at the following path starting with the Processing folder: Processing/libraries/javafx/library/macos-x86_64/modules/. If your operating system is not macos then select the appropriate folder for your system. Reference: JavaFX | Pane Class - GeeksforGeeks

import py5
import javafx.stage.Stage
import javafx.scene.Scene
import javafx.scene.layout.Pane

this = py5._instance

def settings():
    this.size(1,1,this.FX2D)
    
def setup():
    label = javafx.scene.control.Label("Hello world.")
    label.relocate(80,10)
    print(label)
    btn = javafx.scene.control.Button("Button")
    print(btn)
#   **** Adds label to pane ****    
    pane = javafx.scene.layout.Pane(label)
    print("pane =",pane)
    pane.getChildren().add(btn)
    btn.relocate(80,50)
    scene = javafx.scene.Scene(pane,250,200)
    stage = javafx.stage.Stage()
    stage.setTitle("JavaFX Demo")
    print("stage =",stage)   
    print("scene = ",scene)  
    stage.setScene(scene)
    stage.show()
    
__name__ == '__main__' and py5.run_sketch()

Output:
jfx_demo

Addendum:

…And, yes you may run JavaFX in the Thonny editor with py5 plugin using ‘Imported mode’ and dispense with all the prefixes.

# Uses Imported mode for py5

import javafx.scene.Scene
import javafx.scene.layout.Pane
import javafx.stage.Stage
import javafx.scene
import javafx.scene.text.Text
import javafx.scene.text.Font
import javafx.scene.paint.Color

def settings():
    size(1,1,FX2D)
 
def setup():
    btn = javafx.scene.control.Button("Button")
    print(btn)
    txt = javafx.scene.text.Text("Welcome to JavaFX")
    txt.setUnderline(True)
    font = javafx.scene.text.Font("Verdana",25)
    txt.setFont(font)
    print("txt =",txt)
    print(txt.getText())
    pane = javafx.scene.layout.Pane()
    print("pane =",pane)
    pane.getChildren().add(txt)
    txt.relocate(40,20)
    pane.getChildren().add(btn)
    btn.relocate(80,120)      
    scene = javafx.scene.Scene(pane,320,200)
    stage = javafx.stage.Stage()
    print("stage =",stage)
    stage.setTitle("JavaFX Window")
    print("scene = ",scene)  
    stage.setScene(scene)
    stage.show()
    
run_sketch()

Output:
importedMode

Addendum:
I’ve been unable to run either of these demos in Windows 11. Has been run in MacOS (Intel chip) and Linux(as reported by another user). Also unable to run in MacOS with M2 chip (error msg similar to Windows error shown below.) This is the error in Windows 11 in case anyone recognizes it:

Graphics Device initialization failed for :  d3d, sw
Error initializing QuantumRenderer: no suitable pipeline found
java.lang.RuntimeException: java.lang.RuntimeException: Error initializing QuantumRenderer: no suitable pipeline found
	at com.sun.javafx.tk.quantum.QuantumRenderer.getInstance(QuantumRenderer.java:283)
	at com.sun.javafx.tk.quantum.QuantumToolkit.init(QuantumToolkit.java:254)
	at com.sun.javafx.tk.Toolkit.getToolkit(Toolkit.java:264)
	at com.sun.javafx.perf.PerformanceTracker.logEvent(PerformanceTracker.java:100)
	at javafx.scene.Node.<clinit>(Node.java:417)
	at processing.javafx.PGraphicsFX2D$FontCache.<init>(Unknown Source)
	at processing.javafx.PGraphicsFX2D.<init>(Unknown Source)
	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
	at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480)
	at processing.core.PApplet.makeGraphics(PApplet.java:1986)
	at processing.core.PApplet.createPrimaryGraphics(PApplet.java:2065)
	at processing.core.PApplet.initSurface(PApplet.java:10482)
	at processing.core.PApplet.runSketch(PApplet.java:10443)
Caused by: java.lang.RuntimeException: Error initializing QuantumRenderer: no suitable pipeline found
	at com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.init(QuantumRenderer.java:95)
	at com.sun.javafx.tk.quantum.QuantumRenderer$PipelineRunnable.run(QuantumRenderer.java:125)
	at java.base/java.lang.Thread.run(Thread.java:840)
java.lang.ExceptionInInitializerError
	at processing.javafx.PGraphicsFX2D$FontCache.<init>(Unknown Source)
	at processing.javafx.PGraphicsFX2D.<init>(Unknown Source)
	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
	at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
	at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
	at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480)
	at processing.core.PApplet.makeGraphics(PApplet.java:1986)
	at processing.core.PApplet.createPrimaryGraphics(PApplet.java:2065)
	at processing.core.PApplet.initSurface(PApplet.java:10482)
	at processing.core.PApplet.runSketch(PApplet.java:10443)
Caused by: java.lang.RuntimeException: No toolkit found
	at com.sun.javafx.tk.Toolkit.getToolkit(Toolkit.java:276)
	at com.sun.javafx.perf.PerformanceTracker.logEvent(PerformanceTracker.java:100)
	at javafx.scene.Node.<clinit>(Node.java:417)
	... 11 more
Java exception thrown by Sketch.runSketch:
java.lang.RuntimeException

M2 Mac Fix:

We need to use a special javafx-sdk which will run on aarch64. I used javafx-sdk-21.0.3 downloaded from Gluon: https://gluonhq.com/products/javafx/ (must be compatible with jdk-17)
Reference from StackOverflow is here: https://stackoverflow.com/questions/75147224/error-initializing-quantumrenderer-no-suitable-pipeline-found

I replaced all the jar and lib files in the ‘jars’ folder with those downloaded from Gluon and it ran without error.

Perhaps something similar can be done in Windows.