无法在文本字段中获取文本输入以解析为双精度

Posted

技术标签:

【中文标题】无法在文本字段中获取文本输入以解析为双精度【英文标题】:Unable to get text input in text field to parse to double 【发布时间】:2018-07-04 21:26:15 【问题描述】:

我无法从流窗格的文本字段中的用户输入中获取文本。这似乎非常基本,我已经尝试过其他类似帖子的建议,但它们没有帮助。我需要访问输入以将其转换为双精度,以便对其进行计算。我的按钮设置为在单击时获取用户输入,这就是我遇到错误消息的时候:

Exception in thread "JavaFX Application Thread" 
    java.lang.NumberFormatException: empty String

任何其他建议表示赞赏;我是一个新程序员。该问题首先出现在 getLoanAmount 方法中,但也出现在需要获取我使用的其他文本字段中的文本的其他方法上。

import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.FlowPane;

//this class sets up the GUI and casts the data collected to variables for usage elsewhere
public class loanWithFeatures extends Application 

    //define my constants
    final int MONTHS_IN_YEAR = 12;

    TextField loanAmountTF = new TextField(); 
    TextField termTF = new TextField(); 
    TextField interestRateTF = new TextField();

    //main method 
    public static void main(String[] args)  
        Application.launch(args);

     

    @Override
    public void start(Stage primaryStage) 

        //define my button
        Button btGo = new Button("Calculate Total Interest Cost");
        btGo.setOnAction(new Calculate()); 

        //make my flowpane 
        FlowPane flow = new FlowPane(); 

        flow.setPadding(new Insets(11, 12, 13, 14));  
        flow.setHgap(5); 
        flow.setVgap(5); 

        //for some reason this has to be in this method. It didn't work above 
        loanAmountTF.setPrefWidth(800);  
        termTF.setPrefWidth(800); 
        interestRateTF.setPrefWidth(800); 

        flow.getChildren().addAll(new Label("Loan Amount:"), loanAmountTF); 
        termTF.setPrefColumnCount(2); 
        flow.getChildren().addAll(new Label("Term"), termTF);
        interestRateTF.setPrefColumnCount(2); 
        flow.getChildren().addAll(new Label("Rate"), interestRateTF); 

        flow.getChildren().addAll(btGo); 

        //make the scene, put scene in flowpane 
        Scene scene = new Scene(flow); 

        //stage title 
        primaryStage.setTitle("Total Interest Cost"); 

        //add scene to the stage 
        primaryStage.setScene(scene); 

        //show the stage 
        primaryStage.show(); 
    

    class Calculate implements EventHandler<ActionEvent>  
        @Override 
        public void handle(ActionEvent e)  

            //define my variables 
            double loanAmount = 0, term = 0, rate = 0, monthlyPayment = 0, monthlyInterest = 0, monthlyPrincipal =0, totalRepaid = 0, totalInterest =0, totalInterestPercentage =0; 
            double periodicInterestRate = 0, remainingPrincipal =0; 

            loanWithFeatures newLoan = new loanWithFeatures(); 
            loanAmount = newLoan.getLoanAmount(); 
            term = newLoan.getTerm(term); 
            rate = newLoan.getRate(rate); 
            periodicInterestRate = newLoan.periodicInterestRate(rate); 
            monthlyPayment = newLoan.monthlyPayment(loanAmount, periodicInterestRate, term); 
            remainingPrincipal = newLoan.remainingPrincipal(loanAmount, monthlyPayment, monthlyInterest); 
            monthlyInterest = newLoan.monthlyInterest(monthlyPayment, remainingPrincipal, periodicInterestRate); 
            monthlyPrincipal = newLoan.monthlyPrincipal(monthlyPayment, monthlyInterest); 
            totalRepaid = newLoan.totalRepaid(monthlyPayment, term); 
            totalInterest = newLoan.totalInterest(totalRepaid, loanAmount);
            totalInterestPercentage = newLoan.totalInterestPercentage(loanAmount, totalInterest); 
        
    

    //method to get loan amount 
    public double getLoanAmount()  

        double loanAmountDouble = Double.parseDouble(loanAmountTF.getText()); 

        return loanAmountDouble; 
    

    //method to get term 
    public int getTerm(double term)  
        //define a string var, assign the value from textfield to that, cast to int, return int
        String termInput;  

        termInput = termTF.getText(); 

        int termIntYear = Integer.parseInt(termInput); 
        int termIntMonths = termIntYear * MONTHS_IN_YEAR; 

        return termIntMonths;  
    

    //method to get rate
    public double getRate(double rate)  
        String rateInput; 

        rateInput = interestRateTF.getText(); 

        double rateDouble = Integer.parseInt(rateInput); 

        return rateDouble; 
    

    //method to define balloon payment, when it occurs


    //come back to this, I want it to be a checkbox, I don't know how to do that yet


    //method, get interest only or no?
    /*public boolean getInterestOnly(boolean interestOnly)  
        Boolean interestOnlyBool = false;  
        String interestOnlyString = "uninitialized"; 

        interestOnlyString = interestOnlyTF.getText(); 

        //this only works if they input true, not something like yes 
        //TODO redo this with a radio list or dropdown that shows only true or false as selections 
        interestOnlyBool = Boolean.parseBoolean(interestOnlyString); 

        return interestOnlyBool; 
     */

    //method, type of amortization
    //TODO come do this later when I know other types of amortization, just make it do full amortization right now


    //method early repayment penalty?
    //TODO do this after I do the math of the prepayment penalty 


    //this method calculates the monthly payment
    public double monthlyPayment(double loanAmount, double periodicInterestRate, double term)  
        double monthlyPaymentDenominator = (Math.pow(1 + periodicInterestRate, term) -1) / (periodicInterestRate * Math.pow(1 + periodicInterestRate, term));
        double monthlyPayment = loanAmount / monthlyPaymentDenominator; 

        return monthlyPayment; 
     

    public double remainingPrincipal(double loanAmount, double monthlyPayment, double monthlyInterest )  
        double remainingPrincipal = loanAmount - (monthlyPayment - monthlyInterest); 

        return remainingPrincipal; 
    

    public double monthlyInterest(double monthlyPayment, double remainingPrincipal, double periodicIntRate)  
        double monthlyInterest = remainingPrincipal * periodicIntRate;   

        return monthlyInterest; 
    

    //this method calculates monthly principal payment 
    public double monthlyPrincipal(double monthlyPayment, double monthlyInterest)  
        double monthlyPrincipal = monthlyPayment - monthlyInterest; 

        return monthlyPrincipal; 
    

    public double periodicInterestRate(double rate)  

        double periodicIntRate = rate / MONTHS_IN_YEAR; 

        return periodicIntRate;
    

    public double totalRepaid(double monthlyPayment, double term)  
        double totalRepaid = monthlyPayment * term; 

        return totalRepaid; 
    

    //this method calculates the total interest paid on the loan
    public double totalInterest(double totalRepaid, double loanAmount)  
        double totalInterest = totalRepaid - loanAmount; 

        return totalInterest; 
     

    //this method calculates total interest percentage
    public double totalInterestPercentage(double loanAmount, double totalInterest)  
        double totalInterestPercentage = totalInterest/loanAmount; 

        return totalInterestPercentage; 
     


