ここにコードを含む JPanel があります。マウスホイールでスクロールすると、パネルがパネルの中心に向かってズームインするようにします。現在、マウスホイールでズームイン/ズームアウトすると、画像の左上隅が同じ場所に留まります。正しいアルゴリズムを見つけるのに苦労しました。
画像を拡大するために、コードは AffineTransform オブジェクトを使用します。このオブジェクトは、マウス ホイールの動きに基づいて増減する double 値に従って画像をスケーリングします。
さらに複雑なのは、パネル内で画像をクリックしてドラッグすることもできることです。クリックしてドラッグした場合、ズームは、必ずしも実際の画像の中心ではなく、PANEL の中心にあるものを拡大する必要があります。
ここでも、ズームは現在表示されている領域の中心点に対して行う必要があります。つまり、ズームが発生しても、ビューの中心点は固定されたままになります。
これはコードです(そして実行可能です):
package clientgui;
import java.awt.*;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.awt.image.BufferedImage;
import java.net.URL;
import javax.swing.border.TitledBorder;
public class MoveImageExample extends JFrame {
ShowCanvas canvas;
public MoveImageExample() throws Exception {
super();
Container container = getContentPane();
canvas = new ShowCanvas(
"http://cdn.smosh.com/sites/default/files/bloguploads/funny-iphone-5-bruce-lee.jpg");
container.setPreferredSize(new Dimension(canvas.getWidth(), canvas
.getHeight()));
System.out.println("width = " + canvas.getWidth() + " height = "
+ canvas.getHeight());
container.add(canvas);
pack();
setVisible(true);
}
public static void main(String arg[]) throws Exception {
new MoveImageExample();
}
}
@SuppressWarnings("serial")
class ShowCanvas extends JPanel {
int imageX = 0, imageY = 0;
int lastMouseX = 0, lastMouseY = 0;
int centerX = 225;
int centerY = 225;
int canvasWidth = 450;
int canvasHeight = 450;
double scaleFactor = 1.0;
boolean firstMouseDrag = true;
BufferedImage image;
public ShowCanvas(String imagePath) throws Exception {
setBackground(Color.white);
MouseMotionHandler mouseHandler = new MouseMotionHandler();
addMouseMotionListener(mouseHandler);
addMouseListener(mouseHandler);
addMouseWheelListener(mouseHandler);
URL url = new URL(imagePath);
Image rawImage = ImageIO.read(url);
image = new BufferedImage(rawImage.getWidth(this),
rawImage.getHeight(this), BufferedImage.TYPE_INT_ARGB);
setSize(image.getWidth(), image.getHeight());
Graphics2D g2 = image.createGraphics();
g2.drawImage(rawImage, imageX, imageY, this);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2D = (Graphics2D) g;
g2D.setColor(Color.gray);
g.fillRect(0, 0, image.getWidth(), image.getHeight());
AffineTransform transformer = new AffineTransform();
// translate the image back (using new scale factor)
transformer.scale(scaleFactor, scaleFactor); // scale by 2x on x and y
// axes.
transformer.translate(imageX / scaleFactor, imageY / scaleFactor);
g2D.drawImage(image, transformer, this);
}
class MouseMotionHandler extends MouseMotionAdapter implements
MouseListener, MouseWheelListener {
public void mousePressed(MouseEvent e) {
lastMouseX = e.getX();
lastMouseY = e.getY();
}
public void mouseDragged(MouseEvent e) {
int xDiff = e.getX() - lastMouseX;
int yDiff = e.getY() - lastMouseY;
imageX = imageX + xDiff;
imageY = imageY + yDiff;
lastMouseX = e.getX();
lastMouseY = e.getY();
repaint();
}
public void mouseWheelMoved(MouseWheelEvent e) {
int notches = e.getWheelRotation();
scaleFactor = scaleFactor + notches / 10.0;
if (scaleFactor < 0.5) {
scaleFactor = 0.5;
} else if (scaleFactor > 3.0) {
scaleFactor = 3.0;
}
repaint();
}
public void mouseReleased(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void mouseClicked(MouseEvent e) {
}
}
}