Re: Draw a rectangle keeping aspect ratio of viewport
Here is an example contrived from some earlier code that Knute kindly
provided to centre the image in the scroll pane.
I believe Peter that the scroll pane is complicating things, which is
further complicated by the resize event??
Sorry this is longer than anticipated but works
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JViewport;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.swing.JScrollPane;
public class TestScale extends JPanel {
static BufferedImage image;
int imageW,imageH;
private static JViewport vp;
private static Point p;
private static int zoom = 1;
private static JScrollPane sp;
private static Rectangle rect;
/**
* This method initializes
*
*/
public TestScale() throws IOException {
super();
initialize();
image = ImageIO.read(new File("Sunset2.JPG"));
imageW = image.getWidth();
imageH = image.getHeight();
rect = new Rectangle();
setPreferredSize(new Dimension(imageW,imageH));
}
public void paintComponent(Graphics g) {
int x = Math.max(getWidth() - imageW,0) / 2;
int y = Math.max(getHeight() - imageH,0) / 2;
g.drawImage(image,x,y,imageW,imageH,null);
drawRect(g);
}
/**
* This method initializes this
*
*/
private void initialize() {
this.setSize(new Dimension(800, 600));
}
private static void drawRect(Graphics g) {
int x1, y1, x2, y2;
int startx = 0;
int starty = 0;
Graphics2D g2d = (Graphics2D) g;
Rectangle vpBounds = sp.getViewport().getBounds();
// is image width smaller or larger than viewport?
if (getScaledImageDimension().width < vpBounds.width) {
startx = (getScaledImageDimension().width / 2);
} else { // nope
startx = (int) vpBounds.x + (vpBounds.width / 2);
}
// is image height smaller or larger than viewport?
if (getScaledImageDimension().height < vpBounds.height) {
starty = getScaledImageDimension().height / 2;
} else {
starty = (int) vpBounds.y + (vpBounds.height / 2);
}
rect.setBounds(new Rectangle(startx, starty, 30 * zoom, 30 *
zoom));
g2d.setColor(Color.WHITE);
g2d.draw(rect);
}
//startx *= getZoomLevel();
private static Dimension getScaledImageDimension() {
return new Dimension(image.getWidth() * zoom, image.getHeight() * zoom );
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
final TestScale t = new TestScale();
final JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
sp = new JScrollPane(t);
f.add(sp,BorderLayout.CENTER);
JMenuBar mb = new JMenuBar();
f.setJMenuBar(mb);
JMenu m = new JMenu("Scale");
mb.add(m);
final JMenuItem oneX = new JMenuItem("1X");
final JMenuItem threeX = new JMenuItem("3X");
oneX.setEnabled(false);
oneX.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
oneX.setEnabled(false);
threeX.setEnabled(true);
t.imageW /= 3;
t.imageH /= 3;
t.setPreferredSize(
new Dimension(t.imageW,t.imageH));
zoom = 1;
t.revalidate();
f.repaint();
}
});
m.add(oneX);
threeX.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
threeX.setEnabled(false);
oneX.setEnabled(true);
t.imageW *= 3;
t.imageH *= 3;
t.setPreferredSize(
new Dimension(t.imageW,t.imageH));
zoom = 3;
t.revalidate();
f.repaint();
EventQueue.invokeLater(new Runnable() {
public void run() {
vp = sp.getViewport();
p = new Point(
(t.imageW - vp.getWidth())/2,
(t.imageH - vp.getHeight())/2);
vp.setViewPosition(p);
}
});
}
});
m.add(threeX);
f.pack();
f.setVisible(true);
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
});
}
}
Rich