Reputation: 169
I am trying to create a GUI for a small project. This project is a java server, at the moment my code works fine, the server is connected and all but it never gets out of a loop and therefore the Frame of the GUI is created and displayed but you cannot interact with it after wards. I know where is the loop, but I cant seem to find a way to make my server listen to new clients and still be able to interact with the GUI. Here is my Code:
public class MainServerFrame {
private static JFrame frame;
private static ServerSocket serverSocket = null;
private static Socket clientSocket = null;
private static final int maxClientsCount = 999;
private static final clientThread[] threads = new clientThread[maxClientsCount];
private static StudentStoring studentDB = new StudentStoring();
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
MainServer();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public static void MainServer() {
// The default port number.
int portNumber = 3333;
try {
serverSocket = new ServerSocket(portNumber);
} catch (IOException e) {
System.out.println(e);
}
System.out.println("SERVER ONLINE");
initialize();
MainServerFrame window = new MainServerFrame();
MainServerFrame.getFrame().setVisible(true);
/*
* Create a client socket for each connection and pass it to a new client
* thread.
*/
HERE IS WHERE I CREATE THE SOCKET AND THEN GET INTO THE LOOP, what kind of design could I use to get rid of this while loop ?
while (true) {
try {
clientSocket = serverSocket.accept();
int i = 0;
for (i = 0; i < maxClientsCount; i++) {
if (threads[i] == null) {
(threads[i] = new clientThread(clientSocket, threads, studentDB)).start();
System.out.println("client " + i + " is connected");
break;
}
}
if (i == maxClientsCount) {
PrintStream os = new PrintStream(clientSocket.getOutputStream());
os.println("Server too busy. Try later.");
os.close();
clientSocket.close();
}
} catch (IOException e) {
System.out.println(e);
}
}
}
/**
* Initialize the contents of the frame.
*/
private static void initialize() {
setFrame(new JFrame());
getFrame().setBounds(100, 100, 450, 300);
getFrame().setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel lblServer = new JLabel("SERVER:");
getFrame().getContentPane().add(lblServer, BorderLayout.NORTH);
}
public static JFrame getFrame() {
return frame;
}
public static void setFrame(JFrame frame) {
MainServerFrame.frame = frame;
}
}
MY CLIENT
import java.awt.Font;
public class MainFrame implements Runnable {
//declare Jpanel
private static JFrame frmHome;
// The client socket
private static Socket clientSocket = null;
// The output stream
static ObjectOutputStream os;
// The input stream
static ObjectInputStream is;
private static BufferedReader inputLine = null;
private static boolean closed = false;
public static void main(String[] args) throws IOException{
// The default port.
int portNumber = 3333;
// The default host.
String host = "localhost";
/*
* Open a socket on a given host and port. Open input and output streams.
*/
try {
clientSocket = new Socket(host, portNumber);
is = new ObjectInputStream(clientSocket.getInputStream());
os = new ObjectOutputStream(clientSocket.getOutputStream());
os.flush();
System.out
.println("CONNECTED TO SERVER\n"
+ "Now using host=" + host + ", portNumber=" + portNumber);
} catch (UnknownHostException e) {
System.err.println("Don't know about host " + host);
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection to the host "
+ host);
}
/*
* If everything has been initialized then we want to write some data to the
* socket we have opened a connection to on the port portNumber.
*/
if (clientSocket != null && os != null && is != null) {
/* Create a thread to read from the server. */
new Thread(new MainFrame()).start();
}
}
public void run() {
/*
* Keep on reading from the socket till we receive "Bye" from the
* server. Once we received that then we want to break.
*/
MainFrame window = new MainFrame();
MainFrame.frmHome.setVisible(true);
String responseLine;
try {
while (!closed) {
}
} finally{
try {
is.close();
os.close();
clientSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public MainFrame() {
initialize();
}
//function to make window visible
void setVisible() throws IOException {
main(null);
}
private void initialize() {
//Initialise Main window with 3 options.
frmHome = new JFrame();
frmHome.setTitle("Home");
frmHome.setBounds(100, 100, 300, 372);
frmHome.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frmHome.getContentPane().setLayout(null);
frmHome.setResizable(false);
JLabel lblWelcomeToSrs = new JLabel("Welcome to SRS");
lblWelcomeToSrs.setFont(new Font("Tahoma", Font.PLAIN, 14));
lblWelcomeToSrs.setBounds(86, 183, 112, 14);
frmHome.getContentPane().add(lblWelcomeToSrs);
//initialise all buttons and labels of window.
JButton btnAdStu = new JButton("Add a student");
btnAdStu.setBounds(10, 207, 126, 23);
btnAdStu.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
AddStudentFrame adus;
try {
try {
adus = new AddStudentFrame();
adus.setVisible();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
frmHome.setVisible(false);
} catch (ParseException e) {
e.printStackTrace();
}
}
});
frmHome.getContentPane().add(btnAdStu);
JButton btnCheckStud = new JButton("Search / Modify");
btnCheckStud.setBounds(146, 207, 127, 23);
btnCheckStud.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
SearchFrame searchFrame;
searchFrame = new SearchFrame();
searchFrame.setVisible();
}
});
frmHome.getContentPane().add(btnCheckStud);
JLabel lblNewLabel = new JLabel("");
lblNewLabel.setBounds(0, 0, 0, 0);
frmHome.getContentPane().add(lblNewLabel);
JLabel lblCreatedByRmi = new JLabel("Created by R\u00E9mi Tuyaerts");
lblCreatedByRmi.setBounds(147, 318, 184, 14);
frmHome.getContentPane().add(lblCreatedByRmi);
JButton btnNewButton = new JButton("Complete List of Students");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
CompleteListFrame studentList = new CompleteListFrame();
studentList.setVisible();
}
});
btnNewButton.setBounds(52, 241, 184, 23);
frmHome.getContentPane().add(btnNewButton);
// wonderful pictures of his excellence design by Yasser
JLabel lblNewLabel_1 = new JLabel("");
Image img = new ImageIcon(frmHome.getClass().getResource("/michaelchung.jpg")).getImage();
lblNewLabel_1.setIcon(new ImageIcon(img));
lblNewLabel_1.setBounds(80, 11, 120, 148);
frmHome.getContentPane().add(lblNewLabel_1);
}
}
Upvotes: 0
Views: 132
Reputation: 208984
First thing I'd like to mention is the use of static
in your method signatures. They should not be static
, and you should not be trying to access them statically (MainServerFrame.getFrame().setVisible(true);
). Take out the static
in all the method signatures, add access the methods like window.getFrame().setVisible(true);
Secondly, the MainServerFrame
is being created on the Event Dispatch Thread. The EDT handle all the UI interaction. Though your code is not complete, it appears the while
loop is in the MainServerFrame
's constructor. The problem with this is that the while
loops blocks the event thread, causing the unresponsiveness. To fix it, you could simply start a new thread for the while loop.
new Thread(new Runnable(){
public void run() {
while (true) {
...
}
}
}).start();
Any calls inside this new thread, which attempts to update the UI, should be wrapped in a SwingUtilities.invokeLater
. Something like
new Thread(new Runnable(){
public void run() {
while (true) {
...
SwingUtilities.invokeLater(new Runnable(){
public void run() {
label.setText(...);
}
});
}
}
}).start();
Here's a simple refactor. I took out some of the code just to make the example simpler
public class MainServerFrame {
private JFrame frame;
private ServerSocket serverSocket = null;
private Socket clientSocket = null;
private int maxClientsCount = 999;
private JTextArea serverLog = new JTextArea(10, 40);
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
MainServerFrame app = new MainServerFrame();
app.getFrame().setVisible(true);
app.startServer();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public MainServerFrame() {
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(serverLog);
frame.pack();
frame.setLocationByPlatform(true);
}
public JFrame getFrame() {
return frame;
}
public void startServer() {
int portNumber = 3333;
try {
serverSocket = new ServerSocket(portNumber);
} catch (IOException e) {
System.out.println(e);
}
new Thread(new Runnable() {
public void run() {
while (true) {
try {
clientSocket = serverSocket.accept();
final String data =
(new DataInputStream(clientSocket.getInputStream())).readUTF();
SwingUtilities.invokeLater(new Runnable(){
public void run() {
serverLog.append(data);
serverLog.append("\n");
}
});
} catch (IOException e) {
System.out.println(e);
}
}
}
}).start();
}
}
UPDATE: Simple client
import java.io.DataOutputStream;
import java.net.Socket;
import java.util.Scanner;
public class Cilent {
public static void main(String[] args) throws Exception {
Socket socket = new Socket("localhost", 3333);
Scanner scanner = new Scanner(System.in);
String data = scanner.nextLine();
(new DataOutputStream(socket.getOutputStream())).writeUTF(data);
}
}
Upvotes: 1