user5219532
user5219532

Reputation:

JavaFX close window and open another one by "x" Button in title bar AND button in window

In my application when the user presses a button the current window will hide/close and open a new window. In this new window is an "Exit" button. When the user clicks it, it will also close/hide the current window and "reopen" the parent window. The same behaviour I have on the "x" button in the title bar. Currently I solved it by having different code blocks for both buttons/events. As the code for the action is mostly the same, my goal is to have only one code block to handle for the "Exit" button and the "x" button in the title bar.

Here is the code I have so far:

import com.sun.deploy.association.Action;
import java.io.IOException;
import java.net.URL;
import java.util.ResourceBundle;
import java.util.logging.Level;
import java.util.logging.Logger;
import javafx.application.Platform;
import javafx.event.ActionEvent;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.ButtonType;
import javafx.scene.control.Dialog;
import javafx.scene.control.MenuItem;
import javafx.stage.Stage;
import javafx.scene.control.DialogEvent;
import javafx.scene.control.DialogPane;
import javafx.scene.layout.GridPane;
import javafx.scene.paint.Color;
import javafx.stage.StageStyle;
import javafx.stage.WindowEvent;

/**
 *
 * @author Mike
 */
public class FXMLBlahBLahUIController implements Initializable {

    @FXML
    private MenuItem FileMenuCloseItem;

    @FXML
    private MenuItem HelpMenuAboutItem;

    @FXML
    private javafx.scene.layout.BorderPane BlahBLahUIMainWindow;

    @FXML
    private javafx.scene.control.Button BackupTaskExitButton;

    @FXML
    private void handleButtonActionMenuFileClose(ActionEvent event) {
        Platform.exit();
    }

    @FXML
    private void handleButtonActionMenuHelpAbout(ActionEvent event) throws Exception {

        // Decalaration of Variables
        DialogPane pane;
        Dialog<ButtonType> dia;

        // Execution Block
        pane = FXMLLoader.load(getClass().getResource("FXMLBlahBLahUIHelpAbout.fxml"));
        dia = new Dialog();
        dia.setDialogPane(pane);
        dia.setContentText(pane.getContentText());
        dia.setResizable(false);
        dia.initStyle(StageStyle.UNDECORATED);
        dia.showAndWait();

    }

    @FXML
    private void handleButtonActionTaskBackup(ActionEvent event) throws Exception {

        // Decalaration of Variables
        FXMLLoader pane;
        Parent backup;
        Stage stage, stage1;

        // Execution Block
        pane = new FXMLLoader(getClass().getResource("FXMLBlahBLahUIBackup.fxml"));
        backup = (Parent) pane.load();
        stage = new Stage();
        stage.setScene(new Scene(backup, Color.TRANSPARENT));
        stage.setTitle("BlahBLahui Backuptasks");
        stage.initStyle(StageStyle.UTILITY);
        stage.setOnCloseRequest(new EventHandler<WindowEvent>() {
            @Override
            public void handle(WindowEvent event) {

                // Decalaration of Variables
                final Stage stage, stage1;
                FXMLLoader pane;
                Parent taskselectwindow = null;

                // Execution Block
                event.consume();
                stage = (Stage) event.getSource();
                stage.close();
                pane = new FXMLLoader(getClass().getResource("FXMLBlahBLahUI.fxml"));
                try {
                    taskselectwindow = (Parent) pane.load();
                } catch (IOException ex) {
                    Logger.getLogger(FXMLBlahBLahUIController.class.getName()).log(Level.SEVERE, null, ex);
                }
                stage1 = new Stage();
                stage1.setScene(new Scene(taskselectwindow));
                stage1.setTitle("BlahBLahUI");
                stage1.show();
            }

        });
        stage1 = (Stage) BlahBLahUIMainWindow.getScene().getWindow();
        stage1.hide();
        stage.show();

    }

    @FXML
    private void handleButtonActionTaskBackupExit(ActionEvent event) throws Exception {

        closebackuptaskandshowmaintask();
    }

    private void closebackuptaskandshowmaintask() throws Exception {
        // Decalaration of Variables
        final Stage stage, stage1;
        FXMLLoader pane;
        Parent taskselectwindow;

        // Execution Block
        stage = (Stage) BackupTaskExitButton.getScene().getWindow();
        stage.close();
        pane = new FXMLLoader(getClass().getResource("FXMLBlahBLahUI.fxml"));
        taskselectwindow = (Parent) pane.load();
        stage1 = new Stage();
        stage1.setScene(new Scene(taskselectwindow));
        stage1.setTitle("BlahBLahUI");
        stage1.show();
    }

    @Override
    public void initialize(URL url, ResourceBundle rb) {
        // TODO
    }

}

This code works as I want but I want to have as much identical code as possible in one class so that I have to call only this class instead of rewriting the same code again and again. For the "Exit" button onAction event I already have created a class. Which modifications are needed there that I can run it on the stage.setOnCloseRequest event too?

Upvotes: 4

Views: 11502

Answers (1)

user5219532
user5219532

Reputation:

I managed to find a solution.

First I changed the method closebackuptaskandshowmaintask.

It looks now so:

    private void closebackuptaskandshowmaintask(Event event) throws Exception {
    // Decalaration of Variables
    final Stage stage, stage1;
    FXMLLoader pane;
    Parent taskselectwindow;
    String eventstring;

    // Execution Block
    eventstring = event.getEventType().toString();
    if ("ACTION".equals(eventstring)) {
        stage = (Stage) BackupTaskExitButton.getScene().getWindow();
        stage.close();
    } else if ("WINDOW_CLOSE_REQUEST".equals(eventstring)) {
        event.consume();
        stage = (Stage) event.getSource();
        stage.close();            
    }
    pane = new FXMLLoader(getClass().getResource("FXMLBlahBLahUI.fxml"));
    taskselectwindow = (Parent) pane.load();
    stage1 = new Stage();
    stage1.setScene(new Scene(taskselectwindow));
    stage1.setTitle("BlahBLahUI");
    stage1.show();
}

Then I replaced the code for stage.setOnCloseRequest with the following:

    stage.setOnCloseRequest(new EventHandler<WindowEvent>() {
    @Override
    public void handle(WindowEvent event1) {
        try {
            closebackuptaskandshowmaintask(event1);
        }catch (Exception ex) {
            Logger.getLogger(FXMLReflectUIController.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
});

Or as lambda expression:

    stage.setOnCloseRequest((WindowEvent event1) -> {
    try {
        closebackuptaskandshowmaintask(event1);
    }catch (Exception ex) {
        Logger.getLogger(FXMLReflectUIController.class.getName()).log(Level.SEVERE, null, ex);
    }
});

Upvotes: 1

Related Questions