JavaFX Choiceox更改不更新图形 [英] JavaFX Choiceox change not updating graphics

查看:347
本文介绍了JavaFX Choiceox更改不更新图形的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我更改基础的可观察数组列表时,图形选择框不会更新.例如,必须有比我在这里看到的建议新的解决方案: JavaFX:如果ObservableList的元素发生更改,则更新ListView

When I change the underlying observable array list the graphics choice box doesn't update. There must be a newer solution than what I have seen suggested here for example: JavaFX: Update of ListView if an element of ObservableList changes

    int selected = productsChoiceBox.getSelectionModel().getSelectedIndex();
    Product prod = products.get(selected);
    prod.setName(productName.getText());
    prod.setUrl(productUrl.getText());

有什么想法吗?我想避免删除和添加.

Any thoughts? I would like to avoid removing and adding.

推荐答案

标准"答案是将ObservableListextractor一起使用.但是,当我对此进行测试时,它的表现不像广告中所述,并且似乎存在一个错误(我的猜测是ChoiceBox无法正确处理其ListChangedListener中触发的wasUpdated类型更改).将向JIRA报告. 更新:在 https://javafx-jira.kenai提交的报告.com/browse/RT-38394

The "standard" answer is to use an ObservableList with an extractor. However, when I tested this out, it didn't behave as advertised, and it seems like there is a bug (my guess is that ChoiceBox is not correctly handling wasUpdated type changes fired in its ListChangedListener) which I will report at JIRA. Update: filed report at https://javafx-jira.kenai.com/browse/RT-38394

工厂方法

The factory method FXCollections.observableArrayList(Callback) creates an (empty) observable array list. The provided Callback is a function that maps each element in the list to an array of Observables. The list registers listeners with those observables, and if those properties change, the list fires update notifications to its listeners.

这会产生奇怪的结果,但ChoiceBox;一种可能的解决方法是使用似乎运行良好的ComboBox.

This produces strange results with a ChoiceBox, however; one possible workaround would be to use a ComboBox which seems to work fine.

这是一些示例代码.选择一个项目:然后在文本字段中键入并按Enter键以更改所选项目的名称.将ChoiceBox更改为ComboBox以查看正确的行为:

Here's some sample code. Select an item: then type in the text field and press enter to change the name of the selected item. Change ChoiceBox to ComboBox to see the correct behavior:

import java.util.stream.Collectors;
import java.util.stream.IntStream;

import javafx.application.Application;
import javafx.beans.Observable;
import javafx.beans.binding.Bindings;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

public class ChoiceBoxUpdateExample extends Application {

    @Override
    public void start(Stage primaryStage) {
        ChoiceBox<Item> choiceBox = new ChoiceBox<>();
        ObservableList<Item> items = FXCollections.observableArrayList(
                item -> new Observable[] {item.nameProperty()}); // the extractor
        items.addAll(
                IntStream.rangeClosed(1, 10)
                .mapToObj(i -> new Item("Item "+i))
                .collect(Collectors.toList()));
        choiceBox.setItems(items);

        TextField changeSelectedField = new TextField();
        changeSelectedField.disableProperty()
            .bind(Bindings.isNull(choiceBox.getSelectionModel().selectedItemProperty()));
        changeSelectedField.setOnAction(event -> 
            choiceBox.getSelectionModel().getSelectedItem().setName(changeSelectedField.getText()));

        BorderPane root = new BorderPane();
        root.setTop(choiceBox);
        root.setBottom(changeSelectedField);
        Scene scene = new Scene(root, 250, 150);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static class Item {
        public final StringProperty name = new SimpleStringProperty();
        public StringProperty nameProperty() {
            return name ;
        }
        public final String getName() {
            return nameProperty().get();
        }
        public final void setName(String name) {
            nameProperty().set(name);
        }
        public Item(String name) {
            setName(name);
        }
        @Override
        public String toString() {
            return getName();
        }
    }

    public static void main(String[] args) {
        launch(args);
    }
}

这篇关于JavaFX Choiceox更改不更新图形的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