I am trying to create a simple MVC client-server using a calculator app. When I try calculate/return the value my GUI freezes. I am not sure exactly what the problem is but I suspect it has something to do with my while(true) in my ControllerClient. I am unsure if I am communicating with the sockets correctly. I am using strings to communicate between client and server
package Client.Controller;
import java.awt.event.ActionEvent;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import Client.View.CalculatorView;
public class ClientController {
private CalculatorView view;
private Socket clientSocket;
private PrintWriter socketOut;
private BufferedReader socketIn;
public ClientController(CalculatorView view, String serverName, int portNum) throws IOException {
this.view = view;
clientSocket = new Socket(serverName, portNum);
socketIn = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
socketOut = new PrintWriter((clientSocket.getOutputStream()), true);
}
public void calculate() {
String firstNum = Integer.toString(view.getFirstNumber());
String secNum = Integer.toString(view.getSecondNumber());
socketOut.println("1" + firstNum + "," + secNum);
view.setTheSolution(Integer.parseInt(readFromServer()));
}
public void communicate() {
view.setVisible(true);
view.addActionListener((ActionEvent e)-> {
calculate();
});
}
private String readFromServer() {
String s = "";
while(true) {
try {
s += socketIn.readLine() + "\n";
if(s.contains("\0")) {
s = s.replace("\0", "\n");
return s;
}
} catch (IOException e) {
System.out.println("Error in reading from server.");
e.printStackTrace();
}
System.out.println(s);
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
CalculatorView view = new CalculatorView();
try {
ClientController control = new ClientController(view, "localhost", 9090);
control.communicate();
}
catch(IOException e) {
System.out.println("Error in main client controller");
e.printStackTrace();
}
}
}
View:
package Client.View;
import java.awt.event.ActionListener;
import javax.swing.*;
public class CalculatorView extends JFrame {
private JTextField firstNumber = new JTextField(10);
private JLabel addLabel = new JLabel("+");
private JTextField secondNumber = new JTextField(10);
private JButton calculateButton = new JButton("Calculate");
private JTextField theSolution = new JTextField(10);
public CalculatorView() {
JPanel calcPanel = new JPanel();
setSize(300, 300);
calcPanel.add(firstNumber);
calcPanel.add(addLabel);
calcPanel.add(secondNumber);
calcPanel.add(calculateButton);
calcPanel.add(theSolution);
add(calcPanel);
}
public int getFirstNumber() {
return Integer.parseInt(firstNumber.getText());
}
public int getSecondNumber() {
return Integer.parseInt(secondNumber.getText());
}
public void setTheSolution(int solution) {
this.theSolution.setText(Integer.toString(solution));
}
public void addActionListener(ActionListener listenForCalculateButton) {
calculateButton.addActionListener(listenForCalculateButton);
}
}
server model app
package Server.Model;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
public class Application implements Runnable{
private CalculatorModel calc;
PrintWriter socketOut;
BufferedReader socketIn;
public Application(CalculatorModel calc, PrintWriter socketOut, BufferedReader socketIn) {
this.calc = calc;
this.socketOut = socketOut;
this.socketIn = socketIn;
}
public void menu() throws IOException {
int input;
int firstNum;
int secNum;
while(true) {
String request = socketIn.readLine();
String[] args = request.split(",");
input = Integer.parseInt(args[0]);
switch(input) {
case 1:
firstNum = Integer.parseInt(args[1]);
secNum = Integer.parseInt(args[2]);
addNum(firstNum, secNum);
break;
default:
System.out.println("Quitting Program");
return;
}
}
}
public synchronized void addNum(int firstNum, int secNum) {
String s ="";
calc = new CalculatorModel();
calc.addTwoNumbers(firstNum, secNum);
s = Integer.toString(calc.getResult());
socketOut.println(s + "\0");
}
@Override
public void run() {
// TODO Auto-generated method stub
try {
menu();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
the model
package Server.Model;
public class CalculatorModel {
private int result;
public void addTwoNumbers(int a, int b) {
result = (a + b);
}
public int getResult() {
return result;
}
}
my server controller
package Server.Controller;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import Server.Model.Application;
import Server.Model.CalculatorModel;
public class ServerController {
ServerSocket serverSocket;
ExecutorService pool;
CalculatorModel calc;
public ServerController(int portNum, CalculatorModel calc) {
try {
serverSocket = new ServerSocket(portNum);
pool = Executors.newCachedThreadPool();
this.calc = calc;
System.out.println("Server is running...");
} catch (IOException e) {
System.out.println("Error in creating server controller.");
e.printStackTrace();
}
}
public void communicate() {
while(true) {
try {
Socket socket = serverSocket.accept();
BufferedReader socketIn = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter socketOut = new PrintWriter(socket.getOutputStream(), true);
String request = socketIn.readLine();
String[] args = request.split(",");
int firstNum = Integer.parseInt(args[0]);
int secNum = Integer.parseInt(args[1]);
Application app = new Application(calc, socketOut, socketIn);
pool.execute(app);
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
CalculatorModel calc = new CalculatorModel();
ServerController server = new ServerController(9090, calc);
server.communicate();
}
}