JavaFX and filling ComboBox with objects

There is a class Street, with a description of an object of the "street" type, which contains itself private String name;, private int id;, private String tymeName and private int typeId, as well as public methods for getting the values of these variables.

There is also @FXML ComboBox<Street> streetList;

Task: you need to output a list of streets by taking the names from the name variable using the getName method. and when a certain street is selected, start event processing via new ChangeListener<Street>() {...}.

I tried to do it by analogy with TableView and TableColumn through .setCellFactory and collections.

Question: How to make the attribute name get from the object to the list via getNameand trigger new ChangeListener<Street>() {...} passing the selected object for further work.

The poke method, in this case, does not help. How to implement the goal through the lines is clear. But what happens if, for example, the list includes Lenin and Lenin? Moreover, the first option is an avenue, the second is a street, but this should not be indicated in the drop-down list. Again, you can come up with a traversal through strings, but it seems to me that it is possible to solve it through passing objects, and not just strings. In tables, this method works.

2 answers

I take turns answering questions.

You need to output a list of streets by taking the names from the name variable using getName{[10] method]}

streetList.setCellFactory(p -> new ListCell <Street> () {

    @Override
    protected void updateItem(Street item, boolean empty) {
        super.updateItem(item, empty);
        if (item != null && !empty) {
            setText(item.getName());
        } else {
            setText(null);
        }
    }
});

And when you select a specific street, start event processing via new ChangeListener() {...}.

streetList.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) - > {
    //тут описываешь логику лисенера
});

Here I used lambda, not new ChangeListener()...

But here's what happens if, for example, the list includes Lenin and Lenin? And the first option is an avenue, the second is a street, but in the in the drop-down list, this should not be indicated by

You will have both an avenue and a street if the objects are Street will be different ( you need to redefine the hashCode() and equals() methods)

UPDATE

Regarding the picture in the comments, there are 2 possible ways.

  1. Redefine the toString() method in the Street class

  2. Redefine buttonCell as follows

    streetList.setButtonCell(new ListCell < Street > () {
    @Override
    protected void updateItem(Street item, boolean empty) {
        super.updateItem(item, empty);
        if (item != null && !empty) {
            setText(item.getName()); // или любую другую логику тут можно написать
        } else {
            setText(null);
        }
    }
    
 2
Author: Andrew Bystrov, 2016-08-30 07:53:20

In addition to @AndrewBystrov's answer. In order to display one of its arguments in the ComboBox text field after selecting an element, you must specify a converter:

public class StringConverterStreet extends StringConverter<Street> {

    @Override
    public String toString(Street street) {
        return street == null ? null : street.getName();
    }

    @Override
    public Street fromString(String string) {
        return null;
    }

}

Used it before

streetList.setConverter(new StringConverterStreet());
streetList.setCellFactory(p -> new ListCell <Street> () {
    @Override
    protected void updateItem(Street item, boolean empty) {
        super.updateItem(item, empty);
        if (item != null && !empty) {
            setText(item.getName());
        } else {
            setText(null);
        }
    }
});

UPDATE

I took the advice of @AndrewBystrov and simply redefined the toString method instead of the converter. The result is the following:

public class Street {
    private int id, typeId;
    private String typeName, name;

    public Street() {
        Street(null, null, null, null);
    }

    public Street(...) {
        ...
    }

    public String getName () {
        return name;
    }

    ...

    @Override
    public String toString () {
        return typeName + " " + name;
    }
}

Thank you very much for your help!

 0
Author: Инженер-погромист, 2016-09-22 20:57:26