Java ImageWorker使用数组返回类型发布/处理方法

时间:2013-01-11 03:30:09

标签: java arrays swing process swingworker

我正在尝试改进我的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);
        }
    }
}

流程方法的问题在于我无法弄清楚如何为数组设置正确的索引,将发布的元素写入。我想发布传递索引以及图像,但这违反了类设置的返回类型。发布只能有一个类型的参数吗?

1 个答案:

答案 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);
        }
    }
}