Skip to content

Commit 453f6f5

Browse files
committed
feat: added choice dialog box API for List and Enum options
1 parent ff09b90 commit 453f6f5

File tree

6 files changed

+71
-5
lines changed

6 files changed

+71
-5
lines changed

fxgl-samples/src/main/java/intermediate/DialogsSample.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import javafx.scene.paint.Color;
1616

1717
import java.util.LinkedHashMap;
18+
import java.util.List;
1819
import java.util.Map;
1920

2021
import static com.almasb.fxgl.dsl.FXGL.*;
@@ -26,6 +27,10 @@
2627
*/
2728
public class DialogsSample extends GameApplication {
2829

30+
private enum CustomEnum {
31+
VALUE1, VALUE2, VALUE3
32+
}
33+
2934
@Override
3035
protected void initSettings(GameSettings settings) { }
3136

@@ -42,6 +47,10 @@ protected void initUI() {
4247
dialogs.put("Choice with 3", () -> getDialogService().showChoiceBox("Choose wisely!", answer -> System.out.println("Chosen: " + answer), "Hello", "World", "FXGL"));
4348
dialogs.put("Choice with 4", () -> getDialogService().showChoiceBox("Choose wisely!", answer -> System.out.println("Chosen: " + answer), "Hello", "World", "FXGL", "JavaFX"));
4449

50+
dialogs.put("Choice with List", () -> getDialogService().showChoiceBox("Choose wisely!", List.of("Item1", "Item2"), answer -> System.out.println("Chosen: " + answer)));
51+
52+
dialogs.put("Choice with Enum", () -> getDialogService().showChoiceBox("Choose wisely!", CustomEnum.class, answer -> System.out.println("Chosen: " + answer)));
53+
4554
dialogs.put("Confirmation", () -> getDialogService().showConfirmationBox("This is a confirmation box. Agree?", answer -> System.out.println("You pressed yes? " + answer)));
4655

4756
dialogs.put("Input", () -> getDialogService().showInputBox("This is an input box. You can type stuff...", answer -> System.out.println("You typed: "+ answer)));

fxgl-scene/src/main/java/com/almasb/fxgl/ui/DialogFactoryService.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import javafx.scene.control.Button;
1313
import javafx.scene.layout.Pane;
1414

15+
import java.util.List;
1516
import java.util.function.Consumer;
1617
import java.util.function.Predicate;
1718

@@ -28,6 +29,8 @@ public abstract class DialogFactoryService extends EngineService {
2829

2930
public abstract <T> Pane choiceDialog(String message, Consumer<T> resultCallback, T firstOption, T... options);
3031

32+
public abstract <T> Pane choiceDialog(String message, List<T> options, Consumer<T> resultCallback);
33+
3134
public abstract Pane inputDialog(String message, Consumer<String> callback);
3235

3336
public abstract Pane inputDialog(String message, Predicate<String> filter, Consumer<String> callback);

fxgl-scene/src/main/java/com/almasb/fxgl/ui/DialogService.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import javafx.scene.Node;
1212
import javafx.scene.control.Button;
1313

14+
import java.util.List;
1415
import java.util.function.Consumer;
1516
import java.util.function.Predicate;
1617

@@ -59,6 +60,28 @@ public abstract class DialogService extends EngineService {
5960
*/
6061
public abstract <T> void showChoiceBox(String message, Consumer<T> resultCallback, T firstOption, T... options);
6162

63+
/**
64+
* Shows a blocking message box with given choices.
65+
* The callback is invoked with the user answer as parameter.
66+
*
67+
* @param message message to show
68+
* @param options the list of options
69+
* @param resultCallback the function to be called
70+
* @param <T> type of options
71+
*/
72+
public abstract <T> void showChoiceBox(String message, List<T> options, Consumer<T> resultCallback);
73+
74+
/**
75+
* Shows a blocking message box with given choices.
76+
* The callback is invoked with the user answer as parameter.
77+
*
78+
* @param message message to show
79+
* @param enumClass the Enum class
80+
* @param resultCallback the function to be called
81+
* @param <T> type of options
82+
*/
83+
public abstract <T extends Enum<T>> void showChoiceBox(String message, Class<T> enumClass, Consumer<T> resultCallback);
84+
6285
/**
6386
* Shows a blocking (stops game execution, method returns normally) message box with OK button and input field. The callback
6487
* is invoked with the field text as parameter.

fxgl-scene/src/main/kotlin/com/almasb/fxgl/ui/FXGLDialogFactoryServiceProvider.kt

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ package com.almasb.fxgl.ui
99
import com.almasb.fxgl.core.Inject
1010
import com.almasb.fxgl.core.util.EmptyRunnable
1111
import com.almasb.fxgl.localization.LocalizationService
12+
import com.almasb.fxgl.logging.Logger
1213
import javafx.beans.binding.StringBinding
1314
import javafx.beans.property.ReadOnlyDoubleProperty
1415
import javafx.beans.value.ChangeListener
@@ -95,16 +96,20 @@ class FXGLDialogFactoryServiceProvider : DialogFactoryService() {
9596
}
9697

9798
override fun <T : Any> choiceDialog(message: String, resultCallback: Consumer<T>, firstOption: T, vararg options: T): Pane {
98-
val text = createMessage(message)
99-
10099
val choices = options.toMutableList()
101100
choices.add(0, firstOption)
102101

102+
return choiceDialog(message, choices, resultCallback)
103+
}
104+
105+
override fun <T : Any> choiceDialog(message: String, options: List<T>, resultCallback: Consumer<T>): Pane {
106+
val text = createMessage(message)
107+
103108
val hbox = HBox()
104109

105-
if (choices.size > 3) {
110+
if (options.size > 3) {
106111

107-
val choiceBox = uiFactory.newChoiceBox(FXCollections.observableArrayList(choices))
112+
val choiceBox = uiFactory.newChoiceBox(FXCollections.observableArrayList(options))
108113
choiceBox.selectionModel.selectFirst()
109114

110115
val btn = uiFactory.newButton("Select")
@@ -115,8 +120,15 @@ class FXGLDialogFactoryServiceProvider : DialogFactoryService() {
115120
hbox.children += choiceBox
116121
hbox.children += btn
117122

123+
} else if (options.size == 0) {
124+
Logger.get<FXGLDialogFactoryServiceProvider>().warning("choiceDialog() called with an empty options list")
125+
126+
val btn = uiFactory.newButton("No options provided")
127+
128+
hbox.children += btn
129+
118130
} else {
119-
choices.forEach { option ->
131+
options.forEach { option ->
120132
val btn = uiFactory.newButton(option.toString())
121133
btn.setOnAction {
122134
resultCallback.accept(option)

fxgl/src/main/kotlin/com/almasb/fxgl/app/services/FXGLDialogService.kt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,19 @@ class FXGLDialogService : DialogService() {
142142
show("Choice", dialog)
143143
}
144144

145+
override fun <T : Any> showChoiceBox(message: String, options: List<T>, resultCallback: Consumer<T>) {
146+
val dialog = dialogFactory.choiceDialog(message, options) { result ->
147+
close()
148+
resultCallback.accept(result)
149+
}
150+
151+
show("Choice", dialog)
152+
}
153+
154+
override fun <T : Enum<T>> showChoiceBox(message: String, enumClass: Class<T>, resultCallback: Consumer<T>) {
155+
showChoiceBox(message, EnumSet.allOf(enumClass).toList(), resultCallback)
156+
}
157+
145158
override fun showInputBox(message: String, resultCallback: Consumer<String>) {
146159
showInputBox(message, Predicate { true }, resultCallback)
147160
}

fxgl/src/test/kotlin/com/almasb/fxgl/app/MockDialogService.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ object MockDialogService : DialogService() {
3131
override fun <T : Any?> showChoiceBox(message: String?, resultCallback: Consumer<T>?, firstOption: T, vararg options: T) {
3232
}
3333

34+
override fun <T : Any?> showChoiceBox(message: String?, options: MutableList<T>?, resultCallback: Consumer<T>?) {
35+
}
36+
37+
override fun <T : Enum<T>?> showChoiceBox(message: String?, enumClass: Class<T>?, resultCallback: Consumer<T>?) {
38+
}
39+
3440
override fun showInputBoxWithCancel(message: String?, filter: Predicate<String>?, resultCallback: Consumer<String>?) {
3541
}
3642

0 commit comments

Comments
 (0)