Aug 11, 2020

Advance Calculator using JavaFX

Updated: Mar 25, 2021

JavaFX is a wonderful improvement to the Java programming language. It includes a wide number of new user interface controls and the ability to add cascade style sheets (CSS), Animations etc. Today, Let’s see how we can build a beautiful advanced calculator in JavaFX with CSS styling. This calculator is done using eclipse IDE and JavaFX Scene Builder 2.0.

This is an advance calculator with a simple UI where you can Add, Substract, Multiply, Divide, Log, Exponential, Factorial, and many more functions are available to calculate

Main.fxml

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

 
<?import javafx.geometry.Insets?>
 
<?import javafx.scene.control.Button?>
 
<?import javafx.scene.control.Label?>
 
<?import javafx.scene.layout.AnchorPane?>
 
<?import javafx.scene.text.Font?>
 

 
<AnchorPane prefHeight="455.0" prefWidth="294.0" xmlns="http://javafx.com/javafx/11.0.1" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.MainController">
 
<children>
 
<Label fx:id="result" alignment="CENTER_RIGHT" prefHeight="66.0" prefWidth="419.0" style="-fx-background-color: white; -fx-border-color: black;">
 
<font>
 
<Font size="37.0" />
 
</font>
 
<opaqueInsets>
 
<Insets />
 
</opaqueInsets>
 
</Label>
 
<AnchorPane layoutX="-4.0" layoutY="66.0" prefHeight="392.0" prefWidth="423.0" style="-fx-background-color: silver;">
 
<children>
 
<Button layoutX="146.0" layoutY="162.0" mnemonicParsing="false" onAction="#processNumber" prefHeight="49.0" prefWidth="52.0" text="6">
 
<font>
 
<Font size="25.0" />
 
</font>
 
</Button>
 
<Button layoutX="83.0" layoutY="100.0" mnemonicParsing="false" onAction="#processNumber" prefHeight="49.0" prefWidth="52.0" text="8">
 
<font>
 
<Font size="25.0" />
 
</font>
 
</Button>
 
<Button layoutX="146.0" layoutY="100.0" mnemonicParsing="false" onAction="#processNumber" prefHeight="49.0" prefWidth="52.0" text="9">
 
<font>
 
<Font size="25.0" />
 
</font>
 
</Button>
 
<Button layoutX="14.0" layoutY="162.0" mnemonicParsing="false" onAction="#processNumber" prefHeight="49.0" prefWidth="52.0" text="4">
 
<font>
 
<Font size="25.0" />
 
</font>
 
</Button>
 
<Button layoutX="83.0" layoutY="162.0" mnemonicParsing="false" onAction="#processNumber" prefHeight="49.0" prefWidth="52.0" text="5">
 
<font>
 
<Font size="25.0" />
 
</font>
 
</Button>
 
<Button layoutX="14.0" layoutY="100.0" mnemonicParsing="false" onAction="#processNumber" prefHeight="49.0" prefWidth="52.0" text="7">
 
<font>
 
<Font size="25.0" />
 
</font>
 
</Button>
 
<Button layoutX="14.0" layoutY="223.0" mnemonicParsing="false" onAction="#processNumber" prefHeight="49.0" prefWidth="52.0" text="1">
 
<font>
 
<Font size="25.0" />
 
</font>
 
</Button>
 
<Button layoutX="83.0" layoutY="223.0" mnemonicParsing="false" onAction="#processNumber" prefHeight="49.0" prefWidth="52.0" text="2">
 
<font>
 
<Font size="25.0" />
 
</font>
 
</Button>
 
<Button layoutX="146.0" layoutY="223.0" mnemonicParsing="false" onAction="#processNumber" prefHeight="49.0" prefWidth="52.0" text="3">
 
<font>
 
<Font size="25.0" />
 
</font>
 
</Button>
 
<Button layoutX="14.0" layoutY="295.0" mnemonicParsing="false" onAction="#processNumber" prefHeight="54.0" prefWidth="121.0" text="0">
 
<font>
 
<Font size="25.0" />
 
</font>
 
</Button>
 
<Button layoutX="146.0" layoutY="293.0" mnemonicParsing="false" onAction="#processNumber" prefHeight="49.0" prefWidth="52.0" text=".">
 
<font>
 
<Font size="25.0" />
 
</font>
 
</Button>
 
<Button layoutX="216.0" layoutY="295.0" mnemonicParsing="false" onAction="#processBinaryOperator" prefHeight="49.0" prefWidth="52.0" text="=">
 
<font>
 
<Font size="25.0" />
 
</font>
 
</Button>
 
<Button layoutX="216.0" layoutY="100.0" mnemonicParsing="false" onAction="#processBinaryOperator" prefHeight="49.0" prefWidth="52.0" text="-">
 
<font>
 
<Font size="25.0" />
 
</font>
 
</Button>
 
<Button layoutX="216.0" layoutY="162.0" mnemonicParsing="false" onAction="#processBinaryOperator" prefHeight="49.0" prefWidth="52.0" text="*">
 
<font>
 
<Font size="25.0" />
 
</font>
 
</Button>
 
<Button layoutX="216.0" layoutY="223.0" mnemonicParsing="false" onAction="#processBinaryOperator" prefHeight="49.0" prefWidth="52.0" text="/">
 
<font>
 
<Font size="25.0" />
 
</font>
 
</Button>
 
<Button layoutX="289.0" layoutY="100.0" mnemonicParsing="false" onAction="#processUnaryOperator" prefHeight="49.0" prefWidth="52.0" text="ln">
 
<font>
 
<Font size="15.0" />
 
</font>
 
</Button>
 
<Button layoutX="355.0" layoutY="100.0" mnemonicParsing="false" onAction="#processUnaryOperator" prefHeight="49.0" prefWidth="52.0" text="Cos">
 
<font>
 
<Font size="15.0" />
 
</font>
 
</Button>
 
<Button layoutX="289.0" layoutY="162.0" mnemonicParsing="false" onAction="#processBinaryOperator" prefHeight="49.0" prefWidth="52.0" text="x^y">
 
<font>
 
<Font size="15.0" />
 
</font>
 
</Button>
 
<Button layoutX="355.0" layoutY="162.0" mnemonicParsing="false" onAction="#processUnaryOperator" prefHeight="49.0" prefWidth="52.0" text="Tan">
 
<font>
 
<Font size="15.0" />
 
</font>
 
</Button>
 
<Button layoutX="289.0" layoutY="223.0" mnemonicParsing="false" onAction="#processUnaryOperator" prefHeight="49.0" prefWidth="52.0" text="x^2">
 
<font>
 
<Font size="15.0" />
 
</font>
 
</Button>
 
<Button layoutX="355.0" layoutY="223.0" mnemonicParsing="false" onAction="#processBinaryOperator" prefHeight="49.0" prefWidth="52.0" text="Mod">
 
<font>
 
<Font size="15.0" />
 
</font>
 
</Button>
 
<Button layoutX="289.0" layoutY="295.0" mnemonicParsing="false" onAction="#processUnaryOperator" prefHeight="49.0" prefWidth="52.0" text="x^3">
 
<font>
 
<Font size="15.0" />
 
</font>
 
</Button>
 
<Button layoutX="355.0" layoutY="295.0" mnemonicParsing="false" onAction="#processUnaryOperator" prefHeight="49.0" prefWidth="52.0" text="x!">
 
<font>
 
<Font size="15.0" />
 
</font>
 
</Button>
 
<Button layoutX="14.0" layoutY="28.0" mnemonicParsing="false" onAction="#ClearFunction" prefHeight="49.0" prefWidth="52.0" text="c">
 
<font>
 
<Font size="25.0" />
 
</font>
 
</Button>
 
<Button layoutX="83.0" layoutY="28.0" mnemonicParsing="false" onAction="#processUnaryOperator" prefHeight="49.0" prefWidth="52.0" text="e^x">
 
<font>
 
<Font size="15.0" />
 
</font>
 
</Button>
 
<Button layoutX="146.0" layoutY="28.0" mnemonicParsing="false" onAction="#processUnaryOperator" prefHeight="49.0" prefWidth="52.0" text="√">
 
<font>
 
<Font size="25.0" />
 
</font>
 
</Button>
 
<Button layoutX="216.0" layoutY="28.0" mnemonicParsing="false" onAction="#processBinaryOperator" prefHeight="49.0" prefWidth="52.0" text="+">
 
