-
Notifications
You must be signed in to change notification settings - Fork 1.7k
HelpWindow: help window stays open even after exiting by clicking the close button #826 #832
HelpWindow: help window stays open even after exiting by clicking the close button #826 #832
Conversation
v1@yamidark submitted v1 for review. Checkout this PR version locallygit fetch https://github.com/se-edu/addressbook-level4.git refs/pr/832/1/head:BRANCHNAME where |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a few nits on the commit message:
The title of the commit message could give a better overview instead? Like for example, MainWindow: add an event handler for the close button
?
any other external method
sounds a bit unclear to me.
This may cause the app to not close properly
To be more specific, only the HelpWindow
doesn't close, right?
The 4th paragraph seems to have gone into too much detail such as explaining what handleExit()
does.
Kind of followed the style I have been using, where the commit title just states what I'm doing, and the other parts of the message explains what it is and why we need it.
We technically can close the
The app itself also doesn't stop running which is the reason why the
Hmmm, yep probably don't need to go into detail what |
Oh, in that case, it should be fine 👍
You could add the example and phrase it like,
Oh, didn't notice that, my bad 😅 |
* Sets an event handler for the app to stop when the {@code MainWindow}'s close button is pressed. | ||
*/ | ||
private void setCloseButtonEvent() { | ||
getPrimaryStage().setOnCloseRequest(event -> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If some other parts of the application calls getPrimaryStage().close();
, it does not trigger OnCloseRequest
. Perhaps we should use setOnHiding
instead? (Source)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If some other parts of the application calls getPrimaryStage().close();, it does not trigger OnCloseRequest. Perhaps we should use setOnHiding instead?
I wanted to differentiate between closing the app internally (via ExitCommand
or the exit menu button) and externally (close button or from taskbar).
If we use setOnHiding
, handleExit()
actually gets called twice if we close it internally since setOnHiding
would call handleExit()
for the 2nd time afterMainApp.stop()
calls mainWindow.hide()
in ui.stop()
.
Also I wonder whether we should perhaps use diff --git a/src/main/resources/view/MainWindow.fxml b/src/main/resources/view/MainWindow.fxml
index 1dadb95b..daf386d8 100644
--- a/src/main/resources/view/MainWindow.fxml
+++ b/src/main/resources/view/MainWindow.fxml
@@ -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" onHiding="#handleExit">
<icons>
<Image url="@/images/address_book_32.png" />
</icons> |
Wanted to do that too, but didn't know if it could be done and my |
Ah okay. IIRC SceneBuilder has never been working even when I was a cs2103t student, so don't worry about it. :P SceneBuilder has strict requirements on how we structure our UI codes (e.g. controllers) and widgets (e.g. placeholders), so loading problems are probably not unheard of. Anyway, you can also spot possible attributes in the JavaFX docs under Property Summary as well. |
7a9043c
to
ce305ac
Compare
v2@yamidark submitted v2 for review. (📚 Archive) (📈 Interdiff between v1 and v2) Checkout this PR version locallygit fetch https://github.com/se-edu/addressbook-level4.git refs/pr/832/2/head:BRANCHNAME where |
Can you call some method in @vivekscl do take a look at the commit message and suggest improvements to it. I spotted a few bugs alrd :P |
Couldn't find any method to move it to the x button, tried manually shifting the cursor there by using |
Take a look at the 2nd answer and here as well. It seems like the main thing we are testing for is that whenever we click on the As such, I think we need to create a |
Probably should have searched for this Anyway, I tried this extending of the |
I don't think we can override Can we try System Rules (also in the link I posted above)? |
System Rules needs at least JUnit 4.9 while ours is 4.12(?) :X. |
Just tested the |
Hmm ok, document this down as part of the commit message then ^^
Commit message needs to be clearer
|
ce305ac
to
61964c9
Compare
v3@yamidark submitted v3 for review. (📚 Archive) (📈 Interdiff between v2 and v3) Checkout this PR version locallygit fetch https://github.com/se-edu/addressbook-level4.git refs/pr/832/3/head:BRANCHNAME where |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-
Showing the link to the API of SecurityManager without explaining in the commit message isn't helpful :P
-
No need for line break for website links, otherwise the hyperlink is unclickable.
let's wait for Vivek to review first.
If you override the method in Can we do unit test for Ideally, we should have an integration test between |
Hmm, so I should explain how we can use
Whoops, didn't notice that. Will update in next iteration.
Now that you mention this, yep, dunno what I was thinking xD.
Will check to see how we can add this test. Should this be done in this PR though? |
The link to the SO post is more helpful.
Yup it should be done in this PR since this PR updates |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some nits with the commit message
para 2:
Thus, if MainApp#stop() is not called, the app may continue to
run even after the MainWindow is closed, causing any existing
HelpWindows...
para 3:
For the first line maybe this sounds better?
According to the life-cycle section in the documentation on JavaFX Application[1]...
para 4:
The sentence structure is too long and complex. Maybe this sounds better?
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.
para 5:
As a result, we are unable to write regression tests for this bug fix as the test classes terminates prematurely...
The
Yea, will mention the |
You can run this on the FX Thread by calling |
d190ee3
to
c7f0cf8
Compare
v5@yamidark submitted v5 for review. (📚 Archive) (📈 Interdiff between v4 and v5) Checkout this PR version locallygit fetch https://github.com/se-edu/addressbook-level4.git refs/pr/832/5/head:BRANCHNAME where |
} | ||
|
||
/** | ||
* Closes the {@code MainWindow} using it's menu bar. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
its
} | ||
|
||
@Test | ||
public void menuBar_exit_success() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are testing exit through menu bar, and the end result we are verifying for is ExitAppRequestEvent
posted. So it should be:
exit_menuBarExitButton_ExitAppRequestEventPosted
} | ||
|
||
/** | ||
* Simulate an external request to close the {@code MainWindow}. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's unclear what "external request" means.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, should I give examples like in this commit message (using the 'X' button or closing from taskbar?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's better to leave it in the code so that future developers know what is this piece of code doing :P
|
||
private MainWindowHandleUnit(Stage stage) { | ||
super(stage); | ||
this.stage = stage; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is a hackish way of doing things :P We can remove the need for this by storing stage
as a variable in the test class alongside with mainWindow
and mainWindowHandle
.
public void setUp() throws Exception { | ||
FxToolkit.setupStage(stage -> { | ||
mainWindow = | ||
new MainWindow(stage, new Config(), new UserPrefs(), new LogicManager(new ModelManager())); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Zhiyuan-Amos Actually, should I extract this out as a method in the test class as prepareMainWindow(Stage)
, which should make the test cleaner and clearer?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup, looks good!
be7e926
to
b552913
Compare
v6@yamidark submitted v6 for review. (📚 Archive) (📈 Interdiff between v5 and v6) Checkout this PR version locallygit fetch https://github.com/se-edu/addressbook-level4.git refs/pr/832/6/head:BRANCHNAME where |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm ok after these changes are made. I didn't take a look at the commit message though. @vivekscl can take a look again? Thanks!
E.g. 1st para:
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.
The MainWindow does not have an event handler to handle external requests (such as clicking on the close button or though the taskbar) to close the MainWindow.
} | ||
|
||
@Test | ||
public void exit_menuBarExitButton_exitAppRequestEventPosted() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we use the term close
elsewhere (closeMainWindowExternally), let's rename exit
to close
.
/** | ||
* {@code MainWindow} unit test class without any other components to test closing of the {@code MainWindow}. | ||
*/ | ||
private class MainWindowHandleUnit extends StageHandle { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This name is kinda weird haha. Let's rename it to EmptyMainWindowHandle
.
} | ||
|
||
/** | ||
* {@code MainWindow} unit test class without any other components to test closing of the {@code MainWindow}. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Provides a handle for {@code MainWindow}. The components in {@code MainWindow} are not initialized.
<- This header comment is more descriptive as it mentions that this is a handle for MainWindow
.
} | ||
|
||
/** | ||
* Closes the {@code MainWindow} using its menu bar. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's be more specific: Closes the {@code MainWindow} by clicking on the menu bar's exit button.
|
||
/** | ||
* 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). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Closes the {@code MainWindow} through an external request (e.g pressing the 'X' button on the...
. We don't need to know that it's simulating an external request or not. :P
public void setUp() throws Exception { | ||
FxToolkit.setupStage(stage -> { | ||
this.stage = stage; | ||
mainWindow = prepareMainWindow(stage); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought you meant extracting everything in this inner method as a private method :P We generally don't need to extract 1 sentence statements.
FxToolkit.setupStage(stage -> {
this.stage = stage;
mainWindow = new MainWindow(stage, new Config(), new UserPrefs(), new LogicManager(new ModelManager()));
mainWindowHandle = new EmptyMainWindowHandle(stage);
// leave 1 line here to show that the above is initialization of variables, while below is setting up the ui.
stage.setScene(mainWindow.getRoot().getScene());
mainWindowHandle.focus();
});
c08960e
to
28f2c09
Compare
v7@yamidark submitted v7 for review. (📚 Archive) (📈 Interdiff between v6 and v7) Checkout this PR version locallygit fetch https://github.com/se-edu/addressbook-level4.git refs/pr/832/7/head:BRANCHNAME where |
@vivekscl can take a look? ^^ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some minor nits in the commit message:
1st para:
The MainWindow does not have an event handler to handle external requests
(such as the close button or through the taskbar) to close the
MainWindow.
2nd para:
This may cause the app to not close properly since MainApp#stop() is not called as the ExitAppRequestEvent is not raised
.
MainApp#stop() is the method used to call...
Last para:
Did you mean MainWindowHandleUnitTest
?
Maybe this phrasing sounds better?
... does not contain a close button, thus to test if an ExitAppRequestEvent was raised we fire a WindowEvent#WINDOW_CLOSE_REQUEST event which will trigger the onCloseRequest event.
28f2c09
to
b233003
Compare
v8@yamidark submitted v8 for review. (📚 Archive) (📈 Interdiff between v7 and v8) Checkout this PR version locallygit fetch https://github.com/se-edu/addressbook-level4.git refs/pr/832/8/head:BRANCHNAME where |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
handle external
requests(such as the close button or through the taskbar)
Missing whitespace before the parentheses.
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.
Can specify that this method raises ExitAppRequestEvent
since you mentioned about ExitAppRequestEvent
above.
Last paragraph missing period at the end of the sentence.
Let's wait for prof to review first :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good. Some nits only.
import seedu.address.ui.testutil.EventsCollectorRule; | ||
|
||
/** | ||
* Contains test for closing of the {@code MainWindow}. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment sounds like there is only one test?
Also, the class name doesn't indicate that the scope is limited to testing the 'close' feature only.
|
||
/** | ||
* Provides a handle for {@code MainWindow}. The components in {@code MainWindow} are not initialized. | ||
*/ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Provides
is redundant?
The MainWindow does not have an event handler to handle external requests (such as the close button or through the taskbar) to close the MainWindow. This may cause the app to not close properly since MainApp#stop() is not called as the ExitAppRequestEvent is not raised. MainApp#stop() is the method used to call Platform#exit() and System#exit(int) which closes our app and 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(), which raises an ExitAppRequestEvent, when there is an external request to close the app. EmptyMainWindowHandle does not contain a close button, thus to test if an ExitAppRequestEvent was raised, we fire a WindowEvent#WINDOW_CLOSE_REQUEST event which will trigger the onCloseRequest event. [1] JavaFx documentation for Application: https://docs.oracle.com/javafx/2/api/javafx/application/Application.html
b233003
to
b883e8d
Compare
v9@yamidark submitted v9 for review. (📚 Archive) (📈 Interdiff between v8 and v9) Checkout this PR version locallygit fetch https://github.com/se-edu/addressbook-level4.git refs/pr/832/9/head:BRANCHNAME where |
@yamidark update the merge commit message ya :) |
Fixes #826