2013-10-28 1 views
3

그래픽 J (2D가 아님)로 커브 등을 JComponent에 그립니다.마우스 및 그래픽을 사용하여 확대

이제 마우스의 스크롤 휠을 사용하여 확대하고 싶습니다.

어떤 트랙이 있습니까?

내가 BuferredImage에 대해 이야기하는 것을 들었습니까?

+0

몇 가지 고려 사항이 있습니다. 기본 내용을 BufferedImage로 렌더링하더라도 구성 요소의 기본 크기를 수정해야 올바르게 배치 할 수 있습니다. AffineTransform – MadProgrammer

답변

3

시도 JFreeChart; ChartPanel에서의 줌 제어에 사용되는 setMouseWheelEnabled() 방법은 예를 들어 here에 설명되어있다.

11

고려해야 할 몇 가지 고려 사항이 있습니다. ...

최종 결과는 원하는 것에 따라 달라집니다. Graphics2D API를 사용하여 커브를 그리는 경우 구성 요소가 렌더링 될 때마다 좌표를 단순하게 스케일링하는 것이 더 간단 할 수 있습니다. 축척의 변경 사항이 구성 요소 자체의 기본 크기에 반영되는지 확인해야합니다.

"default"출력을 BufferedImage으로 렌더링하고 AffineTransform을 사용하여 결과를 렌더링하는 데 사용되는 배율을 간단히 변경할 수도 있습니다.

이 간단한 내용은 BufferedImage을 사용하고 디스크에서 그림을로드하지만 기본 개념은 같습니다.

import java.awt.BorderLayout; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseWheelEvent; 
import java.awt.geom.AffineTransform; 
import java.awt.image.BufferedImage; 
import java.io.File; 
import java.io.IOException; 
import javax.imageio.ImageIO; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class ZoomPane { 

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

    public ZoomPane() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 
       frame.add(new JScrollPane(new TestPane())); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class TestPane extends JPanel { 

     private BufferedImage img; 
     private float scale = 1; 

     public TestPane() { 
      try { 
       img = ImageIO.read(new File("/path/to/image")); 
      } catch (IOException ex) { 
       ex.printStackTrace(); 
      } 
      addMouseWheelListener(new MouseAdapter() { 

       @Override 
       public void mouseWheelMoved(MouseWheelEvent e) { 
        double delta = 0.05f * e.getPreciseWheelRotation(); 
        scale += delta; 
        revalidate(); 
        repaint(); 
       } 

      }); 
     } 

     @Override 
     public Dimension getPreferredSize() {    
      Dimension size = new Dimension(200, 200); 
      if (img != null) {    
       size.width = Math.round(img.getWidth() * scale); 
       size.height = Math.round(img.getHeight() * scale);     
      }   
      return size; 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      if (img != null) { 
       Graphics2D g2d = (Graphics2D) g.create(); 
       AffineTransform at = new AffineTransform(); 
       at.scale(scale, scale); 
       g2d.drawImage(img, at, this); 
       g2d.dispose(); 
      } 
     } 
    } 

} 

또한 Graphics 문맥 직접 paintComponent 메서드에 전달 확장 할 수 있습니다.

여기서 중요한 것은

이 예 ... 그렇지 않으면 예상 출력을 생성하지 않습니다들은이 렌더링되는 다른 구성 요소에 전달 될 것입니다, 당신이 완료 한 후 AffineTransform을 다시 기억하는 것입니다 기본적으로 자세한 내용은 Transforming Shapes, Text and Images를 살펴 보자

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseWheelEvent; 
import java.awt.geom.AffineTransform; 
import java.awt.geom.GeneralPath; 
import java.awt.geom.Path2D; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class ZoomPane { 

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

    public ZoomPane() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 
       frame.add(new JScrollPane(new TestPane())); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class TestPane extends JPanel { 

     private float scale = 1; 

     public TestPane() { 
      addMouseWheelListener(new MouseAdapter() { 

       @Override 
       public void mouseWheelMoved(MouseWheelEvent e) { 
        double delta = 0.05f * e.getPreciseWheelRotation(); 
        scale += delta; 
        revalidate(); 
        repaint(); 
       } 

      }); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      Dimension size = new Dimension(200, 200); 
      size.width = Math.round(size.width * scale); 
      size.height = Math.round(size.height * scale); 
      return size; 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      Graphics2D g2d = (Graphics2D) g.create(); 
      AffineTransform at = new AffineTransform(); 
      at.scale(scale, scale); 
      g2d.setTransform(at); 

      g2d.setColor(Color.RED); 

      // This is for demonstration purposes only 
      // I prefer to use getWidth and getHeight 
      int width = 200; 
      int height = 200; 

      Path2D.Float path = new Path2D.Float(); 
      int seg = width/3; 
      path.moveTo(0, height/2); 
      path.curveTo(0, 0, seg, 0, seg, height/2); 
      path.curveTo(
        seg, height, 
        seg * 2, height, 
        seg * 2, height/2); 
      path.curveTo(
        seg * 2, 0, 
        seg * 3, 0, 
        seg * 3, height/2); 

      g2d.draw(path); 


      g2d.dispose(); 
     } 
    } 
} 

로 엉망이 간단하고, 우리가 조작하고 원본을 초래하지 않고 폐기 할 수있는 Graphics 컨텍스트의 복사본을 생성

+0

우수를 확인하십시오! ['SineTest'] (http://stackoverflow.com/a/9373195/230513)도 참조하십시오. – trashgod

+0

@Sage 어떻게? 여전히 모든 작업을 수행해야하므로 더 복잡하게 만드는 이유는 무엇입니까? 원한다면 출력에'RenderingHints'를 적용 할 수도 있습니다 - 이것은 단지 저입니다.) – MadProgrammer

+0

@MadProgrammer, 어! 나는 그 요점을 놓쳤다. 그것을 잊어 버려 :) +1 – Sage

관련 문제