0

I have found this code which transfer a JPanel to an image and then print it to PDF file but since I have that my JPanel inside a JScrollPane and does not contain any layout or dimensions because it depends on the JScrollPane layout so I can't print it. the error says can't print a picture with height 0 and width 0. When I try to pass the JScrollPane itself I get just the frame of the JScrollPane printed only without the content JPanel.

public void printToPDF(java.awt.Image awtImage, String fileName) {
    try {
        Document d = new Document();
        PdfWriter writer = PdfWriter.getInstance(d, new FileOutputStream(
                fileName));
        d.open();


        Image iTextImage = Image.getInstance(writer, awtImage, 1);
        //iTextImage.setAbsolutePosition(100,300);
        iTextImage.scalePercent(100);
        d.add(iTextImage);

        d.close();

    } catch (Exception e) {
        e.printStackTrace();
    }   
}

public static java.awt.Image getImageFromPanel(Component component) {

    BufferedImage image = new BufferedImage(component.getWidth(),
            component.getHeight(), BufferedImage.TYPE_INT_RGB);
    component.paint(image.getGraphics());
    return image;
}

and Here is the main method:

         JScrollPane scrollPane = new JScrollPane();
    scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
    scrollPane.setBounds(0, 0, 600, 510);
    scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
    getContentPane().add(scrollPane);

    GridBagConstraints c = new GridBagConstraints();
    JPanel borderpanel = new JPanel();
    scrollPane.setViewportView(borderpanel);

    Color veryLight = new Color(239,230,230);
    JPanel container = new JPanel();
    borderpanel.add(container, BorderLayout.CENTER);
    container.setLayout(new GridLayout(0,1,0,1));
    container.setBackground(Color.WHITE);

    JPanel test = new JPanel();
    test.setLayout(new GridLayout(0,1,0,1));
    container.add(test, BorderLayout.CENTER);

        JPanel rowPanel = new JPanel();
        rowPanel.setPreferredSize(new Dimension(580,50));
        test.add(rowPanel, BorderLayout.WEST);
        rowPanel.setLayout(null);

        JLabel auctionTitle = new JLabel("Auction Title");
        auctionTitle.setForeground(Color.WHITE);
        auctionTitle.setFont(new Font("Tahoma", Font.PLAIN, 14));
        auctionTitle.setBounds(102, 0, 82, 20);
        rowPanel.add(auctionTitle); 
        rowPanel.setBackground(SystemColor.GRAY);

        JTextArea textArea = new JTextArea();
        textArea.setBackground(veryLight);
        textArea.setBounds(191, 0, 386, 50);
        rowPanel.add(textArea);


        final java.awt.Image image = getImageFromPanel(borderpanel);

        String fileName = "C:\\Users\\Test\\Desktop\\newfile.pdf";
        printToPDF(image, fileName);

I want to print borderpanel

Hussein
  • 653
  • 3
  • 10
  • 28
  • do you set anything to visible yet? – gpasch Apr 07 '16 at 12:56
  • I can see everything when I run it @gpasch – Hussein Apr 07 '16 at 12:57
  • 1
    yea but I dont see anything in between here: rowPanel.add(textArea); final java.awt.Image image = getImageFromPanel(borderpanel); is the borderPanel visible in this vicinity? no matter how you see it at the end. Check where the dmensions are zero. – gpasch Apr 07 '16 at 13:22
  • I have add setvisible on every component and still the same. I think I know where is the problem just how I described it before. I am passing a component without dimensions because it from Grid-layout and depends completely on the JScrolpane dimensions. I am getting Image of a label If I pass a label since the label have dimensions and even when it invisible @gpasch – Hussein Apr 07 '16 at 13:42

1 Answers1

1

Use java.awt.Robot to get the image of the panel:

public static java.awt.Image getImageFromPanel(Component component) {

    Point p = new Point(0, 0);
    SwingUtilities.convertPointToScreen(p, component);

    int width = component.getSize().width;
    int height = component.getSize().height;
    Rectangle screenBounds = new Rectangle(p.x, p.y, width, height);

    Robot robot = new Robot();
    BufferedImage image = robot.createScreenCapture(screenBounds);

    component.getGraphics().drawImage(image, 0, 0, component);

    return image;
} 
rdonuk
  • 3,921
  • 21
  • 39
  • Mate My problem not with how to get the image, because I can get Image of a label for example if I pass a label. The problem is with the height and width of the panel I pass. Since the panel in Grid-layout and depends completely on the dimensions of the JScrollpane so theoretically when I pass the Panel I am passing component without dimensions. By the way I have tried your code and getting the same error "Rectangle width and height must be > 0" – Hussein Apr 07 '16 at 13:37
  • 1
    I see. May be getting size information from the scroll pane can solve you issue. `getImageFromPanel(Component component, int width, int height)`. Call method like this: `getImageFromPanel(borderpanel, scrollPane.getWidth(), scrollPane.getHeight());` – rdonuk Apr 07 '16 at 13:42
  • It prints a block of black only because the actual JPanel "borderpanel" has no dimensions. Can you please give me a way to set dimensions for that panel along with the using of GridLayout. – Hussein Apr 07 '16 at 13:49
  • by the way, you are calling the `getImageFromPanel` after call `setVisible` for your main JFrame, right? – rdonuk Apr 07 '16 at 14:01