Packages

  • package root

    Helper methods and classes to simplify ScalaFX use.

    Helper methods and classes to simplify ScalaFX use.

    Package org.scalafx.extras contains basic helper methods for running tasks on threads and showing messages.

    Package org.scalafx.extras.image contains image display component with scrolling and zooming.

    Package org.scalafx.extras.mvcfx contains classes for creating with UI components based on FXML.

    Definition Classes
    root
  • package org
    Definition Classes
    root
  • package scalafx
    Definition Classes
    org
  • package extras

    Helper methods for working with ScalaFX.

    Helper methods for working with ScalaFX.

    Definition Classes
    scalafx
  • package image
  • package mvcfx

    Package mvcfx helps in implementation of Model-View-Controller-like patters, we call it MVCfx.

    Package mvcfx helps in implementation of Model-View-Controller-like patters, we call it MVCfx. The pattern is build around use of views defined in FXML (the view), with binding to ScalaFX using ScalaFXML library.

    There are two cooperating classes ControllerFX for binding FXML to Scala code and ModelFX that contains logic for the component. An additional helper MVCfx class is provided to instantiate the ControllerFX and the corresponding ModelFX.

    The structure of the UI component is defined in a standard JavaFX FXML file. The Scala side of the FXML is in a class ControllerFX. Part of the ControllerFX is automatically generated by ScalaFXML macro, the rest can be customized as needed, including binding of the UI to appropriate parts of the component logic represented by the ModelFX. Use of the MVCfx is optional and primarily intended to simplify instantiation of the ControllerFX and the ModelFX.

    Below is an example using the classes in mvcfx. The code implements a simple Stop Watch. The complete code is in demos part of the ScalaFX Extras project.

    Note the recommended naming convention used: * StopWatch extends MVCfx * StopWatchModel extends ModelFX * StopWatchController extends ControllerFX * StopWatch.fxml the FXVM declaration of the view

    First we have the FXML definitions representing the structure of the user interface (org/scalafx/extras/mvcfx/stopwatch/StopWatch.fxml)

    <?import javafx.geometry.Insets?>
    <?import javafx.scene.control.*?>
    <?import javafx.scene.layout.BorderPane?>
    <?import javafx.scene.layout.HBox?>
    <?import javafx.scene.text.*?>
    <BorderPane xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1"
                fx:controller="org.scalafx.extras.mvcfx.stopwatch.StopWatchController">
        <bottom>
            <ButtonBar BorderPane.alignment="CENTER">
                <buttons>
                    <Button fx:id="startButton" mnemonicParsing="false" text="Start"/>
                    <Button fx:id="stopButton" mnemonicParsing="false" text="Stop"/>
                    <Button fx:id="resetButton" mnemonicParsing="false" text="Reset"/>
                </buttons>
            </ButtonBar>
        </bottom>
        <center>
            <HBox>
                <children>
                    <Label fx:id="minutesLabel" alignment="CENTER" contentDisplay="CENTER" text="99" textAlignment="CENTER"
                           BorderPane.alignment="CENTER">
                    </Label>
                    <Label text=":">
                    </Label>
                    <Label fx:id="secondsLabel" alignment="CENTER" contentDisplay="CENTER" text="99" textAlignment="CENTER">
                    </Label>
                    <Label text=".">
                    </Label>
                    <Label fx:id="fractionLabel" alignment="CENTER" contentDisplay="CENTER" text="99"
                           textAlignment="CENTER">
                    </Label>
                </children>
            </HBox>
        </center>
    </BorderPane>

    The ControllerFX creates connection of the FXML to Scala code and underlying ModelFX for the application logic. Note the @sfxml annotation and the constructor arguments corresponding to controls defined in FXML, like minutesLabel. The last argument to the constructor is the ModelFX. (org.scalafx.extras.mvcfx.stopwatch.StopWatchController)

    package org.scalafx.extras.mvcfx.stopwatch
    
    import org.scalafx.extras.mvcfx.ControllerFX
    
    import scalafx.Includes._
    import scalafx.scene.control.{Button, Label}
    import scalafxml.core.macros.sfxml
    
    @sfxml
    class StopWatchController(minutesLabel: Label,
                              secondsLabel: Label,
                              fractionLabel: Label,
                              startButton: Button,
                              stopButton: Button,
                              resetButton: Button,
                              model: StopWatchModel) extends ControllerFX {
    
      minutesLabel.text.value = format2d(model.minutes.longValue)
      model.minutes.onChange { (_, _, newValue) =>
        minutesLabel.text.value = format2d(newValue.longValue)
      }
      secondsLabel.text.value = format2d(model.seconds.longValue())
      model.seconds.onChange { (_, _, newValue) =>
        secondsLabel.text.value = format2d(newValue.longValue())
      }
      fractionLabel.text.value = format2d(model.secondFraction.longValue() / 10)
      model.secondFraction.onChange { (_, _, newValue) =>
        fractionLabel.text.value = format2d(newValue.longValue() / 10)
      }
    
      startButton.disable <== model.running
      stopButton.disable <== !model.running
      resetButton.disable <== model.running
    
      startButton.onAction = handle {
        model.onStart()
      }
      stopButton.onAction = handle {
        model.onStop()
      }
      resetButton.onAction = handle {
        model.onReset()
      }
    
      private def format2d(t: Number) = f"${t.longValue()}%02d"
    }

    The ModelFX implements the logic for the operation of the Stop Watch. Notice that there are no direct references to UI controls. The connection to the UI is through the properties (like minutes). The ModelFX is not aware how the ControllerFX is implemented. (org.scalafx.extras.mvcfx.stopwatch.StopWatchModel)

    package org.scalafx.extras.mvcfx.stopwatch
    
    import javafx.{concurrent => jfxc}
    
    import org.scalafx.extras._
    import org.scalafx.extras.mvcfx.ModelFX
    
    import scalafx.Includes._
    import scalafx.beans.property.{LongProperty, ReadOnlyBooleanProperty, ReadOnlyBooleanWrapper}
    
    class StopWatchModel extends ModelFX {
    
      private val _running = ReadOnlyBooleanWrapper(false)
    
      val running: ReadOnlyBooleanProperty = _running.readOnlyProperty
    
      private val counterService = new CounterService()
      counterService.period = 10.ms
    
      val minutes = new LongProperty()
      val seconds = new LongProperty()
      val secondFraction = new LongProperty()
    
      counterService.elapsedTime.onChange { (_, _, newValue) =>
        val t = newValue.longValue()
        secondFraction.value = t % 1000
        seconds.value = (t / 1000) % 60
        minutes.value = t / 1000 / 60
      }
    
      def onStart(): Unit = {
        counterService.doResume()
        _running.value = true
      }
    
      def onStop(): Unit = {
        counterService.doPause()
        _running.value = false
      }
    
      def onReset(): Unit = counterService.doReset()
    
      private class CounterService extends jfxc.ScheduledService[Long] {
    
        private var timeAccumulator: Long = 0
        private var restartTime: Long = 0
    
        val elapsedTime = new LongProperty()
    
        override def createTask(): jfxc.Task[Long] = {
          new jfxc.Task[Long]() {
            override protected def call(): Long = {
              val ct = System.currentTimeMillis()
              val et = timeAccumulator + (ct - restartTime)
              onFX {elapsedTime.value = et}
              et
            }
          }
        }
    
        def doPause(): Unit = {
          val ct = System.currentTimeMillis()
          timeAccumulator += (ct - restartTime)
          onFX {elapsedTime.value = timeAccumulator}
          this.cancel()
        }
    
        def doResume(): Unit = {
          restartTime = System.currentTimeMillis()
          this.restart()
        }
    
        def doReset(): Unit = {
          timeAccumulator = 0
          onFX {elapsedTime.value = 0}
        }
      }
    }

    The MVCfx implementation is very simple, it only needs instance of the model and information about location of the FXML resource. (org.scalafx.extras.mvcfx.stopwatch.StopWatch)

    package org.scalafx.extras.mvcfx.stopwatch
    
    import org.scalafx.extras.mvcfx.MVCfx
    
    class StopWatch(val model: StopWatchModel = new StopWatchModel())
      extends MVCfx("/org/scalafx/extras/mvcfx/stopwatch/StopWatchView.fxml")

    The MVCfx can be easily used in an Application class to create UI. (org.scalafx.extras.mvcfx.stopwatch.StopWatchApp)

    package org.scalafx.extras.mvcfx.stopwatch
    
    import scala.language.implicitConversions
    import scalafx.application.JFXApp
    import scalafx.application.JFXApp.PrimaryStage
    import scalafx.scene.Scene
    import scalafx.scene.layout.BorderPane
    
    object StopWatchApp extends JFXApp {
      stage = new PrimaryStage {
        scene = new Scene {
          title = "StopWatch"
          root = new BorderPane {
            center = new StopWatch().view
          }
        }
      }
    }
  • package pong
  • BusyWorker
  • ShowMessage
  • ShowMessageLogger

