Javafx 为什么在TextFormatter中没有调用toString?

Javafx 为什么在TextFormatter中没有调用toString?,javafx,converter,textfield,Javafx,Converter,Textfield,我想创建一个可以键入任何数字的字段,它将转换为.(小数点后有一个数字)并存储为整数 问题:如果用户已经有了编号5.0并删除了0,在焦点丢失后,它将保持为5.,因为没有调用转换器中的toString方法 但是,如果用户拥有number55.0并删除0,则在焦点丢失后,toString方法将被调用,number将再次变为55.0 MyMain.fxml: <?xml version="1.0" encoding="UTF-8"?> <?import javafx.scene.co

我想创建一个可以键入任何数字的字段,它将转换为.(小数点后有一个数字)并存储为整数

问题:如果用户已经有了编号5.0并删除了0,在焦点丢失后,它将保持为5.,因为没有调用转换器中的
toString
方法

但是,如果用户拥有number55.0并删除0,则在焦点丢失后,
toString
方法将被调用,number将再次变为55.0

My
Main.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.layout.AnchorPane?>


<AnchorPane prefHeight="300.0" prefWidth="500.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="home.accounting.view.MainController">
   <children>
      <TableView fx:id="waterTable" layoutX="31.0" layoutY="50.0" prefHeight="200.0" prefWidth="200.0" AnchorPane.bottomAnchor="50.0" AnchorPane.leftAnchor="30.0" AnchorPane.rightAnchor="30.0" AnchorPane.topAnchor="50.0">
        <columns>
          <TableColumn fx:id="flat" maxWidth="75.0" prefWidth="75.0" text="Flat" />
          <TableColumn fx:id="newValue" prefWidth="185.0" text="New Value" />
            <TableColumn fx:id="oldValue" prefWidth="185.0" text="Old Value" />
        </columns>
      </TableView>
   </children>
</AnchorPane>
MainController.java

public class MainApp extends Application {

    private AnchorPane rootLayout;

    @Override
    public void start(Stage primaryStage) {

        primaryStage.setTitle("Test");
        try {
            FXMLLoader loader = new FXMLLoader();
            loader.setLocation(MainApp.class.getResource("view/Main.fxml"));
            rootLayout = (AnchorPane)loader.load();
            Scene scene = new Scene(rootLayout);
            primaryStage.setScene(scene);
            primaryStage.show();
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

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

    @FXML
    private TableView<Water> waterTable;

    @FXML
    private TableColumn<Water, Integer> flat;

    @FXML
    private TableColumn<Water, Integer> newValue;

    @FXML TableColumn<Water, Integer> oldValue;

    private List<Water> waterList;

    private static final String waterFormat = "0.0";

    private static final StringConverter<Integer> VALUE_CONVERTER = new StringConverter<Integer>() {

        @Override
        public String toString(Integer object) {
            System.out.println("TO STRING CONVERTER: "+object);
            return object == null ? "" : convertToString(object);
        }

        @Override
        public Integer fromString(String string) {
            System.out.println("TO INTEGER CONVERTER:"+string+";"+string.isEmpty());
            return string.isEmpty() ? null : convertToInt(string);
        }

    };


    @FXML
    private void initialize(){
        createObjects();
        setupCells();
        createRows();
    }

    private void createObjects(){
        waterList = new ArrayList<>();

        for(int i=0; i<5; i++){
            waterList.add(new Water(i+1));
        }
    }

    private void setupCells(){
        flat.setCellValueFactory(cellData -> new ReadOnlyObjectWrapper<>(cellData.getValue().getFlat()));

        newValue.setCellValueFactory(cellData -> new ReadOnlyObjectWrapper<>(cellData.getValue().getNewValue()));
        newValue.setCellFactory(new Callback<TableColumn<Water,Integer>, TableCell<Water, Integer>>() {

            @Override
            public TableCell<Water, Integer> call(TableColumn<Water, Integer> param) {
                return new TableCell<Water, Integer>(){

                    private final TextFormatter<Integer> formatter;
                    private final TextField textField;
                    {
                        textField = new TextField();
                        formatter = new TextFormatter<>(VALUE_CONVERTER, null, null);
                        textField.setTextFormatter(formatter);
                    }
                    @Override
                    protected void updateItem(Integer value, boolean empty){
                        super.updateItem(value, empty);
                        if (empty){
                            setGraphic(null);
                        } else {
                            setGraphic(textField);
                            formatter.setValue(value);
                        }
                    }
                };   
            }
        });
    }

    private void createRows(){
        waterTable.setItems(FXCollections.observableArrayList(waterList));
    }

    private static int convertToInt(String water){
        int waterInt = 0;
        try{
            BigDecimal userInput = new BigDecimal(water);
            DecimalFormat waterConverter = new DecimalFormat(waterFormat);
            String waterString = waterConverter.format(userInput);
            waterInt = Integer.parseInt(String.valueOf(new BigDecimal(waterString).movePointRight(1)));
        }catch (Exception e) {
            e.printStackTrace();
        }

        return waterInt;
    }

    private static String convertToString(int water){
        System.out.println("TO STRING CONVERTER: "+water);
        BigDecimal userInput = new BigDecimal(water);
        DecimalFormat waterConverter = new DecimalFormat(waterFormat);
        String waterString = waterConverter.format(userInput.movePointLeft(1));
        return waterString;
    }
}
public class Water {

    private Integer flat;
    private Integer newValue;
    private Integer oldValue;

    public Water(Integer flat){
        this.flat = flat;
    }

    public Integer getFlat() {
        return flat;
    }

    public void setFlat(Integer flat) {
        this.flat = flat;
    }

    public Integer getNewValue() {
        return newValue;
    }

    public void setNewValue(Integer newValue) {
        this.newValue = newValue;
    }

    public Integer getOldValue() {
        return oldValue;
    }

    public void setOldValue(Integer oldValue) {
        this.oldValue = oldValue;
    }
}
结果:


我不确定您真正想要实现的目标是什么:将十进制存储为整数?我想消除这个错误,如果从终端删除0,并且用户移动到不同的字段,则在再次单击此字段之前,0不会返回,原因是不清楚:。Pagblo,问题是我有粗体字的问题。我发布了我的完整代码。我想如果你尝试一下,你会更清楚问题是什么。如果您尝试键入22.0并点击
Enter
,然后删除0并再次点击
Enter
,您将自动获得22.0。在2.0的情况下,您不会得到相同的结果。我就是不明白为什么22.0会和2.0不同?我已经试过你的代码了。我总是有一个
NumberFormatException
,这是我从一开始就指出的。您的类型(Integer、BigDecimal)不兼容。。。