Reputation: 25
i am new to this java/javafx stuff and i would be very pleased if somebody could help me out of this.
i have the following code :
// Main.java
package lernen;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Main extends Application
{
@Override
public void start(Stage primaryStage)
{
Presenter p = new Presenter();
View v = new View(p);
Model m = new Model();
p.setModel(m);
p.setView(v);
Scene scene = new Scene(v.getUI());
primaryStage.setTitle("Schiebefenster");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args)
{
launch(args);
}
}
// View.java
package lernen;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.layout.GridPane;
public class View
{
private Presenter presenter;
private GridPane pane;
private Button b1, b2;
private Label l1, l2;
// private ObservableList<String> candidates = FXCollections.observableArrayList("a", "b", "c", "d");
private ObservableList<String> candidates = FXCollections.observableArrayList();
private ListView<String> list = new ListView<>(candidates);
private ObservableList<String> selected = FXCollections.observableArrayList();
private ListView<String> list2 = new ListView<>(selected);
public View(Presenter presenter)
{
this.presenter = presenter;
initView();
}
private void initView()
{
pane = new GridPane();
pane.setVisible(true);
l1 = new Label("Buchstabe");
pane.add(l1, 0, 0);
l2 = new Label("Selektiert");
pane.add(l2, 4, 0);
b1 = new Button("<");
pane.add(b1, 2, 2);
b2 = new Button(">");
pane.add(b2, 2, 3);
// list = new ListView<String>();
pane.add(list, 0, 1, 2, 5);
// list2 = new ListView<>();
pane.add(list2, 4, 1, 2, 5);
b2.setOnAction((ActionEvent) -> {
String potential = list.getSelectionModel().getSelectedItem();
if (potential != null)
{
list.getSelectionModel().clearSelection();
candidates.remove(potential);
selected.add(potential);
}
});
b1.setOnAction((ActionEvent) -> {
String selectedItem = list2.getSelectionModel().getSelectedItem();
if (selectedItem != null)
{
list2.getSelectionModel().clearSelection();
selected.remove(selectedItem);
candidates.add(selectedItem);
}
});
}
public GridPane getUI()
{
return pane;
}
public ListView<String> getList()
{
return list;
}
public ListView<String> getList2()
{
return list2;
}
}
// Presenter.java
package lernen;
public class Presenter
{
private View view;
private Model model;
public Presenter()
{
}
public void setView(View view)
{
this.view = view;
this.view.getList().setItems(model.getData());
}
public void setModel(Model model)
{
this.model = model;
}
}
// Model.java
package lernen;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
public class Model
{
private ObservableList<String> data = FXCollections.observableArrayList();
public Model()
{
data.addAll("a", "b", "c", "d", "e");
}
public ObservableList<String> getData()
{
return data;
}
}
The given task is to move a item from the left list to the right and vice versa according to the MVP pattern. The problem is: If i move one letter to the right side, the letter on the left side is still there. I hope u guys can help me with this. Thanks in advance!
Upvotes: 0
Views: 1911
Reputation: 21809
In the presenter you call
this.view.getList().setItems(model.getData());
so the list will display the items defined in the ObservableList
of the model, therefore, when in the event handler of b2
you call
candidates.remove(potential);
you actually try to remove the item from a different list (which is actually empty).
I guess the confusion comes from the following:
You defined an ObservableList
, and you assigned this list to serve as the data model of your ListView
.
private ObservableList<String> candidates = FXCollections.observableArrayList();
private ListView<String> list = new ListView<>(candidates);
and then when in the controller you called
this.view.getList().setItems(model.getData());
you thought that, this will fill the candidates
ObservableList
with the elements of the ObservableList
stored in the model (all of them elements from the list in the model will be copied to this list). But, when you call setItems
, you set the reference stored in the itemsProperty to be specified ObservableList
, therefore it will point to the ObservableList
stored in the model and no longer to candidates
.
You can modify this line to:
this.view.getList().getItems().addAll(model.getData());
The difference is, that in this case getItems()
will return the ObservableList
stored in the itemsProperty
and then all of the elements are copied from the model to this list, but it will still point to candidates
. In this case the ObservableList
in the model is not touched.
Or alternatively you can change your listeners as:
view.getList2().getItems().remove(selectedItem);
which will remove the element from the ObservableList
in your model also.
The situation is basically the same as here: Why does JavaFX table.getItems().clear() clear the ObservableList as well
Upvotes: 2
Reputation: 25
// presenter.java
package lernen;
public class Presenter
{
private View view;
private Model model;
public Presenter()
{
}
public void setView(View view)
{
this.view = view;
this.view.getList().setItems(model.getData());
}
public void setModel(Model model)
{
this.model = model;
}
public void RightToLeft() {
System.out.println("RightToLeft triggered.");
String selectedItem = view.getList2().getSelectionModel().getSelectedItem();
if (selectedItem != null)
{
view.getList2().getSelectionModel().clearSelection();
view.getList2().getItems().remove(selectedItem);
view.getList().getItems().add(selectedItem);
}
}
public void LeftToRight() {
System.out.println("LeftToRight triggered.");
String selectedItem = view.getList().getSelectionModel().getSelectedItem();
if (selectedItem != null)
{
view.getList().getSelectionModel().clearSelection();
view.getList().getItems().remove(selectedItem);
view.getList2().getItems().add(selectedItem);
}
}
}
// view.java
package lernen;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.layout.GridPane;
public class View
{
private Presenter presenter;
private GridPane pane;
private Button b1, b2;
private Label l1, l2;
private ObservableList<String> candidates = FXCollections.observableArrayList();
private ListView<String> list = new ListView<>(candidates);
private ObservableList<String> selected = FXCollections.observableArrayList();
private ListView<String> list2 = new ListView<>(selected);
public View(Presenter presenter)
{
this.presenter = presenter;
initView();
}
private void initView()
{
pane = new GridPane();
pane.setVisible(true);
l1 = new Label("Buchstabe");
pane.add(l1, 0, 0);
l2 = new Label("Selektiert");
pane.add(l2, 4, 0);
b1 = new Button("<");
pane.add(b1, 2, 2);
b2 = new Button(">");
pane.add(b2, 2, 3);
list = new ListView<String>();
pane.add(list, 0, 1, 2, 5);
list2 = new ListView<>();
pane.add(list2, 4, 1, 2, 5);
b1.setOnAction(e -> presenter.RightToLeft());
b2.setOnAction(e -> presenter.LeftToRight());
}
public GridPane getUI()
{
return pane;
}
public ListView<String> getList()
{
return list;
}
public ListView<String> getList2()
{
return list2;
}
}
Upvotes: 0