Note that there are some explanatory texts on larger screens.

plurals
  1. POIs this a good design for creating smooth animations in Java/Swing?
    primarykey
    data
    text
    <p>I have a JPanel subclass with custom paintComponent() implementation. It is being refreshed at 50fps. It is typically in the range of 500x300 pixels in size. I'm seeing some flickering (not too bad but noticeable) and I've inserted some debug code that indicates that Swing/EDT is skipping (presumably) redundant painting. I am guessing that's because the EDT is not giving enough time for paintComponent() to always finish or it is taking too much time on the EDT.</p> <p>My thinking is that I need to take the code currently implementing paintComponent() (which is not very complex but not completely trivial either) and refactor it so it is executed on its own Thread (or at least not the EDT) and draws to an ImageBuffer. I then implement paintComponent on my custom JPanel and draw (render) from the ImageBuffer to the screen (actually to the buffer behind Swing components as my research into the solution led me some information about Swing being (by default) double-buffered, though I'm not completely clear on that). If it is true that the rendering from the ImageBuffer to the JPanel is faster than my implementation that constructs the ImageBuffer then I will be going in the right direction.</p> <p>Is this the proper design direction for me to take?</p> <p><strong>UPDATE</strong></p> <p>I modified my implementation as discussed in reponses below:</p> <p>1) Create a BufferedImage</p> <p><code>BufferedImage myBufferedImage = new BufferedImage(mySize.width,mySize.height,BufferedImage.TYPE_INT_ARGB)</code></p> <p>2) Create a Thread dedicated to peforming the processing to determine what is to be drawn.</p> <p>3) Move the code previously in paintComponent() to another method that is executed by the dedicated Thread. At the end of this method, call repaint();</p> <p>4) Create a new paintComponent() that simply calls <code>g.drawImage(myBufferedImage,0,0,null);</code></p> <p>5) Where I previously would call repaint(), trigger myThread to perform the drawing to myBufferedImage.</p> <p>This was a disaster, as predicted. Much worse flickering and sluggishness, partial paints, etc. I believe this was due to contention reading/writing myBufferedImage (as mentioned below). So I then created a lock and lock myBufferedImage when I am writing to it (in the dedicated drawing Thread) and wait to get that lock in paintComponent() before calling Graphics2D.drawImage(); The flicker and partial paints go away - but performance is no better (maybe even worse) than when I was doing all the calculations for the drawing in paintComponent (and therefore in the EDT). </p> <p>This has me stumped at this point.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload