Over a million developers have joined DZone.

Part Deux of Building a Calculator with the Shiny New JavaFX SDK 1.0

· Java Zone

Discover how powerful static code analysis and ergonomic design make development not only productive but also an enjoyable experience, brought to you in partnership with JetBrains

In the first post of this Simple Calculator App series, we took some baby steps toward creating a simple calculator.  We're using the comp, shown below, that graphics designer Mark Dingman of Malden Labs supplied:

Calculator_comp

For teaching purposes, I'm taking a very incremental and sometimes indirect approach to building this.  For example, in the first post I used the SwingButton class for the calculator keys.  In this post, we'll use a Group that consists of a Rectangle and Text object to create each key.  Also, we'll use a for expression to succinctly create the keys -- a technique that has another benefit related to event handling that you'll see in a moment.  And remember, the calculator in its current state simply displays the keys typed rather than performing any calculations.  We'll create that code when showing you how to define classes, functions, etc. in JavaFX.

 

Click on the calculator image above to invoke the Simple Calculator JavaFX applet, or the Java Web Start icon below to make the application appear in its own window:

Webstart.small2

Understanding the Code Behind this JavaFX Applet

Take a look at the code below, and note what has changed since its first incarnation.

/*
 * SimpleCalc2.fx
 *
 * Developed 2008 by James L. Weaver (jim.weaver at javafxpert.com)
 * to demonstrate creating applications using JavaFX SDK 1.0
 */
package javafxpert;

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.*;

/**
 * The "stage" for the application
 */
Stage {
  // The model
  var displayStr:String;
  var keyLabels = ["7", "8", "9", "+",
           "4", "5", "6", "-",
           "1", "2", "3", "x",
           "0", ".", "=", "/"];

  title: "Calculator 2"
  scene: Scene {
    // The gradient on the calculator keys
    var btnGradient = 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)
        }
      ]
    };
    content: [
      // The rounded rectangle behind the entire calculator
      Rectangle {
        width: 278
        height: 401
        arcWidth: 16
        arcHeight: 16
        fill: LinearGradient {
          startX: 0.0, startY: 0.0,
          endX: 0.5, endY: 1.0
          stops: [
            Stop {
              offset: 0.0
              color: Color.rgb(119, 116, 123)
            },
            Stop {
              offset: 1.0
              color: Color.rgb(2, 2, 2)
            }
          ]
        },
      },
      VBox {
        transforms: bind Translate.translate(20, 20)
        spacing: 27
        content: [
          // The calculator's display
          TextBox {
            text: bind displayStr
            width: 238
            height: 65
            editable: false
            style: bind "text-fill: #343434; "
                  "background-fill: #f4f4f4; "
                  "font: 28pt Dialog; "
                  "font-weight: bold; "
          },
          // The calculator's keys
          VBox {
            spacing: 2
            content: for (row in [0..3]) {
              HBox {
                spacing: 2
                content: for (column in [0..3]) {
                  Group {
                    var rectRef:Rectangle;
                    var textRef:Text;
                    content: [
                      rectRef = Rectangle {
                        width: 58
                        height: 50
                        fill: btnGradient
                      },
                      textRef = Text {
                        transforms: bind
                          Translate.translate((rectRef.layoutBounds.width -
                                     textRef.layoutBounds.width) / 2,
                                     (rectRef.layoutBounds.height -
                                     textRef.layoutBounds.height) / 2)
                        content: keyLabels[row * 4 + column]
                        textOrigin: TextOrigin.TOP
                        fill: Color.rgb(222, 222, 222)
                        font: Font {
                          name: "Arial Bold"
                          size: 30
                        }
                      }
                    ]
                    onMouseClicked: function(me:MouseEvent):Void {
                      displayStr = "{displayStr}{textRef.content}"
                    }
                  }
                }
              }
            }
          }
        ]
      }
    ]
  }
}

Notice the for expressions that creates an HBox for each row, and a Group for each calculator key in a row.  The value of a for expression is a sequence (think array) of objects.  More information on the for expression can be found in the JavaFX Language Reference (in development at this writing).

Another noteworthy item is the value of the transforms attribute in the Text object.  The Translate.translate function above causes the Text to be centered horizonally and vertically within the Rectangle.

One of the advantages of using the for expression is that only one event handler is required for all of the keys, rather than one for each key as in the previous Simple Calculator version.  In this case the onMouseClicked attribute is on the Group that contains the Rectangle and Text.

One more item of note is the use of the LinearGradient class to make the application begin looking more like the graphic comp shown above.  Consult the JavaFX API docs for more information on using this class.  By the way, the API documentation is available online as well as being in the JavaFX SDK.

Please leave a comment if you have any questions!

Regards,

Jim Weaver
JavaFXpert.com

Learn more about Kotlin, a new programming language designed to solve problems that software developers face every day brought to you in partnership with JetBrains.

Topics:

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}