usando ImageIcon
es probablemente la cosa más fácil de hacer. Un par de cosas a tener en cuenta:
ImageIcon(URL)
sí mismo hace uso de Toolkit.getImage(URL)
. Puede preferir usar Toolkit.createImage(URL)
en su lugar - getImage()
puede usar datos de imagen en caché o compartidos.
ImageIcon
utiliza un MediaTracker
para esperar efectivamente hasta que la imagen esté completamente cargada.
Por lo tanto, el problema no puede ser el uso de Toolkit
(ImageIO
es un animal diferente), sino más bien el hecho de que usted no está haciendo una imagen completamente cargado. Una cosa interesante intentar sería:
Image image = f.getToolkit().createImage(url);
//...
ImagePanel imagePanel = new ImagePanel(image);
imagePanel.prepareImage(image, imagePanel);
//...
Mi swing/AWT/J2D pueden ser un poco borrosa, pero la idea es que desde su ImagePanel
es un ImageObserver
, puede ser notificada de forma asíncrona sobre información de la imagen. El método Component.imageUpdate()
debe invocar repaint
según sea necesario.
Editar:
Como se señaló en los comentarios, no se requiere la llamada a prepareImage
- un ejemplo de trabajo se incluye a continuación. La clave es que el método Oreemplazado invoca Graphics.drawImage
, que proporciona el gancho ImageObserver
. El método imageUpdate
(implementado en java.awt.Component
) se invocará continuamente con el indicador ImageObserver.FRAMEBITS
establecido.
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("http://pscode.org/media/starzoom-thumb.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);
}
});
}
}
Gran captura. Probado 'Toolkit.createImage (URL)' como un reemplazo directo 'drop-in' para 'new ImageIcon (url) .getImage()' y la imagen también se recicló. Tenga en cuenta que no me molesté en llamar a 'prepareImage'. –
Editaré mi respuesta mañana, pero también noté que la prueba que creé (una versión modificada de su código) no requirió la llamada a prepareImage. Creo que la llamada a Graphics.drawImage proporciona el gancho ImageObserver ... – kschneid
Solo noté la edición justo ahora. ¡Pensé que esta podría ser mi primera sesión de preguntas y respuestas canónicas, pero resulta que tu respuesta es mejor! No estoy seguro si estar irritado por ser derrotado, o encantado de encontrar a alguien con más detalles. (Considera unos momentos más ...) De acuerdo, estoy encantado. Gracias por tu respuesta. :) –