简体   繁体   中英

How can I run custom-script-code from the level of Java application?

I have an application in which I want to provide users with the possibility to write simple scripts, so they can drive application in more individual manner. Those scripts will be based on the Java custom library and will be written in eg JavaFX TextArea control item.

Now, say, some user has written something like this: 在此处输入图片说明

When he or she clicks the "Run Script" button, the script will be executed according to the custom library's content. But the question is: How can I run this kind of "pseudo Java code" in Java application, and force the application to behave according to the user's script?

PS: there can be also other possibilities for the form of this "script-language". There is no necessity for it to be "java-library-based" language.

There is the javax.script for this. We can implement the ScriptEngine interface and use its eval function or use the already implemented js engine, for example:

ScriptEngineManager seManager = new ScriptEngineManager();
ScriptEngine engine = seManager.getEngineByName("js");
button.setOnMousePressed(new EventHandler() {
    @Override
    public void handle(MouseEvent mouseEvent) {     
        try {
            engine.eval(textArea.getText());
        } catch (ScriptException e) {
            e.printStackTrace();
        }
    }
});

Have a look at the FX Playground project, a JavaFX-based prototyping tool or live editor from Carl Dea:

This project allows a JavaFX or Html5 developer to run code on the fly without needing to compile a Java project.

You can execute HTML5 code, access JavaFX graphics APIs, load third party libraries, and supports languages as JavaScript (Nashorn, Webkit), Groovy, GroovyFX, Jython, JRuby, Scala, Clojure, Coffe4Java.

Complementing Alexander.Berg's answer, you can achieve this using Javascript thanks to the Nashorn engine. Here's a quick example:

MyFXMLController.java:

public class MyFXMLController implements Initializable {

    @FXML
    private Label labelName;

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        labelName.setText("Fernando Paz");
        playAnimationScript();
    }

    private void playAnimationScript() {
        try {
            ScriptEngine engine = new ScriptEngineManager().getEngineByName("javascript");
            File scriptFile = new File("src/application/label-animation.js");
            engine.put("labelName", labelName);
            engine.eval(new FileReader(scriptFile));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

label-animation.js:

load("fx:base.js");
load("fx:controls.js");
load("fx:graphics.js");

playAnimation();

function playAnimation() {
    labelName.opacity = 0.0;
    animation = new Timeline();
    animation.getKeyFrames().addAll(new KeyFrame(new Duration(600), new KeyValue(labelName.opacityProperty(), 1.0)));
    animation.autoReverse = true;
    animation.cycleCount = Animation.INDEFINITE;
    animation.play();
}

Further information about running scripts in JavaFX can be found here:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM