From 624ad5d229e94fd2e6bfc032c26d617a819c86bc Mon Sep 17 00:00:00 2001 From: agubin Date: Fri, 3 Jul 2020 10:28:52 +0300 Subject: [PATCH 1/2] 1st commit --- work/Clients/NetworkClients.jar | Bin 0 -> 12855 bytes work/Clients/src/Clients/AphorismClient.java | 19 + work/Clients/src/Clients/Client.java | 67 ++++ work/Clients/src/Clients/ClientModule.java | 95 +++++ work/Clients/src/Clients/InfoClient.java | 22 ++ work/Clients/src/Clients/NoticeModule.java | 33 ++ work/Clients/src/Clients/TimeClient.java | 19 + work/Clients/src/META-INF/MANIFEST.MF | 3 + work/Clients/src/sample/Controller.java | 230 ++++++++++++ work/Clients/src/sample/Main.java | 23 ++ work/Clients/src/sample/sample.fxml | 353 ++++++++++++++++++ work/Servers/NetworkServers.jar | Bin 0 -> 41910 bytes work/Servers/src/META-INF/MANIFEST.MF | 3 + work/Servers/src/notes.JSON | 36 ++ work/Servers/src/sample/Controller.java | 152 ++++++++ work/Servers/src/sample/Main.java | 23 ++ work/Servers/src/sample/sample.fxml | 174 +++++++++ work/Servers/src/srvs/Account.java | 37 ++ work/Servers/src/srvs/AphorismModule.java | 93 +++++ work/Servers/src/srvs/IOconnection.java | 39 ++ work/Servers/src/srvs/InfoModule.java | 71 ++++ work/Servers/src/srvs/NoticeModule.java | 157 ++++++++ work/Servers/src/srvs/Server.java | 78 ++++ work/Servers/src/srvs/TimeModule.java | 40 ++ work/Servers/src/wisdom.txt | 164 ++++++++ ...1\202\320\260\320\271\321\202\320\265.txt" | 12 + 26 files changed, 1943 insertions(+) create mode 100644 work/Clients/NetworkClients.jar create mode 100644 work/Clients/src/Clients/AphorismClient.java create mode 100644 work/Clients/src/Clients/Client.java create mode 100644 work/Clients/src/Clients/ClientModule.java create mode 100644 work/Clients/src/Clients/InfoClient.java create mode 100644 work/Clients/src/Clients/NoticeModule.java create mode 100644 work/Clients/src/Clients/TimeClient.java create mode 100644 work/Clients/src/META-INF/MANIFEST.MF create mode 100644 work/Clients/src/sample/Controller.java create mode 100644 work/Clients/src/sample/Main.java create mode 100644 work/Clients/src/sample/sample.fxml create mode 100644 work/Servers/NetworkServers.jar create mode 100644 work/Servers/src/META-INF/MANIFEST.MF create mode 100644 work/Servers/src/notes.JSON create mode 100644 work/Servers/src/sample/Controller.java create mode 100644 work/Servers/src/sample/Main.java create mode 100644 work/Servers/src/sample/sample.fxml create mode 100644 work/Servers/src/srvs/Account.java create mode 100644 work/Servers/src/srvs/AphorismModule.java create mode 100644 work/Servers/src/srvs/IOconnection.java create mode 100644 work/Servers/src/srvs/InfoModule.java create mode 100644 work/Servers/src/srvs/NoticeModule.java create mode 100644 work/Servers/src/srvs/Server.java create mode 100644 work/Servers/src/srvs/TimeModule.java create mode 100644 work/Servers/src/wisdom.txt create mode 100644 "work/\320\237\320\276\320\266\320\260\320\273\321\203\320\271\321\201\321\202\320\260 \320\277\321\200\320\276\321\207\320\270\321\202\320\260\320\271\321\202\320\265.txt" diff --git a/work/Clients/NetworkClients.jar b/work/Clients/NetworkClients.jar new file mode 100644 index 0000000000000000000000000000000000000000..3fb3f4abbc0c583fa0210d35f2e98b890d4e3d08 GIT binary patch literal 12855 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 literal 0 HcmV?d00001 diff --git a/work/Clients/src/Clients/AphorismClient.java b/work/Clients/src/Clients/AphorismClient.java new file mode 100644 index 0000000..0cca22e --- /dev/null +++ b/work/Clients/src/Clients/AphorismClient.java @@ -0,0 +1,19 @@ +package Clients; + +import javafx.scene.control.TextArea; +import javafx.scene.control.TextField; + +public class AphorismClient extends ClientModule { + + public AphorismClient(TextArea ta_Resp, TextArea ta_Logs) { + super(ta_Resp, ta_Logs); + } + public AphorismClient(TextArea ta_Resp, TextArea ta_Logs, TextField tf_request) { + super(ta_Resp, ta_Logs, tf_request); + } + + @Override + public void write() { + out.println("get"); + } +} diff --git a/work/Clients/src/Clients/Client.java b/work/Clients/src/Clients/Client.java new file mode 100644 index 0000000..537d87f --- /dev/null +++ b/work/Clients/src/Clients/Client.java @@ -0,0 +1,67 @@ +package Clients; + +import java.io.IOException; +import java.net.Socket; + +public class Client extends Thread { + + private Socket server; + private ClientModule module; + + private Client(String host, int port, ClientModule module) { + setDaemon(true); + this.module = module; + try { + server = new Socket(host, port); + module.printLog("Connection established"); + } catch (IOException ex) { + module.printLog("Connecting failed"); + } + } + + public static Client getInstance(String host, int port, ClientModule module) { + return new Client(host, port, module); + } + public String getDialog() { + return module.getDialog(); + } + public void setSelected(boolean state) { + module.setSelected(state); + } + + @Override + public String toString() { + return module.toString(); + } + + public void close() { + try { + if (server != null) + server.close(); + module.printLog("Client disconnected successfully"); + } catch (IOException ex) { + module.printLog("Client terminating failed"); + } + } + + @Override + public void run() { + try{ + module.workWith(server); + } catch (IOException ex) { + module.printLog("Input / Output closing failed"); + } finally { + close(); + } + } + + public void sendRequest() { + module.printLog("send request to server"); + module.write(); + } + public void disconnect() { + module.printLog("send disconnecting command"); + module.write(module.getDisconnectCmd()); + module.go = false; + } +} diff --git a/work/Clients/src/Clients/ClientModule.java b/work/Clients/src/Clients/ClientModule.java new file mode 100644 index 0000000..5dae85e --- /dev/null +++ b/work/Clients/src/Clients/ClientModule.java @@ -0,0 +1,95 @@ +package Clients; + +import javafx.scene.control.TextArea; +import javafx.scene.control.TextField; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.net.Socket; + +public abstract class ClientModule { + //stores dialog with server + StringBuilder dialog = new StringBuilder(); + //indicates if the client is selected in the list of clients + boolean selected = false; + //terminate tool + public volatile boolean go = true; + public TextArea taResp; + public TextArea taLogs; + public TextField tfRequest; + public BufferedReader in; + public PrintWriter out; + private String disconnectCmd = "exit"; + + public ClientModule(TextArea ta_Resp, TextArea ta_Logs) { + taResp = ta_Resp; + taLogs = ta_Logs; + } + public ClientModule(TextArea ta_Resp, TextArea ta_Logs, TextField tf_request) { + taResp = ta_Resp; + taLogs = ta_Logs; + tfRequest = tf_request; + } + + public String getDialog() { + return dialog.toString(); + } + public void setSelected(boolean state) { + selected = state; + } + + public String getDisconnectCmd() { + return disconnectCmd; + } + + public void printLog(String log) { + taLogs.appendText(log + "\n"); + } + public void printResp(String response) { + taResp.setText(response); + } + public void workWith(Socket server) throws IOException { + try { + in = new BufferedReader(new InputStreamReader(server.getInputStream())); + out = new PrintWriter(server.getOutputStream(), true); + printLog("in/out streams opened"); + listen(); + } catch (IOException ex) { + printLog("Input / Output opening failed"); + } finally { + in.close(); + out.close(); + printLog("in/out streams closed"); + } + } + + public void write() { + out.println(tfRequest.getText()); + tfRequest.clear(); + } + public void write(String command) { + out.println(command); + } + + + public void listen() { + Thread listener = new Thread(() -> { + String input = ""; + while (!input.equalsIgnoreCase("exit")) { + printResp(input); + try { + input = in.readLine(); + } catch (IOException ex) { + printLog("input reading failed"); + break; + } + printLog("Server response : " + input); + } + }); + listener.setDaemon(true); + listener.start(); + while (go && listener.isAlive()) Thread.onSpinWait(); + } +} diff --git a/work/Clients/src/Clients/InfoClient.java b/work/Clients/src/Clients/InfoClient.java new file mode 100644 index 0000000..99ed475 --- /dev/null +++ b/work/Clients/src/Clients/InfoClient.java @@ -0,0 +1,22 @@ +package Clients; + +import javafx.scene.control.TextArea; +import javafx.scene.control.TextField; + +public class InfoClient extends ClientModule { + + public InfoClient(TextArea ta_Resp, TextArea ta_Logs) { + super(ta_Resp, ta_Logs); + } + + public InfoClient(TextArea ta_Resp, TextArea ta_Logs, TextField tf_request) { + super(ta_Resp, ta_Logs, tf_request); + } + + @Override + public void printResp(String response) { + taResp.clear(); + for (String line : response.split("\\|")) + taResp.appendText(line + "\n"); + } +} diff --git a/work/Clients/src/Clients/NoticeModule.java b/work/Clients/src/Clients/NoticeModule.java new file mode 100644 index 0000000..a6c102f --- /dev/null +++ b/work/Clients/src/Clients/NoticeModule.java @@ -0,0 +1,33 @@ +package Clients; + +import javafx.scene.control.TextArea; +import javafx.scene.control.TextField; + +public class NoticeModule extends ClientModule { + private static int numOfClients = 0; + private int index; + + public NoticeModule(TextArea ta_Resp, TextArea ta_Logs) { + super(ta_Resp, ta_Logs); + numOfClients++; + index = numOfClients; + } + + public NoticeModule(TextArea ta_Resp, TextArea ta_Logs, TextField tf_request) { + super(ta_Resp, ta_Logs, tf_request); + numOfClients++; + index = numOfClients; + } + + @Override + public void printResp(String response) { + dialog.append(response).append("\n"); + if (selected) + taResp.appendText(response + "\n"); + } + + @Override + public String toString() { + return "Listener#" + index; + } +} diff --git a/work/Clients/src/Clients/TimeClient.java b/work/Clients/src/Clients/TimeClient.java new file mode 100644 index 0000000..ae15ec2 --- /dev/null +++ b/work/Clients/src/Clients/TimeClient.java @@ -0,0 +1,19 @@ +package Clients; + +import javafx.scene.control.TextArea; +import javafx.scene.control.TextField; + +public class TimeClient extends ClientModule { + + public TimeClient(TextArea ta_Resp, TextArea ta_Logs) { + super(ta_Resp, ta_Logs); + } + public TimeClient(TextArea ta_Resp, TextArea ta_Logs, TextField tf_request) { + super(ta_Resp, ta_Logs, tf_request); + } + + @Override + public void write() { + out.println("get"); + } +} diff --git a/work/Clients/src/META-INF/MANIFEST.MF b/work/Clients/src/META-INF/MANIFEST.MF new file mode 100644 index 0000000..440fa71 --- /dev/null +++ b/work/Clients/src/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: sample.Main + diff --git a/work/Clients/src/sample/Controller.java b/work/Clients/src/sample/Controller.java new file mode 100644 index 0000000..db85be9 --- /dev/null +++ b/work/Clients/src/sample/Controller.java @@ -0,0 +1,230 @@ +package sample; + +import Clients.*; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.fxml.FXML; +import javafx.fxml.Initializable; +import javafx.scene.control.Button; +import javafx.scene.control.ListView; +import javafx.scene.control.TextArea; +import javafx.scene.control.TextField; + +import java.net.URL; +import java.util.ResourceBundle; + +public class Controller implements Initializable { + + Client timeClient; + + Client aphClient; + + Client notClient; + @FXML + ListView listeners; + ObservableList data; + + Client infoClient; + + + @FXML + TextField tfHost_timeCl; + @FXML + TextField tfPort_timeCl; + @FXML + TextArea taResp_timeCl; + @FXML + TextArea taLogs_timeCl; + @FXML + Button btnCon_timeCl; + @FXML + Button btnDisCon_timeCl; + @FXML + Button btnReq_timeCl; + + @FXML + TextField tfHost_aphCl; + @FXML + TextField tfPort_aphCl; + @FXML + TextArea taResp_aphCl; + @FXML + TextArea taLogs_aphCl; + @FXML + Button btnCon_aphCl; + @FXML + Button btnDisCon_aphCl; + @FXML + Button btnReq_aphCl; + + @FXML + TextField tfHost_notCl; + @FXML + TextField tfPort_notCl; + @FXML + TextField tfReq_notCl; + @FXML + TextArea taResp_notCl; + @FXML + TextArea taLogs_notCl; + @FXML + Button btnCon_notCl; + @FXML + Button btnDisCon_notCl; + @FXML + Button btnReq_notCl; + + @FXML + TextField tfHost_infoCl; + @FXML + TextField tfPort_infoCl; + @FXML + TextField tfReq_infoCl; + @FXML + TextArea taResp_infoCl; + @FXML + TextArea taLogs_infoCl; + @FXML + Button btnCon_infoCl; + @FXML + Button btnDisCon_infoCl; + @FXML + Button btnReq_infoCl; + + Thread buttonsState; + + @Override + public void initialize(URL url, ResourceBundle resourceBundle) { + tfPort_timeCl.setText("1201"); + tfHost_timeCl.setText("localhost"); + tfPort_aphCl.setText("1202"); + tfHost_aphCl.setText("localhost"); + tfPort_notCl.setText("1203"); + tfHost_notCl.setText("localhost"); + tfPort_infoCl.setText("1204"); + tfHost_infoCl.setText("localhost"); + + data = FXCollections.observableArrayList(); + listeners.setItems(data); + //show dialog of the elected client + listeners.getSelectionModel().selectedItemProperty().addListener((observableValue, old_client, new_client) -> { + if (data.isEmpty()) { + taResp_notCl.setText(""); + } + else{ + if (old_client != null) + old_client.setSelected(false); + taResp_notCl.setText(new_client.getDialog()); + new_client.setSelected(true); + } + }); + + buttonsState = new Thread(() -> { + while (true) { + btn_state_if_timeClient(timeClient == null || !timeClient.isAlive()); + btn_state_if_aphClient(aphClient == null || !aphClient.isAlive()); + btn_state_if_notClient(data.isEmpty()); + btn_state_if_infoClient(infoClient == null || !infoClient.isAlive()); + Thread.onSpinWait(); + } + }); + buttonsState.setDaemon(true); + buttonsState.start(); + } + private void btn_state_if_timeClient(boolean flag) { + btnCon_timeCl.setDisable(!flag); + btnDisCon_timeCl.setDisable(flag); + btnReq_timeCl.setDisable(flag); + } + private void btn_state_if_aphClient(boolean flag) { + btnCon_aphCl.setDisable(!flag); + btnDisCon_aphCl.setDisable(flag); + btnReq_aphCl.setDisable(flag); + } + private void btn_state_if_notClient(boolean flag) { + btnCon_notCl.setDisable(false); + btnDisCon_notCl.setDisable(flag); + btnReq_notCl.setDisable(flag); + } + private void btn_state_if_infoClient(boolean flag) { + btnCon_infoCl.setDisable(!flag); + btnDisCon_infoCl.setDisable(flag); + btnReq_infoCl.setDisable(flag); + } + private int whichPort(int port, TextField tfPort, TextArea taLogs) { + try { + port = Integer.parseInt(tfPort.getText()); + } catch (NumberFormatException e) { + taLogs.appendText("WARNING: invalid format of the port field\n"); + } + return port; + } + + @FXML + void OnClick_btnCon_timeCl() { + timeClient = Client.getInstance(tfHost_timeCl.getText(), + whichPort(1201, tfPort_timeCl, taLogs_timeCl), new TimeClient(taResp_timeCl, taLogs_timeCl)); + timeClient.start(); + + } + @FXML + void OnCLick_btnDisCon_timeCl() { + timeClient.disconnect(); + } + @FXML + void OnClick_btnReq_timeCl() { + timeClient.sendRequest(); + } + + @FXML + void OnClick_btnCon_aphCl() { + aphClient = Client.getInstance(tfHost_aphCl.getText(), + whichPort(1202, tfPort_aphCl, taLogs_aphCl), new AphorismClient(taResp_aphCl, taLogs_aphCl)); + aphClient.start(); + } + @FXML + void OnCLick_btnDisCon_aphCl() { + aphClient.disconnect(); + } + @FXML + void OnClick_btnReq_aphCl() { + aphClient.sendRequest(); + } + + @FXML + void OnClick_btnCon_notCl() { + notClient = Client.getInstance(tfHost_notCl.getText(), + whichPort(1203, tfPort_notCl, taLogs_notCl), new NoticeModule(taResp_notCl, taLogs_notCl, tfReq_notCl)); + data.add(notClient); + notClient.start(); + if (notClient.isAlive()) { + listeners.getSelectionModel().select(notClient); + } + } + @FXML + void OnCLick_btnDisCon_notCl() { + Client client = listeners.getSelectionModel().getSelectedItem(); + data.remove(client); + client.disconnect(); + } + @FXML + void OnClick_btnReq_notCl() { + listeners.getSelectionModel().getSelectedItem().sendRequest(); + } + + @FXML + void OnClick_btnCon_infoCl() { + + infoClient = Client.getInstance(tfHost_infoCl.getText(), + whichPort(1204, tfPort_infoCl, taLogs_infoCl), new InfoClient(taResp_infoCl, taLogs_infoCl, tfReq_infoCl)); + infoClient.start(); + } + @FXML + void OnCLick_btnDisCon_infoCl() { + infoClient.disconnect(); + } + @FXML + void OnClick_btnReq_infoCl() { + infoClient.sendRequest(); + } +} diff --git a/work/Clients/src/sample/Main.java b/work/Clients/src/sample/Main.java new file mode 100644 index 0000000..fc51a77 --- /dev/null +++ b/work/Clients/src/sample/Main.java @@ -0,0 +1,23 @@ +package sample; + +import javafx.application.Application; +import javafx.fxml.FXMLLoader; +import javafx.scene.Parent; +import javafx.scene.Scene; +import javafx.stage.Stage; + +public class Main extends Application { + + @Override + public void start(Stage primaryStage) throws Exception{ + Parent root = FXMLLoader.load(getClass().getResource("sample.fxml")); + primaryStage.setTitle("Clients"); + primaryStage.setScene(new Scene(root)); + primaryStage.show(); + } + + + public static void main(String[] args) { + launch(args); + } +} diff --git a/work/Clients/src/sample/sample.fxml b/work/Clients/src/sample/sample.fxml new file mode 100644 index 0000000..4163d8c --- /dev/null +++ b/work/Clients/src/sample/sample.fxml @@ -0,0 +1,353 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/work/Servers/NetworkServers.jar b/work/Servers/NetworkServers.jar new file mode 100644 index 0000000000000000000000000000000000000000..b90808efe27056d9ba59c651cedc9bdcdfa070d0 GIT binary patch literal 41910 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 literal 0 HcmV?d00001 diff --git a/work/Servers/src/META-INF/MANIFEST.MF b/work/Servers/src/META-INF/MANIFEST.MF new file mode 100644 index 0000000..440fa71 --- /dev/null +++ b/work/Servers/src/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: sample.Main + diff --git a/work/Servers/src/notes.JSON b/work/Servers/src/notes.JSON new file mode 100644 index 0000000..9b7d776 --- /dev/null +++ b/work/Servers/src/notes.JSON @@ -0,0 +1,36 @@ +[ + { + "id": 1, + "notes": [ + { + "time": "14:02", + "note": "1st note of 1st" + }, + { + "time": "14:03", + "note": "2st note of 1st" + }, + { + "time": "14:04", + "note": "3st note of 1st" + } + ] + }, + { + "id": 2, + "notes": [ + { + "time": "17:01", + "note": "1st note of 2nd" + }, + { + "time": "17:03", + "note": "2st note of 2nd" + }, + { + "time": "17:13", + "note": "3st note of 2nd" + } + ] + } +] \ No newline at end of file diff --git a/work/Servers/src/sample/Controller.java b/work/Servers/src/sample/Controller.java new file mode 100644 index 0000000..d0fedaa --- /dev/null +++ b/work/Servers/src/sample/Controller.java @@ -0,0 +1,152 @@ +package sample; + +import javafx.fxml.FXML; +import javafx.fxml.Initializable; +import javafx.scene.control.Button; +import javafx.scene.control.TextArea; +import javafx.scene.control.TextField; + +import java.net.URL; +import java.util.ResourceBundle; + +import srvs.*; + +public class Controller implements Initializable { + + private Server timeServer; + private Server aphServer; + private Server notServer; + private Server infoServer; + + @FXML + TextField tfPort_timeMod; + @FXML + Button btnStart_timeMod; + @FXML + Button btnStop_timeMod; + @FXML + TextArea taLog_timeMod; + + + @FXML + TextField tfPort_aphMod; + @FXML + Button btnStart_aphMod; + @FXML + Button btnStop_aphMod; + @FXML + TextArea taLog_aphMod; + + @FXML + TextField tfPort_notMod; + @FXML + Button btnStart_notMod; + @FXML + Button btnStop_notMod; + @FXML + TextArea taLog_notMod; + + @FXML + TextField tfPort_infoMod; + @FXML + Button btnStart_infoMod; + @FXML + Button btnStop_infoMod; + @FXML + TextArea taLog_infoMod; + + private Thread buttonsState; + + + @Override + public void initialize(URL url, ResourceBundle resourceBundle) { + //set default ports for servers + tfPort_timeMod.setText("1201"); + tfPort_aphMod.setText("1202"); + tfPort_notMod.setText("1203"); + tfPort_infoMod.setText("1204"); + + buttonsState = new Thread(() -> { + while (true) { + btn_state_if_timeServer(timeServer == null || !timeServer.isAlive()); + btn_state_if_aphServer(aphServer == null || !aphServer.isAlive()); + btn_state_if_notServer(notServer == null || !notServer.isAlive()); + btn_state_if_infoServer(infoServer == null || !infoServer.isAlive()); + Thread.onSpinWait(); + } + }); + buttonsState.setDaemon(true); + buttonsState.start(); + } + private void btn_state_if_timeServer(boolean flag) { + btnStart_timeMod.setDisable(!flag); + btnStop_timeMod.setDisable(flag); + } + private void btn_state_if_aphServer(boolean flag) { + btnStart_aphMod.setDisable(!flag); + btnStop_aphMod.setDisable(flag); + } + private void btn_state_if_notServer(boolean flag) { + btnStart_notMod.setDisable(!flag); + btnStop_notMod.setDisable(flag); + } + private void btn_state_if_infoServer(boolean flag) { + btnStart_infoMod.setDisable(!flag); + btnStop_infoMod.setDisable(flag); + } + + //Reads port from the textField and checks it. Return read port or default port. + private int whichPort(int port, TextField tfPort, TextArea taLogs) { + try { + port = Integer.parseInt(tfPort.getText()); + } catch (NumberFormatException e) { + taLogs.appendText("WARNING: invalid format of the port field\n"); + } + return port; + } + private void stopServer(Server server) { + server.module.doLog("send stop command to the server\n"); + server.terminateFlag = true; + server.close(); + } + + @FXML + void onClick_startBtn_timeMod() { + timeServer = Server.getInstance(new TimeModule(taLog_timeMod), whichPort(1201, tfPort_timeMod, taLog_timeMod)).multiThread(false); + timeServer.start(); + } + @FXML + void onClick_stopBtn_timeMod() { + stopServer(timeServer); + } + + @FXML + void onClick_startBtn_aphMod() { + aphServer = Server.getInstance(new AphorismModule(taLog_aphMod), whichPort(1202, tfPort_aphMod, taLog_aphMod)).multiThread(false); + aphServer.start(); + } + @FXML + void onClick_stopBtn_aphMod() { + stopServer(aphServer); + } + + @FXML + void onClick_startBtn_notMod() { + notServer = Server.getInstance(new NoticeModule(taLog_notMod), whichPort(1203, tfPort_notMod, taLog_notMod)).multiThread(true); + notServer.start(); + } + @FXML + void onClick_stopBtn_notMod() { + stopServer(notServer); + } + + @FXML + void onClick_startBtn_infoMod() { + infoServer = Server.getInstance(new InfoModule(taLog_infoMod), whichPort(1204, tfPort_infoMod, taLog_infoMod)).multiThread(false); + infoServer.start(); + } + @FXML + void onClick_stopBtn_infoMod() { + stopServer(infoServer); + } +} diff --git a/work/Servers/src/sample/Main.java b/work/Servers/src/sample/Main.java new file mode 100644 index 0000000..cbd246d --- /dev/null +++ b/work/Servers/src/sample/Main.java @@ -0,0 +1,23 @@ +package sample; + +import javafx.application.Application; +import javafx.fxml.FXMLLoader; +import javafx.scene.Parent; +import javafx.scene.Scene; +import javafx.stage.Stage; + +public class Main extends Application { + + @Override + public void start(Stage primaryStage) throws Exception{ + Parent root = FXMLLoader.load(getClass().getResource("sample.fxml")); + primaryStage.setTitle("Servers"); + primaryStage.setScene(new Scene(root)); + primaryStage.show(); + } + + + public static void main(String[] args) { + launch(args); + } +} diff --git a/work/Servers/src/sample/sample.fxml b/work/Servers/src/sample/sample.fxml new file mode 100644 index 0000000..5097acf --- /dev/null +++ b/work/Servers/src/sample/sample.fxml @@ -0,0 +1,174 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +