Merge branch 'new_issue#19' into 'master'
New issue#19 See merge request !31
This commit is contained in:
@@ -38,6 +38,8 @@ public class ConnectionAcceptor implements Runnable {
|
|||||||
*/
|
*/
|
||||||
private ServerSocket serverSocket;
|
private ServerSocket serverSocket;
|
||||||
|
|
||||||
|
private Socket mockSocket = null;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of client connections.
|
* List of client connections.
|
||||||
@@ -97,6 +99,13 @@ public class ConnectionAcceptor implements Runnable {
|
|||||||
return serverPort;
|
return serverPort;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void closeConnection() throws IOException {
|
||||||
|
this.raceLogic.boolFalse();
|
||||||
|
if(!this.serverSocket.isClosed()){
|
||||||
|
this.serverSocket.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -109,8 +118,13 @@ public class ConnectionAcceptor implements Runnable {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
if(Thread.currentThread().isInterrupted()){
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
Socket mockSocket = serverSocket.accept();
|
try {
|
||||||
|
this.mockSocket = serverSocket.accept();
|
||||||
|
} catch (Exception e){}
|
||||||
|
|
||||||
Logger.getGlobal().log(Level.INFO, String.format("Client connected. client ip/port = %s. Local ip/port = %s.", mockSocket.getRemoteSocketAddress(), mockSocket.getLocalSocketAddress()));
|
Logger.getGlobal().log(Level.INFO, String.format("Client connected. client ip/port = %s. Local ip/port = %s.", mockSocket.getRemoteSocketAddress(), mockSocket.getLocalSocketAddress()));
|
||||||
|
|
||||||
|
|||||||
@@ -64,6 +64,10 @@ public class Event {
|
|||||||
*/
|
*/
|
||||||
private SourceIdAllocator sourceIdAllocator;
|
private SourceIdAllocator sourceIdAllocator;
|
||||||
|
|
||||||
|
private Thread raceThread;
|
||||||
|
|
||||||
|
private Thread connectionThread;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -144,7 +148,8 @@ public class Event {
|
|||||||
this.latestMessages,
|
this.latestMessages,
|
||||||
this.compositeCommand);
|
this.compositeCommand);
|
||||||
|
|
||||||
new Thread(newRace, "Event.Start()->RaceLogic thread").start();
|
this.raceThread = new Thread(newRace, "Event.Start()->RaceLogic thread");
|
||||||
|
raceThread.start();
|
||||||
|
|
||||||
|
|
||||||
//Create connection acceptor.
|
//Create connection acceptor.
|
||||||
@@ -157,13 +162,20 @@ public class Event {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
new Thread(connectionAcceptor, "Event.Start()->ConnectionAcceptor thread").start();
|
this.connectionThread = new Thread(connectionAcceptor, "Event.Start()->ConnectionAcceptor thread");
|
||||||
|
connectionThread.start();
|
||||||
|
|
||||||
sendXMLs();
|
sendXMLs();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void endEvent() throws IOException {
|
||||||
|
this.connectionThread.interrupt();
|
||||||
|
this.connectionAcceptor.closeConnection();
|
||||||
|
this.raceThread.interrupt();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -15,8 +15,6 @@ import java.util.logging.Logger;
|
|||||||
*/
|
*/
|
||||||
public class MockOutput implements RunnableWithFramePeriod {
|
public class MockOutput implements RunnableWithFramePeriod {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A queue to send messages to client.
|
* A queue to send messages to client.
|
||||||
*/
|
*/
|
||||||
@@ -103,6 +101,8 @@ public class MockOutput implements RunnableWithFramePeriod {
|
|||||||
Logger.getGlobal().log(Level.WARNING, "MockOutput.run() interrupted while putting message in queue.", e);
|
Logger.getGlobal().log(Level.WARNING, "MockOutput.run() interrupted while putting message in queue.", e);
|
||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
return;
|
return;
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ public class HeartBeatService implements RunnableWithFramePeriod {
|
|||||||
* Puts a HeartBeat message on the message queue.
|
* Puts a HeartBeat message on the message queue.
|
||||||
* @throws InterruptedException Thrown if the thread is interrupted.
|
* @throws InterruptedException Thrown if the thread is interrupted.
|
||||||
*/
|
*/
|
||||||
private void sendHeartBeat() throws InterruptedException {
|
private void sendHeartBeat() throws Exception {
|
||||||
|
|
||||||
HeartBeat heartBeat = createHeartbeatMessage();
|
HeartBeat heartBeat = createHeartbeatMessage();
|
||||||
|
|
||||||
@@ -92,13 +92,17 @@ public class HeartBeatService implements RunnableWithFramePeriod {
|
|||||||
|
|
||||||
while (!Thread.interrupted()) {
|
while (!Thread.interrupted()) {
|
||||||
long currentFrameTime = System.currentTimeMillis();
|
long currentFrameTime = System.currentTimeMillis();
|
||||||
|
try {
|
||||||
waitForFramePeriod(lastHeartbeatTime, currentFrameTime, heartbeatPeriod);
|
waitForFramePeriod(lastHeartbeatTime, currentFrameTime, heartbeatPeriod);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
lastHeartbeatTime = currentFrameTime;
|
lastHeartbeatTime = currentFrameTime;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
sendHeartBeat();
|
sendHeartBeat();
|
||||||
|
|
||||||
} catch (InterruptedException e) {
|
} catch (Exception e) {
|
||||||
Logger.getGlobal().log(Level.WARNING, "HeartBeatService: " + this + " sendHeartBeat() was interrupted on thread: " + Thread.currentThread(), e);
|
Logger.getGlobal().log(Level.WARNING, "HeartBeatService: " + this + " sendHeartBeat() was interrupted on thread: " + Thread.currentThread(), e);
|
||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ public class RaceLogic implements RunnableWithFramePeriod, Observer {
|
|||||||
|
|
||||||
private CompositeCommand commands;
|
private CompositeCommand commands;
|
||||||
|
|
||||||
|
private boolean loopBool = true;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialises race loop with state and server message queue
|
* Initialises race loop with state and server message queue
|
||||||
* @param race state of race to modify
|
* @param race state of race to modify
|
||||||
@@ -48,20 +50,32 @@ public class RaceLogic implements RunnableWithFramePeriod, Observer {
|
|||||||
public void run() {
|
public void run() {
|
||||||
race.initialiseBoats();
|
race.initialiseBoats();
|
||||||
|
|
||||||
|
try {
|
||||||
countdown();
|
countdown();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
raceLoop();
|
raceLoop();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void boolFalse(){
|
||||||
|
loopBool = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Countdown timer until race starts.
|
* Countdown timer until race starts.
|
||||||
*/
|
*/
|
||||||
private void countdown() {
|
private void countdown() throws Exception {
|
||||||
|
|
||||||
long previousFrameTime = System.currentTimeMillis();
|
long previousFrameTime = System.currentTimeMillis();
|
||||||
|
|
||||||
while (race.getRaceStatusEnum() != RaceStatusEnum.STARTED) {
|
while (race.getRaceStatusEnum() != RaceStatusEnum.STARTED && loopBool) {
|
||||||
|
|
||||||
long currentTime = System.currentTimeMillis();
|
long currentTime = System.currentTimeMillis();
|
||||||
|
|
||||||
@@ -96,11 +110,11 @@ public class RaceLogic implements RunnableWithFramePeriod, Observer {
|
|||||||
/**
|
/**
|
||||||
* Timer that runs for the duration of the race, until all boats finish.
|
* Timer that runs for the duration of the race, until all boats finish.
|
||||||
*/
|
*/
|
||||||
private void raceLoop() {
|
private void raceLoop() throws Exception {
|
||||||
|
|
||||||
long previousFrameTime = System.currentTimeMillis();
|
long previousFrameTime = System.currentTimeMillis();
|
||||||
|
|
||||||
while (race.getRaceStatusEnum() != RaceStatusEnum.FINISHED) {
|
while (race.getRaceStatusEnum() != RaceStatusEnum.FINISHED && loopBool) {
|
||||||
|
|
||||||
//Get the current time.
|
//Get the current time.
|
||||||
long currentTime = System.currentTimeMillis();
|
long currentTime = System.currentTimeMillis();
|
||||||
|
|||||||
@@ -93,7 +93,11 @@ public class MessageSerialiser implements RunnableWithFramePeriod {
|
|||||||
|
|
||||||
|
|
||||||
long currentFrameTime = System.currentTimeMillis();
|
long currentFrameTime = System.currentTimeMillis();
|
||||||
|
try {
|
||||||
waitForFramePeriod(previousFrameTime, currentFrameTime, 16);
|
waitForFramePeriod(previousFrameTime, currentFrameTime, 16);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
previousFrameTime = currentFrameTime;
|
previousFrameTime = currentFrameTime;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ public interface RunnableWithFramePeriod extends Runnable {
|
|||||||
* @param currentFrameTime The timestamp of the current frame.
|
* @param currentFrameTime The timestamp of the current frame.
|
||||||
* @param minimumFramePeriod The minimum period the frame must be.
|
* @param minimumFramePeriod The minimum period the frame must be.
|
||||||
*/
|
*/
|
||||||
default void waitForFramePeriod(long previousFrameTime, long currentFrameTime, long minimumFramePeriod) {
|
default void waitForFramePeriod(long previousFrameTime, long currentFrameTime, long minimumFramePeriod) throws Exception {
|
||||||
|
|
||||||
|
|
||||||
//This is the time elapsed, in milliseconds, since the last server "frame".
|
//This is the time elapsed, in milliseconds, since the last server "frame".
|
||||||
@@ -39,10 +39,10 @@ public interface RunnableWithFramePeriod extends Runnable {
|
|||||||
|
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
//If we get interrupted, exit the function.
|
//If we get interrupted, exit the function.
|
||||||
Logger.getGlobal().log(Level.SEVERE, "RunnableWithFramePeriod.waitForFramePeriod().sleep(framePeriod) was interrupted on thread: " + Thread.currentThread(), e);
|
/*Logger.getGlobal().log(Level.SEVERE, "RunnableWithFramePeriod.waitForFramePeriod().sleep(framePeriod) was interrupted on thread: " + Thread.currentThread(), e);
|
||||||
//Re-set the interrupt flag.
|
//Re-set the interrupt flag.
|
||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
return;
|
return;*/
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ public class ConnectionController extends Controller {
|
|||||||
Socket socket = new Socket(connection.getHostname(), connection.getPort());
|
Socket socket = new Socket(connection.getHostname(), connection.getPort());
|
||||||
socket.setKeepAlive(true);
|
socket.setKeepAlive(true);
|
||||||
connectionWrapper.setVisible(false);
|
connectionWrapper.setVisible(false);
|
||||||
parent.enterLobby(socket);
|
//parent.enterLobby(socket);
|
||||||
} catch (IOException e) { /* Never reached */ }
|
} catch (IOException e) { /* Never reached */ }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,8 @@ public class HostController extends Controller {
|
|||||||
@FXML
|
@FXML
|
||||||
AnchorPane hostWrapper;
|
AnchorPane hostWrapper;
|
||||||
|
|
||||||
|
private Event game;
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initialize(URL location, ResourceBundle resources) {
|
public void initialize(URL location, ResourceBundle resources) {
|
||||||
@@ -46,7 +48,7 @@ public class HostController extends Controller {
|
|||||||
*/
|
*/
|
||||||
public void hostGamePressed() throws IOException{
|
public void hostGamePressed() throws IOException{
|
||||||
try {
|
try {
|
||||||
Event game = new Event(false);
|
this.game = new Event(false);
|
||||||
game.start();
|
game.start();
|
||||||
connectSocket("localhost", 4942);
|
connectSocket("localhost", 4942);
|
||||||
} catch (EventConstructionException e) {
|
} catch (EventConstructionException e) {
|
||||||
@@ -55,6 +57,10 @@ public class HostController extends Controller {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void endEvent() throws IOException {
|
||||||
|
game.endEvent();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Connect to a socket
|
* Connect to a socket
|
||||||
* @param address address of the server
|
* @param address address of the server
|
||||||
@@ -64,7 +70,7 @@ public class HostController extends Controller {
|
|||||||
try{
|
try{
|
||||||
Socket socket = new Socket(address, port);
|
Socket socket = new Socket(address, port);
|
||||||
hostWrapper.setVisible(false);
|
hostWrapper.setVisible(false);
|
||||||
parent.enterLobby(socket);
|
parent.enterLobby(socket, true);
|
||||||
} catch (IOException e) { /* Never reached */ }
|
} catch (IOException e) { /* Never reached */ }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,4 +85,9 @@ public class HostController extends Controller {
|
|||||||
hostWrapper.setVisible(true);
|
hostWrapper.setVisible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void menuBtnPressed(){
|
||||||
|
hostWrapper.setVisible(false);
|
||||||
|
parent.enterTitle();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,12 +86,17 @@ public class LobbyController extends Controller {
|
|||||||
RaceConnection connection = lobbyTable.getSelectionModel().getSelectedItem();
|
RaceConnection connection = lobbyTable.getSelectionModel().getSelectedItem();
|
||||||
Socket socket = new Socket(connection.getHostname(), connection.getPort());
|
Socket socket = new Socket(connection.getHostname(), connection.getPort());
|
||||||
lobbyWrapper.setVisible(false);
|
lobbyWrapper.setVisible(false);
|
||||||
parent.enterLobby(socket);
|
parent.enterLobby(socket, false);
|
||||||
} catch (IOException e) { /* Never reached */
|
} catch (IOException e) { /* Never reached */
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void menuBtnPressed(){
|
||||||
|
lobbyWrapper.setVisible(false);
|
||||||
|
parent.enterTitle();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* adds a new connection
|
* adds a new connection
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -3,10 +3,12 @@ package visualiser.Controllers;
|
|||||||
import javafx.collections.ObservableList;
|
import javafx.collections.ObservableList;
|
||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.scene.layout.AnchorPane;
|
import javafx.scene.layout.AnchorPane;
|
||||||
|
import visualiser.app.App;
|
||||||
import visualiser.gameController.ControllerClient;
|
import visualiser.gameController.ControllerClient;
|
||||||
import visualiser.model.VisualiserBoat;
|
import visualiser.model.VisualiserBoat;
|
||||||
import visualiser.model.VisualiserRaceEvent;
|
import visualiser.model.VisualiserRaceEvent;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.ResourceBundle;
|
import java.util.ResourceBundle;
|
||||||
@@ -39,16 +41,19 @@ public class MainController extends Controller {
|
|||||||
* @param visualiserRace The object modelling the race.
|
* @param visualiserRace The object modelling the race.
|
||||||
* @param controllerClient Socket Client that manipulates the controller.
|
* @param controllerClient Socket Client that manipulates the controller.
|
||||||
*/
|
*/
|
||||||
public void beginRace(VisualiserRaceEvent visualiserRace, ControllerClient controllerClient) {
|
public void beginRace(VisualiserRaceEvent visualiserRace, ControllerClient controllerClient, Boolean isHost) {
|
||||||
raceController.startRace(visualiserRace, controllerClient);
|
raceController.startRace(visualiserRace, controllerClient, isHost);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void endEvent() throws IOException { hostController.endEvent(); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transitions from the server selection screen to the pre-race lobby for a given server.
|
* Transitions from the server selection screen to the pre-race lobby for a given server.
|
||||||
* @param socket The server to read data from.
|
* @param socket The server to read data from.
|
||||||
|
* @param isHost is connection a host
|
||||||
*/
|
*/
|
||||||
public void enterLobby(Socket socket) {
|
public void enterLobby(Socket socket, Boolean isHost) {
|
||||||
startController.enterLobby(socket);
|
startController.enterLobby(socket, isHost);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -62,7 +67,9 @@ public class MainController extends Controller {
|
|||||||
/**
|
/**
|
||||||
* Transitions into the title screen
|
* Transitions into the title screen
|
||||||
*/
|
*/
|
||||||
public void enterTitle(){ titleController.enterTitle(); }
|
public void enterTitle() {
|
||||||
|
titleController.enterTitle();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transitions into lobby screen
|
* Transitions into lobby screen
|
||||||
|
|||||||
@@ -10,6 +10,8 @@ import javafx.collections.transformation.SortedList;
|
|||||||
import javafx.fxml.FXML;
|
import javafx.fxml.FXML;
|
||||||
import javafx.scene.chart.LineChart;
|
import javafx.scene.chart.LineChart;
|
||||||
import javafx.scene.control.*;
|
import javafx.scene.control.*;
|
||||||
|
import javafx.scene.control.Label;
|
||||||
|
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.scene.layout.GridPane;
|
import javafx.scene.layout.GridPane;
|
||||||
@@ -18,12 +20,15 @@ import javafx.scene.layout.StackPane;
|
|||||||
import javafx.util.Callback;
|
import javafx.util.Callback;
|
||||||
import network.Messages.Enums.RaceStatusEnum;
|
import network.Messages.Enums.RaceStatusEnum;
|
||||||
import shared.model.Leg;
|
import shared.model.Leg;
|
||||||
|
import visualiser.app.App;
|
||||||
import visualiser.gameController.ControllerClient;
|
import visualiser.gameController.ControllerClient;
|
||||||
import visualiser.gameController.Keys.ControlKey;
|
import visualiser.gameController.Keys.ControlKey;
|
||||||
import visualiser.gameController.Keys.KeyFactory;
|
import visualiser.gameController.Keys.KeyFactory;
|
||||||
import visualiser.model.*;
|
import visualiser.model.*;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.ResourceBundle;
|
import java.util.ResourceBundle;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
@@ -48,7 +53,7 @@ public class RaceController extends Controller {
|
|||||||
private ControllerClient controllerClient;
|
private ControllerClient controllerClient;
|
||||||
|
|
||||||
|
|
||||||
|
private boolean isHost;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The canvas that draws the race.
|
* The canvas that draws the race.
|
||||||
@@ -128,6 +133,35 @@ public class RaceController extends Controller {
|
|||||||
Logger.getGlobal().log(Level.WARNING, "RaceController was interrupted on thread: " + Thread.currentThread() + "while sending: " + controlKey, e);
|
Logger.getGlobal().log(Level.WARNING, "RaceController was interrupted on thread: " + Thread.currentThread() + "while sending: " + controlKey, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(event.getCode() == KeyCode.ESCAPE) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (isHost) {
|
||||||
|
Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
|
||||||
|
alert.setTitle("Exit Race");
|
||||||
|
alert.setContentText("Do you wish to quit the race? You are the host");
|
||||||
|
Optional<ButtonType> result = alert.showAndWait();
|
||||||
|
if (result.get() == ButtonType.OK) {
|
||||||
|
parent.endEvent();
|
||||||
|
race.setVisible(false);
|
||||||
|
App.app.showMainStage(App.getStage());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
|
||||||
|
alert.setTitle("Exit Race");
|
||||||
|
alert.setContentText("Do you wish to quit the race?");
|
||||||
|
Optional<ButtonType> result = alert.showAndWait();
|
||||||
|
if (result.get() == ButtonType.OK) {
|
||||||
|
race.setVisible(false);
|
||||||
|
App.app.showMainStage(App.getStage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -366,11 +400,13 @@ public class RaceController extends Controller {
|
|||||||
* Displays a specified race.
|
* Displays a specified race.
|
||||||
* @param visualiserRace Object modelling the race.
|
* @param visualiserRace Object modelling the race.
|
||||||
* @param controllerClient Socket Client that manipulates the controller.
|
* @param controllerClient Socket Client that manipulates the controller.
|
||||||
|
* @param isHost is user a host
|
||||||
*/
|
*/
|
||||||
public void startRace(VisualiserRaceEvent visualiserRace, ControllerClient controllerClient) {
|
public void startRace(VisualiserRaceEvent visualiserRace, ControllerClient controllerClient, Boolean isHost) {
|
||||||
|
|
||||||
this.visualiserRace = visualiserRace;
|
this.visualiserRace = visualiserRace;
|
||||||
this.controllerClient = controllerClient;
|
this.controllerClient = controllerClient;
|
||||||
|
this.isHost = isHost;
|
||||||
|
|
||||||
initialiseRace();
|
initialiseRace();
|
||||||
|
|
||||||
@@ -434,7 +470,14 @@ public class RaceController extends Controller {
|
|||||||
//Return to main screen if we lose connection.
|
//Return to main screen if we lose connection.
|
||||||
if (!visualiserRace.getServerConnection().isAlive()) {
|
if (!visualiserRace.getServerConnection().isAlive()) {
|
||||||
race.setVisible(false);
|
race.setVisible(false);
|
||||||
parent.enterTitle();
|
//parent.enterTitle();
|
||||||
|
try {
|
||||||
|
App.app.showMainStage(App.getStage());
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
//TODO currently this doesn't work correctly - the title screen remains visible after clicking join game
|
//TODO currently this doesn't work correctly - the title screen remains visible after clicking join game
|
||||||
//TODO we should display an error to the user
|
//TODO we should display an error to the user
|
||||||
//TODO also need to "reset" any state (race, connections, etc...).
|
//TODO also need to "reset" any state (race, connections, etc...).
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ public class StartController extends Controller {
|
|||||||
*/
|
*/
|
||||||
private ControllerClient controllerClient;
|
private ControllerClient controllerClient;
|
||||||
|
|
||||||
|
private boolean isHost;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -238,7 +238,7 @@ public class StartController extends Controller {
|
|||||||
startWrapper.setVisible(false);
|
startWrapper.setVisible(false);
|
||||||
//start.setVisible(false);//TODO is this needed?
|
//start.setVisible(false);//TODO is this needed?
|
||||||
|
|
||||||
parent.beginRace(visualiserRaceEvent, controllerClient);
|
parent.beginRace(visualiserRaceEvent, controllerClient, isHost);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -250,10 +250,13 @@ public class StartController extends Controller {
|
|||||||
/**
|
/**
|
||||||
* Show starting information for a race given a socket.
|
* Show starting information for a race given a socket.
|
||||||
* @param socket network source of information
|
* @param socket network source of information
|
||||||
|
* @param isHost is user a host
|
||||||
*/
|
*/
|
||||||
public void enterLobby(Socket socket) {
|
public void enterLobby(Socket socket, Boolean isHost) {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
this.isHost = isHost;
|
||||||
|
|
||||||
this.visualiserRaceEvent = new VisualiserRaceEvent(socket, RequestToJoinEnum.PARTICIPANT);
|
this.visualiserRaceEvent = new VisualiserRaceEvent(socket, RequestToJoinEnum.PARTICIPANT);
|
||||||
|
|
||||||
this.controllerClient = visualiserRaceEvent.getControllerClient();
|
this.controllerClient = visualiserRaceEvent.getControllerClient();
|
||||||
|
|||||||
@@ -1,9 +1,14 @@
|
|||||||
package visualiser.Controllers;
|
package visualiser.Controllers;
|
||||||
|
|
||||||
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.RadioButton;
|
import javafx.scene.control.RadioButton;
|
||||||
import javafx.scene.layout.AnchorPane;
|
import javafx.scene.layout.AnchorPane;
|
||||||
|
import javafx.stage.Modality;
|
||||||
|
import javafx.stage.Stage;
|
||||||
import visualiser.app.App;
|
import visualiser.app.App;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@@ -17,6 +22,7 @@ import java.util.ResourceBundle;
|
|||||||
* the game.
|
* the game.
|
||||||
*/
|
*/
|
||||||
public class TitleController extends Controller {
|
public class TitleController extends Controller {
|
||||||
|
//FXML stuff
|
||||||
@FXML
|
@FXML
|
||||||
Button btnJoin;
|
Button btnJoin;
|
||||||
@FXML
|
@FXML
|
||||||
@@ -77,4 +83,26 @@ public class TitleController extends Controller {
|
|||||||
public void initialize(URL location, ResourceBundle resources) {
|
public void initialize(URL location, ResourceBundle resources) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called when control button is pressed. New pop up window displaying controls
|
||||||
|
*/
|
||||||
|
public void controlBtnPressed(){
|
||||||
|
FXMLLoader loader = new FXMLLoader();
|
||||||
|
loader.setLocation(getClass().getResource("/visualiser/scenes/controls.fxml"));
|
||||||
|
Parent layout;
|
||||||
|
try {
|
||||||
|
layout = loader.load();
|
||||||
|
Scene scene = new Scene(layout);
|
||||||
|
Stage popupStage = new Stage();
|
||||||
|
popupStage.setResizable(false);
|
||||||
|
popupStage.setTitle("Game Controls");
|
||||||
|
popupStage.initModality(Modality.WINDOW_MODAL);
|
||||||
|
popupStage.setScene(scene);
|
||||||
|
popupStage.showAndWait();
|
||||||
|
} catch (Exception e){
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,48 @@
|
|||||||
package visualiser.app;
|
package visualiser.app;
|
||||||
|
|
||||||
|
import javafx.animation.FadeTransition;
|
||||||
import javafx.application.Application;
|
import javafx.application.Application;
|
||||||
import javafx.application.Platform;
|
import javafx.application.Platform;
|
||||||
|
import javafx.beans.property.ReadOnlyObjectProperty;
|
||||||
|
import javafx.collections.FXCollections;
|
||||||
|
import javafx.collections.ObservableList;
|
||||||
|
import javafx.concurrent.Task;
|
||||||
|
import javafx.concurrent.Worker;
|
||||||
import javafx.event.EventHandler;
|
import javafx.event.EventHandler;
|
||||||
import javafx.fxml.FXMLLoader;
|
import javafx.fxml.FXMLLoader;
|
||||||
|
import javafx.geometry.Pos;
|
||||||
|
import javafx.geometry.Rectangle2D;
|
||||||
import javafx.scene.Parent;
|
import javafx.scene.Parent;
|
||||||
import javafx.scene.Scene;
|
import javafx.scene.Scene;
|
||||||
|
import javafx.scene.control.Label;
|
||||||
|
import javafx.scene.control.ListView;
|
||||||
|
import javafx.scene.control.ProgressBar;
|
||||||
|
import javafx.scene.effect.DropShadow;
|
||||||
import javafx.scene.image.Image;
|
import javafx.scene.image.Image;
|
||||||
|
import javafx.scene.image.ImageView;
|
||||||
|
import javafx.scene.layout.Pane;
|
||||||
|
import javafx.scene.layout.VBox;
|
||||||
|
import javafx.scene.paint.Color;
|
||||||
|
import javafx.stage.Screen;
|
||||||
import javafx.stage.Stage;
|
import javafx.stage.Stage;
|
||||||
|
import javafx.stage.StageStyle;
|
||||||
import javafx.stage.WindowEvent;
|
import javafx.stage.WindowEvent;
|
||||||
|
import javafx.util.Duration;
|
||||||
import visualiser.Controllers.MainController;
|
import visualiser.Controllers.MainController;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
public class App extends Application {
|
public class App extends Application {
|
||||||
|
|
||||||
|
|
||||||
private static Stage stage;
|
private static Stage stage;
|
||||||
|
private Pane splashLayout;
|
||||||
|
private ProgressBar loadProgress;
|
||||||
|
private Label progressText;
|
||||||
|
private static final int SPLASH_WIDTH = 676;
|
||||||
|
private static final int SPLASH_HEIGHT = 227;
|
||||||
|
|
||||||
|
public static App app;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Entry point for running the programme
|
* Entry point for running the programme
|
||||||
@@ -23,19 +53,103 @@ public class App extends Application {
|
|||||||
launch(args);
|
launch(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init() {
|
||||||
|
ImageView splash = new ImageView(new Image(
|
||||||
|
getClass().getClassLoader().getResourceAsStream("images/splashScreen.png")
|
||||||
|
));
|
||||||
|
loadProgress = new ProgressBar();
|
||||||
|
loadProgress.setPrefWidth(SPLASH_WIDTH - 20);
|
||||||
|
progressText = new Label("Preparing application . . .");
|
||||||
|
splashLayout = new VBox();
|
||||||
|
splashLayout.getChildren().addAll(splash, loadProgress, progressText);
|
||||||
|
progressText.setAlignment(Pos.CENTER);
|
||||||
|
splashLayout.setStyle(
|
||||||
|
"-fx-padding: 5; " +
|
||||||
|
"-fx-background-color: cornsilk; " +
|
||||||
|
"-fx-border-width:5; " +
|
||||||
|
"-fx-border-color: " +
|
||||||
|
"linear-gradient(" +
|
||||||
|
"to bottom, " +
|
||||||
|
"chocolate, " +
|
||||||
|
"derive(chocolate, 50%)" +
|
||||||
|
");"
|
||||||
|
);
|
||||||
|
splashLayout.setEffect(new DropShadow());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method that displays the visualiser, starting with the title screen.
|
* Method that sets up and displays the splash screen
|
||||||
* @param stage the stage to be displayed.
|
* @param initStage the inital stage
|
||||||
* @throws Exception if something wrong with title screen.
|
* @throws Exception if something wrong with title screen.
|
||||||
*/
|
*/
|
||||||
public void start(Stage stage) throws Exception {
|
public void start(Stage initStage) throws Exception {
|
||||||
stage.setOnCloseRequest(new EventHandler<WindowEvent>() {
|
final Task<ObservableList<String>> boatTask = new Task<ObservableList<String>>() {
|
||||||
@Override
|
@Override
|
||||||
public void handle(WindowEvent event) {
|
protected ObservableList<String> call() throws InterruptedException {
|
||||||
Platform.exit();
|
ObservableList<String> addedFilling =
|
||||||
System.exit(0);
|
FXCollections.<String>observableArrayList();
|
||||||
|
ObservableList<String> burgerFilling =
|
||||||
|
FXCollections.observableArrayList(
|
||||||
|
"Buns", "Patties", "Lettuce", "Onions", "Tomato",
|
||||||
|
"Sauces"
|
||||||
|
);
|
||||||
|
|
||||||
|
updateMessage("Preparing ingredients . . .");
|
||||||
|
Thread.sleep(1000);
|
||||||
|
for (int i = 0; i < burgerFilling.size(); i++) {
|
||||||
|
Thread.sleep(800);
|
||||||
|
updateProgress(i + 1, burgerFilling.size());
|
||||||
|
String nextFilling = burgerFilling.get(i);
|
||||||
|
addedFilling.add(nextFilling);
|
||||||
|
updateMessage("Adding the " + nextFilling + " . . .");
|
||||||
}
|
}
|
||||||
});
|
Thread.sleep(400);
|
||||||
|
updateMessage("Burger's done!");
|
||||||
|
|
||||||
|
return addedFilling;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
showSplash(
|
||||||
|
initStage,
|
||||||
|
boatTask,
|
||||||
|
() -> {
|
||||||
|
try {
|
||||||
|
showMainStage(new Stage());
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
new Thread(boatTask).start();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get main stage
|
||||||
|
* @return main stage
|
||||||
|
*/
|
||||||
|
public static Stage getStage() {
|
||||||
|
return App.stage;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set main stage
|
||||||
|
* @param stage stage to set main stage
|
||||||
|
*/
|
||||||
|
public static void setStage(Stage stage) {
|
||||||
|
App.stage = stage;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show the main stage after the splash screen
|
||||||
|
* @param stage main stage for application
|
||||||
|
* @throws Exception Throws an exception on error
|
||||||
|
*/
|
||||||
|
public void showMainStage(Stage stage) throws Exception {
|
||||||
|
App.stage = stage;
|
||||||
|
App.app = this;
|
||||||
FXMLLoader loader = new FXMLLoader(getClass().getResource("/visualiser/scenes/main.fxml"));
|
FXMLLoader loader = new FXMLLoader(getClass().getResource("/visualiser/scenes/main.fxml"));
|
||||||
Parent root = loader.load();
|
Parent root = loader.load();
|
||||||
stage.setResizable(false);
|
stage.setResizable(false);
|
||||||
@@ -49,13 +163,57 @@ public class App extends Application {
|
|||||||
mc.startCss();
|
mc.startCss();
|
||||||
setStage(stage);
|
setStage(stage);
|
||||||
stage.show();
|
stage.show();
|
||||||
|
stage.setOnCloseRequest(new EventHandler<WindowEvent>() {
|
||||||
|
@Override
|
||||||
|
public void handle(WindowEvent event) {
|
||||||
|
Platform.exit();
|
||||||
|
System.exit(0);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Stage getStage() {
|
/**
|
||||||
return App.stage;
|
* Show the splash screen
|
||||||
|
* @param initStage Initial stage
|
||||||
|
* @param task Task for splash screen
|
||||||
|
* @param initCompletionHandler initCompletionHandler interface
|
||||||
|
*/
|
||||||
|
private void showSplash(
|
||||||
|
final Stage initStage,
|
||||||
|
Task<?> task,
|
||||||
|
InitCompletionHandler initCompletionHandler
|
||||||
|
) {
|
||||||
|
progressText.textProperty().bind(task.messageProperty());
|
||||||
|
loadProgress.progressProperty().bind(task.progressProperty());
|
||||||
|
task.stateProperty().addListener((observableValue, oldState, newState) -> {
|
||||||
|
if (newState == Worker.State.SUCCEEDED) {
|
||||||
|
loadProgress.progressProperty().unbind();
|
||||||
|
loadProgress.setProgress(1);
|
||||||
|
initStage.toFront();
|
||||||
|
FadeTransition fadeSplash = new FadeTransition(Duration.seconds(2), splashLayout);
|
||||||
|
fadeSplash.setFromValue(1.0);
|
||||||
|
fadeSplash.setToValue(0.0);
|
||||||
|
fadeSplash.setOnFinished(actionEvent -> initStage.hide());
|
||||||
|
fadeSplash.play();
|
||||||
|
|
||||||
|
initCompletionHandler.complete();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Scene splashScene = new Scene(splashLayout, Color.TRANSPARENT);
|
||||||
|
final Rectangle2D bounds = Screen.getPrimary().getBounds();
|
||||||
|
initStage.setScene(splashScene);
|
||||||
|
initStage.setX(bounds.getMinX() + bounds.getWidth() / 2 - SPLASH_WIDTH / 2);
|
||||||
|
initStage.setY(bounds.getMinY() + bounds.getHeight() / 2 - SPLASH_HEIGHT / 2);
|
||||||
|
initStage.initStyle(StageStyle.TRANSPARENT);
|
||||||
|
initStage.setAlwaysOnTop(true);
|
||||||
|
initStage.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void setStage(Stage stage) {
|
/**
|
||||||
App.stage = stage;
|
* InnitCompletionHandler interface
|
||||||
|
*/
|
||||||
|
public interface InitCompletionHandler {
|
||||||
|
void complete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,7 +69,11 @@ public class VisualiserRaceService implements RunnableWithFramePeriod {
|
|||||||
|
|
||||||
long currentFrameTime = System.currentTimeMillis();
|
long currentFrameTime = System.currentTimeMillis();
|
||||||
|
|
||||||
|
try {
|
||||||
waitForFramePeriod(previousFrameTime, currentFrameTime, 16);
|
waitForFramePeriod(previousFrameTime, currentFrameTime, 16);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
previousFrameTime = currentFrameTime;
|
previousFrameTime = currentFrameTime;
|
||||||
|
|
||||||
|
|||||||
@@ -330,7 +330,11 @@ public class ServerConnection implements RunnableWithFramePeriod {
|
|||||||
while (!Thread.interrupted()) {
|
while (!Thread.interrupted()) {
|
||||||
|
|
||||||
long currentFrameTime = System.currentTimeMillis();
|
long currentFrameTime = System.currentTimeMillis();
|
||||||
|
try {
|
||||||
waitForFramePeriod(previousFrameTime, currentFrameTime, 100);
|
waitForFramePeriod(previousFrameTime, currentFrameTime, 100);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
previousFrameTime = currentFrameTime;
|
previousFrameTime = currentFrameTime;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 600 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.0 MiB |
@@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<?import javafx.scene.image.*?>
|
||||||
|
<?import java.lang.*?>
|
||||||
|
<?import javafx.scene.layout.*?>
|
||||||
|
|
||||||
|
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="350.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
|
||||||
|
<children>
|
||||||
|
<ImageView fitHeight="385.0" fitWidth="600.0" layoutY="-2.0" pickOnBounds="true" preserveRatio="true" AnchorPane.bottomAnchor="-1.9456787109375" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="-2.0">
|
||||||
|
<image>
|
||||||
|
<Image url="@../images/game_controls.png" />
|
||||||
|
</image>
|
||||||
|
</ImageView>
|
||||||
|
</children>
|
||||||
|
</AnchorPane>
|
||||||
@@ -33,6 +33,7 @@
|
|||||||
<Font size="17.0" />
|
<Font size="17.0" />
|
||||||
</font>
|
</font>
|
||||||
</Label>
|
</Label>
|
||||||
|
<Button mnemonicParsing="false" onAction="#menuBtnPressed" text="Main Menu" GridPane.halignment="CENTER" />
|
||||||
</children>
|
</children>
|
||||||
</GridPane>
|
</GridPane>
|
||||||
</children>
|
</children>
|
||||||
|
|||||||
@@ -1,5 +1,10 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
|
||||||
|
<?import java.lang.*?>
|
||||||
|
<?import javafx.geometry.*?>
|
||||||
|
<?import javafx.scene.control.*?>
|
||||||
|
<?import javafx.scene.layout.*?>
|
||||||
|
<?import javafx.scene.text.*?>
|
||||||
<?import javafx.geometry.Insets?>
|
<?import javafx.geometry.Insets?>
|
||||||
<?import javafx.scene.control.Button?>
|
<?import javafx.scene.control.Button?>
|
||||||
<?import javafx.scene.control.Label?>
|
<?import javafx.scene.control.Label?>
|
||||||
@@ -12,7 +17,7 @@
|
|||||||
<?import javafx.scene.layout.RowConstraints?>
|
<?import javafx.scene.layout.RowConstraints?>
|
||||||
<?import javafx.scene.text.Font?>
|
<?import javafx.scene.text.Font?>
|
||||||
|
|
||||||
<AnchorPane fx:id="lobbyWrapper" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="600.0" prefWidth="780.0" visible="false" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="visualiser.Controllers.LobbyController">
|
<AnchorPane fx:id="lobbyWrapper" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="600.0" prefWidth="780.0" visible="false" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="visualiser.Controllers.LobbyController">
|
||||||
<children>
|
<children>
|
||||||
<GridPane fx:id="connection" prefHeight="600.0" prefWidth="780.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
<GridPane fx:id="connection" prefHeight="600.0" prefWidth="780.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
|
||||||
<columnConstraints>
|
<columnConstraints>
|
||||||
@@ -75,8 +80,11 @@
|
|||||||
<children>
|
<children>
|
||||||
<TextField fx:id="addressFld" promptText="Address">
|
<TextField fx:id="addressFld" promptText="Address">
|
||||||
<GridPane.margin>
|
<GridPane.margin>
|
||||||
<Insets left="20.0" right="20.0" />
|
<Insets left="50.0" right="20.0" />
|
||||||
</GridPane.margin></TextField>
|
</GridPane.margin>
|
||||||
|
<opaqueInsets>
|
||||||
|
<Insets />
|
||||||
|
</opaqueInsets></TextField>
|
||||||
<TextField fx:id="portFld" promptText="Port Number" GridPane.columnIndex="1">
|
<TextField fx:id="portFld" promptText="Port Number" GridPane.columnIndex="1">
|
||||||
<GridPane.margin>
|
<GridPane.margin>
|
||||||
<Insets left="20.0" right="20.0" />
|
<Insets left="20.0" right="20.0" />
|
||||||
@@ -86,6 +94,11 @@
|
|||||||
<Insets />
|
<Insets />
|
||||||
</GridPane.margin>
|
</GridPane.margin>
|
||||||
</GridPane>
|
</GridPane>
|
||||||
|
<Button mnemonicParsing="false" onAction="#menuBtnPressed" text="Main Menu">
|
||||||
|
<GridPane.margin>
|
||||||
|
<Insets left="50.0" />
|
||||||
|
</GridPane.margin>
|
||||||
|
</Button>
|
||||||
</children>
|
</children>
|
||||||
</GridPane>
|
</GridPane>
|
||||||
</children>
|
</children>
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
</Text>
|
</Text>
|
||||||
<RadioButton fx:id="nightModeRD" layoutX="681.0" layoutY="168.0" mnemonicParsing="false" onAction="#setNightMode" text="Night Mode" />
|
<RadioButton fx:id="nightModeRD" layoutX="681.0" layoutY="168.0" mnemonicParsing="false" onAction="#setNightMode" text="Night Mode" />
|
||||||
<RadioButton fx:id="dayModeRD" layoutX="574.0" layoutY="168.0" mnemonicParsing="false" onAction="#setDayMode" selected="true" text="Day Mode" />
|
<RadioButton fx:id="dayModeRD" layoutX="574.0" layoutY="168.0" mnemonicParsing="false" onAction="#setDayMode" selected="true" text="Day Mode" />
|
||||||
|
<Button layoutX="28.0" layoutY="152.0" mnemonicParsing="false" onAction="#controlBtnPressed" text="Controls" />
|
||||||
</children>
|
</children>
|
||||||
</Pane>
|
</Pane>
|
||||||
<Pane prefHeight="20.0" prefWidth="20.0" style="-fx-background-color: #6be6ff;" GridPane.columnSpan="4" GridPane.rowSpan="4">
|
<Pane prefHeight="20.0" prefWidth="20.0" style="-fx-background-color: #6be6ff;" GridPane.columnSpan="4" GridPane.rowSpan="4">
|
||||||
|
|||||||
Reference in New Issue
Block a user