cljfx

https://github.com/cljfx/cljfx
2020-01-27T15:14:25.006400Z

Hi there, First, thanks for this library, I find it really useful and nice to use. Quick question - what’s the best way to set some property on a Stage object? I mean how to pull java object from a tree, modify it and put it back?

vlaaad 2020-01-27T15:36:31.013100Z

Hi, glad you like it! There are couple of way to do that. First is using fx/on-instance-lifecycle where you get an instance when it's created in :on-created callback. Note that this callback is executed only once per component, even when callback's function itself is changed (so you can't use it to change this property to another). Second is creating desired prop with fx/make-ext-with-props . It will allow managing properties in the same way you control other stuff in cljfx.

;; mutator that changes stage's property for specified key
(defn- mutable-property [key]
  (fx.mutator/adder-remover
    (fn [^Stage stage value] (.put (.getProperties stage) key value))
    (fn [^Stage stage _] (.remove (.getProperties stage) key))))

;; extension lifecycle
(def ext-with-my-prop
  (fx/make-ext-with-props
    {:my-prop (fx.prop/make (mutable-property :my-prop) fx.lifecycle/scalar)}))

;; example description
(def desc
  {:fx/type ext-with-my-prop
   :props {:my-prop "boop"}
   :desc {:fx/type :stage
          :scene {:fx/type :scene
                  :root {:fx/type :v-box}}}})

;; it works!
(.getProperties ^Stage (fx/instance @(fx/on-fx-thread (fx/create-component desc))))
; => {:my-prop "boop"}

vlaaad 2020-01-27T15:38:06.014Z

first is easier but limited, second is more verbose and more general

👍 1
vlaaad 2020-01-27T15:39:12.014300Z

@romantsopin ^

2020-01-27T15:45:08.016400Z

That’s what I needed, thanks!

jlmr 2020-01-27T18:13:49.018400Z

@vlaaad, is there a recommended way to update the *context from a core.async channel? I’ve been doing a (perhaps naive) swap!:

(defn reset-in-model
  [id path val]
  (swap! *context fx/swap-context assoc-in (into [:some id :path] path) val))

(defn ui-channel
  [id]
  (let [c (a/chan 10)]
    (go-loop []
      (if-let [{:keys [path payload]} (<! c)]
        (reset-in-model id path payload))
      (recur))
    c))
But this is causing problems elsewhere in my core.async code.

vlaaad 2020-01-27T18:31:26.018600Z

*context is a regular atom, there is only swap!/reset!

vlaaad 2020-01-27T18:32:47.018700Z

I wonder what problems it might cause?

jlmr 2020-01-27T19:57:51.020700Z

In the go-loop that was responsible for putting values on the ui-channel the bindings in the loop sometimes reset to the initial values. Very weird behaviour