Skip to content

Commit

Permalink
Merge branch 'master' into release
Browse files Browse the repository at this point in the history
  • Loading branch information
jpsacha committed Jul 14, 2022
2 parents d5c8a50 + 7e274ff commit 0831b9d
Show file tree
Hide file tree
Showing 22 changed files with 1,506 additions and 153 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,3 +26,4 @@ project/target
.externalToolBuilders/
/_local_/
/.bsp/
.DS_Store
2 changes: 1 addition & 1 deletion .scalafmt.conf
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version = 3.2.1
version = 3.5.8

runner.dialect = scala3
fileOverride {
Expand Down
117 changes: 93 additions & 24 deletions ReadMe.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,17 @@ Extras do not have direct corresponding concepts in JavaFX.
0. [Project Structure](#project-structure)
0. [SBT](#sbt)
0. [Features](#features)
1. [Helper Methods](#helper-methods)
1. [Simpler Display of Dialogs](#simpler-display-of-dialogs)
1. [BusyWorker](#busyworker)
1. [Simpler Use of FXML with MVCfx Pattern](#simpler-use-of-fxml-with-mvcfx-pattern)
1. [Image Display Component](#imagedisplay-component)
1. [Helper Methods](#helper-methods)
1. [Simpler Display of Standard Dialogs](#simpler-display-of-standard-dialogs)
1. [Easy Custom Dialogs](#easy-custom-dialogs)
1. [BusyWorker](#busyworker)
1. [Simpler Use of FXML with MVCfx Pattern](#simpler-use-of-fxml-with-mvcfx-pattern)
1. [Image Display Component](#imagedisplay-component)
0. [Demos](#demos)
1. [StopWatch Application](#stopwatch-application)
1. [ShowMessage Demo](#showmessage-demo)
1. [BusyWorker Demo](#busyworker-demo)
1. [ImageDisplay Demo](#imagedisplay-demo)
1. [StopWatch Application](#stopwatch-application)
1. [ShowMessage Demo](#showmessage-demo)
1. [BusyWorker Demo](#busyworker-demo)
1. [ImageDisplay Demo](#imagedisplay-demo)
0. [Status](#status)
0. [Discussion and Support](#discussion-and-support)
0. [License](#license)
Expand Down Expand Up @@ -57,7 +58,6 @@ The main helper methods:
* `onFXAndWait` run code on FX Application thread and wait till finished
* `offFX` run code a thread in parallel
* `offFXAndWait` run code a thread and wait till finished
* `showException` show an exception dialog

Example scheduling some code on FX Application thread

Expand All @@ -73,37 +73,106 @@ Example execution some code on a separate thread and waiting for the result of c

```scala
val x = offFXAndWait {
val a = 3
val b = 7
a * b
val a = 3
val b = 7
a * b
}

```

### Simpler Display of Dialogs
### Simpler Display of Standard Dialogs

The mixin `ShowMessage` makes it easier to display dialogs. It is typically used with a UI `Model`. The dialogs can be
Standard dialogs can be quickly displayed using functions provided my `ShowMessage`. For instance,

```scala
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.

```scala
class MyUIModel extends Model with ShowMessage {

def onSomeUserAction(): Unit = {
// ...
showInformation("Dialog Title",
"This is the information \"header\"",
"This is the information detailed \"content\".")
// ...
}
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`.

### Easy Custom Dialogs

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`:

1. Creation, where elements of the dialog are appended vertically using `add*(...)` methods, for
instance,`addStringField(label, defaultText)`
2. User interaction, dialog is displayed using `showDialog()` method
3. 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:

```scala
// 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.")
}
```

![GenericDialogFX Demo](notes/assets/GenericDialogFX_2.png)

A more elaborate example is in the `GenericDialogFXDemo`.

### BusyWorker

BusyWorker helps running a UI task on separate threads (other than the JavaFX Application thread). It will show busy
Expand All @@ -129,7 +198,7 @@ new BusyWorker("Simple Task", parentWindow).doTask { () =>
Here is a little more elaborated example. It updates a progress message and progress indicator.

```scala
val buttonPane: Pane =
val buttonPane: Pane =
...
val progressLabel: Label =
...
Expand Down
39 changes: 13 additions & 26 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ import scala.xml.{Node => XmlNode, NodeSeq => XmlNodeSeq, _}
// JAR_BUILT_BY - Name to be added to Jar metadata field "Built-By" (defaults to System.getProperty("user.name")
//

val projectVersion = "0.5.0"
val projectVersion = "0.5.0.2-SNAPSHOT"
val versionTagDir = if (projectVersion.endsWith("SNAPSHOT")) "master" else "v." + projectVersion
val _scalaVersions = Seq("3.0.2", "2.13.7", "2.12.15")
val _scalaVersions = Seq("3.0.2", "2.13.8", "2.12.16")
val _scalaVersion = _scalaVersions.head
val _javaFXVersion = "17.0.1"
val _javaFXVersion = "18.0.1"

ThisBuild / version := projectVersion
ThisBuild / crossScalaVersions := _scalaVersions
Expand All @@ -24,18 +24,9 @@ ThisBuild / organization := "org.scalafx"
publishArtifact := false
publish / skip := true

lazy val OSName = System.getProperty("os.name") match {
case n if n.startsWith("Linux") => "linux"
case n if n.startsWith("Mac") => "mac"
case n if n.startsWith("Windows") => "win"
case _ => throw new Exception("Unknown platform!")
}

lazy val JavaFXModuleNames = Seq("base", "controls", "fxml", "graphics", "media", "swing", "web")
lazy val JavaFXModuleLibsProvided: Seq[ModuleID] =
JavaFXModuleNames.map(m => "org.openjfx" % s"javafx-$m" % _javaFXVersion % "provided" classifier OSName)
lazy val JavaFXModuleLibs: Seq[ModuleID] =
JavaFXModuleNames.map(m => "org.openjfx" % s"javafx-$m" % _javaFXVersion classifier OSName)
Seq("base", "controls", "fxml", "graphics", "media", "swing", "web")
.map(m => "org.openjfx" % s"javafx-$m" % _javaFXVersion)

def isScala2(scalaVersion: String): Boolean = {
CrossVersion.partialVersion(scalaVersion) match {
Expand Down Expand Up @@ -93,14 +84,14 @@ lazy val scalaFXExtrasDemos = (project in file("scalafx-extras-demos")).settings
publishArtifact := false,
libraryDependencies ++= Seq(
"com.typesafe.scala-logging" %% "scala-logging" % "3.9.4",
"ch.qos.logback" % "logback-classic" % "1.2.9"
"ch.qos.logback" % "logback-classic" % "1.2.11"
)
).dependsOn(scalaFXExtras % "compile;test->test")

// Resolvers
// Add snapshots to root project to enable compilation with Scala SNAPSHOT compiler,
// e.g., 2.11.0-SNAPSHOT
resolvers += Resolver.sonatypeRepo("snapshots")
resolvers ++= Resolver.sonatypeOssRepos("snapshots")

// Common settings
lazy val scalaFXExtrasSettings = Seq(
Expand All @@ -113,7 +104,8 @@ lazy val scalaFXExtrasSettings = Seq(
"-deprecation",
"-encoding",
"utf8",
"-feature"
"-feature",
"-release", "8"
) ++
(
if (isScala2(scalaVersion.value))
Expand Down Expand Up @@ -161,15 +153,10 @@ lazy val scalaFXExtrasSettings = Seq(
else
Seq.empty[sbt.ModuleID]
),
javacOptions ++= Seq(
"-target", "1.8",
"-source", "1.8",
"-Xlint:deprecation"
),
libraryDependencies ++= Seq(
"org.scalafx" %% "scalafx" % "17.0.1-R26",
"org.scalatest" %% "scalatest" % "3.2.10" % "test"
) ++ JavaFXModuleLibsProvided,
"org.scalafx" %% "scalafx" % "18.0.1-R27",
"org.scalatest" %% "scalatest" % "3.2.11" % "test"
) ++ JavaFXModuleLibs,
libraryDependencies ++= (
if (isScala2(scalaVersion.value))
Seq(
Expand Down Expand Up @@ -200,7 +187,7 @@ lazy val scalaFXExtrasSettings = Seq(
run / fork := true,
Test / fork := true,
Test / parallelExecution := false,
resolvers += Resolver.sonatypeRepo("snapshots"),
resolvers ++= Resolver.sonatypeOssRepos("snapshots"),
// print junit-style XML for CI
Test / testOptions += {
val t = (Test / target).value
Expand Down
50 changes: 50 additions & 0 deletions notes/0.6.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
### ScalaFX-Extras Release v.0.6.0

This release add a new class for convenient creation of input dialogs: `GenericDialogFX`. You can easily add controls to
he dialog then
read their values after the dialog was closed

```scala
// 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.")
}
```

The `scalafx-extras-demos` subproject has a more elaborated example.

Enhancements:

* Support creation of custom dialogs, like ImageJ's GenericDialog #16
* Let any standard dialog be displayed with a one-liner #17

To post questions please use [Project Discussions][Discussions] or [ScalaFX Users Group][scalafx-users]

[Discussions]: https://github.com/scalafx/scalafx-extras/discussions

[scalafx-users]: https://groups.google.com/forum/#!forum/scalafx-users

[Issue #16]: https://github.com/scalafx/scalafx-extras/issues/16

[Issue #17]: https://github.com/scalafx/scalafx-extras/issues/17

Binary file added notes/assets/GenericDialogFX_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions project/build.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#
# Copyright (c) 2011-2021, ScalaFX Project
# Copyright (c) 2011-2022, ScalaFX Project
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
Expand All @@ -24,5 +24,5 @@
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
sbt.version=1.6.0-RC1
sbt.version=1.7.1

2 changes: 1 addition & 1 deletion project/sbt-sonatype.sbt
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
// [https://github.com/xerial/sbt-sonatype]
addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.9.10")
addSbtPlugin("org.xerial.sbt" % "sbt-sonatype" % "3.9.13")
addSbtPlugin("com.jsuereth" % "sbt-pgp" % "2.1.1")
Loading

0 comments on commit 0831b9d

Please sign in to comment.