Call external javascript functions from java
--------------- RunScript.java -----------------
import java.io.*;
import java.nio.file.*;
import java.util.concurrent.*;
import javax.script.*;
import javafx.application.*;
import javafx.stage.*;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.geometry.*;
import javafx.scene.text.*;
public class RunScript extends Application {
ScriptEngine engine;
long iniTime;
CompiledScript compiledScript;
boolean compiled = false;
Future<?> future = null;
ExecutorService executorService;
@Override
public void start(Stage stage) {
String engineName = "JavaScript";
File file = new File("script.txt");
TextArea scriptArea = new TextArea();
TextArea resultArea = new TextArea();
resultArea.setEditable(false);
Font font = Font.font("Monospaced");
scriptArea.setFont(font);
resultArea.setFont(font);
BorderPane layout = new BorderPane();
Scene scene = new Scene(layout, 900, 600);
stage.setScene(scene);
if (file.exists()) {
try {
scriptArea.appendText(new String(Files.readAllBytes(file.toPath())));
} catch (Exception e) {}
}
else scriptArea.setText(demoJavaScript());
scriptArea.home();
ScriptEngineManager manager = new ScriptEngineManager();
engine = manager.getEngineByName(engineName);
if (engine == null) throw new RuntimeException("No script engine found for " + engineName);
ScriptContext context = engine.getContext();
Writer writer = new Writer() {
@Override
public void write(char cbuf[], int off, int len) {
String s = new String(cbuf, off, len);
Platform.runLater(() -> { resultArea.appendText(s); });
}
@Override
public void flush() {}
@Override
public void close() {}
};
context.setErrorWriter(writer);
context.setWriter(writer);
SplitPane splitPane = new SplitPane(scriptArea, resultArea);
layout.setCenter(splitPane);
BorderPane bottomPane = new BorderPane();
BorderPane.setMargin(bottomPane, new Insets(2));
Button button = new Button();
bottomPane.setLeft(button);
button.setMinWidth(60);
String stRun = "Run", stStop = "Stop";
button.setText(stRun);
button.setOnAction((event) -> {
button.setText(stStop);
if (future != null && !future.isDone()) {
future.cancel(true);
button.setDisable(true);
} else {
resultArea.clear();
String script = new String(scriptArea.getText());
executorService = Executors.newSingleThreadExecutor((runnable) -> {
Thread thread = new Thread(runnable);
thread.setDaemon(true);
return thread;
});
future = executorService.submit(() -> {
try {
iniTime = System.currentTimeMillis();
if (engine instanceof Compilable) {
if (!compiled) {
compiledScript = ((Compilable)engine).compile(script);
compiled = true;
Platform.runLater(() -> { resultArea.appendText("Compile time: " + (System.currentTimeMillis() - iniTime) + " ms\n"); });
iniTime = System.currentTimeMillis();
}
compiledScript.eval();
} else {
engine.eval(script);
}
Platform.runLater(() -> { resultArea.appendText("Run time: " + (System.currentTimeMillis() - iniTime) + " ms\n"); });
} catch (Exception e) {
Platform.runLater(() -> { resultArea.appendText(e.getMessage() + "\n"); });
}
Platform.runLater(() -> {
button.setText(stRun);
button.setDisable(false);
resultArea.setScrollTop(Double.MAX_VALUE);
});
});
executorService.shutdown();
}
});
layout.setBottom(bottomPane);
scriptArea.textProperty().addListener((observable, oldValue, newValue) -> {
compiled = false;
});
stage.setOnCloseRequest(event -> {
try {
Files.write(file.toPath(), scriptArea.getText().getBytes());
} catch (Exception e) {}
});
stage.show();
}
String demoJavaScript() {
StringBuilder sb = new StringBuilder();
sb.append("for (var angle = 0; angle <= Math.PI * 2; angle += .2) {\n");
sb.append(" var y = 15 * Math.sin(angle);\n");
sb.append(" if (y > 0) print(repeat(' ', 15) + repeat('*', y));\n");
sb.append(" else print(repeat(' ', 15 + y) + repeat('*', -y));\n");
sb.append(" //java.lang.Thread.sleep(100);\n");
sb.append(" sleep(100);\n");
sb.append("}\n\n");
sb.append("function repeat(s, n) {\n");
sb.append(" return new Array(Math.max(0, Math.floor(n)) + 1).join(s);\n");
sb.append("}\n\n");
sb.append("function sleep(milliseconds) {\n");
sb.append(" var ending = new Date().getTime() + milliseconds;\n");
sb.append(" while (new Date().getTime() < ending )\n");
sb.append(" if (java.lang.Thread.currentThread().isInterrupted())\n");
sb.append(" throw new java.lang.InterruptedException();\n");
sb.append("}\n\n");
return sb.toString();
}
}