创建一个新的事件处理程序和源

时间:2013-07-26 14:17:49

标签: java multithreading event-handling

我有一个用户界面(UI)类。它创建一些线程(让我们称之为T)来做一些工作。我希望在T完成工作时通知我的UI类。 我想我需要在UI类中创建一个事件处理程序(在onClick()等之间)并从T触发它。 问题:这可能吗?怎么样 ? //要清楚,UI类已经有一些事件处理程序,它由我没写的函数触发。比如onClick()等。

1 个答案:

答案 0 :(得分:0)

这是一个相当常见的要求,因为您通常希望在UI线程上尽可能少地做。

如果您正在使用swing,请查看SwingWorker课程。如果您不使用swing,可能需要查看ExecutorServiceFutureTask

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;

public class Futures {

    public static void main(String[] args) {

        UI ui = new UI();
        FutureHandle<String> handle = new FutureHandle<String>(new BigJob());
        FutureHandle<String> handle2 = new FutureHandle<String>(new BigJob());

        ui.doUIStuff("Things can happen on the UI thread");
        ui.startHeavyLiftingJob(handle);
        ui.doUIStuff("I've got a big job running, but I'm still responsive");
        ui.startHeavyLiftingJob(handle2);

    }


    /**
     * Your UI class. Don't want to do anything big
     * on the UI's thread.
     */
    static class UI implements Listener<String> {

        private ExecutorService threadPool = Executors.newFixedThreadPool(5);

        public void doUIStuff(String msg) {
            System.out.println(msg);
        }

        public void startHeavyLiftingJob(FutureHandle<String> handle) {
            System.out.println("Starting background task");
            handle.setListener(this);
            threadPool.execute(handle);
        }

        public void callback(String result) {
            System.out.println("Ooh, result ready: " + result);
        }

    }


    /**
     * A handle on a future which makes a callback to a listener
     * when the callable task is done.
     */
    static class FutureHandle<V> extends FutureTask<V> {

        private Listener<V> listener;

        public FutureHandle(Callable<V> callable) {
            super(callable);
        }

        @Override
        protected void done() {
            try {
                listener.callback(get());
            } catch (InterruptedException e) {
                //handle execution getting interrupted
            } catch (ExecutionException e) {
                //handle error in execution
            }
        }

        public void setListener(Listener<V> listener) {
            this.listener = listener;
        }

    }

    /**
     * Class that represents something you don't want to do on the UI thread.
     */
    static class BigJob implements Callable<String> {

        public String call() throws Exception {
            Thread.sleep(2000);
            return "big job has finished";
        }

    }


    interface Listener<V> {
        public void callback(V result);
    }
}