ImageLoading in JPanel using JFileChooser - java

I am trying to load an image into a JPanel using JFileChooser. But when I try to run the program and load a selected image nothing happens in the JPanel. I am attaching the source code snippet here:
JFileChooser fileChooser = new JFileChooser();
fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
FileFilter filter = new FileNameExtensionFilter("Image files","jpeg","jpg");
fileChooser.setFileFilter(filter);
int result = fileChooser.showOpenDialog(null);
if(result == fileChooser.APPROVE_OPTION){
imgFile = fileChooser.getSelectedFile();//imgFile is File type
try{
myPicture = ImageIO.read(imgFile);//myPicture is BufferedImage
JLabel picLabel = new JLabel(new ImageIcon( myPicture )) ;
imagePanel.add( picLabel );
imagePanel.repaint();
System.out.println("You have selected "+imgFile);
}catch(Exception e){
e.printStackTrace();
}
}
}
Can anyone shed light on this?

The problem is that I have added two panels in my frame.
You might compare what you're doing with this complete example that uses two panels: a file chooser on the left and a display panel on the right.

I think this might help you...
Object selectedItem = jComboBox14.getSelectedItem();
ImageIcon picturetoInsert = new ImageIcon(selectedItem.toString());
JLabel label = new JLabel("", picturetoInsert, JLabel.CENTER);
JPanel panel = new JPanel(new GridLayout(1, 1));
panel.add(label, BorderLayout.CENTER);
jInternalFrame22.getContentPane();
jInternalFrame22.setContentPane(panel);
jInternalFrame22.setVisible(true);

Why don you try with the paint component?
class imagePanel extends JPanel
{
BufferedImage image;
public void paintComponent(Graphics g)
{
super.paintComponent(g);
if(image != null)
{
g.drawImage(image, 0, 0, this);
}
}
}

There could be a few reasons for this. You could try
imagePanel.invalidate()
before the repaint call to force it to redraw.
Or possibly the label is to small and needs resizing since there may not have been an image before. You could try invoke the
frame.pack();
method to get the frame to recompute its component sizes.
Or you could try force the size of the label (setting its min size) to ensure it has enough space to show the image.

Related

Images not visible in JList