package extras

Helper methods for working with ScalaFX.

Source
package.scala
Linear Supertypes
Content Hierarchy
Ordering
  1. Alphabetic
  2. By Inheritance
Inherited
  1. extras
  2. AnyRef
  3. Any
  1. Hide All
  2. Show All
Visibility
  1. Public
  2. Protected

Package Members

  1. package image
  2. package mvcfx

    Package mvcfx helps in implementation of Model-View-Controller-like patters, we call it MVCfx.

    Package mvcfx helps in implementation of Model-View-Controller-like patters, we call it MVCfx. The pattern is build around use of views defined in FXML (the view), with binding to ScalaFX using ScalaFXML library.

    There are two cooperating classes ControllerFX for binding FXML to Scala code and ModelFX that contains logic for the component. An additional helper MVCfx class is provided to instantiate the ControllerFX and the corresponding ModelFX.

    The structure of the UI component is defined in a standard JavaFX FXML file. The Scala side of the FXML is in a class ControllerFX. Part of the ControllerFX is automatically generated by ScalaFXML macro, the rest can be customized as needed, including binding of the UI to appropriate parts of the component logic represented by the ModelFX. Use of the MVCfx is optional and primarily intended to simplify instantiation of the ControllerFX and the ModelFX.

    Below is an example using the classes in mvcfx. The code implements a simple Stop Watch. The complete code is in demos part of the ScalaFX Extras project.

    Note the recommended naming convention used: * StopWatch extends MVCfx * StopWatchModel extends ModelFX * StopWatchController extends ControllerFX * StopWatch.fxml the FXVM declaration of the view

    First we have the FXML definitions representing the structure of the user interface (org/scalafx/extras/mvcfx/stopwatch/StopWatch.fxml)

    <?import javafx.geometry.Insets?>
    <?import javafx.scene.control.*?>
    <?import javafx.scene.layout.BorderPane?>
    <?import javafx.scene.layout.HBox?>
    <?import javafx.scene.text.*?>
    <BorderPane xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1"
                fx:controller="org.scalafx.extras.mvcfx.stopwatch.StopWatchController">
        <bottom>
            <ButtonBar BorderPane.alignment="CENTER">
                <buttons>
                    <Button fx:id="startButton" mnemonicParsing="false" text="Start"/>
                    <Button fx:id="stopButton" mnemonicParsing="false" text="Stop"/>
                    <Button fx:id="resetButton" mnemonicParsing="false" text="Reset"/>
                </buttons>
            </ButtonBar>
        </bottom>
        <center>
            <HBox>
                <children>
                    <Label fx:id="minutesLabel" alignment="CENTER" contentDisplay="CENTER" text="99" textAlignment="CENTER"
                           BorderPane.alignment="CENTER">
                    </Label>
                    <Label text=":">
                    </Label>
                    <Label fx:id="secondsLabel" alignment="CENTER" contentDisplay="CENTER" text="99" textAlignment="CENTER">
                    </Label>
                    <Label text=".">
                    </Label>
                    <Label fx:id="fractionLabel" alignment="CENTER" contentDisplay="CENTER" text="99"
                           textAlignment="CENTER">
                    </Label>
                </children>
            </HBox>
        </center>
    </BorderPane>

    The ControllerFX creates connection of the FXML to Scala code and underlying ModelFX for the application logic. Note the @sfxml annotation and the constructor arguments corresponding to controls defined in FXML, like minutesLabel. The last argument to the constructor is the ModelFX. (org.scalafx.extras.mvcfx.stopwatch.StopWatchController)

    package org.scalafx.extras.mvcfx.stopwatch
    
    import org.scalafx.extras.mvcfx.ControllerFX
    
    import scalafx.Includes._
    import scalafx.scene.control.{Button, Label}
    import scalafxml.core.macros.sfxml
    
    @sfxml
    class StopWatchController(minutesLabel: Label,
                              secondsLabel: Label,
                              fractionLabel: Label,
                              startButton: Button,
                              stopButton: Button,
                              resetButton: Button,
                              model: StopWatchModel) extends ControllerFX {
    
      minutesLabel.text.value = format2d(model.minutes.longValue)
      model.minutes.onChange { (_, _, newValue) =>
        minutesLabel.text.value = format2d(newValue.longValue)
      }
      secondsLabel.text.value = format2d(model.seconds.longValue())
      model.seconds.onChange { (_, _, newValue) =>
        secondsLabel.text.value = format2d(newValue.longValue())
      }
      fractionLabel.text.value = format2d(model.secondFraction.longValue() / 10)
      model.secondFraction.onChange { (_, _, newValue) =>
        fractionLabel.text.value = format2d(newValue.longValue() / 10)
      }
    
      startButton.disable <== model.running
      stopButton.disable <== !model.running
      resetButton.disable <== model.running
    
      startButton.onAction = handle {
        model.onStart()
      }
      stopButton.onAction = handle {
        model.onStop()
      }
      resetButton.onAction = handle {
        model.onReset()
      }
    
      private def format2d(t: Number) = f"${t.longValue()}%02d"
    }

    The ModelFX implements the logic for the operation of the Stop Watch. Notice that there are no direct references to UI controls. The connection to the UI is through the properties (like minutes). The ModelFX is not aware how the ControllerFX is implemented. (org.scalafx.extras.mvcfx.stopwatch.StopWatchModel)

    package org.scalafx.extras.mvcfx.stopwatch
    
    import javafx.{concurrent => jfxc}
    
    import org.scalafx.extras._
    import org.scalafx.extras.mvcfx.ModelFX
    
    import scalafx.Includes._
    import scalafx.beans.property.{LongProperty, ReadOnlyBooleanProperty, ReadOnlyBooleanWrapper}
    
    class StopWatchModel extends ModelFX {
    
      private val _running = ReadOnlyBooleanWrapper(false)
    
      val running: ReadOnlyBooleanProperty = _running.readOnlyProperty
    
      private val counterService = new CounterService()
      counterService.period = 10.ms
    
      val minutes = new LongProperty()
      val seconds = new LongProperty()
      val secondFraction = new LongProperty()
    
      counterService.elapsedTime.onChange { (_, _, newValue) =>
        val t = newValue.longValue()
        secondFraction.value = t % 1000
        seconds.value = (t / 1000) % 60
        minutes.value = t / 1000 / 60
      }
    
      def onStart(): Unit = {
        counterService.doResume()
        _running.value = true
      }
    
      def onStop(): Unit = {
        counterService.doPause()
        _running.value = false
      }
    
      def onReset(): Unit = counterService.doReset()
    
      private class CounterService extends jfxc.ScheduledService[Long] {
    
        private var timeAccumulator: Long = 0
        private var restartTime: Long = 0
    
        val elapsedTime = new LongProperty()
    
        override def createTask(): jfxc.Task[Long] = {
          new jfxc.Task[Long]() {
            override protected def call(): Long = {
              val ct = System.currentTimeMillis()
              val et = timeAccumulator + (ct - restartTime)
              onFX {elapsedTime.value = et}
              et
            }
          }
        }
    
        def doPause(): Unit = {
          val ct = System.currentTimeMillis()
          timeAccumulator += (ct - restartTime)
          onFX {elapsedTime.value = timeAccumulator}
          this.cancel()
        }
    
        def doResume(): Unit = {
          restartTime = System.currentTimeMillis()
          this.restart()
        }
    
        def doReset(): Unit = {
          timeAccumulator = 0
          onFX {elapsedTime.value = 0}
        }
      }
    }

    The MVCfx implementation is very simple, it only needs instance of the model and information about location of the FXML resource. (org.scalafx.extras.mvcfx.stopwatch.StopWatch)

    package org.scalafx.extras.mvcfx.stopwatch
    
    import org.scalafx.extras.mvcfx.MVCfx
    
    class StopWatch(val model: StopWatchModel = new StopWatchModel())
      extends MVCfx("/org/scalafx/extras/mvcfx/stopwatch/StopWatchView.fxml")

    The MVCfx can be easily used in an Application class to create UI. (org.scalafx.extras.mvcfx.stopwatch.StopWatchApp)

    package org.scalafx.extras.mvcfx.stopwatch
    
    import scala.language.implicitConversions
    import scalafx.application.JFXApp
    import scalafx.application.JFXApp.PrimaryStage
    import scalafx.scene.Scene
    import scalafx.scene.layout.BorderPane
    
    object StopWatchApp extends JFXApp {
      stage = new PrimaryStage {
        scene = new Scene {
          title = "StopWatch"
          root = new BorderPane {
            center = new StopWatch().view
          }
        }
      }
    }
  3. package pong

