I would like to know a best practise for a JavaFX application which has many views. I'm using the MVC pattern. On the views it should be possible that the user can add/edit/delete model data of the connected view. Let's assume the scenario with a left side button navigation menu where it's possible to set the center area of a BoraderPane layout (See picture).
Start view of a simple example application
When I switch the view and come back to the counter view, then the counter value is not shown anymore. With the solution below, I the FXMLLoader loads the fxml file and also a new controller instance, so the data which were set before are lost. At the moment the counter value is implemented in the controller, but in a later stage (when know a way how to relate the Model with it's controller) I would like to store it in a CounterModel. Ofc this is a simple example, the real application has many views and also more models which need to be organized in the way that the model is connected to the right controller.
The questions would be:
Where is the best location to store view depending data for a view, where the data only belongs to one single particular view and how can I make sure that the model is connected to it's controller again? (Maybe there is also another way where it's not possible to delete the controller instance after leaving the view???)
(is not part of the application above, but related to this topic) what is the best practise to filter a data source (Model) which holds an array of objects to show filtered data on different views?
Here is the code for the above application:
Below Code for MainApplication.java:
public class MainApplication extends Application {
@Override
public void start(Stage stage) throws IOException {
FXMLLoader fxmlLoader = new FXMLLoader(MainApplication.class.getResource("main-
view.fxml"));
Scene scene = new Scene(fxmlLoader.load(), 300, 100);
stage.setTitle("Example");
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch();
}
}
Code for MainController.java:
public class MainController implements Initializable {
@FXML
private BorderPane mainPane;
@FXML
protected void onSwitchViewButtonClick(ActionEvent event) throws IOException {
FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setLocation(getClass().getResource("/src/main/resources/com/example/demo/counter-view.fxml"));
AnchorPane counterViewScene = fxmlLoader.load();
mainPane.setCenter(counterViewScene);
}
@FXML
void onStartViewButtonClick(ActionEvent event) throws IOException {
FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setLocation(getClass().getResource("/src/main/resources/com/example/demo/start-view.fxml"));
AnchorPane counterViewScene = fxmlLoader.load();
mainPane.setCenter(counterViewScene);
}
@Override
public void initialize(URL location, ResourceBundle resources) {
FXMLLoader fxmlLoader = new FXMLLoader();
fxmlLoader.setLocation(getClass().getResource("/src/main/resources/com/example/demo/start-view.fxml"));
AnchorPane counterViewScene = null;
try {
counterViewScene = fxmlLoader.load();
} catch (IOException e) {
e.printStackTrace();
}
mainPane.setCenter(counterViewScene);
}
}
Code for CounterView.java:
public class CounterView {
private Integer counter=0;
@FXML
private Label labelCounterValue;
@FXML
void onIncrementButtonClick(ActionEvent event) {
counter++;
labelCounterValue.setText(counter.toString());
}
}