Getting the monitor's refresh rate with AWT/Swing:
java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment()
.getDefaultScreenDevice()
.getDisplayMode()
.getRefreshRate()
Question: Is there a similar method/procedure in getting the refresh rate with JavaFX? And if there is one, how to do it?
No equivalent public API in JavaFX
This is the
DisplayMode.getRefreshRate()javadoc for the awt API you are currently using:There is no equivalent public JavaFX API.
If the public api existed in JavaFX, it would probably be accessible via the Screen class, but there is no accessor for such functionality defined there.
There is an undocumented, unsupported, private API which would appear to offer similar functionality:
JavaFX pulse processing
Related information on how JavaFX works can be found in the pulse documentation for the JavaFX architecture description.
The screen hardware refresh rate is different from JavaFX internal pulse processing rate. Though I guess it is technically possible that these could be synchronized in the internal implementation (and that may happen in some cases), there is nothing in the public documentation which mentions whether that actually occurs.
A note on adaptive refresh technologies
Also note, with the advent of technologies such as gsync and free sync the refresh rate can be adapted to the content.
Such technologies make the notion of relying on a hardware refresh rate in the monitor a bit blurry at best.
Answers to FAQs
You state that your intention for querying the display refresh rate is:
JavaFX is, by default intentionally capped at a 60fps frame-rate, regardless of the monitor specifications.
This cap can be overridden using undocumented system properties, as outlined here:
You could use the undocumented feature to remove the frame rate cap in JavaFX and then rely on the underlying video card driver and hardware to render at the maximum rate available within the underlying hardware and software capability for the screen.
Here is the code which deals with that in the openjfx source.
In the source, the framerate is governed by the undocumented property
javafx.animation.framerate, which corresponds to the settingFRAMERATE_PROPin the above source andjavafx.animation.pulsewhich corresponds to the settingPULSE_PROP.The internal Toolkit class provides a fallback API to use the refresh rate of the display.
So perhaps you could achieve what you want by setting the the system property
javafx.animation.framerate, to the value ofcom.sun.javafx.tk.Toolkit.getToolkit().getRefreshRate()or by setting bothjavafx.animation.framerateandjavafx.animation.pulseto null. I have not tried this, so I do not know. Care would need to be taken to ensure that the values that you set are correctly maintained and not overridden by defaults.You need to be aware that, if you do this, you are making use of undocumented APIs so this would require opening appropriate module exports so that the APIs are accessible and also may be removed or become incompatible without notice in future versions of the platform (though these settings have been unchanged for many years currently).
By default, yes, it is a tradeoff.
For the types of applications generally developed using JavaFX 60fps refresh max within the pulse rendering mechanism is generally sufficient regardless of the underlying hardware capabilities of the device. Increasing the rate cap above that level is usually not a good tradeoff for most JavaFX applications as it means use of higher resources (CPU and Video processing capacity and power draw), for gains in refresh updates which are generally undetectable to most users and often not supported by underlying hardware.
That said, if you want to override this default limit, there are undocumented ways of doing so, as mentioned above.
Using the AWT method may be a reasonable alternative in this case.
The hardware refresh won't change depending on the chosen UI toolkit.
Currently (JavaFX 17), the JavaFX system depends on the
java.awtpackage (javafx.basemodule requires thejava.desktopmodule which contains all of the awt classes). So if JavaFX is available, so is thejava.awt.DisplayModeclass.So if the goal is to determine the hardware refresh rate, you can do that using the existing awt API.
Hardware refresh rate will not change depending on the UI toolkit used.
The definition of the scene graph pulse rate in JavaFX for updating rendering of the scene graph is somewhat related to refresh rate, but is a JavaFX only concept because Swing does not make use of a scene graph during its rendering phase.