Skip to content
This repository has been archived by the owner on Mar 5, 2023. It is now read-only.

Commit

Permalink
MainWindow.fxml: update onCloseRequest event to call handleExit()
Browse files Browse the repository at this point in the history
The MainWindow has no specified event handler when there are external
requests to close the MainWindow, such as the close button or through
the taskbar.

This may cause the app to not close properly since it will not raise an
ExitAppRequestEvent, in turn MainApp#stop() is not called.
MainApp#stop() is the method used to call Platform#exit() and
System#exit(int) which stops our app and closes all remaining open
windows. Thus, if MainApp#stop() is not called, the app may continue to
run even after the MainWindow is closed, causing existing HelpWindows
to remain open even when the user expects the app to stop.

According to the life-cycle section in the documentation on JavaFX
Application[1], the app will only finish and call MainApp#stop() when
the app either calls Platform#exit() or when the last window has been
closed. Thus, should there be any HelpWindows still opened, the app
will continue running, causing those HelpWindows to remain open.

Let's add an event handler for the onCloseRequest event in the root of
MainWindow.fxml. This event will call MainWindow#handleExit() when
raised by an external request to close the app.

MainWindowHandleUnit does not contain a close button, thus we fire a
WindowEvent#WINDOW_CLOSE_REQUEST event which simulates an external
request to close the MainWindow for testing if an ExitAppRequestEvent
was raised.

[1] JavaFx documentation for Application:
https://docs.oracle.com/javafx/2/api/javafx/application/Application.html
  • Loading branch information
yamidark committed Feb 24, 2018
1 parent 529d75f commit be7e926
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/main/resources/view/MainWindow.fxml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<?import javafx.scene.layout.VBox?>

<fx:root type="javafx.stage.Stage" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"
minWidth="450" minHeight="600">
minWidth="450" minHeight="600" onCloseRequest="#handleExit">
<icons>
<Image url="@/images/address_book_32.png" />
</icons>
Expand Down
86 changes: 86 additions & 0 deletions src/test/java/seedu/address/ui/MainWindowTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package seedu.address.ui;

import static org.junit.Assert.assertTrue;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.testfx.api.FxToolkit;

import guitests.guihandles.StageHandle;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;
import seedu.address.commons.core.Config;
import seedu.address.commons.events.ui.ExitAppRequestEvent;
import seedu.address.logic.LogicManager;
import seedu.address.model.ModelManager;
import seedu.address.model.UserPrefs;
import seedu.address.ui.testutil.EventsCollectorRule;

public class MainWindowTest extends GuiUnitTest {
@Rule
public final EventsCollectorRule eventsCollectorRule = new EventsCollectorRule();

private MainWindow mainWindow;
private MainWindowHandleUnit mainWindowHandle;
private Stage stage;

@Before
public void setUp() throws Exception {
FxToolkit.setupStage(stage -> {
this.stage = stage;
mainWindow = prepareMainWindow(stage);
stage.setScene(mainWindow.getRoot().getScene());
mainWindowHandle = new MainWindowHandleUnit(stage);
mainWindowHandle.focus();
});
FxToolkit.showStage();
}

@Test
public void exit_menuBarExitButton_exitAppRequestEventPosted() {
mainWindowHandle.clickOnMenuExitButton();
assertTrue(eventsCollectorRule.eventsCollector.getMostRecent() instanceof ExitAppRequestEvent);
assertTrue(eventsCollectorRule.eventsCollector.getSize() == 1);
}

@Test
public void exit_externalRequest_exitAppRequestEventPosted() {
mainWindowHandle.closeMainWindowExternally();
assertTrue(eventsCollectorRule.eventsCollector.getMostRecent() instanceof ExitAppRequestEvent);
assertTrue(eventsCollectorRule.eventsCollector.getSize() == 1);
}

/**
* Returns a default {@code MainWindow} with the given {@code stage} and default values for its other parameters.
*/
private MainWindow prepareMainWindow(Stage stage) {
return new MainWindow(stage, new Config(), new UserPrefs(), new LogicManager(new ModelManager()));
}

/**
* {@code MainWindow} unit test class without any other components to test closing of the {@code MainWindow}.
*/
private class MainWindowHandleUnit extends StageHandle {

private MainWindowHandleUnit(Stage stage) {
super(stage);
}

/**
* Closes the {@code MainWindow} using its menu bar.
*/
private void clickOnMenuExitButton() {
guiRobot.clickOn("File");
guiRobot.clickOn("Exit");
}

/**
* Simulate an external request to close the {@code MainWindow} (e.g pressing the 'X' button on the
* {@code MainWindow} or closing the app through the taskbar).
*/
private void closeMainWindowExternally() {
guiRobot.interact(() -> stage.fireEvent(new WindowEvent(stage, WindowEvent.WINDOW_CLOSE_REQUEST)));
}
}
}

0 comments on commit be7e926

Please sign in to comment.