我有一个创建新线程的类。
`
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上。 在主要内容中,我将使用我创建的图像调用绘图。有时它可以工作,但有时面板上的图像会闪烁。我尝试了绘图功能等绘图功能。他们没有工作。我只能减少闪烁。
答案 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 PanelR
或BufferedImage 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.