I have a problem. I have two classes in same javafx package. A single html file with javascript at the head section, a java class(extending Application). Now the problem is when i tried to click the button after the page is displayed in the javafx webview, nothing is updated in the webView. Below is the code for the two file. Please i need to know why it isn't working. i have been debugging this problem since 8hrs now, no success. thanks in advance. java class
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import javafx.application.Application;
import javafx.concurrent.Worker;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import netscape.javascript.JSObject;
public class JavaFXApplication25 extends Application {
// inner class
public class Adder
{
public double add(double n, double m)
{
return n + m;
}
}
@Override
public void start(Stage primaryStage) throws URISyntaxException, MalformedURLException {
WebView w = new WebView();
WebEngine e = w.getEngine();
e.setJavaScriptEnabled(true);
e.load(this.getClass().getResource("tester.html").toURI().toURL().toExternalForm());
Scene scene = new Scene(new VBox(w));
primaryStage.setScene(scene);
primaryStage.show();
// make javascript aware of java object
e.getLoadWorker().stateProperty().addListener(
(p, o, n) ->{
if(n == Worker.State.SUCCEEDED){
JSObject b = (JSObject) e.executeScript("window");
b.setMember("adder", new Adder());
}
}
);
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
The html file
<html>
<head>
<title>TODO supply a title</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script type="text/javascript">
function addNum(){
var n1 = Number(document.getElementById('num1').value);
var n2 = Number(document.getElementById('num2').value);
var n3 = adder.add(n1, n2);
document.getElementById('r').innerHTML = n3;
}
</script>
</head>
<body>
<input type="text" id="num1" />
<input type="text" id="num2" />
<p> <span id="r"> </span></p>
<button onclick="addNum()" >Add</button>
</body>
The point is that the programs runs and displays the page, but on pressing the button, nothing is updated on the page I even tried to make the upcall before loading the html page, yet, no success. Please someone should help check the bug in the code. Thanks once again.
Now below is the output after been run. It shows nothing even after when the Add button is clicked several times! No error message on the standard console, nothing nothing! output
Welcome to the execrable pain in the ass that is DOM event sync between JavaFX and DOM stuff.
The worker state "SUCCEEDED" does not necessarily mean that the DOM is loaded in the page.
The DOM is loaded at document.onLoad() ... and even so it's kind of a can of worms since not all content is loaded by that time (images and stuff). JQuery has a convenient
JQuery(document).ready(function (e){ /*do whatever*/ })routine you can use to trigger something that lets JavaFX know that it's ready to do stuff in the DOM (basically what you tried to accomplish with the code above[..]Worker.State.SUCCEEDED[..])Essentially the sequence of events is something like:
To add insult to injury, this sequence of events can take anywhere between 1ms and 1 minute to reach (8)... it's arbitrary as hell.
I wound up writing code which starts comparing node trees for changes in order to figure out when exactly to start messing with the DOM.... but i digress.
What you want is to make sure you initiate your JS-JavaFX communication protocol once the DOM is ready to run your custom javascript.
Put that shit in
document.onLoad(), listen for it inside JavaFX, and then set the adder as you did so already... then hope for the best.