Pull to refresh

Comments 41

В нескольких фирмах, в которых я работал — как стартапах, так и крупных компаниях, делали Rich Client на свинге. Были проблемы, но ни разу не жалели о выборе платформы. Автор правильно указал основные плюсы — огромный выбор библиотек и накопленных знаний.
Немножко отсебятины, почему Свинг не есть очень хорошо. Просто личное впечатление.

В своё время мне, РНР-шнику, пришлось поучаствовать в разработке одного приложения на Джаве. Я делал UI. На Свинге. Вобщем-то, всё было более-менее нормально, пока не возникла одна особенность — проблема с отрисовкой lightweight-компонентов на JDialog (на фрейме всё было отлично, а вот с диалогом — проблемы). Печаль ситуации была еще и в том, что мы были скованы рамками JRE 6 (в JRE 7 это уже работало нормально, но радости не приносило, т.к. использовать всё-равно надо было JRE 6).

Полез гуглить. Чисто случайно нашел данный баг на еще sun-овском(!) багтрекере. Страниц 5 разного рода изобретательности матюков по этому поводу и workaround в почти самом конце + пара комментов, что это должно работать. Workaround базировался на том, что в реализации Свинга для JRE 6 был то ли один метод в реализации JDialog был пабликом вместо логичного привата, то ли что-то в этом роде. Вобщем, работало с использованием глюка самой JRE, вернее, реализации Свинга в ней.

Но — не заработало. Погуглив еще, нашел этот же воркэраунд на каком-то форуме, где люди в комментариях отписались, что в очередном апдейте JRE 6 такой вот хак закрыли, и теперь нифига не работает. Баг с отрисовкой никуда при этом не делся, его никто не исправлял, хотя жалобы были у очень многих. И т.к. у конечного юзера, скорее всего, будет версия JRE 6 с последним апдейтом, надеяться на то, что чисто случайно воркэраунд заработает, нельзя.

Вобщем, после этой истории, в которой меня поразил не столько факт наличия бага, сколько закрытие единственного способа его обойти, отношение к Свингу испортилось окончательно, и впредь, ежели чего, буду руками-ногами отбиваться, прежде чем соглашаться иметь с ним дело.
Такая же история с File.exists.
OpenJDK на тот момент не было?
Да вроде бы было. Собственно, сама история произошла не то чтобы очень давно, всего около года назад. Просто мы были весьма скованы в средствах разработки, да и баг проявился только когда проект был почти закончен (ну захотелось добавить одну маленькую фичу, кто ж знал что такие косяки повылазят). Т.е. перепиливать проект под OpenJDK и потом еще искать возможные баги как-то не было ни времени, ни особого желания. Списали эту фичу на следующую итерацию разработки, потом оно всё заглохло и вот как-то так и закончилось.
Когда писал программу, выяснил, что не поддерживался один из типов данных в clipboard. Поправил в нескольких местах в исходниках, пересобрал JDK — проблема решилась.

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

Исходники OpenJDK на несколько апдейтов отстают от билда Oracle. Т.е. они одинаковые с поправкой на несколько релизов.
Я сильно новичек в Джаве (собственно, тот проект был первым и последним моим опытом в ней), поэтому вопрос. У нас было скачиваемое через web приложение. Не помню, как называлась сама технология, но суть была в том, что юзеру через http загружался клиент и, собственно, потом уже это всё работало, т.е. никаких скомпилированных файлов не было, возможности сделать дистрибутив со своим подхаченным OpenJDK, соответственно, тоже. Насколько я понимаю, работоспособность приложения зависела исключительно от того, какая версия JRE стоит у конечного юзера (собственно, поэтому JRE 6 и использовали — для пущей обратной совместимости). Как выкручиваться в таких ситуациях?
Как и с обычными приложениями: делать свой инсталлятор. Java Web Start работать не будет.
UFO just landed and posted this here
Это косается всех версий или только 8ки?
Я ответил про отставание, потому что видел пост от сотрудников Oracle, что они зимой 12-13 собираются фиксить только уязвимости. Эти фиксы будут попадать в OpenJDK «по мере возможностей». К сожалению, не смог сейчас найти эту страницу, чтобы проверить верно я запомнил или нет.
UFO just landed and posted this here
нативный. выглядит вот так:
Может кто ещё подскажет, какой UI-фреймворк не привязан к стандартным компонентам? Что-нибудь вроде XAML, только для Java. Чтобы можно было легко модифицировать вид стандартных элементов.
Qt не подошел, т.к. был целиком на “нативных” компонентах, а часто требовалось где-то изменить отрисовку.

