2

I am trying to create a BufferedImage from a JPanel, without using a JFrame. Yesterday, I was finally able to get the image to appear with help from this community (see below), but now I'm having some layout trouble. All of the components on the BufferedImage begin drawing at 0,0, instead of following the layout manager. Does anyone know of a solution for this problem?

Yesterday's question: Can I create a BufferedImage from a JPanel without rendering in a JFrame?

In the code below, the two labels will overwrite each other in the top left corner of the image.

import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.image.BufferedImage;

import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

public class RenderTest {

        RenderTest() {
        JPanel panel = new JPanel();
        panel.setBackground(Color.RED);
        panel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
        Dimension dim = new Dimension(150,50);
        panel.setSize(dim);
        panel.setMinimumSize(dim);
        panel.setMaximumSize(dim);
        panel.setPreferredSize(dim);
        JLabel label = new JLabel("hello");
        JLabel label2 = new JLabel(" world");
        label.setSize(label.getPreferredSize());
        label2.setSize(label2.getPreferredSize());
        panel.add(label);
        panel.add(label2);

        BufferedImage bi = getScreenShot(panel);
        JOptionPane.showMessageDialog(null, new JLabel(new ImageIcon(bi)));
    }

    private BufferedImage getScreenShot(JPanel panel){
        BufferedImage bi = new BufferedImage(
            panel.getWidth(), panel.getHeight(), BufferedImage.TYPE_INT_ARGB);
        panel.paint(bi.getGraphics());
        return bi;
    }

    public static void main(String[] args) {
        new RenderTest();
    }
}
Community
  • 1
  • 1
Brooke
  • 175
  • 1
  • 1
  • 8
  • (chuckle) My initial suspicions turned out to be wrong. Huh.. OK. What is the ultimate purpose of all this? What user feature are you hoping to offer? I can think of several different ways to achieve a variety of features. – Andrew Thompson Sep 19 '12 at 18:51
  • I am painting BufferedImages, pixel by pixel, for the project I'm working on. Then I need to add a corresponding scale, title information, etc to that image to be saved onto a PowerPoint slide. Currently, I set it up by laying everything out on a JPanel, getting a “screenshot” of that panel, and using Apache POI to save a that BufferedImage to a PowerPoint slide. Does that make sense? Is there another way that I’m not thinking of? – Brooke Sep 19 '12 at 19:07
  • Good explanation. See if my latest answer does it for you. – Andrew Thompson Sep 19 '12 at 19:12

2 Answers2

4

More tips from the queen. 'Call addNotify()'.

import java.awt.*;
import java.awt.image.BufferedImage;
import javax.swing.*;
import javax.swing.border.EmptyBorder;

public class RenderTest {

    RenderTest() {
        JPanel panel = new JPanel(new GridLayout(0,1,10,10));
        panel.setBackground(Color.RED);
        panel.setBorder(new EmptyBorder(5,25,5,25));

        JLabel label = new JLabel("hello");
        panel.add(label);
        JLabel label2 = new JLabel("goodbye");
        panel.add(label2);

        panel.addNotify();
        panel.setSize(panel.getPreferredSize());
        panel.validate();

        BufferedImage bi = getScreenShot(panel);
        JOptionPane.showMessageDialog(null, new JLabel(new ImageIcon(bi)));
    }

    private BufferedImage getScreenShot(JPanel panel){
        BufferedImage bi = new BufferedImage(
                panel.getWidth(), panel.getHeight(), BufferedImage.TYPE_INT_ARGB);
        panel.paint(bi.getGraphics());
        return bi;
    }

    public static void main(String[] args) {
        new RenderTest();
    }
}

BTW - I would not recommend setting the sizes to arbitrary dimensions and then attempt to combine that with layouts. Just thought I'd mention that since I'm getting the impression that is what you want. This is a situation where we might position everything exactly so that is one way to go, but choose one approach or the other.

Community
  • 1
  • 1
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • +1 but I think that JPanel is not isDisplayable, then have to look for hack – mKorbel Sep 19 '12 at 19:24
  • It looks like it's going to work but it's being kind of finicky with the dimensions. Can you give me a quick example of what you mean (in regards to the arbitrary dimensions)? I'm not sure I understand. – Brooke Sep 19 '12 at 19:36
  • HOORAY! It worked! I've been messing with this for days! Thanks so much guys! – Brooke Sep 19 '12 at 20:09
0
JLabel label = new JLabel("hello");
panel.add(label);
JLabel label2 = new JLabel("goodbye");
panel.add(label2);

Could this be a system requined process?

I'm not sure, but the tree looks like it might.

Cole Tobin
  • 9,206
  • 15
  • 49
  • 74