I have this small subclass of JavaFX's javafx.scene.control.Dialog
that requires the enum specifying the data type of the input data:
package com.github.coderodde.jfx.ui;
import java.util.Objects;
import java.util.Optional;
import javafx.event.EventHandler;
import javafx.scene.control.ButtonBar.ButtonData;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Dialog;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.GridPane;
import javafx.scene.paint.Color;
public final class TypedInputDialog extends Dialog<Number> {
private static final Color DEFAULT_COLOR_TEXT_NORMAL = Color.BLACK;
private static final Color DEFAULT_COLOR_TEXT_ERROR = Color.RED;
public enum InputType {
INTEGER,
LONG,
FLOAT,
DOUBLE;
}
private String promptText = "";
private final InputType inputType;
private final Label errorMessageLabel = new Label();
private final TextField inputTextField = new TextField();
private EventHandler<KeyEvent> keyEventHandler;
private Color colorTextNormal = DEFAULT_COLOR_TEXT_NORMAL;
private Color colorTextError = DEFAULT_COLOR_TEXT_ERROR;
private Optional<Number> data = Optional.empty();
public TypedInputDialog(InputType inputType) {
this.inputType = inputType;
buildKeyEventHandler();
inputTextField.setPromptText(promptText);
inputTextField.setOnKeyTyped(keyEventHandler);
GridPane gridPane = new GridPane();
gridPane.add(errorMessageLabel, 0, 0);
gridPane.add(inputTextField, 0, 1);
getDialogPane().setContent(gridPane);
ButtonType buttonTypeOK = new ButtonType("OK", ButtonData.OK_DONE);
this.getDialogPane().getButtonTypes().add(buttonTypeOK);
this.setResultConverter((ButtonType p) -> {
if (p == buttonTypeOK) {
return data.orElse(null);
}
return null;
});
}
public String getPromptText() {
return promptText;
}
public void setPromptText(String promptText) {
this.promptText =
Objects.requireNonNull(
promptText,
"The input prompt text is null.");
}
public Color getNormalTextColor() {
return colorTextNormal;
}
public Color getErrorTextColor() {
return colorTextError;
}
public void setNormalTextColor(Color normalTextColor) {
this.colorTextNormal =
Objects.requireNonNull(
normalTextColor,
"The input color is null.");
}
public void setErrorTextColor(Color errorTextColor) {
this.colorTextError =
Objects.requireNonNull(
errorTextColor,
"The input color is null.");
}
private void buildKeyEventHandler() {
this.keyEventHandler = (keyEvent) -> {
switch (inputType) {
case DOUBLE:
processDouble();
break;
case FLOAT:
processFloat();
break;
case INTEGER:
processInteger();
break;
case LONG:
processLong();
break;
default:
throw new IllegalStateException(
"Unknown type: " + inputType);
}
};
}
private void processInteger() {
if (inputTextField.getText().isBlank()) {
data = Optional.empty();
writeNormalMessage("");
return;
}
int value;
try {
value = Integer.parseInt(inputTextField.getText());
writeNormalMessage("");
data = Optional.ofNullable(value);
} catch (NumberFormatException ex) {
writeErrorMessage(
"Wrong 32-bit integer value: " + inputTextField.getText());
}
}
private void processLong() {
if (inputTextField.getText().isBlank()) {
data = Optional.empty();
writeNormalMessage("");
return;
}
long value;
try {
value = Long.parseLong(inputTextField.getText());
writeNormalMessage("");
data = Optional.ofNullable(value);
} catch (NumberFormatException ex) {
writeErrorMessage(
"Wrong 64-bit integer value: " + inputTextField.getText());
}
}
private void processFloat() {
if (inputTextField.getText().isBlank()) {
data = Optional.empty();
writeNormalMessage("");
return;
}
float value;
try {
value = Float.parseFloat(inputTextField.getText());
writeNormalMessage("");
data = Optional.ofNullable(value);
} catch (NumberFormatException ex) {
writeErrorMessage(
"Wrong 32-bit floating-point value: "
+ inputTextField.getText());
}
}
private void processDouble() {
if (inputTextField.getText().isBlank()) {
data = Optional.empty();
writeNormalMessage("");
return;
}
double value;
try {
value = Double.parseDouble(inputTextField.getText());
writeNormalMessage("");
data = Optional.ofNullable(value);
} catch (NumberFormatException ex) {
writeErrorMessage(
"Wrong 64-bit floating-point value: "
+ inputTextField.getText());
}
}
private void writeNormalMessage(String statusMessage) {
writeStatusMessage(
statusMessage,
colorTextNormal);
}
private void writeErrorMessage(String statusMessage) {
writeStatusMessage(
statusMessage,
colorTextError);
}
private void writeStatusMessage(String statusMessage, Color textColor) {
errorMessageLabel.setStyle(
"-fx-text-fill: "
+ convertColorToRGBText(textColor)
+ ";");
errorMessageLabel.setText(statusMessage);
}
private static String convertColorToRGBText(Color color) {
return String.format(
"#%02X%02X%02X",
(int)(color.getRed() * 255),
(int)(color.getGreen() * 255),
(int)(color.getBlue() * 255));
}
}
package com.github.coderodde.jfx.ui;
import java.util.Optional;
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.stage.Stage;
public class Demo extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) throws Exception {
TypedInputDialog dialog =
new TypedInputDialog(TypedInputDialog.InputType.DOUBLE);
dialog.setPromptText("(Enter value here)");
dialog.setTitle("Demo TypedInputDialog");
dialog.setHeaderText("Enter a double floating-point value:");
Optional<Number> result = dialog.showAndWait();
System.out.println("Input value: " + result.orElse(null));
}
}
Critique request
So what do you think? What shall I improve?
Thanks in advance.