web-dev-qa-db-fra.com

Paire de valeurs de clé combo dans JavaFX 2

Je commence tout juste à apprendre JavaFX 2.
J'essaie maintenant de créer un exemple d'application. Puis je me suis retrouvé coincé dans la combobox.
Je n'ai trouvé aucune référence à la paire clé/valeur pour la liste déroulante dans JavaFX.
La liste déroulante javadoc à http://docs.Oracle.com/javafx/2/api/index.html ne dit pas grand-chose à propos de la paire valeur/clé.

Comment créer une liste déroulante dont les éléments ont une valeur d'affichage et une valeur réelle différentes?

17
Shrestha

Vous avez 2 approches:
1. Remplacez simplement la méthode toString() dans votre classe datamodel. Exemple: 

public class Demo extends Application {

    private final ObservableList<Employee> 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<Employee> combobox = new ComboBox<>(data);
        combobox.getSelectionModel().selectFirst(); // Select first as default
        combobox.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Employee>() {

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

Notez l'attribut toString () de la classe Employee. La clé de la liste déroulante (valeur réelle) sera l'instance Employee et la valeur d'affichage est employee.toString() dans ce cas.
2. La deuxième approche consiste à définir la propriété cellFactory de la liste déroulante. 

combobox.setCellFactory(new Callback<ListView<Employee>, ListCell<Employee>>() {

    @Override
    public ListCell<Employee> call(ListView<Employee> arg0) {
        return new ListCell<Employee>() {

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

Cette approche donne un contrôle plus puissant sur le rendu des cellules. Vous ne pouvez pas simplement formater la valeur d'affichage, mais également inclure un nœud (contrôle) dans une cellule (bouton dans ce cas) et ajouter une logique d'affichage (item.getSalary ()? "": "") Aussi. La valeur réelle reste la même, c’est-à-dire l’instance Employé.

18
Uluk Biy

Il existe une autre solution, implémentant un StringConverter . C'est très utile pour les objets:

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

}

Mise en œuvre du convertisseur:

public class ProductConverter extends StringConverter<Product> {

    /** Cache of Products */
    private Map<String, Product> productMap = new HashMap<String, Product>();

    @Override
    public String toString(Product product) {
        productMap.put(product.getName(), product);
        return product.getName();
    }

    @Override
    public Product fromString(String name) {
        return productMap.get(name);
    }

}

Code en vue:

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

Pour obtenir la valeur du produit, vous pouvez appeler la méthode getValue ():

cboProducts.getValue()
12
ajaristi

Je sais que cette question est ancienne, mais comme je viens de passer des heures inutilement à creuser dans ce dossier, il est en quelque sorte une obligation pour moi de partager les résultats. Il semble que la zone de liste déroulante avec la méthode toiden () redéfinie les chaînes de manière à ce qu'elles soient renvoyées aux objets, même s'il existe des doublons dans la liste. La résolution doit être basée sur l'index et toString () est utilisé uniquement pour la présentation.

0
Yordan Nalbantov