Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/306.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java .setVisible(true)立即重新绘制_Java_Swing_Transparency_Visibility_Repaint - Fatal编程技术网

Java .setVisible(true)立即重新绘制

Java .setVisible(true)立即重新绘制,java,swing,transparency,visibility,repaint,Java,Swing,Transparency,Visibility,Repaint,在一个简短的方法中,我使用setVisible(false)隐藏JFrame。 然后我截图并用setVisible(true)恢复JFrame 在再次显示后,窗口应该显示与以前不同的图片(比如说拍摄的部分屏幕截图) 问题是,在调用setVisible(true)之后,在调用paintComponent并绘制更新状态之前,窗口会以旧内容闪烁一秒钟 我可能会用一种丑陋的方式来解决这个问题,但我想知道是否有更好的解决方案 提前谢谢你的帮助 编辑:在准备一个示例时,我注意到,如果不像我在程序中那样使用透

在一个简短的方法中,我使用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
    }

}

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

只有在显示窗口后,帧才会在事件分派线程上重新绘制

在Java1.6之前,AWT中没有每窗口双缓冲,因此您可能会看到一个灰色背景,这就是臭名昭著的“灰色矩形”问题


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

我意识到这个答案是在提出问题一年后提出的,但我也遇到了类似的问题,当然在尝试解决它之前也做了一些研究。对于遇到此问题的任何人,请尝试在打包前处理您的窗口/框架并使其可见。

在框架再次可见之前设置图像。确保代码在事件分派线程上执行。如果您需要更多帮助,请发布您的日志。使用
EventQueue.invokeLater()
对更改进行排序。无法重现,是进行SSCE的时候了,正如@camickr已经建议的那样听起来有点合理-只是:我根本无法重现问题。因此,在使用新创建的框架之前,我建议找出真正的原因:-)它只会发生在复杂的框架中,并且只有在框架中的某些内容不可见时才发生。我的回答解释了原因。好了,除了创建一个新的框架之外,你什么也做不了。正如我所说的:推理听起来不错,我当然会在再次展示之前更改内容(否则我怎么可能尝试复制)。所以区别可能是复杂的部分,有多复杂?从屏幕外图像显示和绘制框架,然后验证并重新绘制根窗格。根据日志记录的方式,你仍然会看到旧内容一段时间。是的,我理解其中的原因。。。直到我看到它(固执的我:)最终还是会在我的上网本上试用。谢谢这应该是公认的答案。每次显示对话框时都创建一个新框架是不可接受的。您确定可以处理窗口吗?我想我在Oracle文档中读到,这释放了本机资源,只有在完成框架/窗口时才能完成。