Как разрабатывать HTML 5 Desktop приложения на Java?

vaadin-desktopМотивация

Кому могут понадобиться Desktop приложения, использующие веб-страницы в качестве UI? Отвечу прямо — всем! Всем кто страдает, пользуясь неудобными и некрасивыми приложениями.

Для меня, как для разработчика, очень важно делать пользовательские интерфейсы удобными, интересными и позволяющими пользователям не отвлекаться от работы. Кроме того, очень хочется, чтобы интерфейсы были привлекательными и их было приятно показывать. Все эти соображения приводят нас к неутешительному выводу: существующие UI фреймворки для настольных приложений ужасны.

Так что же такое есть в веб-приложениях, чего нет в настольных?

  • Разнообразие визуального оформления
  • Адаптивные и идеально-масштабируемые интерфейсы
  • Развитые анимации
  • Богатый набор компонентов и библиотек для разработки UI

Похожими возможностями обладают WPF для .NET приложений и JavaFX из мира Java. Но их компоненты не могут угнаться за стремительно развивающимися web-технологиями.

Системный кризис UI фреймворков в Java

Если мы поближе посмотрим на JavaFX, то увидим что многие идеи Web проникли в этот фреймворк. Самая главная технология UI в web-приложениях — CSS, позволяющая великолепно выглядеть вашим приложениям. JavaFX поддерживает её для стилизации компонентов, пополняя набор стандартных CSS атрибутов своими специфичными атрибутами. При этом поддержка стандартных атрибутов CSS в компонентах JavaFX похожа на лоскутное одеяло с большими дырками и заплатками.

Поищите в Java мире что-нибудь похожее по возможностям на JavaFX и вы сильно расстроитесь. Ничего нет! Есть жуткий Swing, есть сторонние технологии, позволяющие использовать Qt для Java, но все эти технологии являются полумерами. Так что если вы хотите написать Desktop приложение на Java, то вам придётся использовать JavaFX.

Когда вы воспользуетесь JavaFX, вы заметите, как мало сторонних компонентов написано, и как мало людей по-настоящему полагаются на JavaFX. Это всего лишь одна из технологий.

Спросите любого Java разработчика, какой интерфейс лучше всего сделать для Java-приложения? Вы получите один ответ, лучший интерфейс для Java-приложения — это веб-интерфейс.

Но есть некоторые области, в которых до сих пор нельзя обойтись без Desktop приложений:

  • Приложения CALL-центров для приёма заказов такси
  • Приложения, требующие поддержку работы Offline

А ведь как здорово было бы использовать HTML/CSS/JS для реализации UI в этих приложениях?

Как должно выглядеть HTML5 приложение?

Представьте, что вы запустили ваш любимый web-сайт вне браузера в виде Desktop приложения и оно выглядит, как если бы это была отдельная вкладка браузера без лишних меню, декораций и панелей, так как если бы это было приложение, которому доступны нотификации на рабочем столе и интеграция с другими приложениями, автоматическое обновление и оно может работать в отсутствии интернета.

О, это было бы волшебно!

Как реализовать такое приложение на Java?

Последнее время довольно популярным стал подход, продвигаемый фреймворками Electron и node-webkit. Основная идея — скомпилировать вместе Node.JS и браузер Chromium, предоставив среду для разработки Desktop приложений на JavaScript. В такой схеме Electron предоставляет JavaScript API для возможностей, специфичных для Desktop приложений, таких как уведомления, нативные меню и многое другое, а само приложение разрабатывается на JavaScript.

Desktop приложения на базе Electron включают две составляющие:

  1. Backend в виде Node.JS приложения
  2. Frontend в виде JavaScript компонентов или Single-Page-Application

Но наше горе, как Java разработчиков, состоит в том, что наши приложения написаны на Java и мы не хотим их переписывать на JavaScript.

Я изучил этот вопрос и выделил пару живых вариантов реализации HTML5 UI в Desktop приложении на Java:

  1. JavaFX WebView + Jetty
  2. Java CEF + Jetty

