2016-11-29 5 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 основан на архитектуре model-view-controller и, таким образом, отображает только состояние модели. Таким образом, вы можете сделать снимок модели и использовать ее с другим экземпляром представления, и она будет изменяться. Для получения дополнительной информации о mvc см. Http://www.oracle.com/technetwork/articles/javase/index-142890.html и, возможно, https://www.link-intersystems.com/blog/2013/07/20/the-mvc-pattern-implement-with-java-swing/ –

ответ

0

, но проблема в том, что при изменении размера окна я теряю много качества.

При изменении размера изображения вы теряете качество. Это называется pixilation. Если вы не хотите потерять качество, не изменяйте размер изображения больше.

Я создал диаграмму, расширяющую JPanel и отмену метода paint().

Не переопределяйте краску(). Пользовательская покраска выполняется путем переопределения paintComponent(...) и не забудьте указать super.paintComponent(...) в начале метода.

Но почему вы даже создаете пользовательскую панель. Просто используйте BufferedImage, чтобы создать ImageIcon, а затем добавьте ImageIcon в JLabel. Таким образом, изображение всегда будет отображаться по фактическому размеру, поэтому изменение размера окна не повлияет на качество.

+0

Это то, что я сделал сначала. Но мне было интересно, есть ли способ увеличить моментальный снимок без потери качества, так как это было бы очень полезно для пользователя. Я знаю, что это возможно невозможно через изображения ('Image',' ImageIcon' или что-то еще), поэтому мой вопрос заключается в том, есть ли другой способ достижения моей цели. – Roberto

+0

Это не имеет ничего общего с Java. Вы просто не можете сделать изображение больше без потери качества. Вы когда-нибудь пробовали масштабирование изображения, которое вы снимаете с помощью своей камеры? – camickr