Par de valores clave de cuadro combinado en JavaFX 2

Estoy empezando a aprender JavaFX 2.
Ahora estoy tratando de construir una aplicación de muestra. Luego me quedé atrapado en el combobox.
No encontré ninguna referencia al par de valores clave para combobox en JavaFX.
El combobox javadoc en http://docs.oracle.com/javafx/2/api/index.html no dice mucho sobre el par de valores clave.

¿Cómo puedo crear un combobox que tenga elementos que tengan diferente valor de visualización y valor real?

Tienes 2 enfoques:
1. Simplemente anule el método toString() en su clase de modelo de datos. Ejemplo:

 public class Demo extends Application { private final ObservableList data = FXCollections.observableArrayList( new Employee("Azamat", 2200.15), new Employee("Veli", 1400.0), new Employee("Nurbek", 900.5)); @Override public void start(Stage primaryStage) { ComboBox combobox = new ComboBox<>(data); combobox.getSelectionModel().selectFirst(); // Select first as default combobox.getSelectionModel().selectedItemProperty().addListener(new ChangeListener() { @Override public void changed(ObservableValue< ? extends Employee> arg0, Employee arg1, Employee arg2) { if (arg2 != null) { System.out.println("Selected employee: " + arg2.getName()); } } }); StackPane root = new StackPane(); root.getChildren().add(combobox); primaryStage.setScene(new Scene(root, 300, 250)); primaryStage.show(); } public static class Employee { private String name; private Double salary; @Override public String toString() { return name + " (sal:" + salary + ")"; } public Employee(String name, Double salary) { this.name = name; this.salary = salary; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Double getSalary() { return salary; } public void setSalary(Double salary) { this.salary = salary; } } public static void main(String[] args) { launch(args); } } 

Tenga en cuenta el overriden toString () de la clase Employee. La clave del combobox (valor real) será la instancia del Employee y el valor de visualización será employee.toString() en este caso.
2. El segundo enfoque es establecer la propiedad cellFactory del cuadro combinado.

 combobox.setCellFactory(new Callback, ListCell>() { @Override public ListCell call(ListView arg0) { return new ListCell() { private final Button btn; { setContentDisplay(ContentDisplay.GRAPHIC_ONLY); btn = new Button(); } @Override protected void updateItem(Employee item, boolean empty) { super.updateItem(item, empty); if (item == null || empty) { setGraphic(null); } else { btn.setStyle(item.getSalary() > 1000 ? "-fx-base:red" : "-fx-base: green"); btn.setText(item.getName() + "=" + item.getSalary()); setGraphic(btn); } } }; } }); 

Este enfoque proporciona un control más poderoso sobre la representación de células. No puede simplemente formatear el valor de visualización, sino también incluir cualquier nodo (control) en la celda (botón en este caso) y agregar alguna lógica de visualización (item.getSalary ()? “”: “”) También. El valor real sigue siendo el mismo, es decir, instancia de empleado.

Hay otra solución, implementar un StringConverter . Es muy útil para objetos:

 public class Product { private String code; private String name; public Product(String code, String name) { this.code = code; this.name = name; } public String getCode() { return code; } public void setCode(String code) { this.code = code; } public String getName() { return name; } public void setName(String name) { this.name = name; } } 

Implementación del convertidor:

 public class ProductConverter extends StringConverter { /** Cache of Products */ private Map productMap = new HashMap(); @Override public String toString(Product product) { productMap.put(product.getName(), product); return product.getName(); } @Override public Product fromString(String name) { return productMap.get(name); } } 

Código a la vista:

  ComboBox cboProducts = new ComboBox; cboProducts.setConverter(new ProductConverter()); cboProducts.getItems().addAll(serviceManager.getProductList()); 

Para obtener el valor del producto, puede llamar al método getValue ():

 cboProducts.getValue() 

Sé que esta pregunta es antigua, pero como pasé horas inútilmente indagando sobre este tema, es una especie de obligación para mí compartir los resultados. Parece que el ComboBox con el método overriden toString () resuelve las cadenas de regreso a los objetos correctos, incluso si hay cadenas duplicadas en la lista. La resolución debe basarse en el índice y toString () solo se usa para la presentación.