我有一个 JPanel,这里有代码。当我用鼠标滚轮滚动时,我希望面板向面板中的中心放大。目前,每当我用鼠标滚轮放大/缩小时,图像左上角的角落都会保持在同一个位置。我很难找到正确的算法。
为了放大图片,代码使用 AffineTransform 对象根据鼠标滚轮的移动增加或减少的双精度值缩放图像。
还增加了复杂性的是,图像也可以在面板周围单击和拖动。如果单击并拖动它,则缩放仍必须放大 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) {
}
}
}