Позвольте с Вами не согласиться. Qt позволяет проводить мощную кастомизацию приложения средствами QSS (аналог CSS), можете посмотреть, к примеру, на проект, в котором я принимал участие:

Код можно на гитхабе посмотреть. К примеру, на основной стиль.

Отрисовка в Qt очень шустрая и достаточно легко кастомизируется, как видите.
PS: прошу прощения за «чужие» скриншоты, проект мёртв и скриншоты сделать без работающего сервера проблематично. =)
Спасибо. Добавил в статью
Вот только делать анимацию на виджетах это сразу застрелиться хочется. Сейчас такую морду быстрее всего наклепать на Qt5.1 и QtQuickControls, там еще остались баги, в основном в input'е, но они не настолько критичные, как в file.exist.
Кстати, что интересно, контролы вполне сносно работают на Андроиде, хотя его поддержка в них не заявлена никак.
Ну, я про анимацию ничего не говорил. Хотя она делается на порядок проще, нежели в том же WinAPI/MFC.
Но да, для быстрого их создания QML куда лучше подходит.

Кстати, в Qt5 можно сделать окно, на котором QML находится прозрачным? Помнится, в 4.8 нельзя было.
Не пробовал, если честно. В 4.8 я такое же делал, кстати, для попапов, правда через жопу.
Adobe Air не поддерживает multi-threading.

Уже поддерживает. Начиная с версии 3.4 там появились Worker-ы.
Неплохо было бы добавить инфо об этом в статью.
Я сейчас на свинге приложение пишу (не по работе, а свое иногда дома по вечерам). Очень нравится т.к. все очень понятно, просто и т.д. Но время от времени сталкиваюсь с отсутствием необходимых фич, которые давно есть в других фреймворках, а в свинге надо шерстить stackoverflow в поисках решения (благо находятся быстро). Одной из таких фич был автоскроллинг при добавлении текста, если скроллер находится относительно новых данных, но как только скролл сдвинут, то автоскроллинг перестает работать, пока не вернемся к актуальным данным. Или прозрачность окон/элементов о которых упоминалось уже — нету нативной реализации, надо танцевать с бубном и не факт, что будет везде работать.
Сейчас смотрю в сторону JavaFX, чем-то напоминает WPF, но т.к. не пробовал на нем что-либо делать, то ничего сказать не могу.

Кстати, вопрос к автору статьи: пробовали ли вы JavaFX? Хорош ли он по вашему для создания десктопных приложений?
К сожалению, не могу ничего сказать. Когда я начал писать программу, JavaFX для Мака не было. А когда появился, уже было написано достаточно много кода для Swing.
Мне кажется, что от танцев с бубном не избавиться. С любым фреймворком. Серебрянных пуль не бывыет. Например, на JavaFX будет сложно сделать ListView/TableView на несколько (десятков) тысяч записей. Придется продумывать/реализовывать виртуализацию объектов в дереве.
Swing – только hardware accelerated. Это значит ваше приложение не будет работать в VMware, Parallels или через удаленный рабочий стол. Если вы не готовы с этим мириться, то смотрите в сторону SWT.

Это несколько странное заявление. У свинга бывают проблемы (не у всех приложений) с переключением с remote desktop на нормальный режим и обратно (и да, это раздражает), ещё бывают проблемы с несколькими мониторами, когда диалоги появляются не на том мониторе (и это тоже раздражает), но в целом больших проблем с работой через удаленный рабочий стол я не видел. Тем более в виртуальных машинах.
Какая операционная система? Здесь проблемы с Mac.
Win/Linux. Интересно, попробую дома. Это проблемы OpenJDK или старой Apple'oвской реализации?
Если в основном интересовал порт на Mac, почему в списке есть Mono+GTK, но нет Mono+MonoMac?
>Win/Linux. Интересно, попробую дома. Это проблемы OpenJDK или старой Apple'oвской реализации?
Это проблемы OpenJDK на Mac. У них нет «fallback» на софтверную отрисовку. В Apple'овской реализации отрисовка была через Quartz. К сожалению, она только 10.6 и уже «умерла».

