I found a few questions similar to the one I have, including this and this, but none that really answered the problem, and it's because I am using a JScrollPane
. I found the code necessary for the formula; it's this:
originX -= mouseX / zoom - mouseX;
originY -= mouseY / zoom - mouseY;
So I tried plugging it into a JScrollPane
:
JScrollPane scrollPane = drawFrame.scrollPane;
JScrollBar vert = scrollPane.getVerticalScrollBar(),
horiz = scrollPane.getHorizontalScrollBar();
horiz.setValue(
(int)(horiz.getValue() - (float)pastMouseX / zoom + pastMouseX)
);
vert.setValue(
(int)(vert.getValue() - (float)pastMouseY / zoom + pastMouseY)
);
And the point at which the mouse zooms into is all over the place and I don't know why. Here is the minimal reproducible example:
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
public class ResizeTest extends JFrame{
JScrollPane scrollPane;
BufferedImage image;
int mouseX, mouseY;
float zoom;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable(){
@Override
public void run(){
new ResizeTest();
}
});
}
public ResizeTest(){
zoom = 1;
try{
image = ImageIO.read(new File("a.jpg"));
}catch(IOException e){
e.printStackTrace();
}
JPanel panel = new JPanel(){
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.scale(zoom, zoom);
g2.drawImage(image, 0, 0, null);
System.out.println(zoom);
}
@Override
public Dimension getPreferredSize(){
return new Dimension(image.getWidth(), image.getHeight());
}
};
scrollPane = new JScrollPane(panel);
panel.addMouseWheelListener(new MouseWheelListener(){
@Override
public void mouseWheelMoved(MouseWheelEvent e) {
if(e.isControlDown()) {
if(e.getWheelRotation() > 0){
zoom /= 1.3333333333f;
if(zoom < 0.125)
zoom = 0.125f;
}
else if (e.getWheelRotation() < 0){
zoom *= 1.3333333333f;
if(zoom > 10)
zoom = 10;
}
if(zoom < 10){
JScrollBar vert = scrollPane.getVerticalScrollBar(),
horiz = scrollPane.getHorizontalScrollBar();
horiz.setValue(
(int)(horiz.getValue() - (float)mouseX / zoom + mouseX)
);
vert.setValue(
(int)(vert.getValue() - (float)mouseY / zoom + mouseY)
);
}
} else {
scrollPane.dispatchEvent(e);
}
panel.repaint();
}
});
panel.addMouseMotionListener(new MouseMotionListener(){
@Override
public void mouseDragged(MouseEvent e) {
mouseX = e.getX();
mouseY = e.getY();
}
@Override
public void mouseMoved(MouseEvent e) {
mouseX = e.getX();
mouseY = e.getY();
}
});
setSize(new Dimension(1200,700));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
add(scrollPane);
setVisible(true);
}
@Override
public Dimension getPreferredSize(){
return new Dimension(1200, 700);
}
}
int
scale from 10 to 100 in 10 steps. 2) Draw or read your image at its maximum size. 3) Always reduce your maximum image down by the scale value. 4) Your origin formulas zoom in and out on the origin (upper left corner) of the image. Most people want to zoom based on the mouse pointer. You have to calculate the image size at each scale factor and figure out how to move theJScrollPane
sliders so the mouse pointer point remains in the center of theJScrollPane
.JScrollPane
and how it takes in the new scrolling coordinates with the formula I found on other questions.JScrollBar
thatgetValue()
returns? Is it on the very left or right side of where the scrolling bar is on theJScrollBar
's total length?