3

I am trying to use a menubar that enables a user to choose a file and display it in JPanel and image should fit exactly in JPanel. But JFileChooser doesn't display anything upon successfully chosing file from dialog box. I tried refering to many links : How to add an image to a JPanel? and Browse for image file and display it using Java Swing but nothing worked out. Please help. Following is my code:

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

class Main {
private JFrame j;
private JMenu jmenu;
private JMenuBar jbar;
private JMenuItem jmi, jexit;
private JPanel jpanel, jpanelbar;
private JButton jpre, jnext;
JLabel image;
ImageIcon ic;
Image img;

Main() {
    j = new JFrame("Image Viewer");
    j.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    // j.setExtendedState(Frame.MAXIMIZED_BOTH);
    // j.setLocationRelativeTo(null);
    j.setLocationByPlatform(true);
    j.setLayout(new GridBagLayout());
    GridBagConstraints c = new GridBagConstraints();
    jpanel = new JPanel();
    c.anchor = GridBagConstraints.PAGE_START;
    c.fill = GridBagConstraints.HORIZONTAL;
    c.gridx = c.gridy = 0;
    c.gridwidth = 2;
    // c.weightx=0.1;
    c.weighty = 0.1;
    c.ipady = 600;
    c.insets = new Insets(5, 5, 10, 5);
    // jpanel.setBackground(Color.BLACK);
    j.add(jpanel, c);

    jpanelbar = new JPanel();
    jpanelbar.setBackground(Color.red);
    c.weightx = 0.1;
    c.gridx = 0;
    c.gridy = 1;
    c.fill = GridBagConstraints.HORIZONTAL;
    c.insets = new Insets(5, 5, 5, 5);
    c.ipady = 150;
    j.add(jpanelbar, c);

    jpanelbar.setLayout(new GridBagLayout());
    GridBagConstraints x = new GridBagConstraints();
    jpre = new JButton("Previous");
    x.gridx = 0;
    x.gridy = 0;
    x.gridwidth = 1;
    x.weightx = 0.1;
    // x.insets=new Insets(5,5,5,5);
    // x.fill=GridBagConstraints.NONE;
    jpanelbar.add(jpre, x);

    jnext = new JButton("Next");
    x.gridx = 1;
    jpanelbar.add(jnext, x);

    // Creating Menu
    jbar = new JMenuBar();
    jmenu = new JMenu("File");
    jmi = new JMenuItem("Open");
    jmi.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent ae) {
            JFileChooser fc = new JFileChooser();
            int result = fc.showOpenDialog(null);
            if (result == JFileChooser.APPROVE_OPTION) {
                File file = fc.getSelectedFile();
                String sname = file.getName();
                image = new JLabel("", new ImageIcon(sname), JLabel.CENTER);
                jpanel.add(image, BorderLayout.CENTER);
            }
        }
    });
    jexit = new JMenuItem("Exit");
    jexit.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent ae) {
            System.exit(0);
        }
    });
    jmenu.add(jmi);
    jmenu.add(jexit);
    jbar.add(jmenu);
    j.setJMenuBar(jbar);

    j.setSize(800, 600);
    j.setResizable(false);
    j.setVisible(true);
}

public static void main(String s[]) {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            new Main();
        }
    });
}
}

The updated code as follows:

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

