metoda: addCharacter(int x, int y)
dostaje null z prostego powodu. 2 razy inicjalizujesz tablicę:
static String[][] tab = new String[4][4];
public static void main(String[] args) {
String[][] tab = new String[4][4];
przez co posiadasz pole statyczne o nazwie tab oraz zmienną lokalną o tej samej nazwie. W listenerze natomiast pytasz if(TicTacToe.addCharacterUser(1,1)), jest to zapytanie o pole, a nie zmienna lokalną funkcji main, która jest zainicjalizowana jako tablica 4x4 z samymi null'ami!
Zamień na:
public class TicTacToe {
static String[][] tab;
public static void main(String[] args) {
tab = new String[4][4]
tab[0][0] = ...