cljfx

https://github.com/cljfx/cljfx
Grigory Shepelev 2020-09-10T08:16:04.069500Z

A little question

Grigory Shepelev 2020-09-10T08:16:56.070500Z

This is my renderer

(def renderer
  (fx/create-renderer
   :middleware (fx/wrap-map-desc #(root-view %))
   :opts {:fx.opt/map-event-handler 
          (fn [x]
            (try
              (handle x)
              (catch Exception e
                {"want to show alert with exception info here"})))}))

Grigory Shepelev 2020-09-10T08:17:21.071200Z

And thank you @vlaaad for such a nice lib.

Grigory Shepelev 2020-09-10T08:19:53.072Z

But the code above doesn't work as expected. When exception happends catch block not evaluated at all.

vlaaad 2020-09-10T08:20:54.072700Z

how do you know it’s not evaluated? have you tried putting println in the catch block?

vlaaad 2020-09-10T08:22:45.073300Z

looking at your renderer I would say it should be evaluated

Grigory Shepelev 2020-09-10T08:28:18.073600Z

Yes

Grigory Shepelev 2020-09-10T08:28:24.073900Z

I did tried

vlaaad 2020-09-10T08:29:01.074200Z

Perhaps the exception happens in some async thread?

Grigory Shepelev 2020-09-10T08:30:21.074500Z

Nope. Linear.

Grigory Shepelev 2020-09-10T08:30:47.075300Z

I will send a full code to try a little later. Sorry, I have to go now

vlaaad 2020-09-10T08:30:56.075500Z

sure, np!

Grigory Shepelev 2020-09-10T08:35:19.076Z

At least I know I've got the idea right

vlaaad 2020-09-10T08:35:35.076300Z

yeah, I think you are on the right track!

Grigory Shepelev 2020-09-10T09:55:45.077300Z

(ns example.gui
  (:require [cljfx.api :as fx]
            [clojure.string :as str]))

(def *state
  (atom 0))

(defmulti handle ::event)

(defmethod handle ::press
  [_]
  (throw
   (Exception. "error")))

(defn root-view
  [a]
  {:fx/type :stage
   :title "App"
   :showing true
   :width 800
   :height 600
   :scene
   {:fx/type :scene
    :root
    {:fx/type :v-box
     :alignment :center
     :spacing 15
     :children
     [{:fx/type :h-box
       :alignment :center
       :spacing 15
       :children
       [{:fx/type :button
         :text "Button"
         :on-action {::event ::press}}]}]}}})

(def renderer
  (fx/create-renderer
   :middleware (fx/wrap-map-desc #(root-view %))
   :opts {:fx.opt/map-event-handler
          (fn [x]
            (try
              (handle x)
              (catch Exception e
                (print "sas"))))}))

Grigory Shepelev 2020-09-10T09:55:49.077600Z

(fx/mount-renderer *state renderer)

Grigory Shepelev 2020-09-10T09:55:53.077800Z

Try this @vlaaad

vlaaad 2020-09-10T09:59:48.078Z

print->println

vlaaad 2020-09-10T10:00:15.078500Z

print does not flush the output, so you won’t see results immediately

Grigory Shepelev 2020-09-10T10:00:32.078800Z

still nothing 😞

vlaaad 2020-09-10T10:01:18.079500Z

have you called (fx/mount-renderer *state renderer) again after redefining renderer to use println instead of print ?

vlaaad 2020-09-10T10:01:22.079700Z

it worked for me

Grigory Shepelev 2020-09-10T10:01:33.079900Z

1 min

Grigory Shepelev 2020-09-10T10:03:34.080300Z

Oh. I'm running it in calva repl... I guess that's the problem

vlaaad 2020-09-10T10:06:52.080500Z

hmmm

Grigory Shepelev 2020-09-10T10:07:22.081400Z

I'm really sorrt.

Grigory Shepelev 2020-09-10T10:07:30.081800Z

sorry. It's the repl situation

vlaaad 2020-09-10T10:07:58.082500Z

I don’t know how calva output works, but I would guess that it can show only what was printed in the main thread, while JavaFX event handling happens on the JavaFX UI thread, so output probably goes to your process output pane

vlaaad 2020-09-10T10:08:15.082900Z

it might be in some terminal window that calva started

Grigory Shepelev 2020-09-10T10:08:46.083200Z

I figured that out. Thanks

vlaaad 2020-09-10T10:09:18.083700Z

I slightly edited your code so it shows a dialog:

(ns cljfx-ex
  (:require [cljfx.api :as fx]
            [clojure.main :as m]
            [clojure.pprint :as pp]))

(def *state
  (atom 0))

(defmulti handle ::event)
(defmethod handle ::press [_] (throw (Exception. "error")))

(defn root-view
  [a]
  {:fx/type :stage
   :title "App"
   :showing true
   :width 800
   :height 600
   :scene {:fx/type :scene
           :root {:fx/type :v-box
                  :alignment :center
                  :spacing 15
                  :children [{:fx/type :h-box
                              :alignment :center
                              :spacing 15
                              :children [{:fx/type :button
                                          :text "Button"
                                          :on-action {::event ::press}}]}]}}})

(def renderer
  (fx/create-renderer
    :middleware (fx/wrap-map-desc #(root-view %))
    :opts {:fx.opt/map-event-handler
           (fn [x]
             (try
               (handle x)
               (catch Exception e
                 (fx/create-component
                   {:fx/type :dialog
                    :showing true
                    :dialog-pane {:fx/type :dialog-pane
                                  :header-text "Event handling exception"
                                  :content-text (-> e Throwable->map m/ex-triage m/ex-str)
                                  :expandable-content {:fx/type :label
                                                       :text (with-out-str (pp/pprint e))}
                                  :button-types [:ok]}}))))}))

(fx/mount-renderer *state renderer)

Grigory Shepelev 2020-09-10T10:11:37.083900Z

Yep. Thanks.