我正在尝试改进我的SwingWorker类ImageWorker。 ImageWorker旨在用于大型图像阵列。定期调用ImageWorker来加载新图像,同时将所看到图像的数组索引设置为null。这就是为什么它只加载到i< currentPosition + 40阻止它试图一次性加载整个阵列,这对于较慢的机器来说太多了。目前它需要加载所有40个图像才能在EDT上运行done()方法。在我没有时间提前启动ImageWorker的地方,这会导致几毫秒的单一延迟。
我想实现发布/进程,但我似乎无法找到将这些方法与数组一起使用的示例。 使用带有数组返回类型的发布/进程是否有一个已知的良好实践?或者我应该尝试将单个图像发布为imageArray [i],然后使用process将这些图像合并到适当的数组中?我似乎无法找到任何使用这些方法的数组的代码,只有字符串和整数。
归功于trashgod帮助我开始使用ImageWorker。 我的original question已经发展到足以保证这个新线程。原始线程包含使用ImageWorker的代码的SSCCE,可在此处找到:Full Code。
private class ImageWorker extends SwingWorker<Image[], Image>
{
private int currentPosition;
private int arraySize;
private String trickName;
private Image[] imageArray;
public ImageWorker(int arraySize, int currentPosition, String trick)
{
super();
this.currentPosition = currentPosition;
this.arraySize = arraySize;
this.trickName = trick;
}
@Override
public Image[] doInBackground()
{
imageArray = new Image[arraySize];
for(int i = currentPosition; i < currentPosition+40 && i < arraySize; i++)
{
try
{
imageArray[i] = ImageIO.read(new File("images/" + trickName + (i+1) + ".jpg"));
}
catch (IOException e)
{
System.out.println(trickName);
System.out.println(e.getMessage());
System.exit(0);
}
}
return imageArray;
}
@Override
public void done()
{
try
{
if(trickName.equals("handCuffs"))
{
handCuffs = get();
}
else if(trickName.equals("cups"))
{
cups = get();
}
}
catch(InterruptedException ignore){}
catch(java.util.concurrent.ExecutionException e)
{
String why = null;
Throwable cause = e.getCause();
if(cause != null)
{
why = cause.getMessage();
}
else
{
why = e.getMessage();
}
System.err.println("Error retrieving file: " + why);
}
}
}
似乎我应该在for循环中的每个图像上使用publish,然后使用process将它们作为元素放在数组中。过程部分似乎更难。我编辑了上面的代码以包含一个进程方法,但它还没有正常工作。
private class ImageWorker extends SwingWorker<Image[], Image>
{
private int currentPosition;
private int arraySize;
private String trickName;
private Image[] imageArray;
public ImageWorker(int arraySize, int currentPosition, String trick)
{
super();
this.currentPosition = currentPosition;
this.arraySize = arraySize;
this.trickName = trick;
i = currentPosition;
}
@Override
public Image[] doInBackground()
{
imageArray = new Image[arraySize];
for(int i = currentPosition; i < currentPosition+40 && i < arraySize; i++)
{
try
{
imageArray[i] = ImageIO.read(new File("images/" + trickName + (i+1) + ".jpg"));
publish(imageArray[i], i);
}
catch (IOException e)
{
System.out.println(trickName);
System.out.println(e.getMessage());
System.exit(0);
}
}
return imageArray;
}
@Override
public void process(List<Image> chunks, int i)
{
for(Image element: chunks)
{
if(trickName.equals("handCuffs"))
{
handCuffs[i] = element;
}
else if(trickName.equals("cups"))
{
cups[i] = element;
}
}
}
@Override
public void done()
{
try
{
if(trickName.equals("handCuffs"))
{
handCuffs = get();
}
else if(trickName.equals("cups"))
{
cups = get();
}
}
catch(InterruptedException ignore){}
catch(java.util.concurrent.ExecutionException e)
{
String why = null;
Throwable cause = e.getCause();
if(cause != null)
{
why = cause.getMessage();
}
else
{
why = e.getMessage();
}
System.err.println("Error retrieving file: " + why);
}
}
}
流程方法的问题在于我无法弄清楚如何为数组设置正确的索引,将发布的元素写入。我想发布传递索引以及图像,但这违反了类设置的返回类型。发布只能有一个类型的参数吗?
答案 0 :(得分:3)
感谢trashgod和MadProgrammer对此的所有帮助。如果其他人想要实现类似的SwingWorker,这里是我的最终代码,包括封装arrayImage [i]的包装类和相应的索引int i。
private class ArrayWrapper
{
private int i;
private Image image;
public ArrayWrapper(Image image, int i)
{
this.i = i;
this.image = image;
}
public int getIndex()
{
return i;
}
public Image getImage()
{
return image;
}
}
private class ImageWorker extends SwingWorker<Image[], ArrayWrapper>
{
private int currentPosition;
private int arraySize;
private String trickName;
private Image[] imageArray;
public ImageWorker(int arraySize, int currentPosition, String trick)
{
super();
this.currentPosition = currentPosition;
this.arraySize = arraySize;
this.trickName = trick;
}
@Override
public Image[] doInBackground()
{
imageArray = new Image[arraySize];
for(int i = currentPosition; i < currentPosition+40 && i < arraySize; i++)
{
try
{
imageArray[i] = ImageIO.read(new File("images/" + trickName + (i+1) + ".jpg"));
ArrayWrapper wrapArray = new ArrayWrapper(imageArray[i], i);
publish(wrapArray);
}
catch (IOException e)
{
System.out.println(trickName);
System.out.println(e.getMessage());
System.exit(0);
}
}
return imageArray;
}
@Override
public void process(List<ArrayWrapper> chunks)
{
for(ArrayWrapper element: chunks)
{
if(trickName.equals("handCuffs"))
{
handCuffs[element.getIndex()] = element.getImage();
}
else if(trickName.equals("cups"))
{
cups[element.getIndex()] = element.getImage();
}
}
}
@Override
public void done()
{
try
{
if(trickName.equals("handCuffs"))
{
handCuffs = get();
}
else if(trickName.equals("cups"))
{
cups = get();
}
}
catch(InterruptedException ignore){}
catch(java.util.concurrent.ExecutionException e)
{
String why = null;
Throwable cause = e.getCause();
if(cause != null)
{
why = cause.getMessage();
}
else
{
why = e.getMessage();
}
System.err.println("Error retrieving file: " + why);
}
}
}