问题
I'm displaying an image in a JFrame using a JLabel and setting it's icon.
It works the first time, but whenever I go to change the image, it remains what I set it the first time, so I've tried this and still the same result.
contentPane.remove(lblPlaceholder);
lblPlaceholder = null;
lblPlaceholder = new JLabel("");
lblPlaceholder.setBounds(10, 322, 125, 32);
contentPane.add(lblPlaceholder);
lblPlaceholder.setIcon(new ImageIcon("tempimage.png"));
How can I get it to change it's image? I've also tried repainting the JFrame with no results.
回答1:
Works fine for me. I think there is something else in your code you're not sharing. A SSCCE would help clarify other issues.
Some suggestions based on what you have provided...
- Avoid
null
layouts (looks like you might be using one) - Avoid
setBounds
import java.awt.BorderLayout;
import java.awt.EventQueue;
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.ArrayList;
import java.util.List;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class ShowLabelImage {
public static void main(String[] args) {
new ShowLabelImage();
}
private JLabel label;
private List<BufferedImage> images;
private int currentPic = 0;
public ShowLabelImage() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
images = new ArrayList<>(2);
try {
images.add(ImageIO.read(new File("path/to/pic1")));
images.add(ImageIO.read(new File("path/to/pic2")));
} catch (IOException exp) {
exp.printStackTrace();
}
label = new JLabel();
label.setHorizontalAlignment(JLabel.CENTER);
label.setVerticalAlignment(JLabel.CENTER);
JButton switchPic = new JButton("Switch");
switchPic.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
currentPic++;
if (currentPic >= images.size()) {
currentPic = 0;
}
label.setIcon(new ImageIcon(images.get(currentPic)));
}
});
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(label);
frame.add(switchPic, BorderLayout.SOUTH);
switchPic.doClick();
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
回答2:
There is no need to create a new label, and it is probably hindering things.
Change:
contentPane.remove(lblPlaceholder);
lblPlaceholder = null;
lblPlaceholder = new JLabel("");
lblPlaceholder.setBounds(10, 322, 125, 32);
contentPane.add(lblPlaceholder);
lblPlaceholder.setIcon(new ImageIcon("tempimage.png"));
To:
lblPlaceholder.setIcon(new ImageIcon("tempimage.png"));
See also this working example.
Further tips
- Java GUIs might have to work on a number of platforms, on different screen resolutions & using different PLAFs. As such they are not conducive to exact placement of components. To organize the components for a robust GUI, instead use layout managers, or combinations of them, along with layout padding & borders for white space. E.G. The above GUI uses a
GridBagLayout
to center the image within aJScrollPane
. - For help with layouts provide ASCII art of the GUI as it should appear in smallest size and (if resizable) with extra width/height.
- For better help sooner, post an SSCCE.
回答3:
If you look at the ImageIcon constructor, you'll see that it loads the icon with this method: image = Toolkit.getDefaultToolkit().getImage(location);
The documentation of this method says:
* Returns an image which gets pixel data from the specified URL.
* The pixel data referenced by the specified URL must be in one
* of the following formats: GIF, JPEG or PNG.
* The underlying toolkit attempts to resolve multiple requests
* with the same URL to the same returned Image.
To refresh the ImageIcon every time you load it from the same filename, you should add something random to the end of the URL, without changeing the actual filename. Something like this should work:
try {
URL url = new URL(file.toURI().toString()
+ "?" + System.currentTimeMillis());
jLabel1.setIcon(new ImageIcon(url));
} catch (MalformedURLException ex) {
ex.printStackTrace();
}
来源:https://stackoverflow.com/questions/17480765/refreshing-a-jlabel-icon-image