0

So I'm a college student presently learning Java and JavaFX by myself, with some help from you all.

I'm trying to start by making a relatively simple calculator, customizing it with some CSS. My program works fine, the only real problem is the lag whenever I actually calculate what I want. So I'll go, "5 + 5 =" and as soon as I hit equals it lags and then shows "10". Not sure why and I haven't found much on it.

Thanks for the help in advance.

NOTE: If you have any other suggestions to help me improve my code, feel free to post it. I have a long way to go.

import javafx.application.Application;
import javafx.scene.control.*;
import javafx.scene.input.*;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.geometry.Insets;
import javafx.scene.layout.*;
import javafx.scene.text.Font;
import javax.script.ScriptEngineManager;
import java.math.BigDecimal;
import javax.script.ScriptEngine;

public class practice3 extends Application {

    Stage window;
    Button plus,
    minus,
    divide,
    multiply,
    clear,
    zero,
    one,
    two,
    three,
    four,
    five,
    six,
    seven,
    eight,
    nine,
    decimal,
    equals;
    TextField display;
    double total,
    num1;
    String input = "";
    String equationInput = ""; //equationInput will store all data up to a symbol is pressed
    Label equation;

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

    }

    @Override
    public void start(Stage primaryStage) throws Exception {

        window = primaryStage;
        window.setTitle("Simple Calculator");

        //Display Text Field
        display = new TextField();
        display.setEditable(false);
        display.setPrefHeight(70);
        display.setFont(Font.font("Verdana", 50));

        equation = new Label();
        equation.setPrefHeight(70);
        equation.setFont(Font.font("Verdana", 12));
        equation.setText(equationInput);
        equation.setPrefWidth(209);
        equation.setPadding(new Insets(0, 0, 3, 3));

        //Buttons
        plus = new Button("+");
        plus.setPrefSize(70, 70);
        plus.setOnAction(e - >operationButton("+"));

        minus = new Button("-");
        minus.setPrefSize(70, 70);
        minus.setOnAction(e - >operationButton("-"));

        divide = new Button("/");
        divide.setPrefSize(70, 70);
        divide.setOnAction(e->operationButton("/"));

        multiply = new Button("*");
        multiply.setPrefSize(70, 70);
        multiply.setOnAction(e->operationButton("*"));

        clear = new Button("C");
        clear.setPrefSize(70, 70);
        clear.setOnAction(e->clearButton());

        equals = new Button("=");
        equals.setPrefSize(70, 70);
        equals.setOnAction(e->{
            try {
                calculate();
            } catch(Exception e1) {
                System.out.println("Error in code.");
            }
        });

        decimal = new Button(".");
        decimal.setPrefSize(70, 70);
        decimal.setOnAction(e->decimalButton());

        //Numbers
        one = new Button("1");
        one.setPrefSize(70, 70);
        one.setOnAction(e->numberButton("1"));

        two = new Button("2");
        two.setPrefSize(70, 70);
        two.setOnAction(e->numberButton("2"));

        three = new Button("3");
        three.setPrefSize(70, 70);
        three.setOnAction(e->numberButton("3"));

        four = new Button("4");
        four.setPrefSize(70, 70);
        four.setOnAction(e->numberButton("4"));

        five = new Button("5");
        five.setPrefSize(70, 70);
        five.setOnAction(e->numberButton("5"));

        six = new Button("6");
        six.setPrefSize(70, 70);
        six.setOnAction(e->numberButton("6"));

        seven = new Button("7");
        seven.setPrefSize(70, 70); //WidthxHeight
        seven.setOnAction(e->numberButton("7"));

        eight = new Button("8");
        eight.setPrefSize(70, 70);
        eight.setOnAction(e->numberButton("8"));

        nine = new Button("9");
        nine.setPrefSize(70, 70);
        nine.setOnAction(e->numberButton("9"));

        zero = new Button("0");
        zero.setPrefSize(70, 70);
        zero.setOnAction(e->numberButton("0"));

        BorderPane layout = new BorderPane();
        GridPane grid = new GridPane();
        layout.setCenter(grid);

        layout.setTop(display);

        //Setting Constraints for Buttons and Equation Display
        grid.setConstraints(seven, 0, 1);
        grid.setConstraints(eight, 1, 1);
        grid.setConstraints(nine, 2, 1);
        grid.setConstraints(clear, 3, 0);
        grid.setConstraints(four, 0, 2);
        grid.setConstraints(five, 1, 2);
        grid.setConstraints(six, 2, 2);
        grid.setConstraints(plus, 3, 1);
        grid.setConstraints(one, 0, 3);
        grid.setConstraints(two, 1, 3);
        grid.setConstraints(three, 2, 3);
        grid.setConstraints(minus, 3, 2);
        grid.setConstraints(decimal, 0, 4);
        grid.setConstraints(zero, 1, 4);
        grid.setConstraints(multiply, 3, 3);
        grid.setConstraints(divide, 3, 4);
        grid.setConstraints(equals, 2, 4);
        grid.setConstraints(equation, 0, 0, 3, 1);

        display.setStyle("-fx-focus-color: transparent;");

        grid.getChildren().addAll(seven, eight, nine, clear, four, five, six, plus, one, two, three, minus, decimal, zero, multiply, divide, equals, equation);

        layout.setPadding(new Insets(5, 5, 5, 5));

        display.setText("0");

        Scene scene = new Scene(layout, 290, 462);

        //Keyboard Events
        scene.addEventHandler(KeyEvent.KEY_PRESSED, (key) -> {
            if (key.getCode() == KeyCode.DIGIT1 || key.getCode() == KeyCode.NUMPAD1) {
                numberButton("1");
            }
            else if (key.getCode() == KeyCode.DIGIT2 || key.getCode() == KeyCode.NUMPAD2) {
                numberButton("2");
            }
            else if (key.getCode() == KeyCode.DIGIT3 || key.getCode() == KeyCode.NUMPAD3) {
                numberButton("3");
            }
            else if (key.getCode() == KeyCode.DIGIT4 || key.getCode() == KeyCode.NUMPAD4) {
                numberButton("4");
            }
            else if (key.getCode() == KeyCode.DIGIT5 || key.getCode() == KeyCode.NUMPAD5) {
                numberButton("5");
            }
            else if (key.getCode() == KeyCode.DIGIT6 || key.getCode() == KeyCode.NUMPAD6) {
                numberButton("6");
            }
            else if (key.getCode() == KeyCode.DIGIT7 || key.getCode() == KeyCode.NUMPAD7) {
                numberButton("7");
            }
            else if (key.getCode() == KeyCode.DIGIT8 || key.getCode() == KeyCode.NUMPAD8) {
                numberButton("8");
            }
            else if (key.getCode() == KeyCode.DIGIT9 || key.getCode() == KeyCode.NUMPAD9) {
                numberButton("9");
            }
            else if (key.getCode() == KeyCode.DIGIT0 || key.getCode() == KeyCode.NUMPAD0) {
                numberButton("0");
            }
            else if (key.getCode() == KeyCode.PERIOD || key.getCode() == KeyCode.DECIMAL) {
                decimalButton();
            }
            else if (key.getCode() == KeyCode.ADD) {
                operationButton("+");
            }
            else if (key.getCode() == KeyCode.SUBTRACT) {
                operationButton("-");
            }
            else if (key.getCode() == KeyCode.MULTIPLY) {
                operationButton("*");
            }
            else if (key.getCode() == KeyCode.DIVIDE) {
                operationButton("/");
            }
            else if (key.getCode() == KeyCode.EQUALS) {
                try {
                    calculate();
                } catch(Exception e1) {
                    System.out.println("Error in code.");
                }
            }
            else if (key.getCode() == KeyCode.C) {
                clearButton();
            }
        });

        scene.getStylesheets().add("practice3.css");
        equation.getStyleClass().add("equation-label");
        //End
        window.setScene(scene);
        window.show();

    }

    private void clearButton() {
        input = "";
        total = 0;
        num1 = 0;
        equationInput = "";
        display.setText("0");
        equation.setText("");
    }

    private void numberButton(String value) {
        input += value;
        display.setText(input);

    }

    private void decimalButton() {
        int check;
        if (input.indexOf(".") == -1) {
            if (input == "") {
                input += "0.";
                display.setText(input);
            }
            else {
                input += ".";
                display.setText(input);
            }

        }
    }

    private void operationButton(String symbol) {

        equationInput += input;
        input = "";

        if (symbol == "+") {
            equationInput += " + ";
        }
        else if (symbol == "-") {
            equationInput += " - ";
        }
        else if (symbol == "*") {
            equationInput += " * ";
        }
        else if (symbol == "/") {
            equationInput += " / ";
        }

        equation.setText(equationInput);
        display.setText("0");
    }

    private void calculate() throws Exception {

        String answer = "0";
        double answer1;
        Object eval;

        equationInput += input;
        input = "";

        ScriptEngineManager mgr = new ScriptEngineManager();
        ScriptEngine engine = mgr.getEngineByName("JavaScript");

        eval = engine.eval(equationInput);
        answer1 = new BigDecimal(eval.toString()).doubleValue();
        answer = String.valueOf(answer1);

        equationInput += " = ";
        display.setText(answer);
        equation.setText(equationInput);
    }
}

