在一个简短的方法中,我使用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
}
}
答案 0 :(得分:4)
这是因为每个AWT窗口都有一个与屏幕上图像保持同步的离屏图像。显示窗口时,其内容将直接从屏幕外图像中绘制。这发生在工具包线程上,而不是在事件派发线程上。
仅在显示窗口后,才会在事件派发线程上重新绘制帧。
在Java 1.6之前,AWT中没有每窗口双缓冲,所以你会看到一个灰色的背景,这是臭名昭着的“灰色矩形”问题。
我所知道的唯一解决方法是每次都创建一个新框架。您可以重用旧框架的内容面板,因此开销不是很高。
答案 1 :(得分:3)
我意识到这个答案是在提出问题一年后提出来的,但我遇到了类似的问题,当然在我试图解决之前已经研究了一下。对于遇到此问题的任何人,请在打包之前尝试丢弃窗口/框架并使其可见。