Printing odd and even numbers with two threads
Inconsistency
In OddNumberGenerator your printer is called q.  In EvenNumberGenerator it is called printer.  Why the difference?
The odd one prints to max-1 but the even one prints to max.  They should both print to max, otherwise you are assuming that max must be even.
No check after wait
After your wait() call, you don't check to see if you are in the correct state before printing the next number.  If both threads called printOdd(), it would happily print two or more odd numbers in a row.  It's not a problem with your program because your two threads are well behaved, but it isn't a very good example of using synchronization.
Simplification
You don't need separate printOdd() and printEven() functions that do almost the same thing.  You could combine them into a single printNumber() function.
Similarly, you don't need two number generators.  If you just added a start variable to the number generator, you could create an odd generator with a start value of 1 and an even generator with a start value of 2.