【问题标题】:JavaFX Editable ComboBox : Showing toString on item selectionJavaFX 可编辑组合框:在项目选择上显示 toString
【发布时间】:2013-10-15 02:00:18
【问题描述】:

我有一个ComboBox<Person>,类型为Person,我在其中添加了几个Person 类的对象。

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

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 时,这会失败。

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

正常情况:

可编辑案例:

有什么解决办法吗?

我有一个模型类:

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

【问题讨论】:

    标签: combobox javafx-2 javafx javafx-8


    【解决方案1】:

    为此需要在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);
        }
    }
    

    结果:

    【讨论】:

      【解决方案2】:

      这是我自己的问题的答案,经过多次努力和更正后,我找到了最好的答案。

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

      【讨论】:

      • 您是否查看过我的答案,该答案给出了正确的解决方案并在您提交问题 1 小时后发布?
      猜你喜欢
      • 1970-01-01
      • 2014-11-10
      • 2017-02-11
      • 2014-07-21
      • 1970-01-01
      • 2023-04-09
      • 2011-08-30
      • 2017-08-09
      • 1970-01-01
      相关资源
      最近更新 更多