I'm writing a little photo application (asked some questions before) and I have one problem which I cannot resolve. The idea is that there are two sections: the upper one is for an overview (using thumbnails) and the lower one shows the selected image in it's full size. I cannot use ImageIO (required by my lecturer).
I'm using a JList for the overview but most images are not visible. I chose a folder with about 20 images and only 2 show up. And one of them isn't even centered.
For some reason, if I delete those lines:
thumbnaillist.setFixedCellWidth(thumbW);
thumbnaillist.setFixedCellHeight(thumbH);
One image shows up that wasn't visible before, but now the other two disappear.
This is my code:
public class PVE extends JFrame {
private JFileChooser fileChoose;
//MenuBar
private JMenuBar menubar;
private JMenu file;
private JMenuItem openFolder;
private JMenuItem exit;
//Thumbnails
private JList thumbnaillist;
private DefaultListModel<ImageIcon> listmodel;
private JScrollPane tscroll;
private ImageIcon thumbs;
private int thumbW = 100;
private int thumbH = 100;
//for full size view
private JPanel imgview;
public PVE() {
setLayout(new BorderLayout());
//MenuBar
menubar = new JMenuBar();
file = new JMenu("File");
openFolder = new JMenuItem("Open folder...");
exit = new JMenuItem("Quit");
file.add(openFolder);
file.addSeparator();
file.add(exit);
menubar.add(file);
setJMenuBar(menubar);
fileChoose = new JFileChooser();
openFolder.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
fileChoose.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
fileChoose.showOpenDialog(null);
File chosenDir = fileChoose.getSelectedFile();
loadToThumbView(chosenDir);
}
});
//Thumbnail view
listmodel = new DefaultListModel();
thumbnaillist = new JList(listmodel);
thumbnaillist.setLayoutOrientation(JList.HORIZONTAL_WRAP);
thumbnaillist.setFixedCellWidth(thumbW);
thumbnaillist.setFixedCellHeight(thumbH);
thumbnaillist.setVisibleRowCount(1);
tscroll = new JScrollPane(thumbnaillist, JScrollPane.VERTICAL_SCROLLBAR_NEVER,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
tscroll.setPreferredSize(new Dimension(0, 100));
add(tscroll, "North");
//for full size view
imgview = new JPanel();
imgview.setBackground(Color.decode("#f7f7f7"));
add(imgview, "Center");
setTitle("Photo Viewer");
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
SwingUtilities.updateComponentTreeUI(this);
} catch (Exception e) {
}
setSize(700, 700);
setLocation(200, 200);
setVisible(true);
}
public void loadToThumbView(File folder) {
listmodel.removeAllElements();
File[] imgpaths = folder.listFiles();
for (int j = 0; j < imgpaths.length; j++) {
listmodel.addElement(resizeToThumbnail(new ImageIcon(imgpaths[j].toString())));
}
}
public ImageIcon resizeToThumbnail(ImageIcon icon) {
Image img = icon.getImage();
BufferedImage bf = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
Graphics g = bf.createGraphics();
g.drawImage(img, 0, 0, thumbW, thumbH, null);
ImageIcon kB = new ImageIcon(bf);
return kB;
}
public static void main(String argv[]) {
PVE pv = new PVE();
}
}
Your problem is because of the way you're scaling your images.
I'm not exactly sure why but I guess it has something to do with the BufferedImage#createGraphics() call and that I was able to reproduce the problem with .jpg images while .png files were correctly painted.
However if you scale your images instead of converting them to a BufferedImage and getting a new ImageIcon from it, you get the correct output:
public ImageIcon resizeToThumbnail(ImageIcon icon) {
Image img = icon.getImage();
Image scaled = img.getScaledInstance(thumbW, thumbH, Image.SCALE_SMOOTH);
return new ImageIcon(scaled);
}
This is the folder I used to test:
And the outputs with your code and mine:
Important notes
And as as a recommendation don't make a window that big if all you're using is that little bar above. If you're adding something else below, then it's ok but for now it's not that "user friendly" (IMHO). Instead of JFrame#setSize() you could try using JFrame#pack() method so your frame resizes to it's preferred size.
Some other things I noted in your program:
You're not placing it inside the Event Dispatch Thread (EDT) which is dangerous since your application won't be Thread safe that way. You can change that if you change your main method as follows:
public static void main(String argS[]) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
PVE pv = new PVE();
}
});
}
You're setting the JScrollPane preferred size, instead you should override its getPreferredSize() method, see Should I avoid the use of setPreferred|Maximum|MinimumSize methods in Java Swing? (YES)
You're extending JFrame, you should instead create an instance of it unless you're overriding one of its methods (and you're not, so don't do it) or you have any good reason to do it. If you need to extend a Container you should extend JPanel instead, as JFrame is a rigid container which cannot be placed inside another one. See this question and this one.
I think I'm not missing anything, and hope this helps
Your “scaled” images are actually images which are the same size as the original image, but are blank except for a scaled version drawn in the upper left corner. That upper left corner is clipped out of view in each rendered cell (at least for the somewhat large images I tested with).
The scaled image needs to be created with the thumbnail size, not the size of the original image. Meaning, change this:
BufferedImage bf = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB);
to this:
BufferedImage bf = new BufferedImage(thumbW, thumbH, BufferedImage.TYPE_INT_ARGB);

JPanel background image doesn't apply to a JPanel inside it

