Java 图像平移和缩放

Java 图像平移和缩放,java,image,swing,zooming,changelistener,Java,Image,Swing,Zooming,Changelistener,我想显示一个图像放大和缩小,可以移动。我有下面的脚本,但它不能移动。如何修复它 守则: 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 j

我想显示一个图像放大和缩小,可以移动。我有下面的脚本,但它不能移动。如何修复它

守则:

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);
}
}
有错误,但我一直坚持改正


谢谢…

问题是,屏幕上显示的图像的参考与调整其大小时创建的图像不同

您可以通过使用创建
PanPanel

BufferedImage scaled = getScaledImage(scale);
label = new PanPanel(scaled);
getScaledImage
每次调用时都会基于原始图像创建一个新图像

BufferedImage bi = new BufferedImage(w, h, image.getType());
这意味着,
pad和zoom
中的
image
panpanpanel
中的图像不同,因此对
image
或任何新缩放实例所做的任何更改都不会被绘制,因为
panpanpanel
对它们一无所知

现在,在
stateChanged
中,您没有更新已有的
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);
int value = ((JSlider) e.getSource()).getValue();
double scale = value / 200.0;
BufferedImage scaled = getScaledImage(scale);
label.setImage(scaled);