(There were other options out there, too— for example, SWT’s the widget toolkit used by Eclipse which feels a bit more native on some platforms than Swing.)
Because compiling on windows and deploying on linux/unix/etc, that was posssible 20 years before java in c/c++.
"20 years before Java"? That's 1975 we're talking about.
Was it possible to build a program on Windows 95/NT and then deploy that to a Unix system? Probably. But given that today this can still be quite a pain to cross-compile C code I bet it wasn't easy. Besides, "it compiles" doesn't mean "it works" or "it works on this other platform" (quite likely with a different CPU architecture), especially not in C. And few people were writing any tests in the 90s.
Java abstracted a lot of details like endianness, platform-specific APIs, etc. away.
> who uses that in real life?
There's quite a few cross-platform Java desktop apps; the IntelliJ IDEs are a good example (although they've since developed Kotlin, it's still the same Java VM). DBeaver is another example, openoffice.org used quite a bit of Java back in the day (although I think that's mostly phased out now) – I'm sure there are more.
And of course in the 90s you had Java Web Applets.
Java is a bit less popular for this than it was, but I've run plenty of Java programs on my FreeBSD machine back in the day, and I'm pretty sure "FreeBSD" wasn't really something the developers really thought of when they wrote it (I can't remember which off-hand, it was a long time ago but I have "fond" memories of dealing with the manual installation bruhhaha because of the license at the time).
Well POSIX dates from the late 80s. That's not cross-CPU, but at least cross-OS, which is what Gates was really concerned about.
Nowadays we do the same with .NET code as well, when using .NET Core.
That's not to say that Java provided a "good" cross-platform experience by our current standards - but the fact that it provided it at all was huge!
I can reuse my Java code on Android, but since approach to UX on mobile is completely different, the UI front needs to be separate anyway. But I once wrote a game with LibGDX that essentially had the same core codebase.
While they run on a different VM (Dalvik), Android programs are (mostly) written in Java, and provide a cross-platform function - namely different CPUs (Android can come in ARM, ARM64, x86, x64, MIPS), and all run the same binary (except if there's native extensions... which negates all of that)