Главная | Описание языка | FXD | API | Примеры | Инструменты Разработки | Новости | Ресурсы | Форум
Документация[]
На Английском
На Русском
Полезные советы[]
Установка языка JavaFX Script[]
Установка JavaFX SDK[]
- Установите JavaFX SDK с сайта www.javafx.com
В текстовом редакторе создайте файл HelloWorld.fx и скопируйте туда код примера:
import javafx.stage.*;
import javafx.scene.*;
import javafx.scene.text.*;
import javafx.scene.paint.*;
import javafx.scene.effect.*;
Stage {
title: "Hello Frame"
width: 250
height: 80
scene: Scene {
content: Text {
x: 10 y: 30
font: Font { size: 24 }
fill: Color.BLUE
effect: DropShadow{ offsetX: 3 offsetY: 3}
content: "Hello World!"
}
}
}
Чтобы скомпилировать и запустить пример, наберите в командной строке:
> javafxc HelloWorld.fx > javafx HelloWorld
На экране монитора у вас должно появится окошко с заголовком "Hello Frame" и надписью "Hello World!"
Инструменты Разработки[]
Для программирования на языке JavaFX Script можно воспользоваться существующими средами разработки:
Краткое введение в язык JavaFX Script[]
Смотри краткое введение в язык JavaFX Script на примере компании Pond Inc
Особенности языка JavaFX Script[]
Декларативный синтаксис[]
В отличие от императивных языков, в которых описывается последовательность исполняемых действий, язык JavaFX Script позволяет описать структуру самой программы.
Создание программы на языке JavaFX Script можно разбить на 2 этапа
- описание необходимых компонент (классов)
- построение программы из готовых компонент
Сама программа строится по принципу:
- пишем имя компонента
- в фигурных скобках задаем атрибуты компонента
MyComponent{
attribute1: value1
attribute2: value2
// ...
attributeN: valueN
}
Атрибуты могут иметь простой тип (число, строка) или сложный.
MyComponent{
attr1: SubComp1{
subAttr1: value1
// ...
}
// ...
attrN: SubComp1{
subAttr1: value1
// ...
}
}
Таким образом программа на JavaFX представляет из себя дерево вложенных друг в друга компонент.
Примеры:
2D графика
UI интерфейс
Структура данных
Язык JavaFX Script позволяет описывать данные аналогично тому, как это делается в XML
XML: contacts.xml | JavaFX: Contacts.fx |
|
|
Описав класс Contact на языке JavaFX Script вы сможете скомпилировать файл Contacts.fx (компилятор проверит все ошибки), загрузить данные из этого файла в вашу программу и использовать их.
Пример:
class Contact{
var firstName: String;
var lastName: String;
var eMailAddress: String;
}
var contacts = loadFXCode("Contacts");
for(contact in contacts){
println("{contact.firstName} {contact.lastName} has {contact.eMailAddress} email address");
}
Результат исполнения программы:
Mike Wazowski has Mike.Wazowski@monster.com email address Sulley Monster has Sulley.Monster@monster.com email address
Система, состоящая из компонент
Связывание данных[]
Поскольку программа на JavaFX состоит из набора компонент, возникает необходимость связывать между собой атрибуты компонент в дереве программы.
Для этого используется оператор bind.
В примере ниже переменная R связывается:
- с атрибутом value комонента Slider
- с атрибутом radius комонента Circle
- с атрибутом content комонента Text
Прямое использование классов языка Java[]
Программы на JavaFX Script и других языках[]
Hello World[]
JavaFX Script
Java
Создание Hello World из готовых компонент:
Расширение класса JFrame:
Обработка событий[]
JavaFX Script
Java
Описание языка JavaFX Script[]
Смотри также документацию:
- на русском языке: Язык программирования JavaFX Script
- на английском языке: The JavaFX™ Script Programming Language
Main файл[]
println("Hello World!");
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.text.Text;
import javafx.scene.text.Font;
Stage {
title: "Hello World!"
scene: Scene {
content: Text {
x: 10, y: 30
font : Font { size: 24 }
content: "Hello World!"
}
}
}
Метод run[]
function run(){
println("Hello world!");
}
Получение параметров[]
Получение параметров в методе run:
function run(args:String[]){
for(arg in args){
println("arg: {arg}");
}
}
или получение переданных параметров по имени:
println("Argument {FX.getArgument( "key" )}");
Передача параметров[]
Командная строка
javafx -cp FXArguments.jar fxarguments.Main key="From Command Line"
Апплет
<script src="http://dl.javafx.com/1.2/dtfx.js"></script>
<script>
javafx(
{
archive: "FXArguments.jar",
draggable: true,
width: 250,
height: 80,
code: "fxarguments.Main",
name: "FXArguments",
},
{
key: "from Applet"
}
);
</script>
JNLP
<jnlp spec="1.0+" codebase="dist" href="FXArguments.jnlp">
<application-desc main-class="com.sun.javafx.runtime.main.Main">
<argument>MainJavaFXScript=fxarguments.Main</argument>
<argument>key=from Java Web Start</argument>
</application-desc>
</jnlp>
Типы данных[]
Базовые типы[]
В языке JavaFX Script существуют следующие примитивные типы:
Логический тип
- Boolean
Символьный тип
- Character
- String
Целые числа
- Byte
- Short
- Integer
- Long
Числа с плавающей точкой
- Float (Number)
- Double
Время
- Duration
JavaFX тип | Описание | Пример |
Boolean | Логический тип | true, false |
Character | Символ | |
String | Строка | "Hello World!" |
Byte | Байт | 10 |
Short | Короткое целое число | 12 |
Integer | Целое число | 12 |
Long | Длиное целое число | 12 |
Float | Вещественное число | 5.0 |
Double | Вещественное число с двойной точностью | 10.0 |
Duration | Время | 12s // 12 секунд |
Поэтому можно использовать все те методы, которые есть у этих типов в языке Java
Примеры использования:
var s = "Hello"; // Создаем переменную типа String println(s.toUpperCase()); // распечатается строка: "HELLO"
var b = true; // Создаем переменную типа Boolean println(b.equals(true)); //распечатается строка: true println(b.equals(false)); //распечатается строка: false
var n = 1.5; // Создаем переменную типа Number println(n.intValue()); // распечатается строка: 1
Функции[]
Объявление функции:
function sqr(x:Number):Number { x * x };
println("sqr(3) = {sqr(3)}"); // output: sqr(3) = 9.0
Функции являются отдельным типом данных.
Например, переменной можно присвоить функцию:
var f = function(x:Number):Number { x * x };
println("f(3) = {f(3)}"); // output: f(3) = 9.0
Класс может иметь атрибут типа функция:
class TaskManager{
var task:function();
}
Функцию можно передавать в качестве аргумента другой функции
import java.lang.Math;
function f(x:Number):Number{ Math.cos(x) }
function integral( f: function(Number):Number, a:Number, b: Number, dx: Number):Number{
var s = 0.0;
for(x in [a..b step dx]){
s += f(x) * dx;
}
s -= 0.5 * f(a) * dx + 0.5 * f(b) * dx;
return s;
}
println( integral(f, -Math .PI / 2, Math.PI / 2, 0.01) );
Последовательности[]
Последовательность (Sequence) в языке JavaFX Script содержит в себе набор элементов одного и того же типа.
В языке JavaFX Script все последовательности одномерные.
Для того, чтобы задать последовательность, нужно перечислить ее элементы через запятую в квадратных скобках:
var nums = [1,2,3,4,5]; var strings = ["one", "two", "three"];
Квадратные скобки служат указанием, что объявляемый аттрибут является последовательностью:
class List{
public var items: String[];
}
var list = List{ items: ["item1", "item2", "item3"] };
Последовательности можно вкладывать друг в друга, получая при этом один общую последовательность:
var week_days = ["Mon","Tue","Wed","Thur","Fri"]; var days = [week_days, ["Sat","Sun"] ];
Результатом будет последовательность: ["Mon","Tue","Wed","Thur","Fri","Sat","Sun"];
Нумерация последовательностей производится от 0.
Получение элемента последовательности по индексу:
var numbers = ["zero","one", "two", "three"]; var n1 = numbers[1]; // n1 = "one" var n2 = numbers[2]; // n2 = "two"
Получение размера последовательности:
var numbers = ["zero","one", "two", "three"]; var size = sizeof numbers; // size = 4
Выборка элементов последовательности:
var nums = [1,2,3,4,5];
println(nums[n|n > 2]); // [ 3, 4, 5 ]
Вставка и удаление элементов последовательности:
var seq = [1.0, 2.0, 3.0];
insert 1.5 after seq[0]; // [1.0, 1.5, 2.0, 3.0]
insert 2.5 before seq[3]; // [1.0, 1.5, 2.0, 2.5, 3.0 ]
delete seq[4];
println(seq); // [ 1.0, 1.5, 2.0, 2.5 ]
Встроенные операции:
println( reverse nums ); // [ 5, 4, 3, 2, 1 ]
Итерация последовательности:
var seq = [1, 2, 3, 4, 5];
for(elem in seq){
println(elem);
}
var sqrSeq = for(n in seq) { n * n };
Сортировка последовательности:
import javafx.util.Sequences;
var sequence = [ 5, 2, 3, 1, 4 ];
var sortedSequence = Sequences.sort(sequence) as Integer[];
println(sortedSequence); // [ 1, 2, 3, 4, 5 ]
Сортировка с помощью Comparator-а:
class Vector{
public var x:Number;
public var y:Number;
public function length () { Math.sqrt( x * x + y * y) }
public override function toString ():String { "[ {x}, {y}]" }
}
var vectors = [ Vector{ x: 0 y: 2}, Vector{ x: 1 y: 0}, Vector{ x: 1 y: 1} ];
var sortedVectors = Sequences.sort(vectors, Comparator{
public override function compare(obj1 : Object, obj2 : Object): Integer{
var v1 = (obj1 as Vector);
var v2 = (obj2 as Vector);
var delta = v2.length() - v1.length();
if (delta == 0 ) { 0 } else if ( delta < 0 ) { 1 } else { -1 } ;
}
}
) as Vector[];
println(sortedVectors); // [ [ 1.0, 0.0], [ 1.0, 1.0], [ 0.0, 2.0] ]
Описние устройства последовательностей:
- http://per.bothner.com/blog/2009/JavaFX-sequence-basics
- http://per.bothner.com/blog/2009/JavaFX-unboxed-sequences
- http://per.bothner.com/blog/2009/JavaFX-sequence-updating
- http://per.bothner.com/blog/2009/JavaFX-sequence-triggers
Перечисляемые типы[]
В языке JavaFX Script нет собственных перечислимых типов данных, но их можно использовать из Java.
Day.java
public enum Day {
SUNDAY,
MONDAY,
// ...
}
Использование перечислимого типа:
Main.fx
var day = Day.SUNDAY;
var days = Day.values();
for(d in days){
println("day: {d}");
}
Операторы[]
Математические операции:
Оператор | Описание | Пример Использования |
+ | Сложить | 2 + 3 |
- | Вычесть | 5 - 2 |
* | Умножить | 2 * 2 |
/ | Разделить | 10 / 5 |
Константы и переменные[]
Константы[]
Константы задаются с помощью ключевого слова def:
def PI = 3.1415;
Переменные[]
Объявление переменной[]
Для объявления переменной используется синтаксис:
var имя_переменной[:тип_переменной] [= значение];
Пример использования:
var radius = 10;
println("radius={radius}"); // результат: radius=10
var angle:Number = 45;
println("angle={angle}"); // результат: angle=45.0 // т.е angle имеет тип Number, а не Integer
Рекурсивное использование переменной[]
Иногда при создании объекта возникает необходимость тут же использовать его атрибуты или методы.
Например вы задаете окружность, а при нажатии мышкой на окружность нужно изменить ее цвет.
Чтобы код успешно скомпилировался в этом случае необходимо обязательно указывать тип определяемой переменной.
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
var circle:Circle = Circle{
fill: Color.GREEN
onMouseClicked: function (event){
circle.fill = Color.BLUE;
}
}
Использование переменной в дереве программы[]
Иногда небходимо обратится к объекту, который является частью дерева программы.
В этом случае можно определить переменную соответсвующего типа в начале программы а потом в дереве программе присвоить ей необходимый объект.
Пример того, как переменной присвоить компонент MediaPlayer, который задан в дереве программы:
var mediaPlayer: MediaPlayer;
MediaView {
mediaPlayer: mediaPlayer = MediaPlayer { }
}
Подробный пример:
import javafx.scene.*;
import javafx.scene.media.*;
import javafx.scene.control.*;
var mediaPlayer: MediaPlayer;
Scene {
content: [
MediaView {
mediaPlayer: mediaPlayer = MediaPlayer {
media: Media {
source: "movie.avi"
}
}
}
Button {
text: "Play"
action: function () {
mediaPlayer.play();
}
}
Button {
text: "Pause"
action: function () {
mediaPlayer.pause();
}
}
]
}
Классы[]
Объявление класса[]
public class Cat{
}
Объявление атрибутов и функций[]
public class Cat {
var name:String;
public function talk(): String { return "Meow!"; };
}
Статические атрибуты и функции объявляются вне класса:
public var quantity = 0;
public class Animal {
init{ quantity++ }
}
Инициализация объекта[]
Инициализация атрибутов:
class Cat {
var name:String = "Pushok";
}
Ининциализация объекта с помощью блока init:
class Cat {
var name:String;
init{
name = "Pushok"
}
}
var cat = Cat{ };
println("Cat name is {cat.name}"); // Cat name is Pushok
Ининциализация объекта с использованием триггеров:
class Cat{
public var name: String on replace{
if(name == null){ name = "unknown" }
};
}
Cat{ }; // name: unknown
Абстрактные классы[]
Чтобы объявить абстрактный класс, нужно использовать ключевое слово abstract
например:
public abstract class Animal{
public var name: String;
public abstract function talk(): String;
}
Интерфейсы[]
В JavaFX нет интерфейсов как таковых, но зато позволяется расширять Java интерфейсы.
Наследование классов[]
Чтобы отнаследоваться от уже существующего класса, надо использовать ключевое слово extends
например:
public class Dog extends Animal {
override var name = "dog";
public override function talk(): String { "Bark!"; };
}
Множественное наследование[]
В JavaFX можно создавать mixin классы. mixin классы, это абстрактные классы для которых разрешено множественное наследование.
например:
mixin class A{
}
Полный пример c использованием Классов[]
abstract class Animal{
public var name: String = "unknown";
public abstract function talk(): String;
public override function toString () { name }
init{
println("[init] animal: {this}");
}
}
class Cat extends Animal{
override var name= "cat";
override function talk(): String { "Meow!"; };
}
class Dog extends Animal {
override var name = "dog";
override function talk(): String { "Bark!"; };
}
var cat = Cat {}; // output: [init] animal: cat
var dog = Dog {}; // output: [init] animal: dog
var mouse = Animal{
name: "mouse"
override function talk() { return "Squeak!"; }
}
// output: [init] animal: mouse
println("{cat} : {cat.talk()}" ); // output: cat : Meow!
println("{dog} : {dog.talk()}" ); // output: dog : Bark!
println("{mouse}: {mouse.talk()}"); // output: mouse: Squeak!
Функции[]
Объявление функции[]
Снтаксис объявления функции:
function имя_фукции(список аргументов):тип_возвращаемого_значения { тело_фукции }
Функции в языке JavaFX Script позволяют как вычислить какое-нибудь значение, так и выполнить
определенный набор действий.
Пример объявления функции:
function square(x: Number):Number { x * x }
function hello(name: String){ System.out.println("Hello {name}!"); }
Пример вызова функций:
var a = square(2); println("square(3)={square(3)}"); // square(3)=9.0
hello("Peter"); // Hello Peter!
Рекурсивные функции[]
Так же можно определять рекурсивные функции:
function factorial(n: Integer):Integer{ return if ( n == 0 ) then { 1 } else { n * factorial(n - 1) } }
println("factorial(5) = {factorial(5)}"); // factorial(5) = 120
Функция как самостоятельный тип данных[]
Функции в языке JavaFX Script являются отдельным типом данных. Их можно присваивать переменным:
var abs = function(x:Number):Number { if (x < 0 ) then -x else x }
println("abs( -3 ) = {abs( -3)}"); // abs( -3 ) = 3.0
Базовые конструкции[]
Оператор импорта import[]
import в JavaFX похож на import в Java, однако есть и сущесвенное отличие: import может встречатся в любом месте кода (не обязательно между package и class. В этом плане import напоминает required_once() из языка PHP.
import javafx.scene.shape.Circle;
Кроме того, в интепретируемой версии языка JavaFX Script была интересная разновидность этого оператора, позволяющая импортировать класс и назначить ему синоним, под которым этот класс будет "виден":
import java.awt.Color as AWTColor;
import javafx.scene.paint.Color;
Таким образом в JavaFX решалась проблема использования классов с одинаковыми именами в Java (например, совместное использования java.util.Date и java.sql.Date). Такую же возможность планируется реализовать и в компилируемой версии языка JavaFX Script.
Block Expression[]
В фигурных скобках можно написать выражение, которое будет выполнено. Результат последнего выражения будет возвращен в качестве значения.
Например:
println("2 * 3 = { 2 * 3 }");
Еще пример:
var N = 5; var fact = {var n = 1; for(i in [1..N]){ n = i * n} n };
Оператор связывания данных bind[]
В языке JavaFX определен оператор bind который позволяет связать переменную с определенным выражением. При этом изменение любой переменной из выражения также автоматически влечет изменение связанной с этим выражением переменной.
Синтаксис оператора:
переменная = bind выражение
Пример использования оператора bind:
function max(x:Number, y:Number):Number { if( x < y ) then y else x }
var a = 3;
var b = 4;
var maxAB = bind max(a,b);
println("max( {a}, {b} ) = {maxAB}"); // max( 3, 4 ) = 4.0
a = 5;
println("max( {a}, {b} ) = {maxAB}"); // max( 5, 4 ) = 5.0
b = 7;
println("max( {a}, {b} ) = {maxAB}"); // max( 5, 7 ) = 7.0
Как видно из примера, при изменении любой из переменных a или b автоматически изменяется и связанная с ними переменная maxAB
Триггеры[]
Триггеры (triggers) используются для того, чтобы по определенным событиям (например изменение переменной или атрибута класса) можно было исполнять необходимые пользователю действия.
Пример:
var a = 10 on replace{ println("a: {a}"); } // output a: 10
Установка тригера для атрибута класса:
class A{
var hello: String on replace{
println("Hello {hello}!");
}
}
var a = A{ hello: "World" }; // Hello World!
Использование старого и нового значения атрибута:
class B{
var num: Number on replace oldValue = newValue{
println("old value {oldValue} has been changed to new value {newValue}");
}
}
var b = B{ num: 10 }; // old value 0.0 has been changed to new value 10.0
b.num = 20; // old value 10.0 has been changed to new value 20.0
Установка триггера для последовательности:
class C{
var seq: Number[] on replace oldValue[a..b] = newValue{
println("changed boundaries: [{a}..{b}]");
println(oldValue);
println(newValue);
}
}
var c = C{ seq: [1, 2, 3] };
c.seq= [3, 2];
Условная конструкция if[]
Формат конструкции:
if (<условие>) then {
выполняется последовательность действий, если условие верно
} else
выполняется последовательность действий, если условие не верно
}
Например фукция, которая вычисляет максимум двух чисел, может выглядеть следующим образом:
function max(x:Number, y:Number):Number{
if( x < y ) then y else x
}
println (max(3,5));
Цикл for[]
Формат оператора:
for( <variable> in <sequence> ){
// Тело цикла
}
Пример цикла, который повторяется 100 раз:
for (i in [1..100]){ println("Iteration: {i}"); }
Пример цикла, создающий 3 кнопки:
import javafx.scene.Group;
import javafx.scene.control.Button;
Group {
content: for (text in ["Prevoius", "Home", "Next"]) Button { text: text }
}
Операция indexof позволяет определить индекс итерируемой переменной в теле цикла:
var animals = [ "cat", "dog", "mouse" ];
for(animal in animals){
println("animals[{indexof animal}] = {animal}");
}
Результат исполнения программы:
animals[0] = cat animals[1] = dog animals[2] = mouse
Асинхронный вызов методов[]
Асинхронный вызов Java методов[]
http://blogs.sun.com/clarkeman/entry/javafx_async_task
MyRunnableFuture.java
import javafx.async.RunnableFuture;
public class MyRunnableFuture implements RunnableFuture{
public void run() throws Exception {
System.out.println("Call Java Methods!");
}
}
Main.fx
import javafx.async.JavaTaskBase;
import javafx.async.RunnableFuture;
var task = JavaTaskBase{
override function create():RunnableFuture{
new MyRunnableFuture();
}
}
task.start();
Асинхронный вызов JavaFX кода I[]
JavaRunnableFuture.java
import javafx.async.RunnableFuture;
public class JavaRunnableFuture implements RunnableFuture {
RunnableFuture runnable;
public JavaRunnableFuture(RunnableFuture runnable){
this.runnable = runnable;
}
@Override
public void run() throws Exception {
System.out.println("Call Java Methods!");
runnable.run();
}
}
Main.fx
JavaTaskBase{
override function create():RunnableFuture{
new JavaRunnableFuture(
RunnableFuture{
override function run():Void {
println("Call Java Methods!");
}
}
);
}
}.start();
Асинхронный вызов JavaFX кода II[]
AsyncProgramMoveImpl.java
import javafx.async.*;
import com.sun.javafx.runtime.async.*;
public class AsyncProgramMoveImpl extends AbstractAsyncOperation{
RunnableFuture runnable;
AsyncProgramMoveImpl(RunnableFuture runnable, AsyncOperationListener listener) {
super(listener);
this.runnable = runnable;
}
@Override
public Object call() throws Exception {
runnable.run();
return null;
}
}
JavaFXTaskBase.fx
import javafx.async.Task;
import javafx.async.RunnableFuture;
import com.sun.javafx.runtime.async.AsyncOperationListener;
import java.lang.Exception;
public class JavaFXTaskBase extends Task {
var peer: AsyncProgramMoveImpl;
public var action:function();
public override function start() : Void{
if (peer == null) {
peer = new AsyncProgramMoveImpl(RunnableFuture{ override function run(){ action() } }, asyncListener );
peer.start();
}
}
public override function stop() : Void{
}
var asyncListener = AsyncOperationListener {
public override function onProgress(progressValue:Integer, progressMax:Integer):Void {}
public override function onCompletion(value:Object):Void {}
public override function onCancel():Void {}
public override function onException(e:Exception):Void{}
}
}
Main.fx
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.Button;
Stage {
title: "Application title"
scene: Scene {
content: Button {
text: "Asynch Operation"
action: function() {
JavaFXTaskBase{
action: function(){
while(true){
println("infinty loop!");
}
}
}.start();
}
}
}
}
Интеграция с языком Java[]
Использование Java классов[]
В языке JavaFX Script можно напрямую использовать любые классы из языка Java.
Пример использования класса java.util.Date:
Реализация Java интерфейсов[]
Пример реализации и использования интерфейса FileFilter языка Java:
import java.io.*;
var imagesDir: File = new File ("resources");
var imageFiles: File[] = imagesDir.listFiles( FileFilter{
override function accept(pathname:File){
not pathname.getName().endsWith("Thumbs.db");
}
}
);
Пример реализации и использования интерфейса Runnable языка Java:
import java.lang.Thread;
import java.lang.Runnable;
var runnable = Runnable{
public override function run () {
println("Run...");
}
}
new Thread(runnable).start();
Декларативный синтаксис[]
Дерево программы[]
import javafx.stage.*;
import javafx.scene.*;
import javafx.scene.shape.*;
import javafx.scene.paint.*;
import javafx.scene.shape.*;
Stage {
title: "JavaFX Tree"
scene: Scene {
width: 300
height: 300
content: [
Group{
translateX: 50
translateY: 100
content:[
Rectangle{
width: 100
height: 100
fill: Color.BLUE
}
Circle{
radius: 50
fill: Color.GREEN
}
]
}
Group{
translateX: 150
translateY: 100
rotate: 45
content: [
Polygon {
points : [ 0,0, 100,0, 100,100 ]
fill: Color.ORANGE
}
]
}
]
}
}
Получение доступа к элементу в дереве программы[]
Связывание данных[]
import javafx.scene.*;
import javafx.scene.shape.*;
import javafx.scene.paint.*;
import javafx.scene.control.*;
var radius = 50.0;
Scene {
width: 200
height: 200
content: [
Slider {
min: 10
max: 100
value: bind radius with inverse
}
Circle {
centerX: 100, centerY: 100
radius: bind radius
fill: Color.ORANGE
}
]
}
Получение объекта по имени переменной[]
import javafx.scene.*;
import javafx.scene.shape.*;
import javafx.scene.paint.*;
import javafx.scene.input.*;
import javafx.scene.control.*;
var circle:Circle;
Scene {
width: 200
height: 200
content: [
circle = Circle {
centerX: 100
centerY: 100
radius: 40
fill: Color.GREEN
onMouseEntered: function( e: MouseEvent ):Void {
circle.fill = Color.ORANGE;
}
onMouseExited: function( e: MouseEvent ):Void {
circle.fill = Color.GREEN;
}
}
Button{
text: "Set Blue color"
action: function(){
circle.fill = Color.BLUE;
}
}
]
}
Получение объекта по id в дереве[]
import javafx.scene.*;
import javafx.stage.*;
import javafx.scene.layout.*;
import javafx.scene.control.*;
def stage : Stage = Stage {
title: "Application title"
width: 300
height: 300
scene: Scene {
content: VBox {
content: [
Button {
text: "Set default text"
action: function() {
var t : TextBox = stage.scene.lookup("textBoxID") as TextBox;
t.text = t.promptText;
}
}
TextBox {
id: "textBoxID"
promptText: "First name"
}
]
}
}
}
Каскадные Таблицы стилей[]
Более подробно о каскадных таблицах стилей можно узнать на страничке:
Язык JavaFX Script позволяет изменять свойства компонент программы не изменяя при этом саму программу. Для этого надо создать файл с расширение css и в нем описать имя компонента и его новое занчение свойства.
Например JavaFX Script программа рисует круг:
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
Stage {
title: "Application title"
scene: Scene {
width: 200
height: 200
stylesheets: ["{__DIR__}Style.css"]
content: Circle {
centerX: 100
centerY: 100
radius: 50
fill: Color.ORANGE
stroke: Color.GREEN
}
}
}
С помощью css файла можно поменять свойства этого круга, например прозрачность и цвет (файл Style.css):
Circle {
opacity: 0.5;
fill: yellow;
}
Локализация[]
Локализационные файлы[]
Файл: Main.fx
import java.util.Locale;
import javafx.ext.swing.SwingLabel;
import javafx.scene.Scene;
import javafx.stage.Stage;
Locale.setDefault(new Locale("ru"));
Stage{
title: ##"Frame"
scene: Scene{
content: SwingLabel{
text: ##"Hello"
}
}
visible: true
}
Файл: Main_ru.fxproperties
"Frame"="Окно" "Hello"="Привет"
Порядок слов в локализированной строке[]
Пусть нелокализованная строка в коде использует переменные:
var name1 = ##"Peter";
var name2 = ##"John";
var hello = ##"Hello {name1} and {name2}";
тогда строка в локализационном файле будет выглядеть следующим образом:
"Peter"="Петр" "John"="Джон" "Hello %s and %s" = "Привет %s и %s"
Где "s" обозначает, что переменная передается в виде строки.
Если надо переменные вывести в другом порядке, тогда можно использовать номер переменной:
"Hello %s and %s" = "Привет %2$s и %1$s"
Подробнее о способах форматированния данных можно изнать из документации по файлу java.util.Formatter
Storage API[]
Storage API позволяет хранить данные вашей программы локально на компьютере между запусками программы.
Запись данные в Storage:
import java.util.Date;
import javafx.io.Storage;
import javafx.util.Properties;
def storage = Storage {source: "myprogram.properties"};
def properties = new Properties();
properties.put("user", "admin");
properties.put("date", "{new Date()}");
storeConfig(storage, properties);
function storeConfig(storage:Storage, properties:Properties) {
var outputStream = storage.resource.openOutputStream(false);
properties.store(outputStream);
outputStream.close();
}
Чтение данных из Storage:
import javafx.io.Storage;
import javafx.util.Properties;
def storage = Storage {source: "myprogram.properties"};
def properties = new Properties();
loadConfig(storage, properties);
println(properties.get("user"));
println(properties.get("date"));
function loadConfig(storage:Storage, properties: Properties) {
var inputStream = storage.resource.openInputStream();
properties.load(inputStream);
inputStream.close();
}
Вопросы и ответы[]
Задайте интересующий вас вопрос по языку JavaFX Script
- на форуме
- на русском алиасе users-ru@openjfx.dev.java.net, на который можно подписаться со страницы openjfx.dev.java.net