ObservableList.size()始终等于0,但链接到它的comboBox不能为空

问题描述 投票:0回答:1

大家早上好,

我正面临所谓的错误,因为它根本没有任何意义。

要了解我面临的错误,我必须将其放在上下文中。我有一个带有参数的应用程序。这些使用java.utils包的Preferences类存储在java Preferences中。然后将这些参数绑定到允许修改它们的不同javafx控制器。

例如,启用/禁用复选框或微调框选择一个值。为了实现这种绑定,我已经实现了模式策略,因为每个控制器都不同地对待其值。所以我有一个CheckBoxParameterStrategy类,ComboboxParameterStrategy等...

到目前为止一切顺利。

但是我创建的类仅处理诸如String,ComboBox,TextField等的信息...

除了我需要使用和显示来自我的一个名为“ Risk”的模型的信息,像这样:

package Model.databaseModels;

import javafx.beans.property.*;

public class Risk extends DatabaseModel{

final DoubleProperty riskValueProperty;

public Risk(int id, Double value){

    super(id);

    riskValueProperty = new SimpleDoubleProperty(value);

}


/*
    Properties
 */
public DoubleProperty riskValueProperty(){
    return riskValueProperty;
}

/*
    Getter
 */

public Double getRiskValue(){
    return riskValueProperty.get();
}

/* */
public String toString(){

    return String.valueOf(getRiskValue());

}
}

您应该知道使用以下功能将我的参数绑定到其控制器:

/**
 * Permet d'initialiser une Combox avec un type de donnée spéciale
 * Ex: ComboBox<Risk> ou ComboBox<Market>
 *
 * @param key {String}
 * @param comboBox
 * @param items
 */
public void initRiskComboBox(String key, ComboBox<Risk> comboBox, ObservableList<Risk> items){
    initImpl(key, new RiskComboBoxStrategy(comboBox, key, items));
}

/**
 * Permet d'initialiser les différents control représenter par la classe ParameterStrategy
 * @param key {String} clé correspondant au nom du paramétre que modifie le control
 * @param parameter {ParameterStrategy} control à initialiser avec sa valeur de configuration
 */
private void initImpl(String key, ParameterStrategy parameter){
    parameter.setValue(this.getPreferenceValue(key));
    parametersSynchronous.put(key,parameter);
}

如果我在此模型中使用ComboBox,则如下所示:ComboBox。我的ComboBox没有显示正确的信息...。由于未提供CellFcatory,因此是逻辑的。因此,我创建了一个RiskComboBoxStrategy类,如下所示:

package Model.parameter;

import Model.databaseModels.Risk;
import application.Configuration;
import application.Main;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.collections.ObservableList;
import javafx.scene.control.*;
import javafx.util.Callback;

public class RiskComboBoxStrategy implements ParameterStrategy {

private final ReadOnlyObjectProperty<Risk> riskProperty;
private final String PropertyName;

private final SelectionModel<Risk> selectionModel;

private final ComboBox<Risk> comboBox;

/**
 * Constructeur par défaut
 * @param comboBox La comboBox à paramétrer
 * @param PropertyName Nom du paramétres à enregistrer
 * @param items ObservableList contenenant les itmems à ajouter à la ComboBox
 */
public RiskComboBoxStrategy(ComboBox<Risk> comboBox, String PropertyName, ObservableList<Risk> items){ 


    System.out.println("STEP 1");

    System.out.println(items); (2)

    comboBox.setDisable(true);

    this.PropertyName = PropertyName;
    this.comboBox = comboBox;

    selectionModel = this.comboBox.getSelectionModel();
    riskProperty = selectionModel.selectedItemProperty();

    this.comboBox.setItems(items); (1)
    this.comboBox.getSelectionModel().selectFirst();


    //this.CreateFactories();

    riskProperty.addListener((observableValue, oldValue, newValue) -> {

        //on met à jour la valeur du paramétre correspondant avec la nouvelle séléction
        Configuration.preferences.setPreferenceValue(
                this.PropertyName,
                String.valueOf(riskProperty.getValue().getRiskValue())
        );

        System.out.println("Valeur de la comboBox:   " + riskProperty.getValue().getRiskValue());

    });


}

@Override
public String getValue() {
    return String.valueOf(selectionModel.getSelectedItem().getRiskValue());
}

@Override
public void setValue(String value) {

    //on test si un des risques contenus dans notre ObservableList
    // contient le risque passer en paramétre de la fonction

    System.out.println("STEP 2");

    for(Risk risk: comboBox.getItems()){

        System.out.println(risk.getRiskValue());

        if(risk.getRiskValue() == Double.parseDouble(value)){
            selectionModel.select(risk);
        }else{
            selectionModel.selectFirst();
        }

    }

}

/*
    Factories
 */
private void CreateFactories(){

    //Factory pour afficher le risque
    comboBox.setCellFactory(new Callback<>() {

        @Override
        public ListCell<Risk> call(ListView<Risk> riskListView) {

            return new ListCell<>() {

                @Override
                public void updateItem(Risk risk, boolean b) {
                    super.updateItem(risk, b);
                    if(risk != null){
                        setText(String.valueOf(risk.getRiskValue()));
                    }
                }

            };

        }
    });

    //Factory pour afficher le risque
    comboBox.setButtonCell(new ListCell<>(){

        @Override
        public void updateItem(Risk risk, boolean b) {
            super.updateItem(risk, b);
            if(risk != null){
                setText(String.valueOf(risk.getRiskValue()));
            }

           }
       });

    }
}

我们正在解决我们的错误。此代码首先检索用作我们参数的控制器的comboBox,其修改的参数名称,最后是包含我的Risk对象的ObservableList。

问题基本上来自setValue()函数。在测试我的课程时,我意识到里面的循环没有执行。所以我自然地看着我的物品的大小。看到它是0令我感到惊讶,因为我的ComboBox已满,所以没有意义。在??????中显示对象时,它显示的ObservableList的大小怎么可能从0开始因此,我在步骤(1)中工作,而在步骤(2)中显示空白...

有趣的是,我的ComboBox充满了从“ items”参数中获得的项目。但是,如果我尝试使用:

显示
System.out.println(comboBox.getItems());

我的comboBox被类型为“风险”的各种对象很好地填充时,我得到了一个空表。我故意停用了创建工厂的功能,因为我认为问题出在这里,但根本没有。

我创建了一个github下载最小的可复制示例,以显示出什么问题:github.com/BowgartField/trading-small

谢谢您的回答。

javafx
1个回答
0
投票

您的列表单元格实现不正确:如果单元格从显示项目变为不显示项目,它们将永远不会更新单元格。您需要:

private void CreateFactories(){

    //Factory pour afficher le risque
    comboBox.setCellFactory(new Callback<>() {

        @Override
        public ListCell<Risk> call(ListView<Risk> riskListView) {

            return new ListCell<>() {

                @Override
                public void updateItem(Risk risk, boolean empty) {
                    super.updateItem(risk, empty);
                    if(empty || risk == null){
                        setText("") ;
                    } else {
                        setText(String.valueOf(risk.getRiskValue()));
                    }
                }

            };

        }
    });

    //Factory pour afficher le risque
    comboBox.setButtonCell(new ListCell<>(){

        @Override
        public void updateItem(Risk risk, boolean empty) {
            super.updateItem(risk, empty);
            if(empty || risk == null){
                setText("");
            } else {
                setText(String.valueOf(risk.getRiskValue()));
            }

           }
       });

    }
}
© www.soinside.com 2019 - 2024. All rights reserved.