Reputation: 4497
I want to create a custom JavaFX dialog. So far I've create something like that:
public class LoginDialog extends Dialog {
public LoginDialog(Data data) {
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("fxml/LoginDialog.fxml"));
Parent root = loader.load();
LoginDialogController controller = loader.<LoginDialogController>getController();
controller.setModel(new LoginModel(data));
getDialogPane().setContent(root);
} catch (IOException e) {
e.printStackTrace();
}
}
}
But - at first I'm not convinced that this is the right way to do this.
Secondly - I wish to use a Button declared in LoginDialog.fxml file to close this LoginDialog, after showAndWait() call. Is it possible? How can I set the return value?
Upvotes: 1
Views: 15990
Reputation: 19640
You can create a dialog using the following way
public void popup() {
final Stage dialog = new Stage();
dialog.setTitle("Confirmation");
Button yes = new Button("Yes");
Button no = new Button("No");
Label displayLabel = new Label("What do you want to do ?");
displayLabel.setFont(Font.font(null, FontWeight.BOLD, 14));
dialog.initModality(Modality.NONE);
dialog.initOwner((Stage) tableview.getScene().getWindow());
HBox dialogHbox = new HBox(20);
dialogHbox.setAlignment(Pos.CENTER);
VBox dialogVbox1 = new VBox(20);
dialogVbox1.setAlignment(Pos.CENTER_LEFT);
VBox dialogVbox2 = new VBox(20);
dialogVbox2.setAlignment(Pos.CENTER_RIGHT);
dialogHbox.getChildren().add(displayLabel);
dialogVbox1.getChildren().add(yes);
dialogVbox2.getChildren().add(no);
yes.addEventHandler(MouseEvent.MOUSE_CLICKED,
new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent e) {
// inside here you can use the minimize or close the previous stage//
dialog.close();
}
});
no.addEventHandler(MouseEvent.MOUSE_CLICKED,
new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent e) {
dialog.close();
}
});
dialogHbox.getChildren().addAll(dialogVbox1, dialogVbox2);
Scene dialogScene = new Scene(dialogHbox, 500, 40);
dialogScene.getStylesheets().add("//style sheet of your choice");
dialog.setScene(dialogScene);
dialog.show();
}
This method is preferable by me as i donot have to create a sepearate controller and i get a pop up
Upvotes: 2
Reputation: 209714
Close the window from the controller:
public class LoginDialogController {
@FXML
private Button button ;
@FXML
private void handleButtonPress() {
button.getScene().getWindow().hide();
}
// ...
}
(and in the FXML you need something like <Button fx:id="button" onAction="#handleButtonPress" ... />
)
To return a value, specify the type for the dialog and set the result converter:
public class LoginDialog extends Dialog<SomeDataType> {
public LoginDialog(Data data) {
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("fxml/LoginDialog.fxml"));
Parent root = loader.load();
LoginDialogController controller = loader.<LoginDialogController>getController();
controller.setModel(new LoginModel(data));
getDialogPane().setContent(root);
setResultConverter(buttonType -> {
SomeDataType someData = ... ;
return someData ;
});
} catch (IOException e) {
e.printStackTrace();
}
}
}
Obviously you can reference the controller in the result converter, call methods on it, etc, so you can return different values depending on what the user does in the UI.
Upvotes: 3