简体   繁体   中英

Java draw to Graphics in own thread, outside EDT?

I am coding a Swing Application, it uses Apache PDFBox to draw a PDF page to the Graphics2D object of a JPanel in the paintComponent method. The drawing takes a while, so when my application needs to display many PDF pages simultaneously, it get's slow and laggy. I know, since the JPanel I draw the PDF page to is part of the GUI, it needs to be drawn in the Event Dispatch Thread. But is there absolutely no possibility to draw each JPanel in an own thread? Like using SwingWorker or so?

Example code (simplified):

public class PDFPanel extends JPanel {
    @Override
    protected void paintComponent(Graphics graphics) {
        super.paintComponent(graphics);

        Graphics2D g2 = (Graphics2D) graphics;
        int scale = 1;   // (simplified this line)

        g2.setColor(getBackground());
        g2.fillRect(0, 0, getWidth(), getHeight());

        try {
            pdfRenderer.renderPageToGraphics(pageNumber, g2, (float) scale, (float) scale);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

Use a BufferedImage image field. It has a method createGraphics() where you can draw to. Afterward call Graphics.dispose() to clean up resources.

Then in paintComponent check the availability of the image, for displaying it.

The rendering can be done in a Future, SwingWorker or whatever. You are right that heavy operations should never be done in paintComponent especially as it may be called repeatedly.

Better launch the rendering in the constructor, or in your controller.

    BufferedImage image = new BufferedImage(getWidth(), getHeight(),
        BufferedImage.TYPE_INT_ARGB);
    Graphics2D g2d = image.createGraphics();
    try {
        pdfRenderer.renderPageToGraphics(pageNumber, g2, (float) scale, (float) scale);
    } finally {
        g2d.dispose();
    }

Initially width and height are not filled, so better use width and height from the PDF. Also not that a Graphics2D allows scaling; you could easily add zooming.

How to atomically handle passing the rendered image is probably clear.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM