无法停止在JPanel

时间:2015-08-12 16:39:52

标签: java swing jpanel flicker drawimage

我有一个创建新线程的类。

`

public ScreenG(JPanel PanelR)
{
    Panel = PanelR;
    RenderImage = new BufferedImage(1, 1, BufferedImage.TYPE_INT_RGB);
    FPS = 25;
    Hide = false;

    (new Thread() 
    {
        public void run() 
        {   
              while(true)
              {
                  if(Hide == false)
                  {
                    Timer = System.currentTimeMillis() + (1000/FPS);

                    if(!DrawRendering)
                    {
                        Graphics g = Panel.getGraphics();
                        g.drawImage(RenderImage, 0, 0, null);
                    }

                    DrawRendering = false;

                    while(System.currentTimeMillis() <= Timer) try { Thread.sleep(1); } catch (InterruptedException e) {Thread.currentThread().interrupt();}
                  }
              }
        }
    }).start();
}

public void draw(BufferedImage ImageR)
{
    DrawRendering = true;
    RenderImage = ImageR;
    Graphics g = Panel.getGraphics();
    g.drawImage(RenderImage, 0, 0, null);
}`

在我的主要内容中,我创建了一个ScreenG的新实例。这将启动一个新线程,将一个bufferedImage绘制到具有一致FPS的JPanel上。 在主要内容中,我将使用我创建的图像调用绘图。有时它可以工作,但有时面板上的图像会闪烁。我尝试了绘图功能等绘图功能。他们没有工作。我只能减少闪烁。

3 个答案:

答案 0 :(得分:2)

设计不可行。 Swing不会与实际将屏幕数据发送到监视器的位图光栅DMA同步,因此当您忙于渲染时,DMA可能会读取屏幕缓冲区(可能的例外是全屏模式)。 p>

要至少尽量减少闪烁,请遵循自定义Swing绘画的推荐方法:https://docs.oracle.com/javase/tutorial/uiswing/painting/

你可以使用Swing计时器或者来自另一个线程的SwingUtilities.invokeAndWait / invokeLater轻松触发EDT上的定期重新绘制(无论你的设计中哪种效果最好)。

答案 1 :(得分:0)

闪烁可能是因为更新后渲染速度不够快。

现在我建议您在渲染其组件时使用Swing s paintComponent (Graphics g)。话虽如此。要解决闪烁问题,请在BufferStrategy

中添加JFrame

如果没有该代码,我只能提供一般解决方案。

JFrame jframe = new JFrame ();

...

BufferStrategy bufferstrategy = jframe.getBufferStrategy ();

if (bufferstrategy == null) {
    jframe.createBufferStrategy(3);
    return;
}

g.dispose();
bufferstrategy.show();

要了解有关BufferStrategy的更多信息,建议您阅读documentation

小笔记

您的代码中没有理由存储JPanel PanelRBufferedImage ImageR。您可以直接在PanelR resp上直接调用方法。 ImageR

答案 2 :(得分:0)

Thank you for the answers. I read Oracle tutorial that you recommended and get my paintComponent() function working correctly on the main thread. To do that I am calling JPanel().repaint() from the draw() function. I will learn about using BufferStrategy next.