Статьи

Интеграция JavaFX и Swing

Я только что закончил переписывать компонент моего приложения, который использовал Swing, а теперь использует JavaFX, в результате я получил компонент JavaFX, который интегрируется с большим приложением Swing. Это большое приложение, и переписывание заняло у меня некоторое время, в конце концов, все работало нормально, и я рад, что сделал это.

Почему вы можете захотеть сделать это в своем приложении

Возможно, вы захотите переписать свое приложение Swing и изменить его на использование JavaFX. Самый простой способ — сделать это постепенно, меняя каждый компонент за раз. Для этого необходимо интегрировать каждый из недавно измененных компонентов JavaFX с остальным приложением Swing.

Я резюмирую, почему вы можете начать переписывать свое приложение с Swing на JavaFX:

  • Это будущее

    Swing в значительной степени мертв в том смысле, что он не получит дальнейшего развития. JavaFX — это новый инструментарий пользовательского интерфейса для Java, он лучше подготовлен к будущему с такими вещами, как сенсорная поддержка, 3D, встроенная поддержка анимации, воспроизведение видео и аудио и т. Д.

  • Вероятная будущая поддержка мобильных устройств: Android, IOS…

    Из того, что я видел, я думаю, что это в значительной степени гарантия того, что поддержка Android, IOS и т. Д. Будет доступна, у Oracle уже есть рабочие прототипы этого, которые они показывают на публичных конференциях, единственный вопрос — когда. Я думаю, что это не займет много времени, возможно, мы увидим больше об этом в следующем JavaOne, который скоро появится.

  • Это твердое тело

    JavaFX — это хорошо разработанный инструментарий с быстро растущим темпом, блестящим будущим и набором хороших бесплатных инструментов для пользовательского интерфейса. Кроме того, в отличие от прошлого, Oracle придает большое значение обратной связи с разработчиками, изменяя и адаптируя свои API для достижения своих целей.

  • Это довольно

    В отличие от Swing, не считая сторонних библиотек, что само по себе было некрасиво, JavaFX выглядит хорошо с самого начала. Учитывая, что в настоящее время пользователи ожидают хорошо выглядящих хорошо разработанных приложений, это довольно хороший момент.

  • Приятные дополнения

    Некоторые приятные дополнения, такие как API диаграмм, встроенный браузер с поддержкой HTML5 и т. Д.

Как ты это делаешь

Вернувшись к JavaFX 1.3, вы можете встроить Swing в JavaFX, но не наоборот, по крайней мере, официально. Я реализовал компонент Swing, который позволил вам встраивать содержимое JavaFX в Swing (называемое JXScene) и сделал его общедоступным в проекте jfxtras. Это был единственный способ встроить сцену JavaFX в приложение Swing.

Теперь Oracle с JavaFX 2.X сделал официальный способ встраивания JavaFX в Swing, который имеет больше смысла, но, к сожалению, не является способом встраивания Swing в JavaFX, однако, я думаю, этого будет достаточно в большинстве случаев.

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.
    }
});


подсказки

  1. JavaFX уже генерирует исключения, когда вы обращаетесь к ресурсу JavaFX за пределами пользовательского потока JavaFX, но имейте в виду, что это не всегда происходит. Чтобы минимизировать затраты производительности, проверяются не все ситуации.
  2. Если вы используете стороннюю библиотеку Substance, то исключение также будет генерироваться при каждом доступе к ресурсу Swing вне EDT. Настройка Substance в качестве внешнего вида Swing может быть хорошим решением для уменьшения количества ошибок параллелизма на стороне Swing, которые вы могли бы совершить.
  3. Будьте очень осторожны при совместном использовании ресурсов между двумя потоками пользовательского интерфейса, старайтесь избегать этого в максимально возможной степени. Лучший способ решить проблемы с многопоточностью — это избегать их, и такие проблемы являются одними из самых трудных для решения в программной инженерии. Существует причина, по которой Swing начинал как многопоточный инструментарий и заканчивал переходом на однопоточный.
  4. Иногда вам может потребоваться проверить, находитесь ли вы в пользовательском потоке JavaFX через Platform.isFxApplicationThread() и только runLater(...) вызываете Platform.runLater(…) , потому что если вы находитесь в пользовательском runLater(...) JavaFX и вызываете runLater(...) выполнение кода, который находится внутри, все еще будет отложено до более позднего времени, и это может быть не тем, что вы хотите.

Другие ссылки, чтобы проверить:

Ссылка: Интеграция JavaFX и Swing от нашего партнера JCG Педро Дуке Виейры в блоге Pixel Duke .