JavaFX Цветные круги
Я немного подробнее расскажу о причинах использования Scala, но я считаю, что все это лучше всего проиллюстрировать на примере кода. Одним из основных примеров функциональности JavaFX 2.0, который поставляется с SDK, является пример приложения, которое называется ColorfulCircles. Полный исходный код можно найти здесь:
С помощью Свена Реймерса мы перенесли это в Scala поверх библиотеки ScalaFX . Работающий источник приложения можно найти здесь:
Обновление : у Дина Айверсона отличный пример того же кода в GroovyFX
Не стесняйтесь просматривать исходный код на досуге, и обратите внимание на следующее:
1. ScalaFX более лаконичен
Версия ScalaFX короче как по количеству строк, так и, что более важно, по количеству символов.
Количество кодов (исключая лицензии и импорт):
- линии:
- Ява: 48
- ScalaFX: 42
- Символы:
- Ява: 1602
- ScalaFX: 866
Это связано с пользовательским языком DSL, который полностью выразителен с меньшей избыточностью. В Java-версии кода вы заметите намного больше шаблонного и синтаксического повторения, которое требуется для языка.
2. Код ScalaFX выглядит как выход
Хотя вывод примера «Цветные круги» довольно прост, он на самом деле скрывает некоторую сложность в том, как он структурирован. Вот выходные данные из JavaFX 2.0 Build 45 с использованием ScalaFX:
На самом деле вы видите SceneGraph, состоящий из следующих слоев:
- Сцена с черным фоном, которая содержит …
- Группа, которая содержит
- 30 полупрозрачных кругов, покрытых…
- Прямоугольная накладка цвета радуги
- Группа, которая содержит
При чтении кода ScalaFX вы получаете эту вложенность через объявление объектно-буквального стиля Узлов в Сцене, приведенное здесь:
1
2
3
4
5
6
7
8
9
|
// ScalaFX Scene Excerpt: scene = new Scene { content = Seq( new Group { circles = for (i <- 0 until 30 ) yield new Circle { ... } } new Rectangle { ... } ) } |
Однако версия Java не дает вам того же иерархического представления, а вместо этого использует императивную серию вызовов для конструкторов, получателей и методов сбора.
3. Индивидуальный анимационный синтаксис
Анимации очень часто используются при создании хороших интерфейсов, поэтому JavaFX Script имеет встроенную конструкцию для упрощения создания анимаций. ScalaFX имеет похожий синтаксис, который позволяет быстро и легко создавать анимации, что используется в примере ColorfulCircles:
1
2
3
4
5
6
|
Seq( at( 0 s) {circle.centerX -> random * 800 }, at( 0 s) {circle.centerY -> random * 600 }, at( 40 s) {circle.centerX -> random * 800 }, at( 40 s) {circle.centerY -> random * 600 } ) |
Это позволяет легко создавать сложные анимации.
4. А версия ScalaFX имеет скрытую бонусную функцию …
В отличие от версии JavaFX, содержимое привязано к ширине и высоте сцены. Привязка в ScalaFX так же проста, как замена оператора присваивания (=) на оператор связывания (<==), как показано здесь:
1
2
3
|
// ScalaFX Property Setting: width < == scene.width height < == scene.height |
Хотя это простое изменение оператора в ScalaFX, для этого требуется достаточно сложный код, чтобы они решили опустить его из примера JavaFX. Свободный перевод на Java будет следующим:
1
2
3
|
// Java Fixed Property Binding colors.widthProperty().bind(scene.widthProperty()) colors.heightProperty().bind(scene.heightProperty()) |
Хотя точный эквивалентный код в синтаксисе Java на самом деле будет следующим:
1
2
3
|
// Java Dynamic Property Binding colors.widthProperty().bind(Bindings.selectDouble(primaryStage.sceneProperty(), "width" )) colors.heightProperty().bind(Bindings.selectDouble(primaryStage.sceneProperty(), "height" )) |
Любая из этих версий является немного более сложной и громоздкой, чем эквивалент ScalaFX, и это для очень простого связывания!
О ScalaFX
ScalaFX — это пользовательский интерфейс DSL, написанный на языке Scala, который находится поверх JavaFX 2.0 (не путать с большой работой Инго Майера по функциональному реактивному программированию для Swing). Это означает, что каждое приложение ScalaFX также является действительным приложением Scala. Благодаря расширению он поддерживает полную совместимость с Java и может работать везде, где поддерживаются виртуальная машина Java (JVM) и JavaFX 2.0.
Некоторые функции ScalaFX включают в себя:
Удобный для программиста объектно-буквальный синтаксис
ScalaFX использует простой иерархический шаблон для создания новых объектов и построения графа сцены. Вот простой пример, который создает новый этап с прямоугольником, который меняет цвет в зависимости от событий мыши:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
|
stage = new Stage { title.value = "Hello Stage" width = 600 height = 450 scene = new Scene { fill = Color.LIGHTGREEN content = new Rectangle { x = 25 y = 40 width = 100 height = 100 fill < == when (hover) then Color.GREEN otherwise Color.RED } } visible = true } |
В отличие от компоновщиков, которые вы найдете в основных API JavaFX, синтаксис объявления объекта ScalaFX использует обычный объектный API. Это означает, что вы можете использовать те же операторы и удобный синтаксис для создания и изменения графа сцены. Кроме того, все, что допустимо в блоке Scala (например, объявления переменных, вызовы методов, привязка и т. Д.), Также может быть встроено при создании объектов. Для сборщиков JavaFX вам необходимо объявить связывание после того, как вы закончите создавать свои объекты, что приводит к диссоциации и сложному обслуживанию кода.
Природные выражения языка
Одним из величайших преимуществ использования языка Scala в качестве DSL является широкая поддержка операторов в качестве методов. Это похоже на концепцию перегрузки операторов в C ++, но гораздо более единообразно и чисто в своем приложении.
Библиотека связывания ScalaFX предоставляет обычные операторы, такие как &&, ||, +, -, *, / поверх всех привязываемых объектов. Кроме того, Scala поддерживает приоритет операторов, поэтому выглядит и чувствует, что вы пишете нормальные выражения, даже если вы создаете связанные объекты под обложками. В результате у вас есть полная функциональность, доступная из библиотек связывания JavaFX 2.0 с кодом, похожим на математические выражения и операторы.
Вот несколько примеров того, что вы можете сделать с помощью API привязки ScalaFX:
Инфикс сложение / вычитание / умножение / деление / и т. Д.
1
|
height < == rect 1 .height + rect 2 .height |
Агрегатные операторы
1
|
width < == max(rect 1 .width, rect 2 .width, rect 3 .width) |
Условные выражения
1
|
color < == when (hover) then Color.GREEN otherwise Color.RED |
Сложные логические выражения и конкатенация строк
1
|
text < == when (rect.hover || circle.hover && !disabled) then textField.text + " is enabled" otherwise "disabled" |
Инвалидация в произвольной форме и обработчики изменений
1
2
3
|
rect.hover onInvalidate { needsRepaint = true } |
Полностью типобезопасные API
Это может показаться незначительным моментом… Безопасность типов — это то, что разработчики Java всегда имели (и часто принимают как должное), а разработчики на других языках сценариев живут без них (и в результате неосознанно страдают от ошибок времени выполнения). Однако это критически важная функция, если вы разрабатываете приложения, в которых после развертывания не может быть непредвиденных ошибок и ошибок во время выполнения.
Хороший компилятор сможет выявлять многие распространенные ошибки кодирования путем сравнения ожидаемых и фактических типов, а отличный компилятор (например, Scala) автоматически выведет для вас типы, поэтому вам не придется повторять их через весь код.
ScalaFX получает лучшее из обоих миров благодаря скриптовому синтаксису DSL, в котором вам редко приходится явным образом вводить объекты, с высокой степенью безопасности типов компилятора Scala, который будет выводить и проверять типы каждого выражения и вызова API. Это означает меньше времени, затрачиваемого на отладку странных ошибок кода и орфографических ошибок, и более качественный код прямо из ворот!
Полная совместимость JavaFX / ScalaFX
Часто бывает так, что у вас нет полной свободы в отношении преобладающего языка кодовой базы или библиотек, из которых вы включаете функциональность. Даже в кодовой базе смешанной среды, где у вас есть Java, Scala и, возможно, другие языки JVM, ScalaFX будет легко конвертировать и взаимодействовать.
ScalaFX получает эту функциональность благодаря неявным операторским возможностям Scala. Везде, где ваша программа ожидает типизированный объект JavaFX, она автоматически вставит код для преобразования из обернутых объектов ScalaFX в собственные классы JavaFX. Каждый раз, когда вы используете специфическую функцию ScalaFX, компилятор автоматически создает объект-оболочку ScalaFX, который позволяет вам вызывать расширенные методы и получать доступ ко всем функциям. Все это происходит за кулисами, позволяя вам сосредоточиться на написании чистого кода, а не суетиться об интеграции и функциональной совместимости.
Со всей этой магией взаимодействия, происходящей за кулисами, у вашего приложения есть некоторые дополнительные издержки. Мы постарались минимизировать это, используя такие функции, как @specialize в языке Scala, что позволяет нам избежать затрат на упаковку и распаковку примитивов. Однако без реальных ориентиров трудно сказать, насколько хорошо мы проделали работу. Надеюсь, подробнее об этом в следующем посте.
Узнайте больше о ScalaFX
Сайт проекта ScalaFX размещается в Google Code, включая несколько списков рассылки, к которым вам следует присоединиться, если вы заинтересованы:
На момент написания статьи у нас не было готового релиза, но мы заинтересованы в ранней обратной связи с пользователями. Если вы хотите попробовать, скачайте исходный код и быстро его раскрутите!
У меня будет больше деталей о ScalaFX на моей предстоящей сессии JavaOne с Дином Айверсоном под названием « JavaFX 2.0 с альтернативными языками ». Узнайте больше о Scala, Groovy и других языках JVM, которые можно использовать для написания более простого и понятного кода.
Ссылка: JavaFX 2.0 и Scala, Like Milk и Cookies от нашего партнера JCG