0

I want to add a Image into a JPanel, the JPanel is inside JInternalFrame, and the JInternalFrame has a parent, the JDesktopPane.

I've tried with another class to add a Image from a path, and then, jPanel1 = new Imagen(<String FilePath>); , the class will receive the path in String, in the window constructor, but it does not work. and I have tried by customizing code from the initComponents(), the line jPanel1 = javax.swing.JPanel(); and replacing this line by jPanel1 = new Imagen();, the parameter that the constructor will receive, is the path of the image file, and this method works fine, but it only run one time (inside the initComponents() method), and I can't (or I don't known) how to replace the image from the JPanel. :(

The project starts first with a JDesptopPane, an then one JInternalFrame (1), from this internalframe, it shows other JInternalFrame(2), from this internalFrame, it shows other JInternalFrame(3), in the internalFrame 3, I want to find with a button, and JFileChooser, an image, and the path received by the filechooser, I want to set as parameter in the Imagen() class. and set the image into a JPanel that is builded into the JInternalFrame(3).

EDIT 1: Thanks for your comments. Here the code of JInternalFrame(3), the window constructor:

public AgregarContacto() {

    JFileChooser jf = new JFileChooser();

    jf.setDialogTitle("Elija el archivo de Imagen");
    int i = jf.showOpenDialog(null);

    if (i == JFileChooser.APPROVE_OPTION) {

        default1 = jf.getSelectedFile().getAbsolutePath();
    }
    initComponents();
    jPanel1= new Imagen(default1);
    for (String llenarMese : p.llenarMeses()) {
        Mes.addItem(llenarMese);
    }

    for (String llenarDia : p.llenarDias31()) {
        Dia.addItem(llenarDia);
    }

    for (String llenarAnios : p.Anios()) {
        Anio.addItem(llenarAnios);
    }  
}

And here the code of the class Imagen() that will receive in the Constructor a string:

public class Imagen extends JPanel {
    String ruta;
    private BufferedImage imag;

    public Imagen(String path){
        ruta = path;
        try{
            imag = ImageIO.read(new File("unknown.png"));
        }catch(IOException ex){
            JOptionPane.showMessageDialog(null, "Error " + ex.getMessage());
        }
    }


    @Override
    public void paint(Graphics g){
    super.paint(g);
    Image Scaledimage = imag.getScaledInstance(this.getWidth(), this.getHeight(), Image.SCALE_SMOOTH);
    g.drawImage(Scaledimage, 0, 0, null);
    }
}
user1803551
  • 12,965
  • 5
  • 47
  • 74
Allan Ramirez
  • 125
  • 1
  • 15
  • 1
    I would like to help but unfortunately, cant download the project from that location as the URL is blocked in my office. Could you write a small test program - SSCCE? How are you setting the image into the panel? Are you using a JLabel as the image container? If you are, get rid of all the internal frames, have a JFrame that has a JPanel which has a JLabel and a button. When you click the button, choose the file and set into the label. If that works repeat it for your code with the internal frames. Else post the code here and I can help. – sethu May 19 '15 at 00:08
  • 1
    Please don't post code in links much less as a compressed huge complex program file. If you need help here, you should first isolate the problem in a small fully contained program, one that you can post here, again is small, that we can compile, run and that demonstrates your problem for us, a [minimal example program](http://sscce.org). – Hovercraft Full Of Eels May 19 '15 at 00:12
  • *"I want to"* - Okay, but what's not working? – MadProgrammer May 19 '15 at 00:35
  • *"I can't (or I don't known) how to replace the image from the JPanel. :("* Two options, remove the existing panel and create a new instance when you need to or, preferrably, provide a setter to the `ImagePanel` which allows it to change the image – MadProgrammer May 19 '15 at 00:37
  • Hi @MadProgrammer, when I select a File, from the Filechooser, and I set the panel = new Imagen(path); this did not load the image into jPanel1. Rebember, that this windows(JInternalFrame) is inside the DesktopPane. Thanks for comment. – Allan Ramirez May 19 '15 at 00:39
  • You need to re-add it to the frame... – MadProgrammer May 19 '15 at 00:39
  • Hi @MadProgrammer, I tried this:`try{ imag = ImageIO.read(new File("unknown.png")); ImagePane imgPane = new ImagePane(); imgPane.setImage(imag); imgPane.setRounded(true); jPanel1.add(imgPane); }catch(IOException ex){ ex.printStackTrace(); }` but it doesn't work; – Allan Ramirez May 19 '15 at 00:59
  • Call `revalidate` on `jPanel1` AFTER you've added the new instance of `ImagePane`, also, make sure you remove the any old ones first – MadProgrammer May 19 '15 at 01:06

1 Answers1

2

There are a multitude of ways to do this, but, one of the more preferable, would be to provide the ImagePane with the ability to change the image it is displaying without need to create a new instance of it.

This way, you could simply pass the ImagePane a reference to the image you want to load and let it do it's job

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JDesktopPane;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.filechooser.FileFilter;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JDesktopPane dp = new JDesktopPane() {
                    @Override
                    public Dimension getPreferredSize() {
                        return new Dimension(600, 600);
                    }
                };

                JInternalFrame inFrm = new JInternalFrame("Image", true, true, true, true);
                inFrm.add(new ShowImagePane());
                inFrm.pack();
                inFrm.setVisible(true);
                dp.add(inFrm);

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(dp);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class ShowImagePane extends JPanel {

        private JFileChooser fc;

        public ShowImagePane() {
            setLayout(new BorderLayout());
            ImagePane imagePane = new ImagePane();
            add(imagePane);
            JButton open = new JButton("Open...");
            open.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    if (fc == null) {
                        fc = new JFileChooser();
                        fc.addChoosableFileFilter(new FileFilter() {

                            @Override
                            public boolean accept(File f) {
                                String name = f.getName().toLowerCase();
                                return name.endsWith(".png")
                                                || name.endsWith(".jpg")
                                                || name.endsWith(".jpeg")
                                                || name.endsWith(".bmp");
                            }

                            @Override
                            public String getDescription() {
                                return "Images";
                            }
                        });
                        fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
                        fc.setMultiSelectionEnabled(false);
                    }

                    switch (fc.showOpenDialog(ShowImagePane.this)) {
                        case JFileChooser.APPROVE_OPTION:
                            File selected = fc.getSelectedFile();
                            try {
                                imagePane.setImageSource(selected);
                            } catch (IOException ex) {
                                ex.printStackTrace();
                            }
                            break;
                    }
                }
            });
            add(open, BorderLayout.SOUTH);
        }

    }

    public class ImagePane extends JPanel {

        private BufferedImage bgImage;
        private Image scaled;

        public ImagePane(File source) throws IOException {
            setImageSource(source);
        }

        public ImagePane() {
        }

        @Override
        public void invalidate() {
            super.invalidate();
            resizeImage();
        }

        public void setImageSource(File source) throws IOException {
            if (source != null) {
                bgImage = ImageIO.read(source);
                resizeImage();
            } else {
                bgImage = null;
            }
        }

        @Override
        public Dimension getPreferredSize() {
            return bgImage == null ? new Dimension(200, 200) : new Dimension(bgImage.getWidth(), bgImage.getHeight());
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (scaled != null) {
                Graphics2D g2d = (Graphics2D) g.create();
                int x = (getWidth() - scaled.getWidth(this)) / 2;
                int y = (getHeight() - scaled.getHeight(this)) / 2;
                g2d.drawImage(scaled, x, y, this);
                g2d.dispose();
            }
        }

        protected void resizeImage() {
            if (bgImage != null) {
                if (getWidth() < getHeight()) {
                    scaled = bgImage.getScaledInstance(this.getWidth(), -1, Image.SCALE_SMOOTH);
                } else {
                    scaled = bgImage.getScaledInstance(-1, getHeight(), Image.SCALE_SMOOTH);
                }
                repaint();
            }
        }

    }

}

Image#getScaledInstance is neither the fastest or, more importantly, best quality scaling algorithm. Because it can take time to re-scale an image, you should only do it when you have to.

Take a look at Java: maintaining aspect ratio of JPanel background image and Quality of Image after resize very low -- Java for more details and ideas

Community
  • 1
  • 1
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • Thanks, I just used the ImagePane class, and I did: ` ImagePane imgPane = new ImagePane(); try{ //imag = ImageIO.read(new File("unknown.png")); imgPane.setImageSource(new File("unknown.png")); //imgPane.setRounded(true); }catch(IOException ex){ ex.printStackTrace(); } jPanel1.add(imgPane,BorderLayout.CENTER);` – Allan Ramirez May 19 '15 at 02:05