Added application state saving
This commit is contained in:
parent
81710e9d15
commit
b3ffa5ecd4
11 changed files with 168 additions and 21 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -7,3 +7,4 @@ src/main/java/META-INF/
|
|||
dependency-reduced-pom.xml
|
||||
history.sqlite
|
||||
themes/
|
||||
/config/restaurant.state
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
package com.rohitawate.restaurant.homewindow;
|
||||
|
||||
import com.rohitawate.restaurant.models.requests.DataDispatchRequest;
|
||||
import com.rohitawate.restaurant.models.requests.RestaurantRequest;
|
||||
import com.rohitawate.restaurant.util.themes.ThemeManager;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
|
@ -76,7 +75,7 @@ public class BodyTabController implements Initializable {
|
|||
/**
|
||||
* Returns a RestaurantRequest object initialized with the request body.
|
||||
*/
|
||||
public RestaurantRequest getBasicRequest(String requestType) {
|
||||
public DataDispatchRequest getBasicRequest(String requestType) {
|
||||
DataDispatchRequest request = new DataDispatchRequest(requestType);
|
||||
|
||||
if (rawTab.isSelected()) {
|
||||
|
|
|
@ -21,6 +21,7 @@ import com.rohitawate.restaurant.exceptions.UnreliableResponseException;
|
|||
import com.rohitawate.restaurant.models.requests.DELETERequest;
|
||||
import com.rohitawate.restaurant.models.requests.DataDispatchRequest;
|
||||
import com.rohitawate.restaurant.models.requests.GETRequest;
|
||||
import com.rohitawate.restaurant.models.requests.RestaurantRequest;
|
||||
import com.rohitawate.restaurant.models.responses.RestaurantResponse;
|
||||
import com.rohitawate.restaurant.requestsmanager.DELETERequestManager;
|
||||
import com.rohitawate.restaurant.requestsmanager.DataDispatchRequestManager;
|
||||
|
@ -47,6 +48,7 @@ import java.net.MalformedURLException;
|
|||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
public class DashboardController implements Initializable {
|
||||
|
@ -81,7 +83,7 @@ public class DashboardController implements Initializable {
|
|||
|
||||
@Override
|
||||
public void initialize(URL url, ResourceBundle rb) {
|
||||
applySettings();
|
||||
applyDashboardSettings();
|
||||
|
||||
try {
|
||||
// Loading the headers tab
|
||||
|
@ -110,7 +112,7 @@ public class DashboardController implements Initializable {
|
|||
|
||||
paramsControllers = new ArrayList<>();
|
||||
appendedParams = new ArrayList<>();
|
||||
addParam(); // Adds a blank param field
|
||||
addParamField(); // Adds a blank param field
|
||||
|
||||
snackBar = new JFXSnackbar(dashboard);
|
||||
bodyTab.disableProperty().bind(Bindings.and(httpMethodBox.valueProperty().isNotEqualTo("POST"),
|
||||
|
@ -121,7 +123,7 @@ public class DashboardController implements Initializable {
|
|||
}
|
||||
|
||||
@FXML
|
||||
private void sendAction() {
|
||||
private void sendRequest() {
|
||||
promptLayer.setVisible(false);
|
||||
if (responseBox.getChildren().size() == 2) {
|
||||
responseBox.getChildren().remove(0);
|
||||
|
@ -148,7 +150,7 @@ public class DashboardController implements Initializable {
|
|||
}
|
||||
|
||||
GETRequest getRequest = new GETRequest(addressField.getText());
|
||||
getRequest.addHeaders(headerTabController.getHeaders());
|
||||
getRequest.setHeaders(headerTabController.getHeaders());
|
||||
requestManager.setRequest(getRequest);
|
||||
cancelButton.setOnAction(e -> requestManager.cancel());
|
||||
requestManager.setOnRunning(e -> {
|
||||
|
@ -200,7 +202,7 @@ public class DashboardController implements Initializable {
|
|||
DataDispatchRequest dataDispatchRequest =
|
||||
(DataDispatchRequest) bodyTabController.getBasicRequest(httpMethodBox.getValue());
|
||||
dataDispatchRequest.setTarget(addressField.getText());
|
||||
dataDispatchRequest.addHeaders(headerTabController.getHeaders());
|
||||
dataDispatchRequest.setHeaders(headerTabController.getHeaders());
|
||||
|
||||
requestManager.setRequest(dataDispatchRequest);
|
||||
cancelButton.setOnAction(e -> requestManager.cancel());
|
||||
|
@ -250,7 +252,7 @@ public class DashboardController implements Initializable {
|
|||
}
|
||||
|
||||
DELETERequest deleteRequest = new DELETERequest(addressField.getText());
|
||||
deleteRequest.addHeaders(headerTabController.getHeaders());
|
||||
deleteRequest.setHeaders(headerTabController.getHeaders());
|
||||
requestManager.setRequest(deleteRequest);
|
||||
cancelButton.setOnAction(e -> requestManager.cancel());
|
||||
requestManager.setOnRunning(e -> {
|
||||
|
@ -312,7 +314,7 @@ public class DashboardController implements Initializable {
|
|||
responseSize.setText(Integer.toString(response.getSize()) + " B");
|
||||
}
|
||||
|
||||
private void applySettings() {
|
||||
private void applyDashboardSettings() {
|
||||
String responseAreaCSS = "-fx-font-family: " + Settings.responseAreaFont + ";" +
|
||||
"-fx-font-size: " + Settings.responseAreaFontSize;
|
||||
responseArea.setStyle(responseAreaCSS);
|
||||
|
@ -342,7 +344,7 @@ public class DashboardController implements Initializable {
|
|||
}
|
||||
|
||||
@FXML
|
||||
private void addParam() {
|
||||
private void addParamField() {
|
||||
try {
|
||||
FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/homewindow/StringKeyValueField.fxml"));
|
||||
Parent headerField = loader.load();
|
||||
|
@ -357,4 +359,35 @@ public class DashboardController implements Initializable {
|
|||
public StringProperty getAddressProperty() {
|
||||
return addressField.textProperty();
|
||||
}
|
||||
|
||||
// Returns the current state of the Dashboard
|
||||
public RestaurantRequest getState() {
|
||||
try {
|
||||
switch (httpMethodBox.getValue()) {
|
||||
case "GET":
|
||||
GETRequest getRequest = new GETRequest(addressField.getText());
|
||||
getRequest.setHeaders(headerTabController.getHeaders());
|
||||
return getRequest;
|
||||
case "POST":
|
||||
case "PUT":
|
||||
DataDispatchRequest dataDispatchRequest = bodyTabController.getBasicRequest(httpMethodBox.getValue());
|
||||
dataDispatchRequest.setHeaders(headerTabController.getHeaders());
|
||||
return dataDispatchRequest;
|
||||
case "DELETE":
|
||||
DELETERequest deleteRequest = new DELETERequest(addressField.getText());
|
||||
deleteRequest.setHeaders(headerTabController.getHeaders());
|
||||
return deleteRequest;
|
||||
}
|
||||
} catch (MalformedURLException MURLE) {
|
||||
System.out.println("Dashboard state was saved with a malformed URL.");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void setState(RestaurantRequest request) {
|
||||
addressField.setText(request.getTarget().toString());
|
||||
|
||||
for (Map.Entry entry : request.getHeaders().entrySet())
|
||||
headerTabController.addHeader(entry.getKey().toString(), entry.getValue().toString());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,12 +43,29 @@ public class HeaderTabController implements Initializable {
|
|||
}
|
||||
|
||||
@FXML
|
||||
private void addHeader() {
|
||||
public void addHeader(String key, String value) {
|
||||
/*
|
||||
Re-uses previous field if it is empty,
|
||||
else loads a new one.
|
||||
*/
|
||||
if (controllers.size() > 0) {
|
||||
StringKeyValueFieldController previousController = controllers.get(controllers.size() - 1);
|
||||
|
||||
if (previousController.isKeyFieldEmtpy() &&
|
||||
previousController.isValueFieldEmpty()) {
|
||||
previousController.setKeyField(key);
|
||||
previousController.setValueField(value);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/homewindow/StringKeyValueField.fxml"));
|
||||
Parent headerField = loader.load();
|
||||
ThemeManager.setTheme(headerField);
|
||||
StringKeyValueFieldController controller = loader.getController();
|
||||
controller.setKeyField(key);
|
||||
controller.setValueField(value);
|
||||
controllers.add(controller);
|
||||
headersBox.getChildren().add(headerField);
|
||||
} catch (IOException e) {
|
||||
|
@ -56,6 +73,10 @@ public class HeaderTabController implements Initializable {
|
|||
}
|
||||
}
|
||||
|
||||
public void addHeader() {
|
||||
addHeader("", "");
|
||||
}
|
||||
|
||||
public HashMap<String, String> getHeaders() {
|
||||
HashMap<String, String> headers = new HashMap<>();
|
||||
for (StringKeyValueFieldController controller : controllers) {
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
package com.rohitawate.restaurant.homewindow;
|
||||
|
||||
import com.rohitawate.restaurant.models.requests.RestaurantRequest;
|
||||
import javafx.application.Platform;
|
||||
import javafx.beans.binding.Bindings;
|
||||
import javafx.fxml.FXML;
|
||||
|
@ -28,9 +29,12 @@ import javafx.scene.control.TabPane;
|
|||
import javafx.scene.input.KeyCode;
|
||||
import javafx.scene.input.KeyCodeCombination;
|
||||
import javafx.scene.input.KeyCombination;
|
||||
import javafx.stage.Stage;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.*;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
public class HomeWindowController implements Initializable {
|
||||
|
@ -38,25 +42,35 @@ public class HomeWindowController implements Initializable {
|
|||
private TabPane homeWindowTabPane;
|
||||
|
||||
private KeyCombination newTab = new KeyCodeCombination(KeyCode.T, KeyCombination.CONTROL_DOWN);
|
||||
private List<DashboardController> controllers;
|
||||
|
||||
@Override
|
||||
public void initialize(URL location, ResourceBundle resources) {
|
||||
addTab();
|
||||
controllers = new ArrayList<>();
|
||||
recoverState();
|
||||
Platform.runLater(() -> {
|
||||
Scene thisScene = homeWindowTabPane.getScene();
|
||||
thisScene.setOnKeyPressed(e -> {
|
||||
if (newTab.match(e))
|
||||
addTab();
|
||||
});
|
||||
Stage thisStage = (Stage) thisScene.getWindow();
|
||||
thisStage.setOnCloseRequest(e -> saveState());
|
||||
});
|
||||
}
|
||||
|
||||
private void addTab() {
|
||||
addTab(null);
|
||||
}
|
||||
|
||||
private void addTab(RestaurantRequest request) {
|
||||
try {
|
||||
Tab newTab = new Tab();
|
||||
FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/homewindow/Dashboard.fxml"));
|
||||
Parent dashboard = loader.load();
|
||||
DashboardController controller = loader.getController();
|
||||
if (request != null)
|
||||
controller.setState(request);
|
||||
newTab.setContent(dashboard);
|
||||
newTab.textProperty().bind(Bindings
|
||||
.when(controller.getAddressProperty().isNotEmpty())
|
||||
|
@ -65,10 +79,61 @@ public class HomeWindowController implements Initializable {
|
|||
newTab.setOnCloseRequest(e -> {
|
||||
if (homeWindowTabPane.getTabs().size() == 1)
|
||||
addTab();
|
||||
controllers.remove(controller);
|
||||
});
|
||||
homeWindowTabPane.getTabs().add(newTab);
|
||||
controllers.add(controller);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void saveState() {
|
||||
List<RestaurantRequest> states = new ArrayList<>();
|
||||
|
||||
// Get the states of all the tabs
|
||||
for (DashboardController controller : controllers)
|
||||
states.add(controller.getState());
|
||||
|
||||
try {
|
||||
File configFolder = new File("config/");
|
||||
if (!configFolder.exists())
|
||||
configFolder.mkdir();
|
||||
|
||||
OutputStream fileStream = new FileOutputStream("config/restaurant.state");
|
||||
ObjectOutputStream objectStream = new ObjectOutputStream(fileStream);
|
||||
objectStream.writeObject(states);
|
||||
objectStream.close();
|
||||
System.out.println("Application state saved successfully.");
|
||||
} catch (IOException e) {
|
||||
System.out.println("Failed to save the application's state:");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void recoverState() {
|
||||
try {
|
||||
InputStream fileStream = new FileInputStream("config/restaurant.state");
|
||||
ObjectInputStream objectStream = new ObjectInputStream(fileStream);
|
||||
|
||||
System.out.print("Application state file found. Recovering state... ");
|
||||
|
||||
List<RestaurantRequest> states = (List<RestaurantRequest>) objectStream.readObject();
|
||||
|
||||
if (states.size() > 0) {
|
||||
for (RestaurantRequest request : states)
|
||||
addTab(request);
|
||||
} else {
|
||||
addTab();
|
||||
}
|
||||
} catch (FileNotFoundException e) {
|
||||
System.out.print("Application state file not found. Loading default state... ");
|
||||
addTab();
|
||||
} catch (IOException | ClassNotFoundException e) {
|
||||
System.out.print("Application state file is possibly corrupted. Could not recover the state.\nLoading default state... ");
|
||||
addTab();
|
||||
} finally {
|
||||
System.out.println("Successful");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,4 +72,20 @@ public class StringKeyValueFieldController implements Initializable {
|
|||
public boolean isChecked() {
|
||||
return checkBox.isSelected();
|
||||
}
|
||||
|
||||
public void setKeyField(String key) {
|
||||
keyField.setText(key);
|
||||
}
|
||||
|
||||
public void setValueField(String value) {
|
||||
valueField.setText(value);
|
||||
}
|
||||
|
||||
public boolean isKeyFieldEmtpy() {
|
||||
return keyField.getText().isEmpty();
|
||||
}
|
||||
|
||||
public boolean isValueFieldEmpty() {
|
||||
return valueField.getText().isEmpty();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,11 +16,12 @@
|
|||
|
||||
package com.rohitawate.restaurant.models.requests;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
|
||||
public abstract class RestaurantRequest {
|
||||
public abstract class RestaurantRequest implements Serializable {
|
||||
URL target;
|
||||
private HashMap<String, String> headers;
|
||||
|
||||
|
@ -43,7 +44,7 @@ public abstract class RestaurantRequest {
|
|||
headers.put(key, value);
|
||||
}
|
||||
|
||||
public void addHeaders(HashMap<String, String> headers) {
|
||||
public void setHeaders(HashMap<String, String> headers) {
|
||||
this.headers = headers;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@ import com.rohitawate.restaurant.models.requests.GETRequest;
|
|||
import com.rohitawate.restaurant.models.requests.RestaurantRequest;
|
||||
import com.rohitawate.restaurant.util.json.JSONUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.sql.*;
|
||||
import java.time.LocalDate;
|
||||
|
@ -36,7 +37,11 @@ public class HistoryManager {
|
|||
|
||||
public HistoryManager() {
|
||||
try {
|
||||
conn = DriverManager.getConnection("jdbc:sqlite:history.sqlite");
|
||||
File configFolder = new File("config/");
|
||||
if (!configFolder.exists())
|
||||
configFolder.mkdir();
|
||||
|
||||
conn = DriverManager.getConnection("jdbc:sqlite:config/history.sqlite");
|
||||
|
||||
// Read all queries from Queries.json
|
||||
InputStream queriesFile = getClass().getResourceAsStream("/sql/Queries.json");
|
||||
|
|
|
@ -21,6 +21,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
|
|||
import com.rohitawate.restaurant.util.json.JSONUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
|
||||
/**
|
||||
* Loads up custom values into Settings from settings.json.
|
||||
|
@ -36,7 +37,12 @@ public class SettingsLoader implements Runnable {
|
|||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
File settingsFile = new File("settings.json");
|
||||
File settingsFile = new File("config/settings.json");
|
||||
|
||||
if (settingsFile.exists())
|
||||
System.out.print("Settings file found. Loading settings... ");
|
||||
else
|
||||
throw new FileNotFoundException();
|
||||
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
JsonNode nodes = mapper.readTree(settingsFile);
|
||||
|
@ -54,9 +60,9 @@ public class SettingsLoader implements Runnable {
|
|||
|
||||
Settings.theme = JSONUtils.trimString(nodes.get("theme").toString());
|
||||
} catch (Exception E) {
|
||||
System.out.println("Settings file not found. Loading default values...");
|
||||
System.out.print("Settings file not found. Loading default values... ");
|
||||
} finally {
|
||||
System.out.println("Settings loaded.");
|
||||
System.out.println("Successful");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
<Insets right="20.0" />
|
||||
</HBox.margin>
|
||||
</ComboBox>
|
||||
<JFXButton fx:id="sendButton" buttonType="RAISED" defaultButton="true" onAction="#sendAction"
|
||||
<JFXButton fx:id="sendButton" buttonType="RAISED" defaultButton="true" onAction="#sendRequest"
|
||||
prefHeight="39.0" prefWidth="100.0" text=" SEND" textFill="WHITE" HBox.hgrow="ALWAYS">
|
||||
<padding>
|
||||
<Insets bottom="5.0" left="15.0" right="15.0" top="5.0" />
|
||||
|
@ -91,7 +91,7 @@
|
|||
<Insets/>
|
||||
</VBox.margin>
|
||||
<children>
|
||||
<JFXButton fx:id="newParamButton" onAction="#addParam"
|
||||
<JFXButton fx:id="newParamButton" onAction="#addParamField"
|
||||
text=" NEW PARAM" textFill="WHITE"
|
||||
HBox.hgrow="ALWAYS">
|
||||
<graphic>
|
||||
|
|
Loading…
Reference in a new issue