
FAQ JavaFXConsultez toutes les FAQ
Nombre d'auteurs : 4, nombre de questions : 507, derni�re mise � jour : 2 novembre 2016 Ajouter une question
Cette FAQ a �t� r�alis�e � partir des questions fr�quemment pos�es sur le forum JavaFX de http://java.developpez.com ainsi que l'exp�rience personnelle des auteurs.
Nous tenons � souligner que cette FAQ ne garantit en aucun cas que les informations qu'elle propose sont correctes. Les auteurs font leur maximum, mais l'erreur est humaine. Cette FAQ ne pr�tend pas non plus �tre compl�te. Si vous trouvez une erreur, ou que vous souhaitez nous aider en devenant r�dacteur, lisez ceci.
Sur ce, nous vous souhaitons une bonne lecture.
- Comment tester si le web est support� sur ma plateforme ?
- Comment afficher une page web ?
- Comment r�cup�rer une r�f�rence sur le WebEngine de la vue ?
- Comment charger une page web ?
- Comment savoir quand une page est compl�tement charg�e ?
- Est-il possible d'afficher une page web HTML5 en utilisant JavaScript ?
- Est-il possible d'afficher une page web contenant du Flash ?
- Comment interagir avec la page web depuis Java ?
- Comment interagir avec Java depuis la page web ?
- Comment s'interfacer avec Google Maps ?
Pour tester si le rendu des pages web est support� par votre plateforme, vous pouvez invoquer la m�thode isSupported() de la classe javafx.application.Platform en lui passant en param�tre la valeur javafx.application.ConditionalFeature.WEB :
Code Java : | S�lectionner tout |
Platform.isSupported(ConditionalFeature.WEB);
� l'heure actuelle (JDK8_u20), le rendu des pages web n'est pas disponible sur la version ARM du JDK destin�e aux plateformes embarqu�es (ex. : Raspberry Pi, etc.).
Pour afficher une page web, vous devez inclure dans votre sc�ne un n�ud graphique de type javafx.scene.web.WebView. Ce n�ud est un n�ud graphique comme un autre, il peut donc �tre d�plac�, modifi� et subir des effets ou transformations comme n'importe quel autre n�ud SceneGraph.
Par exemple :
Code Java : | S�lectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | public class Main extends Application { @Override public void start(Stage primaryStage) { final WebView webView = new WebView(); final Scene scene = new Scene(webView, 350, 300); primaryStage.setTitle("Test de WebView"); primaryStage.setScene(scene); primaryStage.show(); } public static void main(String[] args) { launch(args); } } |
Ici, bien s�r l'affichage reste vierge puisque nous n'avons charg� aucune page web.
WebView est en fait une vue sur un objet de type javafx.scene.web.WebEngine, un moteur de page web, qui se chargera d'afficher une page web, de maintenir et manipuler son DOM, d�interpr�ter du code JavaScript ou encore de permettre la communication dans les deux sens entre Java et JavaScript. WebEngine est bas� sur

