我曾经这样写过
JLabel label=new JLable(URL);
frame.getContentPane().add(label);
它适用于动画 gif 图像
但是,当我想使用 imageProxy 从互联网加载 gif 时 它不起作用。
我的imageProxy是这个
public class ImageProxy implements Icon{
ImageIcon imageIcon;
URL imageURL;
Thread retrievalThread;
boolean retrieving =false;
public ImageProxy(URL url){
imageURL = url;
}
public int getIconHeight() {skip}
public int getIconWidth() {skip}
@Override
public void paintIcon(final Component c, Graphics g, int x, int y) {
System.out.println("paint");
if(imageIcon !=null){
imageIcon.paintIcon(c, g, x, y);
}else{
g.drawString("Loading image", x+10, y+80);
if(!retrieving){
retrieving =true;
retrievalThread = new Thread(new Runnable(){
public void run(){
try{
imageIcon = new ImageIcon(imageURL);
c.repaint();
}catch(Exception e){
e.printStackTrace();
}
}
});
retrievalThread.start();
}
}
}
}
可以成功加载图片,但不会自动刷新图片 我必须通过缩放框架来改变图像, 每次我缩放它都会改变一张图片
我阅读了文档, 它说,在其他情况下显示 gif 我需要 setImageObsever 我试过了,没用。并且 imageIcon 在没有代理的情况下正常工作,通过 getImageObserver 打印 null
我也尝试阅读源代码,但我不太明白。
请帮帮我,谢谢。
最佳答案
问题的根源很可能是在JLabel
实现ImageObserver
接口(interface)上:
public boolean imageUpdate(Image img, int infoflags,
int x, int y, int w, int h) {
// Don't use getDisabledIcon, will trigger creation of icon if icon
// not set.
if (!isShowing() ||
!SwingUtilities.doesIconReferenceImage(getIcon(), img) &&
!SwingUtilities.doesIconReferenceImage(disabledIcon, img)) {
return false;
}
return super.imageUpdate(img, infoflags, x, y, w, h);
}
以下是 SwingUtilities.doesIconReferenceImage
的代码:
static boolean doesIconReferenceImage(Icon icon, Image image) {
Image iconImage = (icon != null && (icon instanceof ImageIcon)) ?
((ImageIcon)icon).getImage() : null;
return (iconImage == image);
}
如您所见,如果图标不是 ImageIcon
的实例,则 imageUpdate()
的结果将为 false
,甚至无需调用 super 的实现,该实现实际上负责在 JLabel
上调用 repaint()
来刷新动画图标的新帧。此外,返回 false 意味着我们不再对更新感兴趣。
您可以扩展JLabel
来克服这个限制。这是 JLabel
的一个非常简单的扩展,它重写了 imageUpdate()
。 imageUpdate
实现的实际代码取自 Component.imageUpdate()
,为简单起见,仅 isInc
和 incRate
是常量:
public static class CustomLabel extends JLabel {
private static final boolean isInc = true;
private static final int incRate = 100;
public CustomLabel(Icon image) {
super(image);
}
@Override
public boolean imageUpdate(Image img, int infoflags, int x, int y,
int w, int h) {
int rate = -1;
if ((infoflags & (FRAMEBITS | ALLBITS)) != 0) {
rate = 0;
} else if ((infoflags & SOMEBITS) != 0) {
if (isInc) {
rate = incRate;
if (rate < 0) {
rate = 0;
}
}
}
if (rate >= 0) {
repaint(rate, 0, 0, getWidth(), getHeight());
}
return (infoflags & (ALLBITS | ABORT)) == 0;
}
}
您可以插入imageUpdate()
来添加在图像仍在加载时显示“正在加载图像”字符串的功能。
我想知道ImageIcon
实现代理的真正原因是什么。如果您需要同步图像加载,可以使用ImageIO
API。
关于java - 使用 java swing 在 ImageIcon 代理中显示动画 gif,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15744415/