Using ImageIcon
is probably the most straightforward thing to do. A couple of things to keep in mind:
ImageIcon(URL)
itself makes use of Toolkit.getImage(URL)
. You may prefer using Toolkit.createImage(URL)
instead - getImage()
may use cached or shared image data.
ImageIcon
makes use of a MediaTracker
to effectively wait until the image is completely loaded.
So, your issue may not be the use of Toolkit
(ImageIO
is a different beast), but rather the fact that you're not rendering a fully loaded image. One interesting thing to try would be:
Image image = f.getToolkit().createImage(url);
//...
ImagePanel imagePanel = new ImagePanel(image);
imagePanel.prepareImage(image, imagePanel);
//...
My Swing/AWT/J2D may be a bit fuzzy, but the idea is that since your ImagePanel
is an ImageObserver
, it can be notified asynchronously about image information. The Component.imageUpdate()
method should invoke repaint
as needed.
Edit:
As noted in the comments, the call to prepareImage
is not required - a working example is included below. The key is that the overridden paintComponent
method invokes Graphics.drawImage
, which provides the ImageObserver
hook. The imageUpdate
method (implemented in java.awt.Component
) will continuously be invoked with the ImageObserver.FRAMEBITS
flag set.
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.image.ImageObserver;
import java.net.MalformedURLException;
import java.net.URL;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
public class ImagePanel extends JPanel {
private final Image image;
public ImagePanel(Image image) {
super();
this.image = image;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(this.image, 0, 0, getWidth(), getHeight(), this);
}
public static void main(String[] args) throws MalformedURLException {
final URL url = new URL("https://i.stack.imgur.com/iQFxo.gif");
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame f = new JFrame("Image");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLocationByPlatform(true);
Image image = f.getToolkit().createImage(url);
ImagePanel imagePanel = new ImagePanel(image);
imagePanel.setLayout(new GridLayout(5, 10, 10, 10));
imagePanel.setBorder(new EmptyBorder(20, 20, 20, 20));
for (int ii = 1; ii < 51; ii++) {
imagePanel.add(new JButton("" + ii));
}
f.setContentPane(imagePanel);
f.pack();
f.setVisible(true);
}
});
}
}
Toolkit.createImage(URL)
as a direct 'drop-in' replacement fornew ImageIcon(url).getImage()
& the image also cycled. Note that I did not bother to callprepareImage
. – Nammu