Issue
I have a JavaFX application where I am loading the HTML page. The HTML generates a Base64 which is being written to a file once it is loaded using JavaScript bridge. I am trying to get this Base64 data once it is written from the main class. How can I achieve it?
Below is the code.
Test.java
public class Test {
public static void main(String[] args) throws InterruptedException {
String input = "[{'name': 'sub',
'description': 'sub',
'length': 25,
'diameter': {'outer': 0.5, 'inner': 0}
},
{'name': 'jar',
'description': 'jar',
'length': 25,
'diameter': {'outer': 0.5, 'inner': 0}
},
{'name': 'sub',
'description': 'sub',
'length': 15,
'diameter': {'outer': 0.5, 'inner': 0}
},
{'name': 'drill pipe',
'description': 'drill pipe',
'length': 35,
'diameter': {'outer': 0.5, 'inner': 0}
},
{'name': 'sub',
'description': 'sub',
'length': 20,
'diameter': {'outer': 0.5, 'inner': 0}
},
{'name': 'stabilizer',
'description': 'stabilizer',
'length': 35,
'diameter': {'outer': 0.5, 'inner': 0}
},
{'name': 'mwd',
'description': 'mwd',
'length': 25,
'diameter': {'outer': 0.5, 'inner': 0}
},
{'name': 'sub',
'description': 'sub',
'length': 10,
'diameter': {'outer': 0.5, 'inner': 0}
},
{'name': 'sub',
'description': 'sub',
'length': 10,
'diameter': {'outer': 0.5, 'inner': 0}
}]";
new Thread() {
@Override
public void run() {
String args[] = {"--inputData=" + input};
JavaFxApplication.main(args);
Platform.runLater(new Runnable() {
@Override
public void run() {
getBase64Data();
}
});
}
}.start();
private static void getBase64Data() {
System.out.println("Done");
try {
File exisitingFile = new File(Paths.get("Output").toAbsolutePath() + "/Base64.txt");
System.out.println("is File Exists=" + exisitingFile.exists());
if(exisitingFile.exists()) {
InputStream is = new FileInputStream(new File(Paths.get("Output").toAbsolutePath() + "/Base64.txt"));
BufferedReader buf = new BufferedReader(new InputStreamReader(is));
String line = buf.readLine();
StringBuilder sb = new StringBuilder();
while(line != null) {
sb.append(line).append("\n");
line = buf.readLine();
}
String fileAsString = sb.toString();
buf.close();
System.out.println("Valid Base64: " + fileAsString);
FileUtils.forceDelete(exisitingFile);
}
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally {
System.exit(0);
}
}
}
JavaFxApplication.java
public class JavaFxApplication extends Application {
private JavaBridge javaBridge = new JavaBridge();
@Override
public void start(Stage primaryStage) throws Exception {
try {
String path = Paths.get("Input/BHAEditor").toAbsolutePath() + File.separator + "OriginalCanvas.html";
Parameters parameters = getParameters();
Map<String, String> named = parameters.getNamed();
String inputData = named.get("inputData");
System.out.println("inputData=" + inputData);
WebView webView = new WebView();
WebEngine webEngine = webView.getEngine();
webEngine.setJavaScriptEnabled(true);
webView.setContextMenuEnabled(true);
webView.getEngine().setOnError(event -> System.out.println(event.getMessage()));
webView.getEngine().setOnAlert(event -> System.out.println(event.getData()));
webView.getEngine().locationProperty()
.addListener((observable, oldValue, newValue) -> System.out.println(newValue));
Scene scene = new Scene(webView, 600, 600);
primaryStage.setScene(scene);
primaryStage.setTitle("Hello World");
// primaryStage.show();
File f = new File(path);
webEngine.getLoadWorker().stateProperty().addListener(new ChangeListener<State>() {
@Override
public void changed(@SuppressWarnings("rawtypes") ObservableValue ov, State oldState, State newState) {
if (newState == Worker.State.SUCCEEDED) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
String javaScript = "BHAEditorDemo(" + inputData + ")";
webEngine.executeScript(javaScript);
JSObject jsobj = (JSObject) webEngine.executeScript("window");
jsobj.setMember("bridge", javaBridge);
}
}
});
webEngine.load(f.toURI().toString());
webEngine.setOnError((event) -> {
System.out.println(event.getMessage());
});
}
catch (Exception ex) {
System.err.print("error " + ex.getMessage());
ex.printStackTrace();
}
WebConsoleListener.setDefaultListener((webView, message, lineNumber, sourceId) -> {
System.out.println(message + "[at " + lineNumber + "]");
});
}
public static void main(String[] args) {
launch(args);
}
public class JavaBridge {
public void generateBase64(String base64) throws IOException {
OutputStream os = null;
try {
File exisitingFile = new File(Paths.get("Output").toAbsolutePath() + "/Base64.txt");
if(exisitingFile.exists()) {
FileUtils.forceDelete(exisitingFile);
}
os = new FileOutputStream(new File(Paths.get("Output").toAbsolutePath() + "/Base64.txt"));
os.write(base64.getBytes(), 0, base64.length());
}
catch (IOException e) {
e.printStackTrace();
}
finally {
try {
os.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
Solution
Finally I was able to get the result. I kept the alert statement after the canvas image Base64 text generated in HTML. I used webEngine.setOnAlert method to check if the alert was executed and then printed the HTML content. I got the correct response. Below is the code
HTML
alert("ready");
JavaFX application
webEngine.setOnAlert(new EventHandler<WebEvent<String>>(){
@Override
public void handle(WebEvent<String> event) {
//labelWebTitle.setText(webEngine.getTitle());
if("ready".equals(event.getData())){
//TODO: initialize
System.out.println("HTML Ready");
WebEngine engine = (WebEngine)event.getSource();
String html = (String) engine.executeScript("document.documentElement.outerHTML");
org.jsoup.nodes.Document doc = Jsoup.parse(html);
Element image = doc.getElementById("canvasImage");
System.out.println(image.attr("src"));
}
}
});
Answered By - Nithin