大家早上好,
我正面临所谓的错误,因为它根本没有任何意义。
要了解我面临的错误,我必须将其放在上下文中。我有一个带有参数的应用程序。这些使用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
谢谢您的回答。
您的列表单元格实现不正确:如果单元格从显示项目变为不显示项目,它们将永远不会更新单元格。您需要:
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()));
}
}
});
}
}