Support for JavaFX 8u40 Dialogs is now mostly implemented. All
dialog classes are wrapped Dialog, Alert, ChoiceInputDialog,
TextInputDialog, and related. Source code is on
SFX8u40
branch. You can also use latest snapshot from Sonatype
(8.0.40-SNAPSHOT). There are two demos that illustrate use of Dialog
classes
DialogsDemo
(for Alerts) and
LoginDialogDemo
(custom dialog). Most looks pretty good. Here is an example of
using error alert:
new Alert(AlertType.Error) {
title = "Error Dialog"
headerText = "Look, an Error Dialog"
contentText = "Ooops, there was an error!"
}.showAndWait()
Take look and let me know if you have suggestion on things that
could be improved.
There is one use case that I am not completely happy. Confirmation
Alerts return an Option indicating what button was pressed to close
a dialog. Option inner type is `javafx.scene.control.ButtonType`.
Since it is JavaFX rather than ScalaFX type matching can look bit
verbose. Here is an example:
val alert = new Alert(AlertType.Confirmation) {
title = "Confirmation Dialog"
headerText = "Look, a Confirmation Dialog"
contentText = "Are you ok with this?"
}
val result = alert.showAndWait()
result match {
case Some(ButtonType.OK.delegate) => println("OK")
case Some(ButtonType.Cancel.delegate) => println("Cancel")
case _ => println("Something else")
}
Notice that type of the `result` is
`Option[javafx.scene.control.ButtonType]`, which requires use of
`Some(ButtonType.OK.delegate)` and
`Some(ButtonType.Cancel.delegate)` in the match statement. This is a
"common" issue with "inner" types that cannot be automatically
wrapped by implicit conversions (at lest not by current ScalaFX).
To avoid `delegate` references I added a helper `
apply`
to `ButtonType` that converts the option to ScalaFX
(`Option[scalafx.scene.control.ButtonType]`). It has to be used
explicitly, but makes the use case a bit cleaner (no delegates):
val alert = new Alert(AlertType.Confirmation) {
title = "Confirmation Dialog"
headerText = "Look, a Confirmation Dialog"
contentText = "Are you ok with this?"
}
val result = alert.showAndWait()
ButtonType(result) match {
case Some(ButtonType.OK) => println("OK")
case Some(ButtonType.Cancel) => println("Cancel")
case _ => println("Something else")
}
I am looking for some suggestions how to improve it. Optimally this
could be simply:
result match {
case Some(ButtonType.OK) => println("OK")
case Some(ButtonType.Cancel) => println("Cancel")
case _ => println("Something else")
}
The questions is how this could be done. I tried playing with Dialog
parameter type (here javafx.scene.control.ButtonType) trying to do
some dependent type tricks to add a wrapper (here
scalafx.scene.control.ButtonType) if it is available. I think it is
at least theoretically possible, but I could not figure out yet how
to do it. It is a more general problem in ScalaFX (inner types that
should be wrapped), so solving this here could be used in may other
places.
Let me know what you think,
Jarek