4

基になる監視可能な配列リストを変更すると、グラフィック選択ボックスが更新されません。たとえば、ここで提案したものよりも新しいソリューションが必要です: JavaFX: ObservableList の要素が変更された場合の ListView の更新

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

何かご意見は?削除と追加は避けたいと思います。

4

2 に答える 2

4

「標準的な」答えは、ObservableListを とともに使用することextractorです。ただし、これをテストしたところ、宣伝どおりに動作せず、バグがあるようです (私の推測では、 で発生した型の変更をChoiceBox正しく処理していない可能性があります)。これについては JIRA で報告します。更新: https://javafx-jira.kenai.com/browse/RT-38394でレポートを提出wasUpdatedListChangedListener

ファクトリ メソッドFXCollections.observableArrayList(Callback)は、(空の) 監視可能な配列リストを作成します。提供されCallbackているのは、リスト内の各要素を の配列にマップする関数ですObservable。リストはリスナーをそれらのオブザーバブルに登録し、それらのプロパティが変更された場合、リストはそのリスナーに更新通知を送信します。

ChoiceBoxただし、これは で奇妙な結果をもたらします。考えられる回避策の 1 つは、正常に動作するように見える a を使用することComboBoxです。

ここにいくつかのサンプルコードがあります。項目を選択: テキスト フィールドに入力し、Enter キーを押して、選択した項目の名前を変更します。に変更ChoiceBoxComboBoxて、正しい動作を確認します。

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);
    }
}
于 2014-08-22T01:25:02.463 に答える
2

正しい適切な答えは James_D からのものですが、本当に ChoiceBox を使用したい場合は、追加と削除を試してください。

    int selected = productsChoiceBox.getSelectionModel().getSelectedIndex();
    products.remove(selected);
    products.add(selected, prod);

これが正しい方法だとは思いませんが、テストしたところ、うまくいきました。ChoiceBox は、削除および選択されたインデックスにとどまり、更新されたように見えます。

于 2014-08-22T02:02:43.713 に答える