JavaFX计算器 - 如何添加平方根和平方根函数?

时间:2016-06-06 20:39:14

标签: java javafx

我正在制作一个JavaFX计算器。我正在尝试开发一个方形和平方根函数,但我很困惑在Controller.java中为该方法编写的内容。我不确定他们是否正常工作,如果我点击它们就没有任何回报。我想,"好吧,存储的值是什么?"我尝试向其添加0以查看是否存在结果和错误。

App.java:

package com.honors.calc;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class App extends Application {

    @Override
    public void start(Stage primaryStage) throws Exception {
        Parent root = FXMLLoader.load(getClass().getResource("ui.fxml"));

        primaryStage.setScene(new Scene(root));
        primaryStage.show();

    }

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

    }

}

Model.java:

package com.honors.calc;

public class Model {

    public long calculate(long number1, long number2, String operator) {
        switch (operator) {
            case "+":
                return number1 + number2;
            case "-":
                return number1 - number2;
            case "*":
                return number1 * number2;
            case "/":
                if (number2 == 0)
                    return 0;

                return number1 / number2;
            case "C":
                number1 = 0;
                number2 = 0;
                return 0;
            case "CE":
                number2 = 0;
                return 0;
            case "x²":
                return number1 * number1;
            case "√":
                return (long) Math.sqrt(number1);
        }
        System.out.println("Unknown operator - " + operator);
        return 0;
    }
}

Controller.java:

package com.honors.calc;

import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.text.Text;

public class Controller {
    @FXML
    private Text output;

    private long number1 = 0;
    private String operator = "";
    private boolean start = true;

    private Model model = new Model();

    @FXML
    private void processNumpad(ActionEvent event) {
        if (start) {
            // clear screen
            output.setText("");
            start = false;
        }
        String value = ((Button)event.getSource()).getText();
        output.setText(output.getText() + value);
    }

    @FXML
    private void processOperator(ActionEvent event) {
        String value = ((Button)event.getSource()).getText();

        if(!"=".equals(value)) {
            if (!operator.isEmpty())
                return;

            operator = value;
            number1 = Long.parseLong(output.getText());
            output.setText("");
        } else {
            // calculation
            if (operator.isEmpty())
                return;

            output.setText(String.valueOf(model.calculate(number1, Long.parseLong(output.getText()), operator)));
            operator = "";
            // reset
            start = true;
        }
    }

    @FXML
    private void processClear(ActionEvent event) {
        output.setText("0");
    }

    @FXML
    private void processClearEntry(ActionEvent event) {
        output.setText("");
    }

    @FXML
    private void processSquare(ActionEvent event) {


    }

    @FXML
    private void processSquareRoot(ActionEvent event) {

    }
}

ui.fxml:

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

<?import java.net.*?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.beans.property.*?>
<?import javafx.geometry.*?>
<?import javafx.scene.shape.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.text.*?>
<?import javafx.scene.paint.Color?>

<VBox spacing="10" alignment="CENTER" prefWidth="300" prefHeight="320" fx:controller="com.honors.calc.Controller" xmlns:fx="http://javafx.com/fxml">
    <fx:define>
        <Font fx:id="FONT" size="18" />
    </fx:define>

    <StackPane alignment="CENTER">
        <Rectangle fill="TRANSPARENT" stroke="GRAY" width="230" height="50" />
        <Text fx:id="output" font="$FONT" />
    </StackPane>

    <HBox spacing="10" alignment="CENTER">
        <Button text="C" prefWidth="50" font="$FONT" onAction="#processClear" />
        <Button text="CE" prefWidth="50" font="$FONT" onAction="#processClearEntry" />
        <Button text="x²" prefWidth="50" font="$FONT" onAction="#processSquare" />
        <Button text="√" prefWidth="50" font="$FONT" onAction="#processSquareRoot" />
    </HBox>

    <HBox spacing="10" alignment="CENTER">
        <Button text="7" prefWidth="50" font="$FONT" onAction="#processNumpad" />
        <Button text="8" prefWidth="50" font="$FONT" onAction="#processNumpad" />
        <Button text="9" prefWidth="50" font="$FONT" onAction="#processNumpad" />
        <Button text="/" prefWidth="50" font="$FONT" onAction="#processOperator" />
    </HBox>

    <HBox spacing="10" alignment="CENTER">
        <Button text="4" prefWidth="50" font="$FONT" onAction="#processNumpad" />
        <Button text="5" prefWidth="50" font="$FONT" onAction="#processNumpad" />
        <Button text="6" prefWidth="50" font="$FONT" onAction="#processNumpad" />
        <Button text="*" prefWidth="50" font="$FONT" onAction="#processOperator" />
    </HBox>

    <HBox spacing="10" alignment="CENTER">
        <Button text="1" prefWidth="50" font="$FONT" onAction="#processNumpad" />
        <Button text="2" prefWidth="50" font="$FONT" onAction="#processNumpad" />
        <Button text="3" prefWidth="50" font="$FONT" onAction="#processNumpad" />
        <Button text="-" prefWidth="50" font="$FONT" onAction="#processOperator" />
    </HBox>

    <HBox spacing="10" alignment="CENTER">
        <Button text="0" prefWidth="110" font="$FONT" onAction="#processNumpad" />
        <Button text="=" prefWidth="50" font="$FONT" onAction="#processOperator" />
        <Button text="+" prefWidth="50" font="$FONT" onAction="#processOperator" />
    </HBox>

</VBox>

1 个答案:

答案 0 :(得分:0)

您的主要问题源于此处未处理的NumberFormatException

output.setText(String.valueOf(model.calculate(number1, Long.parseLong(output.getText()), operator)));

由于您的设计需要等于启动实际计算,因此它还假设存在第二个数字。所以这可以通过以下输入重新创建:

  

5x²=(作为第二个值未提供,正在为第二个值解析空字符串)

快速修复就是用以下内容替换该行:

        long number2 = 0;
        try{
            number2 = Long.parseLong(output.getText());
        }catch (NumberFormatException nfe){
            System.out.println("Invalid value provided for second value");
        }
        output.setText(String.valueOf(model.calculate(number1, number2, operator)));

并更新你的fxml:

<Button text="x²" prefWidth="50" font="$FONT" onAction="#processOperator" />
<Button text="√" prefWidth="50" font="$FONT" onAction="#processOperator" />

这将消除对这些方法的需求:

    @FXML
    private void processSquare(ActionEvent event) {    
    }

    @FXML
    private void processSquareRoot(ActionEvent event) {    
    }

即使你要实现它们,它们也无法在不改进底层设计的情况下计算值,因为所需的操作和数量仅在processOperator方法中使用

<小时/> 作为旁注,我建议您阅读Shunting Yard Algorithm。它用于将中缀符号方程解析为它们的后缀等价物,以便于计算。在过去亲自使用它来创建自定义科学计算器,它将允许您为自己的计算器添加其他功能。实现的主要好处是能够使用其他运算符输入更复杂的方程式。

即使你最终没有使用它,知道/了解

也是一个有趣的算法