拍摄JPanel的快照并在新窗口中显示

时间:2016-11-29 10:34:04

标签: java swing snapshot

我创建了一个扩展JPanel并覆盖paint()方法的图表。当我点击这个面板时,我想创建一个"快照"的图表并在新的JFrame中打开。

我尝试创建一个缓冲图像,如下所示,但问题是,当我调整窗口大小时,我的质量会大打折扣。

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class SnapshotDemo extends JPanel{

    private JComponent src;
    private BufferedImage img;
    private final JFrame f = new JFrame();

    public SnapshotDemo(JComponent src) {
        super(new BorderLayout());
        this.src = src;
        this.img = takeSnapshot(src);
    }


    @Override
    public void paint(Graphics g) {
        Graphics2D g2 = (Graphics2D)g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2.drawImage(img, 0, 0, getWidth(), getHeight(), null);
    }

    public void display(){
        f.setContentPane(this);
        f.setSize(1000,600);
        f.setVisible(true);
    }

    public static BufferedImage takeSnapshot(JComponent src){
        BufferedImage i = new BufferedImage(src.getWidth(), src.getHeight(), BufferedImage.TYPE_INT_RGB);
        Graphics2D g2 = i.createGraphics();
        src.printAll(g2);
        return i;
    }

    public static void main(String[] args) {
        JPanel p = new JPanel(){
            @Override
            public void paint(Graphics g) {
                super.paint(g);
                Graphics2D g2 = (Graphics2D)g.create();
                g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
                int x = 0;
                int y = 0;
                int stepx = getWidth()/5;
                int stepy = getHeight()/5;
                for(int i=0; i<10; i++){
                    g2.drawLine(x, y, x+stepx, y+stepy);
                    x+=stepx;
                    y+=stepy;
                }
                g2.setPaint(Color.red);
                g2.drawOval(getWidth()/2-30, getHeight()/2-30, 60, 60);
            }
        };
        p.addMouseListener(new MouseListener() {
            @Override
            public void mouseReleased(MouseEvent e) {}  
            @Override
            public void mousePressed(MouseEvent e) {}
            @Override
            public void mouseExited(MouseEvent e) {}
            @Override
            public void mouseEntered(MouseEvent e) {}
            @Override
            public void mouseClicked(MouseEvent e) {
                SnapshotDemo d = new SnapshotDemo(p);
                d.display();
            }
        });
        JFrame f = new JFrame();
        f.setContentPane(p);
        f.setSize(1000, 600);
        f.setVisible(true);
    }
}

有关如何更好地处理此问题的任何想法?有没有办法避免使用图像(BufferedImage等...)? 提前谢谢。

1 个答案:

答案 0 :(得分:0)

  

但问题是,当我调整窗口大小时,我会失去很多质量。

当你调整任何图像大小时,你会失去质量。这称为像素化。如果您不想放松质量,请不要将图像调整得更大。

  

我创建了一个扩展JPanel并覆盖paint()方法的图表。

不要覆盖paint()。自定义绘画是通过覆盖paintComponent(...)完成的,并且在方法开始时不要忘记super.paintComponent(...)

但你为什么要创建自定义面板呢?只需使用BufferedImage创建ImageIcon,然后将ImageIcon添加到JLabel即可。这样,图像将始终以其实际大小显示,因此调整窗口大小不会影响质量。