.setVisible (true) immediate repainting

In the short method, I hide the JFrame using setVisible (false). Then I take a screenshot and restore the JFrame with setVisible (true).

After it becomes visible again, the window should display a different image than before (say, part of this screenshot).

The problem is that after calling setVisible (true), the window blinks with the old content for a second of a second before calling paintComponent and an updated state appears.

Perhaps I could get around this ugly, but I wanted to know if there are better solutions.

Thank you in advance for your help.

edit: When preparing the example, I noticed that the effect was practically not observed when I did not use transparency, as in my program. It must have already been mentioned. Here is what I came up with:

import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Toolkit; import javax.swing.JFrame; import javax.swing.JPanel; import com.sun.awt.AWTUtilities; public class Test { static boolean flag = false; static Dimension scrSize = Toolkit.getDefaultToolkit().getScreenSize(); public static void main(String[] args) throws InterruptedException { JFrame frame = new JFrame(); frame.setUndecorated(true); AWTUtilities.setWindowOpaque(frame, false); //draw on a transparent window frame.setSize(scrSize.width, scrSize.height); frame.setContentPane(new JPanel() { protected void paintComponent(Graphics g) { if (Test.flag) { g.setColor(Color.RED); g.drawRect(50, 50, scrSize.width - 100, scrSize.height - 100); } else { g.setColor(Color.GREEN); g.fillOval(50, 50, scrSize.width - 100, scrSize.height - 100); } } }); frame.setVisible(true); //green oval shown Thread.sleep(1000); frame.setVisible(false); flag = true; // next draw produces red rectangle Thread.sleep(1000); frame.setVisible(true); // before the next draw, // you can see a flash of the green oval } } 
+4
source share
2 answers

I understand that this answer is proposed a year after the question was asked, but I had a similar problem, and of course I did a little research before trying to solve it. For those who are faced with this question, try removing your window / frame before repacking and making it visible.

+3
source

This is because each AWT window has an off-screen image that synchronizes with the on-screen image. When a window is displayed, its contents are painted directly from the image off-screen. This happens in the tool stream, not in the event dispatch stream.

Only after the window is displayed, the frame is redrawn in the event sending stream.

Prior to Java 1.6, AWT did not double-window buffering, so you saw a gray background that was the notorious gray rectangle problem.

The only workaround I know is to create a new frame every time. You can reuse the contents panel of the old frame, so the overhead is not so high.

+4
source

All Articles