JavaFX ComboBox set Items from ObservableList

Andrea picture Andrea · Feb 9, 2014 · Viewed 7.5k times · Source

i need help to get a specified list of items from ObservableList and add them to a combo box.

My ObservableList contains value received from DB (in specific a table with just 3 columns) and i want to show only one column value in combo box. When combo box is selected the other values are charged in 2 textfield.

Code as follows.

ImportAccettazioniModel:

public ObservableList<Impostazioni> listImpostazioni = FXCollections.observableArrayList();

public static class Impostazioni {
    private final StringProperty rowid;
    private final StringProperty nome;
    private final StringProperty operatore;
    private final StringProperty delimitatore;

    private Impostazioni(String Rowid, String Nome, String Operatore, String Delimitatore) {
        this.rowid = new SimpleStringProperty(Rowid);
        this.nome = new SimpleStringProperty(Nome);
        this.operatore = new SimpleStringProperty(Operatore);
        this.delimitatore = new SimpleStringProperty(Delimitatore);
    }

    public StringProperty rowidProperty() { return rowid; }
    public StringProperty nomeProperty() { return nome; }
    public StringProperty operatoreProperty() { return operatore; }
    public StringProperty delimitatoreProperty() { return delimitatore; }
}

ImportAccettazioniController:

@FXML
private ComboBox<ImportAccettazioniModel.Impostazioni> comboCaricaNome;


// get data from model to popupate combobox
public final void getImpostazioniDataFields() {
    comboCaricaNome.getItems().clear();
    comboCaricaNome.setItems(model.listImpostazioni);
    comboCaricaNome.setCellFactory(new Callback<ListView<Impostazioni>, ListCell<Impostazioni>>() {
        @Override public ListCell<Impostazioni> call(ListView<Impostazioni> p) {
            return new ListCell<Impostazioni>() { 
                    @Override
                    protected void updateItem(Impostazioni t, boolean bln) {
                        super.updateItem(t, bln);
                        if(t != null){
                            setText(t.nomeProperty().toString().toUpperCase());
                            System.out.println("SET PROPERTY " + t.nomeProperty().toString());
                        } else {
                            setText(null);
                        }    

                    }                       
            };
        }
    });

}


comboCaricaNome.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<ImportAccettazioniModel.Impostazioni>() {
        @Override public void changed(ObservableValue<? extends ImportAccettazioniModel.Impostazioni> observable,ImportAccettazioniModel.Impostazioni oldValue, ImportAccettazioniModel.Impostazioni newValue) {
            setTextFields(newValue);
        } 

    });

//set data to textfield with the selected combo box
private void setTextFields(Impostazioni listImpostazioni) {
    //setRowid(Impostazioni.rowidProperty().getValue());
    if (comboCaricaNome.getItems().isEmpty()) {
        editCaricaOperatore.setText("");
        editCaricaDelimitatore.setText("");
    } else {
        editCaricaOperatore.setText(listImpostazioni.operatoreProperty().getValue());
        editCaricaDelimitatore.setText(listImpostazioni.delimitatoreProperty().getValue());
    }   
}

Now, the logic seems to work but my combo box doesn't contain the value nomeProperty().

How can i solve?

Thanks in advance

Answer

Uluk Biy picture Uluk Biy · Feb 9, 2014

To get the observed value of the JavaFX Property use Property.get() or Property.getValue(). By convention, the Java developers override toString() method to not show message for customers, instead it is used for internal usages by another developers.

As a result, the line

setText(t.nomeProperty().toString().toUpperCase());

should be

setText(t.nomeProperty().getValue().toUpperCase());

UPDATE:
Since you are using the ComboBox rather than ChoiceBox, you should also override default button cell property of combobox, according to your needs:

comboCaricaNome.setButtonCell(new ListCell<Impostazioni>() {
    @Override
    protected void updateItem(Impostazioni t, boolean bln) {
        super.updateItem(t, bln);
        if (t != null) {
            setText(t.nomeProperty().getValue().toUpperCase());
        } else {
            setText(null);
        }
    }
});

As you can see this is the same ListCell which is set for cellFactory. Refactoring is up to you, or of course you can implement a listcell with different content as well.