Type Members

  1. class BusyWorker extends ShowMessage

    BusyWorker helps running UI tasks a separate threads (other than the JavaFX Application thread).

    BusyWorker helps running UI tasks a separate threads (other than the JavaFX Application thread). It will show busy cursor and disable specified nodes while task is performed. It gives an option to show progress and status messages. BusyWorker run tasks and takes care of handling handling exceptions and displaying error dialogs. There is also option to perform custom finish actions after task is completed.

    While task is performed property busy is set to true. Only one task, for a given worker, can be run at the time. When a task in being performed busyDisabledNode will be disabled and its cursor will be set to Wait/Busy cursor.

    Progress and messages from the running task can be monitored using progressValue and progressMessage properties.

    Below is an example of using using BusyWorker that updates a progress message and progress indicator. The full example can be found in the BusyWorkerDemo of the ScalaFX Extras Demo project.

    val buttonPane: Pane = ...
    val progressLabel: Label = ...
    val progressBar: ProgressBar = ...
    
    val busyWorker = new BusyWorker("BusyWorker Demo", buttonPane) {
      progressLabel.text <== progressMessage
      progressBar.progress <== progressValue
    }
    
    val button = new Button("Click Me") {
          onAction = () => busyWorker.doTask("Task 1")(
            new SimpleTask[String] {
              override def call(): String = {
                val maxItems = 10
                for (i <- 1 to maxItems) {
                  println(i)
                  message() = s"Processing item $i/$maxItems"
                  progress() = (i - 1) / 10.0
                  Thread.sleep(250)
                }
                progress() = 1
                "Done"
              }
            }
          )
    }
  2. trait ShowMessage extends AnyRef

    Mixin that adds ability to easily show message dialogs.

    Mixin that adds ability to easily show message dialogs. A messageLogger can be provided, so when the error or warning dialogs are shown, they are also logged.

    A ShowMessage mixin will typically be used with the ModelFX.

  3. trait ShowMessageLogger extends AnyRef

    Logging operations used by ShowMessage.

    Logging operations used by ShowMessage. Enables ShowMessage to use loggers preferred by the user.

