2016-07-15 53 views
0

我是新来这个java/javafx的东西,我会很高兴,如果有人可以帮助我这个。JavaFX - 移动ListView项目 - MVC

我有以下代码:

// 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; 
    } 

} 

给定的任务是根据MVP模式将项目从左侧列表移动到右侧,反之亦然。问题是:如果我将一个字母移到右侧,左侧的字母仍然存在。我希望你们能帮助我。 在此先感谢!

回答

1

在主持人打电话

this.view.getList().setItems(model.getData()); 

这样的列表将显示模型的ObservableList定义的项目,因此,当在b2事件处理程序调用

candidates.remove(potential); 

你实际上试图从不同的列表中删除该项目(实际上是空的)。

我猜的混乱来自于以下几个:

您定义的ObservableList,你分配这个列表作为你的ListView的数据模型。

private ObservableList<String> candidates = FXCollections.observableArrayList(); 
private ListView<String> list = new ListView<>(candidates); 

,然后当控制器,你叫

this.view.getList().setItems(model.getData()); 

你认为,这将填补candidatesObservableList与存储在模型中ObservableList的元素(它们都根据列表元素在模型中将被复制到这个列表中)。但是,当您拨打setItems时,您将存储在itemsProperty中的参考值设置为ObservableList,因此它将指向存储在模型中的ObservableList,而不再指定为candidates

您可以修改此行:

this.view.getList().getItems().addAll(model.getData()); 

不同的是,在这种情况下getItems()将返回存储在itemsProperty,然后所有的元素都从模型复制到该列表中ObservableList,但它仍会指向candidates。在这种情况下,模型中的ObservableList未触及。

或者你也可以改变你的听众为:

view.getList2().getItems().remove(selectedItem); 

这也将删除从ObservableList元素在你的模型。

情况基本上是因为这里是相同的:Why does JavaFX table.getItems().clear() clear the ObservableList as well

+0

很多的帮助表示感谢。我几分钟前用不同的方法解决了这个问题。但你的解决方案似乎工作! *竖起大拇指* – manCRO

0

// 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; 
    } 

}