Add basic tab switching

This commit is contained in:
Rohit Awate 2018-07-17 13:20:17 +05:30
parent 5f85f83696
commit 8cea5f006a
No known key found for this signature in database
GPG key ID: 1051D7B79CF2EE25
8 changed files with 192 additions and 88 deletions

View file

@ -156,14 +156,18 @@ public class BodyTabController implements Initializable {
public void setState(ComposerState state) {
// Adding URL tab's tuples
if (state.urlStringTuples != null)
if (state.urlStringTuples != null) {
urlTabController.clear();
for (FieldState fieldState : state.urlStringTuples)
urlTabController.addField(fieldState);
}
// Adding Form tab's string tuples
if (state.formStringTuples != null)
formDataTabController.clear();
if (state.formStringTuples != null) {
for (FieldState fieldState : state.formStringTuples)
formDataTabController.addStringField(fieldState);
}
// Adding Form tab's file tuples
if (state.formFileTuples != null)
@ -171,7 +175,6 @@ public class BodyTabController implements Initializable {
formDataTabController.addFileField(fieldState);
setRawTab(state);
filePathField.setText(state.binaryFilePath);
}

View file

@ -22,6 +22,7 @@ import com.jfoenix.controls.JFXSnackbar;
import com.rohitawate.everest.controllers.codearea.EverestCodeArea;
import com.rohitawate.everest.controllers.codearea.EverestCodeArea.HighlightMode;
import com.rohitawate.everest.controllers.state.ComposerState;
import com.rohitawate.everest.controllers.state.DashboardState;
import com.rohitawate.everest.controllers.state.FieldState;
import com.rohitawate.everest.exceptions.RedirectException;
import com.rohitawate.everest.exceptions.UnreliableResponseException;
@ -314,7 +315,7 @@ public class DashboardController implements Initializable {
default:
loadingLayer.setVisible(false);
}
Services.historyManager.saveHistory(getState());
Services.historyManager.saveHistory(getState().composer);
} catch (MalformedURLException MURLE) {
promptLayer.setVisible(true);
snackbar.show("Invalid address. Please verify and try again.", 3000);
@ -401,38 +402,41 @@ public class DashboardController implements Initializable {
responseHeadersViewer.populate(response);
}
private void prettifyResponseBody(EverestResponse response) {
String type;
if (response.getMediaType() != null)
type = response.getMediaType().toString();
else
type = null;
String responseBody = response.getBody();
private void displayResponse(DashboardState state) {
prettifyResponseBody(state.responseBody, state.responseType);
responseBox.getChildren().remove(responseDetails);
responseBox.getChildren().add(0, responseDetails);
statusCode.setText(Integer.toString(state.statusCode));
statusCodeDescription.setText(Response.Status.fromStatusCode(state.statusCode).getReasonPhrase());
responseTime.setText(Long.toString(state.responseTime) + " ms");
responseSize.setText(Integer.toString(state.responseSize) + " B");
responseHeadersViewer.populate(state.responseHeaders);
}
private void prettifyResponseBody(String body, String contentType) {
visualizerTab.setDisable(true);
visualizer.clear();
try {
if (type != null) {
// Selects only the part preceding the ';', skipping the character encoding
type = type.split(";")[0];
switch (type.toLowerCase()) {
try {
if (contentType != null) {
// Selects only the part preceding the ';', skipping the character encoding
contentType = contentType.split(";")[0];
switch (contentType.toLowerCase()) {
case "application/json":
responseTypeBox.setValue("JSON");
JsonNode node = EverestUtilities.jsonMapper.readTree(responseBody);
JsonNode node = EverestUtilities.jsonMapper.readTree(body);
responseArea.setText(EverestUtilities.jsonMapper.writeValueAsString(node), HighlightMode.JSON);
visualizerTab.setDisable(false);
visualizer.populate(node);
break;
case "application/xml":
responseTypeBox.setValue("XML");
responseArea.setText(responseBody, HighlightMode.XML);
responseArea.setText(body, HighlightMode.XML);
break;
case "text/html":
responseTypeBox.setValue("HTML");
responseArea.setText(responseBody, HighlightMode.HTML);
responseArea.setText(body, HighlightMode.HTML);
if (Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
snackbar.show("Open link in browser?", "YES", 5000, e -> {
snackbar.close();
@ -448,7 +452,7 @@ public class DashboardController implements Initializable {
break;
default:
responseTypeBox.setValue("PLAIN TEXT");
responseArea.setText(responseBody, HighlightMode.PLAIN);
responseArea.setText(body, HighlightMode.PLAIN);
}
} else {
responseTypeBox.setValue("PLAIN");
@ -463,6 +467,20 @@ public class DashboardController implements Initializable {
}
}
private void prettifyResponseBody(EverestResponse response) {
String type;
if (response.getMediaType() != null)
type = response.getMediaType().toString();
else
type = "";
String responseBody = response.getBody();
prettifyResponseBody(responseBody, type);
}
@FXML
private void clearResponseArea() {
responseBox.getChildren().remove(0);
@ -557,8 +575,10 @@ public class DashboardController implements Initializable {
/**
* @return Current state of the Dashboard.
*/
public ComposerState getState() {
public DashboardState getState() {
DashboardState dashboardState = new DashboardState();
ComposerState composerState;
switch (httpMethodBox.getValue()) {
case "POST":
case "PUT":
@ -575,7 +595,26 @@ public class DashboardController implements Initializable {
composerState.headers = headerTabController.getFieldStates();
composerState.params = getParamFieldStates();
return composerState;
dashboardState.composer = composerState;
dashboardState.showResponse = responseArea.isVisible();
if (dashboardState.showResponse) {
dashboardState.responseHeaders = headerTabController.getHeaders();
dashboardState.statusCode = Integer.parseInt(statusCode.getText());
String temp = responseSize.getText();
temp = temp.substring(0, temp.length() - 2);
dashboardState.responseSize = Integer.parseInt(temp);
temp = responseTime.getText();
temp = temp.substring(0, temp.length() - 3);
dashboardState.responseTime = Integer.parseInt(temp);
dashboardState.responseBody = responseArea.getText();
dashboardState.responseType = responseTypeBox.getValue();
}
return dashboardState;
}
/**
@ -583,7 +622,14 @@ public class DashboardController implements Initializable {
*
* @param state - State of the dashboard
*/
public void setState(ComposerState state) {
public void setState(DashboardState state) {
if (state.showResponse) {
displayResponse(state);
}
if (state.composer == null)
return;
/*
The only value from a set of constants in the state.json file is the httpMethod
which, if manipulated to a non-standard value by the user, would still
@ -596,7 +642,7 @@ public class DashboardController implements Initializable {
*/
boolean validMethod = false;
for (String method : httpMethods) {
if (state.httpMethod.equals(method))
if (state.composer.httpMethod.equals(method))
validMethod = true;
}
@ -605,20 +651,35 @@ public class DashboardController implements Initializable {
return;
}
httpMethodBox.setValue(state.httpMethod);
httpMethodBox.setValue(state.composer.httpMethod);
if (state.target != null)
addressField.setText(state.target);
if (state.composer.target != null)
addressField.setText(state.composer.target);
if (state.headers != null)
for (FieldState fieldState : state.headers)
if (state.composer.headers != null) {
headerTabController.clear();
for (FieldState fieldState : state.composer.headers)
headerTabController.addHeader(fieldState);
}
if (state.params != null)
for (FieldState fieldState : state.params)
if (state.composer.params != null) {
clearParams();
for (FieldState fieldState : state.composer.params)
addParamField(fieldState);
}
if (!(httpMethodBox.getValue().equals("GET") || httpMethodBox.getValue().equals("DELETE")))
bodyTabController.setState(state);
bodyTabController.setState(state.composer);
}
void clearParams() {
if (params != null)
params.clear();
if (paramsControllers != null)
paramsControllers.clear();
paramsBox.getChildren().clear();
addParamField();
}
}

View file

@ -223,4 +223,22 @@ public class FormDataTabController implements Initializable {
return states;
}
void clear() {
if (stringMap != null)
stringMap.clear();
if (fileMap != null)
fileMap.clear();
if (stringControllers != null)
stringControllers.clear();
if (fileControllers != null)
fileControllers.clear();
fieldsBox.getChildren().clear();
addStringField();
addFileField();
}
}

View file

@ -134,4 +134,14 @@ public class HeaderTabController implements Initializable {
return states;
}
void clear() {
if (headers != null)
headers.clear();
if (controllers != null)
controllers.clear();
headersBox.getChildren().clear();
addHeader();
}
}

View file

@ -18,6 +18,7 @@ package com.rohitawate.everest.controllers;
import com.fasterxml.jackson.core.type.TypeReference;
import com.rohitawate.everest.controllers.state.ComposerState;
import com.rohitawate.everest.controllers.state.DashboardState;
import com.rohitawate.everest.misc.EverestUtilities;
import com.rohitawate.everest.misc.KeyMap;
import com.rohitawate.everest.misc.Services;
@ -25,6 +26,7 @@ import com.rohitawate.everest.misc.ThemeManager;
import javafx.application.Platform;
import javafx.beans.binding.Bindings;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ObservableValue;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
@ -58,7 +60,7 @@ public class HomeWindowController implements Initializable {
@FXML
private VBox tabDashboardBox;
private HashMap<Tab, DashboardController> tabControllerMap;
private HashMap<Tab, DashboardState> tabStateMap;
private DashboardController dashboard;
@Override
@ -73,7 +75,7 @@ public class HomeWindowController implements Initializable {
}
// Using LinkedHashMap because they retain order
tabControllerMap = new LinkedHashMap<>();
tabStateMap = new LinkedHashMap<>();
recoverState();
historyPaneController.addItemClickHandler(this::addTab);
@ -87,6 +89,16 @@ public class HomeWindowController implements Initializable {
Stage thisStage = (Stage) homeWindowSP.getScene().getWindow();
thisStage.setOnCloseRequest(e -> saveState());
});
homeWindowTabPane.getSelectionModel().selectedItemProperty().addListener(this::onTabSwitched);
}
private void onTabSwitched(ObservableValue<? extends Tab> obs, Tab prevTab, Tab newTab) {
DashboardState dashboardState = dashboard.getState();
tabStateMap.replace(prevTab, dashboardState);
dashboardState = tabStateMap.get(newTab);
dashboard.setState(dashboardState);
}
private void setGlobalShortcuts() {
@ -96,14 +108,11 @@ public class HomeWindowController implements Initializable {
if (KeyMap.newTab.match(e)) {
addTab();
} else if (KeyMap.focusAddressBar.match(e)) {
Tab activeTab = getActiveTab();
tabControllerMap.get(activeTab).addressField.requestFocus();
dashboard.addressField.requestFocus();
} else if (KeyMap.focusMethodBox.match(e)) {
Tab activeTab = getActiveTab();
tabControllerMap.get(activeTab).httpMethodBox.show();
dashboard.httpMethodBox.show();
} else if (KeyMap.sendRequest.match(e)) {
Tab activeTab = getActiveTab();
tabControllerMap.get(activeTab).sendRequest();
dashboard.sendRequest();
} else if (KeyMap.toggleHistory.match(e)) {
toggleHistoryPane();
} else if (KeyMap.closeTab.match(e)) {
@ -111,27 +120,19 @@ public class HomeWindowController implements Initializable {
if (homeWindowTabPane.getTabs().size() == 1)
addTab();
homeWindowTabPane.getTabs().remove(activeTab);
tabControllerMap.remove(activeTab);
tabStateMap.remove(activeTab);
} else if (KeyMap.searchHistory.match(e)) {
historyPaneController.focusSearchField();
} else if (KeyMap.focusParams.match(e)) {
Tab activeTab = getActiveTab();
DashboardController controller = tabControllerMap.get(activeTab);
controller.requestOptionsTab.getSelectionModel().select(controller.paramsTab);
dashboard.requestOptionsTab.getSelectionModel().select(dashboard.paramsTab);
} else if (KeyMap.focusAuth.match(e)) {
Tab activeTab = getActiveTab();
DashboardController controller = tabControllerMap.get(activeTab);
controller.requestOptionsTab.getSelectionModel().select(controller.authTab);
dashboard.requestOptionsTab.getSelectionModel().select(dashboard.authTab);
} else if (KeyMap.focusHeaders.match(e)) {
Tab activeTab = getActiveTab();
DashboardController controller = tabControllerMap.get(activeTab);
controller.requestOptionsTab.getSelectionModel().select(controller.headersTab);
dashboard.requestOptionsTab.getSelectionModel().select(dashboard.headersTab);
} else if (KeyMap.focusBody.match(e)) {
Tab activeTab = getActiveTab();
DashboardController controller = tabControllerMap.get(activeTab);
String httpMethod = controller.httpMethodBox.getValue();
String httpMethod = dashboard.httpMethodBox.getValue();
if (!httpMethod.equals("GET") && !httpMethod.equals("DELETE")) {
controller.requestOptionsTab.getSelectionModel().select(controller.bodyTab);
dashboard.requestOptionsTab.getSelectionModel().select(dashboard.bodyTab);
}
} else if (KeyMap.refreshTheme.match(e)) {
ThemeManager.refreshTheme();
@ -152,45 +153,26 @@ public class HomeWindowController implements Initializable {
}
private void addTab(ComposerState composerState) {
try {
Tab newTab = new Tab();
FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/homewindow/Dashboard.fxml"));
Parent dashboard = loader.load();
DashboardController controller = loader.getController();
Tab newTab = new Tab();
homeWindowTabPane.getTabs().add(newTab);
if (composerState != null)
controller.setState(composerState);
StringProperty addressProperty = dashboard.addressField.textProperty();
newTab.textProperty().bind(
Bindings.when(addressProperty.isNotEmpty())
.then(addressProperty)
.otherwise("New Tab"));
newTab.setContent(dashboard);
// Binds the addressField text to the Tab text
StringProperty addressProperty = controller.addressField.textProperty();
newTab.textProperty().bind(
Bindings.when(addressProperty.isNotEmpty())
.then(addressProperty)
.otherwise("New Tab"));
// Tab closing procedure
newTab.setOnCloseRequest(e -> {
if (homeWindowTabPane.getTabs().size() == 1)
addTab();
tabControllerMap.remove(newTab);
});
homeWindowTabPane.getTabs().add(newTab);
homeWindowTabPane.getSelectionModel().select(newTab);
tabControllerMap.put(newTab, controller);
} catch (IOException e) {
Services.loggingService.logSevere("Could not add a new tab.", e, LocalDateTime.now());
}
DashboardState dashboardState = new DashboardState();
dashboardState.composer = composerState;
tabStateMap.put(newTab, dashboardState);
}
private void saveState() {
ArrayList<ComposerState> composerStates = new ArrayList<>();
// Get the states of all the tabs
for (DashboardController controller : tabControllerMap.values())
composerStates.add(controller.getState());
for (DashboardState dashboardState : tabStateMap.values())
composerStates.add(dashboardState.composer);
try {
File stateFile = new File("Everest/config/state.json");

View file

@ -23,8 +23,12 @@ import javafx.scene.control.ScrollPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javax.ws.rs.core.MultivaluedHashMap;
import java.util.HashMap;
class ResponseHeadersViewer extends ScrollPane {
private VBox container;
private MultivaluedHashMap<String, String> map;
ResponseHeadersViewer() {
this.container = new VBox();
@ -33,12 +37,26 @@ class ResponseHeadersViewer extends ScrollPane {
this.setFitToHeight(true);
this.setFitToWidth(true);
map = new MultivaluedHashMap<>();
}
void populate(HashMap<String, String> headers) {
map.clear();
headers.forEach((key, value) -> map.putSingle(key, value));
populate();
}
void populate(EverestResponse response) {
map.clear();
map = (MultivaluedHashMap<String, String>) response.getHeaders();
populate();
}
private void populate() {
container.getChildren().clear();
response.getHeaders().forEach((key, value) -> {
map.forEach((key, value) -> {
Label keyLabel = new Label(key + ": ");
keyLabel.getStyleClass().addAll("visualizerKeyLabel", "visualizerLabel");
@ -47,5 +65,6 @@ class ResponseHeadersViewer extends ScrollPane {
container.getChildren().add(new HBox(keyLabel, valueLabel));
});
}
}

View file

@ -135,4 +135,14 @@ public class URLTabController implements Initializable {
return states;
}
void clear() {
if (tuples != null)
tuples.clear();
if (controllers != null)
controllers.clear();
fieldsBox.getChildren().clear();
addField();
}
}

View file

@ -23,6 +23,7 @@ public class DashboardState {
public boolean showResponse;
public int statusCode;
public String responseType;
public String responseBody;
public int responseTime;
public int responseSize;
public HashMap<String, String> responseHeaders;