I'm sure I still don't understand everything you're trying to do or exactly how you're doing it, but I think I get the picture ('scuse the pun) enough to say how I would do it. Hopefully this will help you.
I would go similar to your method #2 in your second post, having a "template" card, over which I draw the elements of an actual card instance.
I wouldn't use labels to draw the text, but graphics.drawString(). This is because I don't like mixing plain rendering (i.e. to a Graphics2D) with Swing rendering. I don't know if there's any problems with doing it, but it doesn't seem right to me, in that I don't think it's what Swing is intended to do.
It sounds like 145x200 is the size of a whole
card (i.e. the card template)? So, I assume your PNG images will be smaller than this. If I assume (just for this calculation) that they are about 100x100 and 32-bit, then amount of memory they'll take is:
= ((w * h) * (bits/8)) * no. of cards
= ((100 * 100) * (32/8)) * 100
= 4000000 bytes
= 3.8 MB
So, if you can afford to use 3.8 MB for your images, it will be easier. I would do this (i.e. keep them in memory) - seems pretty cheap to me.
You say near the end that there can be up to 20 of the same card? You may need to make sure here that the card to be rendered
object is different to the card that the player has in their hand
object, with the 2nd having a reference to the first. So there may be many card instances allocated to the players that represent the same card (type), but they all reference to the one BufferdImage instance. This will ensure you don't double up by having the same image in memory twice.
Hope my opinion helps you somewhat.