Un JLabel
permet le contenu HTML, qui peuvent contenir une image parmi le contenu:JLabel: charge images HTML de façon asynchrone
String html = "<html><body>...<img src=\"http://some_url/image.png\"/>...</body></html>";
JLabel label = new JLabel(html);
Notez que j'utilise le JLabel
pour le rendu des images dans un JXTreeTable
, de sorte que la mise à jour du texte du JLabel
est fait sur l'EDT dans le moteur de rendu.
Le problème est que l'image est chargée de manière synchrone. Avec un serveur lent, l'EDT peut être bloqué pendant plusieurs secondes pendant le chargement de l'image.
J'ai déjà découvert pourquoi l'image est chargée de manière synchrone et quelle classe je dois modifier pour passer au chargement asynchrone d'images.
Le chargement de l'image est effectué par la classe javax.swing.text.html.ImageView
, qui a une méthode setLoadsSynchronously
.
Le problème est que je n'ai pas la moindre idée comment je peux facilement régler le HTMLFactory
/HTMLEditorKit
qui est responsable de la création de ce ImageView
, et qui est utilisé en interne par le JLabel
. Pour rendre les choses encore plus compliquées, j'ai besoin d'une solution qui fonctionne pour tout Look and Feels.
Dans le cas où ce qui précède n'est pas clair, la décharge de fil suivant montre ce que l'EDT est bloquée au cours de la recherche d'images:
"[email protected]" prio=6 tid=0x10 nid=NA waiting
java.lang.Thread.State: WAITING
at java.lang.Object.wait(Object.java:-1)
at java.awt.MediaTracker.waitForID(MediaTracker.java:677)
at javax.swing.ImageIcon.loadImage(ImageIcon.java:314)
at javax.swing.ImageIcon.setImage(ImageIcon.java:381)
at javax.swing.text.html.ImageView.loadImage(ImageView.java:704)
at javax.swing.text.html.ImageView.refreshImage(ImageView.java:673)
at javax.swing.text.html.ImageView.sync(ImageView.java:645)
at javax.swing.text.html.ImageView.getPreferredSpan(ImageView.java:443)
at javax.swing.text.FlowView$LogicalView.getPreferredSpan(FlowView.java:732)
at javax.swing.text.FlowView.calculateMinorAxisRequirements(FlowView.java:233)
at javax.swing.text.ParagraphView.calculateMinorAxisRequirements(ParagraphView.java:717)
at javax.swing.text.html.ParagraphView.calculateMinorAxisRequirements(ParagraphView.java:157)
at javax.swing.text.BoxView.checkRequests(BoxView.java:935)
at javax.swing.text.BoxView.getMinimumSpan(BoxView.java:568)
at javax.swing.text.html.ParagraphView.getMinimumSpan(ParagraphView.java:270)
at javax.swing.text.BoxView.calculateMinorAxisRequirements(BoxView.java:903)
at javax.swing.text.html.BlockView.calculateMinorAxisRequirements(BlockView.java:146)
at javax.swing.text.BoxView.checkRequests(BoxView.java:935)
at javax.swing.text.BoxView.getMinimumSpan(BoxView.java:568)
at javax.swing.text.html.BlockView.getMinimumSpan(BlockView.java:378)
at javax.swing.text.BoxView.calculateMinorAxisRequirements(BoxView.java:903)
at javax.swing.text.html.BlockView.calculateMinorAxisRequirements(BlockView.java:146)
at javax.swing.text.BoxView.checkRequests(BoxView.java:935)
at javax.swing.text.BoxView.getMinimumSpan(BoxView.java:568)
at javax.swing.text.html.BlockView.getMinimumSpan(BlockView.java:378)
at javax.swing.text.BoxView.calculateMinorAxisRequirements(BoxView.java:903)
at javax.swing.text.html.BlockView.calculateMinorAxisRequirements(BlockView.java:146)
at javax.swing.text.BoxView.checkRequests(BoxView.java:935)
at javax.swing.text.BoxView.getPreferredSpan(BoxView.java:545)
at javax.swing.text.html.BlockView.getPreferredSpan(BlockView.java:362)
at javax.swing.plaf.basic.BasicHTML$Renderer.<init>(BasicHTML.java:383)
at javax.swing.plaf.basic.BasicHTML.createHTMLView(BasicHTML.java:67)
at javax.swing.plaf.basic.BasicHTML.updateRenderer(BasicHTML.java:207)
at javax.swing.plaf.basic.BasicLabelUI.propertyChange(BasicLabelUI.java:417)
at javax.swing.plaf.synth.SynthLabelUI.propertyChange(SynthLabelUI.java:296)
at java.beans.PropertyChangeSupport.fire(PropertyChangeSupport.java:335)
at java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:327)
at java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:263)
at java.awt.Component.firePropertyChange(Component.java:8428)
at org.jdesktop.swingx.renderer.JRendererLabel.firePropertyChange(JRendererLabel.java:292)
at javax.swing.JLabel.setText(JLabel.java:330)
Les exemples [ici] (https://stackoverflow.com/q/4530428/230513) utilisent 'SwingWorker' pour mettre à jour l'icône d'un label. – trashgod