Skip to content

Instantly share code, notes, and snippets.

@sundararajana
Created April 2, 2015 10:39
Show Gist options
  • Save sundararajana/7b19ec08a8878426af5e to your computer and use it in GitHub Desktop.
Save sundararajana/7b19ec08a8878426af5e to your computer and use it in GitHub Desktop.
jslogofx.js - Extending a webapp using #javafx and #nashorn
#!/usr/bin/jjs -fx
/**
* This #nashorn script demonstrates using JavaFX WebView
* and DOM interaction to extend the functionality of a
* pre-written webapp without changing that application code.
* jslogo implements Logo programming language with DOM and JS.
* In this example, we extend "jslogo" webapp to add a feature
* to load logo script file from local file system.
*
* Steps to use this script:
*
* 1. git clone https://github.com/inexorabletash/jslogo
* 2. copy this script under the same directory where you cloned jslogo
* 3. jjs -fx jslogo.fx
*
* You'll see a lightsalmon color "Load Logo File.." button. On clicking
* you can choose a logo script to run. The chosen script file is read
* and the content is set into the text area of "jslogo". You can then
* click "Run" button of "jslogo".
*/
if (!$OPTIONS._fx) {
print("Usage: jjs -fx jslogofx.js");
exit(1);
}
// FXML for UI description of our extension app
var fxml = <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import javafx.scene.web.*?>
<?import javafx.scene.layout.*?>
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<center>
<WebView id="webview" prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER" />
</center>
<bottom>
<!-- button to open a file chooser to select a file to load -->
<Button disable="true" style="-fx-font-weight: bold; -fx-background-color: lightsalmon" id="load" text="Load Logo File.." />
</bottom>
</BorderPane>
EOF
// Java and FX classes used
var ByteArrayInputStream = Java.type("java.io.ByteArrayInputStream");
var ChangeListener = Java.type("javafx.beans.value.ChangeListener");
var File = Java.type("java.io.File");
var FileChooser = Java.type("javafx.stage.FileChooser");
var FXMLLoader = Java.type("javafx.fxml.FXMLLoader");
var Scene = Java.type("javafx.scene.Scene");
function start(stage) {
var loader = new FXMLLoader();
// load FXML from a string
var root = loader.load(new ByteArrayInputStream(fxml.getBytes("UTF-8")));
// DOM Document object
var document;
// get the button and the WebView
var load = root.lookup("#load");
var wv = root.lookup("#webview");
// on click handler for "load" button
load.onAction = function() {
// make sure, we have DOM Document element
if (!document) {
return;
}
var fileChooser = new FileChooser();
fileChooser.title = "Open logo file";
fileChooser.extensionFilters.addAll(
new FileChooser.ExtensionFilter("Logo Files", "*.lg"),
new FileChooser.ExtensionFilter("All Files", "*.*"));
var selectedFile = fileChooser.showOpenDialog(stage);
if (selectedFile != null) {
var code = readFully(selectedFile);
// set file content into the text area of JS Logo index.htm
var textArea = document.getElementById("logo-ta-single-line");
if (textArea) {
textArea.value = code;
}
textArea = document.getElementById("logo-ta-multi-line");
if (textArea) {
textArea.value = code;
}
}
}
// load jslogo's 'main' index.htm file.
wv.engine.load(new File(__DIR__ + "index.htm").toURL());
// on load of the document, save DOM document object
// and also enable our "load" button
wv.engine.loadWorker.stateProperty().addListener(
new ChangeListener() {
changed: function() {
// DOM document element
document = wv.engine.document;
load.disable = false;
}
});
var scene = new Scene(root, 800, 600);
stage.title = "JS Logo FX";
stage.scene = scene;
stage.show();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment