Calculator in JavaFX

A simple calculator implemented in JavaFX.

Based on the JavaFX calculator script done by Jim Weaver.

calculator screenshot
calculator screenshot

calculator script:


/*
 * Simple calculator implemented in JavaFX
 *
 * Based on the JavaFX calculator program done by Jim Weaver.
 * (http://java.dzone.com/articles/part-deux-building-a-calculato)
 *
 *
 * @author CCH cch.weblog at gmail.com
 * Created on Dec 12, 2008, 11:39:52 AM
 */

import javafx.ext.swing.*;
import javafx.stage.Stage;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.input.*;
import javafx.scene.layout.*;
import javafx.scene.paint.*;
import javafx.scene.shape.*;
import javafx.scene.text.*;
import javafx.scene.transform.*;

var str : String = "";
var tmp : String = "";
var left : Number = 0.0;
var right : Number = 0.0;
var operator : String = "";
var flush : Boolean = false;

// button gradient
def buttonGradient = LinearGradient {
    startX: 0.0,
    startY: 0.0,
    endX: 0.0,
    endY: 1.0
    stops: [
        Stop {
            offset: 0.0
            color: Color.rgb(166, 166, 168)
        },
        Stop {
            offset: 1.0
            color: Color.rgb(122, 122, 122)
        }
    ]
};

// background gradient
def backgroundGradient = LinearGradient {
    startX: 0.0,
    startY: 0.0,
    endX: 0.5,
    endY: 1.0
    stops: [
        Stop {
            offset: 0.0
            color: Color.rgb(128, 128, 64)
        },
        Stop {
            offset: 1.0
            color: Color.rgb(128, 128, 0)
        }
    ]
};

def keyLabels = [
    "7",   "8",    "9",   "/",   "sqrt",
    "4",   "5",    "6",   "x",   "%",
    "1",   "2",    "3",   "-",   "1/x",
    "0",   "+/-",  ".",   "+",   "="
];

Stage {

    title: "Calculator"
    resizable : false

    scene: Scene {
        content: [
            // background
            Rectangle {
                width: 240
                height: 260
                arcWidth: 10
                arcHeight: 10
                fill: backgroundGradient
            },

            // panels, built on top of the background
            VBox {
                transforms: bind Translate.translate(20, 20)
                spacing: 10
                content: [
                    // display panel
                    buildDisplayPanel(),

                    // Backspace, CE and C buttons panel
                    HBox {
                        spacing: 5
                        content: [
                            // Backspace button
                            buildBackspaceButton(),

                            // CE button
                            buildCEButton(),

                            // C button
                            buildCButton(),
                        ]
                    },

                    // numbers and operators panel
                    VBox {
                        spacing: 5
                        content:
                        for (row in [0..3]) {
                            HBox {
                                spacing: 5
                                content:
                                for (column in [0..4]) {
                                    buildKeyButton(row, column);
                                }
                            }
                        }
                    } // end of numbers and operators panel
                ] // end of panels content
            } // end of panels
        ] // end of Scene content
    } // end of Scene
 }

function buildDisplayPanel() {
    SwingTextField {
        text: bind str
        width: 195
        height: 30
        editable: false
        horizontalAlignment : SwingHorizontalAlignment.RIGHT
        style: bind "font: 14pt Dialog; font-weight: bold; "
    }
}

function buildBackspaceButton() : Group {

    Group {
        var rectRef:Rectangle;
        var textRef:Text;
        content: [
            rectRef = Rectangle {
                width: 95
                height: 30
                fill: buttonGradient
            },
            textRef = Text {
                transforms: bind
                Translate.translate(
                    (rectRef.layoutBounds.width -
                     textRef.layoutBounds.width) / 2,
                    (rectRef.layoutBounds.height +
                     textRef.layoutBounds.height) / 2)
                content: "Backspace"
                textOrigin: TextOrigin.BOTTOM
                fill: Color.rgb(222, 222, 222)
                font: Font {
                    name: "Arial Bold"
                    size: 15
                }
            }
        ]
        onMousePressed: function(me:MouseEvent):Void {
            textRef.fill = Color.rgb(0, 0, 0);

            if (tmp != "") {
                tmp = "{tmp.substring(0, tmp.length() - 1)}";
                str = tmp;
            }
        }
        onMouseReleased: function(me:MouseEvent):Void {
            textRef.fill = Color.rgb(222, 222, 222);
        }
        onMouseEntered: function(me:MouseEvent):Void {
            rectRef.fill = Color.rgb(128, 128, 192);
        }
        onMouseExited: function(me:MouseEvent):Void {
            rectRef.fill = buttonGradient
        }
    }
}

