.setVisible(true)立即重绘

时间:2011-10-12 01:17:23

标签: java swing transparency visibility repaint

在一个简短的方法中,我使用setVisible(false)隐藏JFrame。 然后我截取屏幕截图并使用setVisible(true)恢复JFrame。

再次显示后,窗口应该显示与之前不同的图片(比如说截图的一部分)。

问题是,在调用setVisible(true)之后,在调用paintComponent并绘制更新状态之前,窗口会使用旧内容闪烁一秒钟。

我可能会以丑陋的方式解决这个问题,但我想知道是否有更好的解决方案。

提前感谢您提供任何帮助

编辑:在准备一个例子的时候,我注意到,当我不在程序中使用透明度时几乎看不到效果。应该提到这一点。以下是我提出的建议:

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
    }

}

2 个答案:

答案 0 :(得分:4)

这是因为每个AWT窗口都有一个与屏幕上图像保持同步的离屏图像。显示窗口时,其内容将直接从屏幕外图像中绘制。这发生在工具包线程上,而不是在事件派发线程上。

仅在显示窗口后,才会在事件派发线程上重新绘制帧。

在Java 1.6之前,AWT中没有每窗口双缓冲,所以你会看到一个灰色的背景,这是臭名昭着的“灰色矩形”问题。

我所知道的唯一解决方法是每次都创建一个新框架。您可以重用旧框架的内容面板,因此开销不是很高。

答案 1 :(得分:3)

我意识到这个答案是在提出问题一年后提出来的,但我遇到了类似的问题,当然在我试图解决之前已经研究了一下。对于遇到此问题的任何人,请在打包之前尝试丢弃窗口/框架并使其可见。