【问题标题】:JavaFX 2.0 Choice Box Issue. How to update a choiceBox, which represents a list of objects, when an object is updated?JavaFX 2.0 选择框问题。更新对象时如何更新代表对象列表的选择框?
【发布时间】:2014-02-18 12:38:58
【问题描述】:

我有一个代表列表对象的选择框。当代表其中一个对象的名称被另一位代码更改时,选择框下拉列表中的名称不会更改。例如,如果我有一个由列表 Test 对象组成的选择框。测试代码如下:

class Test {
    String name;

    public Test(String name) {
        this.name = name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return name; 
    }
} 

然后有一个选择框如下:

ChoiceBox<Test> chi = new ChoiceBox<>();
ObservableList<Test> items = FXCollections.observableArrayList();
chi.setItems(items);
items.addAll(new Test("ITEM1"),new Test("ITEM2"),new Test("ITEM3"));

ChoiceBox 将显示列表 ITEM1、ITEM2 和 ITEM3

如果我随后通过以下代码更改其中一项的名称:

items.get(1).setName("CHANGED");

ChoiceBox 仍将显示列表 ITEM1、ITEM2 和 ITEM3。我怎样才能让choiceBox更新并显示列表ITEM1、CHANGED和ITEM3?

【问题讨论】:

  • 除了选择框中的一个潜在错误(不知道):您为什么期望会发生任何事情 - 您的 bean 不会触发任何通知...

标签: java object javafx-2


【解决方案1】:

只是为了完整性-在 fx2 中,您可能会被 replace approach 卡住,如另一个答案中所述。从 fx8 开始,有一种机制可以告诉列表监听其包含的项目的更改(前提是,当然,您的项目具有属性并在更改时通知侦听器):

/** changed item to 
 *  - use property and notify on change
 *  - not override toString (for visuals, use converter instead)
 */ 
class Test {
    StringProperty name;

    public Test(String name) {
        setName(name);
    }

    public StringProperty nameProperty() {
         if (name == null) name = new SimpleStringProperty(this, "name");
         return name;
    }
    public void setName(String name) {
        nameProperty().set(name);
    }

    public String getName() {
        return nameProperty().get();
    }

} 

// use in collection with extractor
ObservableList<Test> items = FXCollections.observableList(
    e -> new Observable[] {e.nameProperty()} );
items.addAll(...);
choiceBox = new ChoiceBox<>(items);
// tell the choice how to represent the item
StringConverter<Test> converter = new StringConverter<Test>() {

    @Override
    public String toString(Test album) {
        return album != null ? album.getName() : null;
    }

    @Override
    public Test fromString(String string) {
        return null;
    }

};
choiceBox.setConverter(converter);

【讨论】:

  • 要编译它,我必须将ObservableList&lt;AlbumFx&gt; items = FXCollections.observableList( e -&gt; new Observable[] {e.nameProperty()} ); to ObservableList&lt;Test&gt; items = FXCollections.observableArrayList(e -&gt; new Observable[] {e.nameProperty()}); new StringProperty(this, "name"); to @987654327 @
  • e-> new Observable[]{e.nameProperty} - 没有为 observableList 找到合适的方法
  • 检查你的导入,你可能有 java.util.Observable 与 fx 版本
  • 我有javafx.beans.Observable。还是应该是observableArrayList
  • @OrdinaryDraft 嗯 ...那我不知道你的上下文有什么不同,worksforme。您可以考虑使用minimal reproducible example 发布一个问题来说明问题。
【解决方案2】:

我在 JavaFX 8 中遇到了同样的问题(也有 ComboBox)。通过删除该项目然后在同一位置添加一个新项目,我能够获得相同的功能。

例子:

这会获取选中的项目,创建一个新项目,然后调用替换方法:

Channel selected = channelChoiceBox.getSelectionModel().getSelectedItem();
Channel newChan = new Channel("Example", "Channel");
replaceChannel(newChan, selected);

这会将所选频道替换为新频道,有效地对其进行编辑:

private void replaceChannel(Channel newChan, Channel oldChan) {
    int i = channelChoiceBox.getItems().indexOf(oldChan);
    channelChoiceBox.getItems().remove(oldChan);
    channelChoiceBox.getItems().add(i, newChan);
    channelChoiceBox.setValue(newChan);
}

这并不理想,但可以。

免责声明:我是 Java 和一般编程的新手。

【讨论】:

  • 在 fx8 中,您可以在创建列表时使用提取器(返回要观察的属性的回调)
【解决方案3】:

是的。这似乎是 JavaFx 的问题。我也曾面对过。使用 ComboBox 而不是可以工作的 ChoiceBox。

【讨论】:

  • 使用组合框仍然遇到问题
猜你喜欢
  • 1970-01-01
  • 2014-04-12
  • 2016-09-15
  • 1970-01-01
  • 1970-01-01
  • 2013-11-26
  • 2012-04-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多