I'm currently working on a desktop application using JavaFX (Please note that I'm not using the Screen Builder, I create my view directly in the coding). I would like to implement the Passive View variant of the MVP (Model View Presenter) pattern.
As I could not find any clear examples.. I tried to create a basic setup by myself.
Main Classs
public class Main extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) throws Exception {
Model model = new Model();
View view = new View(stage);
Presenter presenter = new Presenter(model, view);
}
}
Model
public class Model {
private StringProperty labelText;
public Model() {
this.labelText = new SimpleStringProperty();
}
public String getLabelText() {
return labelText.get();
}
public StringProperty labelTextProperty() {
return labelText;
}
public void setLabelText(String labelText) {
this.labelText.set(labelText);
}
}
View
public class View {
private Button button;
private Label label;
public View(Stage stage) {
label = new Label("This is a test");
label.setLayoutX(50);
label.setLayoutY(50);
button = new Button("Click me");
button.setLayoutX(200);
button.setLayoutY(50);
Pane pane = new Pane();
pane.getChildren().addAll(label, button);
Scene scene = new Scene(pane, 400, 200); //Standard size 1200, 800
stage.setScene(scene);
stage.show();
}
public Button getButton() {
return button;
}
public void setButton(Button button) {
this.button = button;
}
public Label getLabel() {
return label;
}
public void setLabel(Label label) {
this.label = label;
}
}
Presenter
public class Presenter implements EventHandler<ActionEvent> {
private Model model;
private View view;
public Presenter(Model model, View view) {
this.model = model;
this.view = view;
//Register action listener for button
this.view.getButton().setOnAction(this);
//Register change listeners of model
this.model.labelTextProperty().addListener(new ChangeListener<String>() {
@Override
public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
//Update view
}
});
}
@Override
public void handle(ActionEvent event) {
if (event.getSource() == this.view.getButton()) {
//Update model
}
}
}
I thought the following things should be considered when implementing a passive view pattern:
- Model and View are completely separated
- View creates and displays only the UI elements
- Model contains the data of the application and the logic to change this data
- Presenter updates the model as well as the view
- Presenter registers action event listeners and updates the model if required (View -> Presenter -> Model)
- Presenter listens to changes of the model and updates the view if required (Model -> Presenter -> View)
Using these information, I tried to build this basic structure for a model-view-presenter setup. Did I implement the passive view correctly?