scala/ScalaBook/chapter-06/calc.scala
import swing._
import swing.event._
object calc extends SimpleGUIApplication {
def top = new MainFrame {
val max_cols = 20
var isDecimal = false
var tmp: String = _
var leftOperand: Double = _
var curr_value:Double = 0.0
var isFirstOperation = true
var previous_oper = ""
var opPressed = false
def do_oper(oper:String, l:Double, r:Double): Double =
oper match {
case "+" => l+r
case "-" => l-r
case "*" => l*r
case "/" => if (r == 0.0)
Math.NaN_DOUBLE
else l/r
}
title = "Rudimentary Calculator"
//preferredSize = (350,250)
font = new java.awt.Font("Verdana", java.awt.Font.PLAIN, 20)
val cb0 = new Button { text = "0" }
val cb1 = new Button { text = "1" }
val cb2 = new Button { text = "2" }
val cb3 = new Button { text = "3" }
val cb4 = new Button { text = "4" }
val cb5 = new Button { text = "5" }
val cb6 = new Button { text = "6" }
val cb7 = new Button { text = "7" }
val cb8 = new Button { text = "8" }
val cb9 = new Button { text = "9" }
val cbp = new Button { text = "." }
val cbe = new Button { text = "=" }
val cbplus = new Button { text = "+" }
val cbminus = new Button { text = "-" }
val cbtimes = new Button { text = "*" }
val cbdivide = new Button { text = "/" }
val cbpm = new Button { text = "±" }
val cbclr = new Button { text = "Clr" }
val cbsqrt = new Button { text = "√" }
val cbreci = new Button { text = "1/x" }
var buttons = new GridPanel(0,5){
hGap = 15
vGap = 15
contents += cb7
contents += cb8
contents += cb9
contents += cbplus
contents += cbclr
contents += cb4
contents += cb5
contents += cb6
contents += cbminus
contents += cbsqrt
contents += cb1
contents += cb2
contents += cb3
contents += cbtimes
contents += cbreci
contents += cb0
contents += cbp
contents += cbe
contents += cbdivide
contents += cbpm
}
val num_display = new Label {
text = "0"
border = Swing.LineBorder(java.awt.Color.blue, 3)
font = new java.awt.Font("Verdana", java.awt.Font.BOLD, 16)
horizontalAlignment = Alignment.Right
}
contents = new GridBagPanel {
var c = new Constraints
c.fill = GridBagPanel.Fill.Horizontal
c.gridwidth = java.awt.GridBagConstraints.REMAINDER
add(num_display, c)
add(Swing.VStrut(20), c)
c.fill = GridBagPanel.Fill.None
add(buttons, c)
border = Swing.EmptyBorder(30, 30, 30, 30)
}
listenTo(cb7)
reactions += {
case ButtonClicked(b) =>
if ( b.eq(cb7) && ( num_display.text.length < max_cols) ) {
tmp = num_display.text
if (tmp == "0" || tmp == "Error" || opPressed)
tmp = ""
num_display.text = tmp.concat("7")
opPressed = false
}
}
listenTo(cb8)
reactions += {
case ButtonClicked(b) =>
if ( b.eq(cb8) && ( num_display.text.length < max_cols) ) {
tmp = num_display.text
if (tmp == "0" || tmp == "Error" || opPressed)
tmp = ""
num_display.text = tmp.concat("8")
opPressed = false
}
}
listenTo(cb9)
reactions += {
case ButtonClicked(b) =>
if ( b.eq(cb9) && ( num_display.text.length < max_cols) ) {
tmp = num_display.text
if (tmp == "0" || tmp == "Error" || opPressed)
tmp = ""
num_display.text = tmp.concat("9")
opPressed = false
}
}
listenTo(cb4)
reactions += {
case ButtonClicked(b) =>
if ( b.eq(cb4) && ( num_display.text.length < max_cols) ) {
tmp = num_display.text
if (tmp == "0" || tmp == "Error" || opPressed)
tmp = ""
num_display.text = tmp.concat("4")
opPressed = false
}
}
listenTo(cb5)
reactions += {
case ButtonClicked(b) =>
if ( b.eq(cb5) && ( num_display.text.length < max_cols) ) {
tmp = num_display.text
if (tmp == "0" || tmp == "Error" || opPressed)
tmp = ""
num_display.text = tmp.concat("5")
opPressed = false
}
}
listenTo(cb6)
reactions += {
case ButtonClicked(b) =>
if ( b.eq(cb6) && ( num_display.text.length < max_cols) ) {
tmp = num_display.text
if (tmp == "0" || tmp == "Error" || opPressed)
tmp = ""
num_display.text = tmp.concat("6")
opPressed = false
}
}
listenTo(cb1)
reactions += {
case ButtonClicked(b) =>
if ( b.eq(cb1) && ( num_display.text.length < max_cols) ) {
tmp = num_display.text
if (tmp == "0" || tmp == "Error" || opPressed)
tmp = ""
num_display.text = tmp.concat("1")
opPressed = false
}
}
listenTo(cb2)
reactions += {
case ButtonClicked(b) =>
if ( b.eq(cb2) && ( num_display.text.length < max_cols) ) {
tmp = num_display.text
if (tmp == "0" || tmp == "Error" || opPressed)
tmp = ""
num_display.text = tmp.concat("2")
opPressed = false
}
}
listenTo(cb3)
reactions += {
case ButtonClicked(b) =>
if ( b.eq(cb3) && ( num_display.text.length < max_cols) ) {
tmp = num_display.text
if (tmp == "0" || tmp == "Error" || opPressed)
tmp = ""
num_display.text = tmp.concat("3")
opPressed = false
}
}
listenTo(cb0)
reactions += {
case ButtonClicked(b) =>
if ( b.eq(cb0) && ( num_display.text.length < max_cols) ) {
tmp = num_display.text
if (tmp == "0" || tmp == "Error" || opPressed)
tmp = ""
num_display.text = tmp.concat("0")
opPressed = false
}
}
listenTo(cbp)
reactions += {
case ButtonClicked(b) =>
if ( b.eq(cbp) && ( num_display.text.length < max_cols) ) {
tmp = num_display.text
if ( ! isDecimal && tmp != "Error" && ! tmp.contains(".") ) {
num_display.text = tmp.concat(".")
isDecimal = true
}
opPressed = false
}
}
listenTo(cbplus)
reactions += {
case ButtonClicked(b) =>
if ( b.eq(cbplus) ) {
tmp = num_display.text
if ( tmp != "Error") {
curr_value = java.lang.Double.parseDouble(tmp)
if ( ! isFirstOperation ) {
if (!leftOperand.isNaN)
leftOperand = do_oper(previous_oper, leftOperand, curr_value)
if (leftOperand.isNaN)
num_display.text = "Error"
else
num_display.text = leftOperand.toString
}
else {
leftOperand = curr_value
isFirstOperation = false
}
previous_oper = "+"
opPressed = true
isDecimal = false
}
}
}
listenTo(cbminus)
reactions += {
case ButtonClicked(b) =>
if ( b.eq(cbminus) ) {
tmp = num_display.text
if ( tmp != "Error") {
curr_value = java.lang.Double.parseDouble(tmp)
if ( ! isFirstOperation ) {
if (!leftOperand.isNaN)
leftOperand = do_oper(previous_oper, leftOperand, curr_value)
if (leftOperand.isNaN)
num_display.text = "Error"
else
num_display.text = leftOperand.toString
}
else {
leftOperand = curr_value
isFirstOperation = false
}
previous_oper = "-"
opPressed = true
isDecimal = false
}
}
}
listenTo(cbtimes)
reactions += {
case ButtonClicked(b) =>
if ( b.eq(cbtimes) ) {
tmp = num_display.text
if ( tmp != "Error") {
curr_value = java.lang.Double.parseDouble(tmp)
if ( ! isFirstOperation ) {
if (!leftOperand.isNaN)
leftOperand = do_oper(previous_oper, leftOperand, curr_value)
if (leftOperand.isNaN)
num_display.text = "Error"
else
num_display.text = leftOperand.toString
}
else {
leftOperand = curr_value
isFirstOperation = false
}
previous_oper = "*"
opPressed = true
isDecimal = false
}
}
}
listenTo(cbdivide)
reactions += {
case ButtonClicked(b) =>
if ( b.eq(cbdivide) ) {
tmp = num_display.text
if ( tmp != "Error") {
curr_value = java.lang.Double.parseDouble(tmp)
if ( ! isFirstOperation ) {
if (!leftOperand.isNaN)
leftOperand = do_oper(previous_oper, leftOperand, curr_value)
if (leftOperand.isNaN)
num_display.text = "Error"
else
num_display.text = leftOperand.toString
}
else {
leftOperand = curr_value
isFirstOperation = false
}
previous_oper = "/"
opPressed = true
isDecimal = false
}
}
}
listenTo(cbpm)
reactions += {
case ButtonClicked(b) =>
if ( b.eq(cbpm) ) {
tmp = num_display.text
if (tmp != "0" && tmp != "Error" && !opPressed) {
curr_value = -(java.lang.Double.parseDouble(tmp))
num_display.text = curr_value.toString
opPressed = false
}
}
}
listenTo(cbclr)
reactions += {
case ButtonClicked(b) =>
if ( b.eq(cbclr) ) {
num_display.text = "0"
opPressed = false
isFirstOperation = true
isDecimal = false
}
}
listenTo(cbe)
reactions += {
case ButtonClicked(b) =>
if ( b.eq(cbe) ) {
tmp = num_display.text
if ( tmp != "Error") {
curr_value = java.lang.Double.parseDouble(tmp)
if ( ! isFirstOperation ) {
leftOperand = do_oper(previous_oper, leftOperand, curr_value)
if (leftOperand.isNaN)
num_display.text = "Error"
else
num_display.text = leftOperand.toString
}
else {
leftOperand = curr_value
}
isFirstOperation = true
previous_oper = ""
opPressed = false
}
}
}
listenTo(cbsqrt)
reactions += {
case ButtonClicked(b) =>
if ( b.eq(cbsqrt) ) {
tmp = num_display.text
if ( tmp != "Error") {
curr_value = java.lang.Double.parseDouble(tmp)
if ( curr_value < 0.0) {
curr_value = Math.NaN_DOUBLE
num_display.text = "Error"
}
else
num_display.text = (Math.sqrt(curr_value)).toString
}
opPressed = true
}
}
listenTo(cbreci)
reactions += {
case ButtonClicked(b) =>
if ( b.eq(cbreci) ) {
tmp = num_display.text
if ( tmp != "Error") {
curr_value = java.lang.Double.parseDouble(tmp)
if ( curr_value == 0.0) {
curr_value = Math.NaN_DOUBLE
num_display.text = "Error"
}
else
num_display.text = (1/curr_value).toString
}
opPressed = true
}
}
}
}