Call external javascript functions from java

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();
  }
}

Download ZIP

Back