как сохранить панель как изображение в качелях?

Привет, я хочу преобразовать панель, содержащую такие компоненты, как ярлык и кнопки, в файл изображения.

Я сделал следующий код. Изображение было сохранено. но содержимое панели не видно и не сохраняется. Может кто подскажет как сохранить панель с ее компонентами.

Код:

package PanelToImage;

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.*;

public class sample extends JPanel {

public JPanel firstpanel;
public JPanel secondpanel;
JLabel label1, label2;
JButton button1, button2;

public sample() {
    firstpanel = new JPanel();
    firstpanel.setSize(400,300); 
    firstpanel.setBackground(Color.RED);
    secondpanel = new JPanel();
    secondpanel.setBackground(Color.GREEN);
    secondpanel.setSize(400,300); 

    label1 = new JLabel("label1");
    label2 = new JLabel("label2");
    button1 = new JButton("button1");
    button2 = new JButton("button2");

    firstpanel.add(label1);
    firstpanel.add(button1);

    secondpanel.add(label2);
    secondpanel.add(button2);

    saveImage(firstpanel);

    add(firstpanel);

    // add(secondpanel);
}

public static void main(String args[]) {

    JFrame frame = new JFrame();
    sample sam = new sample();
    frame.setContentPane(sam);
    frame.setVisible(true);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setSize(400, 300);

}

private void saveImage(JPanel panel) {
    BufferedImage img = new BufferedImage(panel.getWidth(), panel.getHeight(), BufferedImage.TYPE_INT_RGB);
    panel.paint(img.getGraphics());
    try {
        ImageIO.write(img, "png", new File("E://Screen.png"));
        System.out.println("panel saved as image");

    } catch (Exception e) {
        System.out.println("panel not saved" + e.getMessage());
    }
}
}

person Babu R    schedule 30.06.2012    source источник
comment
См. ComponentImageCapture.java для отображения видимых компонентов - прокрутите вниз, чтобы найти см. также и класс Роба Camick, который берет на себя много тяжелой работы по получению изображения из компонента, который не отображался. А некоторые другие приемы рендеринга компонентов перед отображением можно увидеть в разделе Почему заголовок JTable не отображается на изображении?   -  person Andrew Thompson    schedule 30.06.2012
comment
Мне кажется, вы указываете неправильный Path для создаваемого файла. Поскольку ваша программа ничего не знает о том, что такое Drive E, поэтому на новый File, который будет создан, нужно ссылаться с помощью Relative Path по отношению к .class File, например ..\..\E:\Screen.png, заставляя его подняться на два уровня вверх, а затем обратиться к Drive E, что-то вроде это сработает. Изображение, созданное с помощью моего ответа или ответа @Alberto, создается рядом с файлом .class.   -  person nIcE cOw    schedule 30.06.2012


Ответы (2)


У меня работает этот код (в JFrame):

Container c = getContentPane();
BufferedImage im = new BufferedImage(c.getWidth(), c.getHeight(), BufferedImage.TYPE_INT_ARGB);
c.paint(im.getGraphics());
ImageIO.write(im, "PNG", new File("shot.png"));

Возможно, вы использовали пользовательские панели. Если это правда, попробуйте добавить super.paint(g) в начало paint методов ваших панелей.

EDIT: вы должны вызвать saveImage после отображения фрейма:

public static void main(String args[]) {
    ...
    frame.setSize(400, 300);
    sam.saveImage(sam.firstpanel);
}

EDIT 2: Это сохраненное изображение (маленькое из-за макета, но доказательство того, что оно должно работать):

введите здесь описание изображения

Я назвал saveImage последним вызовом в main и использовал файл в пользовательском каталоге (new File("Screen.png")) как NICE COW сказал.

person Alberto    schedule 30.06.2012
comment
я не использую метод рисования. Я просто использую панель и добавляю с ней компоненты. Но компоненты не видны при сохранении панели в изображение. - person Babu R; 30.06.2012
comment
Смотрите мою правку. Вы должны вызвать saveImage после отображения кадра. - person Alberto; 30.06.2012
comment
См. ComponentImageCapture.java для отображения видимых компонентов - прокрутите вниз, чтобы найти см. также и класс Роба Camick, который берет на себя много тяжелой работы по получению изображения из компонента, который не отображался. А некоторые другие приемы рендеринга компонентов перед отображением можно увидеть в разделе Почему заголовок JTable не отображается на изображении? - person Andrew Thompson; 30.06.2012
comment
извините, я не могу преобразовать панель в изображение с компонентами. проблема не решена. - person Babu R; 30.06.2012
comment
Но пробовали ли вы звонить saveImage после setVisible? Оно работает? - person Alberto; 30.06.2012

Вот попробуйте этот пример программы, вместо использования getGraphics() вам нужно использовать createGraphics() для BufferedImage, который вы собираетесь сделать.

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.*;

public class SnapshotExample
{
    private JPanel contentPane;

    private void displayGUI()
    {
        JFrame frame = new JFrame("Snapshot Example");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        contentPane = new JPanel();
        contentPane.setOpaque(true);
        contentPane.setBackground(Color.WHITE);
        JLabel label = new JLabel("This JLabel will display"
                        + " itself on the SNAPSHOT", JLabel.CENTER);
        contentPane.add(label);

        frame.setContentPane(contentPane);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);

        makePanelImage(contentPane);
    }

    private void makePanelImage(Component panel)
    {
        Dimension size = panel.getSize();
        BufferedImage image = new BufferedImage(
                    size.width, size.height 
                              , BufferedImage.TYPE_INT_RGB);
        Graphics2D g2 = image.createGraphics();
        panel.paint(g2);
        try
        {
            ImageIO.write(image, "png", new File("snapshot.png"));
            System.out.println("Panel saved as Image.");
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }

    public static void main(String... args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            public void run()
            {           
                new SnapshotExample().displayGUI();
            }
        });
    }
}
person nIcE cOw    schedule 30.06.2012
comment
См. ComponentImageCapture.java для отображения видимых компонентов - прокрутите вниз, чтобы найти см. также и класс Роба Camick, который берет на себя много тяжелой работы по получению изображения из компонента, который не отображался. А некоторые другие приемы рендеринга компонентов перед отображением можно увидеть в разделе Почему заголовок JTable не отображается на изображении? - person Andrew Thompson; 30.06.2012
comment
@AndrewThompson: Спасибо за эти ценные ссылки, я видел этот последний вопрос однажды, когда только начал изучать Painting in Swing, хотя в то время все это вылетело из головы. Но на этот раз надеюсь, что смогу многому научиться на этих примерах :-). Еще раз спасибо. Ваше здоровье - person nIcE cOw; 30.06.2012