Coppia di valori chiave combinati in JavaFX 2

Sto appena iniziando a imparare JavaFX 2.
Ora sto provando a build un’applicazione di esempio. Poi sono rimasto bloccato in combobox.
Non ho trovato alcun riferimento alla coppia di valori chiave per combobox in JavaFX.
Il combobox javadoc su http://docs.oracle.com/javafx/2/api/index.html non dice molto sulla coppia di valori chiave.

Come posso creare una casella combinata contenente elementi con valore di visualizzazione e valore effettivo diversi?

Hai 2 approcci:
1. Basta sostituire il metodo toString() nella class datamodel. Esempio:

 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 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); } } 

Notare il sovrascritto toString () della class Employee. La chiave della casella combinata (valore effettivo) sarà l’istanza Employee e in questo caso il valore di visualizzazione è employee.toString() .
2. Il secondo approccio consiste nell’impostare la proprietà cellFactory della casella combinata.

 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); } } }; } }); 

Questo approccio offre un controllo più potente sul rendering delle celle. Non puoi semplicemente formattare il valore di visualizzazione ma anche includere qualsiasi nodo (controllo) nella cella (pulsante in questo caso) e aggiungere qualche logica di visualizzazione (item.getSalary ()? “”: “”). Il valore attuale rimane lo stesso vale a dire l’istanza Employee.

C’è un’altra soluzione, implementando un StringConverter . È molto utile per gli oggetti:

 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; } } 

Implementazione del convertitore:

 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); } } 

Codice in vista:

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

Per ottenere il valore del prodotto, puoi chiamare il metodo getValue ():

 cboProducts.getValue() 

So che questa domanda è vecchia, ma poiché ho passato ore intere a scavare inutilmente su questo argomento, è per me una specie obbligata condividere i risultati. Sembra che il metodo ComboBox con overriden toString () risolva correttamente le stringhe sugli oggetti anche se nella lista ci sono duplicati di stringhe. La risoluzione deve essere basata su indice e toString () viene utilizzato solo per la presentazione.