Monday, March 4, 2013

A source code for Java calculator (Java計算機)

The following codes area fully workable codes for a Java calculator. It supports addition, subtraction, multiplication, and division of long decimal numbers or integers. You can copy the Java codes and configure them on your own. The main class is Calculator.java

Because there seems to be some bugs in the Blogger regarding pasting long code, the web page layout is broken. '<' characters inside the Java codes are sometimes misinterpreted as the left angle bracket of ab HTML element. You can download the whole Java project of the calculator from: https://sites.google.com/site/moderntone/JavaCalculator.zip?attredirects=0&d=1








Adder.java

import javax.swing.JTextField;

public class Adder {

 private JTextField number1, number2;
 public Adder(JTextField number1, JTextField number2){
  this.number1 = number1; this.number2 = number2;
 }
 
 public String add(){
  String n1 = number1.getText(), n2 = number2.getText();
  if (n1.charAt(0) != '-' && n2.charAt(0) != '-') {}
  else if (n1.charAt(0) == '-' && n2.charAt(0) == '-'){
   number1.setText(number1.getText().substring(1));
   number2.setText(number2.getText().substring(1));
   return "-" + add();
  }
  else if (n1.charAt(0) != '-' && n2.charAt(0) == '-'){
   number2.setText(number2.getText().substring(1));
   Subtractor subtractor = new Subtractor(number1, number2);
   return subtractor.subtract();
  }
  else{ //n1.charAt(0) == '-' && n2.charAt(0) != '-'
   number1.setText(number1.getText().substring(1));
   Subtractor subtractor = new Subtractor(number2, number1);
   return subtractor.subtract();
  }
  
  AProcessor format = new AProcessor(n1, n2);
  if (n1.contains(".") || n2.contains(".") ){
   format.getProcessingInfo();format.getProcessingInfo2();
   n1 = format.n1;n2 = format.n2;
   String summation = addTwoPositiveIntegers(n1, n2);
   summation = summation.substring(0, summation.length() - format.dotPosition + 1) + "." + summation.substring(summation.length() - 

format.dotPosition + 1);
   summation = Utils.adjustAnswer(summation);
   return Utils.trimEndZeros(summation);
  }
  else {
   format.getProcessingInfo2();
   n1 = format.n1;n2 = format.n2;
   return  Utils.trimZeros(addTwoPositiveIntegers(n1, n2));
  }
 }
 
 private String addTwoPositiveIntegers(String n1, String n2){
  int[] n1digits = Utils.convertStringToDigits(n1), n2digits = Utils.convertStringToDigits(n2);
  return getAdditionResult(n1digits, n2digits);
 }
 
 private String getAdditionResult(int[] n1digits, int[] n2digits){
  int [] answerDigits = new int[n1digits.length];
  for (int i = answerDigits.length -1 ; i >= 1; i--){
   answerDigits[i] += n1digits[i] + n2digits[i];
   if (answerDigits[i] >= 10){
    answerDigits[i] -= 10;answerDigits[i-1]++;
   }
  }
  
  StringBuilder builder = new StringBuilder();
  for (int i = 0; i < answerDigits.length; i++)
   builder.append(answerDigits[i]);
  
  return  Utils.trimZeros(builder.toString());
 }

}

AProcessor.java
public class AProcessor {

 public String n1, n2;
 public int dotPosition;
 
 public AProcessor(String n1, String n2){
  this.n1 = n1;
  this.n2 = n2;
 }
 
 public void getProcessingInfo(){ 
  //counted from the right: 0, 1, 2, .., dotPosition
  if (!n1.contains(".")) n1 +=".0";
  if (!n2.contains(".")) n2 +=".0";
  int i1 = n1.indexOf("."), i2 = n2.indexOf(".");
  String n1afterdot = n1.substring(i1), n2afterdot = n2.substring(i2);
  //when n1 is 3.34 and n2 is 23.3453, convert n1 to 3.3400
  int numberOfAdditionalZerosRightSideOfDot = n1afterdot.length() > n2afterdot.length() ?  
    n1afterdot.length() - n2afterdot.length() : n2afterdot.length() - n1afterdot.length();
  if (n1.substring(i1).length() > n2.substring(i2).length()){
   dotPosition = n1.length() - i1;
   for (int i = 0 ; i < numberOfAdditionalZerosRightSideOfDot ; i++) n2 += "0";
  }
  else {
   dotPosition = n2.length() - i2;
   for (int i = 0 ; i < numberOfAdditionalZerosRightSideOfDot ; i++) n1 += "0";
  }
  n1 = n1.replace(".", "");n2 = n2.replace(".", "");
  
 }
 