>Если в основном интересовал порт на Mac, почему в списке есть Mono+GTK, но нет Mono+MonoMac?
MonoMac не кросс-платформенный. Мне это было принципиально, т.к. 80% кода программы — это UI.
Подтверждаю, на Win/Linux работает через удалёнку.
Мне очень понравился конструктив в статье. Нет этого фанбойизма и истерики, которая присуща темам, связанным с выбором тех или иных технологий.

Код, который решает проблему с поддержкой рендерринга картинок на GPU, было бы неплохо выложить куда-нибудь на GitHub, чтобы другие разработчики могли воспользоваться решением. У GitHub есть плагин для Maven, который умеет собрать артефакт (jar) и положить его в отдельный бранч проекта, причем версии можно указывать тегами. Потом этот урл можно указывать в зависимостях — очень и очень удобно.

Плюс неплохо было бы выложить решение проблемы в виде вопроса-ответа на StackOverflow, чтобы другие потом могли бы его найти. SO позволяет отвечать самому себе. Если кинете ссылку, думаю сообщество поддержит.

Вообще у вас довольно специфическая задача — обработка изображений. Поэтому смело советовать использовать тот или иной тулкит сложно. Если бы я сам занимался разработкой десктопного приложения, я бы делал его на HTML — просто я знаю, как на нем делать интерфейсы, лучше, чем на чем-либо другом. За основу взял бы Node-WebKit или Chromium Embedded Framework.

Знаю, что многие пльзователи Маков не любят ненативные приложения. За это часто ругают Firefox, Opera, среды разработки и т.д. Свои косяки, конечно, есть везде: и в Qt, и в XUL, и в Swing. Но свинг под мак долгое время подпиливали сами Apple, так что тут у него есть некоторое историческое преимущество. В любом случае, главное, что ваше приложение решает конкретные проблемы пользователей, не портя им настроение, а на чем оно написано — дело десятое.
Что по итогу вы использовали, какие библиотеки, дополнения к Swing?
JUnit, TimingFramework, MacWidgets, MigLayout, PropertyList 2.0, ImgScalr, JForms
Qt не подошел, т.к. был целиком на “нативных” компонентах, а часто требовалось где-то изменить отрисовку.

Вообще то Qt точно также как и swing весь на саморисованных (легковесных) компонентах. Системные контролы не используются. А вот например в wxWidgets, IUP и SWT используются именно системные контролы.
Да, я уже понял про эту ошибку. silvansky выше привел пример закостомайзеного приложения на Qt.
Программирую на свинге с 96 года (swing-1.1.1, когда еще не был включен в JRE). На мой взгляд, плохая реализация сомнительной идеи (мимикрировать под нативные ОС). Свинг полностью изжил себя лет 7 назад, когда из Сана ушла вся swing-команда: Chet Haase, Romain Guy, Alex Potochkin, Kirill Grouchnikov, Amy Fowler, и др. Java полностью потеряла позиции на рынке десктопов, даже JavaFX теперь уже не спасет. Императивная отрисовка графики, разработанная в 80-х кодах, изжила себя лет 10 назад и во всех системах была заменена декларативным описанием дерева объектов как JavaFX, SVG, HTML. Кроме того, основным недостатком свинга являлись:
— скудный набор компонентов.
— любой шаг влево связан с жуткими сложностями. Я задолбался в сотый раз писать TableCellRenderer для нормального отображения данных в таблице.
— нет нормального Layout-а. GridBagLayout создавался для IDE tools, но никак не для человека. Точку поставил только MigLayout.
— нет нормального LAF. Мимикрия под системные просто ужасна. Был интересный LAF — Substance.
— общая тормознутость интерфейса. Я не знаю почему так получается, но свинговый интерфейс любой апликации лагает. С SWT такой проблемы нет.

Один вопрос: а почему Вы не выбрали архитектуру веб клиента? Например Embedded Jetty + GWT/SmartGWT или Vaadin?

Ниже прокомментирую некоторые ваши высказывания:

> На сегодняшний день в QML и JavaFX исправлены описанные проблемы. Поэтому, если вы готовы работать со сценическим графом, то вам стоит взять их на тест-драйв.
Интерфейс на JavaFX лагает как слайдшоу на моей рабочей тачке, даже банальный скроллинг. Не ведитесь на удочку Oracle, обещающей светлое будущее JavaFX. Поезд ушел 7 лет назад. Все разговоры о портировании JFX на мобильные завораживают, но, пардон, где Java под iOS/Android? Теперь у нас есть HTML5/Canvas/CSS3/SVG.

