To expand on Iny's answer:
What you should be doing is not saving as gif, basicly. GIF is an 256 color palleted image (hence its small file size). If your image has more than 256 colors, you need to downsample the colors to 256 before trying to save. the encoder doesn't do it for you, because it doesn't know what to do. it probably starts writing the image, and once it exceeds 256 colors, just bails out.
I think you could kindof do it like this (psuedocode)
// Create the buffered image.
BufferedImage bufferedImage = new BufferedImage(w,h,BufferedImage.TYPE_INT_RGB);
... //fill image data (works fine)
ImageIO.write(bufferedImage, "JPG", f1); // works fine
ImageIO.write(bufferedImage, "PNG", f2); //works fine
// downsample to lower color depth by using BYTE_RGB?
BufferedImage crappyImage = new BufferedImage(w,h,BufferedImage.TYPE_BYTE_RGB);
crappyImage.getGraphics().drawImage(bufferedImage, 0, 0, w, h, null);
// or you could repeat the drawing code above with less colors
if (!ImageIO.write(crappyImage , "GIF", f3))
{
//still too many colors
f3.delete();
showError( "Could not save as gif, image had too many colors" );
}
If your drawing code is using Antialiasing to look nice, that will increase the color depth without you thinking about it. For example, drawing an AA'd diagonal blue line on a white background would appear to be 2 colors, Color.WHITE and Color.BLUE, but if you look closely, you have a whole bunch of shades of blue to get rid of the jaggy appearance of the diagonal line.