nl.han.ica.app.models.CodeEditor.java Source code

Java tutorial

Introduction

Here is the source code for nl.han.ica.app.models.CodeEditor.java

Source

/**
 * Copyright 2013 
 * 
 * HAN University of Applied Sciences
 * Maik Diepenbroek
 * Wouter Konecny
 * Sjoerd van den Top
 * Teun van Vegchel
 * Niek Versteege
 *
 * See the file MIT-license.txt for copying permission.
 */

package nl.han.ica.app.models;

import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.concurrent.Worker;
import javafx.scene.web.WebView;
import org.apache.commons.lang3.StringEscapeUtils;

import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;

/**
 * Wrapper around a WebView containing a JavaScript code editor plugin. Provides easy means of communication between the
 * Java and the JavaScript environments.
 */
public class CodeEditor {

    private WebView webView;
    private List<String> scriptCache;
    private Logger logger;

    /**
     * The code editor constructor.
     *
     * @param webView The WebView where the editor is loaded in.
     */
    public CodeEditor(WebView webView) {
        logger = Logger.getLogger(getClass());
        logger.info("Created CodeEditor");
        scriptCache = new ArrayList<>();
        this.webView = webView;
        initializeWebView();
    }

    /**
     * Sets the value of the Code Editor.
     *
     * @param value The value to set in the Code Editor.
     */
    public void setValue(String value) {
        StringBuilder script = new StringBuilder("editor.setValue('");
        script.append(StringEscapeUtils.escapeEcmaScript(value));
        script.append("')");
        execute(script.toString());
    }

    /**
     * Highlights the given line number in the Code Editor.
     *
     * @param lineNr              The line number to highlight.
     * @param textClassname       The classname.
     * @param backgroundClassName The background classname.
     */
    public void highlightLine(int lineNr, String textClassname, String backgroundClassName) {
        StringBuilder script = new StringBuilder("editor.setLineClass(");
        script.append(lineNr).append(", ");
        if (null != textClassname) {
            script.append("'").append(textClassname).append("'");
        } else {
            script.append("null");
        }
        script.append(", ");
        if (null != backgroundClassName) {
            script.append("'").append(backgroundClassName).append("'");
        } else {
            script.append("null");
        }
        script.append(");");
        execute(script.toString());
    }

    /**
     * Highlights a part of a line or a block, for example one word or a few lines.
     *
     * @param lineBegin   The line to start highlight.
     * @param columnBegin The column to start highlighting.
     * @param lineEnd     The line where the highlighting ends.
     * @param columnEnd   The column where the highlighting stops.
     * @param className   The current class name.
     */
    public void highlightText(int lineBegin, int columnBegin, int lineEnd, int columnEnd, String className) {
        Position start = new Position(lineBegin - 1, columnBegin - 1);
        Position end = new Position(lineEnd - 1, columnEnd);
        StringBuilder script = new StringBuilder("editor.markText(");
        script.append(start.toScript());
        script.append(", ");
        script.append(end.toScript());
        script.append(", ");
        script.append("'").append(className).append("'");
        script.append(")");
        execute(script.toString());
    }

    /**
     * Initialize the webview that contains the browser environment for the CodeEditor.
     */
    protected void initializeWebView() {
        logger.info("Initialising web view");
        webView.getEngine().load(getClass().getResource("/editor/editor.html").toExternalForm());
        webView.getEngine().getLoadWorker().stateProperty().addListener(new ChangeListener<Worker.State>() {
            @Override
            public void changed(ObservableValue ov, Worker.State oldState, Worker.State newState) {
                if (newState == Worker.State.SUCCEEDED && !scriptCache.isEmpty()) {
                    for (String script : scriptCache) {
                        execute(script);
                    }
                    scriptCache.clear();
                }
            }
        });
    }

    /**
     * Execute a JavaScript script in the CodeEditor's browser environment.
     *
     * @param script The script to run
     */
    protected void execute(final String script) {
        logger.info("Executing javascript....");

        if (webView.getEngine().getLoadWorker().getState() == Worker.State.SUCCEEDED) {
            logger.info("Executing...  " + script);
            webView.getEngine().executeScript(script);
            logger.info("Executed script");
        } else {
            logger.info("Adding script to cache");
            scriptCache.add(script);
            logger.info("Added script to cache");
        }
    }

    /**
     * Represents a line and column in the JavaScript Editor.
     */
    public static class Position {
        private int line;
        private int column;

        /**
         * Instantiate a new Position.
         *
         * @param line   The line number
         * @param column The column number
         */
        public Position(int line, int column) {
            this.line = line;
            this.column = column;
        }

        /**
         * Outputs the position in JavaScript formatting that can be used by the CodeEditor.
         *
         * @return JavaScript representation of this position.
         */
        public String toScript() {
            StringBuilder script = new StringBuilder("{ ");
            script.append("line: ").append(line);
            script.append(", ");
            script.append("ch: ").append(column);
            script.append(" }");
            return script.toString();
        }
    }

}