【问题标题】:Cannot select a binded item from another controller in combobox or choicebox无法从组合框或选择框中的另一个控制器中选择绑定项
【发布时间】:2015-09-16 15:06:39
【问题描述】:

我有三个控制器,分别是 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”和“grapes”)。但是当我在 list1 中添加一个新字符串说“橙色”时,“橙色”在组合框项目列表中可见,但无法选择它。

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

【问题讨论】:

  • 你能把这个做成一个完整的例子吗?它基本上对我有用。您拥有的代码似乎很好 - 错误必须在其他地方。
  • 你是对的..我认为错误在我的控制器或绑定中..它实际上是在我试图添加到列表中的对象中。我已经发布了更详细的示例。

标签: java binding combobox javafx


【解决方案1】:

问题

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

如果您更改代码以正确加载,那么您将收到异常:

javafx.fxml.LoadException: Root value already specified.

假设/问题

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

解决方案

创建两个不同的 fxml - 控制器对。然后制作一个 typed 可观察列表,然后您就可以对两个列表进行双向绑定了。

  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());
  }

【讨论】:

  • 我试图只制作一个窗口,我可以根据我设置的场景更改场景。然后我想将所有项目从另一个控制器传递给另一个控制器。
【解决方案2】:

我发现了问题。它实际上在我放在 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()后,现在一切正常。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-21
    相关资源
    最近更新 更多