如何停止 SwingWorker? [英] How to Stop a SwingWorker?

查看:28
本文介绍了如何停止 SwingWorker?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我怎样才能阻止 SwingWorker 做他的工作?我知道有 cancel() 方法,但我能做的最多就是匿名创建一个新的 SwingWorker 来完成这项工作.

How can I stop the SwingWorker doing his work? I know there's the cancel() method for that, but the most I could do is to anonymously create a new SwingWorker that is doing the job.

以下是参考代码:

public void mostrarResultado(final ResultSet resultado) {

    new SwingWorker<Void, Object[]>() {

        @Override
        public Void doInBackground() {

            // TODO: Process ResultSet and create Rows.  Call publish() for every N rows created.+
            DefaultTableModel modelo = new DefaultTableModel();
            jTableResultados.removeAll();
            int columnas;
            int res = 0;
            try {
                ResultSetMetaData metadata = resultado.getMetaData();
                columnas = metadata.getColumnCount();
                Object[] etiquetas = new Object[columnas];
                jProgressBar.setIndeterminate(true);
                for (int i = 0; i < columnas; i++) {
                    etiquetas[i] =
                            metadata.getColumnName(i + 1);
                }
                modelo.setColumnIdentifiers(etiquetas);
                jTableResultados.setModel(modelo);

                while (resultado.next() && !this.isCancelled()) {
                    res++;
                    Object fila[] = new Object[columnas];
                    for (int i = 0; i < columnas; i++) {
                        fila[i] = resultado.getObject(i + 1);
                    }
                    modelo.addRow(fila);
                    publish(fila);
                }
                jProgressBar.setIndeterminate(false);
                if (res == 0) {
                    JOptionPane.showMessageDialog(jPanelClientes.getParent(), "No se encontraron resultados con los criterios de búsqueda definidos", "Sin resultados", JOptionPane.INFORMATION_MESSAGE);
                }
            } catch (SQLException ex) {
                LOG.log(Level.SEVERE, "Excepcion: ", ex);
                JOptionPane.showMessageDialog(jPanelClientes.getParent(), "Error en al ejecutar la busqueda seleccionada", "Error", JOptionPane.ERROR_MESSAGE);
            }
            return null;
        }
    }.execute();
}

实际上这项工作做得很好并且发布没有问题,但考虑到我使用数据库,可能会发生查询有太多结果并且完整发布所花费的时间,因此用户必须能够取消任务并运行新任务.

Actually the job is well done and published with no issues, but given that I work with a DB, it can happen that the query has too many results and the time taken for the full publish takes a time so the user has to be able to cancel the task and run a new one.

显然,worker 是一种与取消按钮事件不同的方法,所以我将无法调用 Worker cancel() 方法.

Obviously the worker is a different method than the cancel button event so I won't be able to invoke Worker cancel() method.

尝试以这种方式使工人成为班级的属性,但没有运气:

Tried making the worker an attribute for the class with no luck this way:

    public class myClass extends javax.swing.JFrame {
      private SwingWorker<Void, Object[]> tarea;

但是当我去的时候:

tarea = new SwingWorker<Void,Object[]>(){...} 

我得到了不兼容的类型,发现无效,需要 SwingWorker,而且我完全没有想法.

I get Incompatible types, found void, required SwingWorker, and I'm totally out of ideas.

有什么建议吗?

谢谢

推荐答案

这不是问题的答案(这是如何取消,我认为已经解决了)而是如何将后台处理与视图/模型更新分开.一个伪代码大纲:

This is not a answer to the question (which is how to cancel, I think that's solved) but how to separate the background handling from the view/model updates. A pseudo-code outline:

public static class MyDBWorker extends SwingWorker<Void, Object[]> {

    private JTable table;
    private DefaultTableModel model;
    private ResultSet resultado;

    public MyDBWorker(JTable table, ResultSet resultado) {
        this.table = table;
        this.resultado = resultado;
    }

    @Override
    protected Void doInBackground() throws Exception {
        ResultSetMetaData metadata = resultado.getMetaData();
        int columnas = metadata.getColumnCount();
        Object[] etiquetas = new Object[columnas];
        for (int i = 0; i < columnas; i++) {
            etiquetas[i] = metadata.getColumnName(i + 1);
        }
        publish(etiquetas);
        while (resultado.next() && !this.isCancelled()) {
            Object fila[] = new Object[columnas];
            for (int i = 0; i < columnas; i++) {
                fila[i] = resultado.getObject(i + 1);
            }
            publish(fila);
        }
        return null;
    }


    @Override
    protected void process(List<Object[]> chunks) {
        int startIndex = 0;
        // first chunk, set up a new model
        if (model == null) {
            model = new DefaultTableModel();
            model.setColumnIdentifiers(chunks.get(0));
            table.setModel(model);
            startIndex = 1;
        }
        for (int i = startIndex; i < chunks.size(); i++) {
            model.addRow(chunks.get(i));
        }
    }

    @Override
    protected void done() {
        // nothing to do, we were cancelled
        if (isCancelled()) return;
        // check for errors thrown in doInBackground
        try {
            get();
            // all was well in the background thread
            // check if there are any results
            if (table.getModel().getRowCount() == 0) {
                // show message
            }
        } catch (ExecutionException e) {
            // we get here if f.i. an SQLException is thrown
            // handle it as appropriate, f.i. inform user/logging system
        } catch (InterruptedException e) {
            // 
        }
    }

}

// use it
SwingWorker worker = new MyDBWorker(table, resultado);
PropertyChangeListener stateListener = new PropertyChangeListener() {

    @Override
    public void propertyChange(PropertyChangeEvent e) {
        if (e.getNewValue() == SwingWorker.StateValue.STARTED) {
            progressBar.setIndeterminate(true);
        }
        if (e.getNewValue() == SwingWorker.StateValue.DONE) {
            progressBar.setIndeterminate(false);
        }

    }

};
worker.addPropertyChangeListener(doneListener);
worker.execute();

编辑

修复了一个过程中的错误:向模型添加行必须始终从批处理的第一个索引开始,除非处理标题.

fixed a bug in process: adding rows to the model must start on first index of the batch always, except when processing the header.

这篇关于如何停止 SwingWorker?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