如何从Java应用程序级别运行自定义脚本代码?

时间:2014-10-25 12:58:45

标签: java javafx

我有一个应用程序,我希望为用户提供编写简单脚本的可能性,这样他们就可以以更加个性化的方式驱动应用程序。这些脚本将基于Java自定义库,并将以例如Java编写。 JavaFX TextArea控件项。

现在,比如说,有些用户写了这样的东西: enter image description here

当他或她单击“运行脚本”按钮时,将根据自定义库的内容执行脚本。但问题是:如何在Java应用程序中运行这种“伪Java代码”,并强制应用程序根据用户的脚本运行?

PS:这种“脚本语言”的形式还有其他可能性。它没有必要成为“基于java库”的语言。

3 个答案:

答案 0 :(得分:0)

这有javax.script。 我们可以实现ScriptEngine接口并使用其eval函数或使用已经实现的js引擎,例如:

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

答案 1 :(得分:0)

查看FX Playground项目,基于JavaFX的原型设计工具或Carl Dea的实时编辑器:

  

该项目允许JavaFX或Html5开发人员即时运行代码,而无需编译Java项目。

您可以执行HTML5代码,访问JavaFX图形API,加载第三方库,并支持JavaScript(Nashorn,Webkit),Groovy,GroovyFX,Jython,JRuby,Scala,Clojure,Coffe4Java等语言。

答案 2 :(得分:0)

补充Alexander.Berg的答案,你可以使用Javascript来实现这一点,这要归功于Nashorn引擎。这是一个简单的例子:

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

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

有关在JavaFX中运行脚本的更多信息,请访问: