Reputation: 5602
So I've found this tutorial on how to use google maps API in a Desktop JavaFX application.
The point is that I can't figure out how can I pass data from WebView (javascripts variables, jsons..) to controller and viceversa.
I'd like to make an textfield that on textinput to automaticaly search that address and add an marker there (and viceversa when I move the marker to populate the input). The javascript standalone is no problem for me, but I don't know how to call javascript functions from JavaFX controller or how to send back the variables from javascript (longitude, latitude, etc)
Upvotes: 8
Views: 7401
Reputation: 257
Before you need sure you can use :
import netscape.javascript.JSObject;
2)check these Files:
HelloApplicaion.java
package com.example.map;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.io.IOException;
public class HelloApplication extends Application {
@Override
public void start(Stage stage) throws IOException {
FXMLLoader fxmlLoader = new FXMLLoader(HelloApplication.class.getResource("hello-view.fxml"));
Scene scene = new Scene(fxmlLoader.load(), 1100, 500);
stage.setResizable(false);
stage.setTitle("Hello!");
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}
HelloController.java
package com.example.map;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Worker;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.beans.value.ChangeListener;
import netscape.javascript.JSObject;
import java.net.URL;
import java.util.ResourceBundle;
import java.lang.*;
import javafx.concurrent.Worker.State;
public class HelloController implements Initializable {
@FXML
private WebView view;
private WebEngine engine;
@FXML
private Button b1, b2, b4 ,b3;
// private String link = "file:///index.html";
private String link = getClass().getResource("index.html").toExternalForm();
@FXML
protected void from_pc_to_webview() {
b3.setText("Welcome to JavaFX Application!");
String name="sssss";
engine.setJavaScriptEnabled(true);
engine.executeScript("me()");
}
@Override
public void initialize(URL url, ResourceBundle rb) {
engine = view.getEngine();
engine.load(link);
Worker<Void> worker = engine.getLoadWorker();
worker.stateProperty().addListener(new ChangeListener<State>() {
@Override
public void changed(ObservableValue<? extends State> observableValue, State state, State t1) {
if (t1 == Worker.State.SUCCEEDED) {
JSObject window = (JSObject) engine.executeScript("window");
window.setMember("myObject", new MyObject());
}
}
});
}//initialize
public static class MyObject {
public void doIt() {
System.out.println("Get data from Html <---------");
}
}
@FXML
protected void b1() {
// b4.setText("Welcome to JavaFX Application!");
engine.setJavaScriptEnabled(true);
String me="ddddddddddddddddddddddddddddddddddddddddddddd";
engine.executeScript("me('"+me+"');");
System.out.println("eeeeeeeeeeeeeeeeeeeeeeeeee");
}
}//CLASS
hello-view.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.web.*?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/16" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.example.map.HelloController">
<children>
<WebView fx:id="view" layoutX="50.0" layoutY="0.0" prefHeight="2.0" prefWidth="3.0" AnchorPane.bottomAnchor="30.0" AnchorPane.leftAnchor="100.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="60.0" />
<Button fx:id="b1" layoutX="0.0" layoutY="0.0" mnemonicParsing="false" text="b1" onAction="#b1" />
<Button fx:id="b2" layoutX="55.0" layoutY="0.0" mnemonicParsing="false" text="b2" />
<Button fx:id="b3" layoutX="165.0" layoutY="0.0" mnemonicParsing="false" text="send_to_web" onAction="#from_pc_to_webview"/>
</children>
</AnchorPane>
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form id="form1" name="form1">
<input type="text" id="text1">text value</input>
</form>
<button onclick="java.hi()">Submit</button>
<br/>
<div id="fd">fffffffff</div>
<button onclick="me()">me</button>
<button onclick="ddddddddddd()">html--->java</button>
<button onclick="ddddddddddd()">ddddddddddd</button>
<script>
function me(me){
var myDiv = document.getElementById("fd");
myDiv.innerHTML = me;
}
function ddddddddddd(){
var myDiv = document.getElementById("fd");
myDiv.innerHTML = "-------------------";
window.myObject.doIt();
}
</script>
</body>
</html>
Maybe you need to update your Maven :
Upvotes: 0
Reputation: 159486
See the JavaFX WebView tutorial sections:
Make sure you use JavaFX 2.1+ when doing this, as JavaFX 2.0 does not have full support for upcalls from javaScript to JavaFX.
How to call javascript functions from JavaFX controller?
Java code to be executed after the document has loaded:
webView.getEngine().executeScript("<write your javascript here>");
How to send back the variables from javascript (longitude, latitude, etc)?
Here is a generic communication sample, replace it with the actual Java and JavaScript logic you want to execute.
Java code:
// Add a Java callback object to a WebEngine document once it has loaded.
webEngine.getLoadWorker().stateProperty().addListener(
new ChangeListener<State>() {
@Override public void changed(ObservableValue<? extends State> ov, State oldState, State newState) {
if (newState == State.SUCCEEDED) {
JSObject win = (JSObject) webEngine.executeScript("window");
win.setMember("app", new JavaApp());
}
}
});
}
...
// JavaScript interface object
private class JavaApp {
public void exit() {
Platform.exit();
}
}
JavaScript code (in this case embedded in an onclick handler for a html href):
<a href="about:blank" onclick="app.exit()">Exit the Application</a>
Upvotes: 9