Slightly optimised code style and add more functionality

- optimised UI
- check conflicts when change key bind if the key has already been in use
- abstract keybind as a separate singleton class so all class can access it
- [WIP] turning mode is need to be finished

#story[1245]
This commit is contained in:
Haoming Yin
2017-09-23 17:52:48 +12:00
parent 957821f1f2
commit 4011295b8b
7 changed files with 200 additions and 188 deletions
@@ -0,0 +1,78 @@
package seng302.model;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import javafx.scene.input.KeyCode;
public class GameKeyBind {
private static GameKeyBind instance;
private Map<KeyCode, KeyAction> keyToActionMap;
private Map<KeyAction, KeyCode> actionToKeyMap;
private boolean continuouslyTurning;
private GameKeyBind() {
setToDefault();
}
public void setToDefault() {
actionToKeyMap = new HashMap<>();
keyToActionMap = new HashMap<>();
continuouslyTurning = false;
// default key bindings
ArrayList<KeyCode> keys = new ArrayList<>();
keys.add(KeyCode.Z);
keys.add(KeyCode.X);
keys.add(KeyCode.SPACE);
keys.add(KeyCode.SHIFT);
keys.add(KeyCode.ENTER);
keys.add(KeyCode.PAGE_UP);
keys.add(KeyCode.PAGE_DOWN);
for (int i = 0; i < 7; i++) {
actionToKeyMap.put(KeyAction.getType(i + 1), keys.get(i));
keyToActionMap.put(keys.get(i), KeyAction.getType(i + 1));
}
}
public static GameKeyBind getInstance() {
if (instance == null) {
instance = new GameKeyBind();
}
return instance;
}
public KeyCode getKeyCode(KeyAction keyAction) {
return instance.actionToKeyMap.get(keyAction);
}
/**
* Binds a key to a key action
*
* @return true if successfully bind
*/
public boolean bindKeyToAction(KeyCode keyCode, KeyAction keyAction) {
if (instance.keyToActionMap.containsKey(keyCode)) {
// if the key has been bound to other action, return false
return false;
} else {
instance.keyToActionMap.put(keyCode, keyAction); // add key -> action
KeyCode oldKeyCode = instance.actionToKeyMap
.get(keyAction); // get old key for the action
instance.keyToActionMap.remove(oldKeyCode); // remove the old key -> action
instance.actionToKeyMap
.replace(keyAction, keyCode); // replace the old key by the newer one
return true;
}
}
public void toggleTurningMode() {
continuouslyTurning = !continuouslyTurning;
}
public boolean isContinuouslyTurning() {
return continuouslyTurning;
}
}
@@ -3,7 +3,7 @@ package seng302.model;
import java.util.HashMap;
import java.util.Map;
public enum GameClientAction {
public enum KeyAction {
ZOOM_IN(1),
ZOOM_OUT(2),
VMG(3),
@@ -13,19 +13,19 @@ public enum GameClientAction {
DOWNWIND(7);
private final int type;
private static final Map<Integer, GameClientAction> intToTypeMap = new HashMap<>();
private static final Map<Integer, KeyAction> intToTypeMap = new HashMap<>();
static {
for (GameClientAction type : GameClientAction.values()) {
for (KeyAction type : KeyAction.values()) {
intToTypeMap.put(type.getValue(), type);
}
}
GameClientAction(int type) {
KeyAction(int type) {
this.type = type;
}
public static GameClientAction getType(int value) {
public static KeyAction getType(int value) {
return intToTypeMap.get(value);
}
@@ -7,7 +7,6 @@ import java.time.ZoneOffset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.TimeZone;
@@ -29,7 +28,8 @@ import seng302.gameServer.messages.BoatAction;
import seng302.gameServer.messages.BoatStatus;
import seng302.gameServer.messages.YachtEventType;
import seng302.model.ClientYacht;
import seng302.model.GameClientAction;
import seng302.model.GameKeyBind;
import seng302.model.KeyAction;
import seng302.model.RaceState;
import seng302.model.stream.packets.StreamPacket;
import seng302.model.stream.parser.MarkRoundingData;
@@ -67,7 +67,8 @@ public class GameClient {
private RaceViewController raceViewController;
private ArrayList<ClientYacht> finishedBoats = new ArrayList<>();
private Map<GameClientAction, KeyCode> keyBind = new HashMap<>();
private GameKeyBind gameKeyBind; // all the key binding setting.
private ObservableList<String> clientLobbyList = FXCollections.observableArrayList();
@@ -78,21 +79,7 @@ public class GameClient {
*/
public GameClient(Pane holder) {
this.holderPane = holder;
initialiseKeyBind();
}
/**
* Initialise default keybind.
*/
private void initialiseKeyBind() {
keyBind = new HashMap<>();
keyBind.put(GameClientAction.ZOOM_IN, KeyCode.Z);
keyBind.put(GameClientAction.ZOOM_OUT, KeyCode.X);
keyBind.put(GameClientAction.VMG, KeyCode.SPACE);
keyBind.put(GameClientAction.SAILS_STATE, KeyCode.SHIFT);
keyBind.put(GameClientAction.TACK_GYBE, KeyCode.ENTER);
keyBind.put(GameClientAction.UPWIND, KeyCode.PAGE_UP);
keyBind.put(GameClientAction.DOWNWIND, KeyCode.PAGE_DOWN);
this.gameKeyBind = GameKeyBind.getInstance();
}
/**
@@ -392,13 +379,13 @@ public class GameClient {
return;
}
if (keyBind.get(GameClientAction.VMG) == e.getCode()) { // align with vmg
if (gameKeyBind.getKeyCode(KeyAction.VMG) == e.getCode()) { // align with vmg
socketThread.sendBoatAction(BoatAction.VMG);
} else if (keyBind.get(GameClientAction.UPWIND) == e.getCode()) { // upwind
} else if (gameKeyBind.getKeyCode(KeyAction.UPWIND) == e.getCode()) { // upwind
socketThread.sendBoatAction(BoatAction.UPWIND);
} else if (keyBind.get(GameClientAction.DOWNWIND) == e.getCode()) { // downwind
} else if (gameKeyBind.getKeyCode(KeyAction.DOWNWIND) == e.getCode()) { // downwind
socketThread.sendBoatAction(BoatAction.DOWNWIND);
} else if (keyBind.get(GameClientAction.TACK_GYBE) == e.getCode()) { // tack/gybe
} else if (gameKeyBind.getKeyCode(KeyAction.TACK_GYBE) == e.getCode()) { // tack/gybe
// if chat box is active take whatever is in there and send it to server
socketThread.sendBoatAction(BoatAction.TACK_GYBE);
}
@@ -410,11 +397,11 @@ public class GameClient {
return;
}
if (keyBind.get(GameClientAction.SAILS_STATE) == e.getCode()) { // sails in/sails out
if (gameKeyBind.getKeyCode(KeyAction.SAILS_STATE) == e.getCode()) { // sails in/sails out
socketThread.sendBoatAction(BoatAction.SAILS_IN);
allBoatsMap.get(socketThread.getClientId()).toggleSail();
} else if (keyBind.get(GameClientAction.UPWIND) == e.getCode()
|| keyBind.get(GameClientAction.DOWNWIND) == e.getCode()) {
} else if (gameKeyBind.getKeyCode(KeyAction.UPWIND) == e.getCode()
|| gameKeyBind.getKeyCode(KeyAction.DOWNWIND) == e.getCode()) {
socketThread.sendBoatAction(BoatAction.MAINTAIN_HEADING);
}
}
@@ -473,7 +460,4 @@ public class GameClient {
return allBoatsMap;
}
public Map<GameClientAction, KeyCode> getKeyBind() {
return keyBind;
}
}
@@ -27,7 +27,6 @@ import seng302.gameServer.ServerAdvertiser;
import seng302.utilities.BonjourInstallChecker;
import seng302.utilities.Sounds;
import seng302.visualiser.GameClient;
import seng302.visualiser.controllers.dialogs.KeyBindingDialogController;
public class ViewManager {
@@ -137,7 +136,7 @@ public class ViewManager {
showKeyBindingDialog();
}
} catch (IOException e) {
logger.warn("Could not create Key Binding Dialog.");
logger.warn("Something went wrong when opening key bind dialog");
}
}));
@@ -214,9 +213,6 @@ public class ViewManager {
JFXDialog dialog = new JFXDialog((StackPane) node,
dialogContent.load(),
DialogTransition.CENTER);
KeyBindingDialogController keyBindingDialogController = dialogContent
.getController();
keyBindingDialogController.init(gameClient.getKeyBind(), this);
dialog.show();
Sounds.playButtonClick();
}
@@ -229,7 +225,7 @@ public class ViewManager {
* @param snackbarText text to be displayed.
*/
public void showSnackbar(String snackbarText) {
jfxSnackbar.show(snackbarText, 1000);
jfxSnackbar.show(snackbarText, 1500);
}
/**
@@ -378,12 +374,4 @@ public class ViewManager {
return stage;
}
/**
* Getter to return snackbar object.
*
* @return snackbar object.
*/
public JFXSnackbar getJfxSnackbar() {
return jfxSnackbar;
}
}
@@ -2,19 +2,21 @@ package seng302.visualiser.controllers.dialogs;
import com.jfoenix.controls.JFXButton;
import com.jfoenix.controls.JFXDialogLayout;
import com.jfoenix.controls.JFXToggleButton;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import seng302.model.GameClientAction;
import seng302.model.GameKeyBind;
import seng302.model.KeyAction;
import seng302.visualiser.controllers.ViewManager;
public class KeyBindingDialogController implements Initializable {
@@ -38,116 +40,87 @@ public class KeyBindingDialogController implements Initializable {
private JFXButton upwindBtn;
@FXML
private JFXButton downwindBtn;
@FXML
private JFXButton resetBtn;
@FXML
private JFXButton confirmBtn;
@FXML
private JFXToggleButton turningToggle;
//---------FXML END---------//
private ViewManager viewManager; // added viewManager to access snackbar. To be removed.
private Map<JFXButton, KeyCode> keys;
private GameKeyBind gameKeyBind;
private List<JFXButton> buttons = new ArrayList<>();
private Map<GameClientAction, KeyCode> keyBind;
private LinkedHashMap<JFXButton, GameClientAction> buttonAndGameClientActionMap;
private Map<Button, KeyAction> buttonActionMap;
@Override
public void initialize(URL location, ResourceBundle resources) {
}
/**
* HAOMING HELP!!! CHANGE FUNCTION NAME PLS :))
*
* Takes in a map from GameClient and initialise button mapping to the keys.
*
* @param keyBind a map with GameClientAction and KeyCode pair to be used in GameClient.
*/
public void init(Map<GameClientAction, KeyCode> keyBind, ViewManager viewManager) {
this.keyBind = keyBind;
this.viewManager = viewManager;
gameKeyBind = GameKeyBind.getInstance();
buttons = new ArrayList<>();
Collections
.addAll(buttons, zoomInbtn, zoomOutBtn, vmgBtn, sailInOutBtn, tackGybeBtn, upwindBtn,
downwindBtn);
Collections.addAll(buttons,
zoomInbtn, zoomOutBtn, vmgBtn, sailInOutBtn, tackGybeBtn, upwindBtn, downwindBtn);
bindButtonWithAction();
loadKeyBind();
initializeKeys();
initializeButtons();
buttons.forEach(button -> {
button.setOnMouseEntered(event -> mouseEnter(button));
button.setOnMousePressed(event -> buttonPressed(button));
button.setOnMouseExited(event -> mouseExit(button));
button.setOnKeyPressed(event -> keyPressed(event, button));
});
resetBtn.setOnMouseClicked(event -> {
gameKeyBind.setToDefault();
loadKeyBind();
});
}
/**
* Initialise default button-keybinding pair if not exist, else rebind the existing keybinding
* to the new button which is created when javafx reinitialise a new controller.
* Set buttons' label according to GameKeyBind settings
*/
private void initializeKeys() {
initButtonAndGameClientActionMap();
initializeDefaultKeys();
private void loadKeyBind() {
buttons.forEach(
button -> button
.setText(gameKeyBind.getKeyCode(buttonActionMap.get(button)).getName()));
}
/**
* HAOMING CHANGE FUNCTION NAME HERE TOO :) OR BETTER, REMOVE THIS FUNCTION
*
* Link buttons and the GameClientAction to be used in accessing keys.
*/
private void initButtonAndGameClientActionMap() {
buttonAndGameClientActionMap = new LinkedHashMap<>();
buttonAndGameClientActionMap.put(zoomInbtn, GameClientAction.ZOOM_IN);
buttonAndGameClientActionMap.put(zoomOutBtn, GameClientAction.ZOOM_OUT);
buttonAndGameClientActionMap.put(vmgBtn, GameClientAction.VMG);
buttonAndGameClientActionMap.put(sailInOutBtn, GameClientAction.SAILS_STATE);
buttonAndGameClientActionMap.put(tackGybeBtn, GameClientAction.TACK_GYBE);
buttonAndGameClientActionMap.put(upwindBtn, GameClientAction.UPWIND);
buttonAndGameClientActionMap.put(downwindBtn, GameClientAction.DOWNWIND);
private void bindButtonWithAction() {
buttonActionMap = new HashMap<>();
for (int i = 0; i < 7; i++) {
buttonActionMap.put(buttons.get(i), KeyAction.getType(i + 1));
}
}
/**
* Initialise default keybinding to a button.
*/
private void initializeDefaultKeys() {
keys = new LinkedHashMap<>();
keys.put(zoomInbtn, keyBind.get(GameClientAction.ZOOM_IN));
keys.put(zoomOutBtn, keyBind.get(GameClientAction.ZOOM_OUT));
keys.put(vmgBtn, keyBind.get(GameClientAction.VMG));
keys.put(sailInOutBtn, keyBind.get(GameClientAction.SAILS_STATE));
keys.put(tackGybeBtn, keyBind.get(GameClientAction.TACK_GYBE));
keys.put(upwindBtn, keyBind.get(GameClientAction.UPWIND));
keys.put(downwindBtn, keyBind.get(GameClientAction.DOWNWIND));
private void showSnackBar(String message) {
ViewManager.getInstance().showSnackbar(message);
}
/**
* Change button text to match current keybinding. Adds focusedProperty and keyPressed listener
* to each buttons.
*/
private void initializeButtons() {
for (JFXButton jfxButton : buttons) {
if (keys.get(jfxButton) != null) {
jfxButton.setText(keys.get(jfxButton).getName());
private void mouseEnter(Button button) {
button.setStyle(""
+ "-fx-background-color: -fx-pp-theme-color;"
+ "-fx-text-fill: -fx-pp-front-color;"
+ "-fx-font-size: 15;");
}
private void buttonPressed(Button button) {
button.setText("PRESS KEY...");
}
private void mouseExit(Button button) {
button.setText(GameKeyBind.getInstance().getKeyCode(buttonActionMap.get(button)).getName());
button.setStyle(""
+ "-fx-background-color: -fx-pp-front-color; "
+ "-fx-text-fill: -fx-pp-theme-color; "
+ "-fx-font-size: 13;");
}
private void keyPressed(KeyEvent event, Button button) {
KeyAction buttonAction = buttonActionMap.get(button);
if (gameKeyBind.bindKeyToAction(event.getCode(), buttonAction)) {
showSnackBar(button.getId() + " is set to " + event.getCode().getName());
button.setText(gameKeyBind.getKeyCode(buttonAction).getName());
} else {
jfxButton.setText("");
showSnackBar(event.getCode().getName() + " is already in use");
}
jfxButton.focusedProperty().addListener((observable, oldValue, newValue) -> {
jfxButton.setOnKeyPressed(event -> {
event.consume();
doSomething(event, jfxButton);
});
});
}
}
/**
* HAOMING PLEASE CHANGE THIS DOCSTRING AND THE FUNCTION NAME!!!
*
* @param event BLAH
* @param button BLAH
*/
private void doSomething(KeyEvent event, JFXButton button) {
if (keys.containsValue(event.getCode())) {
keys.replace(button, null);
keyBind.replace(buttonAndGameClientActionMap.get(button), null);
button.setText("");
viewManager
.showSnackbar(button.getId() + " can't be set to " + event.getCode().getName());
} else {
keys.replace(button, event.getCode());
keyBind.replace(buttonAndGameClientActionMap.get(button), event.getCode());
button.setText(event.getCode().getName());
viewManager.showSnackbar(button.getId() + " is set to " + event.getCode().getName());
}
}
}
@@ -1,40 +1,32 @@
#keyBindingDialogHeader {
-fx-font-size: 30px;
-fx-font-size: 27px;
-fx-text-fill: -fx-pp-dark-text-color;
}
JFXButton {
-fx-background-color: -fx-pp-light-text-color;
-fx-text-fill: -fx-pp-theme-color;
-fx-font-size: 15px;
-fx-effect: -fx-pp-dropshadow-light;
-fx-font-size: 13px;
}
Label {
-fx-font-size: 20px;
-fx-font-size: 15px;
-fx-text-fill: -fx-pp-theme-color;
-fx-effect: -fx-pp-dropshadow-light;
}
JFXButton:hover {
-fx-font-size: 18px;
-fx-background-color: -fx-pp-light-theme-color;
-fx-text-fill: -fx-pp-light-text-color;
}
JFXButton:focused {
-fx-font-size: 18px;
-fx-background-color: -fx-pp-theme-color;
-fx-text-fill: -fx-pp-light-text-color;
}
JFXToggleButton {
-jfx-toggle-color: -fx-pp-theme-color;
-fx-text-fill: -fx-pp-theme-color;
}
#resetBtn, #confirmBtn {
#resetBtn {
-fx-background-color: -fx-pp-theme-color;
-fx-text-fill: -fx-pp-front-color;
-fx-effect: -fx-pp-dropshadow-light;
-fx-font-size: 18;
}
#resetBtn:hover {
-fx-font-size: 20;
}
@@ -9,10 +9,9 @@
<?import javafx.scene.layout.ColumnConstraints?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.layout.RowConstraints?>
<JFXDialogLayout fx:id="keyBindDialog" maxHeight="-Infinity" maxWidth="-Infinity"
minHeight="-Infinity" minWidth="-Infinity" prefHeight="650.0" prefWidth="550.0"
xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1"
minHeight="-Infinity" minWidth="-Infinity" prefHeight="580.0" prefWidth="500.0"
xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1"
fx:controller="seng302.visualiser.controllers.dialogs.KeyBindingDialogController">
<children>
<GridPane>
@@ -21,16 +20,17 @@
<ColumnConstraints hgrow="SOMETIMES" minWidth="100.0" prefWidth="100.0"/>
</columnConstraints>
<rowConstraints>
<RowConstraints maxHeight="70.0" minHeight="70.0" prefHeight="70.0" vgrow="SOMETIMES"/>
<RowConstraints maxHeight="60.0" minHeight="60.0" prefHeight="60.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="60.0" minHeight="60.0" prefHeight="60.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="60.0" minHeight="60.0" prefHeight="60.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="60.0" minHeight="60.0" prefHeight="60.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="60.0" minHeight="60.0" prefHeight="60.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="60.0" minHeight="60.0" prefHeight="60.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="60.0" minHeight="60.0" prefHeight="60.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="60.0" minHeight="60.0" prefHeight="60.0" vgrow="SOMETIMES" />
<RowConstraints maxHeight="80.0" minHeight="80.0" prefHeight="80.0" vgrow="SOMETIMES"/>
<RowConstraints maxHeight="50.0" minHeight="50.0" prefHeight="50.0" vgrow="SOMETIMES"/>
<RowConstraints maxHeight="50.0" minHeight="50.0" prefHeight="50.0" vgrow="SOMETIMES"/>
<RowConstraints maxHeight="50.0" minHeight="50.0" prefHeight="50.0" vgrow="SOMETIMES"/>
<RowConstraints maxHeight="50.0" minHeight="50.0" prefHeight="50.0" vgrow="SOMETIMES"/>
<RowConstraints maxHeight="50.0" minHeight="50.0" prefHeight="50.0" vgrow="SOMETIMES"/>
<RowConstraints maxHeight="50.0" minHeight="50.0" prefHeight="50.0" vgrow="SOMETIMES"/>
<RowConstraints maxHeight="50.0" minHeight="50.0" prefHeight="50.0" vgrow="SOMETIMES"/>
<RowConstraints maxHeight="50.0" minHeight="50.0" prefHeight="50.0" vgrow="SOMETIMES"/>
<RowConstraints maxHeight="-Infinity" minHeight="-Infinity" prefHeight="70.0"
vgrow="SOMETIMES"/>
</rowConstraints>
<children>
<Label fx:id="keyBindingDialogHeader" text="CUSTOM KEYBIND" GridPane.columnSpan="2" GridPane.halignment="CENTER" GridPane.valignment="CENTER" />
@@ -70,49 +70,46 @@
<Insets/>
</GridPane.margin></Label>
<JFXButton id="ZOOM IN" fx:id="zoomInbtn" buttonType="RAISED" maxHeight="-Infinity"
maxWidth="-Infinity" minHeight="40.0" minWidth="-Infinity" prefWidth="150.0" text="Z"
maxWidth="-Infinity" minHeight="35.0" minWidth="-Infinity" prefWidth="120.0" text="Z"
GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.rowIndex="1"
GridPane.valignment="CENTER"/>
<JFXButton id="ZOOM OUT" fx:id="zoomOutBtn" buttonType="RAISED" maxHeight="-Infinity"
maxWidth="-Infinity" minHeight="40.0" minWidth="-Infinity" prefWidth="150.0" text="X"
maxWidth="-Infinity" minHeight="35.0" minWidth="-Infinity" prefWidth="120.0" text="X"
GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.rowIndex="2"
GridPane.valignment="CENTER"/>
<JFXButton id="VMG" fx:id="vmgBtn" buttonType="RAISED" maxHeight="-Infinity"
maxWidth="-Infinity" minHeight="40.0" minWidth="-Infinity" prefWidth="150.0"
maxWidth="-Infinity" minHeight="35.0" minWidth="-Infinity" prefWidth="120.0"
text="SPACE" GridPane.columnIndex="1" GridPane.halignment="CENTER"
GridPane.rowIndex="3" GridPane.valignment="CENTER"/>
<JFXButton id="SAILS IN/OUT" fx:id="sailInOutBtn" buttonType="RAISED"
maxHeight="-Infinity" maxWidth="-Infinity" minHeight="40.0" minWidth="-Infinity"
prefWidth="150.0" text="SHIFT" GridPane.columnIndex="1" GridPane.halignment="CENTER"
maxHeight="-Infinity" maxWidth="-Infinity" minHeight="35.0" minWidth="-Infinity"
prefWidth="120.0" text="SHIFT" GridPane.columnIndex="1" GridPane.halignment="CENTER"
GridPane.rowIndex="4" GridPane.valignment="CENTER"/>
<JFXButton id="TACK/GYBE" fx:id="tackGybeBtn" buttonType="RAISED" maxHeight="-Infinity"
maxWidth="-Infinity" minHeight="40.0" minWidth="-Infinity" prefWidth="150.0"
maxWidth="-Infinity" minHeight="35.0" minWidth="-Infinity" prefWidth="120.0"
text="ENTER" GridPane.columnIndex="1" GridPane.halignment="CENTER"
GridPane.rowIndex="5" GridPane.valignment="CENTER"/>
<JFXButton id="UPWIND" fx:id="upwindBtn" buttonType="RAISED" maxHeight="-Infinity"
maxWidth="-Infinity" minHeight="40.0" minWidth="-Infinity" prefWidth="150.0"
maxWidth="-Infinity" minHeight="35.0" minWidth="-Infinity" prefWidth="120.0"
text="PAGE_UP" GridPane.columnIndex="1" GridPane.halignment="CENTER"
GridPane.rowIndex="6" GridPane.valignment="CENTER"/>
<JFXButton id="DOWNWIND" fx:id="downwindBtn" buttonType="RAISED" maxHeight="-Infinity"
maxWidth="-Infinity" minHeight="40.0" minWidth="-Infinity" prefWidth="150.0"
maxWidth="-Infinity" minHeight="35.0" minWidth="-Infinity" prefWidth="120.0"
text="PAGE_DOWN" GridPane.columnIndex="1" GridPane.halignment="CENTER"
GridPane.rowIndex="7" GridPane.valignment="CENTER"/>
<JFXToggleButton minHeight="40.0" prefHeight="40.0" text="OFF / ON"
GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.rowIndex="8"/>
<JFXToggleButton fx:id="turningToggle" minHeight="-Infinity" prefHeight="35.0"
text="OFF / ON" GridPane.columnIndex="1" GridPane.halignment="CENTER"
GridPane.rowIndex="8"/>
<Label text="CONTINUOUSLY TURNING" GridPane.halignment="CENTER" GridPane.rowIndex="8"
GridPane.valignment="CENTER">
<GridPane.margin>
<Insets/>
</GridPane.margin>
</Label>
<JFXButton fx:id="confirmBtn" buttonType="RAISED" maxHeight="-Infinity"
maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="40.0"
prefWidth="150.0" text="CONFIRM" GridPane.columnIndex="1"
GridPane.halignment="CENTER" GridPane.rowIndex="9" GridPane.valignment="CENTER"/>
<JFXButton fx:id="resetBtn" buttonType="RAISED" maxHeight="-Infinity"
maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="40.0"
prefWidth="150.0" text="RESET" GridPane.halignment="CENTER" GridPane.rowIndex="9"
GridPane.valignment="CENTER"/>
maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="45.0"
prefWidth="150.0" text="RESET" GridPane.columnSpan="2" GridPane.halignment="CENTER"
GridPane.rowIndex="9" GridPane.valignment="CENTER"/>
</children>
</GridPane>
</children>