int has 32 bits - you forgot about the other 28 bits that are set to 0, that ~ will turn into 1.
It's best to use Integer.toBinaryString for the visualization:
jshell> Integer.toBinaryString(~4)
$23 ==> "11111111111111111111111111111011"
As to why this value is -5:
Let's check what you get from ~4 + 4:
11111111111111111111111111111011
+ 00000000000000000000000000000100
----------------------------------
11111111111111111111111111111111
It's all ones! What happens if you now add 1?
11111111111111111111111111111111
+ 1
----------------------------------
00000000000000000000000000000000
The computation overflows and you get 0!
Therefore: ~4 + 4 + 1 = 0. Put in another way, ~4 = -4 - 1 = -5.