2013-06-29 2 views
1

크기를 재조정 할 수있는 클래스가 있습니다. 그 배경 위에 그림이 있습니다 (페인트 방법과 Java2D 사용). 배경이 크기 조정될 때마다 그려지는 모든 것을 삭제할 수 있습니까? (결국 올바른 위치에 다시 그려야합니다.) 이미지를 다시 맞춰서 크기를 조정하는 것과 같이 이미 그려진 객체에서 수행 할 수있는 변형이 있습니까?정리할 수있는 그리기 영역을 만드는 최소 방법

import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.RenderingHints; 
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.ImageIcon; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.JSlider; 
import javax.swing.event.ChangeEvent; 
import javax.swing.event.ChangeListener; 

public class Background extends JLabel implements ChangeListener { 
    private ImageIcon background; 
    private BufferedImage image; 

    public Background(JPanel parent){ 
     super(); 
     parent.add(this); 
     try { 
      image = ImageIO.read(new File("/example/background")); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     this.background = new ImageIcon(image); 
     this.setIcon(background); 
    } 
    public void stateChanged(ChangeEvent e) { 
     int value = ((JSlider) e.getSource()).getValue(); 
     double scale = value/100.0; 
     BufferedImage scaled = getScaledImage(scale); 
     this.setIcon(new ImageIcon(scaled)); 
     this.revalidate(); 
    } 
    private BufferedImage getScaledImage(double scale) { 
     int w = (int) (scale * image.getWidth()); 
     int h = (int) (scale * image.getHeight()); 
     BufferedImage bi = new BufferedImage(w, h, image.getType()); 
     Graphics2D g2 = bi.createGraphics(); 
     g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BICUBIC); 
     AffineTransform at = AffineTransform.getScaleInstance(scale, scale); 
     g2.drawRenderedImage(image, at); 
     g2.dispose(); 
     return bi; 
    } 
    @Override 
    public void paint(Graphics g){ 
     super.paint(g); 
     Graphics2D graphObj = (Graphics2D) g; 
     RenderingHints rh = new RenderingHints(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);rh.put(RenderingHints.KEY_RENDERING,RenderingHints.VALUE_RENDER_QUALITY); 
     graphObj.setRenderingHints(rh); 
     graphObj.fillOval(500, 500, 20, 20); 
     graphObj.finalize(); 
    } 
} 
+0

"'의 paintComponent()를'대신 오버라이드 (override)의 '페인트()'오버라이드 (override) 할 필요가 스윙 프로그램."- AWT에서 [* 도장 및 스윙 : 페인트 방법 *] (http://www.oracle.com/technetwork/java/painting-140037.html#callbacks) [예] (http://stackoverflow.com/a/5129757/230513)). – trashgod

답변

2

고려 :

  • 도면을 paintComponent(...) 재정이 아닌 paint(...) 재정에.
  • List<Point>을 저장합니다. 여기서 각 포인트는 1000 x 1000 크기로 정규화됩니다.
  • 그런 다음 paintComponent 메서드에서 for 루프의 각 Point를 반복하고 현재 구성 요소 크기로 배율을 조정 한 다음 그립니다.
  • ComponentListener에 그려진 이미지를 축척 한 다음 repaint()을 호출 할 수 있습니다.
  • 너비와 높이 매개 변수를 사용하는 Graphics#drawImage(...) 오버로드를 사용하여 그려진 이미지의 크기를 조정하는 것이 더 좋습니다.

예를 들어,

import java.awt.Graphics; 
import java.awt.image.BufferedImage; 
import java.io.IOException; 
import java.net.MalformedURLException; 
import java.net.URL; 

import javax.imageio.ImageIO; 
import javax.swing.*; 

public class MyBackground extends JPanel { 
    private BufferedImage img; 

    public MyBackground(BufferedImage img) { 
     this.img = img; 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     if (img != null) { 
     g.drawImage(img, 0, 0, getWidth(), getHeight(), this); 
     } 
    } 

    private static void createAndShowGui() { 
     String comfyChair = "https://duke.kenai.com/comfyChair/ComfyChairRad.png"; 
     BufferedImage img; 
     try { 
     URL url = new URL(comfyChair); 
     img = ImageIO.read(url); 

     MyBackground mainPanel = new MyBackground(img); 

     JFrame frame = new JFrame("MyBackground"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.getContentPane().add(mainPanel); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
     } catch (MalformedURLException e) { 
     e.printStackTrace(); 
     } catch (IOException e) { 
     e.printStackTrace(); 
     } 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      createAndShowGui(); 
     } 
     }); 
    } 
} 

