如何在另一个线程中绘制一个JFrame?

问题描述

我试图使JFrame的paint()方法启动一个线程,然后使用Graphics渲染该线程的形状(在单独的文件中)。当我尝试执行此操作时,没有任何显示。

//JFrame
public class Window extends JFrame {

    public Window() {

        this.setTitle("Test");
        this.setSize(1280,720);
        this.setLocationRelativeTo(null);
        this.setVisible(true);

    }

    public void paint(Graphics g) {
        new ThreadForRendering(g).start();
    }
// Thread I'm trying to run
public class ThreadForRendering extends Thread {

    private final Graphics g;

    public ThreadForRendering(Graphics g) {
        this.g = g;
    }

    public void run() {
        this.g.setColor(Color.RED);
        this.g.fillRect(0,500,500);
    }
}

我尝试将super.paintComponent(g);添加到paint方法中,并在线程启动后在窗口上调用repaint(),但是窗口仍然空白。

解决方法

paint被称为对GUI线程上所需的重新绘制的响应,并且应该很快发生。突破该方案只会导致问题,黑屏问题最少。

@Override public void paintComponent应该是您的绘画实现。 应该很快。

如果要绘制复杂而缓慢的内容,可以填充BufferedImage,然后可以在paintComponnent中绘制。

private AtomicReference<BufferImage> imgRef = new AtomicReference<>();

@Override
public void paintComponent(Graphics g) {
    Graphics2D g2 = (Graphics2D)g;
    BufferedImage img = img.get();
    if (img != null) {
        g2.draw img ...
    }
}

在线程中:

BufferedImage constructedImg = new ...
Graphics g = constructedImg.createGraphics();
try {
    g.fillRect ...
} finally {
    g.dispose();
}
imgRef.set(constructedImg);

通常,绘画是智能完成的:JPanel通常是双缓冲,绘画是在缓冲区中完成的,然后覆盖实际显示的缓冲区。因此,在大多数情况下,不需要解析到另一线程。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...