You need to set velocity to 0 after a collision. Otherwise the negative velocity will keep building up until you pass through the floor in a single update.
Change your action function to this:
public void action(Rectangle r){
setPosition(bottom.x, r.y+1);
velocityY = 0;
}
For a more general solution, see the answer here: Tile based collision detection failing when player is going too fastTile based collision detection failing when player is going too fast