-
Client Freezing
Hi all, well I'm still new to Java and I'm taking a class for it.
I'm working on an assignment where a client program has to send a loan object to a server and the server will compute the monthly payment and send it back to the client. I managed to get it to work for the most part but for some reason the client program freezes after the data has been sent to it. Also it prints in the command line but not in the client's JTextArea. Here's the code, any help would be appreciated. Thanks.
Code:
import java.net.*;
import javax.swing.*;
import java.awt.*;
import java.util.*;
import java.io.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class LoanClient extends JFrame{
private JTextField jtfAnnualInterest = new JTextField(10);
private JTextField jtfNumberOfYears = new JTextField(10);
private JTextField jtfLoanAmount = new JTextField(10);
private ObjectOutputStream toServer;
private DataInputStream fromServer;
private Socket socket;
private JTextArea resultJta = new JTextArea();
private JButton jbtSend = new JButton("Send to Server");
//private JPanel jta = new JTextArea();
public static void main (String [] args){
new LoanClient();
}
public LoanClient(){
setLayout(new BorderLayout());
JPanel jpl = new JPanel();
jpl.setLayout(new GridLayout(3,2));
jpl.add(new JLabel("Annual Interest Rate"));
jpl.add(jtfAnnualInterest);
jpl.add(new JLabel("Number of Years"));
jpl.add(jtfNumberOfYears);
jpl.add(new JLabel("Loan Amount"));
jpl.add(jtfLoanAmount);
jbtSend.addActionListener(new ButtonListener());
add(jpl, BorderLayout.NORTH);
add(jbtSend, BorderLayout.CENTER);
add(resultJta, BorderLayout.SOUTH);
setTitle("Loan Client");
setSize(500, 300);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public class ButtonListener implements ActionListener{
public void actionPerformed(ActionEvent e){
try{
while(true){
socket = new Socket("localhost", 8000);
double annualInterestRate = Double.parseDouble(jtfAnnualInterest.getText());
int numberOfYears = Integer.parseInt(jtfNumberOfYears.getText());
double loanAmount = Double.parseDouble(jtfLoanAmount.getText());
SerializedLoan sl = new SerializedLoan(annualInterestRate, numberOfYears, loanAmount);
toServer = new ObjectOutputStream(socket.getOutputStream());
fromServer = new DataInputStream(socket.getInputStream());
toServer.writeObject(sl);
resultJta.append("For Loan "+ sl.toString() +"\n The monthlyPayment recieved from server was " + fromServer.readDouble());
System.out.println("For Loan "+ sl.toString() +"\n The monthlyPayment recieved from server was " + fromServer.readDouble());
}
}
catch(IOException ex){
ex.printStackTrace();
}
finally{
try{
toServer.close();
fromServer.close();
}
catch(Exception ex){
ex.printStackTrace();
}
}
}
}
}
and here's for the LoanServer
Code:
import java.net.*;
import javax.swing.*;
import java.awt.*;
import java.util.*;
import java.io.*;
public class LoanServer extends JFrame{
private JTextArea jta = new JTextArea();
private ObjectInputStream inputFromClient;
private DataOutputStream outputToClient;
public static void main(String [] args){
new LoanServer();
}
public LoanServer(){
setLayout(new BorderLayout());
add(new JScrollPane(jta), BorderLayout.CENTER);
setTitle("LoanServer");
setSize(500, 300);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
try{
ServerSocket serverSocket = new ServerSocket(8000);
jta.append("Server started at "+ new Date() + "\n");
Socket socket = serverSocket.accept();
inputFromClient = new ObjectInputStream(socket.getInputStream());
outputToClient = new DataOutputStream(socket.getOutputStream());
while(true){
SerializedLoan sl = (SerializedLoan)inputFromClient.readObject();
jta.append(sl.toString());
outputToClient.writeDouble(sl.getMonthlyPayment());
}
}
catch(IOException ex){
ex.printStackTrace();
}
catch(ClassNotFoundException ex){
ex.printStackTrace();
}
finally{
try{
inputFromClient.close();
outputToClient.close();
}
catch(Exception ex){
ex.printStackTrace();
}
}
}
}
and for the Loan class
Code:
public class SerializedLoan implements java.io.Serializable{
private double annualInterestRate;
private int numberOfYears;
private double loanAmount;
private java.util.Date loanDate;
public SerializedLoan(){
this(2.5, 1, 1000);
}
public SerializedLoan( double annualInterestRate, int numberOfYears, double loanAmount){
this.annualInterestRate = annualInterestRate;
this.numberOfYears = numberOfYears;
this.loanAmount = loanAmount;
loanDate = new java.util.Date();
}
public double getAnnualInterest(){
return annualInterestRate;
}
public void setAnnualInterestRate(double annualInterestRate){
this.annualInterestRate = annualInterestRate;
}
public int getNumberOfYears(){
return numberOfYears;
}
public void setNumberOfYears(int numberOfYears){
this.numberOfYears = numberOfYears;
}
public double getLoanAmount(){
return loanAmount;
}
public void setLoanAmount(double loanAmount){
this.loanAmount = loanAmount;
}
public double getMonthlyPayment(){
double monthlyInterestRate = annualInterestRate/1200;
double monthlyPayment = loanAmount * monthlyInterestRate / (1 - (Math.pow(1/(1+ monthlyInterestRate), numberOfYears)));
return monthlyPayment;
}
public double getTotalPayment(){
double totalPayment = getMonthlyPayment() * numberOfYears * 12;
return totalPayment;
}
public java.util.Date getLoanDate(){
return loanDate;
}
public String toString(){
return "Loan created on "+ loanDate + " \n Loan amount " + loanAmount +" \n Years of term " + numberOfYears + "\n Annual interest rate " + annualInterestRate + "\n Monthly payment " +this.getMonthlyPayment();
}
}
-
Moderation: code tags added to your original post to help make your code readable. Please read the link in my signature below to see how to do this yourself.
Your problem appears to be due to calling while (true) on the main Swing thread, the EDT, thus freezing the thread and your GUI. You will need to learn to use background threads for your Swing app to remain responsive and you will find the necessary information here: concurrency in swing
-
Thanks for the advice. Would it be possible to put the while loop within a new class implementing runnable and then execute a new thread in the try catch?
-
Please read the article that I linked to as it will answer most of your questions.