Il est possible de r�cup�rer une r�f�rence sur le WebEngine en invoquant la m�thode getEngine() de la classe WebView.
Par exemple :
Code Java : | S�lectionner tout |
final WebEngine webEngine = webView.getEngine();
Il suffit d'invoquer la m�thode load() de la classe WebEngine pour charger une URL de la page web.
La page web peut provenir de plusieurs sources :
- la page web peut �tre empaquet�e dans une biblioth�que ou une application et r�cup�r�e via le m�canisme des ressources ou des ClassLoader.
Code Java : S�lectionner tout 1
2final URL url = getClass().getResource("page.html"); webView.getEngine().load(url.toExternalForm());
Dans ce cas, la page et toutes ses ressources locales (images, sons, biblioth�ques JavaScript, etc. sp�cifi�es par des chemins d�acc�s relatifs) seront charg�es directement depuis les fichiers JAR ; - la page web peut �tre sur un disque local et peut �tre r�f�renc�es par les classes File, Path, URI ou URL.
Code Java : S�lectionner tout 1
2final String pageURI= new File("page.html").toURI().toString(); webView.getEngine().load(pageURI);
Dans ce cas, la page et toutes ses ressources locales (images, sons, biblioth�ques JavaScript, etc. sp�cifi�es par des chemins d�acc�s relatifs) seront charg�es directement depuis le r�pertoire parent sur le disque ; - la page web peut �tre h�berg�e sur un site web distant et on peut y acc�der par une String ou une URL contenant son chemin d�acc�s.
Code Java : S�lectionner tout webView.getEngine().load("http://www.developpez.com");
Cette instruction chargera la page de garde du site de D�veloppez dans la vue.
Dans ce cas, la page et toutes ses ressources locales (images, sons, biblioth�ques JavaScript, etc. sp�cifi�es par des chemins d�acc�s relatifs) seront charg�es directement depuis le site d�h�bergement distant.
Le chargement de la page est asynchrone : la m�thode retourne imm�diatement et la page sera charg�e ult�rieurement en fonction de son poids et de la vitesse de connexion ainsi que de sa complexit�.
Pour savoir si une page est compl�tement charg�e, ou m�me si son chargement �choue, il suffit d'observer le changement d��tat de la t�che qui effectue le chargement. Le WebEngine dispose en effet de la propri�t� loadWorker qui permet d�acc�der � la t�che qui g�re le chargement de la page. Cette t�che dispose d'une propri�t� state dont la valeur �volue avec le temps.
Par exemple, si avant de charger notre page web nous faisons :
Code Java : | S�lectionner tout |
1 2 3 | webView.getEngine().getLoadWorker().stateProperty().addListener((ObservableValue<? extends Worker.State> observableValue, Worker.State oldValue, Worker.State newValue) -> { System.out.printf("%s -> %s", oldValue, newValue).println(); }); |
Nous pouvons d�sormais suivre l'avancement du chargement de la page.
Ainsi, en chargeant la page de garde du site de D�veloppez, nous aurons une sortie similaire � :
Code : | S�lectionner tout |
1 2 3 | READY -> SCHEDULED SCHEDULED -> RUNNING RUNNING -> SUCCEEDED |
Oui, il est possible d'afficher une page contenant du contenu au format HTML5 ou des biblioth�ques tierces JavaScript (ex. : angular.js). Il faudra bien s�r v�rifier que la biblioth�que fonctionne correctement quand elle est utilis�e dans cet environnement.
Non, il n'est pas possible d'afficher une page web contenant du flash ou n'importe quel type de technologies qui n�cessiteraient un plugin externe dans le navigateur.
Il est possible d'interagir avec le contenu de la page web depuis Java en invoquant la m�thode executeScript() de la classe WebEngine. Cette m�thode permet d�ex�cuter du code au format JavaScript et le cas �ch�ant peut retourner son r�sultat.
Par exemple :
Code Java : | S�lectionner tout |
webEngine.executeScript("history.back()");
Cette m�thode invoque la fonction back() de l'historique de navigation et chargera la page pr�c�dente.
Il est aussi possible de r�cup�rer des variables contenues dans le document. Pour les types de base, la conversion sera automatique d'entre Java et JavaScript (integer deviendra Integer, string deviendra String, etc.).
Les objets JavaScript plus complexes seront empaquet�s sous le type netscape.javascript.JSObject. Il est possible d'invoquer les m�thodes habituelles de la

