3

SwingWorker クラスの ImageWorker を改善しようとしています。ImageWorker は、大量の画像配列で使用することを目的としています。表示された画像の配列インデックスが null に設定されている間、ImageWorker は定期的に呼び出されて新しい画像をロードします。これが、i < currentPosition+40 までしかロードしない理由です。これにより、アレイ全体を一度にロードしようとするのを防ぐことができます。これは、低速のマシンには多すぎます。現在、EDT で done() メソッドを実行する前に、40 個の画像すべてをロードする必要があります。ImageWorker を早期に開始する時間がない時点で、数ミリ秒の単一の遅延が発生します。

パブリッシュ/プロセスを実装したいのですが、これらのメソッドを配列で使用する例が見つからないようです。配列の戻り値の型でパブリッシュ/プロセスを使用するための既知の良い方法はありますか? または、単一の画像を imageArray[i] として公開し、プロセスを使用してそれらの画像を適切な配列に組み込む必要がありますか? これらのメソッドに配列を使用するコードが見つからないようです。文字列と整数だけです。

そもそも ImageWorker を使い始めるのを手伝ってくれた Trashgod のおかげです。私の最初の質問は、おそらくこの新しいスレッドを保証するほど十分に進化しました。元のスレッドには、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 を使用してそれらを配列の要素として配置する必要があるようです。プロセス部分はより難しいようです。上記のコードを編集して 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);
        }
    }
}

process メソッドの問題は、パブリッシュからの要素が書き込まれる配列の正しいインデックスを設定する方法がわからないことです。画像だけでなくインデックスも渡すようにパブリッシュしたいのですが、これはクラスで設定された戻り値の型に違反しています。パブリッシュは 1 つのタイプの引数のみを持つことができますか?

4

1 に答える 1

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);
        }
    }
}
于 2013-01-11T05:39:16.237 に答える