Java Platform Standard Edition

Nashornユーザー・ガイド

リリース9

E90927-01(原本部品番号:E76295-02)

2017年9月

Javaアプリケーション開発でのNashornエンジンの使用方法について説明します。

Java Platform, Standard Edition Nashornユーザー・ガイド, リリース9

E90927-01

Copyright © 2014, 2017, Oracle and/or its affiliates.  All rights reserved.

このソフトウェアおよび関連ドキュメントの使用と開示は、ライセンス契約の制約条件に従うものとし、知的財産に関する法律により保護されています。ライセンス契約で明示的に許諾されている場合もしくは法律によって認められている場合を除き、形式、手段に関係なく、いかなる部分も使用、複写、複製、翻訳、放送、修正、ライセンス供与、送信、配布、発表、実行、公開または表示することはできません。このソフトウェアのリバース・エンジニアリング、逆アセンブル、逆コンパイルは互換性のために法律によって規定されている場合を除き、禁止されています。

ここに記載された情報は予告なしに変更される場合があります。また、誤りが無いことの保証はいたしかねます。誤りを見つけた場合は、オラクル社までご連絡ください。

このソフトウェアまたは関連ドキュメントを、米国政府機関もしくは米国政府機関に代わってこのソフトウェアまたは関連ドキュメントをライセンスされた者に提供する場合は、次の通知が適用されます。

U.S. GOVERNMENT END USERS: Oracle programs, including any operating system, integrated software, any programs installed on the hardware, and/or documentation, delivered to U.S. Government end users are "commercial computer software" pursuant to the applicable Federal Acquisition Regulation and agency-specific supplemental regulations. As such, use, duplication, disclosure, modification, and adaptation of the programs, including any operating system, integrated software, any programs installed on the hardware, and/or documentation, shall be subject to license terms and license restrictions applicable to the programs. No other rights are granted to the U.S. Government.

このソフトウェアもしくはハードウェアは様々な情報管理アプリケーションでの一般的な使用のために開発されたものです。このソフトウェアもしくはハードウェアは、危険が伴うアプリケーション(人的傷害を発生させる可能性があるアプリケーションを含む)への用途を目的として開発されていません。このソフトウェアもしくはハードウェアを危険が伴うアプリケーションで使用する際、安全に使用するために、適切な安全装置、バックアップ、冗長性(redundancy)、その他の対策を講じることは使用者の責任となります。このソフトウェアもしくはハードウェアを危険が伴うアプリケーションで使用したことに起因して損害が発生しても、オラクル社およびその関連会社は一切の責任を負いかねます。

OracleおよびJavaはOracle Corporationおよびその関連企業の登録商標です。その他の名称は、それぞれの所有者の商標または登録商標です。

Intel、Intel Xeonは、Intel Corporationの商標または登録商標です。すべてのSPARCの商標はライセンスをもとに使用し、SPARC International, Inc.の商標または登録商標です。AMD、Opteron、AMDロゴ、AMD Opteronロゴは、Advanced Micro Devices, Inc.の商標または登録商標です。UNIXは、The Open Groupの登録商標です。

このソフトウェアまたはハードウェア、そしてドキュメントは、第三者のコンテンツ、製品、サービスへのアクセス、あるいはそれらに関する情報を提供することがあります。適用されるお客様とOracle Corporationとの間の契約に別段の定めがある場合を除いて、Oracle Corporationおよびその関連会社は、第三者のコンテンツ、製品、サービスに関して一切の責任を負わず、いかなる保証もいたしません。適用されるお客様とOracle Corporationとの間の契約に定めがある場合を除いて、Oracle Corporationおよびその関連会社は、第三者のコンテンツ、製品、サービスへのアクセスまたは使用によって損失、費用、あるいは損害が発生しても一切の責任を負いかねます。

目次

タイトルおよび著作権情報

はじめに

- 対象読者

- ドキュメントのアクセシビリティについて

- 関連ドキュメント

- 表記規則

1 Nashornエンジンの概要

- JavaコードからのNashornの呼出し

- コマンド行からのNashornの呼出し

- NashornパーサーAPI

2 Nashorn Java API

- Javaクラスへのアクセス

- Javaオブジェクトの作成

- クラスおよびインスタンスのメンバーへのアクセス

- JavaBeansの使用

- Java配列の操作

- Java文字列の操作

- Java数値の操作

- Javaリストおよびマップの使用

- Javaクラスの拡張

- 指定したJavaクラスへのスクリプト・アクセスの制限

- クラス・フィルタの使用

- JavaリフレクションAPIへのアクセスの制限

- ClassFilterインタフェースの使用例

3 NashornとJavaFX

- NashornでのJavaFXスクリプト・アプリケーションの解釈

- Nashornを使用したJavaFXスクリプト・アプリケーションの簡略化

- JavaFXアプリケーション(HelloWorld.java)の例

- JavaFXスクリプト・アプリケーション(HelloWorld.js)の例

- JavaFXスクリプト・アプリケーションの簡易バージョン(HelloWorldSimple.js)の例

- Nashornスクリプトのオブジェクト

- スクリプトをロードするJavaFXスクリプト・アプリケーションの例

4 Nashornとシェル・スクリプト

- Shebang

- 文字列補間

- ヒア・ドキュメント

- グローバル・オブジェクト

- その他のNashorn組込み関数

JavaFXスクリプト・アプリケーションの例

- JavaFX 3-Dの例

- JavaFXアニメーションの例

はじめに

このドキュメントでは、Java Platform, Standard Edition (Java SE)によって提供されるスクリプト機能を利用するJavaアプリケーション開発でのNashornエンジンの使用方法について説明します。

対象読者

このドキュメントは、Java SEによって提供されるスクリプト機能のためにNashornエンジンを使用する必要があるJavaプログラマを対象としています。JavaおよびECMAScript言語標準の1つのバージョン(JavaScript)に習熟していることを前提としています。

ドキュメントのアクセシビリティについて