function buildCEButton() : Group {

    Group {
        var rectRef:Rectangle;
        var textRef:Text;
        content: [
            rectRef = Rectangle {
                width: 45
                height: 30
                fill: buttonGradient
            },
            textRef = Text {
                transforms: bind
                Translate.translate(
                    (rectRef.layoutBounds.width -
                     textRef.layoutBounds.width) / 2,
                    (rectRef.layoutBounds.height +
                     textRef.layoutBounds.height) / 2)
                content: "CE"
                textOrigin: TextOrigin.BOTTOM
                fill: Color.rgb(222, 222, 222)
                font: Font {
                    name: "Arial Bold"
                    size: 15
                }
            }
        ]
        onMousePressed: function(me:MouseEvent):Void {
            textRef.fill = Color.rgb(0, 0, 0);

            tmp = "0";
            str = tmp;
        }
        onMouseReleased: function(me:MouseEvent):Void {
            textRef.fill = Color.rgb(222, 222, 222);
        }
        onMouseEntered: function(me:MouseEvent):Void {
            rectRef.fill = Color.rgb(128, 128, 192);
        }
        onMouseExited: function(me:MouseEvent):Void {
            rectRef.fill = buttonGradient
        }
    }
}

function buildCButton() : Group {

    Group {
        var rectRef:Rectangle;
        var textRef:Text;
        content: [
            rectRef = Rectangle {
                width: 45
                height: 30
                fill: buttonGradient
            },
            textRef = Text {
                transforms: bind
                Translate.translate(
                    (rectRef.layoutBounds.width -
                     textRef.layoutBounds.width) / 2,
                    (rectRef.layoutBounds.height +
                     textRef.layoutBounds.height) / 2)
                content: "C"
                textOrigin: TextOrigin.BOTTOM
                fill: Color.rgb(222, 222, 222)
                font: Font {
                    name: "Arial Bold"
                    size: 15
                }
            }
        ]
        onMousePressed: function(me:MouseEvent):Void {
            textRef.fill = Color.rgb(0, 0, 0);
            left = 0.0;
            right = 0.0;
            tmp = "";
            str = tmp;
            operator = "";
        }
        onMouseReleased: function(me:MouseEvent):Void {
            textRef.fill = Color.rgb(222, 222, 222);
        }
        onMouseEntered: function(me:MouseEvent):Void {
            rectRef.fill = Color.rgb(128, 128, 192);
        }
        onMouseExited: function(me:MouseEvent):Void {
            rectRef.fill = buttonGradient
        }
    }
}

function buildKeyButton(row : Integer, column : Integer) : Group {
    Group {
        var rectRef:Rectangle;
        var textRef:Text;
        content: [
            rectRef = Rectangle {
                width: 35
                height: 30
                fill: buttonGradient
            },
            textRef = Text {
                transforms: bind
                Translate.translate(
                    (rectRef.layoutBounds.width -
                     textRef.layoutBounds.width) / 2,
                    (rectRef.layoutBounds.height +
                     textRef.layoutBounds.height) / 2)
                content: keyLabels[
                row * 5 + column]
                textOrigin: TextOrigin.BOTTOM
                fill: Color.rgb(222, 222, 222)
                font: Font {
                    name: "Arial Bold"
                    size: 15
                }
            }
        ]
        onMousePressed: function(me:MouseEvent):Void {
            textRef.fill = Color.rgb(0, 0, 0);
            process(textRef.content);
        }
        onMouseReleased: function(me:MouseEvent):Void {
            textRef.fill = Color.rgb(222, 222, 222);
        }
        onMouseEntered: function(me:MouseEvent):Void {
            rectRef.fill = Color.rgb(128, 128, 192);
        }
        onMouseExited: function(me:MouseEvent):Void {
            rectRef.fill = buttonGradient
        }
    }
}

function process(ch : String) : Void {

    if (ch == '+' or ch == '-' or ch == 'x' or ch == '/') {

        if (str != "") {
            left = java.lang.Double.valueOf(str);
        }

        flush = true;
        operator = ch;
    }
    else if (ch == '%') {
        if (str != "") {
            var t = java.lang.Double.valueOf(str);
            right = left*t/100.0;
        }
        else {
            right = right*0.01;
        }

        str = "{right}";
    }
    else if (ch == 'sqrt') {
        if (str != "") {
            var t = java.lang.Double.valueOf(str);
            str = "{java.lang.Math.sqrt(t)}";
        }
    }
    else if (ch == '1/x') {
        if (str != "") {
            var t = java.lang.Double.valueOf(str);
            str = "{1/t}";
        }
    }
    else if (ch == '+/-') {
        if (str != "") {
            var t = java.lang.Double.valueOf(str);
            str = "{-1*t}";
        }
    }
    else if (ch == '=') {
        if (tmp == "" and str != "") {
            tmp = str;
            right = java.lang.Double.valueOf(str);
        }

        operate();
    }
    else {
        if (flush) {
            str = "";
            tmp = "";
            flush = false;
        }

        str = "{str}{ch}";
    }
}

function operate() {

    try {
        var result : Number;        

        if (operator == '+') {
            result = left + right;
        } else if (operator == '-') {
            result = left - right;
        } else if (operator == 'x') {
            result = left * right;
        } else if (operator == '/') {
            result = left / right;
        } else {
            return;
        }

        str = "{result}";
        left = result;

    } catch (e : java.lang.Exception) {
        str = "{e.getMessage()}";
    }
}

Advertisements
Calculator in JavaFX

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s