What Andrew is trying to tell, amongst a number of things, is you are not taking into account the border and other possible bounding contentions which add to the size of the button...
![enter image description here]()
The button on the left is sized to match the image size, the button on the right takes into consideration the components Insests , allowing the content to be fit within the button without effecting the borders.
Also, I don't think html is the best choice for what you want to achieve.
UPDATED
When this blows up in your face, I didn't tell you ;)
![enter image description here]()
URL url = getClass().getResource("/DukeWaveShadow48x48.png");
String text = "<html><table border='0' width='48' height='48' cellpadding='0' cellspacing='1' background='" + url.toExternalForm() + "'><tr><td width='46' height='46' align='center'>Hello</td></tr></table></html>";