I like the idea with your enter() and exit() methods, I was using a boolean flag for initializing states, I like your way better.
One minor critique is that the way you have it set up there is no way to conditionally change a state. This year it wasn't needed, but I keep hoping for a game where the autonomous routine changes based on field conditions which aren't determined before the start of the match.
As to inner vs. outer classes: The number and the size of the states was why we decided to use inner classes. All told we had about 20 different states, on various machines, most of which consisted of 5 to 10 lines (Most were testing states, our final routine had 5 states). This seems like an awful lot of outer classes.
Ease of use for version control is certainly a strong argument. This year our team didn't use any formal version control software, but I'm pushing for it for next year. If that happens there is a good chance we'll go with outer classes.