2016-11-29 57 views
0

我創建了一個擴展爲JPanel的圖表,並覆蓋了paint()方法。當我點擊這個面板時,我想創建一個圖表的「快照」,並在新的JFrame中打開它。拍攝JPanel快照並在新窗口中顯示

我嘗試通過創建一個緩衝圖像如下所示,但問題是,當我調整窗口的大小時,我失去了很多的質量。

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等)? 在此先感謝。

+0

拍攝圖表模型的快照並在新框架中使用此模型。 –

+0

你能解釋一下你的意思嗎?對不起,但我不是程序員,我需要「對於傻瓜」的解釋:D – Roberto

+1

Swing基於模型 - 視圖 - 控制器體系結構,因此視圖僅顯示模型狀態。因此,您可以拍攝模型的快照並將其與視圖的另一個實例一起使用,並且可以調整大小。有關mvc的詳細信息,請查看http://www.oracle.com/technetwork/articles/javase/index-142890.html,也許https://www.link-intersystems.com/blog/2013/07/20/the-mvc-pattern-implemented-with-java-swing/ –

回答

0

但問題是,當我調整窗口的大小,我鬆了很多質量。

當您調整任何圖像的大小時,就會失去質量。這被稱爲像素化。如果您不想失去質量,請不要調整圖像的大小。

我創建了一個擴展JPanel和覆蓋paint()方法的圖表。

請勿重寫paint()。自定義繪畫是通過覆蓋paintComponent(...)完成的,並且在方法開始時不要忘記super.paintComponent(...)

但爲什麼你甚至創建一個自定義面板。只需使用BufferedImage創建ImageIcon,然後將ImageIcon添加到JLabel。這樣,圖像將始終以實際大小顯示,因此調整窗口大小不會影響質量。

+0

這是我第一次做的。但是我想知道是否有一種方法可以在不損失質量的情況下放大快照,因爲這對用戶非常有幫助。我知道這可能是不可能通過圖像('Image','ImageIcon'或其他),所以我的問題是如果有其他方式來實現我的目標。 – Roberto

+0

這與Java無關。如果不損失質量,你就無法使圖像變大。你有沒有試過用你的相機拍攝的照片放大? – camickr