使用java swing在ImageIcon代理中显示动画gif
我以前写过这个使用java swing在ImageIcon代理中显示动画gif,java,swing,jlabel,imageicon,animated,Java,Swing,Jlabel,Imageicon,Animated,我以前写过这个 JLabel label=new JLable(URL); frame.getContentPane().add(label); 它可以与动画gif图像一起使用 但是,当我想使用imageProxy从internet加载gif表单时 它不起作用 我的代理是这个 public class ImageProxy implements Icon{ ImageIcon imageIcon; URL imageURL; Thread retrievalThread; boolean re
JLabel label=new JLable(URL);
frame.getContentPane().add(label);
它可以与动画gif图像一起使用
但是,当我想使用imageProxy从internet加载gif表单时
它不起作用
我的代理是这个
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,我需要设置ImageObsever
我试过了,没用。并且imageIcon正常工作,getImageObserver没有代理打印null
我也试着阅读源代码,但我并没有真正理解
请帮助我,谢谢。问题的根源可能是
JLabel
实现的ImageObserver
接口:
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的实现,super的实现实际上负责调用JLabel
上的repaint()
来刷新动画图标的新帧。此外,返回false
意味着我们对更新不再感兴趣
您可以扩展JLabel
以克服此限制。下面是一个非常简单的JLabel
扩展,它覆盖了imageUpdate()
。此imageUpdate
实现的实际代码取自组件。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;
}
}
公共静态类CustomLabel扩展了JLabel{
私有静态最终布尔值isInc=true;
专用静态最终整数增量=100;
公共自定义标签(图标图像){
超级(图像);
}
@凌驾
公共布尔图像更新(图像img、int-infoflags、int-x、int-y、,
整数w,整数h){
整数率=-1;
如果((信息标志和(帧位|所有位))!=0){
比率=0;
}如果((信息标志和某些位)!=0,则为else{
如果(isInc){
比率=增加率;
如果(比率<0){
比率=0;
}
}
}
如果(速率>=0){
重新绘制(速率,0,0,getWidth(),getHeight());
}
返回(infoflags&(ALLBITS | ABORT))==0;
}
}
您可以插入imageUpdate()
,添加在图像仍在加载时显示“加载图像”字符串的功能
我想知道为
ImageIcon
实现代理的真正原因是什么。如果需要同步图像加载,可以使用ImageIO
API 问题的根源可能是由JLabel
实现的ImageObserver
接口:
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的实现,super的实现实际上负责调用JLabel
上的repaint()
来刷新动画图标的新帧。此外,返回false
意味着我们对更新不再感兴趣
您可以扩展JLabel
以克服此限制。下面是一个非常简单的JLabel
扩展,它覆盖了imageUpdate()
。此imageUpdate
实现的实际代码取自组件。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;
}
}
公共静态类CustomLabel扩展了JLabel{
私有静态最终布尔值isInc=true;
专用静态最终整数增量=100;
公共自定义标签(图标图像){
超级(图像);
}
@凌驾
公共布尔图像更新(图像img、int-infoflags、int-x、int-y、,
整数w,整数h){
整数率=-1;
如果((信息标志和(帧位|所有位))!=0){
比率=0;
}如果((信息标志和某些位)!=0,则为else{
如果(isInc){
比率=增加率;
如果(比率<0){
比率=0;
}
}
}
如果(速率>=0){
重新绘制(速率,0,0,getWidth(),getHeight());
}
返回(infoflags&(ALLBITS | ABORT))==0;
}
}
您可以插入imageUpdate()
,添加在图像仍在加载时显示“加载图像”字符串的功能
我想知道为ImageIcon
实现代理的真正原因是什么。如果需要同步图像加载,可以使用ImageIO
API