Issue
My application combines Swing and JavaFX. I'd like all components to use the same cursor.
What is the best way to create a JavaFX cursor from a AWT cursor?
EDIT: there is an utility package called javafx.embed.swing.SwingCursors
, unfortunately it is not public. But maybe I can steal code from it.
Solution
The tricky thing about mixing Swing and JavaFX is that they each need to execute in one particular thread. Other than that, making cursors for each toolkit is fairly straightforward.
Obtaining a standard cursor:
private java.awt.Cursor awtCursor;
private javafx.scene.Cursor fxCursor;
// ...
EventQueue.invokeLater(() -> {
awtCursor = java.awt.Cursor.getPredefinedCursor(
java.awt.Cursor.CROSSHAIR_CURSOR);
});
Platform.runLater(() -> {
fxCursor = javafx.scene.Cursor.CROSSHAIR;
});
It’s easy to spot the analogues between the list of standard AWT cursors() with the list of standard JavaFX cursors.
Making a custom cursor from an image URL:
private java.awt.Cursor awtCursor;
private javafx.scene.Cursor fxCursor;
// ...
URL cursorURL = MyApplication.class.getResource("specialcursor.png");
EventQueue.invokeLater(() -> {
java.awt.Toolkit toolkit = java.awt.Toolkit.getDefaultToolkit();
awtCursor = toolkit.createCustomCursor(
toolkit.getImage(cursorURL),
new java.awt.Point(12, 12),
"specialcursor");
});
Platform.runLater(() -> {
fxCursor = new ImageCursor(
new javafx.scene.image.Image(cursorURL.toString()), 12, 12);
});
For existing images, it’s pretty similar, but you have to mind the thread constraints.
Making a custom cursor from an existing AWT image:
private java.awt.Cursor awtCursor;
private javafx.scene.Cursor fxCursor;
// ...
EventQueue.invokeLater(() -> {
java.awt.Image image = /* ... */;
awtCursor = toolkit.createCustomCursor(
image,
new java.awt.Point(12, 12),
"specialcursor");
Platform.runLater(() -> {
fxCursor = new ImageCursor(
javafx.embed.swing.SwingFXUtils.toFXImage(image, null),
12, 12);
});
});
Making a custom cursor from an existing JavaFX image:
private java.awt.Cursor awtCursor;
private javafx.scene.Cursor fxCursor;
// ...
Platform.runLater(() -> {
javafx.scene.image.Image image = /* ... */;
fxCursor = new ImageCursor(image, 12, 12);
EventQueue.invokeLater(() -> {
awtCursor = toolkit.createCustomCursor(
javafx.embed.swing.SwingFXUtils.fromFXImage(image, null),
new java.awt.Point(12, 12),
"specialcursor");
});
});
Answered By - VGR