class Main {
private JFrame j;
private JMenu jmenu;
private JMenuBar jbar;
private JMenuItem jmi, jexit;
private JPanel jpanel, jpanelbar;
private JButton jpre, jnext;
JLabel image;
ImageIcon ic;
Image img;

Main() {
    j = new JFrame("Image Viewer");
    j.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    // j.setExtendedState(Frame.MAXIMIZED_BOTH);
    // j.setLocationRelativeTo(null);
    j.setLocationByPlatform(true);
    j.setLayout(new GridBagLayout());
    GridBagConstraints c = new GridBagConstraints();
    jpanel = new JPanel();
    c.anchor = GridBagConstraints.PAGE_START;
    c.fill = GridBagConstraints.HORIZONTAL;
    c.gridx = c.gridy = 0;
    c.gridwidth = 2;
    // c.weightx=0.1;
    c.weighty = 0.1;
    c.ipady = 600;
    c.insets = new Insets(5, 5, 10, 5);
    // jpanel.setBackground(Color.BLACK);
    j.add(jpanel, c);

    jpanelbar = new JPanel();
    jpanelbar.setBackground(Color.red);
    c.weightx = 0.1;
    c.gridx = 0;
    c.gridy = 1;
    c.fill = GridBagConstraints.HORIZONTAL;
    c.insets = new Insets(5, 5, 5, 5);
    c.ipady = 150;
    j.add(jpanelbar, c);

    jpanelbar.setLayout(new GridBagLayout());
    GridBagConstraints x = new GridBagConstraints();
    jpre = new JButton("Previous");
    x.gridx = 0;
    x.gridy = 0;
    x.gridwidth = 1;
    x.weightx = 0.1;
    // x.insets=new Insets(5,5,5,5);
    // x.fill=GridBagConstraints.NONE;
    jpanelbar.add(jpre, x);

    jnext = new JButton("Next");
    x.gridx = 1;
    jpanelbar.add(jnext, x);

    // Creating Menu
    jbar = new JMenuBar();
    jmenu = new JMenu("File");
    jmi = new JMenuItem("Open");
    jmi.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent ae) {
            JFileChooser fc = new JFileChooser();
            int result = fc.showOpenDialog(null);
            if (result == JFileChooser.APPROVE_OPTION) {
                File file = fc.getSelectedFile();
                String sname = file.getName();
                image = new JLabel("", new ImageIcon(sname), JLabel.CENTER);
                jpanel.add(image, BorderLayout.CENTER);
                jpanel.revalidate();
                jpanel.repaint();
            }
        }
    });
    jexit = new JMenuItem("Exit");
    jexit.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent ae) {
            System.exit(0);
        }
    });
    jmenu.add(jmi);
    jmenu.add(jexit);
    jbar.add(jmenu);
    j.setJMenuBar(jbar);

    j.setSize(800, 600);
    j.setResizable(false);
    j.setVisible(true);
}

public static void main(String s[]) {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            new Main();
        }
    });
}
}
Community
  • 1
  • 1
crazy4
  • 135
  • 1
  • 2
  • 10

3 Answers3

8

I got your code to semi work. There are many, many more problems to solve.

  • I added a BorderLayout to your jpanel.

  • I moved the initialization of image out of your open menu action listener, like Reimeus told you to do.

  • I used ImageIO to read the image.

You'll need this answer eventually. Resize a picture to fit a JLabel

Here's my version of your code. May God have mercy on your soul.

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Image;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

class Main {
    private JFrame      j;
    private JMenu       jmenu;
    private JMenuBar    jbar;
    private JMenuItem   jmi, jexit;
    private JPanel      jpanel, jpanelbar;
    private JButton     jpre, jnext;
    JLabel              image;
    ImageIcon           ic;
    Image               img;

    Main() {
        j = new JFrame("Image Viewer");
        j.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // j.setExtendedState(Frame.MAXIMIZED_BOTH);
        // j.setLocationRelativeTo(null);
        j.setLocationByPlatform(true);
        j.setLayout(new GridBagLayout());

        GridBagConstraints c = new GridBagConstraints();
        jpanel = new JPanel();
        jpanel.setLayout(new BorderLayout());
        image = new JLabel(" ");
        jpanel.add(image, BorderLayout.CENTER);

        c.anchor = GridBagConstraints.PAGE_START;
        c.fill = GridBagConstraints.HORIZONTAL;
        c.gridx = c.gridy = 0;
        c.gridwidth = 2;
        // c.weightx=0.1;
        c.weighty = 0.1;
        c.ipady = 600;
        c.insets = new Insets(5, 5, 10, 5);
        // jpanel.setBackground(Color.BLACK);
        j.add(jpanel, c);

        jpanelbar = new JPanel();
        jpanelbar.setLayout(new GridBagLayout());
        jpanelbar.setBackground(Color.red);

        GridBagConstraints x = new GridBagConstraints();
        jpre = new JButton("Previous");
        x.gridx = 0;
        x.gridy = 0;
        x.gridwidth = 1;
        x.weightx = 0.1;
        // x.insets=new Insets(5,5,5,5);
        // x.fill=GridBagConstraints.NONE;
        jpanelbar.add(jpre, x);

        jnext = new JButton("Next");
        x.gridx = 1;
        jpanelbar.add(jnext, x);

        c.weightx = 0.1;
        c.gridx = 0;
        c.gridy = 1;
        c.fill = GridBagConstraints.HORIZONTAL;
        c.insets = new Insets(5, 5, 5, 5);
        c.ipady = 150;
        j.add(jpanelbar, c);

        // Creating Menu
        jbar = new JMenuBar();
        jmenu = new JMenu("File");
        jmi = new JMenuItem("Open");
        jmi.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent ae) {
                JFileChooser fc = new JFileChooser();
                int result = fc.showOpenDialog(null);
                if (result == JFileChooser.APPROVE_OPTION) {
                    File file = fc.getSelectedFile();
                    try {
                        image.setIcon(new ImageIcon(ImageIO.read(file)));
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        jexit = new JMenuItem("Exit");
        jexit.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent ae) {
                System.exit(0);
            }
        });
        jmenu.add(jmi);
        jmenu.add(jexit);
        jbar.add(jmenu);
        j.setJMenuBar(jbar);

//      j.setSize(800, 600);
        j.pack();
        j.setResizable(true);
        j.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new Main();
            }
        });
    }
}
Community
  • 1
  • 1
