ProgressMonitor отображается после завершения doInBackground - PullRequest
0 голосов
/ 05 декабря 2018

Я пытаюсь использовать ProgressMonitor для обновления пользователя, а также дать возможность отменить операцию.

Это класс SwingWorker, который я использую для чтения графических изображений с HD.Po.getThumbNail () использует ImageIO.read (...);что занимает много времени.

public class BuildArray extends SwingWorker<Object[][], Void>
{
    private ArrayList<PhotoObject> files;
    private Object[][] array;
    private ImageIcon broken;

    private int row;
    private int column;

    public BuildArray(ArrayList<PhotoObject> files, ImageIcon broken)
    {
        this.files = files;
        this.broken = broken;
        column = PhotoObject.HEADER.length;
        array = new Object[files.size()][column];
    }



    @Override
    protected Object[][] doInBackground() throws Exception
    {
        row = 0;
        setProgress(0);
        //System.out.println("SwingWorker: " + javax.swing.SwingUtilities.isEventDispatchThread());
        for (PhotoObject pO : files)
        {
            array[row][0] = pO.getFile();
            array[row][1] = pO.getStatus();
            array[row][2] = pO.getSearchWords();
            if (pO.getThumbNail() == null)
                array[row][3] = broken;
            else
                array[row][3] = new ImageIcon(pO.getThumbNail());
            row++;

            int current = row * 100 / files.size();

            //publish(row);
            setProgress(current);

            if (isCancelled())
                trimArray();
        }
        return array;
    }
}

Это класс 'Manager', который создает экземпляр объекта SwingWorker и возвращает Object [] [] в класс графического интерфейса пользователя, который будет отображать результаты в JTable.Диспетчер передаст ссылку на класс SwingWorker обратно в графический интерфейс для просмотра.

public class PhotoManager extends Thread implements IFunctions
{
    private Object [][] build2DArray(ArrayList<PhotoObject> files, boolean showMonitor)
    {
        BuildArray buildArray = new BuildArray(files, BROKEN);

        if (showMonitor)            
            monitor.startMonitor(buildArray, 0, files.size());

        //System.out.println("PhotoManager: " + javax.swing.SwingUtilities.isEventDispatchThread());

        buildArray.execute();

        Object[][] array = null;
        try
        {
            array = buildArray.get();
        }
        catch (InterruptedException | ExecutionException e)
        {
            array = buildArray.getArray();
        }

        return array;
    }
}

Это класс графического интерфейса, который пытается отобразить ProgressMonitor.

public class MainWindow extends JFrame implements ActionListener, IReDraw, PropertyChangeListener, IProgressMonitor
{
    @Override
    public void startMonitor(SwingWorker<Object[][], Void> sw, int min, int max)
    {
        swingWorker = sw;
        swingWorker.addPropertyChangeListener(this);

        monitor = new ProgressMonitor(this, null, "Processing...", min, max);
    }

    @Override
    public void propertyChange(PropertyChangeEvent evt)
    {
        if (evt.getPropertyName().equals("progress"))
        {
            //int x = (Integer) evt.getNewValue();
            int x = swingWorker.getProgress();
            monitor.setProgress(x);
        }
    }

Поэтому, когда я запускаю это, метод propertyChange () вызывается только после завершения метода doInBackground ().Таким образом, ProgressMonitor отображается только после завершения SwingWorker, что бессмысленно.Оба класса GUI и Manager работают на EDT из того, что я могу сказать.

Я включил только подходящие методы, я думаю.Я смотрел на примеры ProgressMonitor и SwingWorker как здесь, так и на других сайтах.я не знаю, почему это не работает для меня.

...