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) {}
}
}
 
     
    