User can save, reset or cancel.
- Created a notification popups for errors - Added functionality to save, cancel and reset buttons - Key bindings are only saved if they're valid - Added window close event - Can not exit without saving correctly - CSS to cancel, save and reset buttons to differentiate between key buttons - Javadocd #story[1197]
This commit is contained in:
@@ -2,14 +2,20 @@ package visualiser.Controllers;
|
|||||||
|
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
|
import javafx.fxml.FXMLLoader;
|
||||||
|
import javafx.scene.Parent;
|
||||||
|
import javafx.scene.Scene;
|
||||||
import javafx.scene.control.Button;
|
import javafx.scene.control.Button;
|
||||||
import javafx.scene.control.ListView;
|
import javafx.scene.control.ListView;
|
||||||
import javafx.scene.input.KeyCode;
|
import javafx.scene.input.KeyCode;
|
||||||
import javafx.scene.input.KeyEvent;
|
import javafx.scene.input.KeyEvent;
|
||||||
import javafx.scene.layout.AnchorPane;
|
import javafx.scene.layout.AnchorPane;
|
||||||
|
import javafx.stage.Modality;
|
||||||
|
import javafx.stage.Stage;
|
||||||
|
import javafx.stage.WindowEvent;
|
||||||
import visualiser.gameController.Keys.ControlKey;
|
import visualiser.gameController.Keys.ControlKey;
|
||||||
import visualiser.gameController.Keys.KeyFactory;
|
import visualiser.gameController.Keys.KeyFactory;
|
||||||
|
import java.io.IOException;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@@ -26,8 +32,9 @@ public class KeyBindingsController {
|
|||||||
private @FXML ListView lstKey;
|
private @FXML ListView lstKey;
|
||||||
private @FXML ListView lstDescription;
|
private @FXML ListView lstDescription;
|
||||||
private @FXML AnchorPane anchor;
|
private @FXML AnchorPane anchor;
|
||||||
private Button currentButton = null;
|
private Button currentButton = null; // last button clicked
|
||||||
private KeyFactory newKeyFactory;
|
private KeyFactory newKeyFactory;
|
||||||
|
private Boolean changed = false; // keybindings have been modified
|
||||||
|
|
||||||
public void initialize(){
|
public void initialize(){
|
||||||
// create new key factory to modify, keeping the existing one safe
|
// create new key factory to modify, keeping the existing one safe
|
||||||
@@ -96,14 +103,14 @@ public class KeyBindingsController {
|
|||||||
*/
|
*/
|
||||||
public KeyFactory copyExistingFactory(){
|
public KeyFactory copyExistingFactory(){
|
||||||
newKeyFactory = new KeyFactory();
|
newKeyFactory = new KeyFactory();
|
||||||
Map<String, ControlKey> newKeyState = newKeyFactory.getKeyState();
|
|
||||||
Map<String, ControlKey> oldKeyState = keyFactory.getKeyState();
|
Map<String, ControlKey> oldKeyState = keyFactory.getKeyState();
|
||||||
newKeyState = new HashMap<>(); // clear default keys
|
Map<String, ControlKey> newKeyState = new HashMap<>();
|
||||||
|
|
||||||
// copy over commands and their keys
|
// copy over commands and their keys
|
||||||
for (Map.Entry<String, ControlKey> entry : oldKeyState.entrySet()){
|
for (Map.Entry<String, ControlKey> entry : oldKeyState.entrySet()){
|
||||||
newKeyState.put(entry.getKey(), entry.getValue());
|
newKeyState.put(entry.getKey(), entry.getValue());
|
||||||
}
|
}
|
||||||
|
newKeyFactory.setKeyState(newKeyState);
|
||||||
return newKeyFactory;
|
return newKeyFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,14 +144,20 @@ public class KeyBindingsController {
|
|||||||
currentButton.getId());
|
currentButton.getId());
|
||||||
// remove current button selection
|
// remove current button selection
|
||||||
currentButton = null;
|
currentButton = null;
|
||||||
|
changed = true;
|
||||||
btnCancel.requestFocus();
|
btnCancel.requestFocus();
|
||||||
}
|
}
|
||||||
event.consume();
|
event.consume();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancel and exits the key bindings menu. Changes are not forced to be
|
||||||
|
* saved or fixed if invalid, and instead are defaulted back to the last
|
||||||
|
* successful saved state.
|
||||||
|
*/
|
||||||
public void cancel(){
|
public void cancel(){
|
||||||
System.out.println("cancel clicked");
|
((Stage)btnCancel.getScene().getWindow()).close();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -157,13 +170,76 @@ public class KeyBindingsController {
|
|||||||
newKeyFactory = new KeyFactory();
|
newKeyFactory = new KeyFactory();
|
||||||
initializeTable();
|
initializeTable();
|
||||||
populateTable();
|
populateTable();
|
||||||
|
changed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Replace existing {@link KeyFactory} with the modified key bindings.
|
* Replace existing {@link KeyFactory} with the modified key bindings.
|
||||||
*/
|
*/
|
||||||
public void save(){
|
public void save(){
|
||||||
keyFactory = newKeyFactory;
|
if (isFactoryValid()) {
|
||||||
|
keyFactory = newKeyFactory;
|
||||||
|
newKeyFactory = new KeyFactory();
|
||||||
|
changed = false;
|
||||||
|
loadNotification("Key bindings were successfully saved.", false);
|
||||||
|
} else {
|
||||||
|
loadNotification("One or more key bindings are missing. " +
|
||||||
|
"Failed to save.", true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks the {@link KeyFactory} being modified is valid and that no
|
||||||
|
* commands are missing a key binding.
|
||||||
|
* @return True if valid, false if invalid
|
||||||
|
*/
|
||||||
|
public Boolean isFactoryValid(){
|
||||||
|
for (Map.Entry<String, ControlKey> entry : newKeyFactory.getKeyState().entrySet
|
||||||
|
()) {
|
||||||
|
if (entry.getKey().toString()==entry.getValue().toString()){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Method used to stop a user from exiting key bindings without saving
|
||||||
|
* their changes to the {@link KeyFactory}.
|
||||||
|
* @param we {@link WindowEvent} close request to be consumed if settings
|
||||||
|
* have not been successfully saved.
|
||||||
|
*/
|
||||||
|
public void onExit(WindowEvent we){
|
||||||
|
// if modified KeyFactory hasn't been saved
|
||||||
|
if (keyFactory!=newKeyFactory && changed==true){
|
||||||
|
loadNotification("Please cancel or save your changes before exiting" +
|
||||||
|
".", true);
|
||||||
|
we.consume();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads a popup window giving confirmation/warning of user activity.
|
||||||
|
* @param message the message to be displayed to the user
|
||||||
|
* @param warning true if the message to be displayed is due to user error
|
||||||
|
*/
|
||||||
|
public void loadNotification(String message, Boolean warning){
|
||||||
|
Parent root = null;
|
||||||
|
FXMLLoader loader = new FXMLLoader(getClass().getResource
|
||||||
|
("/visualiser/scenes/notification.fxml"));
|
||||||
|
try {
|
||||||
|
root = loader.load();
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
NotificationController controller = loader.getController();
|
||||||
|
Stage stage = new Stage();
|
||||||
|
stage.setScene(new Scene(root));
|
||||||
|
stage.centerOnScreen();
|
||||||
|
stage.initModality(Modality.APPLICATION_MODAL);
|
||||||
|
stage.show();
|
||||||
|
// displays given message in the window
|
||||||
|
controller.setMessage(message, warning);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package visualiser.Controllers;
|
||||||
|
|
||||||
|
import javafx.fxml.FXML;
|
||||||
|
import javafx.scene.control.Label;
|
||||||
|
import javafx.scene.paint.Color;
|
||||||
|
import javafx.scene.text.Text;
|
||||||
|
import javafx.stage.Stage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controller for a popup notification regarding user activity.
|
||||||
|
*/
|
||||||
|
public class NotificationController {
|
||||||
|
private @FXML Label lblDescription;
|
||||||
|
private @FXML Text txtMessage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Closes the popup window once clicked.
|
||||||
|
*/
|
||||||
|
public void ok(){
|
||||||
|
((Stage)lblDescription.getScene().getWindow()).close();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays the appropriate popup notification.
|
||||||
|
* @param message message for the user
|
||||||
|
* @param warning if true warning text shown, if false success text shown
|
||||||
|
*/
|
||||||
|
public void setMessage(String message, Boolean warning){
|
||||||
|
lblDescription.setText(message);
|
||||||
|
if (!warning){
|
||||||
|
txtMessage.setText("Success!");
|
||||||
|
txtMessage.setFill(Color.GREEN);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package visualiser.Controllers;
|
package visualiser.Controllers;
|
||||||
|
|
||||||
|
import javafx.event.EventHandler;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.fxml.FXMLLoader;
|
import javafx.fxml.FXMLLoader;
|
||||||
import javafx.scene.Parent;
|
import javafx.scene.Parent;
|
||||||
@@ -9,6 +10,7 @@ import javafx.scene.control.RadioButton;
|
|||||||
import javafx.scene.layout.AnchorPane;
|
import javafx.scene.layout.AnchorPane;
|
||||||
import javafx.stage.Modality;
|
import javafx.stage.Modality;
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
|
import javafx.stage.WindowEvent;
|
||||||
import visualiser.app.App;
|
import visualiser.app.App;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -88,6 +90,22 @@ public class TitleController extends Controller {
|
|||||||
* Called when control button is pressed. New pop up window displaying controls
|
* Called when control button is pressed. New pop up window displaying controls
|
||||||
*/
|
*/
|
||||||
public void controlBtnPressed(){
|
public void controlBtnPressed(){
|
||||||
|
|
||||||
|
// Parent root2 = loader2.load();
|
||||||
|
// KeyBindingsController controller = loader2.getController();
|
||||||
|
// Stage stage2 = new Stage();
|
||||||
|
// stage2.setScene(new Scene(root2));
|
||||||
|
// stage2.centerOnScreen();
|
||||||
|
// stage2.initModality(Modality.APPLICATION_MODAL);
|
||||||
|
// stage2.show();
|
||||||
|
// stage2.setOnCloseRequest(new EventHandler<WindowEvent>() {
|
||||||
|
// public void handle(WindowEvent we) {
|
||||||
|
// if (we.getEventType() == WindowEvent.WINDOW_CLOSE_REQUEST) {
|
||||||
|
// controller.onExit(we);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
|
||||||
FXMLLoader loader = new FXMLLoader();
|
FXMLLoader loader = new FXMLLoader();
|
||||||
loader.setLocation(getClass().getResource("/visualiser/scenes/keyBindings.fxml"));
|
loader.setLocation(getClass().getResource("/visualiser/scenes/keyBindings.fxml"));
|
||||||
Parent layout;
|
Parent layout;
|
||||||
@@ -100,6 +118,14 @@ public class TitleController extends Controller {
|
|||||||
popupStage.initModality(Modality.WINDOW_MODAL);
|
popupStage.initModality(Modality.WINDOW_MODAL);
|
||||||
popupStage.setScene(scene);
|
popupStage.setScene(scene);
|
||||||
popupStage.showAndWait();
|
popupStage.showAndWait();
|
||||||
|
KeyBindingsController controller = loader.getController();
|
||||||
|
popupStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
|
||||||
|
public void handle(WindowEvent we) {
|
||||||
|
if (we.getEventType() == WindowEvent.WINDOW_CLOSE_REQUEST) {
|
||||||
|
controller.onExit(we);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
} catch (Exception e){
|
} catch (Exception e){
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,6 +39,10 @@ public class KeyFactory {
|
|||||||
return keyState;
|
return keyState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setKeyState(Map<String, ControlKey> keyState) {
|
||||||
|
this.keyState = keyState;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the key bound to a particular command in the keystate.
|
* Update the key bound to a particular command in the keystate.
|
||||||
* @param newKey the new key value for the command
|
* @param newKey the new key value for the command
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
-fx-text-fill: #242d35;
|
-fx-text-fill: #242d35;
|
||||||
-fx-font-size: 12px;
|
-fx-font-size: 12px;
|
||||||
-fx-font-family: "Courier New";
|
-fx-font-family: "Courier New";
|
||||||
|
-fx-border-color: #a9c8ff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button:focused {
|
.button:focused {
|
||||||
@@ -33,3 +34,12 @@
|
|||||||
#anchor {
|
#anchor {
|
||||||
-fx-background-color: #fdfac3;
|
-fx-background-color: #fdfac3;
|
||||||
}
|
}
|
||||||
|
#menu{
|
||||||
|
-fx-background-color: linear-gradient(#acdeff 50%, #a9c8ff 100%);
|
||||||
|
-fx-background-radius: 4px;
|
||||||
|
-fx-border-radius: 4px;
|
||||||
|
-fx-text-fill: #242d35;
|
||||||
|
-fx-font-size: 12px;
|
||||||
|
-fx-font-family: "Verdana";
|
||||||
|
-fx-border-color: #a9c8ff;
|
||||||
|
}
|
||||||
@@ -13,11 +13,12 @@
|
|||||||
<Font name="Comic Sans MS" size="44.0" />
|
<Font name="Comic Sans MS" size="44.0" />
|
||||||
</font>
|
</font>
|
||||||
</Label>
|
</Label>
|
||||||
<Button fx:id="btnCancel" layoutX="430.0" layoutY="428.0" mnemonicParsing="false" onAction="#cancel" prefWidth="160.0" text="Cancel" AnchorPane.bottomAnchor="18.0" AnchorPane.rightAnchor="20.0" />
|
<Button id="menu" fx:id="btnCancel" layoutX="430.0" layoutY="428.0"
|
||||||
|
mnemonicParsing="false" onAction="#cancel" prefWidth="160.0" text="Cancel" AnchorPane.bottomAnchor="18.0" AnchorPane.rightAnchor="20.0" />
|
||||||
<ListView fx:id="lstControl" focusTraversable="false" layoutX="27.0" layoutY="88.0" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="322.0" prefWidth="150.0" />
|
<ListView fx:id="lstControl" focusTraversable="false" layoutX="27.0" layoutY="88.0" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="322.0" prefWidth="150.0" />
|
||||||
<ListView fx:id="lstKey" focusTraversable="false" layoutX="176.0" layoutY="88.0" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="322.0" prefWidth="150.0" />
|
<ListView fx:id="lstKey" focusTraversable="false" layoutX="176.0" layoutY="88.0" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="322.0" prefWidth="150.0" />
|
||||||
<ListView fx:id="lstDescription" focusTraversable="false" layoutX="325.0" layoutY="88.0" prefHeight="322.0" prefWidth="250.0" />
|
<ListView fx:id="lstDescription" focusTraversable="false" layoutX="325.0" layoutY="88.0" prefHeight="322.0" prefWidth="250.0" />
|
||||||
<Button fx:id="btnSave" layoutX="220.0" layoutY="428.0" mnemonicParsing="false" onAction="#save" prefWidth="160.0" text="Save" AnchorPane.bottomAnchor="18.0" />
|
<Button id="menu" fx:id="btnSave" layoutX="220.0" layoutY="428.0" mnemonicParsing="false" onAction="#save" prefWidth="160.0" text="Save" AnchorPane.bottomAnchor="18.0" />
|
||||||
<Button fx:id="btnReset" layoutX="20.0" layoutY="428.0" mnemonicParsing="false" onAction="#reset" prefWidth="160.0" text="Reset to Default" AnchorPane.bottomAnchor="18.0" AnchorPane.leftAnchor="20.0" />
|
<Button id="menu" fx:id="btnReset" layoutX="20.0" layoutY="428.0" mnemonicParsing="false" onAction="#reset" prefWidth="160.0" text="Reset to Default" AnchorPane.bottomAnchor="18.0" AnchorPane.leftAnchor="20.0" />
|
||||||
</children>
|
</children>
|
||||||
</AnchorPane>
|
</AnchorPane>
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<?import javafx.scene.control.Button?>
|
||||||
|
<?import javafx.scene.control.Label?>
|
||||||
|
<?import javafx.scene.layout.Pane?>
|
||||||
|
<?import javafx.scene.text.Font?>
|
||||||
|
<?import javafx.scene.text.Text?>
|
||||||
|
|
||||||
|
<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="100.0" prefWidth="300.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="visualiser.Controllers.NotificationController">
|
||||||
|
<children>
|
||||||
|
<Button fx:id="btnOk" layoutX="110.0" layoutY="65.0" mnemonicParsing="false" onAction="#ok" prefWidth="80.0" text="Ok" />
|
||||||
|
<Text fx:id="txtMessage" fill="RED" layoutY="23.0" strokeType="OUTSIDE" strokeWidth="0.0" text="Warning!" textAlignment="CENTER" wrappingWidth="300.0">
|
||||||
|
<font>
|
||||||
|
<Font name="System Bold" size="14.0" />
|
||||||
|
</font>
|
||||||
|
</Text>
|
||||||
|
<Label fx:id="lblDescription" alignment="CENTER" layoutY="36.0" prefHeight="17.0" prefWidth="300.0" textAlignment="CENTER" />
|
||||||
|
</children>
|
||||||
|
</Pane>
|
||||||
Reference in New Issue
Block a user