Using SwingWorker to update the progress of a thread from another class

ぃ、小莉子 提交于 2020-01-14 05:27:50

问题


Value is updated by the end, but not during the process. I guess the reason is that the publish method locates outside the loop.

As to invoke PropertyChangeListener, can it be achieved by defining the class without extends SwingWorker<Void, Void> ?

To address the question in another way, I have two threads locate in two different classes. Is it possible to build communication between the two using SwingWorker?

Class Application

import javax.swing.JFrame;

public class Application {
    public static void main(String[] args){
        javax.swing.SwingUtilities.invokeLater(new Runnable(){
            @Override
            public void run() {
                JFrame frame = new Progress();
                frame.setSize(200, 300);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.pack();
                frame.setVisible(true);
            }
        });     
    }
}

Class Progress

import java.awt.BorderLayout;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;

@SuppressWarnings("serial")
public class Progress extends JFrame{
    private JProgressBar progressbar;

    public Progress(){
        JButton button = new JButton("Run");
        progressbar = new JProgressBar(0, 100);
        progressbar.setValue(0);
        progressbar.setStringPainted(true);
        JPanel panel = new JPanel();
        panel.add(button);
        panel.add(progressbar);
        add(panel, BorderLayout.PAGE_START);

        button.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent event){
                start();
            }
        });
    }

    private void start(){
        progressbar.setValue(0);

        SwingWorker<Void, Integer> worker = new SwingWorker<Void, Integer>(){

            @Override
            protected Void doInBackground() throws Exception {
                Simulation sim = new Simulation();
                publish(sim.getCount());
                return null;
        }

            @Override
            protected void process(List<Integer> chunks) {
                Integer progress = chunks.get(chunks.size()-1);
                progressbar.setValue(progress);
                progressbar.repaint();
                progressbar.update(progressbar.getGraphics());
            }

            @Override
            protected void done() {
                Toolkit.getDefaultToolkit().beep();
            }
        };
        worker.execute();
    }
}

Class Simulation

public class Simulation {
    private int count;

    public Simulation(){
        for(int i=0; i<100; i++){
            count++;
            System.out.println(count);

            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public int getCount(){
        return count;
    }
}

How can I update the value during the process?


回答1:


You need to implement PropertyChangeListener on your SwingWorker and listen to the Progress property changes and then from overridden propertChange() method update your JProgressBar.

Here is what you are looking.

Hope this helps.



来源:https://stackoverflow.com/questions/23699256/using-swingworker-to-update-the-progress-of-a-thread-from-another-class

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!