The general idea behind things like this (and I use the term general loosely) is that each 'object' in your game (whether it be a tree, car, w/e) is a group of polygons. Now, each of these respective polygons have a set of borders to them, which have a (likely) set or known size. So really, you could look at each of the object in your game as a set of hollow polygons. for example, take this 'hollow' car and wall I just whipped up (I'm an awful artist, so bear with me):
Now, even though in reality your car and wall will have nice details, and color filling, the only things you care about as a programmer handling collisions, is the border.
In the program, you'll have a handler attached to each of the objects in the game, something that listens for changes in the program. (A car moving, for example), and it can detect things like, did a collision happen? did the game end? did the car move past me and I should no longer be displayed. Etc. etc. since you care about collisions, you would pay extra special attention to when either: A) The car listener says it collided with something
or B) the wall listener says something hit it. From there you could change the logic of the program to handle whatever you want happening (stopping the cars animation motion and adding damage, showing a game-over screen, whatever).
From there, really, the best way to go about it is just to try. Java has a ton of graphical frameworks, and each one has it's own nuances. Try them all! or pick one after some research, the world is your playground.
EDIT
One example of a collision of shapes is in Javafx, and it is handled like so: (credit to jewlesea for this piece of code.)
private void checkBounds(Shape block) {
boolean collisionDetected = false;
for (Shape static_bloc : nodes) {
if (static_bloc != block) {
static_bloc.setFill(Color.GREEN);
if (block.getBoundsInParent().intersects(static_bloc.getBoundsInParent())) {
collisionDetected = true;
}
}
}
if (collisionDetected) {
block.setFill(Color.BLUE);
} else {
block.setFill(Color.GREEN);
}
}