Domanda

i' m little bit confused about few things:

Example code,that shows my problem,this isn't compilable

// image
private BufferedImage image;
private Graphics2D graphic;
private changeImage;
. . .
//thread loop
while (running) {
   . . .
    render();
    Graphics showGraphic = getGraphics();
    showGraphic.drawImage(image, 0, 0, null);
    showGraphic.dispose();
    }
 public void render(){
     if(changeImage == 1)
     graphic.drawImage(ImageLoader.TREE, 0, 0, null);
     else if(changeImage == 2){
     graphic.drawImage(ImageLoader.HOUSE, 0, 0, null);
      . . .
     graphic.fillRect(50,60,30,40);
     }
}

I create an global object Graphic2D and i draw things in render(), I do not call repaint() inside the game loop, is it good practice to do this?

Should I use repaint() inside my loop , and the paintComponent() function ?

one other thing, how graphic.dispose() works correctly? , because trying to remove this line of code, nothing happens.

I understand how works dispose() according to java docs, but I have not noticed any differences with dispose() or without.

my program runs very well, but i have this dubts.

È stato utile?

Soluzione

is it good practice to do this

No, this is actually incredibly horrible and error prone. This assumes that this is the Component#getGraphics method. The problem is Swing uses a passive rendering algorithm, that is, Swing decides when and what should be repainted and does this for optimisation reasons.

This means updates are not regular, which really helps when doing animation, and can happen at any time for any number reasons, many of which you simply don't and can't control.

For these reasons, painting should be done within one of the paint methods, preferably, paintComponent of a JComponent based class. This way, when Swing decides to do a repaint, one, you know about it and can update the output accordingly, and two, it won't clear what you have previously painted to it using getGraphics which could cause flickering...

You are also running into potential threading issues, as you thread is trying to paint to the Graphics context, so might the Event Dispatching Thread and that isn't going to end pretty...All painting should be done from within the context of the EDT (for component based painting)

You could try using a BufferedStrategy, which would give you direct control over the painting process, but this limits you to the AWT library. Don't know if this is good or bad in your case.

one other thing, how graphic.dispose() works correctly? , because trying to remove this line of code, nothing happens.

dispose basically releases any native resources that the Graphics context might be holding. General rule of thumb, if you didn't create, you don't dispose of it.

So if you use Graphics#create or BufferedImage#createGraphics to obtain a Graphics context, then you should call dispose when your done with it.

On some systems calling dispose on the Grpahics context used to perform painting of components (such as that passed to paintComponent or obtained from getGraphcis) can prevent further content from been painted.

Equally, not disposing of Graphics contexts that you have created can lead to memory leaks as they won't get garbage collected...

Altri suggerimenti

There are many questions about "good" or "correct" painting in Swing, so this question could be considered as a duplicate, and I won't try to repeat here what should be read in context, for example, in the Lesson about Performing Custom Painting.

However, to summarize the most important information short and concisely:

  • You should never call getGraphics on a Component. It may return null or a Graphics object that is in any other way "invalid". It will fail in the one form or the other, sooner or later
  • You should do all your painting operations in the paintComponent method (or in methods that are called from paintComponent), using the Graphics object that you receive there as an argument
  • Whether or not you call the Graphics#dispose method may not make a difference that is "immediately" visible. You should not call it on the one that you received in the paintComponent. You should only call it on a Graphics object that you either obtained from a BufferedImage, or one that you created by calling Graphics#create(). When you do not call it, this might cause a memory leak that will only be noticed after the application has been running for a while.
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top