2

I have a scrollpane where load an image. I wont this image with her natural size, and if this image is too big, I wont activated the scrollbar, but this instruction

  g.drawImage(immagine, 0, 0, getWidth(), getHeight(), this); 

scaled image for placing in scrollpane. What can I do?

Class Gui:


    import java.awt.*;
    import java.awt.event.*;
    import java.io.File;
    import javax.swing.*;

    public class Gui implements ActionListener {

        private JFrame frmEditor;

        private Mappa content;
        private JMenuItem mntmSfondo;
        private JScrollPane scrollabile;

        /**
         * Launch the application.
         */
        public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
                public void run() {
                    try {
                        Gui window = new Gui();
                        window.frmEditor.setVisible(true);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
        }

        /**
         * Create the application.
         */
        public Gui() {
            initialize();
        }

        /**
         * Initialize the contents of the frame.
         */
        private void initialize() {
            frmEditor = new JFrame();
            frmEditor.setFont(UIManager.getFont("TextArea.font"));
            frmEditor.setBounds(50, 50, 1024, 768);
            frmEditor.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frmEditor.getContentPane().setLayout(new BorderLayout(0, 0));

            JPanel panelTile = new JPanel();
            panelTile.setLayout(new BorderLayout(0, 0));

            content = new Mappa(null);
            content.setMinimumSize(new Dimension(150, 150));
            scrollabile = new JScrollPane(content);
            frmEditor.getContentPane().add(scrollabile, BorderLayout.CENTER);

            inizializzaMenu();
        }

        /**
         * Initialize the menu.
         */
        private void inizializzaMenu() {

            JMenuBar menuBar = new JMenuBar();
            frmEditor.setJMenuBar(menuBar);

            JMenu mnAltro = new JMenu("Modify");
            menuBar.add(mnAltro);

            mntmSfondo = new JMenuItem("Load Background");
            mntmSfondo.addActionListener(this);
            mnAltro.add(mntmSfondo);
        }

        public void actionPerformed(ActionEvent e) {
            Object source = e.getSource();
            if (source == mntmSfondo) {
                JFileChooser fc = new JFileChooser("tuttiSfondi");
                int result = fc.showOpenDialog(null);
                if (result == JFileChooser.APPROVE_OPTION) {
                    File file = fc.getSelectedFile();
                    try {
                        content.setImage(file);
                        //content = new Mappa(file);
                        //scrollabile.setViewportView(content);
                    } catch (Exception ex) {
                    }
                }
                if (result == JFileChooser.CANCEL_OPTION) {
                }
            }
        }

    }

Class Mappa:


    import java.awt.*;
    import java.awt.image.BufferedImage;
    import java.io.*;

    import javax.imageio.ImageIO;
    import javax.swing.*;

    public class Mappa extends JPanel {

        BufferedImage immagine;

        public Mappa(File fileImmagine) {

            if (fileImmagine != null ) {

                BufferedImage img = null;
                try {
                    img = ImageIO.read(new File(fileImmagine.getPath()));
                } catch (IOException e) {
                    e.printStackTrace();
                }
                this.immagine = img;
            }
            repaint();
        }

        public void setImage(File file) throws IOException {

            this.immagine = ImageIO.read(file);
            String name = file.getPath();
            System.out.println(name);
            repaint();

        }

        public void paintComponent(Graphics g) {

            super.paintComponent(g);
            g.clearRect(0, 0, 4000, 4000);
            g.drawImage(this.immagine, 0, 0, getWidth(), getHeight(), this);

            System.out.println("Called Repaint() on Mappa");

        }
    }

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
aura
  • 23
  • 1
  • 3

2 Answers2

2

I wont this image with her natural size, and if this image is too big, I wont activated the scrollbar,

Using JLabel to contain the image and wrap it in a JScrollPane should easily achieve what you want. Take hints from the following example:

class AFrame extends JFrame
{
   public AFrame()
  {

     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     setTitle("Image view Demo with JScrollPane");

     ImageIcon image = new ImageIcon("myImage.png"); // pass the file location of an image
     JLabel label = new JLabel(image);
     JScrollPane scrollPane = new JScrollPane(label);
     scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
     scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
     add(scrollPane, BorderLayout.CENTER);
     pack();
  }

 public static void main(String[] args)
 {
    SwingUtilities.invokeLater(new Runnable() {

       @Override
       public void run() {
          new AFrame().setVisible(true);
       }
    });

  }
}
Sage
  • 15,290
  • 3
  • 33
  • 38
  • I think I cannot use this method because after I need to draw over this image. I use it as a background. – aura Nov 27 '13 at 22:38
2

JScrollPane, or more to the point JViewport will use the component's (or in this case the "view's") preferred size as a bases for determining how big the view should be.

When the view expands beyond the size of the scroll pane, it will show the scroll bars.

So basically, you need to override the getPreferredSize of the public class Mappa extends JPanel { panel, for example

public class Mappa extends JPanel {
    //...
    public Dimension getPreferredSize() {
        return immagine == null ? new Dimension(200, 200) : new Dimension(immagine.getWidth(), immagine.getHeight());
    }
    //...
}

This will encourage the JViewport to always be the same size as the image.

Also, two things...

First, you shouldn't rely on magic numbers, for example

g.clearRect(0, 0, 4000, 4000);

Should be more like...

g.clearRect(0, 0, getWidth(), getHeight());

And secondly,

super.paintComponent(g);

Will do this any way, so calling clearRect is kind of pointless...

You might also like to take a look at Scrollable, but it is quite an advanced topic

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • I am missing the point that, if i need `JScrollPane` to react on view of an image why even using a `JPanel` and override `paintComponent` function! `JLabel` is already doing this for me. isn't a little unnecessary overhead. :( – Sage Nov 27 '13 at 22:23
  • @Sage I'm just basing the answer on what the OP has done, hopefully we can teach them something about how things work in the process. And yes, unless you are doing some kind processing and/or dynamic resizing, a `JLabel` is generally a better approach. But after some many years, I tend not to use `JLabel` so much...as I want to do dynamic rescaling of the image :P – MadProgrammer Nov 27 '13 at 22:31
  • Your point of answering was clearer to me from the beginning, off-course. Just wanted to say, and said :) – Sage Nov 27 '13 at 22:34
  • Adding the overrided method getPrefferedSize() I solve the problem with scrollbar. Thanks. But I need to loading an image with her real size, this problem dosn't solved still. Ex: I have am image 1920*1080 and my JFrame is inizialized here: frmEditor.setBounds(50, 50, 1024, 768); So my image is scaled... – aura Nov 27 '13 at 22:48
  • @MadProgrammer Yes, I know that the instruction g.clearRect(...) is stupid in this case. It the remains of bad programming. I'm very very beginner. :-) Thanks for your patience. – aura Nov 27 '13 at 22:57
  • @aura Try using something like `g.drawImage(this.immagine, 0, 0, this)` instead... – MadProgrammer Nov 27 '13 at 22:59
  • Ok, I solve this uncommented this scrollabile.setViewportView(content); Thank. – aura Nov 27 '13 at 23:03
  • You might be able to resolve it by calling `revalidate`, followed by `repaint` in the `setImage` method. This should cause the `JViewport` to request the panel's preferred size and update itself accordingly... – MadProgrammer Nov 27 '13 at 23:06