1) Masz trzy: if, else if, else if, a w nich dokładnie to samo:
String winner = "Winner: " + checkWinner();
JOptionPane.showMessageDialog(null, winner);
System.exit(0);
2)
Zamiast:
checkWinner()=="X"
Powinieneś albo przekształcić swój kod żeby działał na char'ach albo sprawdzać w ten sposób:
checkWinner().equals("X")
3)
Niepotrzebnie wywołujesz metodę checkWinner() najpierw w warunku if, a później wewnątrz if'a drugi raz. Zamiast tego przed if'em powinieneś przypisać to co checkWinner() zwróciło do jakiejś zmiennej
4)
if(fields[0].getValue()!=null && fields[0].getValue()==fields[1].getValue() && fields[1].getValue()==fields[2].getValue())
Brzydkie to. Zauważ, że robisz to samo sprawdzenie 9 razy tylko dla różnych indeksów tablicy, zamiast tego mógłbyś stworzyć metodę, która zwarca boolean, a jako argumenty przyjmuje te indeksy tablicy - poprawia czytelność i kod jest krótszy.
5)
Zamiast oznaczać pola, w których żaden z graczy nie udzielił jeszcze odpowiedzi jako null mógłbyś użyć Optional<String> z Javy 8. Ewentualnie pójść o krok dalej i zamiast Stringa stworzyć jakiegość enum'a, który ma w sobie "X" i "O".
6)
Wiem, że to głównie kwestia gustu i preferencji, ale w Javie przyjęło się, że klamry piszemy tak:
public void method() {
// whatever
}
Pewnie bardziej podoba Ci się ten styl, którego używasz, ale jeśli kiedyś będziesz wspólnie pracować nad jakimś projektem z innymi programistami, lub po prostu pracować w firmie jako Java Dev to Cię zjadą za te klamry :)