0

I adapted Jonathan Stenbackas Answer (JavaFX - Filtered ComboBox) to a ComboBox with a Jooq Record Bean, displaying one of the Beans fields using a custom ListCell/ButtonCell. The filtering works fine, but I can't get the Editor to show the text of the selected items field.

I added a listener to the combobox' selection and let it print out editors Text. So I get the toString() of the bean, but the Editor is empty. When I use the listener to set the text programmatically, the programmatically set text is printed out, but the editor does not show it. I also tried a JavaFX bean for testing, with the same result. Any recommendation would be highly appreciated.

//retrieving data from database
ObservableList<MyRecord> items = applicationContext.getFetchData().fetchOList();

//wrapping in a FilteredList

FilteredList<MyRecord> filteredItems = new FilteredList<>(items, p -> true);

    ComboBox<MyRecord> cb = new ComboBox<>(filteredItems);
    cb.setEditable(true);
    cb.setCellFactory(c_ -> new NamenCell());
    cb.setButtonCell(new NamenCell());
    TextField editor = cb.getEditor();

    editor.textProperty().addListener((obs, oldValue, newValue) -> {

        final MyRecord selected = cb.getSelectionModel().getSelectedItem();

        Platform.runLater(() -> {
            if (selected == null || !selected.getSurname().equals(editor.getText())) {
                filteredItems.setPredicate(item -> {
                    if (item.getSurname().toLowerCase().contains(newValue.toLowerCase())) {
                        return true;
                    } else {
                        return false;
                    }
                });
            }

        });
    });


    cb.getSelectionModel().selectedItemProperty().addListener(
            (ob, oldValue, newValue) -> {
                if (newValue != null) {
                    cb.getEditor().setText(newValue.getSurname());
                    System.out.println(cb.getEditor().getText());

                }

            });


//The Cell class:

public class NamenCell extends ListCell<MyRecord> {

    public NamenCell() { }
    @Override
    protected void updateItem(MyRecord item, boolean empty) {
        super.updateItem(item, empty);
        setText(item == null ? "" : item.getSurname());

    }
}
Jamith NImantha
  • 1,999
  • 2
  • 20
  • 27
elkebasel
  • 1
  • 1

1 Answers1

0

I found a solution: I extended Combobox. Perhaps this may be useful to someone:



       import javafx.application.Platform;
    import javafx.beans.property.Property;
    import javafx.beans.property.SimpleObjectProperty;
    import javafx.collections.FXCollections;
    import javafx.collections.ObservableList;
    import javafx.collections.transformation.FilteredList;
    import javafx.scene.control.ComboBox;
    import javafx.scene.control.TextField;
    import org.jooq.impl.TableRecordImpl;


    public class FilterComboBox extends ComboBox {
        private ObservableList ol;
        private ObservableList items;
        private FilteredList filteredItems;
        private FilteredList filteredOl;
        private String field;
        private Property selectedBeanProperty = new SimpleObjectProperty();

        public FilterComboBox(){

        }

        public FilterComboBox(ObservableList ol, String field) {
          populate(ol,field);
        }


        public Property selectedBeanProperty() {
            return selectedBeanProperty;
        }

        public void setSelectedBeanProperty(T selectedBeanProperty) {
            this.selectedBeanProperty.setValue(selectedBeanProperty);
        }

        private ObservableList createItems(ObservableList ol, String field) {
            this.items = FXCollections.observableArrayList();
            for (T t : ol) items.add(t.get(field).toString());
            return items;
        }

        public void populate(ObservableList ol, String field){
            this.field=field;
            this.ol = ol;
            this.items = createItems(this.ol, field);
            this.filteredItems = new FilteredList(items, p -> true);
            this.filteredOl= new FilteredList(ol, p->true);
            this.setEditable(true);
            this.setItems(filteredItems);

            TextField editor = this.getEditor();
            editor.textProperty().addListener((obs, oldValue, newValue) -> {
                final String selected = this.getSelectionModel().getSelectedItem();

                Platform.runLater(() -> {
                    if (selected == null || !selected.equals(editor.getText())) {
                        filteredItems.setPredicate(item -> {
                            if (item.toLowerCase().contains(newValue.toLowerCase())) {
                                return true;
                            } else {
                                return false;
                            }
                        });
                    }


                });

            });

            this.getSelectionModel().selectedItemProperty().addListener((obs, oldValue, newValue) -> {
                if (newValue != null &&!newValue.isEmpty() ) {
                    setSelectedBeanProperty(this.ol.get(getOlIndex(newValue, field)));
                }
            });
        }

        public Integer getOlIndex(String s, String field){
            for (T t : ol)
                if(t.get(field).toString().equals(s)){
                return ol.indexOf(t);
            }
            return -1;
        }

    }

elkebasel
  • 1
  • 1