Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

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)