That is very impressive!
Still quite alot of optimisations you can do to the source if you feel like adding sound to it

Heres some suggestions

Change all your double & long constants to smaller types.
Some can goto byte/short/int the rest will be fine as floats.
A classic example of this is :-
1
| enableEvents(someLong); |
it generates smaller bytecode if you push a byte (or in your case a short) onto the stack, and then expand it to a long.
This would be the equivalent of :-
1
| enableEvents((long)someByte); |
In most cases, it will save you 7 bytes in the constants pool, but cost you 1 extra bytecode instruction - a total saving of 6 bytes.
In your case, your flags value is 511, so you will only save 5 bytes by doing this.
Also, for the instances where you have Constants that are multiples of one-another (for example -PI, PI and 2PI).
It occupies less space if you
don't expand the multiplication.
e.g.
1 2 3 4 5
| 20.23452f + 40.46904f
ldc 20.23452f (2 or 3 bytes) ldc 40.46904f (2 or 3 bytes) fadd |
8 bytes in the constants pool,
min. 5 bytecodes (max. 7) to perform the op.
total 13-15.
1 2 3 4 5 6 7
| 20.23452f + 20.23452f * 2
ldc 20.23452f (2 or 3 bytes) dup fconst_2 fmul fadd |
4 bytes in the constants pool,
min 6bytecodes (max. 7) to perform the op.
total 10-11. A possible saving of upto 50%! =)
Adjusting some constants to allow them to be represented in a smaller type will shrink your constants pool.
For example, if you can, change all constant value usage from 128(short) to 127(byte).
Adjusting similar constants so they are identical, to eliminate constants from the constants pool saves you 2 fold - smaller constants pool, and reduced usage of the larger ldc2 instruction.
You could get rid of the 6 static fields, and replace it with 1 Object array. It would add some array dereferencing, but would allow you to have the minimum of 1 member variable.
The compiler &| obfuscator is adding in some bolox code ->
1 2 3 4 5
| if(g1 != g1) break; |
Still unsure why this happens, but i've had it happen to me several times.
dispose()ing of the JFrame, rather than System.exit()ing,
would be cleaner (no low level Exceptions from Java2D), and may even give you a smaller constants pool!
You are using both BufferedImage & MemoryImageSource, eliminating the MemoryImageSource and doing it through the BufferedImage API may save some space.
Re-ordering some of your instructions (especially where you are repeatedly accessing the same Object reference), so you can take better advantage of the dup2 instuction to duplicate values (the object reference) on the stack 2 at a time.
Get rid of the Random class usage, this will save tonnes in your constants pool.
while poor programming practice, Math.random() will suffice.
In many places in the code, there are duplications of
load instructions, when a
dup instruction would generate smaller bytecode.
Here for example, you could save 2 bytes by swapping the second fload of each pair, with a dup.
1 2 3 4 5 6 7 8 9 10
| double d1 = Math.sqrt(f13 * f13 + f15 * f15); |
Note all these optimisations pay no attention to how the changes will effect the efficiency of the jars zlib compression.
It would be near impossible to try and taylor the layout of your code so it got the most out of the compression.
The best you can hope to do, is make the basic class file as small as possible.
Ouch! Just noticed there is some StringBuffer usage in there.
Getting rid of that will save you atleast 40bytes.