Search code examples
swingclojureswingworker

SwingWorker execution in clojure


In clojure you can create a SwingWorker proxy and implement doInBackground and do methods. How would you go on to invoke execute method of swingworker?


Solution

  • You can create and invoke a SwingWorker using standard Java interop, e.g.:

    ;; define a proxy that extends SwingWorker
    (def my-swing-worker 
      (proxy [SwingWorker] []
        (doInBackground []
          (reduce + (range 1000000)))))
    
    ;; run the SwingWorker
    (.execute my-swing-worker)
    
    ;; Get the result
    (.get my-swing-worker)
    => 499999500000
    

    However, normally in Clojure you wouldn't use SwingWorkers directly. There is already a feature in Clojure that provides the functionaility of a SwingWorker: a future uses a separate thread to calculate a long running task and allows you to get the result later. Example usage:

    ;; define and launch a future
    (def my-future 
      (future 
        (reduce + (range 1000000))))
    
    ;; get the result (will wait for future to complete if needed)
    @my-future
    => 499999500000
    

    I think most people would agree the "pure Clojure" way is simpler and more idiomatic for running background tasks. The only reason I can think of to prefer SwingWorker is if you are using some of the specific GUI integration features it provides (e.g. the ability to fire property change events).