scalatutorial.de

Stufe 6Werkzeuge und Oberflächen · Lektion 33 von 34

Swing: Oberflächen mit scala-swing

Aktualisiert am 24. September 20263 Min. LesezeitSchritt 5/6 dieser Stufe

Swing ist das klassische Oberflächen-Toolkit der Java-Plattform. Die Bibliothek scala-swing legt eine schlanke Scala-Schicht darüber: Fenster, Layouts und Komponenten werden knapper beschrieben, Ereignisse mit Pattern Matching behandelt.

Einordnung

Swing ist seit Jahrzehnten Teil des JDK und läuft ohne weitere Installation auf Windows, macOS und Linux. Für neue Desktop-Anwendungen greifen viele heute zu JavaFX (in Scala: ScalaFX) oder zu Weboberflächen. Swing bleibt aber wertvoll für interne Werkzeuge, zum Lernen und für die Pflege bestehender Programme – und scala-swing ist ein gutes Beispiel dafür, wie Scala eine Java-Bibliothek angenehmer macht.

scala-swing ist nicht mehr Teil der Standardbibliothek, sondern ein eigenes Modul:

build.sbtsbt
libraryDependencies += "org.scala-lang.modules" %% "scala-swing" % "3.0.0"

Mit Scala CLI genügt die Direktive //> using dep org.scala-lang.modules::scala-swing:3.0.0 am Anfang der Datei.

Das Anwendungsgerüst

Zaehler.scalaScala 3
import scala.swing.*
import scala.swing.event.ButtonClicked

object Zaehler extends SimpleSwingApplication:
  def top: Frame = new MainFrame:
    title = "Zähler"
    preferredSize = new Dimension(360, 180)

    private var klicks = 0
    private val anzeige = new Label("Klicks: 0")
    private val knopf   = new Button("Plus eins")

    contents = new BoxPanel(Orientation.Vertical):
      contents += anzeige
      contents += knopf
      border = Swing.EmptyBorder(20, 20, 20, 20)

    listenTo(knopf)
    reactions += {
      case ButtonClicked(`knopf`) =>
        klicks += 1
        anzeige.text = s"Klicks: $klicks"
    }

SimpleSwingApplication erzeugt den Einstiegspunkt und zeigt das Fenster an, das top liefert. MainFrame ist ein Hauptfenster, das beim Schließen das Programm beendet. Die Eigenschaften title, preferredSize und contents werden wie Variablen gesetzt – scala-swing übersetzt das in die entsprechenden Java-Aufrufe.

Skizze eines kleinen Swing-Fensters mit Label, Button, Textfeld und CheckBoxZähler – MainFrameKlicks: 3Plus einsTextFieldCheckBoxBoxPanel(Orientation.Vertical)← Label← Button, TextField← CheckBox← Layout-Panel
So etwa sieht das Fenster aus – ergänzt um Textfeld und CheckBox.

Ereignisse

Statt anonymer Listener-Klassen wie in Java hört eine Komponente mit listenTo(…) auf andere und reagiert in reactions mit Pattern Matching auf Ereignisse. Die Backticks um knopf bedeuten: Vergleiche mit dem vorhandenen Wert knopf, statt eine neue Variable einzuführen. So können mehrere Knöpfe im selben Block unterschieden werden.

Häufige Ereignisse sind ButtonClicked, ValueChanged (Textfelder, Schieberegler), SelectionChanged (Listen, ComboBox) und EditDone (Textfeld verlassen oder Enter gedrückt).

Layout-Panels

Wie die Komponenten angeordnet werden, bestimmt das Panel, in dem sie liegen:

PanelAnordnung
FlowPanelnebeneinander, bricht bei Platzmangel um
BoxPanel(Orientation.Vertical)untereinander (oder Horizontal: nebeneinander)
BorderPanelfünf Bereiche: Norden, Süden, Osten, Westen, Mitte
GridPanel(zeilen, spalten)gleich große Zellen im Raster
GridBagPanelflexibles Raster mit Gewichtungen
ScrollPanemacht großen Inhalt scrollbar

Panels lassen sich verschachteln – ein BorderPanel mit einer Werkzeugleiste oben (FlowPanel) und einem Formular in der Mitte (GridPanel) ist ein typischer Aufbau.

Wichtige Komponenten

 Scala 3
val name    = new TextField(20)                     // einzeiliges Textfeld
val notiz   = new TextArea(5, 30)                   // mehrzeilig
val aktiv   = new CheckBox("Newsletter")            // an/aus
val stufe   = new ComboBox(List("Einstieg", "Sprachkern", "Collections"))
val gruppe  = new ButtonGroup()
val klein   = new RadioButton("klein")
val gross   = new RadioButton("groß")
gruppe.buttons ++= List(klein, gross)               // nur einer wählbar
val schalter = new ToggleButton("Dunkelmodus")
val liste   = new ListView(List("Scala", "Java", "Kotlin"))

Zugriff auf die Werte: name.text, aktiv.selected, stufe.selection.item, liste.selection.items. Damit die ComboBox Änderungen meldet, hören Sie auf ihre Auswahl: listenTo(stufe.selection).

Swing und Java mischen

Jede scala-swing-Komponente verpackt eine Java-Swing-Komponente, erreichbar über .peer. Umgekehrt lässt sich eine beliebige Java-Komponente mit Component.wrap(javaKomponente) einbinden. So können Sie Java-Bibliotheken für Diagramme oder Tabellen weiterverwenden.

Passt dazu