Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • Home
  • SEARCH
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6815721
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 26, 20262026-05-26T20:50:26+00:00 2026-05-26T20:50:26+00:00

I have written a simple server – client program with Swing interface using singleton

  • 0

I have written a simple server – client program with Swing interface using singleton and observer pattern. Each client connects to the server and can send messages. The server forwards the messages it receives to the rest of the clients. The clients are using a GUI which allows them to connect and disconnect to the server at any time.
The program works pretty well because I have try – catch everywhere that handle each exception that may occur. But if you play with it you will see in the console a million of exceptions. That is probably because of poor design but i have tried my best to do a clean code.
so the question is :

Can anybody give me hints and advises on how to refactor the code to be more correct and clean (Especially when it comes to disconnect a client from the server)?

There is a main method in the CustomServer class to start the server and a
main method in the Controller to start the client (with GUI).

Thank you for your kind help!

Here is the code:

CustomServer class

package model;
import java.io.*;
import java.net.*;
import controller.Controller;


public class CustomServer extends Thread{
private ServerSocket ss = null;;



public CustomServer() throws Exception {
    ss = new ServerSocket(4444);
    this.start();
}

@Override
public void run(){
    while (true){
        try {
            Socket connSoc = ss.accept();
            new Connect(connSoc);
        } catch (IOException e) {
            e.printStackTrace();
            try{
                ss.close();
            }catch (Exception e1) {
                e1.printStackTrace();
            }
        }

    }
}

private class Connect extends Thread{
    ObjectOutputStream out;
    ObjectInputStream in;

    public Connect(Socket connSoc) {
        final IOController server = IOController.getInstance();
        try {
            out = new ObjectOutputStream(connSoc.getOutputStream());
            in = new ObjectInputStream(connSoc.getInputStream());
            server.add(in, out);
        }catch (Exception e) {
            e.printStackTrace();
            try{
                connSoc.close();
            }catch (Exception ex) {
                e.printStackTrace();
            }
        }
        this.start();
    }
}



public static void main(String[] args) throws Exception{
    new CustomServer();
}

}

CustomClient Class

package model;
import java.io.*;
import java.net.*;
import java.util.*;

public class CustomClient extends Observable{

private Socket connSocket;
private ObjectOutputStream out;
private ObjectInputStream in;
private boolean isOn = true;
private Thread receiver;

public CustomClient() throws Exception{
        System.out.println("inside CClient");
        Socket soc = new Socket();
        soc.connect(new InetSocketAddress(InetAddress.getLocalHost(), 4444));
        out = new ObjectOutputStream(soc.getOutputStream());
        in = new ObjectInputStream(soc.getInputStream());
}

public void transmit(Object obj){
    System.out.println("CClient - transitmin - start");
    try {
        out.writeObject(obj);
        out.flush();
    } catch (IOException e) {
        e.printStackTrace();
    }
    System.out.println("CClient - transitmin - end");
}

public void reveive(){
    System.out.println("CClient - recieve - start");
    receiver = new Thread(new Runnable() {
        @Override
        public void run() {
            while (isOn){
                Object obj = null;
                try {
                    obj = in.readObject();
                    setChanged();
                } catch (Exception ex){
                    ex.printStackTrace();

                }
                if (hasChanged()){
                    notifyObservers(obj);
                }
            }

        }
    });
    receiver.start();
    System.out.println("CClient - recieve - end");

}

public void closeConnection(){
    try{
        in.close();
    } catch (Exception e) {
        System.err.println("CAUGHT");
        e.printStackTrace();
    }
    try{
        out.close();
    } catch (Exception e) {
        System.err.println("CAUGHT");
        e.printStackTrace();
    }
    finally {
        try {
            isOn = false;
            in = null;
            out = null;
            connSocket.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        connSocket = null;
    }
}

public Socket getSocket(){
    return connSocket;
}

}

IOController class

package model;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;

public class IOController{

ArrayList<ObjectInputStream> ins = new ArrayList<ObjectInputStream>();
ArrayList<ObjectOutputStream> outs = new ArrayList<ObjectOutputStream>();
private static IOController instance = new IOController();

private IOController() {    
}

public static IOController getInstance(){
    return instance;
}

public void add(final ObjectInputStream in, final ObjectOutputStream out){
    ins.add(in);
    outs.add(out);
    new Connect(in);
}

private class Connect extends Thread{
    ObjectInputStream in;

    public Connect(ObjectInputStream in) {
        this.in = in;
        this.start();
    }

    @Override
    public void run() {
        boolean isOn = true;
        ArrayList<ObjectOutputStream> toBeRemoved = new ArrayList<ObjectOutputStream>();
        while(isOn){
            try {
                Object obj = in.readObject();
                for (ObjectOutputStream out : outs){
                    try {
                        out.writeObject(obj);
                        out.flush();
                    }catch (Exception ex){
                        toBeRemoved.add(out);
                        ex.printStackTrace();
                    }
                }
                for (ObjectOutputStream oos : toBeRemoved){
                    outs.remove(oos);
                }
            }catch (Exception ex){
                ins.remove(in);
                isOn = false;
                in = null;
                ex.printStackTrace();
            } 
        } 
    }
}
}

Controller class

package controller;
import java.awt.*;
import view.GUI;
import model.CustomClient;

public class Controller {

private GUI gui;
private CustomClient client;


public Controller() {
    gui = new GUI();
    gui.addConnectButtonActionListener(new ConnectButtonActionListener());
    gui.addTextFieldKeyListner(new TextFieldKeyListener());
    gui.addDisconnectButtonActionListener(new DisconnectButtonActionListener());
    gui.addCustomWindowListener(new GuiWindowListener());
}

private class DisconnectButtonActionListener implements ActionListener{

