I am making a simple client-server messenger pair with Sockets and JSwing, and I have recently run into a StackOverflow error. I know(or at least think) that it's caused by a recursive functon(which I don't think I have, but I may) that doesn't have a correct termination condition(does this mean like a return;
in a switch statement?)
Here's some of the error(since it's a StackOverflow, it repeats itself, of course)
Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError
at java.util.HashMap.getEntry(Unknown Source)
at java.util.HashMap.get(Unknown Source)
at sun.awt.AppContext.get(Unknown Source)
at com.sun.java.swing.SwingUtilities3.getDelegateRepaintManager(Unknown Source)
at javax.swing.RepaintManager.getDelegate(Unknown Source)
at javax.swing.RepaintManager.addDirtyRegion(Unknown Source)
at javax.swing.JComponent.repaint(Unknown Source)
at java.awt.Component.repaint(Unknown Source)
at javax.swing.JComponent.setBackground(Unknown Source)
at javax.swing.LookAndFeel.installColors(Unknown Source)
at javax.swing.LookAndFeel.installColorsAndFont(Unknown Source)
at javax.swing.plaf.basic.BasicPanelUI.installDefaults(Unknown Source)
at javax.swing.plaf.basic.BasicPanelUI.installUI(Unknown Source)
at javax.swing.JComponent.setUI(Unknown Source)
at javax.swing.JPanel.setUI(Unknown Source)
at javax.swing.JPanel.updateUI(Unknown Source)
at javax.swing.JPanel.<init>(Unknown Source)
at javax.swing.JPanel.<init>(Unknown Source)
at javax.swing.JPanel.<init>(Unknown Source)
at javax.swing.JRootPane.createGlassPane(Unknown Source)
at javax.swing.JRootPane.<init>(Unknown Source)
at javax.swing.JFrame.createRootPane(Unknown Source)
at javax.swing.JFrame.frameInit(Unknown Source)
at javax.swing.JFrame.<init>(Unknown Source)
at Socket_Swing_Database_Test.SocketManager.<init>(SocketManager.java:9)
at Socket_Swing_Database_Test.ClientSwing.<init>(ClientSwing.java:6)
at Socket_Swing_Database_Test.SocketManager.<init>(SocketManager.java:10)
at Socket_Swing_Database_Test.ClientSwing.<init>(ClientSwing.java:6)
at Socket_Swing_Database_Test.SocketManager.<init>(SocketManager.java:10)
at Socket_Swing_Database_Test.ClientSwing.<init>(ClientSwing.java:6)
at Socket_Swing_Database_Test.SocketManager.<init>(SocketManager.java:10)
My code:
public class ClientMain extends JFrame {
private SocketManager sm = new SocketManager();
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
ClientSwing window = new ClientSwing();
window.setVisible(true);
}
});
}
public void run() {
sm = new SocketManager();
Thread thread = new Thread(sm);
thread.run();
}
}
ClientSwing:
public class ClientSwing extends JFrame implements Runnable {
public SocketManager socketmanager = new SocketManager();
public final int NULL = 0;
public final int DISCONNECTED = 1;
public final int DISCONNECTING = 2;
public final int BEGIN_CONNECT = 3;
public final int CONNECTED = 4;
public int connectionStatus = socketmanager.connectionStatus;
public JPanel panel, statusBar;
public JTextArea textArea;
public JTextField textField, statusColor, usernameField;
public JLabel statusField;
public JMenuBar menuBar;
public JButton connectButton, disconectButton;
public int WIDTH = 640;
public int HEIGHT = 480;
public ClientSwing() {
super("Client");
panel = new JPanel();
panel.setLayout(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setSize(WIDTH, HEIGHT);
setResizable(true);
setJMenuBar(menuBar);
}
@Override
public void run() {
switch(connectionStatus) {
case DISCONNECTED:
break;
case DISCONNECTING:
break;
case CONNECTED:
break;
case BEGIN_CONNECT:
break;
}
}
public void invoke(Runnable runnable) {
SwingUtilities.invokeLater(runnable);
}
}
SocketManager:
public class SocketManager extends JFrame implements Runnable {
public ClientSwing cs = new ClientSwing();
public final int NULL = 0;
public final int DISCONNECTED = 1;
public final int DISCONNECTING = 2;
public final int BEGIN_CONNECT = 3;
public final int CONNECTED = 4;
public final String statusMessages[] = {
" Error! Could not connect", " Disconnected",
" Disconnecting...", " Connceting...", " Connected"
};
public final String END_CHAT_SESSION = new Character((char)0).toString();
public String hostIP = "localhost";
public int port = 2484;
public int connectionStatus = DISCONNECTED;
public StringBuffer toAppend = new StringBuffer("");
public StringBuffer toSend = new StringBuffer("");
public String statusString = statusMessages[connectionStatus];
public Socket socket;
public BufferedReader in;
public PrintWriter out;
public String error;
//Make a method that gets the username from the username field
public String username = "username";
public void changeStatusNTS(int newConnectStatus, boolean noError) {
if(newConnectStatus != NULL) {
connectionStatus = newConnectStatus;
}
if(noError) {
statusString = statusMessages[connectionStatus];
} else {
statusString = statusMessages[NULL];
}
SwingUtilities.invokeLater(cs);
}
public void changeStatusTS(int newConnectStatus, boolean noError) {
if(newConnectStatus != NULL) {
connectionStatus = newConnectStatus;
}
if(noError) {
statusString = statusMessages[connectionStatus];
} else {
statusString = statusMessages[NULL];
}
cs.run();
}
public void cleanUp() {
}
private void appendToChatBox(String s) {
synchronized(toAppend) {
toAppend.append(s);
}
}
private void sendString(String s) {
}
@Override
public void run() {
while(true) {
try {
Thread.sleep(10);
} catch(InterruptedException e) {
error = e.toString();
//Append the error to the textArea
}
switch(connectionStatus) {
case BEGIN_CONNECT:
try {
socket = new Socket(hostIP, port);
in = new BufferedReader(new InputStreamReader(socket.getInputStream())); //I AM RIGHT HERE
out = new PrintWriter(socket.getOutputStream(), true);
changeStatusTS(CONNECTED, true);
} catch(Exception e) {
cleanUp();
changeStatusTS(DISCONNECTED, false);
error = e.toString();
}
break;
case CONNECTED:
try {
if(toSend.length() != 0) {
out.print(toSend);
out.flush();
toSend.setLength(0);
changeStatusTS(NULL, true);
}
if(in.ready()) {
String input = in.readLine();
if((input != null) && (input.length() != 0)) {
if(input.equals(END_CHAT_SESSION)) {
changeStatusTS(DISCONNECTING, true);
} else {
appendToChatBox(username + ": " + input + "\n");
}
}
}
} catch(IOException e) {
cleanUp();
changeStatusTS(DISCONNECTED, false);
error = e.toString();
}
break;
case DISCONNECTING:
out.print(END_CHAT_SESSION);
out.flush();
cleanUp();
changeStatusTS(DISCONNECTED, true);
break;
default: break; //do nothing
}
}
}
class ActionAdapter implements ActionListener {
public void actionPerformed(ActionEvent e) {}
}
}