Par exemple :
Code Java : | S�lectionner tout |
1 2 | final JSObject history = (JSObject) webEngine.executeScript("history"); history.call("back"); |
Ce bout de code a un effet identique au pr�c�dent : nous demandons � l'historique de navigation de charger la page pr�c�dente. Cependant, ici, nous manipulons directement l'objet historique depuis le code Java.
Il est tout � fait possible d�interagir depuis la page web avec notre programme �crit en Java.
Commen�ons par d�finir un formulaire simple qui d�finit deux champs de saisie, un pour le pr�nom et un autre pour le nom d'une personne.
Code HTML : | S�lectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <!DOCTYPE html> <html> <head> <title>Formulaire de saisie</title> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head> <body> <form> Pr�nom : <input type="text" name="firstname" onkeyup="java.setFirstName(this.value)"><br> Nom : <input type="text" name="lastname" onkeyup="java.setLastName(this.value)"> </form> </body> </html> |
Sur chacun de ces champs de saisie, nous avons d�fini un callback qui appelle, en JavaScript, une m�thode sur un objet nomm� � java � en passant en param�tre la valeur de notre champ. Or, pour le moment, notre document ne contient aucune variable nomm�e ainsi.
Nous allons nous en charger� depuis le code Java en passant, via le WebEngine, un objet, �crit en Java, qui sera attach� au document web sous le nom de � java �. Cet objet formera un pont entre les deux environnements et permettra ainsi le dialogue.
Prenons le code suivant :
Code Java : | S�lectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | public class Main extends Application { public static class Pont { public void setFirstName(String value) { System.out.printf("Pr�nom : %s", value).println(); } public void setLastName(String value) { System.out.printf("Nom : %s", value).println(); } } // Cet objet sert de pont entre Java et JavaScript. private final Pont pont = new Pont(); @Override public void start(Stage primaryStage) { final WebView webView = new WebView(); // Chargement du formulaire. webView.getEngine().load(getClass().getResource("Form.html").toExternalForm()); // On passe maintenant l'objet java au formulaire. final JSObject jsobj = (JSObject) webView.getEngine().executeScript("window"); jsobj.setMember("java", pont); final Scene scene = new Scene(webView, 350, 300); primaryStage.setTitle("Test de chargement de WebView"); primaryStage.setScene(scene); primaryStage.show(); } public static void main(String[] args) { launch(args); } } |
Nous avons d�fini une nouvelle classe Pont disposant des m�thodes qui seront appel�es depuis le code JavaScript. Nous r�cup�rons, via le WebEngine, un objet objet de type JSObject qui repr�sente la � fen�tre web � du document. Nous attachons ensuite notre objet de type Pont sur cette r�f�rence en lui donnant le nom de variable � java �.
D�sormais, notre formulaire web fonctionne comme pr�vu : lorsque l'utilisateur saisit un caract�re dans un des deux champs, la m�thode appropri�e est invoqu�e dans l'objet de type Pont. Nous pouvons ainsi faire remonter des valeurs depuis notre page web vers notre code Java.
Veuillez noter qu'il est tr�s important de conserver, dans votre code Java, une r�f�rence vers cet objet pont sous peine de voir le garbage collector le lib�rer de mani�re anticip�e ce qui emp�cherai toute communication ult�rieure entre le code JavaScript et le code Java. En effet, le WebEngine ne conserve qu'une r�f�rence faible sur les objets qui lui sont pass�s et ce pour �viter des fuites m�moires.
L'exemple suivant montre comment interfacer notre application avec un service en ligne, ici l'API Maps de Google qui permet d'interagir avec
Google Maps. Vous pouvez bien sur l'adapter pour interface d'autres services Web tels que
OpenStreetMap,
Leaflet, etc.
Nous allons commencer par inclure dans notre projet un fichier Connector.html qui va afficher une carte Google Maps dans une page web et d�finir sur le document quelques fonctions �crites en JavaScript que nous allons pouvoir appeler depuis notre code Java :
Code HTML : | S�lectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 | <!DOCTYPE html> <html> <head> <meta name="viewport" content="initial-scale=1.0, user-scalable=no" /> <style type="text/css"> html { height: 100% } body { height: 100%; margin: 0px; padding: 0px } #map_canvas { height: 100%; background-color: #666970; } </style> <script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=false"></script> <script type="text/javascript"> function initialize() { var latlng = new google.maps.LatLng(0, 0); var myOptions = { zoom: 3, center: latlng, mapTypeId: google.maps.MapTypeId.ROADMAP, disableDoubleClickZoom: false, keyboardShortcuts: true, scrollwheel: true, draggable: true, disableDefaultUI: false, // Completly disable all controls. mapTypeControl: false, // Allow to change map type. overviewMapControl: false, // Small window of overview. panControl: false, // Disc used to pan the map. rotateControl: false, // Scale slider? navigationControl: false, // Scale slider? streetViewControl: false, // Place a streetview camera. scaleControl: false, // Scale slider? zoomControl: false, // Scale slider? backgroundColor: "#666970", }; document.geocoder = new google.maps.Geocoder(); document.map = new google.maps.Map(document.getElementById("map_canvas"), myOptions); document.zoomIn = function zoomIn() { var zoomLevel = document.map.getZoom(); if (zoomLevel <= 20) document.map.setZoom(zoomLevel + 1); } document.zoomOut = function zoomOut() { var zoomLevel = document.map.getZoom(); if (zoomLevel > 0) document.map.setZoom(zoomLevel - 1); } document.setMapTypeRoad = function setMapTypeRoad() { document.map.setMapTypeId(google.maps.MapTypeId.ROADMAP); } document.setMapTypeSatellite = function setMapTypeSatellite() { document.map.setMapTypeId(google.maps.MapTypeId.SATELLITE); } document.setMapTypeHybrid = function setMapTypeHybrid() { document.map.setMapTypeId(google.maps.MapTypeId.HYBRID); } document.setMapTypeTerrain = function setMapTypeTerrain() { document.map.setMapTypeId(google.maps.MapTypeId.TERRAIN); } document.goToLocation = function goToLocation(searchString) { document.geocoder.geocode({'address': searchString}, function (results, status) { if (status == google.maps.GeocoderStatus.OK) { document.map.setCenter(results[0].geometry.location); } else { alert("Geocode was not successful for the following reason: " + status); } }); } } </script> </head> <body onload="initialize()"> <div id="map_canvas" style="width:100%; height:100%"></div> </body> </html> |
Nous pouvons tester que cette page se charge correctement dans un navigateur Web avant de passer � l��tape suivante
Nous allons maintenant cr�er une interface en JavaFX qui charge ce connecteur dans une WebView. Nous allons �galement ajouter des contr�les qui vont interagir avec le WebEngine pour invoquer les fonctions �crites en JavaScript. Le code parait long, mais c'est principalement � cause du montage de l'UI :
Code Java : | S�lectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 | public class Main extends Application { @Override public void start(Stage primaryStage) { final WebView webView = new WebView(); AnchorPane.setTopAnchor(webView, 0d); AnchorPane.setLeftAnchor(webView, 0d); AnchorPane.setBottomAnchor(webView, 0d); AnchorPane.setRightAnchor(webView, 0d); // Barre sur le haut de l'�cran : affichage. final ToggleGroup displayGroup = new ToggleGroup(); final ToggleButton roadToggle = new ToggleButton("Route"); roadToggle.setDisable(true); roadToggle.setToggleGroup(displayGroup); roadToggle.setSelected(true); final ToggleButton satelliteToggle = new ToggleButton("Satellite"); satelliteToggle.setDisable(true); satelliteToggle.setToggleGroup(displayGroup); final ToggleButton hybrideToggle = new ToggleButton("Hybride"); hybrideToggle.setDisable(true); hybrideToggle.setToggleGroup(displayGroup); final ToggleButton terrainToggle = new ToggleButton("Terrain"); terrainToggle.setDisable(true); terrainToggle.setToggleGroup(displayGroup); displayGroup.selectedToggleProperty().addListener((ObservableValue<? extends Toggle> observableValue, Toggle oldValue, Toggle newValue) -> { String script = null; if (newValue == roadToggle) { script = "document.setMapTypeRoad()"; } else if (newValue == satelliteToggle) { script = "document.setMapTypeSatellite()"; } else if (newValue == hybrideToggle) { script = "document.setMapTypeHybrid()"; } else if (newValue == terrainToggle) { script = "document.setMapTypeTerrain()"; } if (script != null) { webView.getEngine().executeScript(script); } }); final HBox topControls = new HBox(roadToggle, satelliteToggle, hybrideToggle, terrainToggle); AnchorPane.setTopAnchor(topControls, 6d); AnchorPane.setLeftAnchor(topControls, 50d); // Barre sur la gauche de l'�cran : zoom. final Button zoomInButton = new Button("+"); zoomInButton.setDisable(true); zoomInButton.setStyle("-fx-background-radius: 20, 19, 18, 17;"); zoomInButton.setPrefSize(28, 28); zoomInButton.setOnAction(actionEvent -> webView.getEngine().executeScript("document.zoomIn();")); final Button zoomOutButton = new Button("-"); zoomOutButton.setDisable(true); zoomOutButton.setStyle("-fx-background-radius: 20, 19, 18, 17;"); zoomOutButton.setPrefSize(28, 28); zoomOutButton.setOnAction(actionEvent -> webView.getEngine().executeScript("document.zoomOut();")); final VBox leftControls = new VBox(zoomInButton, zoomOutButton); leftControls.setSpacing(6); AnchorPane.setTopAnchor(leftControls, 50d); AnchorPane.setLeftAnchor(leftControls, 6d); // Barre en bas de l'�cran : recherche. final TextField searchField = new TextField(); searchField.setDisable(true); searchField.setEditable(false); HBox.setHgrow(searchField, Priority.ALWAYS); final Button searchButton = new Button("Chercher"); searchButton.setDisable(true); searchButton.setOnAction(actionEvent -> { final String toSearch = searchField.getText(); if (toSearch != null && !toSearch.trim().isEmpty()) { webView.getEngine().executeScript(String.format("document.goToLocation('%s');", toSearch.trim())); } }); final HBox bottomControls = new HBox(searchField, searchButton); bottomControls.setSpacing(6); AnchorPane.setLeftAnchor(bottomControls, 75d); AnchorPane.setBottomAnchor(bottomControls, 16d); AnchorPane.setRightAnchor(bottomControls, 6d); // Assemblage. final AnchorPane root = new AnchorPane(); root.getChildren().setAll(webView, leftControls, topControls, bottomControls); final Scene scene = new Scene(root, 350, 300); primaryStage.setTitle("Test de Google Map"); primaryStage.setScene(scene); primaryStage.show(); // Chargement de la page. webView.getEngine().getLoadWorker().stateProperty().addListener((ObservableValue<? extends Worker.State> observableValue, Worker.State oldValue, Worker.State newValue) -> { final boolean disabled = newValue != Worker.State.SUCCEEDED; zoomInButton.setDisable(disabled); zoomOutButton.setDisable(disabled); roadToggle.setDisable(disabled); satelliteToggle.setDisable(disabled); hybrideToggle.setDisable(disabled); terrainToggle.setDisable(disabled); searchField.setEditable(!disabled); searchField.setDisable(disabled); searchButton.setDisable(disabled); }); webView.getEngine().load(getClass().getResource("Connector.html").toExternalForm()); } public static void main(String[] args) { launch(args); } } |
Ce qui nous donne le r�sultat suivant :

Une fois la page compl�tement charg�e, les contr�les seront activ�s. Quand vous cliquez sur le bouton charg� du zoom avant, par exemple, ce dernier demande au WebEngine d'ex�cuter la fonction JavaScript document.zoomIn(). Le contenu de la page web se met alors � jour avec le nouvel affichage.
Proposer une nouvelle r�ponse sur la FAQ
Ce n'est pas l'endroit pour poser des questions, allez plut�t sur le forum de la rubrique pour �aLes sources pr�sent�es sur cette page sont libres de droits et vous pouvez les utiliser � votre convenance. Par contre, la page de pr�sentation constitue une �uvre intellectuelle prot�g�e par les droits d'auteur. Copyright � 2025 Developpez Developpez LLC. Tous droits r�serv�s Developpez LLC. Aucune reproduction, m�me partielle, ne peut �tre faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'� trois ans de prison et jusqu'� 300 000 � de dommages et int�r�ts.