GUI library + sbt dependency

As my first Scala project I want to create a simple Tetris game. I found that the Scala standard library no longer includes scala-swing.

My questions are:

  1. Which library should i use to create a simple GUI application, draw into a window and catch keypress events?
  2. What is the best way to include this library into the project?
  3. Can SBT download and compile the library?

I’m using a text editor and sbt on Linux (Fedora 29).

Thanks & regards,
Dirk

For GUI you don’t need a library, but a framework. The only option is JavaFX, which is already included in Java.

Here’s the basic skeleton applicaton:

package test

import javafx.application._
import javafx.stage._
import javafx.scene._
import javafx.scene.control._

object Test {
  def main(args: Array[String]) = {
    Application launch classOf[Test]
  }
}

class Test extends Application {

  def start(stage: Stage) = {

    val content = new Label("Hello World")

    val scene = new Scene(content)

    stage setScene scene
    
    stage show()
  }
}

API docs: https://docs.oracle.com/javase/8/javafx/api/toc.htm

Hi kavedaa,

thank you for your answer!

I get compile errors when i try compile the code:

sbt:guitest> run
[info] Compiling 1 Scala source to /home/dirk/dev/scala/target/scala-2.12/classes …
[error] /home/dirk/dev/scala/test.scala:3:8: not found: object javafx
[error] import javafx.application._
[error] ^
[error] /home/dirk/dev/scala/test.scala:4:8: not found: object javafx

What do I have to put into my build.sbt file for javafx?

In the scala interpreter, when i enter

import javafx.application._

I get:

scala> import javafx.application._
:7: error: not found: value javafx
import javafx.application._

Regards,
Dirk

What Java version are you using?

JavaFX is/was part of the Oracle JDK, but is no longer bundled in Java 11 JDK, and OpenJDK always had it separately bundled. But the openjdk implementation OpenJFX it is now available via maven repositories (not sure if these work with Java 8).

As you want to use them from Scala, you may be interested in ScalaFX, which is a wrapper around JavaFX that allows more idiomatic Scala code. It works with JavaFX 8 and 11. Their Github Page includes the sbt snippets you need. If you don’t want to use ScalaFX, try the snippet for Java 11 without the scalafx dependency line.

As you say you want to create a Tetris game, maybe a game engine is more suitable. You actually can use any Java Library from Scala, so there is more choice than just JavaFX. I don’t have any experience in that area, but know of the existence of at least three game engines for Java, libGDX, LitEngine and JMonkeyEngine. If you want to do more game development, they may be worth a look.

3 Likes

To be fair, you could also use Scala.JS and draw on the HTML Canvas.

It seems that there is also an option for Scala Native: https://github.com/lolgab/scalaui

