close fxml window by code, javafx
JavaUser InterfaceJavafxFxmlJava Problem Overview
I need to close the current fxml window by code in the controller
> I know stage.close() or stage.hide() do this in fx
how to implement this in fxml? I tried
private void on_btnClose_clicked(ActionEvent actionEvent) {
Parent root = FXMLLoader.load(getClass().getResource("currentWindow.fxml"));
Scene scene = new Scene(root);
Stage stage = new Stage();
stage.setScene(scene);
stage.show();
}
but it doesn't work!
All help will be greatly appreciated. Thanks!
Java Solutions
Solution 1 - Java
-
give your close button an fx:id, if you haven't yet:
<Button fx:id="closeButton" onAction="#closeButtonAction">
-
In your controller class:
@FXML private javafx.scene.control.Button closeButton; @FXML private void closeButtonAction(){ // get a handle to the stage Stage stage = (Stage) closeButton.getScene().getWindow(); // do what you have to do stage.close(); }
Solution 2 - Java
If you have a window which extends javafx.application.Application;
you can use the following method.
(This will close the whole application, not just the window. I misinterpreted the OP, thanks to the commenters for pointing it out).
Platform.exit();
Example:
public class MainGUI extends Application {
.........
Button exitButton = new Button("Exit");
exitButton.setOnAction(new ExitButtonListener());
.........
public class ExitButtonListener implements EventHandler<ActionEvent> {
@Override
public void handle(ActionEvent arg0) {
Platform.exit();
}
}
Edit for the beauty of Java 8:
public class MainGUI extends Application {
.........
Button exitButton = new Button("Exit");
exitButton.setOnAction(actionEvent -> Platform.exit());
}
Solution 3 - Java
I implemented this in the following way after receiving a NullPointerException
from the accepted answer.
In my FXML:
<Button onMouseClicked="#onMouseClickedCancelBtn" text="Cancel">
In my Controller
class:
@FXML public void onMouseClickedCancelBtn(InputEvent e) {
final Node source = (Node) e.getSource();
final Stage stage = (Stage) source.getScene().getWindow();
stage.close();
}
Solution 4 - Java
If you don't want to overspread you your controller with fxml linked methods you can do something like this:
You have to give it a fx:id. "closeButton" for Example. Should look like this in your FXML file:
<Button fx:id="closeButton" layoutX="876.0" layoutY="74.0" mnemonicParsing="false" textAlignment="CENTER">
Then you can just code the button in your initialize method or wherever you want:
@FXML
Button closeButton
public initialize(){
closeButton.setOnAction(new EventHandler<ActionEvent>(){
@Override
public void handle(ActionEvent e){
((Stage) closeButton.getScence().getWindow()).close();
}
});
}
Solution 5 - Java
I'm not sure if this is the best way (or if it works), but you could try:
private void on_btnClose_clicked(ActionEvent actionEvent) {
Window window = getScene().getWindow();
if (window instanceof Stage){
((Stage) window).close();
}
}
(Assuming your controller is a Node. Otherwise you have to get the node first (getScene() is a method of Node)
Solution 6 - Java
stage.setOnCloseRequest(new EventHandler<WindowEvent>() {
public void handle(WindowEvent we) {
Platform.setImplicitExit(false);
stage.close();
}
});
It is equivalent to hide
. So when you are going to open it next time, you just check if the stage
object is exited or not. If it is exited, you just show()
i.e. (stage.show())
call. Otherwise, you have to start the stage.
Solution 7 - Java
I found a nice solution which does not need an event to be triggered:
@FXML
private Button cancelButton;
close(new Event(cancelButton, stage, null));
@FXML
private void close(Event event) {
((Node)(event.getSource())).getScene().getWindow().hide();
}
Solution 8 - Java
finally, I found a solution
Window window = ((Node)(event.getSource())).getScene().getWindow();
if (window instanceof Stage){
((Stage) window).close();
}
Solution 9 - Java
Hide doesn't close the window, just put in visible mode. The best solution was:
@FXML
private void exitButtonOnAction(ActionEvent event){
((Stage)(((Button)event.getSource()).getScene().getWindow())).close();
}