I'm working on a simple registration window that appears when the java app opens.
It's a JFrame, that has a JPanel in it, which has text fields, labels, and another panel which also contains text fields and labels.
My problem is that the outside panel has a background image, but it doesn't apply to the panel inside it as seen here:
Here is the whole window code:
public void start() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
ex.printStackTrace();
}
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
frame = new JFrame("Chat");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//frame.setMaximumSize(new Dimension((int)screenSize.getWidth()-1000, (int)screenSize.getHeight()-1000));
frame.setMinimumSize(new Dimension((int)screenSize.getWidth()/2-200,(int) screenSize.getHeight()/2));
frame.setResizable(false);
welcome = new LoginPanel();
welcome.setLayout(new BoxLayout(welcome, BoxLayout.Y_AXIS));
welcome.setBorder(BorderFactory.createEmptyBorder(50, welcome.getWidth()/2-500, 50, welcome.getWidth()/2 -500));
//repaintThread = new Thread(new RepaintRunnable(frame, welcome));
//repaintThread.start();
request = new JLabel("Please fill the required fields below:");
request.setFont(new Font("Serif", Font.BOLD, 20));
request.setBorder(BorderFactory.createEmptyBorder(0, 0, 10, 0));
request.setAlignmentX(Component.CENTER_ALIGNMENT);
userInfo = new JPanel();
userInfo.setLayout(new BoxLayout(userInfo, BoxLayout.Y_AXIS));
userInfo.setAlignmentX(Component.CENTER_ALIGNMENT);
Font fieldType = new Font("Serif", Font.PLAIN, 15);
PlainDocument doc = new PlainDocument();
doc.setDocumentFilter(new NameDocument());
enterFirstName = new JLabel("First name:");
enterFirstName.setAlignmentX(Component.LEFT_ALIGNMENT);
enterFirstName.setFont(fieldType);
firstName = new JTextField(20);
firstName.setMaximumSize(firstName.getPreferredSize());
firstName.setDocument(NameDocument.getNewNameDocument(NameDocument.NO_SPACE));
firstName.getDocument().addDocumentListener(new ChangeDocumentListener());
firstName.addActionListener(new ConfirmListener());
firstName.setAlignmentX(Component.LEFT_ALIGNMENT);
enterSecName= new JLabel("Surname:");
enterSecName.setAlignmentX(Component.LEFT_ALIGNMENT);
enterSecName.setFont(fieldType);
secName = new JTextField(30);
secName.setMaximumSize(secName.getPreferredSize());
secName.setDocument(NameDocument.getNewNameDocument(NameDocument.HAS_SPACE));
secName.getDocument().addDocumentListener(new ChangeDocumentListener());
secName.addActionListener(new ConfirmListener());
secName.setAlignmentX(Component.LEFT_ALIGNMENT);
enterNickname = new JLabel("Nickname (how other people will see you in chat):");
enterNickname.setAlignmentX(Component.LEFT_ALIGNMENT);
enterNickname.setFont(fieldType);
nickname = new JTextField(30);
nickname.setMaximumSize(nickname.getPreferredSize());
nickname.setDocument(NameDocument.getNewNameDocument(NameDocument.NO_SPACE));
nickname.addActionListener(new ConfirmListener());
nickname.setAlignmentX(Component.LEFT_ALIGNMENT);
userInfo.add(enterFirstName);
userInfo.add(firstName);
userInfo.add(enterSecName);
userInfo.add(secName);
userInfo.add(enterNickname);
userInfo.add(nickname);
confirm = new JButton("Submit");
confirm.setAlignmentX(Component.CENTER_ALIGNMENT);
confirm.setEnabled(false);
confirm.addActionListener(new ConfirmListener());
welcome.add(request);
welcome.add(userInfo);
welcome.add(new Box.Filler(new Dimension(10, 10), new Dimension(10, 10), new Dimension(10, 10)));
welcome.add(confirm);
frame.getContentPane().add(BorderLayout.CENTER, welcome);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
And here is the LoginPanel code(the outside JPanel):
public class LoginPanel extends JPanel {
public void paintComponent(Graphics g) {
try {
super.paintComponent(g);
BufferedImage background = ImageIO.read(new File("Background.jpg"));
g.drawImage(background, 0, 0, getWidth(), getHeight(), null);
} catch(Exception ex) {
ex.printStackTrace();
}
}
}
it'll also be great if someone will give me advice on how to make this code better, since I'm beginner in Java.
Remember to call setOpaque(false); on any inner JPanels (and on some other components -- though not all) that cover up your image-displaying JPanel. This will allow background images to show through. You don't have to do this with JLabels as they are see-through (non-opaque) by default, but you do with JPanels.
So for you it will be:
userInfo = new JPanel();
userInfo.setOpaque(false);
One other problem is that you should never read in images from within a paintComponent method. This method may be called often, and why re-read the image when it can and should be read in only once. And more importantly, this method should be fast as possible since slowing it down needlessly will slow down the perceived responsiveness of your program. Read the image in once, and store it in a variable that is then displayed within paintComponent.
e.g.,
public class LoginPanel extends JPanel {
private BufferedImage background;
public LoginPanel(BufferedImage background) {
this.background = background;
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (background != null) {
g.drawImage(background, 0, 0, getWidth(), getHeight(), this);
}
}
}
Read the image in and then pass it into the constructor of your LoginPanel class.
Not related to your problem but:
frame.getContentPane().add(BorderLayout.CENTER, welcome);
Since JDK 4 you don't need to use the getContentPane() method you can just use frame.add(...) and the component will be added to the content pane.
Also you are using the wrong add(...) method. You are using add(constraint, component). If you read the API for the method it will tell you to use the add(component, constraint) method.
So you could be using:
frame.add(welcome, BorderLayout.CENTER);

