Project: Calculator
Step 1 Project
Create a new scala project in IntelliJ
Add scala-swing to build.sbt
libraryDependencies += "org.scala-lang.modules" %% "scala-swing" % "3.0.0"
It will only work with Scala 2.13. So we'll have to use the Scala 2 syntax (e.g. braces, new) The compiler is backwards compatible, so it will work with Scala 3.
Step 2: MainFrame
import scala.swing.*
@main
def calculator(): Unit = {
new MainFrame() {
title = "Hello world"
size = new Dimension(300, 300)
centerOnScreen()
open()
}
}
Step 3: Add Components
val label = new Label("hello, world")
val button = new Button("OK")
contents = new BorderPanel {
add(label, BorderPanel.Position.North)
add(button, BorderPanel.Position.South)
}
Step 4: Event Handling
button.reactions += {
case ButtonClicked(e) => click(e)
}
def click(but: AbstractButton): Unit = {
println(but.text)
}
Step 5: More Buttons
val labels = List(
"7", "8", "9", "/",
"4", "5", "6", "*",
"1", "2", "3", "+",
"C", "0", "=", "-")
val buttonGrid = new GridPanel(4, 4)
val buttons = labels.foreach(lbl => {
val btn = new Button(lbl)
btn.reactions += {
case ButtonClicked(e) => click(e)
}
buttonGrid.contents += btn
}
add(buttonGrid, BorderPanel.Position.Center)
Step 6: State Machine
but.text match
case "7"|"8"|"9"|"4"|"5"|"6"|"1"|"2"|"3"|"0" =>
println("number")
label.text += but.text
case "*"|"/"|"+"|"-" =>
println("operator")
operator = but.text
num1 = label.text.toInt
label.text = ""
case "=" =>
calculate()
case _ =>
println("error")
var num1 = 0
var operator = ""
Step 7: Calculate
def calculate(): Unit = {
val num2 = label.text.toInt
val result = operator match
case "+" => num1 + num2
case "-" => num1 - num2
case "*" => num1 * num2
case "/" => num1 / num2
label.text = result.toString
}
Step 8: Layout
label.preferredSize = new Dimension(200, 30)
label.xAlignment = Alignment.Left
label.font = Font("Arial", Font.Plain, 18)