Oracleのアクセシビリティについての詳細情報は、Oracle Accessibility ProgramのWebサイト(http://www.oracle.com/pls/topic/lookup?ctx=acc&id=docacc)を参照してください。

Oracleサポートへのアクセス

サポートを購入したオラクル社のお客様は、My Oracle Supportを介して電子的なサポートにアクセスできます。詳細情報はhttp://www.oracle.com/pls/topic/lookup?ctx=acc&id=infoか、聴覚に障害のあるお客様はhttp://www.oracle.com/pls/topic/lookup?ctx=acc&id=trsを参照してください。

関連ドキュメント

- スクリプト言語とJava 『Java Platform, Standard Edition Java Scriptingプログラマ・ガイド』

- JavaスクリプトAPI (javax.scriptパッケージ)仕様

- jjsおよびjrunscriptツールを使用すると、コマンド行からNashornエンジンを起動できます。

表記規則

このマニュアルでは次の表記規則を使用します。

表記規則

意味

太字

太字は、操作に関連するGraphical User Interface要素、または本文中で定義されている用語および用語集に記載されている用語を示します。

イタリック

イタリックは、ユーザーが特定の値を指定するプレースホルダ変数を示します。

固定幅フォント

固定幅フォントは、段落内のコマンド、URL、サンプル内のコード、画面に表示されるテキスト、または入力するテキストを示します。

1 Nashornエンジンの概要

この項では、Nashornエンジンの概要、およびこれを使用してJavaアプリケーション内またはコマンド行のJavaScriptコードを解釈する方法について説明します。

Nashornエンジンは、ECMAScript言語仕様第5.1版の実装です。これは、ECMAScript 6で導入された多数の新機能も実装します。これには、let、constなどのテンプレート文字列、ブロック・スコープ、イテレータおよびfor..ofループ、Map、Set、WeakMapおよびWeakSetデータ型、シンボル、2進数表現と8進数表現があります。

Nashornプロジェクトの一環として、完全にJava言語で開発されました。このコードは、Da Vinci Machineの新機能に基づいています。Da Vinci Machineは、「Java Specification Request (JSR) 292: Javaプラットフォームにおける動的型付け言語のサポート」のリファレンス実装です。

Nashornエンジンは、Java SE Development Kit (JDK)に含まれています。JavaスクリプトAPIを使用してJavaアプリケーションからNashornを呼び出し、埋め込まれたスクリプトを解釈できます。また、スクリプトをjjsまたはjrunscriptツールに渡すこともできます。

注意:

Nashornは、JDKに含まれる唯一のJavaScriptエンジンです。ただし、「JSR 223: Javaプラットフォームのためのスクリプト」に準拠するスクリプト・エンジンを使用することも、独自のエンジンを実装することもできます。『Java Platform, Standard Edition Java Scriptingプログラマ・ガイド』のスクリプト言語およびJavaに関する項を参照してください。

トピック

- JavaコードからのNashornの呼出し

- コマンド行からのNashornの呼出し

- NashornパーサーAPI

JavaコードからのNashornの呼出し

Javaアプリケーション内でNashornを呼び出すには、JavaスクリプトAPIを使用してNashornエンジンのインスタンスを作成します。

Nashornエンジンのインスタンスを取得するには:

1. javax.scriptパッケージをインポートします。
JavaスクリプトAPIは、このパッケージ内のクラスとインタフェースで構成されます。

2. ScriptEngineManagerオブジェクトを作成します。
ScriptEngineManagerクラスは、JavaスクリプトAPIの出発点です。ScriptEngineManagerオブジェクトを使用して、ScriptEngineオブジェクトをインスタンス化し、各オブジェクトが共有するグローバル変数を管理します。

3. getEngineByName()メソッドを使用して、マネージャからScriptEngineオブジェクトを取得します。
このメソッドは、スクリプト・エンジンの名前のString引数を1つ取ります。Nashornエンジンのインスタンスを取得するには、"nashorn"を渡します。または、次のいずれかを使用することもできます: "Nashorn"、"javascript"、"JavaScript"、"js"、"JS"、"ecmascript"、"ECMAScript"。

Nashornエンジンのインスタンスを取得したら、それを使用して文とスクリプト・ファイルの評価や変数の設定などを行います。次の例のEvalScript.javaは、Nashornを使用してprint("Hello, World!");文を評価する簡単なJavaアプリケーション・コードを示しています。

import javax.script.*;

public class EvalScript {
public static void main(String[] args) throws Exception {
// create a script engine manager
ScriptEngineManager factory = new ScriptEngineManager();
// create a Nashorn script engine
ScriptEngine engine = factory.getEngineByName("nashorn");
// evaluate JavaScript statement
try {
engine.eval("print('Hello, World!');");
} catch (final ScriptException se) { se.printStackTrace(); }
}
}

注意:

eval()メソッドは、適切な処理を必要とするScriptExceptionをスローします。

Javaコードでのスクリプトの使用方法は、『Java Platform, Standard Edition Java Scriptingプログラマ・ガイド』のJavaクラスを使用するJavaスクリプトAPIの例に関する項を参照してください。

コマンド行からのNashornの呼出し

Nashornエンジンを呼び出すために使用できるコマンド行ツールは、2つあります。

- jrunscript
これは、JSR 223に準拠する利用可能なスクリプト・エンジンを呼び出す汎用コマンドです。オプションを指定しないデフォルトでは、jrunscriptはJDKのデフォルトのスクリプト・エンジンであるNashornエンジンを呼び出します。

- jjs
これは、Nashorn専用に作成された推奨ツールです。Nashornを使ってスクリプト・ファイルを評価するには、jjsツールにスクリプト・ファイルの名前を渡します。標準入力を使用して渡された文を解釈する対話型シェルを起動するには、スクリプト・ファイルを指定せずにjjsツールを起動します。

NashornパーサーAPI

NashornパーサーAPIを使用すると、特にIDEやサーバー側のフレームなどのアプリケーションでECMAScriptコードを解析および分析できます。

文字列、URLまたはパーサー・クラスのメソッドを使用するファイルからECMAScriptコードを解析します。これらのメソッドは、ECMAScriptコードを抽象構文ツリーとして表現する、CompilationUnitTreeのインスタンスを返します。パッケージjdk.nashorn.api.treeには、NashornパーサーAPIが含まれています。

2 Nashorn Java API

この項では、Nashornエンジンで解釈されるスクリプトからJavaにアクセスする方法について説明します。

この項には、Nashornエンジンの対話型言語シェル・モードで解釈されるスクリプト文の例が含まれています。この対話型シェルは、スクリプトを指定せずにjjsコマンドを実行すると起動されます。これは何かを試す場合に便利ですが、Nashorn Java APIの主な目的は、JavaアプリケーションをNashornエンジンで解釈できるスクリプトとして作成することです。

トピック

- Javaクラスへのアクセス

- Javaオブジェクトの作成

- クラスおよびインスタンスのメンバーへのアクセス

- JavaBeansの使用

- Java配列の操作

- Java文字列の操作

- Java数値の操作

- Javaリストおよびマップの使用

- Javaクラスの拡張

- 指定したJavaクラスへのスクリプト・アクセスの制限

Javaクラスへのアクセス

Nashornを使用してパッケージおよびクラスにアクセスするには、2つの方法があります。従来の方法ではPackagesグローバル・オブジェクトを使用しますが、推奨される方法ではJavaグローバル・オブジェクトを使用します。この項では、両方の方法について説明します。

事前に定義された最上位のPackagesオブジェクトでは、完全修飾名をPackagesオブジェクトのプロパティと同じように使用して、Javaパッケージおよびクラスにアクセスできます。次の例は、MyPackage.jarがクラス・パスに含まれている場合に、MyPackageパッケージとそのMyClassクラスにアクセスする方法を示しています。

jjs> Packages.MyPackage
[JavaPackage MyPackage]
jjs> Packages.MyPackage.MyClass
[JavaClass MyPackage.MyClass]

Javaパッケージおよびクラスへのアクセスは、カスタム・パッケージおよびクラスへのアクセスより簡単です。参考までに、標準Javaパッケージ(com、edu、java、javafx、javaxおよびorg)には、それぞれグローバル・オブジェクトが定義されています。これらは、Packagesオブジェクトのプロパティに対応する別名を持っています。次の例は、java.langパッケージとjava.lang.Systemクラスにアクセスする方法を示しています。

jjs> java.lang
[JavaPackage java.lang]
jjs> typeof java.lang
object
jjs> java.lang.System
[JavaClass java.lang.System]
jjs> typeof java.lang.System
function

前の例からわかるように、NashornはJavaパッケージをJavaPackageオブジェクトとして解釈し、Javaクラスを(そのクラスのコンストラクタとして使用できる) JavaClass関数オブジェクトとして解釈します。「Javaオブジェクトの作成」でクラスをインスタンス化する方法について説明します。

従来の方法によるJavaパッケージおよびクラスへのアクセスは、直感的で簡単ですが、同時に次の理由で不十分かつ限定的であり、エラーになりやすい傾向があります。

- 各プロパティのアクセスにコストがかかるため、深い階層のパッケージやクラスへのアクセスが遅くなる可能性があります。

- Java配列を作成するための特別な構文がありません。回避策として、java.lang.reflect.Arrayクラスを使用する必要があります。

- クラス名のスペルを間違えると、Nashornはパッケージ名が指定されたと見なし、それをJavaClass関数オブジェクトではなくJavaPackageオブジェクトとして解釈します。それをクラスとして使用しようとしたときにエラーがスローされるまで、このことに気付かない可能性があります。これを回避するには、typeof演算子を使用して、アクセスしようとしている構造が関数オブジェクトとして解釈される条件をテストします。次の例は、この条件チェックの動作を示しています。

jjs> typeof java.lang.System == "function"
true
jjs> typeof java.lang.Zyztem == "function"
false

前述の方法の短所を回避するため、NashornにはJavaクラスを操作する関数を持つJavaグローバル・オブジェクトが定義されています。Java.type()関数は、Javaクラスの完全修飾名を含む文字列を取り、対応するJavaClass関数オブジェクトを返します。次の例は、java.lang.Systemクラスにアクセスする方法を示しています。

jjs> Java.type("java.lang.System")
[JavaClass java.lang.System]

Javaにクラスをインポートする場合と同じように、スクリプトの先頭でJavaClass型の変数を宣言することをお薦めします。次の例は、System変数を宣言し、それにjava.lang.Systemクラスの値を代入する方法を示しています。

jjs> var System = Java.type("java.lang.System")
jjs> System
[JavaClass java.lang.System]

Javaオブジェクトの作成

クラスをインスタンス化するには、JavaClass関数オブジェクトをnew演算子に渡します。Nashornは、関数に渡された引数に基づいて、対応するコンストラクタを呼び出します。

次の例は、デフォルトの初期容量を使用した場合と初期容量を100に設定した場合の、java.util.HashMapクラスをインスタンス化する方法を示しています。

jjs> var HashMap = Java.type("java.util.HashMap")
jjs> var mapDef = new HashMap()
jjs> var map100 = new HashMap(100)

クラスおよびインスタンス・メンバーへのアクセス

次のように、標準ドット表記を使用してstaticフィールド、メソッドおよび内部クラスにアクセスできます。

jjs> Java.type("java.lang.Math").PI
3.141592653589793
jjs> Java.type("java.lang.System").currentTimeMillis()
1375813353330
jjs> Java.type("java.util.Map").Entry
[JavaClass java.util.Map$Entry]

内部クラスには、ドル記号($)または(Javaと一貫性がある)ドットを区切り文字とする内部表現を使用してアクセスすることもできます。

jjs> Java.type("java.util.Map$Entry")
[JavaClass java.util.Map$Entry]
jjs> Java.type("java.util.Map.Entry")
[JavaClass java.util.Map$Entry]

オブジェクトのインスタンス・メソッドを呼び出したり、インスタンス・フィールドにアクセスしたりするには、Javaの場合と同じようにドット演算子を使用します。次の例は、StringオブジェクトのtoUpperCase()メソッドを呼び出す方法を示しています。

jjs> var String = Java.type("java.lang.String")
jjs> var str = new String("Hello")
jjs> str
Hello
jjs> var upper = str.toUpperCase()
jjs> upper
HELLO

Nashornは、角カッコを使ったメンバー・アクセスもサポートします。その場合は、メンバーの名前を角カッコ([])で囲まれた文字列として指定し、その直後にクラス(staticメンバーの場合)またはオブジェクト(インスタンス・メンバーの場合)を指定します。この方法は、ECMAScriptでドット表記の代替として定義されており、Java開発者にとって直感的ではありません。しかし、これを使用してメソッドのオーバーロードのあいまいさを解決できます。デフォルトでは、Nashornは引数にもっとも一致するオーバーロード・メソッドを使用しますが、これが期待する動作であるとはかぎりません。たとえば、次の例に示すように、double値を出力する場合は、java.lang.System.out.println(double)メソッド・オーバーロードを使用する必要があります。

jjs> Java.type("java.lang.System").out.println(10)
10
jjs> Java.type("java.lang.System").out["println(double)"](10)
10.0

JavaBeansの使用

Nashornでは、JavaBeansのアクセサおよびミューテータ・メソッドを同等のJavaScriptプロパティとして扱うことができます。プロパティの名前は、JavaBeanメソッドの名前から接尾辞のgetまたはsetを除き、先頭を小文字にしたものです。

たとえば、java.util.DateオブジェクトのgetYear()およびsetYear()メソッドを呼び出すには、次のようにyearプロパティを使用します。

jjs> var Date = Java.type("java.util.Date")
jjs> var date = new Date()
jjs> date.year + 1900
2013
jjs> date.year = 2014 - 1900
114
jjs> date.year + 1900
2014

Java配列の操作

Java配列クラスにアクセスするには、配列とそれに続く角カッコのペアからなる(Java構文と同様の)オブジェクトの型をJava.type()関数に渡します。

次の例は、整数のJava配列とStringオブジェクトのJava配列にアクセスする方法を示しています。

jjs> Java.type("int[]")
[JavaClass [I]
jjs> Java.type("java.lang.String[]")
[JavaClass [Ljava.lang.String;]

配列型オブジェクトを作成した後は、それを使用して他のクラスと同じように配列をインスタンス化できます。次の例に示すように、インデックスを使って配列のエントリにアクセスしたり、ドット表記または(Java構文と同じように)角カッコ表記を使ってメンバーにアクセスしたりできます。

jjs> var IntArrayType = Java.type("int[]")
jjs> var arr = new IntArrayType(10)
jjs> arr[1] = 123
123
jjs> arr[2] = 321
321
jjs> arr[1] + arr[2]
444
jjs> arr[10]
java.lang.ArrayIndexOutOfBoundsException: Array index out of range: 10
jjs> arr.length
10

既存のJavaScript配列がある場合は、Java.to()関数を使用してそれをJava配列に変換できます。次の例は、文字列"a"、"b"および"c"のJavaScript配列を、同じ値を持つjava.lang.String[]配列に変換する方法を示しています。

jjs> var jsArr = ["a","b","c"]
jjs> var strArrType = Java.type("java.lang.String[]")
jjs> var javaArr = Java.to(jsArr, strArrType)
jjs> javaArr.class
class [Ljava.lang.String;
jjs> javaArr[0]
a

次のように、forおよびfor each文を使用して、Java配列のインデックスと値を反復処理できます。

jjs> for (var i in javaArr) print(i)
0
1
2
jjs> for each (var i in javaArr) print(i)
a
b
c

Java文字列の操作

Nashornは文字列をjava.lang.Stringオブジェクトとして表現します。2つの文字列を連結すると、Stringインスタンスを取得します。

jjs> var a = "abc"
jjs> a.class
class java.lang.String
jjs> var b = a + "def"
jjs> b.class
class java.lang.String
jjs> var c = String(b)
jjs> c.class
class java.lang.String

Java数値の操作

Nashornは、数値を、実行される計算に応じてjava.lang.Double、java.lang.Longまたはjava.lang.Integerオブジェクトとして解釈します。次の例に示すように、Number()関数を使用して数値を強制的にDoubleオブジェクトにすることができます。

jjs> var intNum = 10
jjs> intNum.class
class java.lang.Integer
jjs> var dblNum = Number(intNum)
jjs> dblNum.class
class java.lang.Double

Javaリストおよびマップの使用

NashornはJavaリストを配列として解釈し、for each文でリストの値を反復処理します。マップでキーおよび値を反復処理するには、keySet()およびvalues()メソッドを使用します。

次の例に示すように、角カッコ([])内のインデックスを使用してリストの要素にアクセスしたり、for each文を使用してリストの値を反復処理したりできます。

jjs> var ArrayList = Java.type("java.util.ArrayList")
jjs> var alist = new ArrayList()
jjs> alist.add("a")
true
jjs> alist.add("b")
true
jjs> alist.add("c")
true
jjs> alist[1]
b
jjs> for each (var i in alist) print(i)
a
b
c

注意:
角カッコ内のインデックスを使用してリストおよびマップ要素にアクセスできますが、この構文を使用してキューおよび設定要素にはアクセスできません。

次の例は、HashMapオブジェクトを作成し、keySet()およびvalues()メソッドを使用してそのキーと値を反復処理する方法を示しています。

jjs> var HashMap = Java.type("java.util.HashMap")
jjs> var hm = new HashMap()
jjs> hm.put("name", "Bob")
jjs> hm.put("age", 40)
jjs> hm.put("weight", 180)
jjs> for each (var i in hm.keySet()) print(i)
weight
age
name
jjs> for each (var i in hm.values()) print(i)
180
40
Bob

または、次の例に示すように、リストの値の反復処理と同様に、マップの値を反復処理することもできます。

jjs> for each (var i in hm) print(i)
180
40
Bob

Javaクラスの拡張

クラスを拡張するには、Java.extend()関数を使用します。この関数は、最初の引数としてJava型を取り、他の引数として(JavaScript関数形式の)メソッド実装を取ります。

次のスクリプトは、java.lang.Runnableインタフェースを拡張し、それを使用して新しいjava.lang.Threadオブジェクトを構築しています。

var Run = Java.type("java.lang.Runnable");
var MyRun = Java.extend(Run, {
run: function() {
print("Run in separate thread");
}
});
var Thread = Java.type("java.lang.Thread");
var th = new Thread(new MyRun());

メソッドを実装するための関数をコンストラクタの引数として指定すると、Nashornは自動的に機能インタフェース(注釈タイプFunctionalInterfaceに関する項を参照)を拡張できます。次のスクリプトは、java.lang.Runnableインタフェースを拡張し、それを使用して新しいjava.lang.Threadオブジェクトを構築するスクリプトを示していますが、Java.extend()関数が機能インタフェースに対して自動的に呼び出されているため、例2-1より使用するコードの行数が少なくなっています。

var Thread = Java.type("java.lang.Thread")
var th = new Thread(function() print("Run in a separate thread"))

『Java Platform, Standard Edition Java Scriptingプログラマ・ガイド』のJavaクラスの拡張に関する項では、Java.extend()関数の機能について説明しています。

例2-1 Javaクラスの拡張

var Run = Java.type("java.lang.Runnable");
var MyRun = Java.extend(Run, {
run: function() {
print("Run in separate thread");
}
});
var Thread = Java.type("java.lang.Thread");
var th = new Thread(new MyRun());

例2-2 機能インタフェースの拡張

var Thread = Java.type("java.lang.Thread")
var th = new Thread(function() print("Run in a separate thread"))

指定したJavaクラスへのスクリプト・アクセスの制限

jdk.nashorn.api.scripting.ClassFilterインタフェースにより、Nashornスクリプト・エンジンで実行されるスクリプトから指定したJavaクラスへのアクセスを制限することで、JavaScriptコードからJavaクラスへのアクセスに対してきめの細かい制御を提供できます。

Nashornの、とりわけサーバー側JavaScriptフレームワークを埋め込んでいるアプリケーションは、信頼できないソースからスクリプトを実行しなければならないことがよくあり、そのためアクセスをJava APIに制限する必要があります。これらのアプリケーションは、ClassFilterインタフェースを実装して、Javaクラス・アクセスをJavaクラスのサブセットに制限できます。それには、クライアント・アプリケーションでNashorn APIを使用して、Nashornスクリプト・エンジンをインスタンス化する必要があります。

注意:
ClassFilterインタフェースでJavaクラスへのアクセスを防止できますが、信頼できないスクリプトをセキュアに実行するには不十分です。ClassFilterインタフェースはセキュリティ・マネージャのかわりにはなりません。信頼できないソースのスクリプトを評価する前に、セキュリティ・マネージャを使用してアプリケーションを実行する必要があります。クラス・フィルタは、セキュリティ・マネージャよりもきめの細かい制御を提供します。たとえば、Nashornを埋め込んだアプリケーションは、セキュリティ・マネージャが許可する可能性のあるスクリプト、またはリソースが集中する他の操作からスレッドが起動するのを防ぐことができます。

クラス・フィルタの使用

クラス・フィルタを使用するには、ClassFilterインタフェースを実装して、メソッドboolean exposeToScripts(String)を定義します。

String引数は、Nashornスクリプト・エンジンがスクリプトの実行時に遭遇するJavaクラスまたはパッケージの名前です。メソッドexposeToScriptsを、スクリプトがアクセスしないようにするクラスとパッケージでfalseを戻すように定義します。続いて、メソッドNashornScriptEngineFactory.getScriptEngine(ClassFilter)またはNashornScriptEngineFactory.getScriptEngine(String[]、ClassLoader、ClassFilter)を使用したクラス・フィルタを持つNashronスクリプト・エンジンを作成します。

JavaリフレクションAPIへのアクセスの制限

セキュリティ・マネージャを使用している場合、Nashornでは、スクリプトは、nashorn.javaReflection実行時権限を持っているときのみJavaリフレクションAPI(たとえば、java.lang.reflectとjava.lang.invokeパッケージ)を使用することができます。

クラス・フィルタを使用している場合、セキュリティ・マネージャがない場合でも、NashornではJavaリフレクションAPIにアクセスできません。JavaリフレクションAPIが利用できる場合、スクリプトがClass.forName(String)を使用してクラス・フィルタを回避できるため、クラス・フィルタを使用する必要はない点に注意してください。

ClassFilterインタフェースの使用例

次の例のMyClassFilterTest.javaに、ClassFilterインタフェースを示します。スクリプトがクラスjava.io.Fileにアクセスするのを制限しています。

import javax.script.ScriptEngine;
import jdk.nashorn.api.scripting.ClassFilter;
import jdk.nashorn.api.scripting.NashornScriptEngineFactory;

public class MyClassFilterTest {

class MyCF implements ClassFilter {
@Override
public boolean exposeToScripts(String s) {
if (s.compareTo("java.io.File") == 0) return false;
return true;
}
}

public void testClassFilter() {

final String script =
"print(java.lang.System.getProperty(\"java.home\"));" +
"print(\"Create file variable\");" +
"var File = Java.type(\"java.io.File\");";

NashornScriptEngineFactory factory = new NashornScriptEngineFactory();

ScriptEngine engine = factory.getScriptEngine(
new MyClassFilterTest.MyCF());
try {
engine.eval(script);
} catch (Exception e) {
System.out.println("Exception caught: " + e.toString());
}
}

public static void main(String[] args) {
MyClassFilterTest myApp = new MyClassFilterTest();
myApp.testClassFilter();
}
}

この例の出力は次のとおりです。

C:\Java\jre8
Create file variable
Exception caught: java.lang.RuntimeException: java.lang.ClassNotFoundException:
java.io.File

MyClassFilterTest.javaの例では、次の操作を実行しています。

1. メソッドexposeToScriptsを定義することにより、内部クラスMyCFを持つClassFilterを実装します。この例で、メソッドexposeToScriptsは、String引数がjava.io.Fileの場合にfalseを戻し、それ以外の場合はtrueを戻します。

2. メソッドNashornScriptEngineFactory.getScriptEngine(ClassFilter)を使用して、Nashornスクリプト・エンジンengineを作成します。この例は、MyCFのインスタンスを持つgetScriptEgnineを起動します。

3. Nashornスクリプト・エンジンengineを使用して、次のスクリプトを実行します。

print(java.lang.System.getProperty(\"java.home\"));
print(\"Create file variable\");
var File = Java.type(\"java.io.File\");

engineのクラス・フィルタは、スクリプト内の各Javaパッケージおよびクラスをチェックします。クラス・フィルタがクラスjava.io.Fileに遭遇すると、クラス・フィルタはfalseを戻し、Java.type関数はClassNotFoundExceptionを送出します。

3 NashornとJavaFX

この項では、Nashornエンジンで解釈されるスクリプトを使用してJavaFXアプリケーションを作成および実行する方法について説明します。JavaFXに習熟していることを前提としています。

トピック

- NashornでのJavaFXスクリプト・アプリケーションの解釈

- Nashornを使用したJavaFXスクリプト・アプリケーションの簡略化

- Nashornスクリプトのオブジェクト

NashornでのJavaFXスクリプト・アプリケーションの解釈

JavaFXスクリプト・アプリケーションをNashornで解釈するには、-fxオプションを指定したjjsコマンドを使用します。たとえば、次のコマンドはNashornを呼び出してJavaFXscript.jsファイルを解釈します。

jjs -fx JavaFXscript.js

JavaFXスクリプト・アプリケーションは、同等のJavaアプリケーションとほぼ同じですが、Nashornを使用してJavaFX構文の多くを簡略化できます。通常、JavaFXスクリプト・アプリケーションにはstart()関数のみが含まれますが、これはJavaアプリケーションのstart()メソッドと同等です。また、init()およびstop()関数を含めることもできます。

Nashornを使用したJavaFXスクリプト・アプリケーションの簡略化

Nashornを使用すると、特定のタイプを宣言することなくJavaFXコードを簡略化でき、特定のメソッドおよびプロパティに容易にアクセスできます。

「JavaFXアプリケーション(HelloWorld.java)の例」および「JavaFXスクリプト・アプリケーション(HelloWorld.js)の例」の例を分析すると、JavaFXアプリケーションをスクリプトとして作成したときに、NashornによってJavaコードがどのように簡略化されるかがわかります。

- 変数型の宣言、パッケージのインポート、注釈の使用、クラス名の指定、およびクラスのmain()メソッドの実装が不要になります。

- 宣言する必要があるのは、インスタンス化されるJavaFXクラスのみです。

- JavaBeansは、getおよびset接頭辞が不要になり、JavaメソッドではなくJavaScriptプロパティとして扱われます。「JavaBeansの使用」を参照してください。

- javafx.event.EventHandlerインタフェースを実装するときに、実装されるメソッドを明示的に指定する必要はありません。handle()が唯一のメソッドであるため、Nashornは指定された関数をメソッドに自動的に適用します。「Javaクラスの拡張」を参照してください。

JavaFXのプライマリ・ステージは、Nashornではグローバル・プロパティ$STAGEとして使用できます。このグローバル・プロパティを使用すると、スクリプト全体を1つのstart()関数として扱うことができます(その場合でも、init()およびstop()関数を追加できます)。「JavaFXスクリプト・アプリケーションの簡易バージョン(HelloWorldSimple.js)の例」には、「JavaFXスクリプト・アプリケーション(HelloWorld.js)の例」のJavaFXスクリプト・アプリケーションを簡略化したバージョンのソース・コードが含まれています。

JavaFXアプリケーション(HelloWorld.java)の例

次の例のHelloWorld.javaには、1つのボタンを表示する簡単なJavaFXアプリケーションのソース・コードが含まれています。このボタンをクリックすると、標準出力に"Hello World!"が出力されます。

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class HelloWorld extends Application {
public static void main(String[] args) {
launch(args);
}

@Override
public void start(Stage primaryStage) {
primaryStage.setTitle("Hello World!");
Button btn = new Button();
btn.setText("Say 'Hello World'");
btn.setOnAction(new EventHandler<ActionEvent>() {

@Override
public void handle(ActionEvent event) {
System.out.println("Hello World!");
}
});

StackPane root = new StackPane();
root.getChildren().add(btn);
primaryStage.setScene(new Scene(root, 300, 250));
primaryStage.show();
}
}

JavaFXスクリプト・アプリケーション(HelloWorld.js)の例

次の例のHelloWorld.jsには、1つのボタンを表示するJavaFXスクリプト・アプリケーションのソース・コードが含まれています。このボタンをクリックすると、標準出力に"Hello World!"が出力されます。

var Button = javafx.scene.control.Button;
var StackPane = javafx.scene.layout.StackPane;
var Scene = javafx.scene.Scene;

function start(primaryStage) {
primaryStage.title = "Hello World!";
var button = new Button();
button.text = "Say 'Hello World'";
button.onAction = function() print("Hello World!");
var root = new StackPane();
root.children.add(button);
primaryStage.scene = new Scene(root, 300, 250);
primaryStage.show();
}

JavaFXスクリプト・アプリケーションの簡易バージョン(HelloWorldSimple.js)の例

次の例のHelloWorldSimple.jsには、グローバル・プロパティ$STAGEを使用して、JavaFXスクリプト・アプリケーションを簡略化したバージョンのソース・コードが含まれています。

var Button = javafx.scene.control.Button;
var StackPane = javafx.scene.layout.StackPane;
var Scene = javafx.scene.Scene;

$STAGE.title = "Hello World!";
var button = new Button();
button.text = "Say 'Hello World'";
button.onAction = function() print("Hello World!");
var root = new StackPane();
root.children.add(button);
$STAGE.scene = new Scene(root, 300, 250);
$STAGE.show();

Nashornスクリプトのオブジェクト

ほとんどの場合、staticフィールドにアクセスするためにインスタンス化または使用するクラスを追加するだけで済むはずです。ただし、プロトタイプを作成する場合は、JavaFXのパッケージとクラスのグループをインポートするためにロードできる一連のスクリプトがNashornに事前定義されています。スクリプトは、スクリプト名の文字列を取るload()関数を使用してロードできます。

次の表に、組込み可能な定義済のスクリプト・オブジェクトを示します。

スクリプト

インポートされるもの

fx:base.js

- javafx.stage.Stage

- javafx.scene.Scene

- javafx.scene.Group

- javafx/beans

- javafx/collections

- javafx/events

- javafx/util

fx:graphics.js

- javafx/animation

- javafx/application

- javafx/concurrent

- javafx/css

- javafx/geometry

- javafx/print

- javafx/scene

- javafx/stage

fx:controls.js

- javafx/scene/chart

- javafx/scene/control

fx:fxml.js

javafx/fxml

fx:web.js

javafx/scene/web

fx:media.js

javafx/scene/media

fx:swing.js

javafx/embed/swing

fx:swt.js

javafx/embed/swt

「スクリプトをロードするJavaFXスクリプト・アプリケーションの例」には、「JavaFXスクリプト・アプリケーションの簡易バージョン(HelloWorldSimple.js)の例」のJavaFXスクリプト・アプリケーションを、load()関数を使用して必要なパッケージとクラスをインポートするように簡略化したソース・コードが含まれています。

スクリプトをロードするJavaFXスクリプト・アプリケーションの例

次の例には、load()関数を使用してパッケージおよびクラスをインポートする、JavaFXスクリプト・アプリケーションを簡略化したバージョンのソース・コードが含まれています。

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

$STAGE.title = "Hello World!";
var button = new Button();
button.text = "Say 'Hello World'";
button.onAction = function() print("Hello World!");
var root = new StackPane();
root.children.add(button);
$STAGE.scene = new Scene(root, 300, 250);
$STAGE.show();

JavaFXスクリプト・アプリケーションの例については、「JavaFXスクリプト・アプリケーションの例」を参照してください。

4 Nashornとシェル・スクリプト

この項では、JavaScriptスクリプトでUNIXシェル・スクリプト機能を使用できるようにするNashornエンジンの拡張機能について説明します。

Nashornのシェル・スクリプト拡張機能を有効にするには、-scriptingオプションを指定したjjsコマンドを使用します。たとえば、次のコマンドは対話型モードでシェル・スクリプト拡張機能を有効にした状態でNashornを呼び出します。

jjs -scripting

標準のJavaScriptコメント(//および/* */)に加えて、Nashornは番号記号(#)を使用するシェル形式のコメントもサポートします。スクリプトの最初の文字が番号記号である場合は、-scriptingオプションを指定せずにjjsツールを使用しても、スクリプトを解釈するときにNashornのシェル・スクリプト拡張機能が自動的に有効になります。これは、スクリプトの先頭にshebang (#!)を指定して、スクリプトをシェル実行可能ファイルとして実行する場合に便利です。「Shebang」を参照してください。

トピック

- Shebang

- 文字列補間

- ヒア・ドキュメント

- グローバル・オブジェクト

- その他のNashorn組込み関数

Shebang

スクリプト・ファイルの先頭にshebang (#!)を指定すると、そのスクリプト・ファイルをシェル実行可能ファイルとして実行できます。shebangにjjsツールのパスを指定すると、スクリプトを実行したときに、シェルがスクリプトではなくjjsツールを実行し、ツールにスクリプト・ファイルを渡します。

jjsツールは、JAVA_HOME/binディレクトリ(JAVA_HOMEはJDK (またはJRE)のインストール・ディレクトリ)にあります。JDKをインストールすると、通常はJAVA_HOME環境変数が自動的に設定されます。自動的に設定されなかった場合や、複数のバージョンのJDKがインストールされている場合は、手動でJAVA_HOME環境変数をJDKインストール・ディレクトリの正しいパスに設定します。

shebangにjjsツールの直接パスを指定できますが、次のように/usr/binディレクトリにシンボリック・リンクを作成することをお薦めします。

>> cd /usr/bin
>> ln -s $JAVA_HOME/bin/jjs jjs
>>

注意:

場合によっては、sudoを使用してルート特権でlnコマンドを実行する必要があります。

シンボリック・リンクを設定したら、実行可能ファイルとして実行できるNashornスクリプトを作成できます。また、shebang文にコマンド行オプションを直接追加することもできます。次の例のscriptArgs.jsは、Nashornエンジンのバージョンとスクリプトに渡された引数を出力する実行可能スクリプトを示しています。

#!/usr/bin/jjs -fv
print("Arguments: " + arguments);

scriptArgs.jsファイルをシェル実行可能ファイルとして実行すると、このファイルはNashornによって次のように解釈されます。

>> ./scriptArgs.js -- arg1 arg2 arg3
nashorn full version 1.8.0
Arguments: arg1,arg2,arg3
>>

または、jjsツールのパスがPATH環境変数に含まれている場合は、次のようにしてshebangにjjsを指定できます。

#!/usr/bin/env jjs

文字列補間

文字列補間は、UNIXシェルで変数または式の値を含む文字列を作成するために使用されます。Nashornでシェル・スクリプト機能を有効にすると、同じようにして変数や式を文字列リテラルに埋め込むことができます。

たとえば、次のようにDate()コンストラクタの結果をdate変数に割り当て、ドル記号($)と中カッコ({})を使ってこの変数を文字列に渡すことができます。

jjs> var date = Date()
jjs> "Date and time: ${date}"
Date and time: Mon Aug 19 2013 19:43:08 GMT+0400 (MSK)

前の例は、Date()コンストラクタから返された値がdate変数に割り当てられたときに、日付と時間を表示します。式が評価された時点の日付と時間を表示する場合は、次のようにDate()コンストラクタを直接渡すことができます。

jjs> "Current date and time: ${Date()}"
Current date and time: Mon Aug 19 2013 19:49:53 GMT+0400 (MSK)

文字列補間は、二重引用符で囲まれた文字列でのみ機能します。一重引用符に囲まれた文字列は補間されません。

jjs> 'The variable is ${date}'
The variable is ${date}

ヒア・ドキュメント

ヒア・ドキュメント(heredoc)は、改行とインデントを保持した文字列をUNIXシェルに指定します。Nashornでシェル・スクリプト機能を有効にすると、heredocを含むスクリプトを評価できます。

次の例のscriptHereArgs.jsは、最初に渡された引数を1行目に出力し、2番目の引数をインデントして2行目に出力し、3番目の引数を(空白行の後で)4行目に出力する実行可能スクリプトを示しています。

#!/usr/bin/jjs
print(<<EOD);
${arguments[0]} is normal
${arguments[1]} is indented

${arguments[2]} is separated by a blank line
EOD

scriptHereArgs.jsファイルをシェル実行可能ファイルとして実行すると、Nashornエンジンによって次のように解釈されます。

>> ./scriptHereArgs.js -- Line1 Line2 Line3
Line1 is normal
Line2 is indented

Line3 is separated by a blank line

グローバル・オブジェクト

Nashornでシェル・スクリプト機能を有効にすると、いくつかのグローバル・オブジェクトが定義されます。

$ARG

このグローバル・オブジェクトを使用すると、argumentsオブジェクトを使用する場合と同じようにして、スクリプトに渡された引数にアクセスできます。例:

>> jjs -scripting -- arg1 arg2 arg3
jjs> $ARG
arg1,arg2,arg3
jjs> $ARG[1]
arg2

$ENV

このグローバル・オブジェクトは、現在のすべての環境変数をマップします。例:

jjs> $ENV.USER
johndoe
jjs> $ENV.PWD
/foo/bar

$EXEC()

このグローバル・オブジェクトは、コマンドを実行するためのプロセスを起動します。例:

jjs> $EXEC("ls -l")
total 0
drwxr-xr-x+ 1 johndoe staff 4096 Aug 18 11:03 dir
-rwxrw-r--  1 johndoe staff  168 Aug 19 17:44 file.txt

jjs>

$EXEC()関数は、2つ目の引数を取ることもできます。この引数は、プロセスの標準入力(stdin)として使用される文字列です。

jjs> $EXEC("cat", "Send this to stdout")
Send this to stdout
jjs>

注意:

コマンドに入力が不要な場合は、バッククォートによる文字列表記を使ってプロセスを起動できます。たとえば、$EXEC("ls -l")のかわりに`ls -l`を使用できます。

$OPTIONS

このオブジェクトは、nashornの「コマンド・ライン」に渡されるコマンド行オプションを公開します。次に例を示します。

jjs> print("-scripting=" + $OPTIONS_scripting);
jjs> print("--compile-only=" + $OPTIONS_compile_only);
jjs> print("-timezone="+ $OPTIONS_timezone.ID);

$OUT

このグローバル・オブジェクトは、プロセスの最新の標準出力(stdout)を格納するために使用されます。たとえば、$EXEC()の結果は$OUTに保存されます。

$ERR

このグローバル・オブジェクトは、プロセスの最新の標準エラー(stderr)を格納するために使用されます。

$EXIT

このグローバル・オブジェクトは、プロセスの終了コードを格納するために使用されます。終了コードがゼロでない場合、そのプロセスは失敗しています。

その他のNashorn組込み関数

Nashornは、いくつかの組込み関数を定義しています。echo、readLineおよびreadFully関数は、-scriptingモードにのみ定義されます。quit、exit、load、loadWithNewGlobal、Object.bindPropertiesなどの他の拡張機能は、常に利用できます。

quit()

exit()

これらの関数は同義であり、現在のスクリプト・プロセスを終了してシステムに戻ります。システムに返す終了コードを表す整数値を引数として渡すことができます。デフォルトでは、引数を指定しなかった場合の終了コードは、プロセスが正常に終了したことを意味する0に設定されます。

print()

echo()

これらの関数は同義であり、引数として渡された値を文字列に変換し、空白で区切ってstdoutに出力し、続いて改行を出力します。この実装は、java.lang.System.out.print(string)を呼び出した後でjava.lang.System.out.println()を呼び出します。

>> jjs -scripting -- arg1
jjs> var a = "Hello"
jjs> print(123, $ARG[0], a, "World")
123 arg1 Hello World
jjs>

readLine()

この関数は、stdinの入力を1行だけ読み取り、それをstdoutに送ります。または、結果を変数に割り当てることができます。次の例のように、文字列をreadLine()関数に渡してプロンプト行を作成することもできます。

jjs> var name = readLine("What is your name? ")
What is your name? Bob
jjs> print("Hello, ${name}!")
Hello, Bob!
jjs>

readFully()

この関数は、文字列引数として渡されたファイルの内容全体を読み取り、それをstdoutに送ります。または、結果を変数に割り当てることができます。

jjs> readFully("text.txt")
This is the contents of the text.txt file located in the current working directory.

jjs>

readFully()関数は、メソッドbyte[] Files.readAllBytes(Path)を使用してデータを読み取り、返されたバイト配列でバイト・オーダー・マーク(BOM)検出を実行して、読み取ったデータがUnicodeでエンコードされているかどうかを判定します。

load()

この関数は、パス、URLまたはスクリプト・オブジェクトからスクリプトをロードして評価します。

jjs> load("/foo/bar/script.js")
jjs> load("http://example.com/script.js")
jjs> load({name:"script.js", script:"var x = 1 + 1; x;"})

loadWithNewGlobal()

この関数はload()関数とほぼ同じですが、新しいグローバル・オブジェクトを使用してスクリプトが評価されます。これは、スクリプト評価用の新しいコンテキストを作成するための主な手段です。loadWithNewGlobal()に(スクリプトの後で)渡された追加の引数は、新しいコンテキストのargumentsグローバル変数に格納されます。

Object.bindProperties(target, source)

この関数を使用して、sourceオブジェクトのプロパティをオブジェクトtargetにバインドします。この関数を使用することで、グローバル・プロパティの共有が可能になります。たとえば、Document Object Model (DOM)のシミュレーションでは、グローバル・オブジェクトとドキュメントの間でプロパティを共有できます。マルチスレッド・アプリケーションでは、スレッドのグローバル・オブジェクト間で関数を共有できます。

次の例は、objオブジェクトのプロパティをグローバル・オブジェクトにバインドする方法を示しています。

jjs> var obj = {x:34,y:100}
jjs> obj.x
34
jjs> obj.y
100
jjs> x
<shell>:1 ReferenceError: "x" is not defined
jjs> Object.bindProperties(this,obj)
[object global]
jjs> x
34
jjs> y = Math.PI
3.141592653589793
jjs> obj.y
3.141592653589793
jjs>

関数Object.bindProperties(target, source)は、targetに存在しないsourceのプロパティのみをバインドすることに注意してください。次の例に、関数bindPropertiesはobjオブジェクトのプロパティをグローバル・オブジェクトにバインドしようとしています。ただし、xプロパティはすでにグローバル・オブジェクトに存在しています。したがって、関数bindPropertiesは、obj.xをグローバルのxにバインドしません。そのため、obj.xの値を変更しても、グローバルのxの値は変更されません

jjs> x = 2
2
jjs> var obj = {x:3}
jjs> Object.bindProperties(this,obj)
[object global]
jjs> x
2
jjs> x = 4
4
jjs> obj.x
3
jjs> x
4

JavaFXスクリプト・アプリケーションの例

この項では、JavaFXスクリプト・アプリケーションの例を示します。

「NashornとJavaFX」では、Nashornエンジンで解釈されるスクリプトとしてJavaFXアプリケーションを作成する方法について説明します。

トピック

- JavaFX 3-Dの例

- JavaFXアニメーションの例

JavaFX 3-Dの例

この例は、Nashornスクリプト・エンジンの機能を使用して、比較的少ないコードで複雑なタスク(この場合は、JavaFXによる3Dグラフィックスのレンダリング)を実行する方法を示しています。この例を実行すると、ウィンドウに緑色の3つの図形(立方体、球および円柱)が表示されます。

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

var material = new PhongMaterial();
material.diffuseColor = Color.LIGHTGREEN;
material.specularColor = Color.rgb(30, 30, 30);

var meshView = Java.to([
new Box(200, 200, 200),
new Sphere(100),
new Cylinder(100, 200)
], "javafx.scene.shape.Shape3D[]");

for (var i = 0; i != 3; i++) {
meshView[i].material = material;
meshView[i].translateX = (i + 1) * 220;
meshView[i].translateY = 200;
meshView[i].translateZ = 20;
meshView[i].drawMode = DrawMode.FILL;
meshView[i].cullFace = CullFace.BACK;
};

var pointLight = new PointLight(Color.WHITE);
pointLight.translateX = 800;
pointLight.translateY = -200;
pointLight.translateZ = -1000;

var root = new Group(meshView);
root.children.add(pointLight);

var scene = new Scene(root, 800, 400, true);
scene.fill = Color.rgb(127, 127, 127);
scene.camera = new PerspectiveCamera(false);
$STAGE.scene = scene;
$STAGE.show();

JavaFXアニメーションの例

この例は、Nashornスクリプト・エンジンの機能を使用してJavaFXアニメーションを作成する方法を示しています。この例を実行すると、ウィンドウに様々な色の円が動き回る様子が表示されます。

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

var WIDTH = 500;
var HEIGHT = 600;
var animation;

function setup(primaryStage) {
var root = new Group();
primaryStage.resizable = false;
var scene = new Scene(root, WIDTH, HEIGHT);
scene.title = "Colourful Circles";
primaryStage.scene = scene;

// create first list of circles
var layer1 = new Group();
for(var i = 0; i < 15; i++) {
var circle = new Circle(200, Color.web("white", 0.05));
circle.strokeType = StrokeType.OUTSIDE;
circle.stroke = Color.web("white", 0.2);
circle.strokeWidth = 4;
layer1.children.add(circle);
}

// create second list of circles
var layer2 = new Group();
for(var i = 0; i < 20; i++) {
var circle = new Circle(70, Color.web("white", 0.05));
circle.strokeType = StrokeType.OUTSIDE;
circle.stroke = Color.web("white", 0.1);
circle.strokeWidth = 2;
layer2.children.add(circle);
}

// create third list of circles
var layer3 = new Group();
for(var i = 0; i < 10; i++) {
var circle = new Circle(150, Color.web("white", 0.05));
circle.strokeType = StrokeType.OUTSIDE;
circle.stroke = Color.web("white", 0.16);
circle.strokeWidth = 4;
layer3.children.add(circle);
}

// set a blur effect on each layer
layer1.effect = new BoxBlur(30, 30, 3);
layer2.effect = new BoxBlur(2, 2, 2);
layer3.effect = new BoxBlur(10, 10, 3);

// create a rectangle size of window with colored gradient
var colors = new Rectangle(WIDTH, HEIGHT,
new LinearGradient(0, 1, 1, 0, true, CycleMethod.NO_CYCLE,
new Stop(0,   Color.web("#f8bd55")),
new Stop(0.14, Color.web("#c0fe56")),
new Stop(0.28, Color.web("#5dfbc1")),
new Stop(0.43, Color.web("#64c2f8")),
new Stop(0.57, Color.web("#be4af7")),
new Stop(0.71, Color.web("#ed5fc2")),
new Stop(0.85, Color.web("#ef504c")),
new Stop(1,   Color.web("#f2660f"))));
colors.blendMode = BlendMode.OVERLAY;

// create main content
var group = new Group(new Rectangle(WIDTH, HEIGHT, Color.BLACK),
layer1,
layer2,
layer3,
colors);
var clip = new Rectangle(WIDTH, HEIGHT);
clip.smooth = false;
group.clip = clip;
root.children.add(group);

// create list of all circles
var allCircles = new java.util.ArrayList();
allCircles.addAll(layer1.children);
allCircles.addAll(layer2.children);
allCircles.addAll(layer3.children);

// Create a animation to randomly move every circle in allCircles
animation = new Timeline();
for each (var circle in allCircles) {
animation.getKeyFrames().addAll(
new KeyFrame(Duration.ZERO, // set start position at 0s
new KeyValue(circle.translateXProperty(),
Math.random() * WIDTH),
new KeyValue(circle.translateYProperty(),
Math.random() * HEIGHT)),
new KeyFrame(new Duration(20000), // set end position at 20s
new KeyValue(circle.translateXProperty(),
Math.random() * WIDTH),
new KeyValue(circle.translateYProperty(),
Math.random() * HEIGHT))
);
}
animation.autoReverse = true;
animation.cycleCount = Animation.INDEFINITE;
}

function stop() {
animation.stop();
}

function play() {
animation.play();
}

function start(primaryStage) {
setup(primaryStage);
primaryStage.show();
play();
}

Oracleの法律上の注意点

コピーライト

Copyright © 1994-2017, Oracle and/or its affiliates. All rights reserved.

ライセンス制約の保証と結果的に生じる損害の免責

このソフトウェアおよび関連ドキュメントの使用と開示は、ライセンス契約の制約条件に従うものとし、知的財産に関する法律により保護されています。ライセンス契約で明示的に許諾されている場合もしくは法律によって認められている場合を除き、形式、手段に関係なく、いかなる部分も使用、複写、複製、翻訳、放送、修正、ライセンス供与、送信、配布、発表、実行、公開または表示することはできません。このソフトウェアのリバース・エンジニアリング、逆アセンブル、逆コンパイルは互換性のために法律によって規定されている場合を除き、禁止されています。

保証免責

ここに記載された情報は予告なしに変更される場合があります。また、誤りが無いことの保証はいたしかねます。誤りを見つけた場合は、オラクルまでご連絡ください。

制限付権利について

このソフトウェアまたは関連ドキュメントを、米国政府機関もしくは米国政府機関に代わってこのソフトウェアまたは関連ドキュメントをライセンスされた者に提供する場合は、次の通知が適用されます。

U.S. GOVERNMENT END USERS: Oracle programs, including any operating system, integrated software, any programs installed on the hardware, and/or documentation, delivered to U.S. Government end users are "commercial computer software" pursuant to the applicable Federal Acquisition Regulation and agency-specific supplemental regulations. As such, use, duplication, disclosure, modification, and adaptation of the programs, including any operating system, integrated software, any programs installed on the hardware, and/or documentation, shall be subject to license terms and license restrictions applicable to the programs. No other rights are granted to the U.S. Government.

危険な用途への使用について

このソフトウェアまたはハードウェアは様々な情報管理アプリケーションでの一般的な使用のために開発されたものです。このソフトウェアまたはハードウェアは、危険が伴うアプリケーション(人的傷害を発生させる可能性があるアプリケーションを含む)への用途を目的として開発されていません。このソフトウェアまたはハードウェアを危険が伴うアプリケーションで使用する際、安全に使用するために、適切な安全装置、バックアップ、冗長性(redundancy)、その他の対策を講じることは使用者の責任となります。このソフトウェアまたはハードウェアを危険が伴うアプリケーションで使用したことに起因して損害が発生しても、Oracle Corporationおよびその関連会社は一切の責任を負いかねます。

商標と登録商標について

OracleおよびJavaはオラクルおよびその関連会社の登録商標です。その他の社名、商品名等は各社の商標または登録商標である場合があります。

Intel、Intel Xeonは、Intel Corporationの商標または登録商標です。すべてのSPARCの商標はライセンスをもとに使用し、SPARC International, Inc.の商標または登録商標です。AMD、Opteron、AMDロゴ、AMD Opteronロゴは、Advanced Micro Devices, Inc.の商標または登録商標です。UNIXは、The Open Groupの登録商標です。

第三者のコンテンツ、製品、サービスに対する免責事項

このソフトウェアまたはハードウェア、そしてドキュメントは、第三者のコンテンツ、製品、サービスへのアクセス、あるいはそれらに関する情報を提供することがあります。適用されるお客様とOracle Corporationとの間の契約に別段の定めがある場合を除いて、Oracle Corporationおよびその関連会社は、第三者のコンテンツ、製品、サービスに関して一切の責任を負わず、いかなる保証もいたしません。適用されるお客様とOracle Corporationとの間の契約に定めがある場合を除いて、Oracle Corporationおよびその関連会社は、第三者のコンテンツ、製品、サービスへのアクセスまたは使用によって損失、費用、あるいは損害が発生しても一切の責任を負いかねます。

Pre-General Availability (一般提供前)版のドキュメントについて

このドキュメントがPre-General Availability (一般提供前)版の場合:

このドキュメントはPre-General Availability (一般提供前)版であり、デモおよび暫定使用のみを目的としたものです。このソフトウェアを使用するハードウェアに限定するものではありません。Oracle Corporationおよびその関連会社は、このドキュメントに関して一切の責任を負わず、いかなる保証もいたしません。また、このドキュメントを使用したことによって損失、費用、あるいは損害が発生しても、一切の責任を負いかねます。

非公開のPre-General Availability (一般提供前)版のドキュメントについて

このドキュメントが非公開のPre-General Availability (一般提供前)版の場合:

このドキュメントに含まれる情報は、情報の共有のみを目的としたものであって、顧客諮問委員会(Customer Advisory Board)のメンバーとしてのお客様の立場でのみ、またはお客様のPre-General Availability Trial Agreement (Pre-GAトライアル契約)のみに従って検討されるべきものとします。マテリアル、コード、または機能の提供をお約束するものではなく、購入決定を行う際の判断材料とすべきではありません。このドキュメントに記載されている特徴または機能の開発、リリースおよび時期については、オラクルの裁量により決定されます。

このドキュメントには、ソフトウェアまたは印刷物などの形式を問わず、オラクルが独占的な権利を有する財産的情報が含まれています。この機密資料へのアクセスと使用は、お客様とオラクルとの間で締結され、お客様が遵守に同意した、Oracle Master Agreement、Oracle License and Oracle Services Agreement (オラクル・ライセンスおよびサービスに関する契約書)、Oracle Partner Network Agreement、Oracle Distribution Agreementまたはその他のライセンス契約の条件に従うものとします。このドキュメントとその内容の開示、コピー、複製および配布には、オラクルによる事前の承諾を必要とします。このドキュメントはライセンス契約の一部となるものではなく、オラクルおよびその子会社や関連会社との契約を構成するものではありません。

ドキュメントのアクセシビリティ

オラクルのアクセシビリティについての詳細情報は、Oracle Accessibility ProgramのWebサイト(http://www.oracle.com/pls/topic/lookup?ctx=acc&id=docacc)を参照してください。

Oracle Supportへのアクセス

サポートをご契約のお客様には、My Oracle Supportを通して電子支援サービスを提供しています。詳細情報は(http://www.oracle.com/pls/topic/lookup?ctx=acc&id=info)か、聴覚に障害のあるお客様は(http://www.oracle.com/pls/topic/lookup?ctx=acc&id=trs)を参照してください。