- Подписка на печатную версию:
- Подписка на электронную версию:
- Подшивки старых номеров журнала (печатные версии)
LXF119:JavaFX
Материал из Linuxformat.
- JavaFX Создавайте продвинутые интернет-приложения (и не только) без лишних усилий
Содержание |
JavaFX: Первое знакомство
JavaFX |
---|
|
- Часть 1: Наслышаны о новой «кофейной» технологии и желаете знать детали? Антон Черноусов вам их предоставит.
Несмотря на то, что JavaScript активно используется в разработке интерактивных web-приложений, по сути, в основе этой технологии лежат одни большие «грабли». Проблема кроется в различных независимых реализациях JavaScript в разных браузерах. Опытные программисты давно научились обходить узкие места и создают поистине великолепные web-приложения. Однако любого начинающего разработчика раздражает разнообразие ловушек, которые расставлены разными версиями web-обозревателей.
Стандартных средств HTML для создания сочного динамичного изображения недостаточно, если не сказать больше. Интернет без графики беден. Красивые картинки сами собой складываются в мультики, а после на этом фундаменте появляются серьезные приложения. Так уж получилось, что современный Интернет сложно представить без Adobe Flash. Популярность этой технологии основана, прежде всего, на двух фактах: отличных мультимедийных возможностях и стопроцентно одинаковой работе на всех настольных платформах и во всех браузерах (при наличии соответствующего расширения).
Вычисления в виртуальной машине видятся многими как панацея, и на фоне этих ожиданий практически одновременно вышли два интересных проекта: Silverlight от компании Microsoft и JavaFX от компании Sun Microsystems. Оба они предоставляют возможности разработки RIA (Rich Internet Application) – web-приложений, обладающих характеристиками настольных (и обычобычно реализуемых с помощью расширений браузеров или виртуальных машин). В итоге, у нас появился шанс попробовать вкус Java в новой упаковке – JavaFX. Основой для среды выполнения нового скриптового языка, названного (как нетрудно догадаться) JavaFX Script, стала виртуальная машина Java (JVM). По сути, сценарий JavaFX Script транслируется в байт-код, который интерпретируется (или компилируется на лету) JVM. Таким образом, мы имеем новый удобный язык, направленный на создание интерфейса пользователя, основной упор в котором сделан на простое применение мультимедийных возможностей, работающий в проверенной временем виртуальной машине. Последнее, кстати, означает, что сценарии JavaFX имеют доступ ко всему богатству Java-библиотек. Но не будем бежать впереди паровоза, а лучше рассмотрим все по порядку.
Винтики и гаечки
На этом уроке мы познакомимся с синтаксисом и некоторыми основными конструкциями языка JavaFX Script. Для работы с JavaFX вам потребуется зайти на сайт проекта http://www.javafx.com и загрузить последнюю версию SDK (сейчас это JavaFX 1.1.1). К сожалению, на момент написания статьи технология JavaFX была доступна только для платформ Windows и Mac OS X, но Linux-редакция должна появиться уже к тому моменту, когда вы будете читать эти строки. Также вам потребуется среда разработки – по указанному выше адресу доступна специальная версия NetBeans IDE 6.5.1 с интегрированным JavaFX 1.1.1, это официально поддерживаемый комплект разработчика.
Запустите NetBeans и создайте новый проект JavaFX (File > New Project > JavaFX > JavaFX Script Application). Сразу заметим, что все FX-скрипты (классы) – это обыкновенные текстовые файлы с расширением .fx. Рассмотрим структуру FX-класса на примере файла FirstFXScript.fx (вы найдете его на LXFDVD наряду с другими примерами этой статьи):
def numberOne = 100; def stringOne = “the one hundred”; var numberTwo : Integer = 100; var stringTwo : String =“the one hundred”;
В любом FX-скрипте могут быть использованы переменные, которые объявляются двумя разными способами: с применением зарезервированных слов def или var. Отличие в том, что переменные, объявленные с помощью var, могут изменять свое значение в теле скрипта, а созданные посредством def являются константами.
Как и во многих языках, для имени переменной можно использовать буквы и цифры, но начинаться оно должно с буквы. Рекомендуется следовать соглашениям Code Conventions (http://java.sun.com/docs/codeconv/): используются буквы нижнего регистра, но если имя состоит из нескольких слов, то первые буквы всех последующих слов являются прописными, как показано в примере выше.
В первых двух строках примера происходит объявление констант (числа и строки), при этом не указан тип переменной – это допустимо, так как в нашем случае компилятору достаточно информации, чтобы определить его самостоятельно. В последних двух строках тип переменных указан явно.
В следующем примере определены несколько скриптовых функций, одна из которых используется для сложения, а вторая – для установки новых значений переменных.
function summFunction() { var result = numberOne + numberTwo; println(“{stringOne} + {stringTwo} = {result}”); } function changeFunction() { stringTwo = “zero”; numberTwo = 0; } function returnFunction() : String { return “returned string”;}
Последняя функция возвращает значение переменной типа String: для этого в ее теле используется специальное зарезервированное слово return. Если возвращаемое значение не определено в сигнатуре, то функция по умолчанию возвращает значение Void (этот тип данных используется, чтобы указать, что выражение не возвращает никакого значения). В функции summFunction() вывод информации осуществляется на консоль (необходимость писать фигурные скобочки поначалу немного удивляет). Как вы можете заметить, все представленные функции не имеют параметров (параметры – это конкретные значения, передаваемые функции в момент вызова). Для создания функции с параметрами необходимо, чтобы ее сигнатура выглядела следующим образом: function blahFunction(argOne: Integer, argTwo: String). В таком случае у функции blahFunction() будет два параметра: первый типа Integer, второй типа String, и не будет возвращаемого значения.
Функция выполняется в момент ее однозначного вызова, например, так:
summFunction(); changeFunction();
И совершенно не важно, вызывается ли функция до того, как она была определена, или после, как в нашем примере FirstFXScript.fx.
Чтобы закрыть тему функций в этой статье, рассмотрим еще один случай, когда в скрипте необходимо использовать аргументы командной строки. Для этого потребуется создать функцию run() – это своеобразная стартовая точка скрипскрипта (если она определена). Функция run() хранит все параметры командной строки в переменной args – это последовательность объектов типа String.
function run(args : String[]) {…}
Вы можете заметить, что в FirstFXScript.fx такой функции нет. В этом случае компилятор автоматически создает run() без аргументов и размещает исполняемый код внутри нее. Есть еще один случай, когда необходимо использовать функцию run() – но к нему мы еще вернемся.
Встроенные типы данных
В языке JavaFX Script существует пять встроенных типов данных: String, Integer, Number, Boolean и Duration.
Тип String (строка) – один из самых распространенных. Для его объявления можно использовать как одиночные, так и двойные кавычки – никакой роли это не играет, однако следует помнить, что одиночные и двойные кавычки являются симметричными. При объявлении, в строку можно добавить выражение, обрамленное фигурными скобками {}, например:
def year = “'09”; // можно вставлять одиночные кавычки в двойные и наоборот
var name = “STD {year}”;
Для работы с числами существуют два типа: Integer и Number. Как правило, тип определяется автоматически, но вы можете указать его самостоятельно. Предполагается, что вы всегда будете пользоваться типом Integer (целые числа), и только в случаях, где необходимы операции с плавающей точкой, будет использован тип Number.
Тип Boolean остается верен традициям и может принимать два значения: true (истина) и false (ложь), например:
var isHero = true;
Самым интересным встроенным типом, на мой взгляд, является Duration (продолжительность), который содержит количество фиксированных единиц времени (миллисекунд – ms, секунд – s, минут – m или часов – h), например:
var time = 5ms;
Этот тип наиболее часто используется при создании анимации, о которой мы поговорим подробнее в следующий раз. Пять базовых типов определяют основные возможности по работе с исходными данными. Помимо них, есть еще одна фундаментальная структура – последовательность или набор упорядоченных элементов. Последовательности объявляются с помощью квадратных скобок [], а их элементы отделяются друг от друга запятыми, например:
var num1 = [1, 3, 5, 7];
Данная конструкция будет автоматически воспринята компилятором как последовательность элементов целочисленного типа (Integer). При необходимости получить последовательность чисел в некотором диапазоне, сделайте это с помощью следующего выражения: var num2 = [1.. .. 100];. Можно явно указать тип последовательности, например:
var num3: String[] = [“One”,“Two”];
У любой последовательности можно определить ее размер (операция sizeof), а с помощью зарезервированного слова insert можно вставить в последовательность новый элемент, перед указанным или после него:
insert “Zero” before num3[0]; insert “Three” after num3[2];
Не забывайте, что нумерация индексов в последовательностях начинается с 0. Также можно удалять элементы из последовательности с помощью зарезервированных слов delete и from, например, так:
delete “One” from num3; delete num3[1];
Вы, наверное, уже ощутили, что последовательности – это нечто среднее между массивами и коллекциями в Java. У них есть еще много интересных возможностей, например выбор подпоследовательности.
Триггеры
При написании программ очень часто возникает необходимость обеспечить связи между сущностями, чтобы при изменении состояния одной из них это автоматически «чувствовала» вторая. Классически, описанная выше задача решается с помощью паттерна Observer (Наблюдатель). В Java при создании графических приложений используется механизм ActionListeners.
Разработчики JavaFX Script считают, что одной из ключевых возможностей этого языка программирования является возможность привязки данных (binding), то есть обеспечение связи между двумя переменными. В JavaFX введено понятие «триггер», который представляет собой блок кода, связанный с переменной: когда ее значение изменяется, код выполняется автоматически.
Впервые узнав об этой возможности, я подумал, что реализация паттерна Observer и триггеры – это одно и тоже, но я был сильно неправ. При пристальном рассмотрении, механизм оказался недостаточным для замены паттерна Observer, хотя его использование в некоторых случаях существенно упрощает разработку.
Создание связей производится с помощью зарезервированного слова bind, при этом происходит связывание значения переменной со значением выражения. Связываемое выражение может быть переменной основного типа, объектом, функцией или каким-либо выражением. Взгляните на представленный ниже пример связывания переменных:
var parent : Integer = 0; def child : Integer = bind parent; parent = 8; println(child); parent = 16; println(child);
Обратите внимание, что переменная child объявлена при помощи зарезервированного слова def и, следовательно, является константой, которая не может быть изменена напрямую. Связывание – единственный способ добиться изменения этого вида переменных; присвоив parent новое значение, мы автоматически изменим child. Используя аналогичный метод, можно привязать переменную к объекту.
Объекты и модификаторы доступа
В JavaFX есть возможность создавать и использовать собственные объекты. В качестве примера рассмотрим скрипт PhoneBook.fx, в котором реализован класс People, представленный ниже. Как вы можете убедиться, в рамках одного скрипта может располагаться несколько классов, наподобие внутренних классов в Java (InnerClass).
public class People { protected var name : String; protected var phone : String; public function getInfo() : String { return “{name} : {phone}”; }; }
Описание переменных и функций у класса People выполняется аналогично рассмотренному ранее способу. Создать экземпляр такого класса в рамках скрипта очень просто, хотя, пожалуй, следует остановиться на задании начального состояния объекта. У нашего класса People две переменные: name и phone. Ниже представлен процесс инициализации объекта p, при котором переменная name получает значение «F.X.», а переменной phone будет сопоставлен некий телефонный номер.
var p : People = People { name : “F.X.”; phone : “+7 (999) 9 999 999”; };
Читатели, знакомые с языком Java, уже обратили внимание на зарезервированные слова public и protected, которые являются модификаторами доступа. Так вот, я должен слегка разочаровать вас: модификаторы в Java и в JavaFX Script не являются идентичными. Всего в JavaFX Script имеется пять модификаторов: package, protected, public, public-read, public-init:
- Если вы уже смотрели полные исходные коды сценариев на LXFDVD, то могли обратить внимание на строчку package ru.golodnyj.lxf.fx; – ею определяется пакет (package, механизм, позволяющий управлять пространством имен Java-программы) для FX-приложений. Модификатор доступа package используют, когда необходимо сделать переменную, функцию или класс доступными для остального кода внутри пакета.
- В то же время, модификатор доступа protected делает переменную или функцию доступной для кода внутри пакета и дочерних классов, расположенных в любом другом пакете. Данный модификатор не может применяться к классам.
- Классы, переменные или функции с модификатором public открыты для чтения и записи для любого класса или скрипта, находящихся внутри любого пакета.
- Модификатор доступа public-read можно применить к переменной, в этом случае она становится доступна для чтения в рамках всего приложения, но изменение значения (по умолчанию) доступно только из текущего скрипта. Модификатор public-read можно комбинировать с package или protected (в результате получаются package public-read и protected public-read). Это позволяет установить доступ на запись при модификаторах package или protected, соответственно.
- Модификатор public-init применяется к переменной, если ее необходимо публично инициализировать (из любого пакета). Значение такой переменной также может быть считано из любого пакета. Доступ к записи аналогичен модификатору public-read (по умолчанию – доступ к записи только на уровне скрипта плюс расширение через модификаторы package или protected).
Следует отметить, что сам скрипт при встраивании объектов необходимо поместить в функцию run(), например, так:
function run(){ writePeople(); }
Выражения
Выражения (expressions) – это конструкции языка, которые могут быть присвоены значению переменной, функции и так далее. Выражения могут быть объединены с целью создания других выражений. В JavaFX Script выражения играют большую роль: все основные языковые конструкции – циклы, условия и даже блоки – являются выражениями. Блоковое выражение состоит из списка описаний и выражений, взятых в фигурные скобки и разделенных точками с запятой, например, так:
var num1 = [1, 3, 5, 7]; var all = { var sum = 0; for (a in num1) { sum += a }; sum; }
Значение блокового выражения в нашем случае определено переменной sum, имеет тип Integer и будет равно 16. Блоковое выражение имеет тип Void в том случае, если оно не содержит выражений (и var, и def являются выражениями).
Ранее в этой статье мы рассматривали последовательности, и с технической точки зрения они являются интервальными выражениями. По умолчанию, интервал между значениями в последовательности равен 1, но вы можете использовать зарезервированное слово step для того, чтобы задать другое значение интервала, например:
var num4 = [1..10 step 2];
Шаг может быть и отрицательным. Выражениями, как уже было отмечено выше, являются также циклы for и while, но более подробно об этих и других типах выражений мы поговорим в следующий раз.
Итак, мы рассмотрели базовые механизмы скриптового языка JavaFX, который хоть и похож на Java, но не является им – думаю, для первого знакомства этого достаточно. В следующей статье мы напишем на языке JavaFX интерактивное графическое приложение, и более подробно рассмотрим некоторые возможности, которые лишь слегка обозначили в этой статье. А пока предлагаю вам насладиться вечно живым Арканоидом (BrickBreaker) в новой рубашке из JavaFX. Добро пожаловать на http://javafx.com/samples/BrickBreaker/. LXF
Что читать летом
Если вы всерьез заинтересовались разработкой с использованием JavaFX, то помимо основного сайта проекта (http://www.javafx.com) имеет смысл обратить внимание на следующие ресурсы:
- http://learnjavafx.typepad.com/ Блог, который ведет Джим Вивер [Jim Weaver]. Вместе со Стефеном Чином [Stephen Chin], Джим был одним из основных докладчиков о платформе JavaFX на конференции JavaOne (и ведущим технической сессии). Они также являются соавторами книги Pro JavaFX™ Platform: Script, Desktop and Mobile RIA with Java™ Technology, которая выйдет в июне 2009 года в издательстве Apress.
- http://apress.com/book/view/9781430218753 К сожалению, о планах по ее переводу на русский язык нам ничего не известно.
- http://www.psynixis.com/blog/ Блог, который ведет Саймон Броклхерст [Simon Brocklehurst], посвященный не только технологии JavaFX. Саймон является основателем двух компаний и получил степень PhD в Кембриджском университете.
- http://jfxstudio.wordpress.com/ Блог, полностью посвященный JavaFX.
- http://java.sun.com/features/index.html#javafx Здесь можно ознакомиться с некоторыми техническими статьями о JavaFX.
Кроме того, по адресу http://www.javafx.com/samples/ существует галерея учебных проектов, выполненных по технологии JavaFX.