<font>
 
<Font size="25.0" />
 
</font>
 
</Button>
 
<Button layoutX="289.0" layoutY="28.0" mnemonicParsing="false" onAction="#processUnaryOperator" prefHeight="49.0" prefWidth="52.0" text="Log">
 
<font>
 
<Font size="15.0" />
 
</font>
 
</Button>
 
<Button layoutX="355.0" layoutY="28.0" mnemonicParsing="false" onAction="#processUnaryOperator" prefHeight="49.0" prefWidth="52.0" text="Sin">
 
<font>
 
<Font size="15.0" />
 
</font>
 
</Button>
 
</children>
 
</AnchorPane>
 
</children>
 
</AnchorPane>
 

MainController.java

package application;
 

 

 
import javafx.event.ActionEvent;
 
import javafx.fxml.FXML;
 
import javafx.scene.control.Button;
 
import javafx.scene.control.Label;
 

 

 
public class MainController {
 
@FXML
 
private Label result;
 

 
private float number1=0;
 

 
private float number2=0;
 

 
private String operator="";
 

 
private boolean start=true;
 

 
private Calclulate calculate=new Calclulate();
 

 
@FXML
 
public void processNumber(ActionEvent event){
 
if(start){
 
result.setText("");
 
start=false;
 
}
 
String value=((Button)event.getSource()).getText();
 
result.setText(result.getText()+ value);
 
}
 

 
@FXML
 
public void processBinaryOperator(ActionEvent event) {
 
String value=((Button)event.getSource()).getText();
 
if(!value.equals("=")){
 
if(!operator.isEmpty())
 
return;
 

 
operator = value;
 
number1=Float.parseFloat(result.getText());
 
result.setText("");
 
}else{
 
if(operator.isEmpty())
 
return;
 

 
number2=Float.parseFloat(result.getText());
 
float output=calculate.calculateBinaryNumber(number1, number2, operator);
 
result.setText(String.valueOf(output));
 
operator="";
 
}
 
}
 
public void processUnaryOperator(ActionEvent event) {
 

 
String value=((Button)event.getSource()).getText();
 
if(!operator.isEmpty())
 
return;
 

 
operator = value;
 
number1=Float.parseFloat(result.getText());
 
result.setText("");
 

 
float output=calculate.calculateUnaryNumber(number1,operator);
 
result.setText(String.valueOf(output));
 
operator="";
 
}
 

 
public void ClearFunction(ActionEvent event){
 
operator="";
 
start=true;
 
result.setText("");
 
}
 
}
 

Calclulate.Java

package application;
 

 
public class Calclulate {
 

 
public float calculateUnaryNumber(float number1,String operator){
 
switch (operator) {
 
case "√":
 
return (long)Math.sqrt(number1);
 
case "Sin":
 
return (float)Math.sin(number1);
 
case "Cos":
 
return (long)Math.cos(number1);
 
case "Tan":
 
return (float)Math.tan(number1);
 
case "e^x":
 
return (float) Math.exp(number1);
 
case "x^2":
 
return number1*number1;
 
case "x^3":
 
return number1*number1*number1;
 
case "Log":
 
return (float) Math.log10(number1);
 
case "ln":
 
return (float) Math.log(number1);
 
case "x!":
 
int fact=1;
 
for(int i=1;i<=number1;i++)
 
fact=fact*i;
 
return fact;
 
default:
 
break;
 
}
 
return 0;
 
}
 
public float calculateBinaryNumber(float number1,float 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 "Mod":
 
return number1 % number2;
 
case "x^y":
 
return (float) Math.pow(number1, number2);
 
default:
 
break;
 
}
 
return 0;
 
}
 
}
 

Main.java

package application;
 

 
import javafx.application.Application;
 

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

 

 
public class Main extends Application {
 
@Override
 
public void start(Stage primaryStage) {
 
try {
 
Parent root = FXMLLoader.load(getClass().getResource("/application/Main.fxml"));
 
Scene scene = new Scene(root);
 
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
 
primaryStage.setScene(scene);
 
primaryStage.show();
 
} catch(Exception e) {
 
e.printStackTrace();
 
}
 
}
 

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

Output/Screen Shot