【问题讨论】:

“我无法从文本字段访问用户输入” -- 请edit您的问题并解释是什么阻止您访问输入,请访问@ 987654322@ 尤其是阅读How to Ask 以了解如何有效地使用本网站。 谢谢,吉姆。我做了改变。希望这能让它更清楚。感谢您的建议 - 我是社区的新手。 为什么要加倍 rateDouble = Integer.parseInt(rateInput);不是双倍 rateDouble = Double.parseDouble(rateInput); ? 该字段是否也已实际填写?见***.com/questions/37817311/… 【参考方案1】:

Java 中的实例和类存在一个基本问题。你正在做的是调用你的类的一个新实例loanWithFeatures。此实例与您的应用程序在main 中启动的实例不同(您试图从中获取TextField 的文本)。

loanWithFeatures newLoan = new loanWithFeatures(); 
loanAmount = newLoan.getLoanAmount(); 

所以我的建议是省略实例调用并像这样:

class Calculate implements EventHandler<ActionEvent> 
    @Override
    public void handle(ActionEvent e) 

        //define my variables
        double loanAmount = 0, term = 0, rate = 0, monthlyPayment = 0, monthlyInterest = 0, monthlyPrincipal =0, totalRepaid = 0, totalInterest = 0, totalInterestPercentage = 0;
        double periodicInterestRate = 0, remainingPrincipal = 0;

        loanAmount = newLoan.getLoanAmount();
        term = getTerm(term);
        rate = getRate(rate);
        periodicInterestRate = periodicInterestRate(rate);
        monthlyPayment = monthlyPayment(loanAmount, periodicInterestRate, term);
        remainingPrincipal = remainingPrincipal(loanAmount, monthlyPayment, monthlyInterest);
        monthlyInterest = monthlyInterest(monthlyPayment, remainingPrincipal, periodicInterestRate);
        monthlyPrincipal = monthlyPrincipal(monthlyPayment, monthlyInterest);
        totalRepaid = totalRepaid(monthlyPayment, term);
        totalInterest = totalInterest(totalRepaid, loanAmount);
        totalInterestPercentage = totalInterestPercentage(loanAmount, totalInterest);
    

【讨论】:

您忘记添加此行:loanAmount = getLoanAmount();。尽管如此,这应该是答案。

以上是关于无法在文本字段中获取文本输入以解析为双精度的主要内容,如果未能解决你的问题,请参考以下文章

无法在密码文本字段中输入文本以进行 iOS UI 测试

获取文本输入字段中的光标位置(以字符为单位)

获取文本输入字段中的光标位置(以字符为单位)

如何在 vs code 上的 jupyter 中获取输入,我尝试运行 input() 函数以从弹出文本字段中获取输入,但它进入无限循环,

C++ 测试输入是不是为双精度/字符

以编程方式选择输入字段中的部分文本