 public void getProcessingInfo2(){
  int numberOfAdditionalZeros = n1.length() > n2.length() ?  
    n1.length() - n2.length() + 1: n2.length() - n1.length() + 1;
  if (n1.length() > n2.length()){
   n1 = "0" + n1; n2 = getConsecutiveZeros(numberOfAdditionalZeros) + n2;
  }
  else {
   n2 = "0" + n2; n1 = getConsecutiveZeros(numberOfAdditionalZeros) + n1;
  }
 }
 
 private static String getConsecutiveZeros(int n){
  StringBuilder builder = new StringBuilder();
  while (n > 0) {
   builder.append("0");n--;
  }
  return builder.toString();
 }
}

Calculator.java
import java.awt.EventQueue;
import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.*;
import java.util.regex.*;

public class Calculator extends JFrame {

 private static final long serialVersionUID = 1L;
 private JPanel contentPane;
 private JTextField number1, number2, answer;
 private String number1_bak, number2_bak;
 private JComboBox operation;

 public static void main(String[] args) {
  EventQueue.invokeLater(new Runnable() {
   public void run() {
    try {
     Calculator frame = new Calculator();
     frame.setVisible(true);
    } catch (Exception e) {
     e.printStackTrace();
    }
   }
  });
 }

 public Calculator() {
  setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  setBounds(450, 100, 500, 240);
  setTitle("Java Calculator");
  setResizable(false);
  contentPane = new JPanel();
  contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
  contentPane.setLayout(null);
  setContentPane(contentPane);
  
  JLabel lblNewLabel = new JLabel("A calculator that supports basic math operations");
  lblNewLabel.setForeground(Color.BLUE);
  lblNewLabel.setFont(new Font("Dialog", Font.PLAIN, 16));
  lblNewLabel.setBounds(75, 23, 340, 21);
  contentPane.add(lblNewLabel);
  
  number1 = new JTextField();
  number1.setBackground(Color.YELLOW);
  number1.setBounds(130, 64, 253, 21);
  number1.setToolTipText("Input a number");
  number1.addKeyListener(enterListener);
  contentPane.add(number1);
  
  number2 = new JTextField();
  number2.setBackground(Color.YELLOW);
  number2.setBounds(130, 98, 253, 21);
  number2.addKeyListener(enterListener);
  number2.setToolTipText("Input a number");
  contentPane.add(number2);
  
  operation = new JComboBox();
  operation.setFont(new Font("Segoe UI Light", Font.PLAIN, 24));
  operation.setModel(new DefaultComboBoxModel(new String[] {"+", "-", "×", "÷"}));
  operation.setBounds(75, 95, 45, 28);
  operation.addKeyListener(enterListener);
  contentPane.add(operation);
  
  JSeparator separator = new JSeparator();
  separator.setBounds(60, 138, 380, 2);
  contentPane.add(separator);
  
  answer = new JTextField();
  answer.setBorder(new EtchedBorder(EtchedBorder.LOWERED, Color.GRAY, null));
  answer.setEditable(false);
  answer.setBackground(Color.CYAN);
  answer.setColumns(10);
  answer.setBounds(130, 150, 253, 21);
  contentPane.add(answer);
  
  JButton btnNewButton = new JButton("Enter");
  btnNewButton.addActionListener(new ActionListener() {
   public void actionPerformed(ActionEvent arg0) {
    performAction();
   }
  });
  btnNewButton.setBorder(new MatteBorder(1, 1, 1, 1, (Color) new Color(0, 0, 0)));
  btnNewButton.setBounds(395, 97, 64, 23);
  contentPane.add(btnNewButton);
 }
 
 private void performAction(){
  
  number1_bak = number1.getText();number2_bak = number2.getText();
  if (checkInputError(number1) || checkInputError(number2)){
   number1.setText(number1_bak); number2.setText(number2_bak);
   JOptionPane.showMessageDialog(null, "Please input valid double numbers for calculation.");
   return;
  }
  
  switch (operation.getSelectedItem().toString().charAt(0)) {
  case '+':
   Adder adder = new Adder(number1, number2);
   answer.setText(adder.add());
   break;
  case '-':
   Subtractor subtractor = new Subtractor(number1, number2);
   answer.setText(subtractor.subtract());
   break;
  case '×':
   Multiplicator multiplicator = new Multiplicator(number1, number2);
   answer.setText(multiplicator.multiply());
   break;
  case '÷':
   Divisor divisor = new Divisor(number1, number2);
   answer.setText(divisor.divide());
   break;
  default:
   break;
  }
  number1.setText(number1_bak); number2.setText(number2_bak);
 }
 
