The power of paintAll () to paint an invisible JPanel and its components?

I am working on printing a series of JPanels on Printable , the main printing interface that provides a Graphics object that you draw what you want to print. If I have a live JPanel, that is, somewhere in the user interface, everything works fine.

However, if I create a JPanel and never add it to the user interface, printAll () does not seem to do anything. Code abbreviation to SSCCE:

import java.awt.Color; import java.awt.Graphics; import java.awt.image.BufferedImage; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; public class SSCCEPaintInvisible { public static void main(String[] args) { /* Create an JPanel with a JLabel */ JPanel panel = new JPanel(); //panel.setLayout(new FlowLayout()); JLabel label = new JLabel("Hello World"); panel.add(label); //label.invalidate(); //panel.invalidate(); /* Record a picture of the panel */ BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_4BYTE_ABGR); Graphics g = image.getGraphics(); /* Draw something to ensure we're drawing */ g.setColor(Color.BLACK); g.drawLine(0, 0, 100, 100); /* Attempt to draw the panel we created earlier */ panel.paintAll(g); // DOES NOTHING. :( /* Display a frame to test if the graphics was captured */ JFrame frame = new JFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JLabel label2 = new JLabel( new ImageIcon(image) ); frame.add(label2); frame.pack(); frame.setVisible(true); // shows ONLY the black line we drew in the Graphics } } 

If I create a JFrame for the panel and add the panel to the JFrame and make the JFrame visible before calling paintAll (), the code captures the user interface on the chart as expected. Of course, this means that the screen displays a JFrame for printing. A.

Is there a JPanel rendering method that has never been added to the user interface in a Graphics object? Thanks!

+4
source share
1 answer

From the answer prompts @ Cleopatra.

SSCCEPaintInvisible

 import java.awt.*; import java.awt.image.BufferedImage; import javax.swing.*; public class SSCCEPaintInvisible { public static void main(String[] args) { /* Create an JPanel with a JLabel */ JPanel panel = new JPanel(); JLabel label = new JLabel("Hello World"); panel.add(label); // Next 3 are very important! panel.setSize(panel.getPreferredSize()); panel.addNotify(); panel.doLayout(); /* Record a picture of the panel */ BufferedImage image = new BufferedImage(100, 100, BufferedImage.TYPE_4BYTE_ABGR); Graphics g = image.getGraphics(); /* Draw something to ensure we're drawing */ g.setColor(Color.BLACK); g.drawLine(0, 0, 100, 100); /* Attempt to draw the panel we created earlier */ panel.paintAll(g); // DOES NOTHING. :( /* Display a frame to test if the graphics was captured */ JFrame frame = new JFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JLabel label2 = new JLabel( new ImageIcon(image) ); frame.add(label2); frame.pack(); frame.setVisible(true); // shows ONLY the black line we drew in the Graphics } } 

As @GagandeepBali pointed out, this GUI is not created on EDT. The results will be unpredictable if changes to the GUI are not made in the EDT. See Concurrency in Swing and especially Starter Topics for more details.

+3
source

All Articles