I am using JavaFX to create an application. In my code, I set the size of a window or elements using the setWidth() and setHeight() methods. For example:
stage.setWidth(400);
stage.setHeight(400);
What units are used for the values passed to these methods? Are they pixels or some other units? If they are pixels, where is this mentioned in the official documentation or other reliable sources?
I used the setWidth() and setHeight() methods in my JavaFX code and expected the sizes to be set in pixels. However, I couldn't find a clear statement in the official documentation confirming the units. I was looking for an authoritative source to verify if the units are indeed pixels or something else.
As I understand it, the width and height (as well as the x and y coordinates) of a stage are in the coordinates of the screen. (Note that if there are multiple physical displays these will be laid out in a virtual coordinate system encompassing all the screens' the Screen
API gives you access to this.)
The screen coordinates may or may not correspond to actual pixels: the relationship is specified by the outputScaleX
and outputScaleY
properties. These properties are properties of individual screens; they are also properties of Window
and the window properties are updated with the screen properties of the current screen in which the window is displayed.
The window is actually rendered at a scale defined by the renderScaleX
and renderScaleY
properties. By default this tracks the outputScale
properties, but can be changed in code.
Here's a quick test harness.
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.stage.Screen;
import javafx.stage.Stage;
import java.io.IOException;
public class ScaleTest extends Application {
@Override
public void start(Stage stage) throws IOException {
for (Screen screen : Screen.getScreens()) {
System.out.printf("""
Screen: %s%n
dpi: %s%n
outputScaleX/Y: %.3f x %.3f%n
Bounds: %s%n%n
""", screen, screen.getDpi(), screen.getOutputScaleX(), screen.getOutputScaleY(),
screen.getBounds());
}
stage.outputScaleXProperty().subscribe(x -> System.out.printf("Output scale x: %.3f%n", x));
stage.outputScaleYProperty().subscribe(y -> System.out.printf("Output scale y: %.3f%n", y));
stage.renderScaleXProperty().subscribe(x -> System.out.printf("Render scale x: %.3f%n", x));
stage.renderScaleYProperty().subscribe(y -> System.out.printf("Render scale y: %.3f%n", y));
Scene scene = new Scene(new BorderPane(), 400, 400);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}
I am running on a MacBookPro with an external display attached in addition to the default MacBook display. The external display is the "primary" screen with DPI 108 and the built-in "retina" display has a DPI of 151. When I move the stage from to the retina display it shrinks in "physical" size due to a different output scale, as can be seen in the output:
Screen: javafx.stage.Screen@18f04d17 bounds:Rectangle2D [minX=0.0, minY=0.0, maxX=5120.0, maxY=1440.0, width=5120.0, height=1440.0] visualBounds:Rectangle2D [minX=0.0, minY=25.0, maxX=5120.0, maxY=1355.0, width=5120.0, height=1330.0] dpi:108.0 outputScale:(1.0,1.0)
dpi: 108.0
outputScaleX/Y: 1.000 x 1.000
Bounds: Rectangle2D [minX=0.0, minY=0.0, maxX=5120.0, maxY=1440.0, width=5120.0, height=1440.0]
Screen: javafx.stage.Screen@cc4571c0 bounds:Rectangle2D [minX=-1800.0, minY=0.0, maxX=0.0, maxY=1169.0, width=1800.0, height=1169.0] visualBounds:Rectangle2D [minX=-1800.0, minY=44.0, maxX=0.0, maxY=1169.0, width=1800.0, height=1125.0] dpi:151.0 outputScale:(2.0,2.0)
dpi: 151.0
outputScaleX/Y: 2.000 x 2.000
Bounds: Rectangle2D [minX=-1800.0, minY=0.0, maxX=0.0, maxY=1169.0, width=1800.0, height=1169.0]
Output scale x: 1.000
Output scale y: 1.000
Render scale x: 1.000
Render scale y: 1.000
2025-01-22 11:53:06.057 java[19226:140296023] +[IMKClient subclass]: chose IMKClient_Legacy
2025-01-22 11:53:06.057 java[19226:140296023] +[IMKInputSession subclass]: chose IMKInputSession_Legacy
Render scale x: 2.000
Render scale y: 2.000
Output scale x: 2.000
Output scale y: 2.000