> Очень много библиотек.
80% из них уже давно не поддерживается.

> Вся отрисовка hardware-accelerated. Любое Swing-приложение отрисовывается на GPU, от разработчика ничего не требуется.
Это не так. Акселерировано толька отрисовка примитивов и опции с растрами. Поскольку разработчик сам пишет код отрисовки компонентов, то он ответственен за то, чтобы акселерация использовалась по-максимому. Известен такой хак как двойная буферизация. У меня есть книга Swing Hacks по всем подобным хакам свинга, которая занимает 300 страниц.

> Swing – только hardware accelerated.
Это тоже не верно. Swing лежит на AWT, который в свою очередь использует Toolkit, который использует graphics pipeline. Последний по возможности использует ресурсы машины. Так что swing работает и на машинах без акселерации, и на remote desktop, только отрисовка долгая, поскольку транслируется весь растр окна.

> Не все объекты BufferedImage используют аппаратное ускорение.
BufferedImage вообще не accelerated. Это просто растр в памяти. ТруЪ accelerated — это VolatileImage и CompatibleImage. При рендеринге BufferedImage по возможности внутренне создается VolatileImage (или CompatibleImage), данные которого лежат на видеокарте. Битность BufferedImage имеет значение только при переводе в VolatileImage: если она у них совпадает, перевод делается на порядок быстрее. Битность VolatileImage зависит от девайса: например X Window не поддерживала альфа канал (не знаю как в JDK7 с ее новой rendering pipeline)

> При доступе к данным растра BufferedImage, картинка перестает рисоваться через GPU.
Не при доступе, а при изменении данных связанный VolatileImage перестает быть валидным до тех пор, пока BufferedImage не отрисуется заново. Поэтому, если растр часто меняется, лучше сразу пользоваться VolatileImage. Единственная деталь — VolatileImage не гарантирует сохранность данных и в любой момент может быть очищет видеокартой.

> Нет встроенной анимации и полу-прозрачности.
Есть (был) проект SwingX, который расширял компоненты, добавляя дополнительные возможности по отрисовке (Painter).
>Один вопрос: а почему Вы не выбрали архитектуру веб клиента? Например Embedded Jetty + GWT/SmartGWT или Vaadin?
Мое мнение: пакетная обработка графики и веб плохо уживаются. Гонять туда-сюда гигабайты файлов: терять время и дорого платить за трафик.

>Я не знаю почему так получается, но свинговый интерфейс любой апликации лагает.
Может вам такие приложения попадались? Например, отзывчивость интерфейса не была приоритетом при разработке? Для бухгалтера не важно, а ведь надо время потратить, вынести часть обработки в отдельный поток…

>во всех системах была заменена декларативным описанием дерева объектов как JavaFX, SVG, HTML
Не могу согласиться, что во ВСЕХ и что декларативное описание дерева — ВСЕГДА хорошо. Например, на дерево объектов очень плохо ложатся интерфейсы с огромным количеством записей. Приходится идти на хитрости с виртуализацией объектов и урезанием пересчета дерева. И даже со всеми ухищрениями не получается достичь производительности императивной отрисовки. Для примера можете поскролить какой-нибудь TableView/Grid на WPF и сравнить его с WinForms, QT или Delphi.
Насчет во ВСЕХ системах даже и не знаю что сказать. На память только WinRT приходит.

> нет нормального LAF. Мимикрия под системные просто ужасна.
Нативный L&F в JDK 6 был просто замечательный: составные кнопки, выплывающие модальные окна — все это было. В JDK 7 несколько поломали.

>Поскольку разработчик сам пишет код отрисовки компонентов, то он ответственен за то, чтобы акселерация использовалась по-максимому.
Не понял этого высказывания. Приведете пример?

> Так что swing работает и на машинах без акселерации, и на remote
Это верно только для Win. Swing не работает без ускорителя на Mac и поэтому не работает под виртуалками и удаленном доступе.

>Не при доступе, а при изменении данных связанный VolatileImage перестает быть валидным до тех пор, пока BufferedImage не отрисуется заново.
Нет. В текущей реализации OpenJDK 7 растр перестает быть ускоренным навсегда.
> Мое мнение: пакетная обработка графики и веб плохо уживаются. Гонять туда-сюда гигабайты файлов: терять время и дорого платить за трафик.
Я не совсем про это. Сервер запускать именно локально а ГУИ рисовать в браузере. При желании все это можно сделать в один клик по иконке: запускается сервер и встроенный в окно браузер без URLя, вкладок и меню. Количество библиотек с виджетами для веба зашкаливает. Взять хотя бы SmartClient или ExtJS. Для любителей Java есть врапперы для GWT. Кроме того, битмапы и императивную графику можно рисовать на Canvas.