 private KeyListener enterListener = new KeyListener() {
  
  @Override
  public void keyTyped(KeyEvent arg0) {}
  @Override
  public void keyReleased(KeyEvent arg0) {}
  @Override
  public void keyPressed(KeyEvent arg0) {
   if (arg0.getKeyCode() == KeyEvent.VK_ENTER){
    performAction();
   }
  }
 };
 
 private boolean checkInputError(JTextField inputValue){
  if (inputValue.getText().length() == 0)
   return true;
  if (inputValue.getText().charAt(0) == '+')
   inputValue.setText(inputValue.getText().substring(1));
  
  Pattern pattern = Pattern.compile("^-?\\d*\\.?\\d+$");
  Matcher matcher = pattern.matcher(inputValue.getText());
  if (!matcher.find()){
   return true;
  }
  return false;
 }
 
}
Divisor.java
import java.util.ArrayList;
import java.util.List;
import javax.swing.JTextField;

public class Divisor {

 private static final int limitForAnswer = 30;
 private JTextField number1, number2;
 private List tempDigits = new ArrayList();

 
 public Divisor(JTextField number1, JTextField number2){
  this.number1 = number1; this.number2 = number2;
 }
 
 public String divide(){
  String n1 = number1.getText(), n2 = number2.getText();
  if (n1.charAt(0) != '-' && n2.charAt(0) != '-') {}
  else if (n1.charAt(0) == '-' && n2.charAt(0) == '-'){
   number1.setText(number1.getText().substring(1));
   number2.setText(number2.getText().substring(1));
   return divide();
  }
  else if (n1.charAt(0) != '-' && n2.charAt(0) == '-'){
   number2.setText(number2.getText().substring(1));
   String answer = divide();
   return answer.contains("Not") ? "Not a number" : "-" + answer;
  }
  else{ //n1.charAt(0) == '-' && n2.charAt(0) != '-'
   number1.setText(number1.getText().substring(1));
   String answer = divide();
   return answer.contains("Not") ? "Not a number" : "-" + answer;
  }
  
  
  if (n1.contains(".") || n2.contains(".") ){
   
   n1 = someProcess(n1); n2 = someProcess(n2);
   if (n2.equals("0"))
    return "Not a number";
   else if (n1.equals("0"))
    return "0";

   String tempDividend = Utils.trimZeros(n1.replace(".", ""));
   String divisor = Utils.trimZeros(n2).replace(".", "");
   divisor = Utils.trimEndZeros(divisor); tempDividend = Utils.trimEndZeros(tempDividend); 
   divideTwoNums(tempDividend, divisor);
   
   if (!n1.contains(".")) n1 = n1 +".0";
   if (!n2.contains(".")) n2 = n2 +".0";
   String answer = shiftAndGetAnswer(n1, n2);
   return answer;
  }
  else {
   if (Utils.trimZeros(n2).equals("0"))
    return "Not a number";
   else {
    number1.setText(n1 +".0");number2.setText(n2 +".0");
    return divide();
   }
  }

  
 }

 private String shiftAndGetAnswer(String n1, String n2){
  
  int log10n1 = getLog10n(n1), log10n2 = getLog10n(n2);
  StringBuilder builder;
  int log10Value = log10n1 - log10n2;
  if (log10Value +1 > tempDigits.size()){
   builder = new StringBuilder("");
   for (int i = 0; i < tempDigits.size() ; i++)
    builder.append(tempDigits.get(i));
   int temp = log10Value + 1 - tempDigits.size();
   for (int i = 0; i < temp ; i++){
    builder.append("0");
   }
   return Utils.trimZeros(builder.toString());
  }
  else if (log10Value > 0){
   builder = new StringBuilder("");
   for (int i = 0 ; i < log10Value+1; i++)
    builder.append(tempDigits.get(i));
   builder.append('.');
   int temp = tempDigits.size() - log10Value -1;
   if (temp > 0){
    for (int i = 0 ; i < temp; i++)
     builder.append(tempDigits.get(i + log10Value));
   }
   else {
    builder.append('0');
   }
   return Utils.trimZeros(builder.toString());
  }
  else {

   builder = new StringBuilder("");
   for (int i = 0 ; i <  tempDigits.size() ; i++)
    builder.append(tempDigits.get(i));
   return builder.insert(1, '.').toString();
  }
  
 }
 private  String someProcess(String number){
  number = Utils.trimZeros(number);
  number = Utils.adjustAnswer(number);
  number = Utils.trimEndZeros(number);
  return number;
 }
 
