6

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

我的摇摆工人执行一项具有长度的任务n,并重复该任务m次数。现在,我的 GUI 只告诉我任务重复了多少次,但我希望它也告诉我我们正在进行的任务的长度。说n=300and m=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.");
        }
    }

}
4

1 回答 1

7

第二类参数V inSwingWorker<T,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());
    }
}

编辑:用户界面更新示例

这是一个稍微修改过的 worker 实现版本,类似于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();
    }
});
于 2012-06-14T14:48:18.410 回答