I'm using afterburner fx the DI-framework.
My problem is, that I have a "RootLayout" which is a BorderPane. On the top is a MenueBar, which works and in the center I loaded an other pane on startup. Now I want to be able to click on a button, so that the Center-Pane changes to a new View AND I want to pass a value to the new View/Controller.
My main class:
@Override
public void start(Stage primaryStage) throws Exception {
initInjector();
//BorderPane
RootView appView = new RootView();
Scene scene = new Scene(appView.getView());
primaryStage.setTitle("Personalplanung");
primaryStage.setScene(scene);
primaryStage.show();
}
Controller/Presenter of my Root
public class RootPresenter implements Initializable {
@FXML
private AnchorPane center;
/**
* Initializes the controller class.
*/
@Override
public void initialize(URL url, ResourceBundle rb) {
MainView view = new MainView();
center.getChildren().add(view.getView());
}
//Doesn't work because it must be static -> AnchorPane can't be static
public void putCenter(FXMLView fxmlView) {
center.getChildren().add(fxmlView.getView());
}
Presenter of the view I want to change to and pass value (e.g. selected person)
public class MainPresenter implements Initializable {
@Inject
PersonService personService;
/**
* Initializes the controller class.
*/
@Override
public void initialize(URL url, ResourceBundle rb) {
}
/**
* Pseudo display of all persons
* should switch here to PersoView and pass values
* gets triggerd by button click
*/
@FXML
private void handlePersonsOverview() {
personService.all().forEach(person -> {
System.out.println(person.getVorname());
});
}
All my views are empty but extend the FXMLView (is convention)
import com.airhacks.afterburner.views.FXMLView;
public class PersonView extends FXMLView{
}
If I understand your structure correctly, I think you can solve this with a ViewModel
:
public class ViewModel {
private final ObjectProperty<Node> mainView = new SimpleObjectProperty(this, "mainView", null);
public ObjectProperty<Node> mainViewProperty() {
return mainView ;
}
public final Node getMainView() {
return mainView.get();
}
public final void setMainView(Node mainView) {
this.mainView.set(mainView);
}
}
Now just inject the ViewModel
wherever you need it. Bind the center of the root to the view model's mainView property, and update the mainView property from your other presenters:
public class RootPresenter {
@FXML
private BorderPane root ; // I think you have this?
@FXML
private AnchorPane center ; // possibly no longer need this?
@Inject
private ViewModel viewModel ;
public void initialize() {
root.centerProperty().bind(viewModel.mainViewProperty());
MainView view = new MainView();
viewModel.setMainView(view.getView());
}
}
Now any presenter that needs to change the center of your root just needs to do:
public class SomePresenter {
@Inject
private ViewModel viewModel ;
@FXML
public void someHandlerMethod() {
SomeView someView = new SomeView();
viewModel.setMainView(someView.getView());
}
}
To pass values to the new presenter, just define the appropriate properties and methods in the presenter and invoke them when you create the new view:
public class MainPresenter {
private final ObjectProperty<Person> person = new SimpleObjectProperty<>(this, "person") ;
public ObjectProperty<Person> personProperty() {
return person ;
}
public final Person getPerson() {
return person.get();
}
public final void setPerson(Person person) {
this.person.set(person);
}
public void initialize() {
// bind to person as needed ...
// other stuff as before
}
// ...
}
and then you can do
MainView mainView = new MainView();
MainPresenter mainPresenter = (MainPresenter) mainView.getPresenter();
mainPresenter.setPerson(selectedPerson);