Compiling to Javascript and running in the browserProgramming Practice TutorialsThe CS109UI moduleAdvanced use of the CS109UI module

Advanced use of the CS109UI module

Timeouts

If you are programming a game or a typing tutor, the action in your program may want to continue even if the user does not press a key.

You can achieve this by setting a timeout when waiting for user input. Call the function setTimeOut(ms), with a timeout in milliseconds, then call waitKey(). If the user pressed a key before the timeout is over, the key is returned, otherwise a "special key" called timeOutChar.

Here is a simple test program (uitest5.kt):

import org.otfried.cs109ui.*
import org.otfried.cs109ui.ImageCanvas
import org.otfried.cs109.Color
import org.otfried.cs109.DrawStyle

import java.awt.image.BufferedImage

fun draw(image: BufferedImage, color: Color) {
  val g = ImageCanvas(image)
  g.clear(Color.WHITE)
  g.setColor(color)
  g.drawRectangle(100.0, 100.0, 300.0, 300.0)
  g.done()
}

fun main(args: Array<String>) {
  setTitle("CS109 UI Timer Test")

  val image = BufferedImage(500, 500, BufferedImage.TYPE_INT_RGB)

  draw(image, Color.RED)
  show(image)

  println("You have 5 seconds to press a key inside the CS109 UI window")

  setTimeOut(5000)
  val ch = waitKey()
  if (ch == timeOutChar)
    println("You lost!")
  else
    println("You won by typing $ch")

  close()  // close window and terminate program
}

The function setTimeOut(ms) also works when waiting for a mouse click. In this case, if no mouse button is clicked before the end of the timeout, the function waitMouse returns (-1, -1).

Here is test program for mouse input timeouts (uitest6.kt):

import org.otfried.cs109ui.*
import org.otfried.cs109ui.ImageCanvas
import org.otfried.cs109.Color
import org.otfried.cs109.DrawStyle

import java.awt.image.BufferedImage

fun draw(image: BufferedImage) {
  val g = ImageCanvas(image)
  g.clear(Color.WHITE)
  g.setColor(Color.RED)
  g.drawRectangle(50.0, 150.0, 150.0, 150.0)
  g.setColor(Color.GREEN)
  g.drawRectangle(300.0, 150.0, 150.0, 150.0)
  g.done()
}

fun main(args: Array<String>) {
  setTitle("CS109 UI Timer Test")

  val image = BufferedImage(500, 500, BufferedImage.TYPE_INT_RGB)

  draw(image)
  show(image)

  println("You have 3 seconds to click a square")

  setTimeOut(3000)
  val (x, y) = waitMouse()

  if (x < 0)
    println("You are too slow.")
  else 
    println("You clicked at $x $y")

  close()  // close window and terminate program
}

More dialogs

Next, we can ask the user to make a selection from a list of choices:

   val drink = askChoice("What do you like best",
      	                  arrayOf("Beer", "Wine", "Makkoli", "Soju", "Water"))
It looks like this:

askChoice window

The function returns the string selected by the user, or the empty string if the dialog is canceled.

Finally, we can show a message and present up to three buttons:

  val choice = askButtons("What do you want to do now?",
	                  arrayOf("Exit", "More dialogs", "Nothing"))
It looks like this:

askButtons window

The function returns a number for the button pressed (in this example, 1 for "Exit", 2 for "More dialogs?", etc.). If the dialog is canceled, zero is returned.

Here is test program for all dialogs: uitest-dialogs.kt

Using both mouse and keyboard

If your program can respond to both the mouse and the keyboard at the same time, use the waitEvent() function to wait for the next event.

This function returns an object of type org.otfried.cs109ui.Result. You can handle it as in the following example code (uitest7.kt):

import org.otfried.cs109ui.*
import org.otfried.cs109ui.ImageCanvas
import org.otfried.cs109.Color
import org.otfried.cs109.DrawStyle

import org.otfried.cs109ui.TimeOut
import org.otfried.cs109ui.Key
import org.otfried.cs109ui.Mouse

import java.awt.image.BufferedImage

fun draw(image: BufferedImage, color: Color) {
  val g = ImageCanvas(image)
  g.clear(Color.WHITE)
  g.setColor(color)
  g.drawRectangle(100.0, 100.0, 300.0, 300.0)
  g.done()
}

fun main(args: Array<String>) {
  setTitle("CS109 UI Timer Test")

  val image = BufferedImage(500, 500, BufferedImage.TYPE_INT_RGB)

  draw(image, Color.RED)
  show(image)

  println("You have 5 seconds to press a key or click the mouse")

  setTimeOut(5000)
  val ev = waitEvent()
  when (ev) {
    is TimeOut -> 
      println("You lost!")
    is Key ->
      println("You won by typing ${ev.ch}")
    is Mouse ->
      println("You won by clicking at (${ev.x}, ${ev.y})")
  }
  close()  // close window and terminate program
}
Compiling to Javascript and running in the browserProgramming Practice TutorialsThe CS109UI moduleAdvanced use of the CS109UI module