Paire de clés de valeur de Combo-box en JavaFX 2

je commence juste à apprendre JavaFX 2.

Maintenant, j'essaie de construire un modèle d'application. Ensuite, j'ai été coincé dans la zone de liste déroulante.

Je n'ai trouvé aucune référence à la paire de valeurs clés de combobox dans JavaFX.

Le combobox javadoc à http://docs.oracle.com/javafx/2/api/index.html ne dit pas grand chose sur la paire de valeurs clés.

Comment puis-je créer un combobox qui contient des éléments ayant une valeur d'affichage et une valeur réelle différentes ?

16
demandé sur assylias 2012-05-22 13:52:15

3 réponses

Vous avez 2 méthodes:

1. Simplement remplacer le toString() méthode 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 les dérogations à toString () de la classe D'employé. La clé de combobox (valeur actuelle) sera la Employee l'instance et la valeur d'affichage est employee.toString() dans ce cas.

2. La deuxième approche consiste à définir la propriété cellFactory du combobox.

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 pouvez non seulement formater la valeur d'affichage, mais aussi inclure n'importe quel noeud (contrôle) dans la cellule (bouton dans ce cas) et ajouter de la logique de visualisation (élément.getSalary ()?"":"") trop. La valeur réelle reste la même instance ie Employee.

17
répondu Uluk Biy 2017-03-26 10:30:11

il y a une autre solution, implémenter un StringConverter. Il 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 oeuvre 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:

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

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

cboProducts.getValue()
11
répondu ajaristi 2018-04-18 00:47:32

je sais que cette question Est ancienne, mais parce que je viens de passer des heures à creuser inutilement sur cette question, c'est une sorte d'obligation pour moi de partager les résultats. Il semble que la méthode ComboBox avec overriden toString() résolve les chaînes de caractères vers les objets juste à droite même s'il y a des doublons de chaîne dans la liste. La résolution doit être basée sur un index et toString () n'est utilisé que pour la présentation.

0
répondu Yordan Nalbantov 2014-08-10 08:10:23