It would be neat if you could use py5 drawing commands to draw something that is inside a JavaFX window that also has those controls on it.
To the best of my knowledge it is not possible to have JavaFX controls in a window which supports standard py5 drawing commands. A py5 window with a FX2D renderer returns PSurfaceFX$ResizableCanvas@703580bf for ‘get_surface().get_native()’, not a JavaFX object. You can draw into the FX2D renderer window using standard Processing primitives (circle, rect, triangle, etc) in the draw() loop as we are accustomed to, but it will not accept JavaFX controls without using a stage, scene, and pane (which creates another window). If you used a P2D renderer you could mix cp5 controls with standard drawing but the graphics is not quite as sharp as those with a FX2D renderer. The only way to have higher resolution graphics with snazzier controls is to use FX2D with JavaFX all the way. JavaFX has its own set of graphic shapes, but of course it’s more code. Examples are shown below.
Py5 window with FX2D renderer:
# Uses Imported mode for py5
_wndW = 450
_wndH = 350
def setup():
size(_wndW, _wndH, FX2D)
window_title("Sketch Drawing")
print(get_surface().get_native())
def draw():
fill(0)
text_size(32)
text("FX2D Renderer Text",80,60)
fill(255,0,0)
circle(100,150,100)
fill(0,0,255)
triangle(220,100,170,200,270,200)
fill(0,255,0)
rect(300,100,100,100)
Output:
Py5 window with P2D renderer and cp5 controls:
# Uses Imported mode for py5
from controlP5 import *
_wndW = 450
_wndH = 350
def setup():
global btn1
size(_wndW, _wndH, P2D)
window_title("Sketch Drawing")
print(get_surface().get_native())
cp5 = ControlP5(get_current_sketch())
btn1 = Button(cp5,"Hello")
def draw():
fill(0)
text_size(32)
text("P2D Renderer Text",80,60)
fill(255,0,0)
circle(100,150,100)
fill(0,0,255)
triangle(220,100,170,200,270,200)
fill(0,255,0)
rect(300,100,100,100)
def mouse_pressed(e):
if(btn1.isPressed()):
print("btn1 was pressed.")
Output:
Py5 window with JavaFX and FX2D renderer:
# Uses Imported mode for py5
import javafx.stage.Stage;
_wndW = 600
_wndH = 300
def myBtnAction(event):
print("btn hit.")
def settings():
size(1,1,FX2D)
print(get_surface())
def setup():
stage = javafx.stage.Stage()
print("stage =",stage)
stage.setTitle("JavaFX Graphics Demo")
# stage.setResizable:true
pane = javafx.scene.layout.Pane()
# Button
btn = javafx.scene.control.Button("Button")
btn.setLayoutX(90)
btn.setLayoutY(10)
btn.setOnAction(myBtnAction)
pane.getChildren().add(btn)
# Text
txt = javafx.scene.text.Text(130, 80, "Welcome to JavaFX!")
txt.setFont(javafx.scene.text.Font(35))
pane.getChildren().add(txt)
# Rectangle
r = javafx.scene.shape.Rectangle(50, 130, 100, 50)
r.setStroke(javafx.scene.paint.Color.color(0.0, 1.0, 0.0, 0.95))
r.setStrokeWidth(5)
r.setArcWidth(15)
r.setArcHeight(15)
pane.getChildren().add(r);
# Circle
myCircle = javafx.scene.shape.Circle(250, 160, 40)
myCircle.setFill(javafx.scene.paint.Color.DARKRED)
myCircle.setStrokeWidth(6)
myCircle.setStroke(javafx.scene.paint.Color.DARKSLATEBLUE)
pane.getChildren().add(myCircle)
# Triangle
polygon = javafx.scene.shape.Polygon();
polygon.getPoints().addAll([ 380.0, 100.0, 330.0, 200.0, 430.0, 200.0 ])
polygon.setFill(javafx.scene.paint.Color.GREEN)
pane.getChildren().add(polygon)
# Line
ln = javafx.scene.shape.Line(450,150,550,150)
ln.setStroke(javafx.scene.paint.Color.color(1.0, 0.0, 0.0, 1.0))
ln.setStrokeWidth(10)
pane.getChildren().add(ln)
scene = javafx.scene.Scene(pane, _wndW, _wndH, javafx.scene.paint.Color.ALICEBLUE)
stage.setScene(scene)
stage.show()
Output: