NullPointerException en PrintWriter [] array - Java

Tengo un problema que trato de resolver desde hace días.

Resumen de código simple (PseudoCode):

1 - Cuando un usuario se conecta, crea un PrintWriter para él.

2 - Almacene el objeto PrintWriter en una matriz PrintWriter [].

3 - Incrementa el número de usuarios conectados.

Cual es mi problema

El compilador lanza una NullPointerException

¿Qué causó la NPE?

Cuando el método sendMessage () es llamado por el objeto creado en la clase mainWindow, la matriz PrintWriter está vacía, no sé qué hace que esté vacía, ya que todas las variables y matrices tienen modificadores estáticos y la matriz PrintWriter [] se pone un valor en el constuctor (cuando un usuario se conecta).

Dentro del agente de ServerHandler, cuando intento enviar un mensaje al cliente, funciona bien y puedo ver que la matriz PrintWriter [] no está vacía, pero cuando llamo al método sendMessage () desde la instancia mainWindow, la matriz está vacía y La variable entera de userCounter sigue siendo 0.

¿Qué he intentado arreglarlo?

Configuración de los variables y los modificadores de matriz a volátil y estático.Escribiendo todo el código desde cero una y otra vez.

Clase de servidor (funciona bien):

package homeControl;

import java.net.*;
import java.util.Scanner;
import java.io.*;
import java.awt.*;

public class Server{
String sporocilo = null;
int id = 0;

outputHelper o = new outputHelper();


public void sprejmiPovezavo()
{
    try
    {
        ServerSocket svrSock = new ServerSocket(5000);

        while(true){

        Socket klientSocket = svrSock.accept();


        new Thread(new ServerHandler(klientSocket)).start();

        }


    }catch(IOException ex)
    {
        ex.printStackTrace();
    }
}


    public static void main(String[] args){
Server svr = new Server();
svr.sprejmiPovezavo();
}

}

Clase ServerHandler (esta clase causa los problemas)

package homeControl;

import java.net.*;
import java.util.ArrayList;
import java.io.*;
import java.awt.*;

public class ServerHandler implements Runnable{
static PrintWriter pw;
static PrintWriter[] writerHolder = new PrintWriter[10];
static int userCounter;
static int selectedID;


public ServerHandler(Socket socket){
    try{
        pw = new PrintWriter(socket.getOutputStream());
        writerHolder[userCounter] = pw;

        // Testing if this writerHolder[] can send the message to the client.
        writerHolder[userCounter].println("autoSent - Testint!");
        writerHolder[userCounter].flush();

        userCounter++;// Increment the number of people connected

        //Testing the values of the variables.
        System.out.println("ORG!\nuserCounter:" + userCounter +  "\nwriterHolder[userCounter]" + writerHolder[0]);
    }catch(Exception ex)
    {
        ex.printStackTrace();
    }
}
public ServerHandler()
{
    // Empty constructor
    // Used so that i don't need to pass a Socket into the class when i create a ServerHandler object from the mainWindow.class...
}



public void sendMessage(int tempID, String messageToBeSent)
{   // Testing the values of variables at the time that this method gets called.
    System.out.println("tempID:" + tempID + "\n" + "messageToBeSent:" +       messageToBeSent + "\n" + "userCounter:" + userCounter + "\n" + "selectedID:" + selectedID); 
    // End of test/Actual code:
    writerHolder[tempID].println(messageToBeSent);
    writerHolder[tempID].flush();
}

public void run()
{

}

}

mainWindows class (donde se llama al método sendMessage ())

package homeControl;

import java.awt.*;
import java.io.*;
import java.net.Socket;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JMenuBar;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JTextField;
import javax.swing.JButton;

public class mainWindow extends JFrame {

private JPanel contentPane;
private JTextField messageTextField;

ServerHandler svr = new ServerHandler(); // Thats why i use the empty constuctor in ServerHandler.class.
outputHelper o = new outputHelper();
int ID;

/**
 * Launch the application.
 */
public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                mainWindow frame = new mainWindow();
                frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

/**
 * Create the frame.
 */
public mainWindow() {
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(100, 100, 450, 300);

    JMenuBar menuBar = new JMenuBar();
    setJMenuBar(menuBar);

    JMenu mnOptions = new JMenu("Options");
    menuBar.add(mnOptions);

    JMenu mnId = new JMenu("ID");
    menuBar.add(mnId);

    JMenuItem idEnaItem = new JMenuItem("ID: 0");
    mnId.add(idEnaItem);

    JMenuItem idDvaItem = new JMenuItem("ID: 1");
    mnId.add(idDvaItem);

    contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    setContentPane(contentPane);
    contentPane.setLayout(null);

    messageTextField = new JTextField();
    messageTextField.setBounds(10, 209, 292, 20);
    contentPane.add(messageTextField);
    messageTextField.setColumns(10);

    JButton sendButton = new JButton("Send");
    sendButton.setBounds(312, 208, 89, 23);
    contentPane.add(sendButton);
    sendButton.addActionListener(new ActionListener(){
        public void actionPerformed(ActionEvent event){

            if(event.getActionCommand() != null)
            { // Calling the sendMessage() in the ServerHandler.class which should send a message to the Client.
               svr.sendMessage(ID,messageTextField.getText());
            }

        }
    });
}
}

Salida del constructor ServerHandler cuando estoy probando PrintWriters:

ORG!

userCounter: 1

writerHolder [userCounter] java.io.PrintWriter@798c668c

Salga del método SendMessage cuando intente enviar un mensaje manualmente:

messageToBeSent: dsda

userCounter: 0

selectedID: 0

ERROR:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at homeControl.ServerHandler.sendMessage(ServerHandler.java:45)
at homeControl.mainWindow$2.actionPerformed(mainWindow.java:84)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
at java.awt.Component.processMouseEvent(Unknown Source)
at javax.swing.JComponent.processMouseEvent(Unknown Source)
at java.awt.Component.processEvent(Unknown Source)
at java.awt.Container.processEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$200(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)

Respuestas a la pregunta(3)

Su respuesta a la pregunta