package prefuse.util.display; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Image; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JSlider; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; /** * Swing widget which displays a preview image and helps select the * scale for an exported image. * * @author <a href="http://jheer.org">jeffrey heer</a> */ public class ScaleSelector extends JComponent implements ChangeListener { private final static int MAX_SIZE = 135; private ImagePanel preview; private JLabel value; private JLabel size; private JSlider slider; private Image image; private int width, height; /** * Create a new ScaleSelector. */ public ScaleSelector() { slider = new JSlider(1,10,1); value = new JLabel("x1"); size = new JLabel(" "); preview = new ImagePanel(); value.setPreferredSize(new Dimension(25,10)); size.setHorizontalAlignment(JLabel.CENTER); slider.setMajorTickSpacing(1); slider.setSnapToTicks(true); slider.addChangeListener(this); setLayout(new BorderLayout()); Box b1 = new Box(BoxLayout.X_AXIS); b1.add(Box.createHorizontalStrut(5)); b1.add(Box.createHorizontalGlue()); b1.add(preview); b1.add(Box.createHorizontalGlue()); b1.add(Box.createHorizontalStrut(5)); add(b1, BorderLayout.CENTER); Box b2 = new Box(BoxLayout.X_AXIS); b2.add(slider); b2.add(Box.createHorizontalStrut(5)); b2.add(value); Box b3 = new Box(BoxLayout.X_AXIS); b3.add(Box.createHorizontalStrut(5)); b3.add(Box.createHorizontalGlue()); b3.add(size); b3.add(Box.createHorizontalGlue()); b3.add(Box.createHorizontalStrut(5)); Box b4 = new Box(BoxLayout.Y_AXIS); b4.add(b2); b4.add(b3); add(b4, BorderLayout.SOUTH); } /** * Set the preview image. * @param img the preview image */ public void setImage(Image img) { image = getScaledImage(img); stateChanged(null); } /** * Get a scaled version of the input image. * @param img the input image * @return a scaled version of the image */ private Image getScaledImage(Image img) { int w = width = img.getWidth(null); int h = height = img.getHeight(null); double ar = ((double)w)/h; int nw = MAX_SIZE, nh = MAX_SIZE; if ( w > h ) { nh = (int)Math.round(nw/ar); } else { nw = (int)Math.round(nh*ar); } return img.getScaledInstance(nw,nh,Image.SCALE_SMOOTH); } /** * Monitor changes to the scale slider. * @see javax.swing.event.ChangeListener#stateChanged(javax.swing.event.ChangeEvent) */ public void stateChanged(ChangeEvent evt) { int scale = slider.getValue(); value.setText("x"+String.valueOf(scale)); size.setText("Image Size: "+(width*scale)+" x "+(height*scale)+" pixels"); preview.repaint(); } /** * Get the current image scale reported by the slider. * @return the image scale to use */ public double getScale() { return slider.getValue(); } /** * Swing component that draws an image scaled to the current * scale factor. */ public class ImagePanel extends JComponent { Dimension d = new Dimension(MAX_SIZE, MAX_SIZE); public ImagePanel() { this.setPreferredSize(d); this.setMinimumSize(d); this.setMaximumSize(d); } public void paintComponent(Graphics g) { double scale = 0.4+(0.06*getScale()); int w = (int)Math.round(scale*image.getWidth(null)); int h = (int)Math.round(scale*image.getHeight(null)); Image img = (scale == 1.0 ? image : image.getScaledInstance(w,h,Image.SCALE_DEFAULT)); int x = (MAX_SIZE-w)/2; int y = (MAX_SIZE-h)/2; g.drawImage(img,x,y,null); } } } // end of class ScaleSelector