> Может вам такие приложения попадались? Например, отзывчивость интерфейса не была приоритетом при разработке?
Нет, это общее впечатление многих пользователей от любого свинг-интерфейса. Netbeans/Idea ощутимо лагают, интерфейс Eclipse более тормозной, но ощущения лагания нет. Еще тормознутость многих апликаций хорошо заметна, когда меняешь лейаут, например тащя JSplitPane. Лейаут в свинге пересчитывается крайне долго, и еще дольше, если количество объектов достаточно большое.

> Нативный L&F в JDK 6 был просто замечательный
Я пришел из тех времен, когда LAF был Metal и Basic. С грехом пополам сделали мимикрию под XP. Потом под Висту с опозданием на год. Последним запилили Nimbus, который ужасен. Сторонние LaF были еще ничего (Alloy, Plastic). В последние годы высказывались идеи по поводу адаптивных лейаутов: это когда например Label выравнивается по font baseline с текстом в следующем TextField, или когда автоматически отключаются бордеры внутри других контейнеров с бордерами. В Substance LaF были потуги на этот счет. Но массово все это так и не было доведено до ума.

> Например, на дерево объектов очень плохо ложатся интерфейсы с огромным количеством записей.
Согласен. С деревом MVC реализовывать неудобно. Но можно. Html, Windows, SWT живут как-то с обычными таблицами, не MVC. Строки для huge-таблицы можно генерить динамически при скроллинге даже в модели с деревом.

> И даже со всеми ухищрениями не получается достичь производительности императивной отрисовки.
А вот здесь не согласен. Умный рендерер может эффективно отсекать невидимые узлы дерева, плюс автоматически делать оптимизации рендеринга: статичное поддерево может быть прозрачно закешировано в виде битмапа. Плюс такие плюшки как декларативная анимация, лееры, эффекты, аффинные преобразования, фильтры, etc… Кроме того, декларативный рендерер позволяет использовать композитные возможности низлежащей платформы (OpenGL, DirectX): лееры и Z-order компонентов могут управляються нативно, тогда как в Swing их каждый раз всех приходится перерисовывать в правильном порядке на канве Graphics2D. Ну и самое главное — асинхронный рендеринг отдельно от Event Dispatch.

> Не понял этого высказывания. Приведете пример?
Рисуя что-то ручками в Graphics2D постоянно приходилось профилировать и думать как это лучше оптимизировать. Большинство оптимизаций сводилось к банальному битмап-кешированию сложных отрисовок, что декларативный рендерер делает автоматически. Другая рекомендуемая оптимизация — брать из Graphics2D clip-регион и не рендерить объекты, которые находятся за его пределами. И еще over 9000 рекомендаций. И все ручками.
>Я не совсем про это. Сервер запускать именно локально а ГУИ рисовать в браузере.
Можно было бы. Crome Embedded Framework, использовать, например. Как советовал alist. Причины субъективные: у меня мало опыта с html и js, мне удобнее, когда опечатки выявляются на этапе компиляции и я люблю строгую типизацию.

>Лейаут в свинге пересчитывается крайне долго, и еще дольше, если количество объектов достаточно большое.
Пожалуй. У меня в приложении осознано нет форм на 20+ полей.

>Умный рендерер может эффективно отсекать невидимые узлы дерева
Я таких не знаю, к сожалению. Писал для WPF и Silverlight. Там он не такой «умный»

>Рисуя что-то ручками в Graphics2D постоянно приходилось профилировать
Эта информация уже устарела. Сейчас можно делать плавную анимацию на полный экран. Главное, чтобы EDT был не загружен:-)
Вспомнил здоровое Swing приложение, которое не лагает:) Intellij IDEA. 12ая версия у мена замечательно ресайзится и пересчитывает лейаут. А скроллинг кода быстрее, чем в Eclipse, который написан на SWT.
Кстати, спасибо за Juce — я про него не знал. Надо будет пощупать. Благо он опенсорс.
Only those users with full accounts are able to leave comments. Log in, please.

Articles