I'm lazy about exceptions, and usually throw and catch Exception without subclassing. Mainly because I've rarely found a spot where I would do different things based on different caught exceptions. For a serious app, I would probably have a single MyAppException class.
I like chained exceptions for end-user applications. I worked on one framework that caught exceptions and reinterpreted them in the context of what we were trying to do. For example, a lowest level exception might be "database table corrupted". The layer above that catches that and throws a new one that says "unable to retrieve user profile data" and the layer above that throws "unable to log on". We chained the exceptions and added a "details" button to the error message box that would dump the whole chain and optionally mail it to support.
For my own utilities I often let exceptions bubble all the way out to main() and let
Java display them. The stack trace is interesting to me, but would be very bad for an end-user app.
BTW: I did chaining on a distributed application, and had to save stack trace data as strings added to our custom Exception class, not references to standard Exceptions, because stack trace info was not serialized between environments. Java 1.4 added chained exceptions, but might lose all the interesting stuff over the wire.