Я только что закончил переписывать компонент моего приложения, который использовал Swing, а теперь использует JavaFX, в результате я получил компонент JavaFX, который интегрируется с большим приложением Swing. Это большое приложение, и переписывание заняло у меня некоторое время, в конце концов, все работало нормально, и я рад, что сделал это.
Причины, по которым вы можете захотеть сделать это в своем приложении Swing
Возможно, вы захотите переписать свое приложение Swing и изменить его на использование JavaFX. Самый простой способ — сделать это постепенно, меняя каждый компонент за раз. Для этого необходимо интегрировать каждый из недавно измененных компонентов JavaFX с остальным приложением Swing.
Я резюмирую, почему вы можете начать переписывать свое приложение с Swing на JavaFX:
- Это будущее
Swing в значительной степени мертв в том смысле, что он не получит дальнейшего развития. JavaFX — это новый инструментарий пользовательского интерфейса для Java, он лучше подготовлен к будущему с такими вещами, как сенсорная поддержка, 3D, встроенная поддержка анимации, воспроизведение видео и аудио и т. Д.
- Вероятная будущая поддержка мобильных устройств: Android, IOS…
Уже существует работающий прототип, который позволяет переносить приложения javafx на IOS под названием RoboVM — http://www.robovm.org/ . По мере того, как все больше и больше JavaFX будут открываться с открытым исходным кодом, RoboVM получит лучший результат, и с этим открытым исходным кодом, вероятно, появятся другие утилиты, которые позволят порты для других сред.
- Это твердое тело
JavaFX — это хорошо разработанный инструментарий с быстро растущим темпом, блестящим будущим и набором хороших бесплатных инструментов для пользовательского интерфейса. Кроме того, в отличие от прошлого, Oracle придает большое значение обратной связи с разработчиками, изменяя и адаптируя свои API для достижения своих целей.
- Это довольно
В отличие от Swing, не считая сторонних библиотек, что само по себе было некрасиво, JavaFX выглядит хорошо с самого начала, особенно новый скин Modena, выходящий на JavaFX 8: http://fxexperience.com/2013/03/modena-theme-update / -. Учитывая, что в наше время пользователи ожидают хорошо выглядящих, хорошо разработанных приложений, это довольно хороший момент.
- Приятные дополнения
Некоторые приятные дополнения, такие как API диаграмм, встроенный браузер с поддержкой HTML5 и т. Д.
Как ты это делаешь
Вернувшись к JavaFX 1.3, вы можете встроить Swing в JavaFX, но не наоборот, по крайней мере, официально. Я реализовал компонент Swing, который позволил вам встраивать содержимое JavaFX в Swing (называемое JXScene) и сделал его общедоступным в проекте jfxtras. Это был единственный способ встроить сцену JavaFX в приложение Swing.
Теперь Oracle с JavaFX 2.X сделал официальный способ встраивания JavaFX в Swing, который имеет больше смысла, но, к сожалению, не является способом встраивания Swing в JavaFX, я думаю, этого будет достаточно в большинстве случаев. Однако с выходом JavaFX 8 у вас также будет возможность встраивать компонент Swing в приложение JavaFX с помощью Swing Node.
ARQUITECTURE
По сути, когда вы встраиваете JavaFX в Swing, вы получаете 2 работающих потока пользовательского интерфейса: поток Swing EDT и поток пользователя JavaFX.
Существует вероятность того, что в будущем будет только один поток для обоих, как в случае с SWT, что заставит Swing работать в пользовательском потоке JavaFX, но сейчас нам придется управлять нашим способом с двумя потоками.
Два потока, выполняющиеся одновременно в пользовательском интерфейсе, — вот что усложняет ситуацию и делает интеграцию JavaFX не так легко, как вы могли бы ожидать, если только вы не создаете какое-то тривиальное небольшое приложение, но я полагаю, что это не сценарий для большей части реального мира случаи применения. Если вы делаете небольшое приложение, то можете сделать все это в JavaFX.
КОДИРОВАНИЕ
JavaFX предоставляет вам JFXPanel, которая представляет собой панель Swing, на которой размещена сцена JavaFX. Вы устанавливаете сцену на JFXPanel и добавляете панель везде, где вы можете добавить компонент Swing.
Для доступа к данным JavaFX вы должны обернуть ваш код в объект Runnable и вызвать метод Platform.runLater
:
01
02
03
04
05
06
07
08
09
10
|
jbutton.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { Platform.runLater( new Runnable() { @Override public void run() { fxlabel.setText( "Swing button clicked!" ); } }); } }); |
На другой стороне находятся данные Swing. Эти данные должны быть доступны только EDT. Чтобы убедиться, что ваш код выполняется в EDT, оберните его в объект Runnable и вызовите SwingUtilities.invokeLater
:
1
2
3
4
5
6
|
SwingUtilities.invokeLater( new Runnable() { @Override public void run() { //Code to change Swing data. } }); |
подсказки
- JavaFX уже генерирует исключения, когда вы обращаетесь к ресурсу JavaFX за пределами пользовательского потока JavaFX, но имейте в виду, что это не всегда происходит. Чтобы минимизировать затраты производительности, проверяются не все ситуации.
- Если вы используете Substance (по моему мнению, без сомнения, лучше всего выглядящий свободно и непринужденно), сторонняя библиотека, кроме исключения, будет также выброшена при каждом обращении к ресурсу Swing вне EDT. Настройка Substance в качестве внешнего вида Swing может быть хорошим решением для уменьшения количества ошибок параллелизма на стороне Swing, которые вы могли бы совершить.
- Будьте очень осторожны при совместном использовании ресурсов между двумя потоками пользовательского интерфейса, старайтесь избегать этого в максимально возможной степени. Лучший способ решить проблемы с многопоточностью — это избегать их, и такие проблемы являются одними из самых трудных для решения в программной инженерии. Существует причина, по которой Swing начинал как многопоточный инструментарий и заканчивал переходом на однопоточный.
- Иногда вам может потребоваться проверить, находитесь ли вы в пользовательском потоке JavaFX через
Platform.isFxApplicationThread()
и толькоrunLater(...)
вызываетеPlatform.runLater(…)
, потому что если вы находитесь в пользовательскомrunLater(...)
JavaFX и вызываетеrunLater(...)
выполнение кода, который находится внутри, все еще будет отложено до более позднего времени, и это может быть не тем, что вы хотите. - Существует множество элементов управления JavaFX, которые охватывают их аналог Swing, однако они отличаются и имеют разные функции, к которым вы должны адаптироваться. Есть также некоторые элементы управления, такие как JFormattedTextField, которые еще не существуют. В заключение, JavaFX отличается от Swing. Имеет разные элементы управления и другую архитектуру и API, к которым вы должны адаптироваться.
Другие ссылки, чтобы проверить:
- Руководство по Oracle: http://docs.oracle.com/javafx/2/swing/jfxpub-swing.htm