Поскольку само Desktop приложение будет так же написано на Java, то мы сможем использовать все фишки Desktop приложений: создавать дополнительные окна, показывать нативные меню, добавлять иконки в трей и показывать уведомления.

JavaFX WebView

WebView — специальный компонент JavaFX, позволяющий отображать web-контент в приложении. WebView использует специальный движок на базе webkit, интегрированный в Java Runtime.

Преимущества WebView:

  • Работает на всех платформах: Linux / MacOS / Windows
  • Отображает страницы довольно быстро
  • Имеет проработанный Java API
  • Удобные интерфейсы вызова JavaScript кода из Java
  • Возможность предоставлять JavaScript коду API Java приложения

Недостатки:

  • Рендеринг отличается от Chrome в худшую сторону, особенно заметно отличие в рендеринге шрифтов
  • Производительность отрисовки и CSS анимаций в среднем в 3-4 раза хуже чем в Chrome
  • Реализация webkit обновляется крайне редко

Я попробовал использовать WebView для встраивания приложений на базе фреймворка Vaadin и заметил эти недостатки, которые определённо не понравятся пользователям. Несмотря на замеченные проблемы, стоит использовать WebView при создании простых приложений или если UI приложения вы будете сами реализовывать на HTML/CSS и при этом полностью контролируете процесс.

Пример использования WebView в HTML5 Desktop приложении вы найдёте на Github: https://github.com/jreznot/fxc

Chromium Embedded Framework

vaadin-desktop

CEF — фреймворк для встраивания Chromium в нативные приложения. Активно развивается и применяется в приложениях для отображения web-контента. Основная цель разработки фреймворка — предоставить удобный API к возможностям Chromium. Распространяется под лицензией BSD. Имеет биндинги для многих языков программирования.

Сайт CEF: https://bitbucket.org/chromiumembedded

Для Java существует биндинг JCEF: https://bitbucket.org/chromiumembedded/java-cef  Он позволяет отображать в приложениях на базе Swing встроенное окно CEF.

Вот так выглядит код окна Swing, в которое встроен фрейм CEF:

Преимущества CEF:

  • Идеальный рендеринг, максимально близкий к Chrome
  • Регулярные обновления движка Blink
  • Отличная производительность отрисовки и анимаций

Недостатки:

  • Бинарные сборки, которые нужно поставлять вместе с приложением
  • Отсутствие готовых сборок JCEF, требуется вручную собирать версии JCEF под все поддерживаемые платформы, поскольку JCEF использует JNI для вызова библиотек CEF
  • API, который отталкивается от возможностей CEF
  • Не всегда стабильные сборки JCEF

Если вы хотите решить проблему тотально, то советую использовать CEF. Пример реализации HTML5 Desktop приложения на CEF вы найдёте на Github: https://github.com/jreznot/cefc

Jetty

Jetty — универсальный сервер для Java приложений, который удобно встраивать в другие приложения. Основная особенность Jetty — API для программной настройки сервера. Так мы можем запустить сервлет в настольном приложении при помощи Jetty:

Пример использования Jetty вместе с CEF вы найдёте здесь: https://github.com/jreznot/cefc

Перспективы

Надеюсь, что в скором времени разработка Desktop приложений на web-стеке придёт и в мир Java и мы сможем поставить крест на Swing!

Yuriy Artamonov on GithubYuriy Artamonov on LinkedinYuriy Artamonov on Twitter
Yuriy Artamonov
Software Developer
До последнего времени Юрий принимал активное участие в разработке опенсорс-фреймворка CUBA Platform, специализируясь на архитектуре и фронтенд-технологиях. Преподавал в Самарском университете разработку приложений для мобильных устройств, основы UI/UX и менторил студентов.

В настоящее время работает в компании JetBrains в команде IntelliJ IDEA Ultimate. Когда выдаётся свободное время, пишет статьи и контрибьютит в проекты с открытым исходным кодом. Обожает реализовывать странные идеи с лозунгом: «А почему бы и нет?».