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/