Reputation: 63
I have a JScrollPane that contains a custom JLabel with an ImageIcon. I want the user to be able to zoom in and out on the image. I'm trying to use the scale()
method in the Graphics2D class to do it, but whenever I zoom, the image is being shifted down/up and right/left depending on whether I'm zooming in or out. I don't know why this is happening or how to tell how much I need to translate()
the Graphics2D object to counteract this. I really appreciate any help you guys can give me. Here's my code:
class ImageViewer extends JFrame implements ActionListener{
private int WIDTH = 800;
private int HEIGHT = 600;
private JScrollPane scrollPane;
JMenuItem zoomIn, zoomOut;
JPanel panel;
MyLabel label;
private String imageUrl = "picture.jpg";
double scale = 1.0;
public static void main(String[] args) {
ImageViewer viewer = new ImageViewer();
viewer.setVisible(true);
}
private ImageViewer() {
this.setTitle("Image Viewer");
this.setSize(WIDTH, HEIGHT);
this.setBackground(Color.gray);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
panel = new JPanel();
panel.setLayout(new BorderLayout());
this.getContentPane().add(panel);
JMenuBar menubar = new JMenuBar();
JMenu zoom = new JMenu("Zoom");
zoomIn = new JMenuItem("Zoom In");
zoom.add(zoomIn);
zoomIn.addActionListener(this);
zoomOut = new JMenuItem("Zoom Out");
zoom.add(zoomOut);
zoomOut.addActionListener(this);
menubar.add(zoom);
this.add(menubar, BorderLayout.NORTH);
Icon image = new ImageIcon(imageUrl);
label = new MyLabel(image);
scrollPane = new JScrollPane();
scrollPane.getViewport().add(label);
panel.add(scrollPane, BorderLayout.CENTER);
}
public void actionPerformed(ActionEvent e) {
Object ob = e.getSource();
if (ob == zoomIn) {
scale += .1;
label.revalidate();
label.repaint();
}
if (ob == zoomOut) {
scale -= .1;
label.revalidate();
label.repaint();
}
}
class MyLabel extends JLabel{
public MyLabel(Icon i){
super(i);
}
protected void paintComponent(Graphics g){
Graphics2D g2 = (Graphics2D) g;
AffineTransform at = g2.getTransform();
g2.scale(scale, scale);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
super.paintComponent(g2);
g2.setTransform(at);
}
public Dimension getPreferredSize(){
int w = (int)(scale * getIcon().getIconWidth()),
h = (int)(scale * getIcon().getIconHeight());
return new Dimension(w, h);
}
}
}
Upvotes: 0
Views: 1185
Reputation: 57421
Before g2.scale(scale, scale);
add g2.translate(desiredX, desiredY);
Upvotes: 4