JacpFX — это инфраструктура RCP, основанная на JavaFX, которая помогает разработчикам структурировать приложение со слабосвязанными, повторно используемыми компонентами, а DataFX-flow — это API, который позволяет определять потоки между контроллерами и представлениями в JavaFX.
Оба проекта разрабатывались независимо, и пока я разрабатывал приложение JacpFX, я осознал отсутствие поддержки потоков. Интеграция простого потока DataFX в JacpFX была довольно простой, компонент JacpFX представляет собой контроллер с представлением FXML или простым представлением JavaFX; с другой стороны, FlowHandler потока DataFX возвращает StackPane, который легко интегрировать в текущее представление. Недостатком этого простого решения является изоляция контекста вашего потока DataFX от контекста JacpFX, что означает, что они не имеют прямого доступа друг к другу.
В JavaOne у меня была возможность провести час с Хендриком Эбберсом (одним из коммиттеров DataFX) и создать для этого решение. Получающийся плагин JacpFX / DataFX-flow позволяет вам внедрять контекст JacpFX определенного компонента в контроллеры потока DataFX. Это позволяет контроллерам потока DataFX взаимодействовать через шину сообщений JacpFX с остальной частью приложения JacpFX. Помимо этого, контроллер потока DataFX получает доступ к пакетам ресурсов и другим методам / ресурсам компонента JacpFX.
Чтобы продемонстрировать использование обеих платформ, я создал простой пример приложения, основанный на следующих шагах:
Создайте приложение JacpFX из архетипа:
JacpFX предоставляет простой архетип с двумя примерами перспективы (представление FXML + JavaFX) и двумя компонентами, повторно используемыми в обеих перспективах. Для создания базового приложения JacpFX используйте простой архетип:
mvn archetype:generate -DarchetypeGroupId=org.jacpfx -DarchetypeArtifactId=JacpFX-simple-quickstart -DarchetypeVersion=2.0.2
Для интеграции плагина DataFX-flow добавьте следующую зависимость к вашему pom:
<dependency> <groupId>org.jacpfx</groupId> <artifactId>jacpfx.JavaFXDataFXPlugin</artifactId> <version>1.0</version> <scope>compile</scope> </dependency>
Создать простой поток между двумя контроллерами потока DataFX
Теперь мы создаем два контроллера потока DataFX, WizardStartController и Wizard1Controller. Wizard1Controller будет содержать контекст JacpFX и включать текстовое поле, ввод текста будет отправляться через сообщения в компонент JacpFX. Контроллер будет выглядеть так:
@FXMLController(value="/fxml/wizard1.fxml", title = "Wizard: Step 1") public class Wizard1Controller { @FXML @ActionTrigger("back") private Button backButton; @FXML @ActionTrigger("next") private Button nextButton; /** ** The JacpFX context **/ @Resource private Context context; @FXML private TextField name; @PostConstruct public void init() { nextButton.setDisable(true); name.setOnKeyReleased(event->{ context.send(BasicConfig.COMPONENT_BOTTOM, name.getText()); }); } }
Интегрировать поток DataFX в компонент JacpFX
Чтобы иметь возможность внедрить контекст JacpFX в контроллер потока DataFX, я создал потоковую
оболочку DataFX, которая дополнительно принимает идентификатор компонента JacpFX, контекст которого должен быть введен. Использование потока DataFX
точно такое же, поэтому мы создаем
FlowHandler и получаем корневой узел потока DataFX при запуске
FlowHandler . Корневой узел теперь может быть включен в ваше представление компонентов JacpFX.
@View(id = BasicConfig.COMPONENT_TOP, name = "SimpleView", resourceBundleLocation = "bundles.languageBundle", initialTargetLayoutId = BasicConfig.TARGET_CONTAINER_TOP) public class ComponentLeft implements FXComponent { private Node pane; @Resource private Context context; @Override public Node handle(final Message<Event, Object> message) { // runs in worker thread return null; } @Override public Node postHandle(final Node arg0, final Message<Event, Object> message) { // runs in FX application thread return this.pane; } @PostConstruct public void onPostConstructComponent(final FXComponentLayout arg0, final ResourceBundle resourceBundle) { this.pane = createUI(); } private Node createUI() { final VBox main = new VBox(); Flow flow = new DataFXFlowWrapper(WizardStartController.class,BasicConfig.COMPONENT_TOP). withLink(WizardStartController.class, "next", Wizard1Controller.class). withGlobalBackAction("back"); FlowHandler flowHandler = flow.createHandler(); StackPane pane = null; try { pane = flowHandler.start(new AnimatedFlowContainer(Duration.millis(320), ContainerAnimations.ZOOM_IN)); main.getChildren().add(pane); } catch (FlowException e) { e.printStackTrace(); } return main; } }
Для запуска JacpFX и DataFX-потока требуется Java 8 / JavaFX 8, упакованный jar можно скачать здесь: http://jacpfx.org/data/SimpleDataFX_JacpFX.jar , просто выполните:
java -jar SimpleDataFX_JacpFX.jar
Источник этого примера приложения можно найти здесь:
Основные сведения о потоке данных можно найти в блоге Хендрика здесь:
http://www.guigarage.com/2014/05/datafx-8-0-tutorials/