Od razu ostrzegam, że w programowaniu w Java jestem totalnym noobem.
W celu dokształcenia się postanowiłem napisać prosty komunikator. Problem polega na tym, że po wysłaniu wiadomości do serwera przy podłączonej większej ilości klientów tekst nie jest poprawnie odbierany w polu tekstowym. Powinien być rozesłany do wszystkich podłączonych klientów, a zamiast tego robi się sieczka. Nie dość, że wiadomość odebrana nie jest tą wysłaną jako ostatnia to jeszcze nie wiem jak zrobić by pola tekstowe odświeżały się na bieżąco. Czy możecie doradzić co poprawić/dodać? Próbowałem dodać obserwatora, ale nie do końca wiem jak poprawnie go zamieścić.
Kod programu zamieszczam poniżej:

Serwer:
FileServer.java


import java.net.*;
import java.io.*;



public class FileServer{
	
	static Socket clientSocket = null;
	static ServerSocket  serverSocket= null;	
	static  clientThread t[] = new clientThread[10]; 

		public static void main(String args[]) throws IOException
	
		{ 

			int port_number =1406;
			try{
				serverSocket = new ServerSocket(port_number);
			}catch(IOException e){System.out.println(e);}
			
			System.out.println("Serwer nasłuchuje portu" +port_number);
					
			while(true){
				try{
					clientSocket=serverSocket.accept();
				System.out.println("Akceptuje połaczenie od: "+clientSocket.getInetAddress());
			
				for(int i=0; i<=9; i++){			    
					if(t[i]==null)									
					{
						(t[i] = new clientThread(clientSocket,t)).start();
						break;
					}
				}						
				}catch(IOException e){System.out.println(e);}		
			}
		}		
}


 

clientThread.java:

 
import java.io.*;
import java.net.*;

class clientThread extends Thread{
    
    DataInputStream is = null;
    PrintStream os = null;
    Socket clientSocket = null;       
    clientThread t[]=null; 
    BufferedReader odczyt;
    DataOutputStream zapis;
    String zdanieWe="";
    String zdanieWy="";
    public clientThread(Socket clientSocket, clientThread[] t){
	this.clientSocket=clientSocket;
        this.t=t;
    }
    
    public void run()    
    {
    		try
    		{   			
    			while(true)
    			{	    
    				is = new DataInputStream(clientSocket.getInputStream());
    				os= new PrintStream(clientSocket.getOutputStream());
    				odczyt=new BufferedReader(new InputStreamReader(is));
    				zdanieWe=odczyt.readLine();
	    	
    				
    				if(zdanieWe!=null){
    				
    					for(int i=0; i<=9; i++)   	
    						if (t[i]!=null)  {
    							//System.out.println("Odczytano zdanie : " + zdanieWe);                                  
    							//new DataFormater();
    							t[i].os.println(zdanieWe);
    							System.out.println("Wyslano zdanie do : "+ t[i]+" "+ zdanieWe);
    							if (zdanieWe.equals("by")){				
    								t[i]=null;
    								zdanieWe="Użytkownik opuścił program";
    		    				}

    						}	    		   				
    				}	    	    			    	
    			}	
    		}	
    		catch(IOException e){};    
    }    
}

Logowanie:
Login.java

import java.sql.DriverManager;
import java.sql.SQLException;

import javax.swing.*;

public class Login
{
  public static String nick = null;
@SuppressWarnings({ "deprecation" })
public Login() 
  {
    JFrame ramka = new JFrame("Logowanie");

    JTextField poleNazwy = new JTextField( );

    JPasswordField poleHasla = new JPasswordField( );

    String komunikat = "Proszę wpisać nazwę użytkownika i hasło.";
    JOptionPane.showOptionDialog(ramka, new Object[] 
    { komunikat, poleNazwy, poleHasla },"Logowanie", JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, null, null);
  
    try {
    	DriverManager.getConnection("jdbc:mysql:///mysql", poleNazwy.getText(), poleHasla.getText());
    	new Klient2();
    	nick = poleNazwy.getText(); 	
    	
	} catch (SQLException e) {
		JFrame blad = new JFrame("Błąd logowania"); 
		String komunikat1="Błędny login lub hasło";
		JOptionPane.showOptionDialog(blad, new Object[] 
		{komunikat1},"Bład Logowania", JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE, null, null, null);
		System.out.println("Błąd logowania");

	}
    poleNazwy.setText(""); //kasowanie pól
    poleHasla.setText("");
  }
  public static void main(String args[]){
	 		 
	  new Login();

  }

}

Program Klienta
Klient2.java


//program Klienta:
import java.net.*;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Klient2 {

	Klient2(){	
		OknoKlient okno = new OknoKlient();
		okno.setSize(300,500);
		okno.setTitle("Okno klienta.");
		okno.setVisible(true);
		okno.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}
}

class OknoKlient extends JFrame implements ActionListener, KeyListener{
/**
	 * 
	 */
	private static final long serialVersionUID = 2L;

	JTextField pole1=null;
	JTextArea pole2=null;
	Socket polaczenie = null;
	DataInputStream we=null;
	DataOutputStream wy=null;
	Watek1 w1=null;
	Watek2 w2=null;


	public OknoKlient() {
	
		setLayout(new FlowLayout());
		JLabel lab1=new JLabel("Wpisz zdanie:");
		add(lab1);
		pole1 =new JTextField(20);
		add(pole1);
		pole1.addKeyListener(this);
	
		JButton przycisk1=new JButton("wyczyść");
		przycisk1.addActionListener(this);
		add(przycisk1);

		JButton przycisk2=new JButton("wyślij");
		przycisk2.addActionListener(this);
		add(przycisk2);

		JButton przycisk3=new JButton("koniec");
		przycisk3.addActionListener(this);
		add(przycisk3);

		JLabel lab2=new JLabel("Odebrane zdanie:");
		add(lab2);
		pole2 =new JTextArea(20,20);
		add(pole2);
		add(new JScrollPane(pole2));
	


		try{
			polaczenie= new Socket("localhost", 1406);
		} catch(Exception e){  }
/* koniec konstruktora: */
	}

	public void actionPerformed(ActionEvent ev) {

		if(ev.getActionCommand()=="wyczyść") {      
			pole1.setText("");
			pole2.setText("");
		}

		if(ev.getActionCommand()=="wyślij") {
			w2=new Watek2(polaczenie,wy);
			w2.start();
		}
		if(ev.getActionCommand()=="koniec") {
			w1=new Watek1(polaczenie,wy);
			w1.start();
		}
	}

	public void keyPressed(KeyEvent e) {
		if (e.getKeyCode()==KeyEvent.VK_ENTER) {
			w2=new Watek2(polaczenie,wy);
			w2.start();
		}
	}
	public void keyReleased(KeyEvent e) {}
	public void keyTyped(KeyEvent e) {}

class Watek1 extends Thread {
Socket polaczenie;
DataOutputStream wy;
DataOutputStream zapis = null;
DataOutputStream wyjscie =null;
InputStream we;
BufferedReader odczyt = null;

	public Watek1(Socket polaczenie,DataOutputStream wy)
    	{     		
		this.polaczenie=polaczenie;
		this.wy=wy;
    	}

	public void run() {
            
		try{
			wyjscie=new DataOutputStream(polaczenie.getOutputStream());
			wyjscie.writeBytes("by");
			polaczenie.close();
			System.exit(0);
        	
		} catch(Exception e){}
	}
}

class Watek2 extends Thread{
Socket polaczenie = null;
DataOutputStream wy;
DataOutputStream zapis = null;
DataInputStream we;
BufferedReader odczyt = null;



	public Watek2(Socket polaczenie,DataOutputStream wy)
    	{
		this.polaczenie=polaczenie;
		this.wy=wy;
    	}

	public void run() {	
		try{
			if(polaczenie!=null && wy!=null && we!=null){
				try{
					new Thread( new Watek2(polaczenie, wy)).start();
				}
				catch(Exception e){System.out.println(e);}
			}				
			wy=new DataOutputStream(polaczenie.getOutputStream());
			String zdanieWe=pole1.getText();      
			if( zdanieWe!=null && !(zdanieWe.equals("")) ) {        
				
				zapis =new DataOutputStream(wy);
				zapis.writeBytes(Login.nick+": "+zdanieWe + "\n");                
				
				new Odbior(polaczenie);
			}
		}  catch(Exception e){}
	}
}

class Odbior{
	Socket sock;
	BufferedReader sockReader;
	String zdanieWy;
	BufferedReader odczyt;
		
	public Odbior(Socket sock){	      
		this.sock=sock;                                                                   	      
		try {			
			this.sockReader=new BufferedReader(new InputStreamReader(sock.getInputStream()));
			odczyt = this.sockReader;
			zdanieWy=odczyt.readLine();			
			if (zdanieWy!=null && !(zdanieWy.equals("")) )  {                                                        	                	            	
				pole2.append(zdanieWy+"\n");                
            }                                            
            else if (zdanieWy==null && (zdanieWy.equals("")) )  {                            	                	
            	pole2.setText("");                            	                                                                                           
            }            
			pole1.setText("");		
		} 
		catch (Exception e) {}	
	}	
}

}

Z góry przepraszam, że kod nie jest zbyt estetyczny.