예 2 :

import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Point; 
import java.awt.RenderingHints; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import java.awt.geom.Point2D; 
import java.awt.image.BufferedImage; 
import java.io.IOException; 
import java.net.MalformedURLException; 
import java.net.URL; 
import java.util.ArrayList; 
import java.util.List; 

import javax.imageio.ImageIO; 
import javax.swing.*; 

public class MyBackground extends JPanel { 
    public static final double NORM_CONST = 1.0; 
    private BufferedImage img; 
    private List<List<Point2D>> normalizedPoints = new ArrayList<List<Point2D>>(); 
    private List<Point2D> pointSubList; 

    public MyBackground(BufferedImage img) { 
     this.img = img; 
     MyMouseAdapter myMouseAdapter = new MyMouseAdapter(); 
     addMouseListener(myMouseAdapter); 
     addMouseMotionListener(myMouseAdapter); 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     if (img != null) { 
     g.drawImage(img, 0, 0, getWidth(), getHeight(), this); 
     } 
     Graphics2D g2 = (Graphics2D) g; 
     g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
      RenderingHints.VALUE_ANTIALIAS_ON); 

     for (List<Point2D> pointList : normalizedPoints) { 
     if (pointList.size() > 1) { 
      for (int i = 1; i < pointList.size(); i++) { 
       Point p1 = deNormalize(pointList.get(i - 1)); 
       Point p2 = deNormalize(pointList.get(i)); 
       g2.drawLine(p1.x, p1.y, p2.x, p2.y); 
      } 
     } 
     } 

     if (pointSubList != null && pointSubList.size() > 1) { 
     for (int i = 1; i < pointSubList.size(); i++) { 
      Point p1 = deNormalize(pointSubList.get(i - 1)); 
      Point p2 = deNormalize(pointSubList.get(i)); 
      g2.drawLine(p1.x, p1.y, p2.x, p2.y); 
     } 
     } 
    } 

    private Point deNormalize(Point2D p2d) { 
     int x = (int) (p2d.getX() * getWidth()/NORM_CONST); 
     int y = (int) (p2d.getY() * getHeight()/NORM_CONST); 
     return new Point(x, y); 
    } 

    private class MyMouseAdapter extends MouseAdapter { 

     @Override 
     public void mousePressed(MouseEvent e) { 
     Point2D p = normalizePoint(e.getPoint()); 
     pointSubList = new ArrayList<>(); 
     pointSubList.add(p); 
     } 

     @Override 
     public void mouseReleased(MouseEvent e) { 
     Point2D p = normalizePoint(e.getPoint()); 
     pointSubList.add(p); 
     normalizedPoints.add(pointSubList); 
     pointSubList = null; 
     repaint(); 
     } 

     @Override 
     public void mouseDragged(MouseEvent e) { 
     Point2D p = normalizePoint(e.getPoint()); 
     pointSubList.add(p); 
     repaint(); 
     } 

     private Point2D normalizePoint(Point point) { 
     double x = (NORM_CONST * point.x)/getWidth(); 
     double y = (NORM_CONST * point.y)/getHeight(); 
     Point2D result = new Point2D.Double(x, y); 
     return result; 
     } 


    } 

    private static void createAndShowGui() { 
     String comfyChair = "https://duke.kenai.com/comfyChair/ComfyChairRad.png"; 
     BufferedImage img; 
     try { 
     URL url = new URL(comfyChair); 
     img = ImageIO.read(url); 

     MyBackground mainPanel = new MyBackground(img); 

     JFrame frame = new JFrame("MyBackground"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.getContentPane().add(mainPanel); 
     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
     } catch (MalformedURLException e) { 
     e.printStackTrace(); 
     } catch (IOException e) { 
     e.printStackTrace(); 
     } 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
      createAndShowGui(); 
     } 
     }); 
    } 
} 
+2

@Claudiop 또는 Icon/ImageIcon으로 직접 JLabels Background 클래스에 이미지를 넣으면 전체 배경 클래스가 꽤 쓸모가 없다. – mKorbel

+0

+1 좋은 조언 –

+0

나는 이해하지만 나는 정말로 확신하지 못한다고 생각한다. 왜 paintComponent를 대체해야합니까? 여전히 paintComponent에 super()를 캐스트해야합니까? 만약 내가 repaint() 그것을 지우거나 다시 그릴거야? 그것을 다시 그릴 경우, 그럼 내가 뭘 그리고 싶은 변경할 수 있습니까? – SOMN

관련 문제