    @Override
    public void actionPerformed(ActionEvent e) {
        client.closeConnection();
        client = null;
        gui.getDisconnectButton().setEnabled(false);
        gui.getConnectButton().setEnabled(true);
    }
}


private class ConnectButtonActionListener implements ActionListener{

    @Override
    public void actionPerformed(ActionEvent e) {
        try { 
            client = new CustomClient();
            client.addObserver(gui);
            client.reveive();
            gui.getConnectButton().setEnabled(false);
            gui.getDisconnectButton().setEnabled(true);
        }catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}

private class TextFieldKeyListener extends KeyAdapter{

    @Override
    public void keyReleased(KeyEvent e) {
        if (e.getKeyCode()==KeyEvent.VK_ENTER){
            String msg = gui.getTextField().getText();
            gui.getTextField().setText("");
            if (client != null){
                client.transmit(msg);
            }
        }
    }
}

private class GuiWindowListener extends WindowAdapter{

    @Override
    public void windowClosing(WindowEvent e) {
        try{
            if (client != null){
                client.closeConnection();
                client = null;
            }
        }catch (Exception e2) {

        }
        System.out.println("closed");


    }
}

public static void main(String[] args) {
    new Controller();
    }
}

and GUI class

package view;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
public class GUI extends JFrame implements Observer{

private JTextField textField;
private JTextArea displayArea;
private JButton connectButton;
private JButton disconnectButton;

public GUI() {
    init();
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    SwingUtilities.invokeLater(new Runnable() {

        @Override
        public void run() {
            pack();
            setVisible(true);
            textField.requestFocusInWindow();
        }
    });
}

public void addConnectButtonActionListener(ActionListener al){
    connectButton.addActionListener(al);
}
public void addDisconnectButtonActionListener(ActionListener al){
    disconnectButton.addActionListener(al);
}
public void addTextFieldKeyListner(KeyListener kl){
    textField.addKeyListener(kl);
}

public void addCustomWindowListener(WindowListener guiWindowListener) {
    addWindowListener(guiWindowListener);

}

public void appendText(String text){
    displayArea.append("\n"+ text);
}

private void init() {
    JPanel panel = new JPanel();
    JPanel southPanel = new JPanel();
    JPanel northPanel = new JPanel();

    connectButton = new JButton("connect");
    connectButton.setFocusable(false);
    disconnectButton = new JButton("disconnect");
    disconnectButton.setFocusable(false);
    textField = new JTextField(20);
    displayArea = new JTextArea();
    displayArea.setEditable(false);
    displayArea.setPreferredSize(new Dimension(300,250));

    panel.setLayout(new BorderLayout());
    southPanel.setLayout(new FlowLayout());
    northPanel.setLayout(new FlowLayout());

    northPanel.add(displayArea);
    southPanel.add(connectButton);
    southPanel.add(disconnectButton);

    panel.add(textField,BorderLayout.CENTER);
    panel.add(southPanel, BorderLayout.SOUTH);
    panel.add(northPanel, BorderLayout.NORTH);
    this.getContentPane().add(panel);

    disconnectButton.setEnabled(false);

    System.out.println(textField.hasFocus());
}


public JTextField getTextField() {
    return textField;
}

public void setTextField(JTextField textField) {
    this.textField = textField;
}

public JTextArea getDisplayArea() {
    return displayArea;
}

public void setDisplayArea(JTextArea displayArea) {
    this.displayArea = displayArea;
}

public JButton getConnectButton() {
    return connectButton;
}

public void setConnectButton(JButton connectButton) {
    this.connectButton = connectButton;
}

public JButton getDisconnectButton() {
    return disconnectButton;
}

public void setDisconnectButton(JButton disconnectButton) {
    this.disconnectButton = disconnectButton;
}

@Override
public void update(Observable observable, Object object) {
    displayArea.append("\n"+(String)object);
}
}
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-26T20:50:27+00:00Added an answer on May 26, 2026 at 8:50 pm

    Without examining your code thoroughly, I see no problem with this approach to implementing the observer pattern. MVCGame is a related example. Synchronization remains a potential pitfall: Kudos for starting on the event dispatch thread, but beware that append() is no longer thread safe in Java 7. This example shows an alternative that also uses invokeLater().

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have written a simple client server program in C under linux. I have
I have a written a very simple UDP Server using Netty - it quite
I have a simple UDP client server written in C++ on Ubuntu 9.10 where
I have written a simple TCP client and server. The problem lies with the
I have written a simple single threaded client server application in Visual C++ .
I have written a simple network program on java using sockets. Program has a
I have written a simple network program on java using sockets. Program has a
I have a very simple server written in C and an equally simple client
I have written a secure TCP server in .NET. This was basically as simple
I have a very simple TCP server written in C. It runs indefinitely, waiting

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.