When using the default graphics renderer, UI scaling in Windows is respected but not when using FX2D. With any scale higher than 100% the canvas sizes incorrectly.
Unfortunately, for the graphics I am teaching, the default renderer is insufficient. FX2D is required for smooth curves.
The pixelDensity() and displayDensity() do not seem made for this problem. Meanwhile pixelWidth works identically to width so no help there.
Is there a solution, or is this a bug / feature request?
I don’t use the Windows operating system on a regular basis and therefore cannot answer your question. However, the demo below shows how to scale JavaFX drawing in case that could be a possible work around to the window scaling issue. The circles start out the same size, but only the first one is scaled up.
import javafx.stage.Stage;
import javafx.scene.layout.Pane;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.transform.Scale;
void setup() {
size(1, 1, FX2D);
Stage stage = new Stage();
Pane pane = new Pane();
// Circles start out the same size.
Circle circle1 = new Circle(200, 155, 50);
circle1.setFill(Color.BLUE);
pane.getChildren().add(circle1);
Circle circle2 = new Circle(450, 155, 50);
circle2.setFill(Color.RED);
pane.getChildren().add(circle2);
// Only circle1 is scaled.
Scale scale = new Scale();
scale.setX(2.5);
scale.setY(2.5);
scale.setPivotX(200); // Same as original coordinates
scale.setPivotY(155);
circle1.getTransforms().addAll(scale);
Scene scene = new Scene(pane, 600, 350);
stage.setTitle("Scaling transformation example JavaFX");
stage.setScene(scene);
stage.show();
}
NOTE :
Results may vary depending on version used!
I was using Processing 4.3.4 (error checking works) and Processing 4.4.4 (error checking broken) and they give different results depending on renderer.
How to disable scaling in JavaFX so it behaves like Processing:
You may be able to (see comment above!) turn off automatic DPI scaling in JavaFX by setting a system property:
System.setProperty("glass.win.uiScale", "1");
The above only seemed to work when starting a new FX2D PApplet (minimal code):
// NOTE:
// In W10 you also need to add the JavaFX JAR files to the sketch in a "code" folder. // Search forum for this discussion.
import processing.javafx.*;
// Corrected some "Type is ambiguous" errors
import javafx.scene.paint.Color;
import javafx.stage.Screen;
//Renderer Applets:
renderApp app; // FX2D
public void settings()
{
size(300, 300);
}
public void setup()
{
// Testing:
System.setProperty("glass.win.uiScale", "1"); // This works!
//displayDensity(1); //If needed!
surface.setVisible(true);
surface.setLocation(10, 10);
app = new renderApp();
Thread thread = new Thread(() -> PApplet.runSketch(new String[]{"renderApp"}, app));
thread.start();
}
public void draw()
{
background(0, 255, 0);
}
// FX2D
public class renderApp extends PApplet
{
public void settings()
{
size(300, 300, FX2D);
}
public void setup()
{
println(Screen.getPrimary().getOutputScaleX());
surface.setVisible(true);
surface.setLocation(320, 10);
Stage primaryStage = new Stage();
Pane root = new Pane();
root.setBackground(new Background(new BackgroundFill(Color.RED, null, null)));
Scene scene = new Scene(root, 300, 300);
primaryStage.setTitle("JavaFX Window");
primaryStage.setScene(scene);
primaryStage.setX(600+30);
primaryStage.setY(10);
primaryStage.show();
}
void draw()
{
background(255, 255, 0);
}
}