Calculator Mobile App (Android, iOS, WinPhone)

Language
This is a simple demo of a functional calculator native mobile application. It is written using Codename One, and can be deployed as a native Android, iOS, Windows Phone, J2ME, BlackBerry, Web, Mac, or Windows App. The code is as follows:
  1. package com.codename1.demos.calculator;
  2.  
  3.  
  4. import com.codename1.ui.Button;
  5. import com.codename1.ui.Component;
  6. import com.codename1.ui.Container;
  7. import com.codename1.ui.Display;
  8. import com.codename1.ui.Form;
  9. import com.codename1.ui.TextField;
  10. import com.codename1.ui.layouts.BorderLayout;
  11. import com.codename1.ui.layouts.GridLayout;
  12. import com.codename1.ui.plaf.UIManager;
  13. import com.codename1.ui.util.Resources;
  14. import java.io.IOException;
  15.  
  16. /**
  17.  * This is a demo Calculator app that performs simple Math.  Its purpose
  18.  * is to demonstrate how to create a simple yet functional GUI in a mobile
  19.  * application that runs on iOS, Android, Javascript,
  20.  * @author shannah
  21.  */
  22. public class Calculator {
  23.  
  24.     private Form current;
  25.    
  26.     private Resources theme;
  27.    
  28.     /**
  29.      * The current operation
  30.      * '+', '-', '*', or '/'
  31.      */
  32.     private char op;
  33.    
  34.     /**
  35.      * The current calculated value
  36.      */
  37.     private double currVal;
  38.    
  39.     /**
  40.      * The input field
  41.      */
  42.     TextField inputField;
  43.    
  44.     /**
  45.      * Flag to indicate that the value has just been reset
  46.      */
  47.     boolean reset = true;
  48.    
  49.     /**
  50.      * Flag to indicate that input mode is to append digits.
  51.      * If false, the next digit pressed will replace whatever
  52.      * is in the input field.
  53.      */
  54.     boolean appendDigits = false;
  55.    
  56.     public void init(Object context) {
  57.         try {
  58.             theme = Resources.openLayered("/theme");
  59.             UIManager.getInstance().setThemeProps(theme.getTheme(theme.getThemeResourceNames()[0]));
  60.         } catch(IOException e){
  61.             e.printStackTrace();
  62.         }
  63.        
  64.     }
  65.    
  66.     /**
  67.      * Clears the current calculation.
  68.      */
  69.     private void clear() {
  70.         inputField.setText(String.valueOf(0));
  71.         op = 0;
  72.         currVal = 0;
  73.         reset = true;
  74.         appendDigits = false;
  75.     }
  76.    
  77.     /**
  78.      * Executes the calculation given the most recent operation that
  79.      * was pressed and displays the value in the input field.
  80.      */
  81.     private void exec() {
  82.        
  83.         double a = Double.parseDouble(inputField.getText());
  84.         if (reset) {
  85.             currVal = a;
  86.             return;
  87.         } else {
  88.             switch (op) {
  89.                 case '+': currVal +=  a; break;
  90.                 case '-': currVal -= a; break;
  91.                 case '*': currVal *= a; break;
  92.                 case '/': currVal /= a; break;
  93.             }
  94.         }
  95.         inputField.setText(String.valueOf(currVal));
  96.         appendDigits = true;
  97.        
  98.     }
  99.    
  100.     /**
  101.      * Appends the given digit to the input field.
  102.      * @param digit
  103.      */
  104.     private void append(int digit) {
  105.         String s = digit >= 0 ? String.valueOf(digit) : ".";
  106.         if (appendDigits) {
  107.             inputField.setText(inputField.getText()+s);
  108.         } else {
  109.             inputField.setText(s);
  110.             appendDigits = true;
  111.         }
  112.     }
  113.    
  114.     /**
  115.      * Sets the current operation, and executes it.
  116.      * @param op
  117.      */
  118.     private void setOp(char op) {
  119.         exec();
  120.         this.op = op;
  121.         this.reset = false;
  122.        
  123.         appendDigits = false;
  124.        
  125.     }
  126.    
  127.     public void start() {
  128.         if (current != null) {
  129.             current.show();
  130.             return;
  131.         }
  132.         // Create the calculator form
  133.         Form f = new Form("Calculator");
  134.         f.setLayout(new BorderLayout());
  135.        
  136.         // The input field placed in the north section
  137.         inputField = new TextField();
  138.         inputField.getDisabledStyle().setAlignment(Component.RIGHT);
  139.         inputField.setEnabled(false);
  140.         inputField.setText(String.valueOf(0));
  141.         f.addComponent(BorderLayout.NORTH, inputField);
  142.        
  143.        
  144.         // We place the numbers in a GridLayout with 4 rows and 3 columns.
  145.        
  146.         Container numbers = new Container();
  147.         numbers.setLayout(new GridLayout(4,3));
  148.        
  149.         // We'll set up the digits as integers.  Only non-negative ints
  150.         // will result in a button being placed for it.
  151.         int digits[] = {1,2,3,4,5,6,7,8,9,-1,0};
  152.         for (int i=0; i<digits.length; i++) {
  153.             int digit = digits[i];
  154.             if (digit >= 0) {
  155.                 Button digitButton = new Button(String.valueOf(digit));
  156.                
  157.                 // Add action listener to digit button which appends
  158.                 // the current digit to the input.
  159.                 digitButton.addActionListener((e) -> {append(digit);});
  160.                 numbers.addComponent(digitButton);
  161.             } else {
  162.                 // If the digit was negative, we just want an empty space in the
  163.                 // grid.
  164.                 Container c = new Container();
  165.                 numbers.addComponent(c);
  166.             }
  167.         }
  168.        
  169.         // Add a decimal button to the last position in the grid.
  170.         Button decimalButton = new Button(".");
  171.        
  172.         // We adopt convention that appending -1 results in decimal
  173.         // being placed in the input field.
  174.         decimalButton.addActionListener((e) -> {append(-1);});
  175.         numbers.addComponent(decimalButton);
  176.        
  177.         f.addComponent(BorderLayout.CENTER, numbers);
  178.        
  179.         // Set up container for the command buttons (+, -, *, etc..)
  180.         // We will place this in the east section in a grid layout.
  181.         Container commands = new Container();
  182.         commands.setPreferredW(Display.getInstance().getDisplayWidth()/4);
  183.         commands.setLayout(new GridLayout(4,1));
  184.         Button clear = new Button("C");
  185.         clear.addActionListener((e) -> {clear();});
  186.         commands.addComponent(clear);
  187.        
  188.         Button plus = new Button("+");
  189.         plus.addActionListener((e) -> {setOp('+');});
  190.         commands.addComponent(plus);
  191.        
  192.         Button minus = new Button("-");
  193.         minus.addActionListener((e) -> {setOp('-');});
  194.         commands.addComponent(minus);
  195.        
  196.         Button mult = new Button("x");
  197.         mult.addActionListener((e) -> {setOp('*');});
  198.         commands.addComponent(mult);
  199.        
  200.         Button div = new Button("/");
  201.         div.addActionListener((e) -> {setOp('/');});
  202.         commands.addComponent(div);
  203.        
  204.         Button eq = new Button("=");
  205.         eq.addActionListener((e) -> {setOp('=');});
  206.         commands.addComponent(eq);
  207.        
  208.        
  209.         f.addComponent(BorderLayout.EAST, commands);
  210.        
  211.        
  212.         // Show the form.
  213.         f.show();
  214.        
  215.                
  216.     }
  217.  
  218.     public void stop() {
  219.         current = Display.getInstance().getCurrent();
  220.     }
  221.    
  222.     public void destroy() {
  223.     }
  224.  
  225. }
To run/build this, you just need Eclipse, NetBeans, or Idea IntelliJ with the free NetBeans Codename One plugin installed. I have included the full Netbeans project in the ZIP file attachment so you should be able to download it and run/build it directly in NetBeans.

Note: Due to the size or complexity of this submission, the author has submitted it as a .zip file to shorten your download time. After downloading it, you will need a program like Winzip to decompress it.

Virus note: All files are scanned once-a-day by SourceCodester.com for viruses, but new viruses come out every day, so no prevention program can catch 100% of them.

FOR YOUR OWN SAFETY, PLEASE:

1. Re-scan downloaded files using your personal virus checker before using it.
2. NEVER, EVER run compiled files (.exe's, .ocx's, .dll's etc.)--only run source code.

Comments

This is a nice one....a job well done

Add new comment