ScalaFX Extras are additions to ScalaFX that simplify creation of User interfaces. In contrast to ScalaFX core, the Extras do not have direct corresponding concepts in JavaFX.
Contents
Module scalafx-extras
contain feature implementations. Module scalafx-extras-demos
illustrates use
of scalafx-extras
To use ScalaFX Extras with SBT add following dependency:
libraryDependencies += "org.scalafx" %% "scalafx-extras" % scalafx_extras_version
The latest published ScalaFX Extras version:
Package org.scalafx.extras
contains basic helper methods for running tasks on threads and showing exception messages.
The main helper methods:
onFX
run code on FX Application thread in parallelonFXAndWait
run code on FX Application thread and wait till finishedoffFX
run code a thread in paralleloffFXAndWait
run code a thread and wait till finished
Example scheduling some code on FX Application thread
onFX {
counterService.doResume()
_running.value = true
}
Example execution some code on a separate thread and waiting for the result of computation
val x = offFXAndWait {
val a = 3
val b = 7
a * b
}
Standard dialogs can be quickly displayed using functions provided my ShowMessage
. For instance,
import org.scalafx.extras.ShowMessage
ShowMessage.information(
"Dialog Title",
"This is the information 'header'",
"This is the information detailed 'content'.",
parentWindow
)
Dialog types supported:
confirmation
confirmationYesNoCancel
error
exception
information
warning
ShowMessage
can be also used as a mixin to be used within a class where there is the same parentWindow
.
It is typically used with a UI Model
. The dialogs can be
displayed using a single method, like showInformation
, showConfirmation
. ShowMessage
takes care of blocking parent
windows and using parent icons in dialogs. It can also log warnings, errors, and exceptions when warnings, errors, and
exceptions dialogs are displayed.
class MyUIModel extends Model with ShowMessage {
def onSomeUserAction(): Unit = {
// ...
showInformation("Dialog Title",
"This is the information 'header'",
"This is the information detailed 'content'.")
// ...
}
// ...
}
The demos module has a complete example of a simple application in ShowMessageDemoApp
.
GenericPane
is a helper class that simplifies creation of panes. Particularly suited for creation of input controls.
Typically there are 4 steps to using a GenericPane
:
-
Creation, where elements of the pane are appended vertically using
add*(...)
methods, for instance,addStringField(label, defaultText)
-
Adding the pane to the UI
-
User interaction, after the pane is displayed
-
Optionally, reading of input. Pane's editable content can be read using
next*()
methods. Content is read in the order it is added. The whole pane content can be read multiple tiles. Remember to callresetReadout()
to ensure that reading is restarted from the beginning of the pane.
A complete example in Scala 3. Shows a pane with 2 directory selection fields and a button "Print Fields". When the button is pressed values of the directory fields are printed
import org.scalafx.extras.generic_pane.GenericPane
import scalafx.application.JFXApp3
import scalafx.application.JFXApp3.PrimaryStage
import scalafx.geometry.Insets
import scalafx.scene.Scene
import scalafx.scene.control.Button
import scalafx.scene.layout.VBox
object GenericPaneDemo extends JFXApp3:
override def start(): Unit =
val gp = new GenericPane():
addDirectoryField("Input", "images")
addDirectoryField("Output", "output")
stage = new PrimaryStage:
title = "GenericPane Demo"
scene = new Scene:
content = new VBox:
padding = Insets(7, 7, 7, 7)
spacing = 7
children = Seq(
gp.pane,
new Button("Print Fields"):
onAction = (_) =>
gp.resetReadout()
println(s"Input dir : ${gp.nextString()}")
println(s"Output dir: ${gp.nextString()}")
)
Custom dialogs can be quickly created using GenericDialogFX
class. This class is particularly suited for creation of
input dialogs.
There are 3 steps to using the GenericDialogFX
:
- Creation, where elements of the dialog are appended vertically using
add*(...)
methods, for instance,addStringField(label, defaultText)
- User interaction, dialog is displayed using
showDialog()
method - Reading of input, once the dialog is closed, dialog content can be read using
next*()
methods. Content is read in the order it is added.
Here is en example:
// Create a dialog
val dialog =
new GenericDialogFX(
title = "GenericDialogFX Demo",
header = "Fancy description can go here."
) {
// Add fields
addCheckbox("Check me out!", defaultValue = false)
addCheckbox("Check me too!", defaultValue = true)
}
// Show dialog to the user
dialog.showDialog()
// Read input provided by the user
if (dialog.wasOKed) {
val select1 = dialog.nextBoolean()
val select2 = dialog.nextBoolean()
println(s"Selection 1: $select1")
println(s"Selection 2: $select2")
} else {
println("Dialog was cancelled.")
}
A more elaborate example is in the GenericDialogFXDemo
.
AutoDialog
can be used too quickly open auto generated dialog from case class. After closing, the dialog will return
edited version of the input case class.
Here is an example of usage:
import org.scalafx.extras.auto_dialog.AutoDialog
case class FilterOptions(kernelSize: Int = 7,
start: Double = 3.14,
tag: String = "alpha",
debugMode: Boolean = false)
val filterOptions = FilterOptions()
val result: Option[FilterOptions] =
new AutoDialog(filterOptions)
.showDialog(
"AutoDialog Demo",
"Fields are auto generated from `FilterOptions` object")
println(s"Result: $result")
BusyWorker helps running a UI task on separate threads (other than the JavaFX Application thread). It will show busy
cursor and disable specified nodes while the task is performed. It gives an option to show progress and status messages.
BusyWorker
takes care of handling exceptions and displaying error dialogs. It provides for an option to perform custom
finish actions after task is completed.
Below is a simple example of using BusyWorker
. When the task is running, BusyWorker
will disable the root pane of
the parentWindow
to indicate that a task is performed. It will also change the cursor in the root pane to "busy". When
task is done, the cursor will be changed back to default and root pane will be enabled back.
new BusyWorker("Simple Task", parentWindow).doTask { () =>
Thread.sleep(1000)
print(1 + 1)
}
Here is a little more elaborated example. It updates a progress message and progress indicator.
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"
}
}
)
}
The full code example can be found in the BusyWorkerDemo.
Package org.scalafx.extras.mvcfx
contains classes for creating with UI components based on FXML that use
Model-View-Controller, here we call it the MVCfx Pattern. See wiki page MVCfx Pattern for details.
The demos module has a complete example of a simple application: StopWatchApp.
ImageDisplay Component is an image view with the ability to zoom in, zoom out, zoom to fit. It can also automatically resize to parent size.
Work in progress
- Helper UI for running batch processing tasks, see
BatchRunnerProgressDemoApp
for example of use - Component for display of progress of batch processing tasks, see
ProgressStatusDemoApp
for example of use
Module scalafx-extras-demos contains examples of using ScalaFX Extras.
StopWatchApp is an application that illustrates uses of the MVCfx Pattern: a Model-View-Controller with FXML layout.
There are slight differences between Scala 2 and 3 related to use of annotations. See StopWatchDemo Scala 2 and StopWatchDemo Scala 3 files for details. It is described in details in MVCfx Pattern wiki page.
ShowMessageDemoApp is a full example of using ShowMessage
and MVCfx.
There are slight differences between Scala 2 and 3 related to use of annotations. See ShowMessageDemo Scala 2 and ShowMessageDemo Scala 3 files for details.
BusyWorkerDemo illustrated different aspects of using BusyWorker
.
ImageDisplayDemoApp a simple example of an application that can display images,
with the ability to zoom in, zoom out, and fit to the current window, flip, and rotate the image.
Illustrates use of the ImageDisplay
component.
BatchRunnerWithProgressDemoApp demo of BatchRunnerWithProgress
GUI.
ScalaFX Extras is still quite experimental and APIs may change significantly.
For discussion and support, please use ScalaFX Users Group or project Discussions. Please report issues using the projects Issue tracker.
BSD-3-Clause ScalaFX license.