The problem is you are re-defining the same trayIcon variable in constructor.
final TrayIcon trayIcon;
So when you initiate the variable by calling trayIcon = new TrayIcon(image, Main.programmName, popup);
the local variable of the method is initialized and not the global one. So when you call displayMessage on global variable you got NPE.
Solution would be to just remove the line from constructor. OTOH you should put null check in showMessage method, as your trayIcon variable can still be null if your condition (SystemTray.isSupported())
stands false. It's better to always put a null check.
Another good thing said by MadProgrammer in comment:
The use of static variables in this case is probably not a good idea. Because it's possible for a developer to capable of instantiating more then one instance, and that case you would end up with erroneous references all over the place. Instead, try and make the Tray class a singleton or remove static keyword from the variable declaration.