Skip to content

Commit 559afd1

Browse files
Added application 5 - custom dialogs
1 parent 5e4c9bf commit 559afd1

File tree

15 files changed

+436
-21
lines changed

15 files changed

+436
-21
lines changed

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ The list of demo apps includes:
1515
* **Application 2** - Drag and Drop
1616
* **Application 3** - Nested Controllers, Event Based using Google EventBus
1717
* **Application 4** - TableView Cell Value Factories vs Cell Factories
18+
* **Application 5** - Custom Dialogs, an alternative to JavaFX official approach
1819

1920

2021
My blog on JavaFx with Kotlin at [https://thickclient.blog/](https://thickclient.blog/)
@@ -125,3 +126,11 @@ Start the application with:
125126

126127
gradlew runApp4
127128

129+
#### Application 5 - Custom Dialogs
130+
131+
* Simple, alternative custom dialog framework (2 classes!!) for creating custom dialogs
132+
* FXML based UI
133+
134+
Start the application with:
135+
136+
gradlew runApp5

build.gradle

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,11 @@ def JFX_INSTALL = '/Library/Java/javafx/13.0'
1212
// END YOUR SETUP
1313

1414
group 'org.epistatic'
15-
version '1.1.0'
15+
version '2.2.0'
1616

1717
repositories {
1818
mavenCentral()
19+
jcenter()
1920
flatDir {
2021
dirs "${JFX_INSTALL}/lib"
2122
}
@@ -98,6 +99,19 @@ task runApp4(type: JavaExec) {
9899
}
99100
}
100101

102+
task runApp5(type: JavaExec) {
103+
group = "Application"
104+
description = "Runs Application 5 - Custom Dialog Demo"
105+
classpath sourceSets.main.runtimeClasspath
106+
main = 'org.epistatic.app5.Main'
107+
doFirst {
108+
jvmArgs = [
109+
'--module-path', "${JFX_INSTALL}/lib",
110+
'--add-modules', 'javafx.fxml,javafx.controls'
111+
]
112+
}
113+
}
114+
101115
task collateInstall(type:Copy){
102116
delete "installBuild"
103117
mkdir "installBuild/lib"

src/main/kotlin/org/epistatic/app4/controller/ApplicationController.kt

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,3 @@
1-
package org.epistatic.app4.controller
2-
3-
import javafx.beans.property.ReadOnlyObjectWrapper
4-
import javafx.collections.FXCollections
5-
import javafx.collections.ObservableList
6-
import javafx.fxml.FXML
7-
import javafx.scene.control.Button
8-
import javafx.scene.control.TableCell
9-
import javafx.scene.control.TableColumn
10-
import javafx.scene.control.TableView
11-
import javafx.scene.control.cell.PropertyValueFactory
12-
import javafx.stage.Stage
13-
import org.epistatic.app4.model.DateItem
14-
import java.time.OffsetDateTime
15-
import java.time.ZoneOffset
16-
17-
181
/**
192
* Licensed to the Apache Software Foundation (ASF) under one
203
* or more contributor license agreements. See the NOTICE file
@@ -34,8 +17,25 @@ import java.time.ZoneOffset
3417
* under the License.
3518
**/
3619

20+
package org.epistatic.app4.controller
21+
22+
import javafx.beans.property.ReadOnlyObjectWrapper
23+
import javafx.collections.FXCollections
24+
import javafx.collections.ObservableList
25+
import javafx.fxml.FXML
26+
import javafx.scene.control.Button
27+
import javafx.scene.control.TableCell
28+
import javafx.scene.control.TableColumn
29+
import javafx.scene.control.TableView
30+
import javafx.scene.control.cell.PropertyValueFactory
31+
import javafx.stage.Stage
32+
import org.epistatic.app4.model.DateItem
33+
import java.time.OffsetDateTime
34+
import java.time.ZoneOffset
35+
36+
3737
/**
38-
* Controller for app5/app4.fxml
38+
* Controller for app4/app4.fxml
3939
*/
4040
class ApplicationController {
4141

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
**/
19+
20+
package org.epistatic.app5
21+
22+
import javafx.application.Application
23+
import javafx.fxml.FXMLLoader
24+
import javafx.scene.Scene
25+
import javafx.scene.layout.GridPane
26+
import javafx.scene.layout.Pane
27+
import javafx.stage.Stage
28+
29+
/**
30+
* An Application with multiple controllers and nested FXML
31+
*
32+
* 1) Assigning controllers to FXML at runtime
33+
* 2) Multiple controllers communicating via Events (via Google EventBus)
34+
* 3) Dragging Items from the Desktop
35+
* 4) Controllers can leverage dependency injection, improving testing options
36+
*/
37+
class Main : Application() {
38+
39+
@Throws(Exception::class)
40+
override fun start(primaryStage: Stage) {
41+
val loader = FXMLLoader(javaClass.getResource("/app5/app5.fxml"))
42+
val root = loader.load<Pane>()
43+
primaryStage.title = "Custom Dialog Demo"
44+
primaryStage.scene = Scene(root, 400.0, 150.0)
45+
primaryStage.show()
46+
}
47+
48+
companion object {
49+
@JvmStatic
50+
fun main(args: Array<String>) {
51+
launch(Main::class.java, *args)
52+
}
53+
}
54+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
**/
19+
20+
package org.epistatic.app5.controller
21+
22+
import javafx.fxml.FXML
23+
import javafx.scene.control.Button
24+
import javafx.scene.control.Label
25+
import javafx.stage.Stage
26+
27+
/**
28+
* Controller for app5 - Custom Dialog Demo
29+
*/
30+
class ApplicationController {
31+
32+
@FXML lateinit var exitButton: Button
33+
@FXML lateinit var nameLabel: Label
34+
35+
@FXML
36+
fun initialize() {
37+
}
38+
39+
@FXML
40+
fun rename() {
41+
val stage = exitButton.scene.window as Stage
42+
val dialog = SingleValueDialog(stage,"New Name", "Change Name", nameLabel.text)
43+
val result = dialog.showAndWait()
44+
if (result.ok){
45+
nameLabel.text = result.data
46+
}
47+
}
48+
49+
@FXML
50+
fun closeApplication() {
51+
val stage = exitButton.scene.window as Stage
52+
stage.close()
53+
}
54+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
**/
19+
20+
package org.epistatic.app5.controller
21+
22+
import javafx.stage.Modality
23+
import javafx.stage.Stage
24+
25+
/**
26+
* Superclass of all non-trivial custom dialogs which are essentially modal windows
27+
* Not for standard message or warning dialogs - use JavaFX dialogs for those
28+
*/
29+
abstract class CustomDialog<T>(ownerStage: Stage, title: String) {
30+
31+
private var result: T? = null
32+
33+
var stage: Stage = Stage()
34+
35+
init {
36+
stage.title = title
37+
stage.initOwner(ownerStage)
38+
}
39+
40+
/**
41+
* override this to return result from dialog's controller
42+
*/
43+
abstract fun result(): DialogResult<T>
44+
45+
/**
46+
* Show dialog modally and then return the result
47+
*/
48+
fun showAndWait(): DialogResult<T> {
49+
stage.initModality(Modality.APPLICATION_MODAL)
50+
stage.showAndWait()
51+
return result()
52+
}
53+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
**/
19+
20+
package org.epistatic.app5.controller
21+
22+
class DialogResult<T>(val ok: Boolean, val data: T)
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/**
2+
* Licensed to the Apache Software Foundation (ASF) under one
3+
* or more contributor license agreements. See the NOTICE file
4+
* distributed with this work for additional information
5+
* regarding copyright ownership. The ASF licenses this file
6+
* to you under the Apache License, Version 2.0 (the
7+
* "License"); you may not use this file except in compliance
8+
* with the License. You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing,
13+
* software distributed under the License is distributed on an
14+
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
* KIND, either express or implied. See the License for the
16+
* specific language governing permissions and limitations
17+
* under the License.
18+
**/
19+
20+
package org.epistatic.app5.controller
21+
22+
import javafx.fxml.FXMLLoader
23+
import javafx.scene.Scene
24+
import javafx.scene.layout.VBox
25+
import javafx.stage.Stage
26+
27+
/**
28+
* Simple dialog for entering a single string value. Title, label and default parameters
29+
* are all constructor arguments
30+
*/
31+
class SingleValueDialog(ownerStage: Stage, label: String, title: String, defaultValue: String?) : CustomDialog<String>(ownerStage, title) {
32+
33+
var controller: SingleValueDialogController
34+
35+
init {
36+
val loader = FXMLLoader(javaClass.getResource("/app5/singleValueDialog.fxml"))
37+
controller = SingleValueDialogController(label, defaultValue)
38+
loader.setController(controller)
39+
val root = loader.load<VBox>()
40+
stage.scene = Scene(root)
41+
}
42+
43+
override fun result(): DialogResult<String> {
44+
val v = controller.getValue()
45+
if (v != null)
46+
return DialogResult(true, v)
47+
return DialogResult(false, "")
48+
}
49+
}

0 commit comments

Comments
 (0)