2013-09-05 194 views
0

我想要显示图像以放大和缩小,并且可以移动。我有下面的脚本,但它不能移动。如何解决它。图像平移和缩放

代码:

package dispertasih; 

import static dispertasih.PanPanel.startX; 
import java.awt.*; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseMotionAdapter; 
import java.awt.geom.*; 
import java.awt.image.BufferedImage; 
import java.io.IOException; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.imageio.ImageIO; 
import javax.swing.*; 
import javax.swing.event.*; 

public class PadAndZoom implements ChangeListener { 
    BufferedImage image; 
    PanPanel label; 

    public void stateChanged(ChangeEvent e) { 
     int value = ((JSlider)e.getSource()).getValue(); 
     double scale = value/200.0; 
     BufferedImage scaled = getScaledImage(scale); 
     label = new PanPanel(scaled); 
     label.revalidate(); // signal scrollpane 
    } 

    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; 
    } 

    private PanPanel getContent() { 
     createAnImage(); 
     label = new PanPanel(image); 
     //label.setHorizontalAlignment(JLabel.CENTER); 
     return label; 
    } 

    private void createAnImage() { 
     int w = 500; 
     int h = 500; 
     int type = BufferedImage.TYPE_INT_RGB; // many options 
     try { 
      image = ImageIO.read(PadAndZoom.class.getResource("/tampilan/background5.jpg")); 
     } catch (IOException ex) { 
      Logger.getLogger(PadAndZoom.class.getName()).log(Level.SEVERE, null, ex); 
     } 


    } 

    private JSlider getControl() { 
     JSlider slider = new JSlider(JSlider.HORIZONTAL, 50, 200, 50); 
     slider.setMajorTickSpacing(50); 
     slider.setMinorTickSpacing(10); 
     slider.setPaintTicks(true); 
     slider.setPaintLabels(true); 
     slider.addChangeListener(this); 
     return slider;   
    } 

    public static void main(String[] args) { 
     PadAndZoom app = new PadAndZoom(); 
     JFrame f = new JFrame(); 
     JButton b = new JButton(); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.getContentPane().add(new JScrollPane(app.getContent())); 

     //f.getContentPane().add(new JButton("tessss")); 
     f.getContentPane().add(app.getControl(), "Last"); 
     f.setSize(400, 400); 
     f.setLocation(200,200); 
     f.setVisible(true); 
    } 
} 
class PanPanelX extends JPanel { 

private int x, y; 
private int width = 800, height = 800; 
BufferedImage img; 
private final static RenderingHints textRenderHints = new RenderingHints(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); 
private final static RenderingHints imageRenderHints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
private final static RenderingHints renderHints = new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); 
static int startX, startY; 

public PanPanelX(BufferedImage img) { 
    x = 20; 
    y = 20; 
    this.img = img; 

    addMouseListener(new MouseAdapter() { 
     @Override 
     public void mousePressed(MouseEvent me) { 
      super.mousePressed(me); 
      startX = me.getX(); 
      startY = me.getY(); 
     } 
    }); 

    addMouseMotionListener(new MouseMotionAdapter() { 
     @Override 
     public void mouseDragged(MouseEvent me) { 
      super.mouseDragged(me); 

      if (me.getX() < startX) {//moving image to right 
       x -= 2; 
      } else if (me.getX() > startX) {//moving image to left 
       x += 2; 
      } 

      if (me.getY() < startY) {//moving image up 
       y -= 2; 
      } else if (me.getY() > startY) {//moving image to down 
       y += 2; 
      } 
      repaint(); 
     } 
    }); 
} 

@Override 
protected void paintComponent(Graphics grphcs) { 
    super.paintComponent(grphcs); 
    Graphics2D g2d = (Graphics2D) grphcs; 

    //turn on some nice effects 
    applyRenderHints(g2d); 

    g2d.drawImage(img, x, y, null); 
} 

@Override 
public Dimension getPreferredSize() { 
    return new Dimension(width, height); 
} 

public static void applyRenderHints(Graphics2D g2d) { 
    g2d.setRenderingHints(textRenderHints); 
    g2d.setRenderingHints(imageRenderHints); 
    g2d.setRenderingHints(renderHints); 
} 
} 

我认为:

public void stateChanged(ChangeEvent e) { 
     int value = ((JSlider)e.getSource()).getValue(); 
     double scale = value/200.0; 
     BufferedImage scaled = getScaledImage(scale); 
     label = new PanPanel(scaled); 
     label.revalidate(); // signal scrollpane 
    } 

也有失误,但我坚持固定它....

谢谢...

回答

2

问题是,屏幕上显示的图像引用与您创建时的图像不同ü调整它...

通过使用创建PanPanel ...

BufferedImage scaled = getScaledImage(scale); 
label = new PanPanel(scaled); 

getScaledImage创建一个新的图像中的每个被调用时,基于原始图像上。

BufferedImage bi = new BufferedImage(w, h, image.getType()); 

这意味着,在PadAndZoomimage是不一样的一个在PanPanel,让您对image任何修改或任何新的缩放情况下将永远不会被画,因为PanPanel什么都不知道关于他们...

现在,在stateChanged中,不是更新已有的PanPanel实例,而是创建它的一个新实例......就是这样......它永远不会添加到任何可显示的组件,所以它永远不会出现屏幕上。

相反,在你PanPanel,你需要为stateChanged方法对图像的缩放实例传递给它提供一些方法...

public void setImage(BufferedImage img) { 
    this.img = img; 
    revalidate(); 
    repaint(); 
} 

然后在您的stateChanged方法,你可以做..

int value = ((JSlider) e.getSource()).getValue(); 
double scale = value/200.0; 
BufferedImage scaled = getScaledImage(scale); 
label.setImage(scaled); 
+0

非常感谢你... – mayus