无法从组合框或选择框中的其他控制器中选择绑定项目

时间:2015-06-30 00:40:28

标签: java binding combobox javafx

我有三个控制器,分别是ParentController,ChildController1和ChildController2。 ParentController同时加载所有子控制器。我有来自ChildController1的list1,我想将它绑定到ChildController2的list2。这是一个示例代码:

ParentController.java

public class ParentController{
    ChildController1 controller1;
    ChildController2 controller2;

    loadControllers();
}


public void loadControllers(){
    FXMLLoader fxmlLoader = new   FXMLLoader(getClass().getResource("/view1.fxml"));
    Parent root1 = (Parent) fxmlLoader.load();
    controller1 = fxmlLoader.getController();

    FXMLLoader fxmlLoader = new   FXMLLoader(getClass().getResource("/view1.fxml"));
    Parent root2 = (Parent) fxmlLoader.load();
    controller2 = fxmlLoader.getController();

    Bindings.bindContentBidirectional(controller1.list1, controller2.list2);
}

ChildController1.java

public class ChildController1{

    @FXML
    Button addItem;

    @FXML
    TextField textField;

    ObservableList list1 = FXCollections.observableArrayList("apple", "grapes");

    @Override
    public void initialize(URL url, ResourceBundle rb){
        addItem.setOnAction(e->{
            list1.add(textField.getText());
        });
    }

}

ChildController2.java

public class ChildController2{
    @FXML
    ComboBox combobox;
    ObservableList list2 = FXCollections.observableArrayList();

    @Override
    public void initialize(URL url, ResourceBundle rb){
        combobox.setItems(list2);
    }
}

运行应用程序时,可以在controller2的组合框中选择前两个项目(" apple"" grape")。但是当我在list1中添加一个新字符串时,请说" orange"," orange"在组合框项目列表中可见,但无法选择它。

任何帮助将不胜感激。提前致谢。

2 个答案:

答案 0 :(得分:0)

问题

您尝试加载两次相同的fxml文档。有两个问题,首先你必须在新的加载器上设置位置,然后在其上调用load()。其次,如果您通过标签" fx:controller"在fxml文档中设置控制器,则无法加载fxml两次。这是因为fxml和控制器对已存在上下文。

如果您更改代码以正确加载,那么您将获得例外:

javafx.fxml.LoadException: Root value already specified.

假设/问题

您是否尝试创建新窗口?如果你尝试,这次尝试将失败。新的Windows(阶段)需要场景和舞台,但这是一个不同的问题。

解决方案

创建两个不同的fxml - 控制器对。然后创建一个类型可观察列表,之后你就可以将这两个列表分开。

  public void loadControllers() throws IOException {
    FXMLLoader child1Loader = new FXMLLoader();
    child1Loader.setLocation(getClass().getResource("Child1.fxml"));
    Parent root1 = child1Loader.load();
    controller1 = child1Loader.getController();

    FXMLLoader child2Loader = new FXMLLoader();
    child2Loader.setLocation(getClass().getResource("Child2.fxml"));
    Parent root2 = (Parent) child1Loader.load();
    controller2 = child2Loader.getController();

    Bindings.bindContentBidirectional(controller1.getObservableList(), controller2.getObservableList());
  }

答案 1 :(得分:0)

我发现了这个问题。它实际上在我放在observablelist list1 上的项目列表中。这是详细的样本:

@FXML
ComboBox<Fruit> fruits;

ObservableList<Ingredient> list1 = FXCollections.observableArrayList();

@Override
public void initialize(URL url, ResourceBundle rb){

    Fruit apple = new Fruit("apple");
    Fruit mango = new Fruit("mango");

    fruits.setItems(FXCollections.observableArrayList(apple, mango));

    addButton.setOnAction(e->{
        Ingredient i = new Ingredient(fruits.getValue(), 5);
        list1.add(i);
    });
}

<强> Ingredient.java

class Ingredient{
    @Expose
    int id;
    @Expose
    Fruit fruit;
    @Expose
    double quantity;

    public Ingredient(Fruit fruit, double quantity){
        this.fruit = fruit;
        this.quantity = quantity;
    }

    @Override
    public int hashCode() {
        int hash = 0;
        hash += (id != null ? id.hashCode() : 0);
        return hash;
    }

    @Override
    public boolean equals(Object object) {
        if (!(object instanceof Ingredient)) {
            return false;
        }

        Ingredient other = (Ingredient) object;
        if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }


}

删除两个生成的覆盖hashcode()和equals()之后,现在一切正常。