Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/364.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java SwingWorker中的取消异常_Java_Swing_Swingworker - Fatal编程技术网

Java SwingWorker中的取消异常

Java SwingWorker中的取消异常,java,swing,swingworker,Java,Swing,Swingworker,我正试图通过点击JFrame表单上的按钮来取消一个函数 以下是我的工作函数: private void start(final Callable<Void> func) { worker = new SwingWorker<Boolean, Integer>() { @Override protected Boolean doInBackground() throws Exception {

我正试图通过点击JFrame表单上的按钮来取消一个函数

以下是我的工作函数:

private void start(final Callable<Void> func) {
        worker = new SwingWorker<Boolean, Integer>() {
            @Override
            protected Boolean doInBackground() throws Exception {
                publish(2);
                func.call();
                return true;
            }

            @Override
            protected void done() {
                boolean status;
                try {
                    status = get();
                    dialog.dispose();
                } catch (InterruptedException | ExecutionException e) {
                    progressBar.setString("ERROR");
                    Logger.getLogger(Parser.class.getName()).log(Level.SEVERE, null, e);
                }
            }

            @Override
            protected void process(List<Integer> chunks) {
                progressBar.setStringPainted(true);
                progressBar.setIndeterminate(true);

            }

        };

但当我单击close按钮时,它会给出异常,并且
func
doinBackground()方法中不会被取消。如何停止
func
方法?

在对和接口产生了令人遗憾的误解(很抱歉,我不得不离开JDBC一段时间:p)之后,我提出的观点仍然有效(幸运的是)。您可以在实现中使用如下方法:

@Override
protected void done() {
    if(isCancelled()) {
        try {
            func.cancel(); // you need to provide this method
            dialog.dispose();
        } catch(InterruptedException ex) {
             progressBar.setString("ERROR");
             Logger.getLogger(Parser.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}
当然,您需要为可调用的实现提供一个
cancel()
方法,根据
call()
方法实际执行的操作,该方法可能简单,也可能困难。例如:

abstract class AbstractCancellableTask<T> implements Callable<T> {

    public abstract void cancel() throws InterruptedException;
}

func如何知道它正在被取消?作为一般规则,doInBackground必须合作(即注意被取消并停止它正在做的任何事情)-但不知道如何在这里应用该规则;-)嗯,这是否意味着不可能取消doInBackground操作?不,但你必须这么做…哦,我犯了一个可怕的错误:(你没有使用接口…对数据库做了太多工作我到处都看到JDBC…很抱歉!但主要概念仍然有效,你可以使用
SwingWorker#isCancelled()
并为您的
func
提供一些
cancel
方法。虽然这并不容易…@AloneInTheDarkNo,关键是提供一个
cancel()
method。这只是一个实现示例。在这种情况下,繁重的任务是循环打印字符串,直到
flag
为false。只有当一些外部对象调用
cancel()时才会发生这种情况
方法将
标志设置为false,这只有在SwingWorker被取消时才会发生。我说清楚了吗?如果没有,请告诉我。@aloneinthedark您有在函数中执行的代码吗?如果有,那么您可以创建一个新的
AbstractCancelableTask
并将该代码放入
调用()中
方法实现。然后您必须管理如何取消该代码的执行(如果可能)。如果您没有该代码,并且只从外部接收到一个可调用函数,那么我担心您将无法实现您的目标。@aloneinthedark不客气!正如我所说,根据需要执行的操作,这可能很容易,也可能很难。希望这是第一个选项;) @AloneInTheDark@AloneInTheDark某些gui对象访问doInBackground中的视图,因此您的函数不能!
abstract class AbstractCancellableTask<T> implements Callable<T> {

    public abstract void cancel() throws InterruptedException;
}
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.concurrent.Callable;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JToggleButton;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;

public class Demo {

    private void createAndShowGUI() {

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

            private AbstractCancellableTask<Void> myCallable;

            @Override
            protected Void doInBackground() throws Exception {

                myCallable = new AbstractCancellableTask<Void>() {

                    private volatile boolean flag = true;

                    @Override
                    public void cancel() throws InterruptedException {
                        flag = false;
                    }

                    @Override
                    public Void call() throws Exception {
                        while(flag) {
                            System.out.println("Running heavy task...");

                        }
                        System.out.println("Stopped!");
                        return null;
                    }
                };

                myCallable.call();
                return null;
            }

            @Override
            protected void done() {
                if(isCancelled()) {
                    try {
                        myCallable.cancel();
                    } catch (InterruptedException ex) {
                        Logger.getLogger(Demo.class.getName()).log(Level.SEVERE, null, ex);
                    }
                }
            }
        };

        JToggleButton button = new JToggleButton("Start...", false);
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JToggleButton toggleButton = (JToggleButton)e.getSource();
                if(toggleButton.isSelected()) {
                    worker.execute();
                    toggleButton.setText("Stop it!");
                } else {
                    worker.cancel(true);
                    toggleButton.setEnabled(false);
                }
            }
        });

        JPanel content = new JPanel();
        content.add(button);

        JFrame frame = new JFrame("Demo");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().add(content);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Demo().createAndShowGUI();
            }
        });
    }

    abstract class AbstractCancellableTask<T> implements Callable<T> {

        public abstract void cancel() throws InterruptedException;
    }
}