JavaFX Editable ComboBox : Showing toString on item selection
You need to set a StringConverter
on the ComboBox for that purpose (there is no other way, looking at the source code of ComboBox)
Here is an example:
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.stage.Stage;
import javafx.util.StringConverter;
import java.util.Arrays;
import java.util.List;
public class ComboBoxTest extends Application {
private ComboBox<Integer> cmb_year = new ComboBox<>();
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) throws Exception {
Group root = new Group();
root.getChildren().add(cmb_year);
cmb_year.setPrefWidth(150);
Scene scene = new Scene(root, 500, 500);
primaryStage.setScene(scene);
primaryStage.show();
List<Integer> ints = Arrays.asList(2012, 2013, 2014, 2015);
cmb_year.getItems().addAll(ints);
cmb_year.setConverter(
new StringConverter<Integer>() {
@Override
public String toString(Integer integer) {
if (integer == null) {
return "";
} else {
return "that's a year: " + integer.intValue();
}
}
@Override
public Integer fromString(String s) {
try {
return Integer.parseInt(s);
} catch (NumberFormatException e) {
return null;
}
}
});
cmb_year.setPromptText("select year");
cmb_year.setEditable(true);
Button distraction = new Button("distraction");
distraction.setLayoutX(100);
distraction.setLayoutY(100);
root.getChildren().add(distraction);
}
}
result:
Here is an answer to my own question which I found best after many efforts and corrections.
mainComboBox.setButtonCell(
new ListCell<Object>() {
@Override
protected void updateItem(Object t, boolean bln) {
super.updateItem(t, bln);
if (bln) {
setText("");
} else {
setText(getStringField(t));
}
}
});
mainComboBox.setConverter(
new StringConverter() {
private Map<String, Object> map = new HashMap<>();
@Override
public String toString(Object t) {
if (t != null) {
String str = getStringField(t);
map.put(str, t);
return str;
} else {
return "";
}
}
@Override
public Object fromString(String string) {
if (validate && !map.containsKey(string)) {
mainComboBox.setValue(null);
mainComboBox.getEditor().clear();
return null;
}
return map.get(string);
}
});
mainComboBox.setCellFactory(
new Callback<ListView<Object>, ListCell<Object>>() {
@Override
public ListCell<Object> call(ListView<Object> p) {
ListCell cell = new ListCell<Object>() {
@Override
protected void updateItem(Object item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText("");
} else {
setText(getStringField(item));
}
}
};return cell;
}
});
And with required function of getStringField(Object)
,
public String getStringField(Object o) {
return ((Pesron) o).getName();
}