 private static int getLog10n(String number){
  if (number.charAt(0) == '0'){
   int i;
   for (i = 2; i < number.length(); i++){
    if (number.charAt(i) != '0')
     break;
   }
   return 1-i;
  }
  else {
   return number.indexOf('.') -1;
  }
 }
 
 
 private int getDigit(String string, int index){
  return string.charAt(index) -'0';
 }
 
 /**
  * For example, if n1 = 14 and n2 = 3, the result is 4666666... (stored in tempDigits)
  * @param n1, n2
  * @return
  */
 private void divideTwoNums(String tempDividend, String divisor){

  int upperBound, lowerBound;
  String product, target;
  
  upperBound = (getDigit(tempDividend, 0) + 1) / getDigit(divisor, 0);
  lowerBound = getDigit(tempDividend, 0) / (getDigit(divisor, 0) + 1);
  if (tempDividend.length() < divisor.length())
   tempDividend = dweiChi(tempDividend, divisor.length() - tempDividend.length());
  target = tempDividend.substring(0, divisor.length());
  
  List succeedingDigits = new ArrayList();
  if (tempDividend.length() > divisor.length()){
   String succeedingString = tempDividend.substring(divisor.length());
   for (int i = 0 ; i < succeedingString.length(); i ++)
    succeedingDigits.add(succeedingString.charAt(i)); 
  }
  
  
  int i;
  for (i = lowerBound; i <= upperBound; i++){
   Multiplicator multiplicator = new Multiplicator("" + i, divisor);
   product = multiplicator.multiply();
   if (product.length() > target.length()) target = "0" + target;
   if (product.compareTo(target) > 0)
    break;
  }
  tempDigits.add(i-1);
  
  
  Multiplicator multiplicator = new Multiplicator("" + (i-1), divisor);
  product = multiplicator.multiply();
  Subtractor subtractor = new Subtractor(tempDividend.substring(0, divisor.length()), product);
  target = subtractor.subtract();
  
  int targetStandardLength = divisor.length() + 1;
  int count = 0;
  while (count < limitForAnswer){
   if (succeedingDigits.size() == 0)
    target = target + "0";
   else {
    target = target + succeedingDigits.get(0);
    succeedingDigits.remove(0);
   }
    
   if (target.length() < targetStandardLength)
    target = dweiChi(target, targetStandardLength - target.length());
   
   lowerBound = (getDigit(target, 0) * 10 + getDigit(target, 1) ) / (getDigit(divisor, 0) + 1);
   upperBound = (getDigit(target, 0) * 10 + getDigit(target, 1) + 1) / getDigit(divisor, 0);

   for (i = lowerBound; i <= upperBound + 1; i++){
    multiplicator = new Multiplicator("" + i, divisor);
    product = multiplicator.multiply();
    if (product.length() < target.length()) product = dweiChi(product, target.length() - product.length());
    else if (product.length() > target.length()) target = dweiChi(target, product.length() - target.length());
     
    if (product.compareTo(target) > 0)
     break;
   }
   tempDigits.add(i-1);
   
   multiplicator = new Multiplicator("" + (i-1), divisor);
   product = multiplicator.multiply();
   subtractor = new Subtractor(target, product);
   target = subtractor.subtract();
   if (isZero(target) && succeedingDigits.size() == 0)
    break;
   count ++;
  }
  
 }
 
 private String dweiChi(String string, int zeroNum){
  StringBuilder builder = new StringBuilder(string);
  for (int i = 0 ; i < zeroNum;i ++)
   builder.insert(0, '0');
  return builder.toString();
 }
 
 private boolean isZero(String target){
  for (int i = 0 ; i < target.length(); i++){
   if (target.charAt(i) != '0')
    return false;
  }
  return true;
 }
}

Multiplicator.java
import javax.swing.JTextField;

public class Multiplicator {

 private JTextField number1, number2;
 
