优化代码结构

This commit is contained in:
peng
2021-11-11 20:53:02 +08:00
parent 113cb63d62
commit db2341a23d
50 changed files with 1286 additions and 1110 deletions

View File

@@ -0,0 +1,35 @@
package com.dayrain.component;
import com.dayrain.utils.FileUtils;
/**
* 配置类句柄
* @author peng
* @date 2021/11/8
*/
public class ConfigHolder {
private static Configuration configuration;
private ConfigHolder() {
}
public synchronized static Configuration init() {
configuration = FileUtils.load();
return configuration;
}
public synchronized static void save() {
FileUtils.saveConfig(configuration);
}
public synchronized static Configuration get() {
if(configuration == null) {
init();
}
return configuration;
}
public synchronized static void replace(Configuration config) {
configuration = config;
}
}

View File

@@ -0,0 +1,92 @@
package com.dayrain.component;
import java.util.List;
/**
* 配置文件
* @author peng
* @date 2021/11/8
*/
public class Configuration {
private String projectName = "HTTP SERVER 模拟器 V1.4";
private int width;
private int height;
private int stringLen;
private int intLen;
private List<ServerConfig> serverConfigs;
public Configuration() {
}
public Configuration(int width, int height, int stringLen, int intLen) {
this.width = width;
this.height = height;
this.stringLen = stringLen;
this.intLen = intLen;
}
public String getProjectName() {
return projectName;
}
public void setProjectName(String projectName) {
this.projectName = projectName;
}
public List<ServerConfig> getServerConfigs() {
return serverConfigs;
}
public void setServerConfigs(List<ServerConfig> serverConfigs) {
this.serverConfigs = serverConfigs;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public int getStringLen() {
return stringLen;
}
public void setStringLen(int stringLen) {
this.stringLen = stringLen;
}
public int getIntLen() {
return intLen;
}
public void setIntLen(int intLen) {
this.intLen = intLen;
}
@Override
public String toString() {
return "Configuration{" +
"projectName='" + projectName + '\'' +
", width=" + width +
", height=" + height +
", stringLen=" + stringLen +
", intLen=" + intLen +
", serverConfigs=" + serverConfigs +
'}';
}
}

View File

@@ -0,0 +1,79 @@
package com.dayrain.component;
import com.dayrain.views.LogArea;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
/**
* 请求日志打印
* @author peng
* @date 2021/11/8
*/
public class ConsoleLog {
private static final HashMap<String, String> logs = new HashMap<>();
private static final String NO_REQUEST = "暂无请求";
private static LogArea logArea;
public static void initTextArea(LogArea area) {
logArea = area;
}
public synchronized static void log(ServerUrl serverUrl, String params, String resp) {
String log = logs.getOrDefault(serverUrl.getServerName(), null);
if (log == null || NO_REQUEST.equals(log)) {
log = "";
}
if (params == null || "".equals(params)) {
params = "";
}
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("[").append(now()).append("]");
stringBuilder.append(serverUrl.getUrlName()).append(" ");
stringBuilder.append(serverUrl.getUrl()).append(" ").append(serverUrl.getRequestType().name()).append("\n");
stringBuilder.append("参数: ").append("\n");
stringBuilder.append(params).append("\n");
stringBuilder.append("返回值: ").append("\n");
stringBuilder.append(resp);
stringBuilder.append("\n\n");
log += stringBuilder.toString();
if(log.length() > 5000) {
log = log.substring(log.length() - 5000);
System.out.println(log.length());
}
logs.put(serverUrl.getServerName(), log);
if (serverUrl.getServerName().equals(logArea.getServerName())) {
if (NO_REQUEST.equals(logArea.getText())) {
logArea.setText(log);
} else {
logArea.setText("");
logArea.appendText(log);
}
logArea.setScrollTop(Double.MAX_VALUE);
}
}
public synchronized static void resetTextArea(String serverName) {
if (!logs.containsKey(serverName)) {
logs.put(serverName, NO_REQUEST);
}
logArea.setServerName(serverName);
logArea.setText(logs.get(serverName));
logArea.appendText("");
logArea.setScrollTop(Double.MAX_VALUE);
}
private static String now() {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-DD-mm HH:mm:ss");
return simpleDateFormat.format(new Date());
}
}

View File

@@ -0,0 +1,102 @@
package com.dayrain.component;
import com.dayrain.utils.FileUtils;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.UUID;
/**
* 请求处理
* @author peng
* @date 2021/11/8
*/
public class RequestHandler implements HttpHandler {
private static final String STRING_PATTERN = "$string$";
private static final String INT_PATTERN = "$int$";
private final ServerUrl serverUrl;
public RequestHandler(ServerUrl serverUrl) {
this.serverUrl = serverUrl;
}
@Override
public void handle(HttpExchange exchange) {
RequestType requestType = serverUrl.getRequestType();
String param = null;
if (RequestType.GET.equals(requestType)) {
param = handleGetRequest(exchange);
}
if (RequestType.POST.equals(requestType)) {
param = handlePostRequest(exchange);
}
String resp = replaceResp(serverUrl.getResponseBody());
ConsoleLog.log(serverUrl, param, resp);
response(exchange, resp);
}
private String handleGetRequest(HttpExchange exchange) {
return exchange.getRequestURI().getQuery();
}
private String handlePostRequest(HttpExchange exchange) {
return FileUtils.getFromInputStream(exchange.getRequestBody());
}
private void response(HttpExchange exchange, String jsonBody) {
try {
byte[] bytes = jsonBody.getBytes(StandardCharsets.UTF_8);
exchange.sendResponseHeaders(200, bytes.length);
exchange.setAttribute("Content-Type", "application/json; charset=utf-8");
OutputStream outputStream = exchange.getResponseBody();
outputStream.write(jsonBody.getBytes(StandardCharsets.UTF_8));
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private String replaceResp(String resp) {
if (resp == null || "".equals(resp)) {
return resp;
}
Configuration configuration = ConfigHolder.get();
int stringLen = configuration.getStringLen();
int intLen = configuration.getIntLen();
while (resp.contains(STRING_PATTERN)) {
resp = resp.replace(STRING_PATTERN, randomString(stringLen));
}
while (resp.contains(INT_PATTERN)) {
resp = resp.replace(INT_PATTERN, String.valueOf(randomInt(intLen)));
}
return resp;
}
private String randomString(int len) {
String res = UUID.randomUUID().toString();
if (len > res.length()) {
len = res.length();
}
return UUID.randomUUID().toString().substring(0, len);
}
private int randomInt(int len) {
int res = (int) Math.pow(10, len - 1);
return res + (int) (Math.pow(10, len - 1) * Math.random());
}
}

View File

@@ -0,0 +1,9 @@
package com.dayrain.component;
/**
* 请求方式
* @author peng
* @date 2021/11/8
*/
public enum RequestType {
GET, POST
}

View File

@@ -0,0 +1,76 @@
package com.dayrain.component;
import com.sun.net.httpserver.HttpServer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
/**
* 服务
* @author peng
* @date 2021/10/25
*/
public class Server implements Runnable {
private static final Logger logger = LoggerFactory.getLogger(Server.class);
private final ServerConfig serverConfig;
private HttpServer httpServer;
public Server(ServerConfig serverConfig) {
this.serverConfig = serverConfig;
}
@Override
public void run() {
start();
System.out.println("" + serverConfig.getServerName() + "】服务已开启...");
}
public synchronized void start() {
try {
this.httpServer = HttpServer.create(new InetSocketAddress(serverConfig.getPort()), 0);
httpServer.setExecutor(Executors.newCachedThreadPool());
for (ServerUrl serverUrl : serverConfig.getServerUrls()) {
addContext(serverUrl);
}
httpServer.start();
} catch (IOException e) {
e.printStackTrace();
logger.error(e.getMessage());
}
}
public synchronized void stop() {
if (httpServer != null) {
System.out.println("" + serverConfig.getServerName() + "】服务已关闭...");
httpServer.stop(0);
}
}
public synchronized void restart() {
stop();
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
start();
}
public synchronized void addContext(ServerUrl serverUrl) {
httpServer.createContext(serverUrl.getUrl(), new RequestHandler(serverUrl));
}
public void removeContext(String url) {
httpServer.removeContext(url);
}
}

View File

@@ -0,0 +1,56 @@
package com.dayrain.component;
import java.util.List;
/**
* 服务配置
* @author peng
* @date 2021/11/8
*/
public class ServerConfig {
/**
* 服务名
*/
private String serverName;
/**
* 端口
*/
private int port;
/**
* 请求url集合
*/
private List<ServerUrl> serverUrls;
public ServerConfig() {
}
public ServerConfig(String serverName, int port, List<ServerUrl> serverUrls) {
this.serverName = serverName;
this.port = port;
this.serverUrls = serverUrls;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public String getServerName() {
return serverName;
}
public void setServerName(String serverName) {
this.serverName = serverName;
}
public List<ServerUrl> getServerUrls() {
return serverUrls;
}
public void setServerUrls(List<ServerUrl> serverUrls) {
this.serverUrls = serverUrls;
}
}

View File

@@ -0,0 +1,68 @@
package com.dayrain.component;
import com.dayrain.server.ServerThread;
import java.util.HashMap;
/**
* 正在运行的 server 线程组
* @author peng
* @date 2021/11/8
*/
public class ServerThreadHolder {
private static final HashMap<String, ServerThread> threadMap = new HashMap<>();
/**
* 停止所有线程
*/
public synchronized static void stopAll() {
if(threadMap.size() > 0) {
for (String serverName : threadMap.keySet()) {
ServerThread serverThread = threadMap.get(serverName);
serverThread.stopServer();
}
}
}
public synchronized static void add(String serverName, ServerThread serverThread) {
if(!threadMap.containsKey(serverName)) {
serverThread.start();
threadMap.put(serverName, serverThread);
}
}
public synchronized static void remove(String serverName) {
if(contains(serverName)) {
threadMap.get(serverName).stopServer();
threadMap.remove(serverName);
}
}
public synchronized static boolean contains(String key) {
return threadMap.containsKey(key);
}
public synchronized static void addUrl(ServerUrl serverUrl) {
if(serverUrl == null || !contains(serverUrl.getServerName())) {
return;
}
ServerThread serverThread = threadMap.get(serverUrl.getServerName());
serverThread.addContext(serverUrl);
}
public synchronized static void restart(String serverName) {
if(contains(serverName)) {
ServerThread serverThread = threadMap.get(serverName);
serverThread.restartServer();
}
}
public static void replaceUrl(String beforeName, String beforeUrl, ServerUrl serverUrl) {
if(contains(beforeName)) {
ServerThread serverThread = threadMap.get(beforeName);
serverThread.replaceUrl(beforeUrl, serverUrl);
}
}
}

View File

@@ -0,0 +1,94 @@
package com.dayrain.component;
import java.util.Map;
/**
* 请求路径
* @author peng
* @date 2021/11/8
*/
public class ServerUrl {
/**
* 路径名
*/
private String urlName;
/**
* 路径url
*/
private String url;
/**
* 服务名称
*/
private String serverName;
/**
* 请求类型
*/
private RequestType requestType;
/**
* 响应体
*/
private String responseBody;
/**
* 请求头
*/
private Map<String, String> headerMap;
public ServerUrl() {
}
public ServerUrl(String serverName, String urlName, String url, RequestType requestType, String responseBody) {
this.serverName = serverName;
this.urlName = urlName;
this.url = url;
this.requestType = requestType;
this.responseBody = responseBody;
}
public String getUrlName() {
return urlName;
}
public void setUrlName(String urlName) {
this.urlName = urlName;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public RequestType getRequestType() {
return requestType;
}
public void setRequestType(RequestType requestType) {
this.requestType = requestType;
}
public Map<String, String> getHeaderMap() {
return headerMap;
}
public void setHeaderMap(Map<String, String> headerMap) {
this.headerMap = headerMap;
}
public String getResponseBody() {
return responseBody;
}
public void setResponseBody(String responseBody) {
this.responseBody = responseBody;
}
public String getServerName() {
return serverName;
}
public void setServerName(String serverName) {
this.serverName = serverName;
}
}

View File

@@ -0,0 +1,35 @@
package com.dayrain.server;
import com.dayrain.component.Server;
import com.dayrain.component.ServerUrl;
public class ServerThread extends Thread {
private final Server server;
public ServerThread(Server server) {
super(server);
this.server = server;
}
public void stopServer() {
server.stop();
}
public void restartServer() {
server.restart();
}
public void addContext(ServerUrl serverUrl) {
server.addContext(serverUrl);
}
public void removeContext(String url) {
server.removeContext(url);
}
public void replaceUrl(String beforeUrl, ServerUrl serverUrl) {
removeContext(beforeUrl);
addContext(serverUrl);
}
}

View File

@@ -0,0 +1,15 @@
package com.dayrain.style;
import javafx.geometry.Insets;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.CornerRadii;
import javafx.scene.paint.Color;
public class BackGroundFactory {
public static Background getBackGround() {
BackgroundFill backgroundFill = new BackgroundFill(Color.GRAY, new CornerRadii(1),
new Insets(0.0, 0.0, 0.0, 0.0));
return new Background(backgroundFill);
}
}

View File

@@ -0,0 +1,26 @@
package com.dayrain.style;
import javafx.geometry.Insets;
import javafx.scene.control.Button;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.CornerRadii;
import javafx.scene.paint.Color;
import javafx.scene.paint.Paint;
import javafx.scene.text.Font;
public class ButtonFactory {
public static Button getButton(String text) {
BackgroundFill bgf = new BackgroundFill(Paint.valueOf("#145b7d"), new CornerRadii(10), new Insets(5));
Button button = new Button();
button.setText(text);
button.setPrefWidth(80);
button.setPrefHeight(50);
button.setFont(Font.font("Microsoft YaHei", 15));
button.setTextFill(Color.WHITE);
button.setBackground(new Background(bgf));
return button;
}
}

View File

@@ -0,0 +1,18 @@
package com.dayrain.style;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
/**
* 圆
* @author peng
* @date 2021/11/11
*/
public class CircleFactory {
public static Circle getLightCircle(Color color) {
Circle circle = new Circle();
circle.setRadius(10);
circle.setFill(color);
return circle;
}
}

View File

@@ -0,0 +1,30 @@
package com.dayrain.style;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.control.Control;
import javafx.scene.control.Label;
import javafx.scene.layout.HBox;
public class FormFactory {
public static HBox getLine(Label label, Control control, double labelWidth, double nodeWidth, double maxWidth) {
HBox hBox = new HBox();
label.setPrefWidth(labelWidth);
control.setPrefWidth(nodeWidth);
hBox.getChildren().addAll(label, control);
hBox.setAlignment(Pos.CENTER_LEFT);
hBox.setMaxWidth(maxWidth);
return hBox;
}
public static HBox getButtonLine(Button button, double labelWidth, double width) {
HBox hBox = new HBox();
Label label = LabelFactory.getLabel("");
label.setPrefWidth(labelWidth);
hBox.getChildren().addAll(label, button);
hBox.setAlignment(Pos.CENTER_RIGHT);
hBox.setMaxWidth(width);
return hBox;
}
}

View File

@@ -0,0 +1,10 @@
package com.dayrain.style;
import javafx.scene.image.Image;
public class IconFactory {
public static Image getIcon() {
return new Image("panda.png");
}
}

View File

@@ -0,0 +1,13 @@
package com.dayrain.style;
import javafx.scene.control.Label;
import javafx.scene.text.Font;
public class LabelFactory {
public static Label getLabel(String text) {
Label label = new Label(text);
label.setFont(Font.font("Microsoft YaHei", 15));
return label;
}
}

View File

@@ -0,0 +1,30 @@
package com.dayrain.style;
import com.dayrain.views.ViewHolder;
import javafx.scene.Scene;
import javafx.stage.Modality;
import javafx.stage.Stage;
/**
* 窗口
* @author peng
* @date 2021/11/11
*/
public class StageFactory {
/**
* 获取标准弹窗
* @author peng
* @date 2021/11/11
*/
public static Stage getPopStage(String name, Scene scene) {
Stage stage = new Stage();
stage.setTitle(name);
stage.setWidth(700);
stage.setHeight(500);
stage.initOwner(ViewHolder.getPrimaryStage());
stage.initModality(Modality.WINDOW_MODAL);
stage.getIcons().addAll(IconFactory.getIcon());
stage.setScene(scene);
return stage;
}
}

View File

@@ -0,0 +1,114 @@
package com.dayrain.utils;
import com.dayrain.component.Configuration;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;
public class FileUtils {
public static void saveConfig(Configuration configuration) {
saveConfig(configuration, getConfigFile());
}
public static void saveConfig(Configuration configuration, File file) {
BufferedWriter bufferedWriter = null;
try {
String config = new ObjectMapper().writerWithDefaultPrettyPrinter().writeValueAsString(configuration);
bufferedWriter = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8));
bufferedWriter.write(config);
bufferedWriter.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (bufferedWriter != null) {
bufferedWriter.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static Configuration load() {
return load(getConfigFile());
}
public static Configuration load(File file) {
BufferedReader bufferedReader = null;
try {
StringBuilder configStr = new StringBuilder();
bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8));
String buf;
while ((buf = bufferedReader.readLine()) != null) {
configStr.append(buf);
}
return "".equals(configStr.toString()) ? new Configuration(1400, 800, 8, 8) : new ObjectMapper().readValue(configStr.toString(), Configuration.class);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (bufferedReader != null) {
bufferedReader.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
public static String getFromInputStream(InputStream inputStream) {
try {
byte[] buf = new byte[4096];
int len;
StringBuilder stringBuilder = new StringBuilder();
while ((len = inputStream.read(buf)) != -1) {
stringBuilder.append(new String(buf, 0, len));
}
return stringBuilder.toString();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
private static File getConfigFile() {
String property = System.getProperty("user.dir");
File file = new File(property + File.separator + "config" + File.separator + "config.json");
if (!file.exists()) {
File dir = new File(property + File.separator + "config");
if (!dir.exists()) {
dir.mkdirs();
}
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
Configuration configuration = new Configuration(1200, 800, 8, 8);
saveConfig(configuration, file);
}
return file;
}
}

View File

@@ -0,0 +1,24 @@
package com.dayrain.utils;
import com.dayrain.component.ServerUrl;
import javafx.collections.ObservableList;
import javafx.scene.control.ListView;
public class ListViewHelper {
public static void addAndRefresh(ServerUrl serverUrl, ListView<ServerUrl> serverUrls) {
serverUrls.getItems().add(serverUrl);
refresh(serverUrls);
}
public static void deleteAndRefresh(ServerUrl serverUrl, ListView<ServerUrl> serverUrls) {
serverUrls.getItems().remove(serverUrl);
refresh(serverUrls);
}
public static void refresh(ListView<ServerUrl> serverUrls) {
ObservableList<ServerUrl> items = serverUrls.getItems();
serverUrls.setItems(null);
serverUrls.setItems(items);
}
}

View File

@@ -0,0 +1,32 @@
package com.dayrain.views;
import com.dayrain.component.ConfigHolder;
import javafx.application.Application;
import javafx.stage.Stage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 启动入口
* @author peng
* @date 2021/11/11
*/
public class ApplicationStarter extends Application {
private static final Logger logger = LoggerFactory.getLogger(ApplicationStarter.class);
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
try {
ConfigHolder.init();
ViewHolder.setPrimaryStage(primaryStage);
new HomeView().start();
}catch (Exception e) {
e.printStackTrace();
logger.error(e.getMessage());
}
}
}

View File

@@ -0,0 +1,85 @@
package com.dayrain.views;
import com.dayrain.component.ConfigHolder;
import com.dayrain.component.ConsoleLog;
import com.dayrain.component.ServerConfig;
import com.dayrain.component.ServerThreadHolder;
import com.dayrain.style.IconFactory;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.Scene;
import javafx.scene.control.SplitPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import java.util.ArrayList;
import java.util.List;
/**
* 主页
* @author peng
* @date 2021/11/11
*/
public class HomeView {
private final Stage primaryStage;
public HomeView() {
this.primaryStage = ViewHolder.getPrimaryStage();
}
/**
* 启动程序
*/
public void start() {
VBox vBox = new VBox();
//菜单栏
MenuBarView menuBar = new MenuBarView();
SplitPane splitPane = new SplitPane();
//日志
LogArea logArea = new LogArea();
ConsoleLog.initTextArea(logArea);
ViewHolder.setLogArea(logArea);
//server
ServerContainer serverContainer = initServer();
ViewHolder.setServerContainer(serverContainer);
splitPane.getItems().addAll(serverContainer, logArea);
splitPane.setDividerPositions(0.55f, 0.45f);
vBox.getChildren().addAll(menuBar, splitPane);
primaryStage.setTitle(ConfigHolder.get().getProjectName());
primaryStage.setScene(new Scene(vBox));
primaryStage.setWidth(ConfigHolder.get().getWidth());
primaryStage.setHeight(ConfigHolder.get().getHeight());
primaryStage.getIcons().add(IconFactory.getIcon());
primaryStage.show();
primaryStage.setOnCloseRequest(event -> {
ConfigHolder.save();
ServerThreadHolder.stopAll();
Platform.exit();
});
}
/**
* 初始化服务列表
* @return 服务的容器
*/
private ServerContainer initServer() {
List<ServerConfig> serverConfigs = ConfigHolder.get().getServerConfigs();
List<ServerPane>serverPanes = new ArrayList<>();
if(serverConfigs != null) {
for (ServerConfig serverConfig : serverConfigs) {
ServerPane serverPane = new ServerPane(serverConfig);
serverPanes.add(serverPane);
}
}
return new ServerContainer(serverPanes);
}
public void restart() {
//停止所有线程
ServerThreadHolder.stopAll();
start();
}
}

View File

@@ -0,0 +1,34 @@
package com.dayrain.views;
import com.dayrain.component.ConfigHolder;
import javafx.scene.control.TextArea;
import javafx.scene.text.Font;
/**
* 打印日志的组件
* 每个服务都有各自的组件
* @author peng
* @date 2021/11/8
*/
public class LogArea extends TextArea {
private String serverName;
public LogArea() {
createView();
}
public void createView() {
this.setEditable(false);
this.setFont(Font.font("Microsoft YaHei", 16));
this.setPrefWidth(582);
this.setPrefHeight(ConfigHolder.get().getHeight());
}
public String getServerName() {
return serverName;
}
public void setServerName(String serverName) {
this.serverName = serverName;
}
}

View File

@@ -0,0 +1,210 @@
package com.dayrain.views;
import com.dayrain.component.ConfigHolder;
import com.dayrain.component.Configuration;
import com.dayrain.component.ServerConfig;
import com.dayrain.style.BackGroundFactory;
import com.dayrain.style.ButtonFactory;
import com.dayrain.style.LabelFactory;
import com.dayrain.style.StageFactory;
import com.dayrain.utils.FileUtils;
import javafx.event.ActionEvent;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.Menu;
import javafx.scene.control.MenuBar;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TextField;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.awt.Desktop;
import java.io.File;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
/**
* 菜单栏
* @author peng
* @date 2021/11/11
*/
public class MenuBarView extends MenuBar {
private static final Logger logger = LoggerFactory.getLogger(MenuBarView.class);
private final Menu menu1 = new Menu("文件");
private final Menu menu2 = new Menu("设置");
private final Menu menu3 = new Menu("帮助");
public MenuBarView() {
creatView();
}
private void creatView() {
MenuItem menuItem11 = new MenuItem("新建");
MenuItem menuItem12 = new MenuItem("导入");
MenuItem menuItem13 = new MenuItem("导出");
menu1.getItems().addAll(menuItem11, menuItem12, menuItem13);
menuItem11.setOnAction(this::addServer);
menuItem12.setOnAction(this::importConfig);
menuItem13.setOnAction(this::exportConfig);
MenuItem menuItem21 = new MenuItem("随机值长度");
menu2.getItems().addAll(menuItem21);
menuItem21.setOnAction(this::updateRandomLength);
MenuItem menuItem31 = new MenuItem("说明书");
MenuItem menuItem32 = new MenuItem("源码地址");
menu3.getItems().addAll(menuItem31, menuItem32);
menuItem31.setOnAction(this::linkIntroduce);
menuItem32.setOnAction(this::linkGithub);
this.setBackground(BackGroundFactory.getBackGround());
this.getMenus().addAll(menu1, menu2, menu3);
}
public void updateRandomLength(ActionEvent evt) {
Configuration configuration = ConfigHolder.get();
Label strName = LabelFactory.getLabel("随机字符长度:");
strName.setPrefWidth(150);
TextField strField = new TextField(String.valueOf(configuration.getStringLen()));
Label intName = LabelFactory.getLabel("随机整数长度:");
javafx.scene.control.TextField intField = new TextField(String.valueOf(configuration.getIntLen()));
intField.setPrefWidth(150);
HBox btnHBox = new HBox();
Label saveTips1 = LabelFactory.getLabel("注: $string$代指随机字符串");
Label saveTips2 = LabelFactory.getLabel("$int$代指随机整数");
Button saveButton = ButtonFactory.getButton("保存");
btnHBox.getChildren().addAll(saveButton);
btnHBox.setAlignment(Pos.CENTER_RIGHT);
btnHBox.setSpacing(20d);
GridPane gridPane = new GridPane();
gridPane.add(strName, 0, 0);
gridPane.add(strField, 1, 0);
gridPane.add(intName, 0, 1);
gridPane.add(intField, 1, 1);
gridPane.add(saveTips1, 0, 3);
gridPane.add(saveTips2, 1, 3);
gridPane.add(btnHBox, 1, 4);
gridPane.setAlignment(Pos.CENTER);
gridPane.setHgap(20d);
gridPane.setVgap(10d);
Stage stage = StageFactory.getPopStage("更改随机值配置", new Scene(gridPane));
stage.show();
saveButton.setOnAction(event -> {
String strLen = strField.getText();
String intLen = intField.getText();
configuration.setStringLen(Integer.parseInt(strLen));
configuration.setIntLen(Integer.parseInt(intLen));
ConfigHolder.save();
stage.close();
});
}
public void exportConfig(ActionEvent evt) {
Stage stage = new Stage();
stage.initOwner(ViewHolder.getPrimaryStage());
FileChooser fileChooser = new FileChooser();
String projectName = ConfigHolder.get().getProjectName();
if (projectName == null) {
projectName = "";
}
projectName += "server";
fileChooser.setTitle("导出配置");
fileChooser.setInitialFileName(projectName + ".json");
File file = fileChooser.showSaveDialog(stage);
if (file != null) {
FileUtils.saveConfig(ConfigHolder.get(), file);
}
}
private void importConfig(ActionEvent evt) {
Stage stage = new Stage();
stage.initOwner(ViewHolder.getPrimaryStage());
FileChooser fileChooser = new FileChooser();
fileChooser.setTitle("选择一个文件");
//过滤器
fileChooser.getExtensionFilters().addAll(new FileChooser.ExtensionFilter("只能导入json文件", "*.json"));
File file = fileChooser.showOpenDialog(stage);
if (file != null) {
Configuration loadConfig = FileUtils.load(file);
ConfigHolder.replace(loadConfig);
FileUtils.saveConfig(loadConfig);
ConfigHolder.replace(loadConfig);
ViewHolder.getHomeView().restart();
}
}
/**
* 添加服务
*/
private void addServer(ActionEvent evt) {
Label nameLabel = LabelFactory.getLabel("服务名称:");
nameLabel.setPrefWidth(80);
javafx.scene.control.TextField nameField = new javafx.scene.control.TextField();
javafx.scene.control.Label portLabel = LabelFactory.getLabel("端口号:");
javafx.scene.control.TextField portField = new javafx.scene.control.TextField();
portField.setPrefWidth(80);
HBox btnHBox = new HBox();
Button saveButton = ButtonFactory.getButton("保存");
btnHBox.getChildren().add(saveButton);
btnHBox.setAlignment(Pos.CENTER_RIGHT);
GridPane gridPane = new GridPane();
gridPane.add(nameLabel, 0, 0);
gridPane.add(nameField, 1, 0);
gridPane.add(portLabel, 0, 1);
gridPane.add(portField, 1, 1);
gridPane.add(btnHBox, 1, 3);
gridPane.setAlignment(Pos.CENTER);
gridPane.setHgap(20d);
gridPane.setVgap(10d);
Stage stage = StageFactory.getPopStage("添加服务", new Scene(gridPane));
stage.show();
saveButton.setOnAction(event -> {
String name = nameField.getText();
String port = portField.getText();
ServerConfig serverConfig = new ServerConfig(name, Integer.parseInt(port), new ArrayList<>());
ConfigHolder.get().getServerConfigs().add(serverConfig);
ViewHolder.getServerContainer().refresh();
ConfigHolder.save();
stage.close();
});
}
private void linkGithub(ActionEvent evt) {
try {
Desktop.getDesktop().browse(new URI("https://github.com/DayRain/http-server-simulator"));
} catch (IOException | URISyntaxException e) {
logger.error("跳转到github时发生了错误: {}", e.getMessage());
e.printStackTrace();
}
}
private void linkIntroduce(ActionEvent evt){
try {
Desktop.getDesktop().browse(new URI("https://blog.csdn.net/qq_37855749/article/details/121030800"));
} catch (IOException | URISyntaxException e) {
logger.error("跳转到csdn时发生了错误: {}", e.getMessage());
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,28 @@
package com.dayrain.views;
import javafx.scene.layout.VBox;
import java.util.List;
/**
* server容器
* @author peng
* @date 2021/11/11
*/
public class ServerContainer extends VBox {
private List<ServerPane> serverPanes;
public ServerContainer(List<ServerPane> serverPanes) {
this.serverPanes = serverPanes;
createView();
}
public void createView() {
getChildren().addAll(serverPanes);
}
public void refresh() {
getChildren().removeAll();
getChildren().addAll(serverPanes);
}
}

View File

@@ -0,0 +1,239 @@
package com.dayrain.views;
import com.dayrain.component.ConfigHolder;
import com.dayrain.component.ConsoleLog;
import com.dayrain.component.RequestType;
import com.dayrain.component.Server;
import com.dayrain.component.ServerConfig;
import com.dayrain.component.ServerThreadHolder;
import com.dayrain.component.ServerUrl;
import com.dayrain.server.ServerThread;
import com.dayrain.style.BackGroundFactory;
import com.dayrain.style.ButtonFactory;
import com.dayrain.style.CircleFactory;
import com.dayrain.style.FormFactory;
import com.dayrain.style.IconFactory;
import com.dayrain.style.LabelFactory;
import com.dayrain.style.StageFactory;
import com.dayrain.utils.ListViewHelper;
import javafx.collections.FXCollections;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonType;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.control.TitledPane;
import javafx.scene.image.ImageView;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.text.Font;
import javafx.stage.Modality;
import javafx.stage.Stage;
import java.util.List;
/**
* server容器
* @author peng
* @date 2021/11/11
*/
public class ServerPane extends TitledPane {
private final ServerConfig serverConfig;
private ServerUrlListView serverUrlListView;
private final Circle statusCircle;
private final Button editButton;
private final Button openButton;
private final Button deleteButton;
private final Button addButton;
public ServerPane(ServerConfig serverConfig) {
this.serverConfig = serverConfig;
this.statusCircle = CircleFactory.getLightCircle(ServerThreadHolder.contains(serverConfig.getServerName()) ? Color.GREEN : Color.RED);
this.editButton = ButtonFactory.getButton("修改配置");
this.openButton = ButtonFactory.getButton("开启服务");
this.deleteButton = ButtonFactory.getButton("删除服务");
this.addButton = ButtonFactory.getButton("添加接口");
createView();
}
public void createView() {
VBox vBox = new VBox();
HBox headBox = new HBox();
//设置服务启动与关闭
openButton.setOnAction(this::startServer);
editButton.setOnAction(this::updateServer);
deleteButton.setOnAction(this::deleteSever);
headBox.getChildren().addAll(openButton, editButton, deleteButton, addButton, statusCircle);
HBox.setMargin(statusCircle, new Insets(0, 0, 0, 30));
headBox.setSpacing(20d);
headBox.setAlignment(Pos.CENTER);
//添加url
this.serverUrlListView = new ServerUrlListView(serverConfig);
addButton.setOnAction(this::addUrl);
vBox.getChildren().addAll(headBox, serverUrlListView);
vBox.setSpacing(10d);
VBox.setMargin(headBox, new Insets(10, 0, 0, 0));
vBox.setPadding(Insets.EMPTY);
setText(serverConfig.getServerName());
this.setContent(vBox);
this.setFont(Font.font("Microsoft YaHei", 18));
this.setPrefWidth(600d);
this.setExpanded(false);
this.setBackground(BackGroundFactory.getBackGround());
this.setOnMouseClicked(event -> {
if (!serverConfig.getServerName().equals(ViewHolder.getLogArea().getServerName())) {
ConsoleLog.resetTextArea(serverConfig.getServerName());
}
});
HBox hBox = new HBox();
hBox.setPrefHeight(60d);
this.setGraphic(hBox);
}
/**
* 启动服务
*/
private void startServer(ActionEvent evt) {
String serverName = serverConfig.getServerName();
if (ServerThreadHolder.contains(serverName)) {
ServerThreadHolder.remove(serverName);
openButton.setText("开启服务");
statusCircle.setFill(Color.RED);
} else {
ServerThreadHolder.add(serverName, new ServerThread(new Server(serverConfig)));
openButton.setText("关闭服务");
statusCircle.setFill(Color.GREEN);
}
}
/**
* 更新服务
*/
private void updateServer(ActionEvent evt) {
Label serverName = LabelFactory.getLabel("服务名称:");
serverName.setPrefWidth(80);
TextField nameField = new TextField(serverConfig.getServerName());
Label portLabel = LabelFactory.getLabel("端口:");
TextField portField = new TextField(String.valueOf(serverConfig.getPort()));
portField.setPrefWidth(80);
HBox btnHBox = new HBox();
Label saveTips = LabelFactory.getLabel("重启后生效");
Button saveButton = ButtonFactory.getButton("保存");
btnHBox.getChildren().addAll(saveTips, saveButton);
btnHBox.setAlignment(Pos.CENTER_RIGHT);
btnHBox.setSpacing(20d);
GridPane gridPane = new GridPane();
gridPane.add(serverName, 0, 0);
gridPane.add(nameField, 1, 0);
gridPane.add(portLabel, 0, 1);
gridPane.add(portField, 1, 1);
gridPane.add(btnHBox, 1, 3);
gridPane.setAlignment(Pos.CENTER);
gridPane.setHgap(20d);
gridPane.setVgap(10d);
Stage stage = StageFactory.getPopStage("更新服务配置", new Scene(gridPane));
stage.show();
saveButton.setOnAction(event -> {
String name = nameField.getText();
int port = Integer.parseInt(portField.getText());
serverConfig.setPort(port);
serverConfig.setServerName(name);
ConfigHolder.save();
stage.close();
});
}
/**
* 删除服务
*/
private void deleteSever(ActionEvent evt) {
Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
alert.setGraphic(new ImageView(IconFactory.getIcon()));
Stage stage = (Stage) alert.getDialogPane().getScene().getWindow();
stage.getIcons().add(IconFactory.getIcon());
alert.setHeaderText("是否确定删除该服务?");
Button okButton = (Button) alert.getDialogPane().lookupButton(ButtonType.OK);
okButton.setOnAction(event1 -> {
ConfigHolder.get().getServerConfigs().remove(serverConfig);
ViewHolder.getServerContainer().refresh();
ConfigHolder.save();
});
alert.show();
}
private void addUrl(ActionEvent evt) {
VBox vBox = new VBox();
Label nameLabel = LabelFactory.getLabel("接口名称:");
TextField nameField = new TextField();
HBox hBox1 = FormFactory.getLine(nameLabel, nameField, 120, 300, 500);
Label urlLabel = LabelFactory.getLabel("接口地址:");
TextField urlField = new TextField();
HBox hBox2 = FormFactory.getLine(urlLabel, urlField, 120, 300, 500);
Label typeLabel = LabelFactory.getLabel("请求方式:");
ChoiceBox<String> choiceBox = new ChoiceBox<>();
choiceBox.setItems(FXCollections.observableArrayList("POST", "GET"));
choiceBox.setValue("POST");
HBox hBox3 = FormFactory.getLine(typeLabel, choiceBox, 120, 70, 500);
Label respLabel = LabelFactory.getLabel("返回结果:");
TextArea textArea = new TextArea();
HBox hBox4 = FormFactory.getLine(respLabel, textArea, 120, 300, 500);
Button saveButton = ButtonFactory.getButton("保存");
HBox hBox5 = FormFactory.getButtonLine(saveButton, 120, 500);
vBox.getChildren().addAll(hBox1, hBox2, hBox3, hBox4, hBox5);
vBox.setSpacing(20d);
vBox.setAlignment(Pos.CENTER);
Stage stage = StageFactory.getPopStage("新增接口信息", new Scene(vBox));
stage.show();
saveButton.setOnAction(event1 -> {
String name = nameField.getText();
List<ServerUrl> serverUrls = serverConfig.getServerUrls();
for (ServerUrl serverUrl : serverUrls) {
if (serverUrl.getUrlName().equals(name)) {
return;
}
}
String url = urlField.getText();
String resp = textArea.getText();
String type = choiceBox.getValue();
ServerUrl serverUrl = new ServerUrl(serverConfig.getServerName(), name, url, type.equals(RequestType.POST.name()) ? RequestType.POST : RequestType.GET, resp);
serverUrls.add(serverUrl);
ServerThreadHolder.addUrl(serverUrl);
ListViewHelper.addAndRefresh(serverUrl, serverUrlListView);
ConfigHolder.save();
stage.close();
});
}
}

View File

@@ -0,0 +1,54 @@
package com.dayrain.views;
import com.dayrain.component.ServerConfig;
import com.dayrain.component.ServerUrl;
import javafx.beans.binding.Bindings;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.stage.Stage;
import javafx.util.Callback;
/**
* server 列表
* @author peng
* @date 2021/11/11
*/
public class ServerUrlListView extends ListView<ServerUrl> {
private ServerConfig serverConfig;
public ServerUrlListView(ServerConfig serverConfig) {
this.serverConfig = serverConfig;
createView();
}
private void createView() {
ObservableList<ServerUrl> urlList = FXCollections.observableArrayList(serverConfig.getServerUrls());
setItems(urlList);
this.setCellFactory(new Callback<ListView<ServerUrl>, ListCell<ServerUrl>>() {
@Override
public ListCell<ServerUrl> call(ListView<ServerUrl> param) {
return new ListCell<ServerUrl>() {
@Override
protected void updateItem(ServerUrl item, boolean empty) {
super.updateItem(item, empty);
if (empty || item == null) {
setText(null);
setGraphic(null);
} else {
ServerUrlPaneView urlPane = new ServerUrlPaneView(item, serverConfig, ServerUrlListView.this);
this.setGraphic(urlPane);
}
}
};
}
});
this.prefHeightProperty().bind(Bindings.size(urlList).multiply(60));
this.setFocusTraversable(false);
}
}

View File

@@ -0,0 +1,156 @@
package com.dayrain.views;
import com.dayrain.component.ConfigHolder;
import com.dayrain.component.RequestType;
import com.dayrain.component.ServerConfig;
import com.dayrain.component.ServerThreadHolder;
import com.dayrain.component.ServerUrl;
import com.dayrain.style.ButtonFactory;
import com.dayrain.style.FormFactory;
import com.dayrain.style.IconFactory;
import com.dayrain.style.LabelFactory;
import com.dayrain.style.StageFactory;
import com.dayrain.utils.ListViewHelper;
import javafx.collections.FXCollections;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonType;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.image.ImageView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import java.util.List;
/**
* url面板
* @author peng
* @date 2021/11/11
*/
public class ServerUrlPaneView extends BorderPane {
private final ServerUrl serverUrl;
private final ServerConfig serverConfig;
private final ListView<ServerUrl> serverListViews;
public ServerUrlPaneView(ServerUrl serverUrl, ServerConfig serverConfig, ListView<ServerUrl> serverListViews) {
this.serverUrl = serverUrl;
this.serverConfig = serverConfig;
this.serverListViews = serverListViews;
createView();
}
public void createView() {
HBox labelBox = new HBox();
Label nameLabel = LabelFactory.getLabel(serverUrl.getUrlName());
nameLabel.setPrefWidth(180d);
nameLabel.setMaxWidth(180d);
Label typeLabel = LabelFactory.getLabel(serverUrl.getRequestType().name());
typeLabel.setPrefWidth(65d);
Label urlLabel = LabelFactory.getLabel(serverUrl.getUrl());
urlLabel.setMaxWidth(220d);
labelBox.getChildren().addAll(nameLabel, typeLabel, urlLabel);
labelBox.setAlignment(Pos.CENTER_LEFT);
HBox btnBox = new HBox();
Button configButton = ButtonFactory.getButton("配置");
Button deleteButton = ButtonFactory.getButton("删除");
btnBox.setSpacing(10d);
btnBox.getChildren().addAll(configButton, deleteButton);
HBox.setMargin(deleteButton, new Insets(0, 5, 0, 0));
deleteButton.setOnAction(this::deleteUrl);
configButton.setOnAction(this::updateUrl);
this.setLeft(labelBox);
this.setRight(btnBox);
}
private void deleteUrl(ActionEvent event) {
Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
alert.setGraphic(new ImageView(IconFactory.getIcon()));
Stage stage = (Stage) alert.getDialogPane().getScene().getWindow();
stage.getIcons().add(IconFactory.getIcon());
alert.setHeaderText("是否确定删除该接口?");
Button okButton = (Button) alert.getDialogPane().lookupButton(ButtonType.OK);
okButton.setOnAction(event1 -> {
List<ServerUrl> serverUrls = serverConfig.getServerUrls();
serverUrls.remove(serverUrl);
ConfigHolder.save();
ListViewHelper.deleteAndRefresh(serverUrl, serverListViews);
});
alert.show();
}
private void updateUrl(ActionEvent event) {
VBox vBox = new VBox();
Label nameLabel = LabelFactory.getLabel("接口名称:");
TextField nameField = new TextField(serverUrl.getUrlName());
HBox hBox1 = FormFactory.getLine(nameLabel, nameField, 120, 300, 500);
Label urlLabel = LabelFactory.getLabel("接口地址:");
TextField urlField = new TextField(serverUrl.getUrl());
HBox hBox2 = FormFactory.getLine(urlLabel, urlField, 120, 300, 500);
Label typeLabel = LabelFactory.getLabel("请求方式:");
ChoiceBox<String> choiceBox = new ChoiceBox<>();
choiceBox.setItems(FXCollections.observableArrayList("POST", "GET"));
choiceBox.setValue(serverUrl.getRequestType().name());
HBox hBox3 = FormFactory.getLine(typeLabel, choiceBox, 120, 70, 500);
Label respLabel = LabelFactory.getLabel("返回结果:");
TextArea textArea = new TextArea(serverUrl.getResponseBody());
HBox hBox4 = FormFactory.getLine(respLabel, textArea, 120, 300, 500);
Button saveButton = ButtonFactory.getButton("保存");
HBox hBox5 = FormFactory.getButtonLine(saveButton, 120, 500);
vBox.getChildren().addAll(hBox1, hBox2, hBox3, hBox4, hBox5);
vBox.setSpacing(20d);
vBox.setAlignment(Pos.CENTER);
Stage stage = StageFactory.getPopStage("更新接口信息", new Scene(vBox));
stage.show();
saveButton.setOnAction(event1 -> {
String name = nameField.getText();
String url = urlField.getText();
String resp = textArea.getText();
String type = choiceBox.getValue();
if(url == null) {
return;
}
if(!url.startsWith("/")) {
url = "/" + url;
}
String beforeUrl = serverUrl.getUrl();
serverUrl.setUrlName(name);
serverUrl.setUrl(url);
serverUrl.setResponseBody(resp);
serverUrl.setRequestType(type.equals(RequestType.POST.name()) ? RequestType.POST : RequestType.GET);
ListViewHelper.refresh(serverListViews);
ConfigHolder.save();
ServerThreadHolder.replaceUrl(serverUrl.getServerName(), beforeUrl, serverUrl);
stage.close();
});
}
}

View File

@@ -0,0 +1,50 @@
package com.dayrain.views;
import javafx.stage.Stage;
/**
* 主要视图的句柄
* @author peng
* @date 2021/11/11
*/
public class ViewHolder {
private static Stage primaryStage;
private static LogArea logArea;
private static ServerContainer serverContainer;
private static HomeView homeView;
static void setPrimaryStage(Stage primaryStage) {
ViewHolder.primaryStage = primaryStage;
}
public static Stage getPrimaryStage() {
return primaryStage;
}
static void setLogArea(LogArea logArea) {
ViewHolder.logArea = logArea;
}
public static LogArea getLogArea() {
return logArea;
}
public static ServerContainer getServerContainer() {
return serverContainer;
}
static void setServerContainer(ServerContainer serverContainer) {
ViewHolder.serverContainer = serverContainer;
}
static void setHomePage(HomeView homeView) {
ViewHolder.homeView = homeView;
}
public static HomeView getHomeView() {
return ViewHolder.homeView;
}
}