The following example is extracted from a larger
project. I have a subclass of JPanel added to the
center of my window, and a BufferedImage which is
displayed on the JPanel. The panel sits inside a
JScrollPane, and if I size the window smaller than
the image I get scrollbars. If the window is sized
large enough to see the entire image, I don't get
scrollbars. This is what I want -- so far so good.
I also added a JSlider to control zoom (it's crude
right now, but I'm just trying to get it functional).
If I zoom the image, I lose the part of the image
that isn't visible after I zoom. I want to be able
to use the scrollbars to scroll to the remainder of
the image, but I can't. I tried setting the
horizontalScrollBarPolicy and
verticalScrollBarPolicy to always show the scroll
bars, but that didn't help -- I stilt can't ever get
to the rest of the image without zooming out. Any
ideas?
import java.awt.*;
import java.awt.image.*;
import java.io.*;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.event.*;
public class ZoomPanel extends JFrame {
private ImagePanel imagePanel;
private JSlider zoomSlider;
public ZoomPanel() {
super("Image Processing Demo");
Container container = getContentPane();
container.setLayout(new BorderLayout(5, 5));
imagePanel = new ImagePanel();
container.add(new JScrollPane(imagePanel), BorderLayout.CENTER);
String fileName = "c:\\larry\\test1.jpg";
File file = new File(fileName);
try {
imagePanel.setImage(ImageIO.read(file));
} catch (IOException x) {}
zoomSlider = new JSlider(SwingConstants.VERTICAL, 1, 10, 1);
zoomSlider.setMajorTickSpacing(1);
zoomSlider.setPaintTicks(true);
zoomSlider.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
repaint();
}
});
container.add(zoomSlider, BorderLayout.EAST);
pack();
setVisible(true);
}
private class ImagePanel extends JPanel {
private BufferedImage image;
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (image == null) return;
g.drawImage(image, 0, 0, getWidth() * zoomSlider.getValue(),
getHeight() * zoomSlider.getValue(), this);
}
public void setImage(BufferedImage image) {
this.image = image;
}
public Dimension getPreferredSize() {
return getMinimumSize();
}
public Dimension getMinimumSize() {
return new Dimension(300, 300);
}
}
public static void main(String args[]) {
ZoomPanel app = new ZoomPanel();
app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
Larry Coon - 24 Nov 2003 00:11 GMT
(snipped)
Postscript to the above: In addition to trying it with the scroll
bars always on, I also tried playing with getMinimumSize() in the
JPanel. For example:
public Dimension getMinimumSize() {return new Dimension(
image == null ? 300 : image.getWidth() * zoomSlider.getValue(),
image == null ? 300 : image.getHeight() * zoomSlider.getValue());
}
This didn't work either.
ak - 24 Nov 2003 06:55 GMT
public Dimension getPreferredSize() {
if(imahe == null) {
return getMinimumSize();
}
return new Dimension(image.getWidth(null)*zoomSlider.getValue(),
image.getHeight(null)*zoomSlider.getValue());
}
public Dimension getMinimumSize() {
return new Dimension(300, 300);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (image == null) return;
g.drawImage(image, 0, 0,image.getWidth(null)*zoomSlider.getValue(),
image.getHeight(null)*zoomSlider.getValue(), this);
}
this should work
ak
> The following example is extracted from a larger
> project. I have a subclass of JPanel added to the
[quoted text clipped - 85 lines]
> }
> }
Larry Coon - 24 Nov 2003 19:30 GMT
> this should work
ak,
Thanks for the reply, but it didn't work.
Larry Coon - 25 Nov 2003 00:12 GMT
> Thanks for the reply, but it didn't work.
Follow up: I got it. I needed a revalidate() after
the drawImage().
ak - 25 Nov 2003 09:44 GMT
you need revalidate only after you change scale. Don't put it to paint().
> > Thanks for the reply, but it didn't work.
>
> Follow up: I got it. I needed a revalidate() after
> the drawImage().
Larry Coon - 25 Nov 2003 18:30 GMT
> you need revalidate only after you change scale. Don't put it to paint().
Thanks for the reply. I moved it to the listener for the slider:
zoomSlider.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
imagePanel.revalidate();
repaint();
}
});
It works correctly this way. Is this the proper way/place to
be calling revalidate? I did a search in the docs, and only
turned up a few things that said to call repaint() *after*
calling revalidate(), without any sort of elaboration.