Value Members

  1. def initFX(): Unit

    Attempt to initialize JavaFX Toolkit.

    Attempt to initialize JavaFX Toolkit. This is only needed when application is not started by JFXApp or JavaFX Application.

    When JavaFX toolkit is not initialized and you attempt to use JavaFX components you will get exception: java.lang.IllegalStateException: Toolkit not initialized.

    In JavaFX 9 and newer you can use Platform.startup(() -> {}).

  2. def offFX[R](op: => R): Unit

    Runs an operation op on a separate thread.

    Runs an operation op on a separate thread. Exceptions during execution are ignored. Similar to org.scalafx.extras#run, with default name for the thread: "offFX".

    op

    operation to be performed.

  3. def offFXAndWait[R](op: => R): R

    Run operation op off FX application thread and wait for completion.

    Run operation op off FX application thread and wait for completion. If the current thread is not the FX application, the operation will be run on it (no new thread will ne created).

    op

    operation to be performed.

    Exceptions thrown

    java.lang.InterruptedException - if the current thread was interrupted while waiting

    java.util.concurrent.CancellationException - if the computation was cancelled

    java.util.concurrent.ExecutionException - if the computation threw an exception

  4. def onFX[R](op: => R): Unit

    Run operation op on FX application thread.

    Run operation op on FX application thread. If on FX Application thread it will wait for operation to compete, if not on FX Application thread it will return without waiting for the operation to complete.

    op

    operation to be performed.

  5. def onFXAndWait[R](op: => R): R

    Run operation op on FX application thread and wait for completion.

    Run operation op on FX application thread and wait for completion. If the current thread is the FX application, the operation will be run on it.

    op

    operation to be performed.

    Exceptions thrown

    java.lang.InterruptedException - if the current thread was interrupted while waiting

    java.util.concurrent.CancellationException - if the computation was cancelled

    java.util.concurrent.ExecutionException - if the computation threw an exception

  6. def run[R](op: => R, name: String): Unit

    Runs an operation op on a separate thread.

    Runs an operation op on a separate thread. Exceptions during execution are ignored.

    op

    operation to run

    name

    name for the thread to run the operation. Useful for debugging.

  7. def runTask[T](task: Task[T], name: String): Unit

    Run task on a named daemon thread.

    Run task on a named daemon thread.

    task

    to run

    name

    name for the thread to run the operation. Useful for debugging.

  8. def showException(title: String, message: String, t: Throwable, ownerWindow: Option[Window] = None): Unit

    Show a modal dialog with an expandable details about an exception (stack trace).

    Show a modal dialog with an expandable details about an exception (stack trace).

    title

    dialog title

    message

    message shown in the dialog header.

    t

    exception.

    ownerWindow

    owner window that will be blacked by the dialog.

  9. def showException(title: String, message: String, t: Throwable, ownerWindow: Window): Unit

    Show a modal dialog with an expandable details about an exception (stack trace).

    Show a modal dialog with an expandable details about an exception (stack trace).

    title

    dialog title

    message

    message shown in the dialog header.

    t

    exception.

    ownerWindow

    owner window that will be blacked by the dialog. Can be null to match JavaFX convention.

  10. def showException(title: String, message: String, t: Throwable, ownerWindow: Node): Unit

    Show a modal dialog with an expandable details about an exception (stack trace).

    Show a modal dialog with an expandable details about an exception (stack trace).

    title

    dialog title

    message

    message shown in the dialog header.

    t

    exception.

    ownerWindow

    owner window that will be blacked by the dialog. Can be null.

  11. object BusyWorker

Inherited from AnyRef

Inherited from Any

Ungrouped