Gilbert Le Blanc
  • 50,182
  • 6
  • 67
  • 111
4

Instead of getName() use getAbsolutePath() on the file object and call repaint() and revalidate() after rendering the image.

Below code should resolve your problem:

jmi.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent ae) {
        JFileChooser fc = new JFileChooser();
        int result = fc.showOpenDialog(null);
        if (result == JFileChooser.APPROVE_OPTION) {
            File file = fc.getSelectedFile();
            String sname = file.getAbsolutePath(); //THIS WAS THE PROBLEM
            image = new JLabel("", new ImageIcon(sname), JLabel.CENTER);
            jpanel.add(image, BorderLayout.CENTER);
            jpanel.revalidate(); //ADD THIS AS WELL
            jpanel.repaint();  //ADD THIS AS WELL
        }
    }
});
Mubin
  • 4,192
  • 3
  • 26
  • 45
  • Hey! thanks. This way it worked out. But can you please explain me what you exactly did? Please. – crazy4 Jun 20 '13 at 17:25
  • 1
    you were using `file.getName()` which will make the rendering process to look for the image in current directory. I changed it to `file.getAbsolutePath()`. Apart from that as mentioned by @Reimeus, you should call `revalidate()` and/or `repaint()` for the UI changes to take effect. Also, mark it as answer if it resolves your question. – Mubin Jun 20 '13 at 17:26
  • Now, upon repaint() and revalidate() the lower panel and buttons has disappeared. Why? I want to display the image without losing them. – crazy4 Jun 20 '13 at 17:32
  • That will happen if the size of the image is bigger than the size of your frame. Test with a smaller image. To know how to resize the image so that it fits the JLabel see this [link](http://stackoverflow.com/questions/16343098/resize-a-picture-to-fit-a-jlabel) – Mubin Jun 20 '13 at 17:36
  • I have tried with a smaller image even with a image with resolution of 110x25 pixels. But the lower buttons are not appearing there. – crazy4 Jun 20 '13 at 17:40
  • `c.weighty = 0.1; c.ipady = 600; //THIS IS THE PROBLEM c.insets = new Insets(5, 5, 10, 5); j.add(jpanel, c);` You are asking `jpanel` to take pad up 600 units vertically, and the size of JFrame `f` is set to 600 as well. That is why the components at the south-end are going beyond the frame. Decrease `c.ipady` to something like 400 and you will see the cause. Otherwise call `f.pack()` after adding the image which will auto-adjust the size of all the components – Mubin Jun 20 '13 at 17:52
2

You need to invoke

jpanel.revalidate();
jpanel.repaint();

after adding the JLabel image to jpanel, but why not simply add the JLabel at startup use setIcon to set the Image instead?

Reimeus
  • 158,255
  • 15
  • 216
  • 276
  • it's still not displaying upon adding these lines. And I'm not getting the second method you specified. – crazy4 Jun 20 '13 at 16:52
  • `repaint` has existed since JDK 1.0. Can you post your updated code? – Reimeus Jun 20 '13 at 16:56
  • @crazy4 Your buttons are disappearing as `revalidate` resizes the panel `jpanel`. If you call `j.pack()`, you would see the preferred sizes. The issue is with the large `ipady` setting - after revalidate the button panel is pushed beyond the bounds of the `JFrame`. – Reimeus Jun 20 '13 at 17:50