Also, I would like to mention that I'm not very good at organization yet so if anything seems confusing feel free to ask!

HDJEMAI
  • 9,436
  • 46
  • 67
  • 93
  • 2
    You are calling out to JavaScript to do an eval when you calculate. I haven't done any benchmarking on it, but I guess either the call or (more likely) the retrieval of the script engine is causing the slowness. I'd advise just doing the eval operation in Java (you would have to research how to implement algorithms to do that). If you must use JavaScript, then perhaps creating the ScriptEngine as a member of the application rather than every time you need to run the calculation may be the way to go. Give these ideas a try and see how to goes. – jewelsea Mar 27 '17 at 23:48
  • Once you get it working, if you would like a code review, paste to http://codereview.stackexchange.com (read [the rules](http://codereview.stackexchange.com/help/on-topic) if that seems useful for you). – jewelsea Mar 28 '17 at 00:12
  • I created a [simple calculator](https://gist.github.com/jewelsea/4344564), you could take a look at, but it is a bit too simplistic as it does not implement a proper expression evaluation algorithm (such as the [shunting yard algorithm](http://www.oxfordmathcenter.com/drupal7/node/628) such as [this](http://introcs.cs.princeton.edu/java/43stack/Evaluate.java.html) as mentioned [here](http://stackoverflow.com/questions/8344460/trouble-understanding-what-to-do-with-output-of-shunting-yard-algorithm)). – jewelsea Mar 28 '17 at 00:15

0 Answers0