JavaFx可编辑组合框:在项目选择上显示toString

时间:2013-10-08 08:30:02

标签: combobox javafx-2 javafx javafx-8

我有ComboBox<Perosn>类型Person,其中我添加了少量Person类的对象,

我使用setCellFactory(Callback)方法在ComboBox下拉列表中显示人名

combobox.setCellFactory(
    new Callback<ListView<Person >, ListCell<Person >>() {
        @Override
        public ListCell<Person > call(ListView<Person > p) {
            ListCell cell = new ListCell<Person >() {
                @Override
                protected void updateItem(Person item, boolean empty) {
                    super.updateItem(item, empty);
                    if (empty) {
                        setText("");
                    } else {
                        setText(item.getName());
                    }
                }
            };
            return cell;
        }
    });

setButtonCell(ListCell)方法在combobox选项中显示名称。

combobox.setButtonCell(
    new ListCell<Object>() {
        @Override
        protected void updateItem(Person t, boolean bln) {
            super.updateItem(t, bln); 
            if (bln) {
                setText("");
            } else {
                setText(t.getName());
            }
        }
    });

这对普通情况非常有效,但是当我使用可编辑的组合框时,这就失败了。

当我写combobox.setEditable(true);然后在项目选择时,组合框的文本字段(编辑器)显示人类的toString()方法。

正常情况:  Normal Case

可编辑案例:  Editable Case

有没有解决方案?

我有一个模型类,

public class Person {
    String name;
    int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" + "name=" + name + ", age=" + age + '}';
    }
}

2 个答案:

答案 0 :(得分:20)

您需要在ComboBox上为此目的设置StringConverter(没有其他方法,查看ComboBox的源代码)

以下是一个例子:

import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.stage.Stage;
import javafx.util.StringConverter;

import java.util.Arrays;
import java.util.List;

public class ComboBoxTest extends Application {
    private ComboBox<Integer> cmb_year = new ComboBox<>();

    public static void main(String[] args) {
        launch(args);
    }

    @Override
    public void start(Stage primaryStage) throws Exception {
        Group root = new Group();
        root.getChildren().add(cmb_year);
        cmb_year.setPrefWidth(150);
        Scene scene = new Scene(root, 500, 500);
        primaryStage.setScene(scene);
        primaryStage.show();

        List<Integer> ints = Arrays.asList(2012, 2013, 2014, 2015);
        cmb_year.getItems().addAll(ints);

        cmb_year.setConverter(
            new StringConverter<Integer>() {
                @Override
                public String toString(Integer integer) {
                    if (integer == null) {
                        return "";
                    } else {
                        return "that's a year: " + integer.intValue();
                    }
                }

                @Override
                public Integer fromString(String s) {
                    try {
                        return Integer.parseInt(s);
                    } catch (NumberFormatException e) {
                        return null;
                    }
                }
            });

        cmb_year.setPromptText("select year");
        cmb_year.setEditable(true);

        Button distraction = new Button("distraction");
        distraction.setLayoutX(100);
        distraction.setLayoutY(100);
        root.getChildren().add(distraction);
    }
}

结果:

enter image description here enter image description here

答案 1 :(得分:9)

以下是我自己的问题的答案,经过多次努力和纠正后,我发现了这个问题。

mainComboBox.setButtonCell(
    new ListCell<Object>() {
        @Override
        protected void updateItem(Object t, boolean bln) {
            super.updateItem(t, bln);
            if (bln) {
                setText("");
            } else {
                setText(getStringField(t));
            }
        }
    });

mainComboBox.setConverter(
    new StringConverter() {
        private Map<String, Object> map = new HashMap<>();

        @Override
        public String toString(Object t) {
            if (t != null) {
                String str = getStringField(t);
                map.put(str, t);
                return str;
            } else {
                return "";
            }
        }

        @Override
        public Object fromString(String string) {
            if (validate && !map.containsKey(string)) {
                mainComboBox.setValue(null);
                mainComboBox.getEditor().clear();
                return null;
            }
            return map.get(string);
        }
    });

mainComboBox.setCellFactory(
    new Callback<ListView<Object>, ListCell<Object>>() {
        @Override
        public ListCell<Object> call(ListView<Object> p) {
            ListCell cell = new ListCell<Object>() {
                @Override
                protected void updateItem(Object item, boolean empty) {
                    super.updateItem(item, empty);
                    if (empty) {
                        setText("");
                    } else {
                        setText(getStringField(item));
                    }
                }
            };return cell;
        }
    });

具有getStringField(Object)的必需功能,

public String getStringField(Object o) {
    return ((Pesron) o).getName();
}