an exception will not be thrown unless you’re doing something out of the ordinary. e.g. drawing to an Image that was created with createImage(width,height) using a Window that was invisible.
and if its so rare, you do not need to bother checking for it, especially in 4K (exception catching is nearly nonexistant in 4K…)
but that doesn’t even matter, the only 100% away to avoid such an exception is not to draw at all
If you bother to check if the Graphics object is null, then you might as well check for the exception. Both appear to indicate the same issue; it’s just a matter of where you are in the game loop when it occurs. If you detect for the null condition to prevent the game from crashing, then you should catch the exception. Doing one without the other doesn’t make a lot of sense. Either accept that the thread can die in the unlikely event that the Graphics object becomes invalid or completely cover your bases to let the program carry on.
I suspect that getGraphics() will only return null or an exception will be thrown during “draw” is when the frame/panel cannot be drawn to prior to being displayed or during shutdown of the application.
I still don’t understand why the Graphics object for a BufferedImage ever needs to be disposed. What could render it invalid?
the exception and null value can be completely different issues. you should check for null because the Window can return null when the Window is minimized or otherwise unfocused/invisible/nondisplayable.
this does not mean you need to check for an extremely rare exception (I’ve never heard of it myself), that’s a waste of space. The doc does not say Graphics will throw an exception, but the doc for getGraphics() does mention it can return null. that’s why you should check for null, and shouldn’t be worried about the Exception ,that’s more on the VM level than anything (probably not something you can control - especially since it will crash your game whether you catch it or not)
can’t say for sure, probably something to do with the underlying buffers. as oNyx mentioned, for reasons unknown, holding any Graphics object in memory will consume ram. so if you’re grabbing a new Graphics object each frame, it’s only logical to dispose of it at the end of each frame
The creteGraphics(int, int) returns an Image, which I assumed to be of subtype BufferedImage. Am I wrong? Having the reference declared as a super class changes nothing right, since the methods will be called on the correct subclass (BufferedImage, in this case, if I’m not wrong).
The image creation within the loop was dumb, I acknowledge that. Thanks for the tip, now it’s fixed :
actually, BufferedImage is a sublcass of Image. Image has been around since java 1.0, BufferedImage wasn’t on the scene until Java 1.3 I believe. Also note that creating a BufferedImage does not rely on your Window to be visible (like createImage(int,int) does).
[quote=“woogley link=topic=15103.msg120075#msg120075 date=1161021396][quote author=zeroone,post:23,topic:28557”]
I still don’t understand why the Graphics object for a BufferedImage ever needs to be disposed. What could render it invalid?
[/quote]
can’t say for sure, probably something to do with the underlying buffers. as oNyx mentioned, for reasons unknown, holding any Graphics object in memory will consume ram. so if you’re grabbing a new Graphics object each frame, it’s only logical to dispose of it at the end of each frame
[/quote]
I’ve never seen this happen, and I can find no mention at all of Graphics objects to be disposed because “they’re no longer valid” in the javadocs.
“no longer invalid” is zeroone’s words, not mine. what you quoted is my best guess, after my recent buffer revelation
I quote the javadoc as saying:
it goes onto say how the Graphics in paint(Graphics) and update(Graphics) are disposed of automatically, but then says otherwise-acquired Graphics objects should be disposed of manually:
as far as solid proof goes, you’d need that program oNyx was talking about and a Mac platform to test it on. I’m stuck on Windows, and Windows doesn’t seem to be affected by dispose() (or lack thereof).
I’ve also heard from Kevin Glass (when I was asking him why he didn’t remove dispose() in his Goop4K game to save space) that dispose needs to be called to avoid graphical glitches on different platforms.
when you read the javadoc quoted above, the major unclarity is when you’re considered to be “done” with a Graphics object - in oNyx’s case, he wasn’t done until the program closed, which resulted in (according to him) RAM consumption.
being on windows, the whole issue is somewhat confusing to me. up until now, I have never used dispose() (just check out the Goomba4K source), but maybe those random glitches (see the Goomba4K thread) were caused by the lack of dipose(). if kevglass isn’t going to take the risk, I’m certainly not either o_O
Miners4k allocates the graphics objects once, and never clears them up. I’ve never heard of any bugs related to that.
The javadoc you quoted doesn’t say you HAVE to dispose it, only that there’s no point in disposing graphics objects you didn’t create yourself. (Ie the only time you should call it is when you created it)
I’ve done the same for every game I’ve made, the only time I heard of the bug is from oNyx/kevglass. have you tested all your games on a mac? (I know I haven’t, heh)
yes, that’s what I’ve said like 5 times in this thread. so if you create a Graphics on each frame, you should dispose of it since the next frame is going to create yet another one, and so on, and so forth…
Ah, I see. I misread what you said all those times.
Since I can’t find any mention of it in the javadocs, I’m going to keep doing what I (and you) do, and will consider any bad behavior from it to be a bug in the java implementation.
So, is the final verdict to ignore the possibility that getGraphics() can return null, to create the Graphics objects only once on application start-up and to never dispose them? That works for me even under OS X. I never tried createBufferStrategy() though.
getGraphics() can definitely return null, that is in the javadocs. what’s not in the javadocs is the exception you were talking about, as well as the “policy” of g.dispose()
“Creates a graphics context for this component. This method will return null if this component is currently not displayable.”
Component.isDisplayable()
“… A component is made displayable either when it is added to a displayable containment hierarchy or when its containment hierarchy is made displayable. A containment hierarchy is made displayable when its ancestor window is either packed or made visible…A containment hierarchy is made undisplayable when its ancestor window is disposed.”
Component.setVisible(boolean)
“Shows or hides this component depending on the value of parameter b.”
Window.dispose()
“Releases all of the native screen resources used by this Window, its subcomponents, and all of its owned children. That is, the resources for these Components will be destroyed, any memory they consume will be returned to the OS, and they will be marked as undisplayable.”
Ergo, getGraphics() when invoked on a Window / Frame that has had setVisible(true) / show() called on it will never return null, until dispose() is called on the Window / Frame.
What is with all this talk of ultra-defensive programming!
We’re talking about 4K games here :
if you’re pulling getGraphics() from the JFrame itself, I would check for null, because I’ve had it become null for reasons I can’t explain. pulling from a JPanel hasnt had that problem for me, though. do what works for you, and cross your fingers. play around, test it out, experience it for yourself