2013-09-05 244 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