There are several options.
One way is to use two BufferedImages, where you draw one in a separate stream and draw from the other, and switch at the end of the drawing (for what I assume, this is a snapshot so often.)
A much better solution is to have a model of directly visualized data (as in the data that it stores, it can be carried out without any further algorithmic work on it).
This means that you will execute your alogirthms in a separate thread, calculate the values ββthat will be used for drawing, call SwingUtilities.invokeLater to update the model. Then the model will be updated only in the Swing stream, and when you redraw, you have access to exactly the data that you need for drawing (and without extraneous data).
If this data is still so much that drawing takes a lot of time (i.e. if you draw diagrams with tons of data points), you will send to calculate which parts of your window need to be repainted and rewritten () only on this. However, this piece should be a lat resort. 99% of your productivity will depend on moving the algorithms to a separate stream and providing the painter access to directly visualized data.
If you look at the recommendations for updating TableModel with external data, then you have a job that receives the data happening in the background thread (usually SwingWorker) and then is sent to the actual model via invokeLater () (This is why the data does not change until your paint () tries to read it.), and then fires the appropriate events from the model update, which tell the table which cells have been changed. The table then knows how much of its viewport needs to be repainted and calls the corresponding repaint () method. During this time, the background thread may continue to retrieve data and add new updates to the event queue through invokeLater.
source share