Examples/Calculator.jaxx |
From JAXXWiki
This is an implementation of Challenge #2 from the XUL Grand Coding Challenge 2004. Because this example program has been implemented in so many different languages, you can easily compare JAXX's syntax against the competition and decide for yourself which you prefer.
Screen shot
letovar
See it in action
To run this example in Java Web Start, click the following link:
To compile and run it yourself, first follow the instructions for installing JAXX. Then download and save the source code using the link below. Once you have done that, compile and run it as follows:
c:\jaxx\examples> jaxxc Calculator.jaxx c:\jaxx\examples> java -classpath .;c:\jaxx\lib\jaxx-runtime.jar Calculator
The first command above assumes that you are in the directory containing the Calculator.jaxx file. Compiling it as shown will produce a class file named Calculator.class in the current directory, and because you were in the same directory as the JAXX file the resulting class will not be placed in a package (its fully-qualified name is just Calculator).
At this point Calculator is a perfectly ordinary Java class, and the only special requirement to run it is that jaxx-runtime.jar be in the classpath.
Source code
Download the source code: Calculator.jaxx
<Application title='Calculator'>
<style source='Calculator.css'/>
<CalculatorEngine id='engine'/>
<Table fill='both' id='table'>
<row>
<cell columns='4'><JLabel id='display' text='{engine.getDisplayText()}'/></cell>
</row>
<row>
<cell columns='2'><JButton id='c' text='C' onActionPerformed='engine.clear()' styleClass='clear'/></cell>
<cell><JButton id='ce' text='CE' onActionPerformed='engine.clearEntry()' styleClass='clear'/></cell>
<cell><JButton id='equals' text='=' onActionPerformed='engine.equal()' styleClass='operator'/></cell>
</row>
<row>
<cell><JButton id='d7' text='7' onActionPerformed='engine.digit(7)' styleClass='digit'/></cell>
<cell><JButton id='d8' text='8' onActionPerformed='engine.digit(8)' styleClass='digit'/></cell>
<cell><JButton id='d9' text='9' onActionPerformed='engine.digit(9)' styleClass='digit'/></cell>
<cell><JButton id='plus' text='+' onActionPerformed='engine.add()' styleClass='operator'/></cell>
</row>
<row>
<cell><JButton id='d4' text='4' onActionPerformed='engine.digit(4)' styleClass='digit'/></cell>
<cell><JButton id='d5' text='5' onActionPerformed='engine.digit(5)' styleClass='digit'/></cell>
<cell><JButton id='d6' text='6' onActionPerformed='engine.digit(6)' styleClass='digit'/></cell>
<cell><JButton id='subtract' text='-' onActionPerformed='engine.subtract()' styleClass='operator'/></cell>
</row>
<row>
<cell><JButton id='d1' text='1' onActionPerformed='engine.digit(1)' styleClass='digit'/></cell>
<cell><JButton id='d2' text='2' onActionPerformed='engine.digit(2)' styleClass='digit'/></cell>
<cell><JButton id='d3' text='3' onActionPerformed='engine.digit(3)' styleClass='digit'/></cell>
<cell><JButton id='multiply' text='x' onActionPerformed='engine.multiply()' styleClass='operator'/></cell>
</row>
<row>
<cell><JButton id='d0' text='0' onActionPerformed='engine.digit(0)' styleClass='digit'/></cell>
<cell><JButton id='sign' text='+/-' onActionPerformed='engine.toggleSign()' styleClass='operator'/></cell>
<cell><JButton id='dot' text='.' onActionPerformed='engine.dot()' styleClass='digit'/></cell>
<cell><JButton id='divide' text='÷' onActionPerformed='engine.divide()' styleClass='operator'/></cell>
</row>
</Table>
</Application>
Stylesheet: Calculator.css
Application {
lookAndFeel: system;
}
#table {
border: {BorderFactory.createEmptyBorder(4, 4, 4, 4)};
font-face: "Trebuchet MS";
}
#display {
background: #BCE5AD;
opaque: true;
horizontalAlignment: right;
border: {BorderFactory.createBevelBorder(BevelBorder.LOWERED)};
font-size: 22;
font-weight: bold;
}
#display:{object.getText().startsWith("-")} {
foreground: red;
}
JButton {
font-size: 18;
width: 60;
height: 35;
}
JButton.digit {
foreground: blue;
}
JButton#dot {
font-size: 20;
}
JButton.operator {
font-size: 18;
foreground: #009900;
}
JButton.clear {
foreground: red;
}
JButton:mouseover {
font-weight: bold;
}
JButton.operator:mouseover {
font-weight: normal;
}
Calculator engine: CalculatorEngine.java
package examples.Calculator;
import java.beans.*;
import java.math.*;
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);
}
}


