jaxx.demo.fun.CalculatorEngine Maven / Gradle / Ivy
/*
* #%L
* JAXX :: Demo
* %%
* Copyright (C) 2008 - 2014 Code Lutin, Tony Chemit
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Lesser Public License for more details.
*
* You should have received a copy of the GNU General Lesser Public
* License along with this program. If not, see
* .
* #L%
*/
package jaxx.demo.fun;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.math.BigDecimal;
public class CalculatorEngine {
public static final String DISPLAY_TEXT_PROPERTY = "displayText";
public static final int ADD = 0;
public static final int SUBTRACT = 1;
public static final int MULTIPLY = 2;
public static final int DIVIDE = 3;
public static final int RESULT = 4;
private int operation = -1;
private boolean clear = true; // true to clear on next key
private String displayText = "0";
private BigDecimal value;
private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
public String getDisplayText() {
return displayText;
}
public void setDisplayText(String displayText) {
String oldDisplayText = this.displayText;
this.displayText = displayText;
firePropertyChange(DISPLAY_TEXT_PROPERTY, oldDisplayText, displayText);
}
public void clear() {
clearEntry();
value = new BigDecimal(0);
operation = -1;
}
public void clearEntry() {
setDisplayText("0");
clear = true;
}
private void checkClear() {
if (clear) {
setDisplayText("");
clear = false;
}
}
public void digit(int digit) {
checkClear();
setDisplayText(getDisplayText() + String.valueOf(digit));
}
public void dot() {
checkClear();
if (getDisplayText().indexOf('.') == -1) {
if (getDisplayText().length() == 0) {
setDisplayText("0.");
} else {
setDisplayText(getDisplayText() + '.');
}
}
}
public void toggleSign() {
String text = getDisplayText();
if (text.startsWith("-")) {
text = text.substring(1);
} else if (!text.equals("0")) {
text = '-' + text;
}
setDisplayText(text);
}
public void equal() {
BigDecimal displayValue = new BigDecimal(getDisplayText());
BigDecimal newValue = displayValue;
switch (operation) {
case ADD:
newValue = value.add(displayValue);
break;
case SUBTRACT:
newValue = value.subtract(displayValue);
break;
case MULTIPLY:
newValue = value.multiply(displayValue);
break;
case DIVIDE:
newValue = value.divide(displayValue, 8, BigDecimal.ROUND_HALF_UP);
break;
}
value = newValue;
setDisplayText(toString(newValue));
clear = true;
operation = -1;
}
public static String toString(BigDecimal decimal) {
// can't use stripTrailingZeros, as it wasn't introduced until 1.5
String result = decimal.toString();
if (result.indexOf(".") != -1) {
while (result.endsWith("0")) {
result = result.substring(0, result.length() - 1);
}
if (result.endsWith(".")) {
result = result.substring(0, result.length() - 1);
}
}
return result;
}
public void operation(int operation) {
if (this.operation != -1) {
equal();
} else {
value = new BigDecimal(getDisplayText());
clear = true;
}
this.operation = operation;
}
public void add() {
operation(ADD);
}
public void subtract() {
operation(SUBTRACT);
}
public void multiply() {
operation(MULTIPLY);
}
public void divide() {
operation(DIVIDE);
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
propertyChangeSupport.addPropertyChangeListener(listener);
}
public void addPropertyChangeListener(String property, PropertyChangeListener listener) {
propertyChangeSupport.addPropertyChangeListener(property, listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
propertyChangeSupport.removePropertyChangeListener(listener);
}
public void removePropertyChangeListener(String property, PropertyChangeListener listener) {
propertyChangeSupport.removePropertyChangeListener(property, listener);
}
protected void firePropertyChange(String property, Object oldValue, Object newValue) {
propertyChangeSupport.firePropertyChange(property, oldValue, newValue);
}
}