W tym poradniku prezentuję kolejne kroki, które umożliwiają wyłączenie bądź zmianę kursora myszki w całej aplikacji JavaFX. Znajdziesz tu rozwiązania problemów, z którymi zetknąłem się do tej pory implementując tytułowe wymaganie. W szczególności dowiesz się w jak sposób możemy wykryć zmianę kursora w kontrolce WebView, aby następnie móc go zmienić na dowolny inny lub też wyłączyć go całkowicie.
- Zmiana kursora myszy na dowolnej kontrolce JavaFX
- Zmiana kursora myszy na komponencie WebView
Zmiana kursora myszy na dowolnej kontrolce JavaFX
Rozważmy przedstawioną poniżej aplikację JavaFX typu HelloWorld. Składa się ona z klasy Main, pełniącej również rolę kontrolera, oraz przykładowej formatki sample.fxml. W klasie znajdziemy uchwyty do kontrolek Pane oraz WebView, jak również metodę initialize, która wykonuje się już po spięciu wspomnianych kontrolek z kontrolerem.
package sample; import javafx.application.Application; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.scene.Cursor; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.scene.layout.Pane; import javafx.scene.web.WebView; import javafx.stage.Stage; public class Main extends Application { @FXML private Pane myPane; @FXML private WebView myWebView; @FXML private void initialize() { } @Override public void start(Stage primaryStage) throws Exception{ Parent root = FXMLLoader.load(getClass().getResource("sample.fxml")); primaryStage.setTitle("Hello World"); Scene scene = new Scene(root, 300, 275); primaryStage.setScene(scene); primaryStage.show(); } public static void main(String[] args) { launch(args); } }
<?xml version="1.0" encoding="UTF-8"?> <?import javafx.scene.layout.HBox?> <?import javafx.scene.layout.Pane?> <?import javafx.scene.web.WebView?> <HBox fx:controller="sample.Main" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.121" xmlns:fx="http://javafx.com/fxml/1"> <children> <Pane prefHeight="200.0" prefWidth="200.0" fx:id="myPane"/> <WebView prefHeight="200.0" prefWidth="200.0" fx:id="myWebView" /> </children> </HBox>
package sample; import javafx.application.Application; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.scene.Cursor; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.scene.layout.Pane; import javafx.scene.web.WebView; import javafx.stage.Stage; public class Main extends Application { @FXML private Pane myPane; @FXML private WebView myWebView; @FXML private void initialize() { } @Override public void start(Stage primaryStage) throws Exception{ Parent root = FXMLLoader.load(getClass().getResource("sample.fxml")); primaryStage.setTitle("Hello World"); Scene scene = new Scene(root, 300, 275); scene.setCursor(Cursor.NONE); primaryStage.setScene(scene); primaryStage.show(); } public static void main(String[] args) { launch(args); } }
package sample; import javafx.application.Application; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.scene.Cursor; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.scene.layout.Pane; import javafx.scene.web.WebView; import javafx.stage.Stage; public class Main extends Application { @FXML private Pane myPane; @FXML private WebView myWebView; @FXML private void initialize() { myPane.setCursor(Cursor.OPEN_HAND); } @Override public void start(Stage primaryStage) throws Exception{ Parent root = FXMLLoader.load(getClass().getResource("sample.fxml")); primaryStage.setTitle("Hello World"); Scene scene = new Scene(root, 300, 275); primaryStage.setScene(scene); primaryStage.show(); } public static void main(String[] args) { launch(args); } }
Zmiana kursora myszy na komponencie WebView
[quads id=1]
Komponent WebView pełni w JavaFX rolę przeglądarki internetowej. W związku z z tym jego głównym zadaniem jest wyświetlanie stron HTML. W przypadku kontrolki WebView problem ukrycia lub zmiany kursora staje się nieco bardziej skomplikowany, ponieważ kursor myszy podczas przeglądania stron internetowych zmienia się dość często a dodatkowo wywołanie metody setCursor na komponencie WebView wydaje się nie przynosić efektu.
Nie jest to jednak do końca prawda. Wywołując metodę myWebView.setCursor(Cursor.NONE) faktycznie ukrywamy kursor, jednak ruch myszki powoduje, że dostosowuje się on do zawartości przeglądanej strony zmieniając się na odpowiedni do danej sytuacji (np. wskazując na link).
package sample; import javafx.application.Application; import javafx.fxml.FXML; import javafx.fxml.FXMLLoader; import javafx.scene.Cursor; import javafx.scene.Parent; import javafx.scene.Scene; import javafx.scene.layout.Pane; import javafx.scene.web.WebView; import javafx.stage.Stage; public class Main extends Application { @FXML private Pane myPane; @FXML private WebView myWebView; @FXML private void initialize() { myPane.setCursor(Cursor.CROSSHAIR); myWebView.setCursor(Cursor.MOVE); myWebView.cursorProperty().addListener((observable, oldValue, newValue) -> { myWebView.setCursor(Cursor.MOVE); }); } @Override public void start(Stage primaryStage) throws Exception{ Parent root = FXMLLoader.load(getClass().getResource("sample.fxml")); primaryStage.setTitle("Hello World"); Scene scene = new Scene(root, 300, 275); scene.setCursor(Cursor.OPEN_HAND); primaryStage.setScene(scene); primaryStage.show(); } public static void main(String[] args) { launch(args); } }