Skip to content

Commit 0e74c6c

Browse files
committed
Merge branch 'master' into release
2 parents a82929d + 330c860 commit 0e74c6c

File tree

8 files changed

+432
-29
lines changed

8 files changed

+432
-29
lines changed

ReadMe.md

Lines changed: 53 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,23 +10,30 @@ Extras do not have direct corresponding concepts in JavaFX.
1010

1111
**Contents**
1212

13-
0. [Project Structure](#project-structure)
14-
0. [SBT](#sbt)
15-
0. [Features](#features)
16-
1. [Helper Methods](#helper-methods)
17-
1. [Simpler Display of Standard Dialogs](#simpler-display-of-standard-dialogs)
18-
1. [Easy Custom Dialogs](#easy-custom-dialogs)
19-
1. [BusyWorker](#busyworker)
20-
1. [Simpler Use of FXML with MVCfx Pattern](#simpler-use-of-fxml-with-mvcfx-pattern)
21-
1. [Image Display Component](#imagedisplay-component)
22-
0. [Demos](#demos)
23-
1. [StopWatch Application](#stopwatch-application)
24-
1. [ShowMessage Demo](#showmessage-demo)
25-
1. [BusyWorker Demo](#busyworker-demo)
26-
1. [ImageDisplay Demo](#imagedisplay-demo)
27-
0. [Status](#status)
28-
0. [Discussion and Support](#discussion-and-support)
29-
0. [License](#license)
13+
<!-- TOC -->
14+
15+
* [Project Structure](#project-structure)
16+
* [SBT](#sbt)
17+
* [Features](#features)
18+
* [Helper Methods](#helper-methods)
19+
* [Simpler Display of Standard Dialogs](#simpler-display-of-standard-dialogs)
20+
* [Easy Custom Dialogs](#easy-custom-dialogs)
21+
* [Edit a Case Class object with AutoDialog](#edit-a-case-class-object-with-autodialog)
22+
* [BusyWorker](#busyworker)
23+
* [Example 1](#example-1)
24+
* [Example 2](#example-2)
25+
* [Simpler Use of FXML with MVCfx Pattern](#simpler-use-of-fxml-with-mvcfx-pattern)
26+
* [ImageDisplay Component](#imagedisplay-component)
27+
* [Demos](#demos)
28+
* [StopWatch Application](#stopwatch-application)
29+
* [ShowMessage Demo](#showmessage-demo)
30+
* [BusyWorker Demo](#busyworker-demo)
31+
* [ImageDisplay Demo](#imagedisplay-demo)
32+
* [Status](#status)
33+
* [Discussion and Support](#discussion-and-support)
34+
* [License](#license)
35+
36+
<!-- TOC -->
3037

3138
Project Structure
3239
-----------------
@@ -173,6 +180,34 @@ if (dialog.wasOKed) {
173180

174181
A more elaborate example is in the `GenericDialogFXDemo`.
175182

183+
### Edit a Case Class object with AutoDialog
184+
185+
`AutoDialog` can be used too quickly open auto generated dialog from case class. After closing, the dialog will return
186+
edited version of the input case class.
187+
188+
Here is an example of usage:
189+
190+
```scala
191+
import org.scalafx.extras.auto_dialog.AutoDialog
192+
193+
case class FilterOptions(kernelSize: Int = 7,
194+
start: Double = 3.14,
195+
tag: String = "alpha",
196+
debugMode: Boolean = false)
197+
198+
val filterOptions = FilterOptions()
199+
200+
val result: Option[FilterOptions] =
201+
new AutoDialog(filterOptions)
202+
.showDialog(
203+
"AutoDialog Demo",
204+
"Fields are auto generated from `FilterOptions` object")
205+
206+
println(s"Result: $result")
207+
```
208+
209+
![GenericDialogFX Demo](notes/assets/AutoDialog.png)
210+
176211
### BusyWorker
177212

178213
BusyWorker helps running a UI task on separate threads (other than the JavaFX Application thread). It will show busy
@@ -193,7 +228,7 @@ new BusyWorker("Simple Task", parentWindow).doTask { () =>
193228
}
194229
```
195230

196-
#### Examnple 2
231+
#### Example 2
197232

198233
Here is a little more elaborated example. It updates a progress message and progress indicator.
199234

build.sbt

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,10 @@ import scala.xml.{Node => XmlNode, NodeSeq => XmlNodeSeq, _}
1010
// JAR_BUILT_BY - Name to be added to Jar metadata field "Built-By" (defaults to System.getProperty("user.name")
1111
//
1212

13-
val projectVersion = "0.6.0"
13+
val projectVersion = "0.6.0.1-SNAPSHOT"
1414
val versionTagDir = if (projectVersion.endsWith("SNAPSHOT")) "master" else "v." + projectVersion
1515
val _scalaVersions = Seq("3.0.2", "2.13.8", "2.12.16")
1616
val _scalaVersion = _scalaVersions.head
17-
val _javaFXVersion = "18.0.1"
1817

1918
ThisBuild / version := projectVersion
2019
ThisBuild / crossScalaVersions := _scalaVersions
@@ -24,10 +23,6 @@ ThisBuild / organization := "org.scalafx"
2423
publishArtifact := false
2524
publish / skip := true
2625

27-
lazy val JavaFXModuleLibs: Seq[ModuleID] =
28-
Seq("base", "controls", "fxml", "graphics", "media", "swing", "web")
29-
.map(m => "org.openjfx" % s"javafx-$m" % _javaFXVersion)
30-
3126
def isScala2(scalaVersion: String): Boolean = {
3227
CrossVersion.partialVersion(scalaVersion) match {
3328
case Some((2, _)) => true
@@ -80,7 +75,6 @@ lazy val scalaFXExtrasDemos = (project in file("scalafx-extras-demos")).settings
8075
"-Xmx512M",
8176
"-Djavafx.verbose"
8277
),
83-
libraryDependencies ++= JavaFXModuleLibs,
8478
publishArtifact := false,
8579
libraryDependencies ++= Seq(
8680
"com.typesafe.scala-logging" %% "scala-logging" % "3.9.4",
@@ -131,7 +125,7 @@ lazy val scalaFXExtrasSettings = Seq(
131125
Compile / doc / scalacOptions ++= (
132126
if(isScala2(scalaVersion.value))
133127
Seq(
134-
s"-doc-external-doc:${scalaInstance.value.libraryJars.head}#http://www.scala-lang.org/api/${scalaVersion.value}/",
128+
s"-doc-external-doc:${scalaInstance.value.libraryJars.head}#https://www.scala-lang.org/api/${scalaVersion.value}/",
135129
"-doc-source-url", "https://github.com/SscalaFX-Extras/scalafx-extras/blob/" + versionTagDir + "/scalafx/€{FILE_PATH}.scala"
136130
) ++ (
137131
Option(System.getenv("GRAPHVIZ_DOT_PATH")) match {
@@ -154,9 +148,9 @@ lazy val scalaFXExtrasSettings = Seq(
154148
Seq.empty[sbt.ModuleID]
155149
),
156150
libraryDependencies ++= Seq(
157-
"org.scalafx" %% "scalafx" % "18.0.1-R27",
151+
"org.scalafx" %% "scalafx" % "18.0.2-R29",
158152
"org.scalatest" %% "scalatest" % "3.2.11" % "test"
159-
) ++ JavaFXModuleLibs,
153+
),
160154
libraryDependencies ++= (
161155
if (isScala2(scalaVersion.value))
162156
Seq(
@@ -215,7 +209,7 @@ import xerial.sbt.Sonatype._
215209
// Metadata needed by Maven Central
216210
// See also http://maven.apache.org/pom.html#Developers
217211
lazy val mavenCentralSettings = Seq(
218-
homepage := Some(new URL("http://www.scalafx.org/")),
212+
homepage := Some(new URL("https://www.scalafx.org/")),
219213
startYear := Some(2016),
220214
licenses := Seq(("BSD", new URL("https://github.com/scalafx/scalafx-extras/blob/master/LICENSE.txt"))),
221215
sonatypeProfileName := "org.scalafx",

notes/0.7.0.md

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
### ScalaFX-Extras Release v.0.7.0
2+
3+
This release provides a convenient way to generate dialogs from case classes (scala 3).
4+
`AutoDialog` is used too quickly open auto generated dialog from case class.
5+
After closing, the dialog will return edited version of the input case class:
6+
7+
```scala
8+
import org.scalafx.extras.auto_dialog.AutoDialog
9+
10+
case class FilterOptions(kernelSize: Int = 7,
11+
start: Double = 3.14,
12+
tag: String = "alpha",
13+
debugMode: Boolean = false)
14+
15+
val result: Option[FilterOptions] =
16+
new AutoDialog(FilterOptions())
17+
.showDialog(
18+
"AutoDialog Demo",
19+
"Fields are auto generated from `FilterOptions` object")
20+
21+
println(s"Result: $result")
22+
```
23+
24+
The `scalafx-extras-demos` subproject has an example.
25+
26+
Enhancements:
27+
28+
* \[Scala 3\] auto generate input dialogs from simple case classes [[#18]]
29+
* Update to ScalaFX 18.0.2-R29 [[#20]]
30+
31+
To post questions please use [Project Discussions][Discussions] or [ScalaFX Users Group][scalafx-users]
32+
33+
[Discussions]: https://github.com/scalafx/scalafx-extras/discussions
34+
35+
[scalafx-users]: https://groups.google.com/forum/#!forum/scalafx-users
36+
37+
[#18]: https://github.com/scalafx/scalafx-extras/issues/18
38+
39+
[#20]: https://github.com/scalafx/scalafx-extras/issues/20
40+

notes/assets/AutoDialog.png

13.7 KB
Loading
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* Copyright (c) 2011-2022, ScalaFX Project
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without
6+
* modification, are permitted provided that the following conditions are met:
7+
* * Redistributions of source code must retain the above copyright
8+
* notice, this list of conditions and the following disclaimer.
9+
* * Redistributions in binary form must reproduce the above copyright
10+
* notice, this list of conditions and the following disclaimer in the
11+
* documentation and/or other materials provided with the distribution.
12+
* * Neither the name of the ScalaFX Project nor the
13+
* names of its contributors may be used to endorse or promote products
14+
* derived from this software without specific prior written permission.
15+
*
16+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19+
* DISCLAIMED. IN NO EVENT SHALL THE SCALAFX PROJECT OR ITS CONTRIBUTORS BE LIABLE
20+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23+
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26+
*/
27+
28+
package org.scalafx.extras.auto_dialog
29+
30+
import org.scalafx.extras.initFX
31+
32+
object AutoDialogDemo:
33+
34+
case class FilterOptions(kernelSize: Int = 7,
35+
start: Double = 3.14,
36+
tag: String = "alpha",
37+
debugMode: Boolean = false)
38+
39+
def main(args: Array[String]): Unit =
40+
41+
initFX()
42+
43+
val filterOptions = FilterOptions()
44+
45+
val result: Option[FilterOptions] =
46+
new AutoDialog(filterOptions)
47+
.showDialog(
48+
"AutoDialog Demo",
49+
"Fields are auto generated from `FilterOptions` object")
50+
51+
println(s"Result: $result")
52+
53+
System.exit(0)
54+
55+
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/*
2+
* Copyright (c) 2011-2022, ScalaFX Project
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without
6+
* modification, are permitted provided that the following conditions are met:
7+
* * Redistributions of source code must retain the above copyright
8+
* notice, this list of conditions and the following disclaimer.
9+
* * Redistributions in binary form must reproduce the above copyright
10+
* notice, this list of conditions and the following disclaimer in the
11+
* documentation and/or other materials provided with the distribution.
12+
* * Neither the name of the ScalaFX Project nor the
13+
* names of its contributors may be used to endorse or promote products
14+
* derived from this software without specific prior written permission.
15+
*
16+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17+
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18+
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19+
* DISCLAIMED. IN NO EVENT SHALL THE SCALAFX PROJECT OR ITS CONTRIBUTORS BE LIABLE
20+
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21+
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22+
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23+
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25+
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26+
*/
27+
28+
package org.scalafx.extras.auto_dialog
29+
30+
import org.scalafx.extras.auto_dialog.{DialogDecoder, DialogEncoder}
31+
import org.scalafx.extras.generic_dialog.GenericDialogFX
32+
import scalafx.stage.Window
33+
34+
35+
/** Automatically created a dialog from a case class.
36+
* Names of the members of the input `data` will be used as labels for fields corresponding to their values.
37+
* Initially case with members of `Boolean`, `Int`, `Double`, and `String` are supported.
38+
*
39+
* Use methods [[#showDialog]] to display the dialog and retrieve edited content.
40+
*
41+
* {{{
42+
* case class FilterOptions(kernelSize: Int = 7,
43+
* start: Double = 3.14,
44+
* tag: String = "alpha",
45+
* debugMode: Boolean = false)
46+
*
47+
* val result: Option[FilterOptions] =
48+
* new AutoDialog(FilterOptions())
49+
* .showDialog(
50+
* "Filter Options",
51+
* "Fields below were auto generated from `FilterOptions` object")
52+
*
53+
* println(s"Result: result")
54+
* }}}
55+
*
56+
* @param data data that will define the dialog and its initial values
57+
*/
58+
class AutoDialog[A >: Null : DialogEncoder : DialogDecoder](data: A):
59+
60+
/**
61+
* Display the dialog and block till the dialog is closed.
62+
*
63+
* @param title dialog title
64+
* @param header dialog header
65+
* @param parentWindow optional parent window that will be blocked when dialog is displayed
66+
* @return when dialog was confirmed with OK it will return content of the fields of the dialog.
67+
* If dialog was cancelled it will return `None`
68+
*/
69+
def showDialog(title: String,
70+
header: String = "",
71+
parentWindow: Option[Window] = None): Option[A] =
72+
val gd = new GenericDialogFX(title, header = header, parentWindow = parentWindow)
73+
74+
// Add fields to the dialog
75+
summon[DialogEncoder[A]].addEditor(gd, "", data)
76+
77+
gd.showDialog()
78+
79+
if gd.wasOKed then
80+
val r = summon[DialogDecoder[A]].decode(gd)
81+
Option(r)
82+
else
83+
None
84+
85+
end AutoDialog

0 commit comments

Comments
 (0)