 public Multiplicator(JTextField number1, JTextField number2){
  this.number1 = number1; this.number2 = number2;
 }
 public Multiplicator(String number1, String number2){
  this.number1 = new JTextField(number1);this.number2 = new JTextField(number2);
 }
 public String multiply(){
  String n1 = number1.getText(), n2 = number2.getText();
  if (n1.charAt(0) != '-' && n2.charAt(0) != '-') {}
  else if (n1.charAt(0) == '-' && n2.charAt(0) == '-'){
   number1.setText(number1.getText().substring(1));
   number2.setText(number2.getText().substring(1));
   return multiply();
  }
  else if (n1.charAt(0) != '-' && n2.charAt(0) == '-'){
   number2.setText(number2.getText().substring(1));
   return "-" + multiply();
  }
  else{ //n1.charAt(0) == '-' && n2.charAt(0) != '-'
   number1.setText(number1.getText().substring(1));
   return "-" + multiply();
  }
  
  if (n1.contains(".") || n2.contains(".") ){
   n1 = preprocess(n1); n2 = preprocess(n2);
   String tempn1 = n1.replace(".", ""), tempn2 = n2.replace(".", "");
   String tempMultiplication = multiplyTwoPositiveIntegers(tempn1, tempn2);
   int shiftHowManyTimes = (n1.length() - n1.indexOf('.') -1) + (n2.length() - n2.indexOf('.') -1);
   StringBuilder builder = new StringBuilder(tempMultiplication + ".0");
   
   for (int i = 0 ; i < shiftHowManyTimes; i ++)
    builder = Utils.shiftRight(builder);
   return Utils.trimEndZeros(builder.toString()) ;
  }
  else 
   return multiplyTwoPositiveIntegers(n1, n2);
 }
 
 private String preprocess(String n){
  if (!n.contains(".")) n += ".0";
  if (n.charAt(0) == '.') n= "0" + n;
  return n;
 }

 private String multiplyTwoPositiveIntegers(String n1, String n2){
  int[] n1digits = Utils.convertStringToDigits(n1), n2digits = Utils.convertStringToDigits(n2);
  n1digits = reverse(n1digits);n2digits = reverse(n2digits);
  
  int[] answerDigits = new int[n1digits.length + n2digits.length];
  for (int i = 0 ; i < n1digits.length; i++){
   for (int j = 0 ; j < n2digits.length; j++){
    int temp = n1digits[i]*n2digits[j];
    answerDigits[i+j] += temp;
   }
  }
  
  for (int i = 0 ; i < answerDigits.length -1; i ++){
   answerDigits[i+1] += answerDigits[i] / 10;
   answerDigits[i] = answerDigits[i] % 10;
  }
  
  StringBuilder builder = new StringBuilder();
  for (int i = answerDigits.length - 1 ; i >= 0; i--)
   builder.append(answerDigits[i]);
  return Utils.trimZeros(builder.toString());
 }
 
