Newsgroup: it.comp.java
Titolo: Visualizzatore di immagini in Java

Tempo fa si è parlato su questo gruppo della volontà di giochicchiare con
delle immagini. Ad esempio, la possibilità di ridimensionarle.
Ho riadattato un pezzo di codice preso dai forum sun, ottenendo la classe
SizingTest. Ho un solo minuscolo problema. Vorrei far si che se l'immagine
è più grande del suo contenitore, che è un JPanel dentro uno JScrollPane,
questa sia scrollabile, ma proprio non riesco. Magari è una scemenza, ma mi
sta facendo perdere del tempo prezioso.
Per cho me lo chiese un mesetto fa, il ridimensionamento si effettua
agilmente con un Graphics2D. Allego codice. Per essere eseguito, necessita
di immagine posta in images/bld.jpg
Grazie a tutti
..............................................
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
public class SizingTest extends JPanel implements ActionListener,
ItemListener
{
        BufferedImage image, scaledImage;
        Dimension size;
        JButton more,less;
        JLabel status;
        JCheckBox sc;
        boolean scaled=true;
        double rate=1.0;
        public SizingTest()
        {
                loadImage();
                size = new Dimension(image.getWidth(), image.getHeight());
                addComponentListener(adjuster);
        }
        protected void paintComponent(Graphics g)
        {
                super.paintComponent(g);
                Graphics2D g2 = (Graphics2D)g;
                int w = getWidth();
                int h = getHeight();
                if(scaledImage == null)
                        createScaledImage(w, h);
                int x = (w - scaledImage.getWidth())/2;
                int y = (h - scaledImage.getHeight())/2;
                g2.drawImage(scaledImage, x, y, this);
        }
        public Dimension getMinimumSize()
        {
                return new Dimension(0,0);
        }
 
        private void createScaledImage(int w, int h)
        {
                int frameWidth  = (int)(w);
                int frameHeight = (int)(h);
 
                scaledImage = new BufferedImage(frameWidth, frameHeight, image.getType());
                Graphics2D g2 = scaledImage.createGraphics();
                g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                                RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
 
                g2.setPaint(getBackground());
                g2.fillRect(0, 0, frameWidth, frameHeight);
 
                double scale = getScale(frameWidth, frameHeight);
 
                double x = (frameWidth  - scale * size.width)/2;
                double y = (frameHeight - scale * size.height)/2;
                AffineTransform at = AffineTransform.getTranslateInstance(x, y);
                at.scale(scale, scale);
                g2.drawRenderedImage(image, at);
                g2.dispose();
        }
        private double getScale(double w, double h)
        {
                if (scaled) {
                        double xScale = w / size.width;
                        double yScale = h / size.height;
                        double scale = Math.min(xScale, yScale);
                        System.out.printf("Scale: %f\n", scale);
                        this.rate=scale;
                        return scale;
                }else return rate;              
        }
        private ComponentListener adjuster = new ComponentAdapter()
        {
                public void componentResized(ComponentEvent e)
                {
                        scaledImage = null;
                        repaint();
                }
        };
        private void loadImage()
        {
                String path = "images/bld.jpg";
                try
                {
                        URL url = getClass().getResource(path);
                        image = ImageIO.read(url);
                }
                catch(MalformedURLException mue)
                {
                        System.err.println("url: " + mue.getMessage());
                }
                catch(IOException ioe)
                {
                        System.err.println("read: " + ioe.getMessage());
                }
        }
        private JPanel getUIPanel()
        {
                JPanel panel = new JPanel();
                panel.setLayout(new FlowLayout());
 
                more= new JButton("+");
                less= new JButton("-");
                status= new JLabel("Zoom: " + rate *100 + "%");
                sc= new JCheckBox("Riscalata");
                sc.setSelected(true);
                sc.addItemListener(this);
 
                panel.add(sc);
                panel.add(more);
                panel.add(less);
                panel.add(status);
 
                more.addActionListener(this);
                less.addActionListener(this);
                return panel;
        }
        public static void main(String[] args)
        {
                SizingTest test = new SizingTest();
                JFrame f = new JFrame();
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                JScrollPane js=new JScrollPane(test);
                test.setPreferredSize(js.getPreferredSize());
                f.getContentPane().add(js);
                f.getContentPane().add(test.getUIPanel(), "South");
                f.setSize(400,400);
                f.setLocation(200,200);
                f.setVisible(true);
        }
        public void actionPerformed(ActionEvent e) {
                Object s=e.getSource();
 
                if (!scaled) {
                        if (s == more) {
                                rate += .1;
                        } else if (s == less) {
                                rate -=.1;
                        }
                        scaledImage=null;
                        repaint();
                        status.setText("Zoom: " + rate *100 + "%");
                }               
        }
        public void itemStateChanged(ItemEvent e) {
                scaled=sc.isSelected();
                scaledImage=null;
                repaint();
        }
}
.....................................................

 sta facendo perdere del tempo prezioso.
come fa lo scrollpanel a sapere che il panel che c'e' dentro deve essere
scrollabile se nessuno gli dice le dimensioni del panel stesso? o meglio,
il panel gliela dice rispondendo alle varie get*size ma non corrisponde
alla realta'.
quando imposti l'immeagine e la ridimensioni ricordati di impostare la
preferredSize. Non escludo tu debba anche impostare maximum, minimum e la
size stessa...

 preferredSize
Farň delle prove, grazie.

 size stessa...
Io intanto apprezzo lo sforzo di Manuel
Appena riesco ad avere un po di tempo ci do un'occhiata approfondita e
se trovo qualcosa di carino da aggiungere e/o sistemare vi faccio
sapere!
Ciao Marco

 Farņ delle prove, grazie.
Le ho fatte. Il visualizzatore, preso da solo, svolge il suo compito
egregiamente. E' calato nel suo contesto che dą qualche problemino.
Impacchetterņ il tutto in un progetto estrapolato da quello attuale e
vediamo di risolverlo insieme. Grazie comunque per l'attenzione.