JavaFX와 ScriptEngine을 결합한 학습용 애플리케이션 만들기

이 기사는 JavaFX Advent Calendar 2015의 5 일째 기사입니다.

어제의 4일째는 skrb씨의 「Wheel or Touch」입니다. 내일 6일째는 bitter_fox입니다.

인사



만나서 반갑습니다, 토스트 소승이라고합니다. 이번을 계기로 Qiita를 시작했습니다. 잘 부탁드립니다.

자기소개



Java로 GUI 애플리케이션을 만드는 것이 취미입니다. 인터넷계 기업에서 프로그래머를 하고 있습니다. 회사는 Storm Trident를 사용하는 백엔드 시스템, API 및 Android 앱을 만들고 있습니다.

개요



이 기사에서는 JavaFX 와 ScriptEngine 를 조합해, 프로그래밍 언어의 학습에 사용할 수 있는 툴을 만드는 과정을 소개합니다.

ScriptEngine



Java에서 스크립팅 언어를 이동하는 메커니즘으로 기본적으로 JavaScript가 지원됩니다. 그 외, Groovy나 Jython, JRuby, Scala등도 구현되고 있는 것 같습니다.

이번에는 Groovy와 Jython을 구현해 보겠습니다.

종속성 추가



build.gradle의 dependencies에 다음을 추가합니다.

dependencies
compile 'org.codehaus.groovy:groovy-all:2.4.5'
compile 'org.python:jython-standalone:2.7.0'

ScriptEngine 얻기



각 언어의 ScriptEngine 객체는 아래와 같이 취득합니다.
final ScriptEngine python = new PyScriptEngineFactory().getScriptEngine();
final ScriptEngine groovy = new GroovyScriptEngineFactory().getScriptEngine();

덧붙여서 JavaScript는 표준으로 준비되어 있어, 아래와 같이 취득할 수 있습니다.
final ScriptEngine js = new ScriptEngineManager().getEngineByName("javascript");

표준 입출력 리디렉션



일반적으로 ScriptEngine을 사용하여 실행한 코드의 로그 오류 출력은 표준 I/O가 됩니다. JavaFX 애플리케이션에서 이것을 보려면 리디렉션해야합니다.

이번에는 StringWriter를 사용하여 StringBuilder에 처리 결과를 넣습니다.
final StringBuilder result = new StringBuilder();
final StringWriter writer = new StringWriter();

try {
    if (python != null) {
        final ScriptContext context = python.getContext();
        context.setWriter(new PrintWriter(writer));
        context.setErrorWriter(new PrintWriter(writer));
    }
    if (groovy != null) {
        final ScriptContext context = groovy.getContext();
        context.setWriter(new PrintWriter(writer));
        context.setErrorWriter(new PrintWriter(writer));
    }

    final java.lang.Object run = js.eval(script);
    result.append(writer.toString()).append(System.lineSeparator());
    if (run != null) {
        result.append("return = ").append(run.toString());
    }
    writer.close();
}

……

JavaFX 성분



왼쪽의 TextArea에 스크립트 코드를 입력하고 오른쪽의 TextArea에서 실행 결과를 표시합니다. 그뿐입니다. 이제(별로 JavaFX가 아니고) 좋잖아…
final String result = func.runScript(scripterInput.getText(), lang).get();
if (StringUtils.isEmpty(result)) {
    return;
}
scripterOutput.setText(result);

시도하다




시작하면 이런 느낌입니다.


왼쪽의 TextArea에 적당히 스크립트를 넣어 보자.


run 버튼을 누르거나 ctrl+enter로 스크립트가 실행되고 그 결과가 오른쪽의 TextArea에 표시됩니다.
죄송합니다.



CSS를 전환하는 기능을 추가해 보았습니다.


자세한 내용은 소스 코드을 참조하십시오.

이런 느낌 에서 준비한 CSS를 아래와 같이 적용하면 OK입니다.
final ObservableList<String> stylesheets = thisStage.getScene().getStylesheets();
// 前回適用した内容をクリア.
if (stylesheets != null) {
    stylesheets.clear();
}
Application.setUserAgentStylesheet("MODENA");
stylesheets.add("path/to/css");

GitHub 리포지토리



javafx_advent2015

좋은 웹페이지 즐겨찾기