How to change the image of a JLabel

I know this was answered a few times before, but the ones i found were answered with blocks of program specific code and i was having trouble discerning what specific code actually changed the image. I'm trying to change the jlabel image on my GUI during runtime by pushing a button.
public JPanel createContentPane (){
JPanel totalGUI = new JPanel();
totalGUI.setLayout(null);
pictureArea = new JPanel();
pictureArea.setLayout(null);
pictureArea.setLocation(560, 0);
pictureArea.setSize(860, 500);
totalGUI.add(pictureArea);
picture = new JLabel(image);
picture.setLocation(0, 0);
picture.setSize(800, 800);
picture.setHorizontalAlignment(0);
pictureArea.add(picture);
//skipping other code
decision2 = new JButton("Next");
decision2.setLocation(160, 20);
decision2.setSize(70, 30);
decision2.addActionListener(this);
buttonPanel.add(decision2);
return totalGUI;
}
public void actionPerformed(ActionEvent e) {
//skipped other code
else if(e.getSource() == decision2){
//code i need for changing the image
}
}
Thank you for any help you can provide.
You're looking for JLabel's setIcon method
label.setIcon(new ImageIcon(getClass().getResource("/path/to/image.png")));
Have you tried this ?
//code i need for changing the image
call the function that has the JLabel defined, and pass the image_location eg: images/image.png
yourfunction(String imagelocation)
{
BufferedImage bufImg=ImageIO.read(new File(image_location));
jlabel.setIcon(new ImageIcon(bufImg));
}
reference:http://docs.oracle.com/javase/7/docs/api/

How can I place JButton over a JLabel with image?

I use NetBeans IDE to create an application using java. I want to include a JButton over a JLabel with image. Actually when I add JButton over the JLabel it would inserted but it will transparent and the name and the button didn't display. It seems the button to be added under the JLabel. How can I overcome this problem?
there are two ways
put image to JPanel by override paintComponent (standard way)
JLabel haven't any LayoutManager in API, you have to set LayoutManager, then JLabel will be container
ImageIcon img = null;
class Panel extends JPanel{
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (img == null){
img = new ImageIcon("d:\\picture.jpg");
g.drawImage(img.getImage(), 0, 0, null);
}
}
}
//in the constructor
JButton button = new JButton( "OK");
Panel panel = new Panel();
panel.add(button);
add(panel);

Java adding ImageIcon to JLabel

I am trying to make a very basic game with Java and I am having trouble displaying an image on a JFrame. It has worked in the past for me and now is not, i can't see what I did wrong.
I have tried printing the current working directory and changing where I get my image to match that. It is likely that the problem is not getting the image, since my (filefinder or filereader or something like that) can find it without problems, but I cannot correctly add it (the ImageIcon) to the JLabel, or that to the JFrame.
This is my code...
JFrame frame = new JFrame("no image");
ImageIcon image = new ImageIcon("C:/Documents and Settings/user/Desktop/hi/xD/JavaApplication2/image.png");
JLabel imagelabel = new JLabel(image);
frame.add(imagelabel);
The JFrame has been setVisible(true) and pack().
Could someone please help me understand what is wrong.
Your problem lies here:
ImageIcon image = new ImageIcon("C:/Documents and Settings/user/Desktop/hi/xD/JavaApplication2/image.png");
JLabel imagelabel = new JLabel(character);
You create an ImageIcon "image" but you create your JLabel with "character".
It should be:
JLabel imagelabel = new JLabel(image);
Try,
ImageIcon image = new ImageIcon("c:\\path\\image.png");
imagelabel = new JLabel(character, image, JLabel.CENTER);
frame.add(imagelabel);
Take a look at Tutorial - How to use Icons
import javax.awt.*;
import java.awt.*;
import java.awt.event*;
//class name image
class image {
image()
//constructor {
Frame f=new Frame("Image");
//Frame
f.setSize(500,500);
f.setVisible(true);
Panel p =new Panel();
//Panel
f.add(p);
p.addLayout(null);
ImageIcon ii=new ImageIcon("set your image path");
//ImageIcon is used to image Display .
Label l =new Label(ii);
p.add(ii);
p.setBounds(set you bounds);
//Like that(20,20,500,40);
}
public static void main(String [] args) {
image obj = new
}
}

Categories