如何从swingworker更新GUI,返回两个不同的值

时间:2012-06-14 14:29:34

标签: java swing user-interface swingworker

我有一个Java应用程序,它使用SwingWorker更新GUI中的标签和进度条,效果很好。但是,我想在此设置中添加一项功能。

我的摇摆工作人员执行长度为n的任务,并重复该任务m次。现在我的GUI只是告诉我这个任务被重复了多少次,但是我想告诉我我们所处的任务的长度。说n=300m=50,我我喜欢这样的东西:

Task 49 is at 248 ()
Task has been repeated 48 times

我应该在SwingWorker中修改什么?

/**
 *
 * @author digitaldust
 */
public class Model extends SwingWorker<Integer, Integer> {

    private HashMap<String, Number> GUIparams;
    private int session;
    private int ticks;

    Model(HashMap<String, Number> KSMParams) {
        GUIparams = KSMParams;
        session = (Integer)GUIparams.get("experimentsInSession");
        ticks = (Integer)GUIparams.get("howManyTicks");
    }

    /**
     * Actual simulation
     */
    @Override
    protected Integer doInBackground() throws Exception {

        int i=0;
        while(!isCancelled() && i<session){
            i++;
            int ii=0;
            while(!isCancelled() && ii<ticks){
                // this is n, the task length and I'd like to update the GUI with this value
                ii++;
            }
            System.out.println(i);
            // this is m, how many time the task has been repeated, and now it is updated in the GUI
            publish(i);
            setProgress(i);
            Thread.sleep(1000);
        }
        return i;
    }  

    /**
     * Invoked when simulation exits
     */
    @Override
    protected void done() {
        if (isCancelled()) {
            Logger.getLogger(Model.class.getName()).log(Level.WARNING, "Experiment session cancelled by user. Closing Session...");
        } else {
            // do stuff

            Logger.getLogger(Model.class.getName()).log(Level.WARNING, "Experiment session ended.");
        }
    }

}

1 个答案:

答案 0 :(得分:7)

SwingWorker<T,V>中的第二个类型参数V用于通过此SwingWorker的发布和处理方法执行中间结果。这可能是您的自定义类。以下是基于发布的SSCCE(为清晰起见缩写)的示例:

class Progress {
    private int task;
    private int element;

    public Progress(int task, int element) {
        super();
        this.task = task;
        this.element = element;
    }
        ...
}

public class Model extends SwingWorker<Integer, Progress> {
    ...
    @Override
    protected Integer doInBackground() throws Exception {
            ...
            publish(new Progress(i, ii));
        }
}

编辑:流程方法实施的示例

@Override
protected void process(List<Progress> progressList) {
    for (Progress p : progressList){
        System.out.println(p.getTask() + " : " + p.getElement());
    }
}

编辑:用户更新的示例

这是工作者实现的略微修改版本,类似于SwingWorker手册中演示的示例。唯一的变化是在textArea中引入setProgress()成员和更新doInBackground()来电。 progress属性用于更新进度条,process()用于更新文本区域。

public static class Model extends SwingWorker<Integer, Progress> {

    private HashMap<String, Number> GUIparams;
    private int session;
    private int ticks;
    private JTextArea textArea;

    Model(HashMap<String, Number> KSMParams, JTextArea textArea) {
        GUIparams = KSMParams;
        session = (Integer)GUIparams.get("experimentsInSession");
        ticks = (Integer)GUIparams.get("howManyTicks");

        this.textArea = textArea;
    }

    @Override
    protected void process(List<Progress> progressList) {
        for (Progress p : progressList){
            textArea.append(p.getTask() + " : " + p.getElement() + "\n");
            System.out.println(p.getTask() + " : " + p.getElement());
        }
    }

    /**
     * Actual simulation
     */
    @Override
    protected Integer doInBackground() throws Exception {

        int i=0;
        while(!isCancelled() && i<session){
            i++;
            int ii=0;
            while(!isCancelled() && ii<ticks){
                // this is n, the task length and I'd like to update the GUI with this value
                ii++;
            }
            //System.out.println(i);
            // this is m, how many time the task has been repeated, and now it is updated in the GUI
            publish(new Progress(i, ii));
            //setProgress(i);
            setProgress(100 * i / session);
            Thread.sleep(1000);
        }
        return i;
    }  

    /**
     * Invoked when simulation exits
     */
    @Override
    protected void done() {
        if (isCancelled()) {
            Logger.getLogger(Model.class.getName()).log(Level.WARNING, "Experiment session cancelled by user. Closing Session...");
        } else {
            // do stuff

            Logger.getLogger(Model.class.getName()).log(Level.WARNING, "Experiment session ended.");
        }
    }
}

这是一个演示初始化:

final JProgressBar progressBar = new JProgressBar(0, 100);
final JTextArea textArea = new JTextArea();
final JButton button = new JButton("Start");

button.addActionListener(new ActionListener(){
    @Override
    public void actionPerformed(ActionEvent e) {
        HashMap<String, Number> map = Maps.newHashMap();
        map.put("experimentsInSession", 10);
        map.put("howManyTicks", 5);

        Model task = new Model(map, textArea);
        task.addPropertyChangeListener(
                 new PropertyChangeListener() {
                     public  void propertyChange(PropertyChangeEvent evt) {
                         if ("progress".equals(evt.getPropertyName())) {
                             progressBar.setValue((Integer)evt.getNewValue());
                         }
                     }
                 });
        task.execute();
    }
});