 private int[] reverse(int[] digits){
  int[] result = new int[digits.length];
  for (int i = 0 ; i
Subtractor.java

import javax.swing.JTextField;

public class Subtractor {

 private JTextField number1, number2;
 public Subtractor(JTextField number1, JTextField number2){
  this.number1 = number1; this.number2 = number2;
 }
 public Subtractor(String number1, String number2){
  this.number1 = new JTextField(number1);this.number2 = new JTextField(number2);
 }
 
 public String subtract(){
  String n1 = number1.getText(), n2 = number2.getText();
  if (n1.charAt(0) != '-' && n2.charAt(0) != '-') {}
  else if (n1.charAt(0) == '-' && n2.charAt(0) == '-'){
   number1.setText(number1.getText().substring(1));
   number2.setText(number2.getText().substring(1));
   Subtractor subtractor = new Subtractor(number2, number1);
   return subtractor.subtract();
  }
  else if (n1.charAt(0) != '-' && n2.charAt(0) == '-'){
   number2.setText(number2.getText().substring(1));
   Adder adder = new Adder(number1, number2);
   return adder.add();
  }
  else{ //n1.charAt(0) == '-' && n2.charAt(0) != '-'
   number1.setText(number1.getText().substring(1));
   Adder adder = new Adder(number1, number2);
   return "-" + adder.add();
  }
  
  AProcessor format = new AProcessor(n1, n2);
  if (n1.contains(".") || n2.contains(".") ){
   format.getProcessingInfo();format.getProcessingInfo2();
   n1 = format.n1;n2 = format.n2;
   String subtraction = subtractTwoPositiveIntegers(n1, n2);
   subtraction = subtraction.substring(0, subtraction.length() - format.dotPosition + 1) + "." + subtraction.substring

(subtraction.length() - format.dotPosition + 1);
   subtraction = Utils.adjustAnswer(subtraction);
   return Utils.trimEndZeros(subtraction);
  }
  else {
   format.getProcessingInfo2();
   n1 = format.n1;n2 = format.n2;
   return subtractTwoPositiveIntegers(n1, n2);
  }
 }
 
 public String subtract_buLin(int length){
  String tempResult = subtract();
  int zerosNum = length - tempResult.length();
  StringBuilder builder = new StringBuilder(tempResult);
  for (int i = 0 ; i < zerosNum; i ++)
   builder.insert(0, '0');
  return builder.toString();
 }
 
 private String subtractTwoPositiveIntegers(String n1, String n2){
  if (n1.compareTo(n2) >= 0){
   int[] n1digits = Utils.convertStringToDigits(n1), n2digits = Utils.convertStringToDigits(n2);
   return getSubtractionResult(n1digits, n2digits);
  }
  else {
   return "-" + subtractTwoPositiveIntegers(n2, n1);
  }
 }
 
 private String getSubtractionResult(int[] n1digits, int[] n2digits ){
  int [] answerDigits = new int[n1digits.length];
  for (int i = 0; i < answerDigits.length ; i++){
   answerDigits[i] += n1digits[i] - n2digits[i];
  }
  for (int i = answerDigits.length - 1; i >= 0; i--){
   if (answerDigits[i] < 0){
    answerDigits[i] += 10;
    answerDigits[i-1]--;
   }
  }
  
  StringBuilder builder = new StringBuilder();
  for (int i = 0; i < answerDigits.length; i++)
   builder.append(answerDigits[i]);
  return Utils.trimZeros(builder.toString());
 }
}
Utils.java
public class Utils {

 /**
  * @param args
  */
 public static void main(String[] args) {
  String test = "003400";String wew;
  wew= Utils.trimZeros(Utils.trimEndZeros(test)).replace(".", "");
  System.out.println(wew);
 }

 public static String trimZeros(String answer){
  
  int i;
  for (i = 0 ; i < answer.length(); i++){
   if (answer.charAt(i) != '0')
    break;
  }
  if (i != answer.length())
   return answer.substring(i);
  else 
   return "0";
 }
 
 public static String trimEndZeros(String number){ //trim end zeros for decimal numberss
  StringBuilder builder = new StringBuilder(number);
  if (number.contains(".")){
   int index = number.length() - 1;
   
   while (builder.charAt(index) == '0') {
    builder.deleteCharAt(index);
    index --;
   }
  
   if (builder.charAt(index) == '.')
    builder.deleteCharAt(index);
  }
  return builder.toString();
 }
 
 
 
 public static String adjustAnswer(String answer){
  if (answer.charAt(0) =='.')
   answer = "0" + answer;
  else if (answer.charAt(0) == '-' && answer.charAt(1) == '.'){
   answer = "-0" + answer.substring(1);
  }
  return answer;
 }
 
 public static StringBuilder shiftRight(StringBuilder number){
  if (number.toString().contains(".")){
   if (number.charAt(0) == '0'){
    number.insert(2, '0');
   }
   else if (number.charAt(1) == '.'){//6.7 -> 0.67
    number.deleteCharAt(1);
    number.insert(0, '.');number.insert(0, '0');
   }
   else {//457.3 -> 45.73
    int dotIndex = number.indexOf(".");
    number.deleteCharAt(dotIndex);
    number.insert(dotIndex -1, '.');
   }
  }
  else {
   System.out.println("there is bug ");System.exit(0);
   return null;
  }
  return number;
 }
 
 public static int[] convertStringToDigits(String string){
  int[] result = new int[string.length()];
  for (int i = 0 ; i < string.length(); i++)
   result[i] = string.charAt(i) - '0';
  return result;
 }
 
 public static int[] convertStringToDigits(String string, int length){
  int howMany = length - string.length();int count = 0;
  StringBuilder newString = new StringBuilder(string);
  do {
   newString.append('0');
  } while(++count < howMany);
  return convertStringToDigits(newString.toString());
 }
}

Saturday, March 2, 2013

A Java source code for Guess Number game (猜數字遊戲)

The Java code below is my implementation of the "guess number game"(猜數字遊戲). It is a fully runnable Java application. A feature of the program is that it supports both Chinese and English languages. You can also copy and configure it on your own.




import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JComboBox;
import javax.swing.DefaultComboBoxModel;
import java.awt.Font;
import java.awt.Color;
import javax.swing.JLabel;
import java.awt.Component;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.JTextField;


public class GuessNumber extends JFrame {

 
 private static final long serialVersionUID = 1L;
 private JPanel contentPane;
 private static final Random random = new Random();
 private String randomNumber;
 private int times;
 /**
  * Launch the application.
  */
 public static void main(String[] args) {
  EventQueue.invokeLater(new Runnable() {
   public void run() {
    try {
     GuessNumber frame = new GuessNumber();
     frame.setVisible(true);
    } catch (Exception e) {
     e.printStackTrace();
    }
   }
  });
 }

 private JComboBox comboBox;
 private JLabel label;
 private JButton btnStart;
 private JTextField textField;
 private JButton btnSwitchLanguage;
 private JLabel additionalLabel;
 private JButton btnEnter;
 private JLabel giAgiBJLabel;
 /**
  * Create the frame.
  */
 public GuessNumber() {
  setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  setBounds(400, 100, 450, 300);
  setResizable(false);
  setTitle("Guess Number");
  contentPane = new JPanel();
  contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
  contentPane.setLayout(null);
  setContentPane(contentPane);
  
  comboBox = new JComboBox();
  comboBox.setForeground(Color.BLUE);
  comboBox.setFont(new Font("微軟正黑體", Font.BOLD, 16));
  comboBox.setModel(new DefaultComboBoxModel(new String[] {"English", "\u4E2D\u6587"}));
  comboBox.setBounds(150, 125, 150, 35);
  contentPane.add(comboBox);
  
  label = new JLabel();
  setLabel();
  contentPane.add(label);
  
  btnStart = new JButton("Start");
  btnStart.addActionListener(new ActionListener() {
   public void actionPerformed(ActionEvent arg0) {
    start();
   }
  });
  btnStart.setForeground(Color.RED);
  btnStart.setFont(new Font("Century", Font.BOLD, 14));
  btnStart.setBounds(180, 190, 90, 30);
  contentPane.add(btnStart);
  
  textField = new JTextField();
  textField.setFont(new Font("Tahoma", Font.BOLD, 18));
  textField.setBounds(170, 120, 120, 35);
  textField.setVisible(false);
  textField.addKeyListener(enterListener);
  contentPane.add(textField);
  
  btnSwitchLanguage = new JButton("Switch Language");
  btnSwitchLanguage.addActionListener(new ActionListener() {
   public void actionPerformed(ActionEvent arg0) {
    switchLanguage();
   }
  });
  btnSwitchLanguage.setFont(new Font("Sylfaen", Font.PLAIN, 10));
  btnSwitchLanguage.setBounds(328, 239, 110, 23);
  btnSwitchLanguage.setVisible(false);
  contentPane.add(btnSwitchLanguage);
  
  additionalLabel = new JLabel("without duplicate digits");
  additionalLabel.setFont(new Font("Kartika", Font.BOLD, 16));
  additionalLabel.setForeground(new Color(153, 102, 0));
  additionalLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
  additionalLabel.setBounds(130, 65, 300, 35);
  additionalLabel.setVisible(false);
  contentPane.add(additionalLabel);
  
  btnEnter = new JButton("Enter");
  btnEnter.addActionListener(new ActionListener() {
   public void actionPerformed(ActionEvent arg0) {
    enter();
   }
  });
  btnEnter.addKeyListener(enterListener);
  btnEnter.setBackground(new Color(173, 255, 47));
  btnEnter.setFont(new Font("新細明體", Font.BOLD, 12));
  btnEnter.setForeground(Color.BLUE);
  btnEnter.setBounds(310, 125, 69, 23);
  btnEnter.setVisible(false);
  contentPane.add(btnEnter);
  
  giAgiBJLabel = new JLabel("");
  giAgiBJLabel.setForeground(new Color(0, 0, 255));
  giAgiBJLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
  giAgiBJLabel.setFont(new Font("Comic Sans MS", Font.PLAIN, 28));
  giAgiBJLabel.setBounds(190, 170, 130, 30);
  contentPane.add(giAgiBJLabel);
 }
 
 public KeyListener enterListener = new KeyListener() {
  
  @Override
  public void keyTyped(KeyEvent arg0) {}
  
  @Override
  public void keyReleased(KeyEvent arg0) {}
  
  @Override
  public void keyPressed(KeyEvent arg0) {
   int key = arg0.getKeyCode();
   if (key == KeyEvent.VK_ENTER){
    enter();
   }
  }
 };
 
 private void enter(){
  times++;
  boolean hasNoInputError = checkInputError();
  if (hasNoInputError){
   if (textField.getText().equals(randomNumber)){
    if (comboBox.getSelectedIndex() == 1)
     JOptionPane.showMessageDialog(null, "恭喜你答對了。你一共猜了"+times+"次");
    else 
     JOptionPane.showMessageDialog(null, "Congratulations! Your answer is correct. You have guessed " + times + " times.");
    switchLanguage();
   }
   else {
    setGiAGiB();
   }
  }
 }
 
 private void switchLanguage(){
  btnEnter.setVisible(false);
  comboBox.setVisible(true);
  btnStart.setVisible(true);
  textField.setText("");
  textField.setVisible(false);
  setLabel();
  additionalLabel.setVisible(false);
  btnSwitchLanguage.setVisible(false);
  giAgiBJLabel.setVisible(false);
  
 }
 
 private boolean checkInputError(){
  String inputText = textField.getText().trim();
  if (inputText.length()!=4){
   if (comboBox.getSelectedIndex() == 1)
    JOptionPane.showMessageDialog(null, "請輸入四位數正整數");
   else 
    JOptionPane.showMessageDialog(null, "Please enter a 4-digit integer");
   return false;
  }
  Pattern pattern = Pattern.compile("\\d\\d\\d\\d");
  Matcher matcher = pattern.matcher(inputText);
  if (!matcher.find()){
   if (comboBox.getSelectedIndex() == 1)
    JOptionPane.showMessageDialog(null, "請輸入有效的正整數");
   else 
    JOptionPane.showMessageDialog(null, "Please enter a valid integer");
   return false;
  }
  
  for (int i = 0; i <= 2; i ++){
   for (int j = i+1; j <= 3 ; j ++ ){
    if (inputText.charAt(i) == inputText.charAt(j)){
     if (comboBox.getSelectedIndex() == 1)
      JOptionPane.showMessageDialog(null, "輸入有誤。四個數字都不能重複");
     else 
      JOptionPane.showMessageDialog(null, "Input error. There should be no duplicate digits");
     return false;
    }
   }
  }
  textField.setText(inputText);
  return true;
 }
 
 
 private void setLabel(){
  label.setText("Select a language");
  label.setForeground(new Color(153, 102, 0));
  label.setAlignmentX(Component.CENTER_ALIGNMENT);
  label.setFont(new Font("Kartika", Font.BOLD, 16));
  label.setBounds(150, 60, 150, 35);
 }
 
 private void start(){
  setRandomNumber();
  btnEnter.setVisible(true);
  comboBox.setVisible(false);
  btnStart.setVisible(false);
  textField.setVisible(true);
  btnSwitchLanguage.setVisible(true);
  setTexts();
  times = 0;
 }
 
 private void setRandomNumber(){
  boolean[] used = new boolean[10];
  int d1 = random.nextInt(10);
  used[d1] = true;
  int d2 =  random.nextInt(9);
  if (used[d2]) d2++;
  used[d2] = true;
  int d3 = random.nextInt(8);
  if (used[d3]) d3++; 
  if (used[d3]) d3++;
  used[d3] = true;
  int d4 = random.nextInt(7);
  if (used[d4]) d4++; 
  if (used[d4]) d4++;
  if (used[d4]) d4++;
  randomNumber = "" + d4 + d3 + d2 + d1;
  System.out.println(randomNumber);
 }
 
 private void setGiAGiB(){
  int a = 0;
  for (int i = 0 ; i < 4 ; i ++){
   if (textField.getText().charAt(i) == randomNumber.charAt(i))
    a++;
  }
  
  int b = 0;
  for (int i = 0 ; i < 4 ; i ++){
   if (randomNumber.contains(textField.getText().charAt(i) + "")){
    if (textField.getText().charAt(i) != randomNumber.charAt(i))
     b++;
   }
  }
  giAgiBJLabel.setText(a + "A" + b + "B");
  giAgiBJLabel.setVisible(true);
 }
 
 private void setTexts(){
  
  if (comboBox.getSelectedIndex() == 1){
   setTitle("猜數字");
   label.setBounds(80, 40, 300, 35);
   label.setFont(new Font("微軟正黑體", Font.BOLD, 16));
   label.setText("請輸入一個數字不重複的四位數正整數");
   btnSwitchLanguage.setBounds(328, 239, 110, 23);
   btnSwitchLanguage.setFont(new Font("微軟正黑體", Font.PLAIN, 10));
   btnSwitchLanguage.setText("切換語言");
   btnEnter.setText("輸入");
  }
  else {
   setTitle("Guess Number");
   label.setBounds(75, 40, 300, 35);
   label.setText("Please enter a 4-digit positive integer");
   btnSwitchLanguage.setText("Switch Language");
   btnSwitchLanguage.setFont(new Font("Sylfaen", Font.PLAIN, 10));
   btnSwitchLanguage.setBounds(328, 239, 110, 23);
   additionalLabel.setVisible(true);
   btnEnter.setText("Enter");
   
  }
  
  
 }
}