While JavaFX/ScalaFX (http://www.scalafx.org/) is probably the recommended option, you can also still use Swing with Scala (https://github.com/scala/scala-swing). As the site says, the Swing libraries are mostly unsupported, but they work for Scala 2.x. I have used both of these with courses I teach, so I have video playlists that go through them. Probably the best option for ScalaFX is https://www.youtube.com/playlist?list=PLLMXbkbDbVt__x5VUQHbI8g25Phxi2yBy. I have more extensive introductions that use the Scala scripting environment at https://www.youtube.com/playlist?list=PLLMXbkbDbVt-VCR1-u4ljyHZfB0VEUw6O and https://www.youtube.com/watch?v=NeI3FSymLFw&list=PLLMXbkbDbVt-gBs0RqYN129NBfOdNbzYt.

If for some reason you really want to use Swing, I have videos that do that in the scripting environment at https://www.youtube.com/watch?v=AbBvRtNBDL0&list=PLLMXbkbDbVt83_unrpdVWH-i5AMGM6bfq and https://www.youtube.com/playlist?list=PLLMXbkbDbVt_I9_qsdoCsiSf9zzqK7ykV.

The playlists would have enough information to write a Tetris game for either of those options.

The ScalaFX videos look great, thank you very much!

I took a peek into “ScalaFX First GUI”, there you download the scalafx.jar file “by hand”. Is there a way to make sbt do this automatically?

Certainly, just add a dependency in the build.sbt file. The scalafx.org site should give the proper format. I often just search “scalafx maven” and look at the sbt formatting they list there. That works with lots of dependencies that are published to the Maven repositories.

Which Java version is recommended to use?

They have branches of ScalaFX that support Java 10 and Java 11. I personally am still using Java 8, so I can’t say anything about the stability or usability of other versions of Java for this purpose.

An additional option to consider: you could write it in Scala.js instead, which compiles the Scala code to JavaScript, and then run it in your web browser – that lets you use any of the zillion browser UI frameworks out there. That’s how I would do this personally…

There is a simple example how to use ScalaFX with SBT:


The master branch is using Java 11, it includes proper setup of JavaFX 11. If you want to use Java 8 look at the sfx-8 branch:

I would recommend using Java 11 and ScalaFX 11.

There are several additional example projects: https://github.com/scalafx

Yes, I found the examples and used them as starting point. I’m also using Java 11.

On my PC, I have two Linuxes, Fedora and Arch Linux. On Fedora, I wasn’t able to run any ScalaFX example. I tried both, Java 8 and 11.

On Arch, it worked out of the box. So now I’m using Arch for my Scala project.

Could you briefly describe what was the issue with Fedora and the ScalaFX examples?

This is what happens when building and running https://github.com/scalafx/scalafx-hello-world.git

[dirk@desktop scalafx-hello-world]$ sbt run
[info] Loading settings for project scalafx-hello-world-build from plugin.sbt ...
[info] Loading project definition from /home/dirk/dev/scala/scalafx-hello-world/project
[info] Updating ProjectRef(uri("file:/home/dirk/dev/scala/scalafx-hello-world/project/"), "scalafx-hello-world-build")...
[info] Done updating.
[info] Loading settings for project scalafx-hello-world from build.sbt ...
[info] Set current project to ScalaFX Hello World (in build file:/home/dirk/dev/scala/scalafx-hello-world/)
[info] Updating ...
[info] Done updating.
[info] Compiling 1 Scala source to /home/dirk/dev/scala/scalafx-hello-world/target/scala-2.12/classes ...
[info] Done compiling.
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by com.google.protobuf.UnsafeUtil (file:/home/dirk/.sbt/boot/scala-2.12.7/org.scala-sbt/sbt/1.2.4/protobuf-java-3.3.1.jar) to field java.nio.Buffer.address
WARNING: Please consider reporting this to the maintainers of com.google.protobuf.UnsafeUtil
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
[info] Packaging /home/dirk/dev/scala/scalafx-hello-world/target/scala-2.12/scalafx-hello-world_2.12-11-R16.jar ...
[info] Done packaging.
[info] Running (fork) hello.ScalaFXHelloWorld 
[error] (java:3390): Gdk-CRITICAL **: 14:26:12.325: gdk_x11_display_set_window_scale: assertion 'GDK_IS_X11_DISPLAY (display)' failed
[info] #
[info] # A fatal error has been detected by the Java Runtime Environment:
[info] #
[info] #  SIGSEGV (0xb) at pc=0x00007faf040c442b, pid=3390, tid=3423
[info] #
[info] # JRE version: OpenJDK Runtime Environment (11.0.1+13) (build 11.0.1+13)
[info] # Java VM: OpenJDK 64-Bit Server VM (11.0.1+13, mixed mode, sharing, tiered, compressed oops, g1 gc, linux-amd64)
[info] # Problematic frame:
[info] # C  [libX11.so.6+0x3142b]
[info] #
[info] # Core dump will be written. Default location: Core dumps may be processed with "/usr/lib/systemd/systemd-coredump %P %u %g %s %t %c %h %e" (or dumping to /home/dirk/dev/scala/scalafx-hello-world/core.3390)
[info] #
[info] # An error report file with more information is saved as:
[info] # /home/dirk/dev/scala/scalafx-hello-world/hs_err_pid3390.log
[info] #
[info] # If you would like to submit a bug report, please visit:
[info] #   http://bugreport.java.com/bugreport/crash.jsp
[info] # The crash happened outside the Java Virtual Machine in native code.
[info] # See problematic frame for where to report the bug.
[info] #
[error] Nonzero exit code returned from runner: 134
[error] (Compile / run) Nonzero exit code returned from runner: 134
[error] Total time: 4 s, completed 26.12.2018, 14:26:12

Thanks for the info on Fedora problems. It may be an issue with JavaFX or how it is setup, there is some info on that problem here: http://jalbum.net/forum/thread.jspa?threadID=54811&tstart=0