【问题标题】:SwingWorker done() called twice?SwingWorker done() 调用了两次?
【发布时间】:2012-03-09 10:20:26
【问题描述】:

我正在做一个Swing java 程序,该程序涉及一个工作人员从对数据库的查询中填充一个 JTable,这工作正常,但是当它完成时,我已经进入了 done() 方法检查是否有任何结果是这样处理的:

    public void done() {
        if (isCancelled()) {
            jLabelResultados.setText("Procesados " + tablaResultados.getModel().getRowCount() + " resultados.");
            return;
        }
        try {
            get();
            if (tablaResultados.getModel().getRowCount() == 0) {
                JOptionPane.showMessageDialog(jPanelClientes.getParent(), "No se encontraron resultados con los criterios de búsqueda definidos", "Sin resultados", JOptionPane.INFORMATION_MESSAGE);
            } else {
                jLabelResultados.setText("Encontrados " + tablaResultados.getModel().getRowCount() + " resultados.");
            }

        } catch (ExecutionException | InterruptedException e) {
            LOG.log(Level.SEVERE, "Excepcion", e);
        }
    }

但我的问题是结果为零时弹出两次,这让我认为done()方法被调用了两次,但我无法找到原因或代码问题。

这是完整的 swingworker 代码供参考:

private class Worker extends SwingWorker<Void, Object[]> {

    private ResultSet resultado;
    private JTable tablaResultados;
    private DefaultTableModel modelo;

    public Worker(ResultSet resultado, JTable tabla) {
        this.resultado = resultado;
        tablaResultados = tabla;
    }

    @Override
    public 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
    public void process(List<Object[]> chunks) {
        if (modelo == null) {
            modelo = new DefaultTableModel();
            modelo.setColumnIdentifiers(chunks.get(0));
            tablaResultados.setModel(modelo);
        }
        for (int i = 1; i < chunks.size(); i++) {
            modelo.addRow(chunks.get(i));
        }

    }

    @Override
    public void done() {
        if (isCancelled()) {
            jLabelResultados.setText("Procesados " + tablaResultados.getModel().getRowCount() + " resultados.");
            return;
        }
        try {
            get();
            if (tablaResultados.getModel().getRowCount() == 0) {
                JOptionPane.showMessageDialog(jPanelClientes.getParent(), "No se encontraron resultados con los criterios de búsqueda definidos", "Sin resultados", JOptionPane.INFORMATION_MESSAGE);
            } else {
                jLabelResultados.setText("Encontrados " + tablaResultados.getModel().getRowCount() + " resultados.");
            }

        } catch (ExecutionException | InterruptedException e) {
            LOG.log(Level.SEVERE, "Excepcion", e);
        }
    }
}

以及使用时:

  tarea = new Worker(resultado, jTableResultados);
    PropertyChangeListener doneListener = new PropertyChangeListener() {

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

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

有什么想法吗? 谢谢!!

【问题讨论】:

  • hmm ...应该可以工作,从来没有见过两次调用完成。 Argghh,刚刚在我的最后一个答案中检测到一个错误:该过程正在丢失行,循环应该仅针对第一批块从第二块开始,对于所有后续它必须从第一个开始。
  • 无法重现(有或没有我的错误) - 所以一定是别的东西,不知道那个“东西”可能是什么。会搜索一些疯狂且完全出乎意料的东西,比如启动两个线程左右。
  • 实际发生的情况是,当我按下选项窗格的接受按钮时,会弹出另一个。也许这给出了另一个提示??
  • 不,抱歉。对于初学者,请尝试找出它们是否由相同或不同的工人打开:f.i.添加一个名称参数并显示在 optionPane
  • 好的,在选项窗格中添加了 this.toString() 不确定这是否是您的意思,但它最终显示了不同的字符串,一个是 (myclass)Worker@1a47da2e,另一个是 (myclass)Worker@ 412e4ba3

标签: java swing swingworker


【解决方案1】:

问题已解决,必须对涉及调用创建 Worker 的方法的代码做一些事情,按钮上有两个不同的事件调用创建两个不同 Worker 的相同方法

已通过删除最严格的事件进行修复。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-06
    • 2014-11-22
    • 2014-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-03
    • 2020-05-17
    相关资源
    最近更新 更多