Combo-box key value pair in JavaFX 2

前端 未结 3 1428
梦谈多话
梦谈多话 2020-11-30 06:13

I am just starting to learn JavaFX 2.
Now I am trying to build a sample application. Then I got stuck in combobox.
I did not find any reference to key value pair for

3条回答
  •  没有蜡笔的小新
    2020-11-30 06:23

    You have 2 approaches:
    1. Simply override the toString() method in your datamodel class. Example:

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

    Note the overriden toString() of the Employee class. The combobox's key (actual value) will be the Employee instance and the display value is employee.toString() in this case.
    2. Second approach is to set cellFactory property of the combobox.

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

    This approach gives more powerful control over cell rendering. You can not just format display value but also include any node (control) into cell (button in this case) and add some viewing logic (item.getSalary()?"":"") too. The actual value remains the same ie Employee instance.

提交回复
热议问题